Skip to main content

What is a dev unit?

A dev unit is the fundamental building block of a PDD project. It consists of four artifacts that belong together and are kept in continuous sync:

Prompt

The source of truth. Defines intent, requirements, and constraints for the module. Versioned in git. Never generated — always authored.

Generated code

The implementation produced by pdd generate. Disposable — regenerated from the prompt whenever the prompt changes. Never manually patched for structural changes.

Runnable example

A minimal program demonstrating how to use the module. Produced by pdd example. Serves as the public interface consumed by dependent modules.

Tests

Unit tests produced by pdd test. Accumulate over time — never replaced, only expanded. Serve as mold walls that constrain all future generations.
The prompt defines intent. Code, example, and tests are generated artifacts — but tests are treated as permanent assets that accumulate rather than regenerate.

How the four artifacts relate

Prompt is the source of truth for all three

When the prompt changes, pdd sync determines which downstream artifacts are out of date and regenerates them. Code is always regenerated from the prompt. The example is regenerated to match updated code. Tests are not regenerated — they accumulate. New tests may be added, but existing passing tests are never discarded.

Tests constrain code, not just verify it

When pdd generate runs, existing tests are included as context in the LLM’s prompt. This means generated code is constrained to pass existing tests — the tests act as specification walls, not after-the-fact checks. Each bug found adds a test, which permanently prevents that bug from recurring in any future generation. This is the ratchet effect: the mold becomes more precise over time.

The example is the interface

The example is not documentation — it is the interface that dependent modules include as context. A 500-line module might have a 50-line usage example. By including only the example, dependent prompts save ~90% of tokens while getting the same contract information. Module A’s prompt includes Module B’s example. When Module B changes, pdd auto-deps updates the include reference, and Module A regenerates with the current interface.

The sync cycle

pdd sync <basename> runs the complete dev unit workflow automatically, executing only the steps needed based on what has changed.
1

auto-deps

Discover and inject relevant dependencies into the prompt — both code examples and documentation files. Remove redundant inline content that duplicates what included documents provide.
2

generate

Create or update the code module from the prompt. Uses fingerprint-based change detection to determine whether to perform incremental patching or full regeneration.
3

example

Generate a runnable usage example if it does not exist or is outdated relative to the code.
4

crash

Fix any runtime errors to make the code and example executable. Resolves immediate failures before verification.
5

verify

Run functional verification — execute the program and judge its output against the prompt’s stated intent.
6

test

Generate comprehensive unit tests if they do not exist, or expand them if the module has changed. Tests accumulate in a single test file per target.
7

fix

Iteratively resolve any bugs found by unit tests. Each iteration sees the failing tests and generates code that satisfies them.
8

update

Back-propagate any implementation learnings into the prompt file. Keeps the prompt as an accurate source of truth.
The sync command skips steps that are unnecessary. For example, if the prompt has not changed since the last run, generate is skipped. If tests already pass at the target coverage, fix is skipped.
# Run full sync with overwrite permission
pdd --force sync factorial_calculator

# Sync with custom budget and coverage target
pdd --force sync --budget 15.0 --target-coverage 95.0 data_processor

# Preview what sync would do without executing
pdd sync --dry-run factorial_calculator

Fingerprint-based change detection

PDD uses content hashes and timestamps to precisely detect what has changed since the last sync. This prevents unnecessary regeneration and enables safe incremental updates. Fingerprint data is stored in .pdd/meta/<basename>_<language>.json. Each fingerprint file tracks:
  • The hash of the prompt at the time of last generation
  • The hash of the generated code
  • The hash of the example
  • Test results and coverage from the last run
  • Timestamps for each operation
When pdd sync runs, it compares current file hashes against stored fingerprints to decide which steps to execute. If the prompt hash matches the stored value, code regeneration is skipped. If the code hash has changed since the last example generation, the example is regenerated. For complex scenarios — such as multiple files changing simultaneously — PDD uses LLM-powered conflict resolution to determine the best approach.

Test accumulation

Tests are a permanent asset. This is a core PDD invariant:
Never discard passing tests after regeneration. Tests accumulate to form a regression net that preserves behavior as the system evolves.
The accumulation workflow:
  1. pdd test generates the initial test file from the prompt and code
  2. When a bug is found, pdd bug adds a failing test case to the existing test file
  3. pdd fix resolves the bug — the LLM sees all existing tests and must pass them
  4. The new test is now a permanent mold wall
Tests persist when the module prompt changes. Only code is regenerated on prompt changes; the test file is expanded, not replaced. This creates a ratchet: each generation is more constrained than the previous one, making regeneration progressively safer over time.

The .pdd/ directory

PDD uses a .pdd/ directory in the project root to store metadata and state:
.pdd
meta
factorial_calculator_python.json
data_processor_python.json
llm_model.csv
PathPurpose
.pdd/meta/<basename>_<language>.jsonFingerprint files — operation history, test results, coverage, sync logs
.pdd/locks/File-descriptor-based lock files that prevent concurrent sync operations
.pdd/llm_model.csvOptional project-specific LLM model configuration
Add .pdd/ to version control (except lock files). The meta/ directory contains important project state — fingerprints, run reports, and sync history — that enables reproducibility across machines.

Smart lock management

Lock files in .pdd/locks/ prevent race conditions when multiple sync operations run simultaneously. PDD uses file-descriptor-based locking and automatically cleans up stale locks from crashed processes. The --dry-run flag performs state analysis without acquiring locks, making it safe to inspect sync state even while another sync is running:
pdd sync --dry-run calculator
pdd --verbose sync --dry-run calculator  # Includes LLM reasoning for complex scenarios

Lifecycle summary

ArtifactCreated byUpdated whenDiscarded?
PromptDeveloper (authored)Developer edits itNever
Codepdd generatePrompt changesYes — regenerated
Examplepdd exampleCode changesYes — regenerated
Testspdd testBugs found (expanded)Never
Fingerprintspdd syncAfter each operationNo — accumulated
The key asymmetry: code and examples are ephemeral (regenerated freely); prompts and tests are permanent assets (accumulated and versioned). This asymmetry is what makes PDD maintenance costs compound downward rather than upward.

Build docs developers (and LLMs) love