Define
Actors, journeys, use cases, business rules, domain terms and requirements: small Markdown files with stable IDs and one agreed shape each. A tool can check the shape without judging the content.
Product decisions get copied into tickets, specs, prompts and documentation. Each copy can say something slightly different, and when the product changes some of the copies get left behind.
Product Definition as Code keeps the agreed product definition in versioned Markdown that delivery work cites instead of restating. Those decisions get one home, and when it changes, one command flags every spec, ticket and prompt that relied on the old wording.
Run this on any repository that has been doing Spec-Driven Development for a few weeks:
$ grep -rn -i "refund" openspec/specsbilling/spec.md:4: Refunds are issued for purchases made in the last 30 days.checkout/spec.md:4: Customers can request a refund within 30 days of delivery.support/spec.md:4: If the order is less than a month old, offer a refund.Three specs, three wordings, two meanings: 30 days from purchase is not 30 days from delivery. Nobody decided that fork. An agent paraphrased it into existence and no human caught it, because specs are words only agents read. PDaC applies the oldest rule in engineering: don’t repeat yourself.
Define the rule once. One small versioned file with an ID, in one agreed place:
---id: BR-REFUND-001type: business-ruletitle: Refund windowstatus: active---
## Rule
Refunds are accepted within 30 days of delivery.Every spec, ticket and prompt then points at BR-REFUND-001 instead of restating it. Nothing is left to fork, the specs get shorter, and no tool is needed to get this far.
The method is three beats, and defining one rule is the smallest slice of the first:
Define
What are we building?
Build
Turn the definition into delivery work.
Change
Evolve it, and find what the change affects.
Once means one home for a decision, not one revision: the third beat is what keeps the first honest. The middle beat carries three stages, so the loop reads as five. Anything marked next is open backlog, not shipped product.
Define
Actors, journeys, use cases, business rules, domain terms and requirements: small Markdown files with stable IDs and one agreed shape each. A tool can check the shape without judging the content.
Derive
Requirements stay connected to the rules and use cases behind them, so an agent is briefed with only the part of the product that matters. Next: a packaged selection-to-briefing step.
Build
Whatever builds, builds: an SDD framework, a coding agent, or a team working from the backlog, all reading the same definition instead of restating it. Delivery owns implementation; the definition owns meaning.
Verify
Structured Behaviour records given, when and then clauses as accepted intent with its own ID and digest, so tests cite the exact behaviour they verify. Next: projection into test syntax such as Gherkin, and coverage reporting.
Evolve
Meaning changes through one mechanism: a Product Change, proposed, reviewed and accepted by a person.
You do not have to adopt all of it. Write it down, agree how it changes, make it checkable: three doors, in whichever order the failure in front of you demands. Start with one product decision and one real delivery item.
Product Definition as Code keeps the agreed product definition in versioned Markdown that delivery work cites instead of restating.
The definition lives in small, related Markdown files: actors, journeys, use cases, business rules, domain terms and requirements. Together they form a validated product graph that humans and AI agents can read alike. It changes only through an explicit Product Change, reviewed and accepted by a human. Consumer documents such as SDD specs, tasks and agent prompts cite the exact product text they rely on by stable ID and content digest. When cited text changes, tools flag every recorded citation for review, so documentation drift is detected instead of remaining silent. Deterministic tools check structure and references, never truth. People decide what is true and what should change.
And there it stops. Spec-Driven Development tools own one implementation increment; PDaC owns the accepted product intent that outlives every spec. What delivery learns flows back as evidence and proposed Product Changes: one-way authority, two-way learning.

PDaC-0, the one-minute map. Eight more diagrams cover the boundary, the model, change, citation and verification.
Pointing a spec at BR-REFUND-001 stops the fork. Recording which version of the rule it relied on makes the dependency checkable, which teams tend to reach once the definition has settled. The recording tells one story:
prodshape citations verify flags every citation that now needs review.Real output, not an animation: the end card names the CLI version it captured. Here is the same story in three commands.
1. Every spec cites the rule instead of restating it. prodshape cite emits the reference, carrying a content digest of the rule at the moment it was cited:
## ReturnsRefunds follow BR-REFUND-001. {pdac:cite id="BR-REFUND-001" digest="sha256:b5c58067…"}2. The rule changes. A governed repository moves the accepted definition only through a Product Change; this sandbox edits the file directly to trigger drift quickly. The catch works the same either way, by file and line, with no grep:
$ prodshape citations verifystale BR-REFUND-001 openspec/specs/billing/spec.md:4stale BR-REFUND-001 openspec/specs/checkout/spec.md:4stale BR-REFUND-001 openspec/specs/support/spec.md:4warning PRODUCT061 openspec/specs/billing/spec.md [BR-REFUND-001]: Citation of 'BR-REFUND-001' is stale: canonical content changed since the citation was recorded3 citation(s): 0 current, 3 stale, 0 tampered, 0 unresolvedPut that command in CI and stale product knowledge stops being invisible. PDaC does not rewrite the specs for you: every citation reports current, stale, tampered or unresolved, and a person reviews each flag. The full rules are in the Citation Contract.
3. The whole script. Verified against @prodshape/cli@0.20.0 and served at pdac.dev/demo.sh. A non-governed sandbox: it runs in a temporary directory via npx, with no global install and no git.
cd "$(mktemp -d)"npm init -y >/dev/null 2>&1npm install --save-dev --save-exact @prodshape/cli@0.20.0prodshape() { npx --no-install prodshape "$@"; }
mkdir -p docs/product/model/business-rules openspec/specs/checkout openspec/specs/billing openspec/specs/support
# ACT 1: the same rule, restated by agents in three specs, three wordingscat > openspec/specs/checkout/spec.md <<'EOF'# Checkout
## ReturnsCustomers can request a refund within 30 days of delivery.EOFcat > openspec/specs/billing/spec.md <<'EOF'# Billing
## CreditsRefunds are issued for purchases made in the last 30 days.EOFcat > openspec/specs/support/spec.md <<'EOF'# Support playbook
## RefundsIf the order is less than a month old, offer a refund.EOF
grep -rn -i "refund" openspec/specs# purchase vs delivery vs "a month": nobody decided that fork
# ACT 2: define once, cite everywherecat > docs/product/model/business-rules/br-refund-001.md <<'EOF'---id: BR-REFUND-001type: business-ruletitle: Refund windowstatus: active---
## Rule
Refunds are accepted within 30 days of delivery.
## Rationale
Customers need a predictable window; finance needs a bounded liability.
## Examples
A delivery on March 1 may be refunded through March 31.
## Exceptions
None.EOF
CITE=$(prodshape cite --id BR-REFUND-001 \ --file docs/product/model/business-rules/br-refund-001.md --form inline)
cat > openspec/specs/checkout/spec.md <<EOF# Checkout
## ReturnsRefunds follow BR-REFUND-001. $CITEEOFcat > openspec/specs/billing/spec.md <<EOF# Billing
## CreditsRefund eligibility is BR-REFUND-001. $CITEEOFcat > openspec/specs/support/spec.md <<EOF# Support playbook
## RefundsApply BR-REFUND-001 as written. $CITEEOF
prodshape citations verify# current x3: every spec agrees with the rule
# ACT 3: the rule changes (sandbox shortcut: a direct edit; a governed repository uses a Product Change)node --input-type=module -e " import { readFileSync, writeFileSync } from 'node:fs'; const p = 'docs/product/model/business-rules/br-refund-001.md'; writeFileSync(p, readFileSync(p,'utf8').replace('30 days','14 days'));"
prodshape citations verify# stale x3: every citing spec, file:line. No grep.On Windows, run it in Git Bash or WSL; the heredocs above are POSIX-shell constructs.
For a real repository, choose the PDaC adoption path that matches how your team delivers software.
A defined product over a queue of tickets.
Explicit change over casual edits.
Typed relationships over organized documents.
Human judgment over machine confidence.
Ten principles follow from these four values. If they match how you build, add your name.
Read and sign the manifestoThe specification is v0.2.0, released on 2026-08-28 and open for comment. The current ProductShape release implements it: its pinned conformance workflow passes all 44 published cases and verifies all 12 pinned digests, run by pdac-conformance, the neutral runner. The file format remains v1alpha1, so existing definitions need no migration, and new v0.2 features are optional.
It is still an early draft extracted from one working implementation. A second, independent implementation and external pilots are release gates for v1, not assumed achievements, and the known limits page names every gap we know about. Next in the open backlog: projection of Structured Behaviour into test syntax, a packaged selection-to-briefing step, and coverage reporting. Full changes in the v0.2.0 release notes.
Articles
The problem behind PDaC, where the method comes from, and the layer above Spec Kit. One argument per article, primary sources only.
The reference implementation
ProductShape, the reference implementation of Product Definition as Code. It
implements PDaC v0.2.0 with the v1alpha1 file format:
npm install -g @prodshape/cli@0.20.0.
Build an implementation
The spec is implementation-independent by design and wants more than one. Read the conformance and listing criteria.
PDaC was introduced in Product Definition as Code for the AI-SDLC (July 2026) and extracted into an open specification.