Skip to main content

Install

npm install @boundary/contract zod

Define a contract

A contract is a schema + rules. The schema defines the shape. The rules define what “correct” means.
score-lead.ts
import { z } from "zod";
import { defineContract } from "@boundary/contract";

const schema = z.object({
  tier: z.enum(["hot", "warm", "cold"]),
  score: z.number().min(0).max(100),
  reason: z.string(),
});

const contract = defineContract({
  schema,
  rules: [
    // if tier is "hot", score must be above 70
    (lead) => lead.tier === "hot" ? lead.score > 70 : true,
    // reason is always required
    (lead) => lead.reason.length > 0 || "reason cannot be empty",
  ],
});
Rules are plain functions: (data) => true | string. Return true if the data is correct, or a string describing the violation.

Wrap your LLM call

Use contract.accept() to wrap your existing provider call. Your LLM code stays the same — Boundary wraps the acceptance boundary around it.
const result = await contract.accept(async (attempt) => {
  const res = await openai.responses.create({
    model: "gpt-4.1",
    input: [
      "Score this lead based on their recent activity",
      ...attempt.repairs,  // targeted fixes from prior failures
    ],
    text: { format: { type: "json_schema", schema } },
  });
  return res.output_text;  // RunFn must return a string
});
If the first attempt fails a rule, Boundary sends the specific violations back to the model and retries. The model fixes its own mistakes.

Use the result

if (result.ok) {
  // Guaranteed: valid JSON + all rules pass
  console.log(result.data);
  // { tier: "cold", score: 25, reason: "Low intent signals" }
} else {
  // All attempts failed — result includes why
  console.log(result.error);
}
result.ok is a discriminated union. When true, result.data is typed and guaranteed correct. When false, result.error explains what failed.

What just happened

Attempt 1 → { tier: "hot", score: 25, reason: "" }
             ✕ tier = "hot" requires score > 70
             ✕ reason cannot be empty
             ↻ violations sent back to model

Attempt 2 → { tier: "cold", score: 25, reason: "Low intent signals" }
             ✔ all rules pass
             ✔ ACCEPTED
The model returned valid JSON with wrong values. Boundary caught it, explained the violations, and the model self-repaired. Your application only saw the correct output.

Next steps

Contracts

How contracts work in detail

Rules

Writing effective domain rules

OpenAI guide

Full integration with OpenAI

Anthropic guide

Full integration with Anthropic