Skip to content

Verification & Validation Paradigm

Wave uses a two-layer V&V model to ensure pipeline outputs meet structural and behavioral requirements. Each layer operates at a different level of abstraction and catches different classes of problems.

Layer 1 — Contracts (Structural Validation)

The contract layer validates step output structure before dependent steps proceed. Contracts catch malformed artifacts early, preventing wasted work downstream.

Contract Types

Wave supports 11 contract types:

TypePurpose
json_schemaValidates output against a JSON Schema
typescript_interfaceValidates TypeScript compilation
test_suiteRuns a test command
markdown_specValidates markdown structure
formatChecks output format
non_empty_fileVerifies file exists and is non-empty
llm_judgeLLM evaluates output against criteria
source_diffVerifies meaningful code changes were made
agent_reviewDelegates validation to another agent session
event_containsValidates specific pipeline events occurred
spec_derived_testGenerates and runs tests from a specification

The first 8 types are created via NewValidator() (internal/contract/contract.go:96-119). agent_review uses ValidateWithRunner() instead, as it requires an adapter runner. spec_derived_test uses ValidateSpecDerived(). event_contains is handled by ValidateEventContains() in the executor.

Hard vs. Soft Validation

  • Hard (must_pass: true, default): Failure blocks pipeline progression. The step transitions to retrying or failed.
  • Soft (must_pass: false): Failure logs a warning but does not block. Useful for advisory checks like linting.

See the Contracts Guide for configuration details and examples.

Layer 2 — Gates (Outcome Validation)

The gate layer provides human or automated checkpoints before the pipeline continues. Gates validate outcomes rather than structure.

Gate Types

TypeCategoryPurpose
approvalHumanPauses for reviewer decision (approve/revise/abort)
timerAutomatedWaits for a specified duration
pr_mergeAutomatedPolls until a PR is merged or closed
ci_passAutomatedPolls until CI checks pass

Gate execution is dispatched via the Execute switch in internal/pipeline/gate.go:77-88.

Fix-Loop Termination

When gates and conditional edges create fix-loops (implement → test → fix → test → ...), three safety mechanisms prevent runaway execution:

  1. Per-step max_visits — Each step has a visit limit (default: 10). Exceeding it fails the pipeline.
  2. Circuit breaker — If a step fails with the same error 3 consecutive times (circuitBreakerWindow = 3), the loop terminates. Errors are normalized before comparison. (internal/pipeline/graph.go:425-452)
  3. Graph-level max_step_visits — An aggregate visit limit across all steps, enforced via EffectiveMaxStepVisits(). (internal/pipeline/graph.go:100-104)

See the Gates Guide for configuration details and the Graph Loops guide for loop configuration.

V&V Pipeline Flow

See Also

Released under the MIT License.