Contracts Guide
Handover contracts validate step output before dependent steps begin. They catch malformed artifacts early, preventing wasted work downstream.
What is a Contract?
A contract validates that a step produced correct output. Contracts can check:
- Structure - JSON schema compliance
- Types - TypeScript compilation
- Behavior - Test suite results
Configuration
Contracts are defined in a step's handover section:
steps:
- id: navigate
handover:
contract:
type: json_schema
schema_path: .wave/contracts/navigation.schema.json
source: .wave/output/analysis.json
on_failure: retry
max_retries: 2| Field | Default | Description |
|---|---|---|
type | - | json_schema, typescript_interface, test_suite, markdown_spec, format, non_empty_file, llm_judge, source_diff, agent_review, event_contains, or spec_derived_test |
schema_path | - | Schema file path (for json_schema) |
source | - | File to validate |
command | - | Test command (for test_suite) |
dir | workspace | Working directory for test_suite: project_root, absolute, or relative |
must_pass | true | Whether failure blocks progression |
on_failure | retry | Action: retry or halt |
max_retries | 2 | Maximum retry attempts |
Contract Types
JSON Schema
Validates output structure:
handover:
contract:
type: json_schema
schema_path: .wave/contracts/navigation.schema.json
source: .wave/output/analysis.jsonExample schema:
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"type": "object",
"required": ["files", "summary"],
"properties": {
"files": {
"type": "array",
"items": {
"type": "object",
"required": ["path", "purpose"],
"properties": {
"path": { "type": "string" },
"purpose": { "type": "string" }
}
}
},
"summary": { "type": "string" }
}
}TypeScript Interface
Validates generated TypeScript compiles:
handover:
contract:
type: typescript_interface
source: .wave/output/types.ts
validate: trueIf tsc is unavailable, degrades to syntax-only checking.
Test Suite
Validates by running tests:
handover:
contract:
type: test_suite
command: "go test ./..."
dir: project_root
must_pass: true
max_retries: 3Use dir: project_root when the command needs project files (like go.mod). Without it, the command runs in the ephemeral workspace directory.
Non-Empty File
Validates that the artifact file exists and is not empty. Useful as a lightweight check that a step produced output.
handover:
contract:
type: non_empty_file
source: .wave/output/result.mdNo additional configuration fields are required beyond type and source.
LLM Judge
Uses an LLM to evaluate the artifact against criteria specified in a prompt. The LLM reads the artifact content and returns a pass/fail judgment.
handover:
contract:
type: llm_judge
source: .wave/output/plan.md
prompt: "Does this plan address all acceptance criteria from the issue?"
model: balanced| Field | Default | Description |
|---|---|---|
prompt | - | Evaluation criteria for the LLM judge |
model | cheapest | Model tier (cheapest, balanced, strongest) or a specific model identifier |
Source Diff
Validates that the step produced meaningful source code changes by checking the git diff. Catches the failure mode where a step claims success but made no actual changes.
handover:
contract:
type: source_diff
glob: "*.go"
min_files: 1| Field | Default | Description |
|---|---|---|
glob | (all files) | Glob pattern to filter which changed files count |
min_files | 1 | Minimum number of qualifying changed files |
Agent Review
Delegates validation to another agent session using an adapter runner. Unlike other contract types, agent_review does not use NewValidator — the executor calls ValidateWithRunner() instead.
handover:
contract:
type: agent_review
source: .wave/output/implementation.md
prompt: "Review this implementation for security issues"Event Contains
Validates that specific pipeline events occurred during step execution. Matches events by state and optional message substrings. Used in Wave's own default ontology pipelines.
handover:
contract:
type: event_contains
events:
- state: ontology_warn
contains: "delivery"| Field | Default | Description |
|---|---|---|
events | - | List of event patterns to match |
events[].state | - | Required event state to match (e.g., ontology_warn) |
events[].contains | (any) | Optional substring the event message must include |
Spec-Derived Test
Generates and runs tests derived from a specification document. Like agent_review, this type requires an adapter runner — NewValidator returns nil and the executor calls ValidateSpecDerived() instead.
handover:
contract:
type: spec_derived_test
source: .wave/output/spec.md
test_dir: .wave/output/tests/Failure Handling
Retry Behavior
When on_failure: retry:
- Step transitions to
retrying - Re-executes with fresh context
- Validates again
- After
max_retriesfailures, transitions tofailed
Halt Behavior
When on_failure: halt:
- Step immediately fails
- Pipeline stops
- Error includes validation details
Optional Contracts
Use must_pass: false for advisory checks:
handover:
contract:
type: test_suite
command: "npm run lint"
must_pass: false # Log but don't blockCommon Patterns
Navigation Contract
- id: navigate
output_artifacts:
- name: analysis
path: .wave/output/analysis.json
handover:
contract:
type: json_schema
schema_path: .wave/contracts/navigation.schema.json
source: .wave/output/analysis.jsonImplementation Contract
- id: implement
handover:
contract:
type: test_suite
command: "go build ./... && go test ./..."
dir: project_root
max_retries: 3Chained Validation
Use a script for multiple checks:
handover:
contract:
type: test_suite
command: ".wave/scripts/validate.sh"#!/bin/bash
set -e
npx ajv validate -s schema.json -d output.json
npm testSchema Organization
.wave/
├── contracts/
│ ├── navigation.schema.json
│ ├── specification.schema.json
│ └── implementation.schema.json
└── pipelines/
└── feature-flow.yamlDebugging Failures
Check audit logs:
cat .wave/traces/<pipeline-id>.jsonl | jq 'select(.type == "contract_failure")'Related Topics
- Pipeline Schema Reference - Contract field reference
- Pipelines Guide - Using contracts in pipelines
See Also
- Validation Philosophy — Why contracts exist and how they fit the V&V model
- V&V Paradigm Guide — Unified three-layer verification and validation model