This guide walks through a first Context-Disciplined Agent Development project using a small passwordless login example. The goal is not to add process for its own sake. The goal is to give an AI agent a compact, verified task packet instead of a vague prompt or a full-repository dump.
By the end, your project will have:
- a durable goal record under
docs/specs/; - a design note that can be validated;
- one agent-ready task packet under
agent/packets/; - a ranked context bundle under
agent/verification/; - verification evidence from your test command;
- a progress note for the next session;
- trace and benchmark outputs.
From the CDAD tools repository:
python3 -m pip install -e .
cdad --helpDuring local development, you can also run without installing:
PYTHONPATH=/path/to/cdad-tools/src python3 -m cdad_tools.cli --helpIn the examples below, replace cdad with the PYTHONPATH=... python3 -m cdad_tools.cli form if you have not installed the package.
Move into the project you want to govern with CDAD:
cd /path/to/your-projectFor a first trial, choose a small but non-trivial task. Good candidates:
- add one backend endpoint;
- update one workflow;
- add one integration point;
- repair one bug with a clear test.
Avoid starting with a whole product rewrite. CDAD works best when the first packet is a bounded verified increment.
cdad init
cdad doctorThis creates:
docs/
architecture/
decisions/
specs/
agent/
memory/
packets/
progress/
verification/
reports/
integrations/
benchmarks/
The split matters:
docs/stores durable human-reviewed intent.agent/packets/stores compact runtime units for agents.agent/verification/stores evidence.agent/progress/stores resumable state.
A goal record is the source of truth. It should define scope, non-goals, constraints, verification, risks, and approval boundaries.
Example:
cdad goal new AUTH-MAGIC-LINK \
--objective "Add passwordless magic-link login request handling." \
--scope-in "backend service for requesting a magic link" \
--scope-in "unit verification for queued email behavior" \
--scope-out "frontend login screen" \
--scope-out "social login" \
--constraint "reuse existing email sender abstraction" \
--constraint "token expiry must remain 15 minutes" \
--risk "token leakage or replay" \
--risk "schema change may be needed for token metadata" \
--quality-bar "A valid email request queues exactly one login email and existing auth behavior remains unchanged." \
--verify "PYTHONPATH=. python3 -m unittest discover -s tests -v"Validate it:
cdad goal validate --reportExpected outputs:
docs/specs/AUTH-MAGIC-LINK.goal.jsondocs/specs/AUTH-MAGIC-LINK.goal.mdagent/reports/AUTH-MAGIC-LINK-goal-validation.json
The Markdown rendering should be readable by humans. The JSON file is the canonical machine-readable record.
Create a design note in docs/specs/. Keep it short and operational:
# Magic Link Design
## Objective
Add passwordless magic-link login request handling for the auth backend.
## Scope In
- backend request service
- unit test coverage for queued email behavior
## Scope Out
- frontend login screen
- social login
- production email provider migration
## Constraints
- reuse the existing email sender abstraction
- token expiry stays 15 minutes
- no schema change without approval
## Risks
- token leakage or replay
- rate limiting may need infrastructure support
## Verification
- run `PYTHONPATH=. python3 -m unittest discover -s tests -v`
- scenario: valid email request returns queued status
## Approval Boundaries
- dependency changes require approval
- schema or contract changes require approval
- security boundary changes require approvalValidate the design:
cdad design validate docs/specs/magic-link-design.md --reportThe validator checks for:
- objective;
- scope in;
- scope out;
- constraints;
- risks;
- verification;
- approval boundaries.
A packet is what the agent should actually consume. It is smaller than the full goal or design.
cdad packet new AUTH-ML-01 \
--goal-id AUTH-MAGIC-LINK \
--objective "Implement and verify magic-link request behavior in the auth service." \
--why-now "This is the backend increment needed before endpoint and UI packets." \
--context src/auth/magic_link.py \
--interface "auth magic-link request service" \
--constraint "Do not change frontend behavior." \
--constraint "Do not introduce a new dependency." \
--verify "PYTHONPATH=. python3 -m unittest discover -s tests -v" \
--scenario "valid email request returns queued status" \
--escalate "Escalate dependency, schema, contract, security boundary, destructive, or scope-widening changes." \
--reference docs/specs/AUTH-MAGIC-LINK.goal.json \
--reference docs/specs/magic-link-design.md \
--priority 1 \
--risk 4 \
--value 5Validate packets:
cdad validate --strict-paths --reportExpected outputs:
agent/packets/AUTH-ML-01.jsonagent/packets/AUTH-ML-01.mdagent/reports/AUTH-ML-01-packet-validation.json
The packet should answer:
- What is the one concrete objective?
- Why is this the next step?
- Which files should be loaded first?
- What must not change?
- How will the agent verify success?
- When should the agent stop and escalate?
cdad next --heuristic dependency-first
cdad next --heuristic dependency-first --jsonOther options:
cdad next --heuristic risk-first
cdad next --heuristic value-firstUse:
dependency-firstwhen packet order matters;risk-firstwhen unknowns or approval boundaries dominate;value-firstwhen several packets are independent.
cdad context AUTH-ML-01 --budget 12000The context bundle includes:
- explicit packet files first;
- referenced goal/design docs;
- related tests;
- related architecture and decision notes;
- estimated token count and file scores.
Expected output:
agent/verification/AUTH-ML-01-context.md
This is the bundle you can hand to an agent with the packet. It is intentionally smaller than the full repo.
Check what CDAD detects:
cdad verificationRun the packet verification:
cdad verify AUTH-ML-01If runnable verification passes, CDAD updates:
- packet status to
Passed; - packet verification evidence path;
- packet Markdown rendering;
agent/verification/AUTH-ML-01-verification.md.
cdad progress add AUTH-ML-01 \
--goal "Magic link request handling" \
--file src/auth/magic_link.py \
--file tests/test_magic_link.py \
--verification "PYTHONPATH=. python3 -m unittest discover -s tests -v passed" \
--result Passed \
--next "Create AUTH-ML-02 for HTTP endpoint routing."Progress records are what let the next agent or next session resume without reconstructing intent from chat.
cdad trace
cdad trace --json --output agent/reports/trace.jsonYou should see a row like:
Goal Packet Status Evidence Progress
AUTH-MAGIC-LINK AUTH-ML-01 Passed AUTH-ML-01-context.md, verification.md yes
The important point is that the packet is linked back to a goal and forward to evidence.
cdad coverage --reportCoverage checks whether:
- packets are linked to goals;
- packet links point to existing goals;
- goals have at least some packet coverage.
Warnings usually mean “add more packets soon.” Errors mean the workflow is not traceable enough for CI.
cdad benchmark --output agent/benchmarks/metrics.jsonThe report includes:
- total packets;
- passed packets;
- verification pass rate;
- context bundle token estimate;
- verification evidence count;
- progress entry count;
- rework mentions.
- average time to verified packet, based on packet timestamps.
This gives you a baseline for whether CDAD is helping or just adding ceremony.
Generate thin command templates:
cdad integration generate --agent codex --force
cdad integration generate --agent claude-code --force
cdad integration generate --agent cursor --force
cdad integration generate --agent github-copilot --force
cdad integration generate --all --forceThese templates tell agents to use CDAD artifacts. They do not embed a giant prompt.
cdad ciCI runs the main quality gates:
- goal validation;
- packet validation with strict path checks;
- goal coverage, if enabled;
- benchmark thresholds.
Defaults live in cdad.config.json:
{
"context_token_budget": 8000,
"ci": {
"min_verification_pass_rate": 0.0,
"max_rework_mentions": 0,
"require_goal_coverage": true
}
}Use the config to tune token budgets and quality thresholds for your team.
Most packets become Passed when cdad verify succeeds. For other states:
cdad packet status AUTH-ML-01 --status NeedsApproval
cdad packet status AUTH-ML-01 --status Blocked
cdad packet link-goal AUTH-ML-01 AUTH-MAGIC-LINKUse manual status changes when the right answer is to pause, ask for approval, or repair traceability rather than keep coding.
A useful goal record is specific:
## Objective
Add passwordless magic-link login request handling.
## Scope Out
- frontend login screen
- social login
## Verification
- [unit] PYTHONPATH=. python3 -m unittest discover -s tests -vA useful task packet is narrower:
## Objective
Implement and verify magic-link request behavior in the auth service.
## Relevant context
- src/auth/magic_link.py
## Verification
- [unit] PYTHONPATH=. python3 -m unittest discover -s tests -v
- [manual] valid email request returns queued statusA useful progress snapshot says what happened and what comes next:
Passed. Verification: PYTHONPATH=. python3 -m unittest discover -s tests -v passed. Next recommended step: Create AUTH-ML-02 for HTTP endpoint routing.cdad doctorpasses.- Goal validation report is
passed. - Design validation report is
passed. - Packet validation report is
passed. cdad contextcreates a bundle with relevant source, tests, and docs.cdad verify <TASK_ID>passes.- Packet status becomes
Passed. cdad progress addupdates the progress log and packet snapshot.cdad traceshows goal -> packet -> evidence -> progress.cdad trace --jsonwrites a machine-readable trace.cdad coverage --reporthas no errors.cdad benchmarkwrites metrics.cdad cipasses.
- Starting with a task that is too large.
- Creating a goal without scope-out.
- Creating a packet without verification.
- Referencing files that do not exist.
- Letting the agent widen scope instead of creating a new packet.
- Treating the context bundle as permanent memory instead of a per-packet runtime input.
After the first packet passes, create the next narrow increment:
cdad packet new AUTH-ML-02 \
--goal-id AUTH-MAGIC-LINK \
--objective "Expose the magic-link request behavior through an HTTP endpoint." \
--why-now "The service is verified and now needs a route for clients." \
--context src/auth/routes.py \
--context src/auth/magic_link.py \
--constraint "Do not change token expiry." \
--verify "PYTHONPATH=. python3 -m unittest discover -s tests -v" \
--reference docs/specs/AUTH-MAGIC-LINK.goal.json \
--depends-on AUTH-ML-01 \
--priority 2 \
--risk 3 \
--value 5That is the CDAD loop: goal, design, packet, context, verify, progress, repeat.