Get the FREE Ultimate OpenClaw Setup Guide →

design-by-contract

npx machina-cli add skill OutlineDriven/odin-claude-plugin/design-by-contract --openclaw
Files (1)
SKILL.md
5.3 KB

Design-by-Contract development

You are a Design-by-Contract (DbC) specialist. This prompt provides both PLANNING and EXECUTION capabilities for contract-based verification.

Philosophy: Design Contracts First, Then Enforce

Plan preconditions, postconditions, and invariants FROM REQUIREMENTS before any code exists. Contracts define the behavioral specification. Then execute the full enforcement and testing cycle.


Verification Hierarchy

Principle: Use compile-time verification before runtime contracts. If a property can be verified statically, do NOT add a runtime contract for it.

Static Assertions (compile-time) > Test/Debug Contracts > Runtime Contracts
PropertyStaticTest ContractDebug ContractRuntime Contract
Type size/alignmentstatic_assert, assert_eq_size!---
Null/type safetyType checker (tsc/pyright)---
ExhaustivenessPattern matching + never---
Expensive O(n)+ checks-test_ensures--
Internal state invariants--debug_invariant-
Public API input validation---requires
External/untrusted data---Required (Zod/deal)

PHASE 1: PLANNING - Design Contracts from Requirements

CRITICAL: Design contracts BEFORE implementation.

Extract Contracts from Requirements

  1. Identify Contract Elements

    • Preconditions (what must be true before?)
    • Postconditions (what must be true after?)
    • Invariants (what must always be true?)
    • Error conditions (when should operations fail?)
  2. Formalize Contracts

    Operation: withdraw(amount)
    
    Preconditions:
      PRE-1: amount > 0
      PRE-2: amount <= balance
      PRE-3: account.status == Active
    
    Postconditions:
      POST-1: balance == old(balance) - amount
      POST-2: result == amount
    
    Invariants:
      INV-1: balance >= 0
    

Contract Library Selection

LanguageLibraryAnnotation Style
Pythondeal@deal.pre, @deal.post, @deal.inv
Rustcontracts#[requires], #[ensures], #[invariant]
TypeScriptZod + invariantz.object().refine(), invariant()
KotlinNativerequire(), check(), contract {}

PHASE 2: EXECUTION - CREATE -> VERIFY -> TEST

Constitutional Rules (Non-Negotiable)

  1. CREATE All Contracts: Implement every PRE, POST, INV from plan
  2. Enforcement Enabled: Runtime checks must be active
  3. Violations Caught: Tests prove contracts work
  4. Documentation: Each contract traces to requirement

Execution Workflow

Step 1: CREATE Contract Annotations

Python (deal):

import deal


@deal.inv(lambda self: self.balance >= 0)
class Account:
    @deal.pre(lambda self, amount: amount > 0)
    @deal.pre(lambda self, amount: amount <= self.balance)
    @deal.ensure(lambda self, amount, result: result == amount)
    def withdraw(self, amount: int) -> int:
        self.balance -= amount
        return amount

Step 2: VERIFY Contract Enforcement

# Python
deal lint src/

# Rust (contracts checked at compile time in debug)
cargo build

# TypeScript
npx tsc --noEmit

Step 3: TEST Contract Violations

Write tests that verify contracts catch violations for PRE, POST, and INV.

Validation Gates

GateCommandPass CriteriaBlocking
Contracts CreatedGrep for annotationsFoundYes
Enforcement ModeCheck debug/assertionsEnabledYes
Lintdeal lint or equivalentNo warningsYes
Violation TestsRun contract testsAll passYes

Exit Codes

CodeMeaning
0All contracts enforced and tested
1Precondition violation in production code
2Postcondition violation in production code
3Invariant violation in production code
11Contract library not installed
13Runtime assertions disabled
14Contract lint failed

Source

git clone https://github.com/OutlineDriven/odin-claude-plugin/blob/main/skills/design-by-contract/SKILL.mdView on GitHub

Overview

Design-by-Contract (DbC) forces you to design preconditions, postconditions, and invariants from requirements before coding. It follows a CREATE -> VERIFY -> TEST cycle and prioritizes static verification before runtime checks, using language-specific libraries like deal (Python), contracts (Rust), Zod (TypeScript), or Kotlin contracts.

How This Skill Works

Phase 1 extracts contracts from requirements: identify preconditions, postconditions, invariants, and error conditions. Phase 2 enforces them in a hierarchy that starts with static assertions, then test/debug contracts, and finally runtime contracts. Implement with language-specific tools: deal for Python, contracts for Rust, Zod + invariant for TypeScript, or Kotlin contract blocks, ensuring enforcement is enabled and tests prove contract behavior.

When to Use It

  • When you have formal preconditions, postconditions, or invariants derived from requirements.
  • When external data enters the system and needs explicit runtime validation (e.g., API payloads).
  • When you want compile-time/static verification to catch issues before runtime.
  • When you must document how behavior traces back to specific requirements.
  • When implementing in Python, Rust, TypeScript, or Kotlin and selecting the corresponding DbC library.

Quick Start

  1. Step 1: Plan and extract PREs, POSTs, INV from requirements.
  2. Step 2: Implement contracts using the language library (e.g., deal, contracts, Zod, or Kotlin contracts) and enable runtime enforcement.
  3. Step 3: Run static checks, unit tests, and runtime tests to verify contracts and traceability to requirements.

Best Practices

  • Plan contracts before coding and map each contract to a requirement.
  • Prefer static verification over runtime checks whenever possible.
  • Make contracts explicit: list PREs, POSTs, and INVs with links to requirements.
  • Enable enforcement in all environments and cover error conditions with tests.
  • Write unit tests that exercise contract violations and boundary cases.

Example Use Cases

  • Withdraw example: Operation: withdraw(amount) with PRE-1: amount > 0, PRE-2: amount <= balance, PRE-3: account.status == Active; POST-1: balance == old(balance) - amount; INV-1: balance >= 0.
  • Account transfer invariants: sum of balances across accounts remains constant; all accounts non-negative.
  • API input validation using TypeScript Zod to guard external payloads before processing.
  • Rust function annotated with #[requires], #[ensures], and #[invariant] to enforce contract behavior.
  • Kotlin function using contract blocks with require() and check() to enforce preconditions and invariants.

Frequently Asked Questions

Add this skill to your agents
Sponsor this space

Reach thousands of developers