contract.accept(), return the provider’s raw text, and only continue with result.data when the contract accepts.
Install the Boundary skill before asking an AI coding agent to add this pattern.
Before Boundary
A typical structured-output flow looks like this:Add a contract near the workflow
Keep the contract close to the feature it protects:Wrap the provider call
Insideaccept(), call your provider the same way you already do. Include attempt.instructions and spread attempt.repairs into later attempts.
Gate the side effect on result.ok
Only accepted data should reach the system Boundary is protecting.
result.error.attempts.at(-1)?.cleaned to your database as a fallback. The whole point of the boundary is that rejected data does not enter the application path.
Write repair-friendly rule messages
A good rule failure tells the model what was wrong and what would satisfy the rule.- Weak
- Useful
Start with local logging
Usedebug: true or createConsoleLogger while you are integrating:
ContractLogger for your own metrics or the hosted SDK for dashboard traces.
Common integration mistakes
| Mistake | Fix |
|---|---|
Returning parsed JSON from the RunFn | Return the raw provider text and let Boundary parse it |
Forgetting attempt.repairs | Spread repair messages into retry prompts |
Treating rejected cleaned data as a fallback | Send rejected runs to review or fail the request |
| Writing rules that call a database or API | Fetch that context before the contract; keep rules synchronous |
| Using vague rule failures | Include the actual value and expected condition |
Next steps
Local development
Debug the contract before production
OpenAI integration
Provider-specific OpenAI example
Anthropic integration
Provider-specific Claude example
Production observability
Send accepted and rejected runs to the dashboard