Phase 1 introduces Tool Builder-authored Tool contracts as expression-only metadata.
Both Agent.for(...) and delegate(...) accept optional contract fields:
purposedeliverableacceptancefailure_policy
delegate(...) example:
pdf_tool = tool_builder.delegate(
"pdf tool",
purpose: "produce a PDF artifact for downstream download",
deliverable: { type: "object", required: %w[path mime bytes] },
acceptance: [{ assert: "mime == 'application/pdf'" }, { assert: "bytes > 0" }],
failure_policy: { on_error: "fallback", fallback_role: "archiver" }
)Agent.for(...) example:
pdf_tool = Agent.for(
"pdf tool",
purpose: "produce a PDF artifact for downstream download",
deliverable: { type: "object", required: %w[path mime bytes] },
acceptance: [{ assert: "mime == 'application/pdf'" }, { assert: "bytes > 0" }],
failure_policy: { on_error: "fallback", fallback_role: "archiver" }
)Merge rule:
delegation_contracthash only -> use hash.- field args only -> build contract from fields.
- both -> merge, with field args winning per key.
- Contract fields are injected into Tool prompts.
- Contract fields are logged for traceability (
contract_purpose, etc.) withcontract_source(none,hash,fields,merged). - Runtime does not enforce validation yet.
- Tool Builder remains responsible for evaluating Tool output quality.
Validation design is intentionally deferred to a later phase.