Skip to content

Contract Types Reference

Contracts validate step output before dependent steps begin. This page documents all available contract types.

Quick Reference

TypeValidatesUse When
test_suiteCommand exit codeVerifying code compiles and tests pass
json_schemaJSON structureEnsuring data format and required fields
typescript_interfaceTypeScript compilesValidating generated type definitions
markdown_specMarkdown structureChecking documentation format
templateStructured templatesValidating JSON/Markdown/YAML templates (experimental)
formatDomain-specific formatsValidating GitHub issues, PRs, analysis outputs (experimental)

test_suite

Run a command and validate exit code.

yaml
handover:
  contract:
    type: test_suite
    command: "npm test"

Use when: Verifying implementation correctness through tests.

Full Configuration

yaml
handover:
  contract:
    type: test_suite
    command: "go test ./... && go vet ./..."
    dir: project_root
    must_pass: true
    on_failure: retry
    max_retries: 3

Fields

FieldRequiredDefaultDescription
commandyes-Shell command to execute
dirnoworkspaceWorking directory: project_root, absolute path, or relative to workspace
must_passnotrueWhether failure blocks progression
on_failurenoretryretry or halt
max_retriesno2Maximum retry attempts

Working Directory

By default, test_suite commands run in the step's workspace directory. Since workspaces are ephemeral and isolated, commands like go test ./... will fail if they expect project files (e.g., go.mod).

Use dir to control where the command runs:

ValueResolves to
(empty)Step workspace (default)
project_rootGit repository root (git rev-parse --show-toplevel)
/absolute/pathUsed as-is
relative/pathRelative to workspace

Examples

Go project (run tests at project root):

yaml
handover:
  contract:
    type: test_suite
    command: "go build ./... && go test ./..."
    dir: project_root

Node.js project:

yaml
handover:
  contract:
    type: test_suite
    command: "npm test"

Python project:

yaml
handover:
  contract:
    type: test_suite
    command: "pytest"

Multi-command validation:

yaml
handover:
  contract:
    type: test_suite
    command: ".wave/scripts/validate.sh"

json_schema

Validate JSON output against a JSON Schema.

yaml
handover:
  contract:
    type: json_schema
    schema_path: .wave/contracts/analysis.schema.json
    source: .wave/output/analysis.json

Use when: Ensuring structured output with specific fields and types.

Full Configuration

yaml
handover:
  contract:
    type: json_schema
    schema_path: .wave/contracts/analysis.schema.json
    source: .wave/output/analysis.json
    must_pass: true
    on_failure: retry
    max_retries: 2

Fields

FieldRequiredDefaultDescription
schema_pathyes-Path to JSON Schema file
sourceyes-Path to JSON file to validate
must_passnotrueWhether failure blocks progression
on_failurenoretryretry or halt
max_retriesno2Maximum retry attempts

Example Schema

.wave/contracts/analysis.schema.json:

json
{
  "$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", "minLength": 10 }
  }
}

Common Patterns

Navigation output:

json
{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "type": "object",
  "required": ["files", "patterns", "summary"],
  "properties": {
    "files": { "type": "array", "items": { "type": "string" } },
    "patterns": { "type": "array", "items": { "type": "string" } },
    "summary": { "type": "string" }
  }
}

Task list output:

json
{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "type": "object",
  "required": ["tasks"],
  "properties": {
    "tasks": {
      "type": "array",
      "minItems": 1,
      "items": {
        "type": "object",
        "required": ["task"],
        "properties": {
          "task": { "type": "string" },
          "priority": { "type": "string", "enum": ["high", "medium", "low"] }
        }
      }
    }
  }
}

typescript_interface

Validate that generated TypeScript compiles successfully.

yaml
handover:
  contract:
    type: typescript_interface
    source: .wave/output/types.ts

Use when: Ensuring generated TypeScript definitions are valid.

Full Configuration

yaml
handover:
  contract:
    type: typescript_interface
    source: .wave/output/types.ts
    validate: true
    must_pass: true
    on_failure: retry
    max_retries: 2

Fields

FieldRequiredDefaultDescription
sourceyes-Path to TypeScript file
validatenotrueRun type checking
must_passnotrueWhether failure blocks progression
on_failurenoretryretry or halt
max_retriesno2Maximum retry attempts

Behavior

  1. Checks TypeScript syntax
  2. If tsc is available, runs full type checking
  3. If tsc is unavailable, performs syntax-only validation

Examples

Type definitions:

yaml
steps:
  - id: generate-types
    persona: craftsman
    exec:
      type: prompt
      source: "Generate TypeScript interfaces for the API"
    output_artifacts:
      - name: types
        path: .wave/output/api.types.ts
    handover:
      contract:
        type: typescript_interface
        source: .wave/output/api.types.ts

markdown_spec

Validate Markdown document structure.

yaml
handover:
  contract:
    type: markdown_spec
    source: .wave/output/spec.md

Use when: Ensuring documentation follows required format.

Full Configuration

yaml
handover:
  contract:
    type: markdown_spec
    source: .wave/output/spec.md
    must_pass: true
    on_failure: retry
    max_retries: 2

Fields

FieldRequiredDefaultDescription
sourceyes-Path to Markdown file
must_passnotrueWhether failure blocks progression
on_failurenoretryretry or halt
max_retriesno2Maximum retry attempts

Validation Checks

  • Valid Markdown syntax
  • Required sections present (configurable)
  • Proper heading hierarchy

Examples

Specification document:

yaml
steps:
  - id: specify
    persona: philosopher
    exec:
      type: prompt
      source: "Create a feature specification"
    output_artifacts:
      - name: spec
        path: .wave/output/spec.md
    handover:
      contract:
        type: markdown_spec
        source: .wave/output/spec.md

template

Validate structured templates with required fields and constraints. Supports JSON, Markdown, and YAML formats.

yaml
handover:
  contract:
    type: template
    source: .wave/output/template.json

Use when: Ensuring generated templates contain required fields and meet format constraints.

Status: Experimental. Supports required field checking, min/max length constraints, pattern matching, and enum validation.


format

Production-ready format validation for domain-specific outputs like GitHub issues, pull requests, and code analysis.

yaml
handover:
  contract:
    type: format
    source: .wave/output/issue.md

Use when: Validating that generated content matches expected domain formats (e.g., GitHub issue structure, PR descriptions).

Status: Experimental. Infers format type from content and applies domain-specific validation rules including placeholder detection.


Failure Handling

Retry Behavior

When on_failure: retry:

  1. Step state changes to retrying
  2. Fresh workspace is created
  3. Step re-executes from scratch
  4. Validation runs again
  5. After max_retries, step fails
yaml
handover:
  contract:
    type: json_schema
    schema_path: .wave/contracts/output.schema.json
    source: .wave/output/data.json
    on_failure: retry
    max_retries: 3

Halt Behavior

When on_failure: halt:

  1. Step immediately fails
  2. Pipeline stops
  3. Error includes validation details
yaml
handover:
  contract:
    type: test_suite
    command: "npm test"
    on_failure: halt

Advisory Contracts

Use must_pass: false for warnings that don't block:

yaml
handover:
  contract:
    type: test_suite
    command: "npm run lint"
    must_pass: false

Validation runs and logs results, but step completes regardless.


Chained Validation

Use a shell script for multiple validation steps:

yaml
handover:
  contract:
    type: test_suite
    command: ".wave/scripts/validate-all.sh"

.wave/scripts/validate-all.sh:

bash
#!/bin/bash
set -e

echo "Validating JSON schema..."
npx ajv validate -s .wave/contracts/output.schema.json -d .wave/output/data.json

echo "Running tests..."
npm test

echo "Checking TypeScript..."
npx tsc --noEmit .wave/output/types.ts

echo "All validations passed"

Contract Organization

Recommended directory structure:

.wave/
├── contracts/
│   ├── navigation.schema.json
│   ├── specification.schema.json
│   ├── task-list.schema.json
│   └── review.schema.json
├── scripts/
│   └── validate.sh
└── pipelines/
    └── gh-pr-review.yaml

Debugging Failures

View contract validation errors:

bash
wave logs run-abc123 --errors

Output:

[14:32:15] contract_failure  analyze  json_schema
  Error: Missing required property 'summary'
  File: .wave/output/analysis.json
  Schema: .wave/contracts/analysis.schema.json

Check audit logs for details:

bash
cat .wave/traces/run-abc123.jsonl | grep contract

Next Steps

Released under the MIT License.