Agent Contract — standard and template
An agent contract is the binding version of a roster entry. The roster describes what an agent is; the contract states what a consumer may rely on, what happens when the agent can't comply, and what the producer must do before changing it.
The five dimensions are unchanged — Role, Skills, Context, Technology, Trigger — plus four sections a roster entry doesn't carry: Identity, Guarantees and limits, Acceptance tests, Change control. Convention is inherited: [insert x here] marks a genuine unknown, never a guess.
Naming follows the programme convention: Agent 1 … Agent n, System A … System n. Real names appear once, in the team key.
Why the extra four sections
A roster entry can be complete and still not be a contract. Three gaps close it:
A contract has one identity. Two entries with the same name and different scope are two contracts, or one contract used twice — never ambiguous. Without an ID and a version, downstream teams cannot say which version they built against.
A contract states failure, not only success. Success criteria describe the good path. A consumer integrating against an agent needs to know what arrives when the agent cannot meet them: an error, an empty set, a partial result with flags, or an escalation. Unstated failure output is where silent breakage lives.
A contract can be changed safely. Version rules, breaking-change definition, and who must be told. Otherwise every improvement is a potential outage for a consumer nobody remembered.
Section 0 — Identity
| Field |
Entry |
| Contract ID |
[TEAM-ROLE-NN — stable, never reused] |
| Agent ref |
[Agent n] |
| Version |
[major.minor] |
| Status |
[draft / active / deprecated] |
| Supersedes |
[contract ID and version, or "none"] |
| Producer owner |
[named person accountable for this agent behaving as written] |
| Consumer owners |
[named people or teams who rely on it] |
| Team |
[insert x here] |
| Instance of |
[shared contract ID this is a parameterised instance of, or "standalone"] |
| Last reviewed |
[date] |
Rule. If two agents share a name, they share a contract or they get different names. A contract used by more than one team is one contract with parameters — the parameters are listed here, not duplicated as separate entries.
Section 1 — Role
- Mission:
[one sentence — the problem it exists to remove]
- Owns:
[the narrowest true statement]
- Does not do:
[the boundary; this is enforceable, not aspirational]
- Upstream:
[contract IDs, or the trigger]
- Downstream:
[contract IDs, or the human role]
Section 2 — Skills
One block per skill. Every block carries five fields — the roster's four plus failure output.
Skill: [name]
- Input: [what arrives, and from whom]
- Output: [the artifact and its shape — reference the schema by ID, do not restate it]
- Method: [numbered steps at the level of what it does]
- Success criteria: [what must be true for a run to count as correct]
- Failure output: [what the consumer receives when success criteria cannot be met — error, empty set with reason, partial result with flags, or escalation to a named role. Never an unmarked partial result.]
Section 3 — Context and data rights
- Data accessed:
[system refs and exact scope]
- Data it must never reach:
[explicit — this is the line a negative test checks]
- Acts as:
[the requesting user / a service identity — determines whose permissions apply]
- Memory / state:
[none — stateless per run / what persists, where, and for how long]
- Retention:
[how long anything it stores is kept, and what deletes it]
- Escalation rule:
[what it flags rather than guesses]
- Dependencies:
[what blocks it, and what it blocks]
Section 4 — Technology
- Connection method:
[connector, API, or file access]
- Tools exposed:
[the named tools the agent may call, each with a one-line description of the capability it provides]
- Access level:
[read-only / write, own output only / write to shared location]
- Auth mechanism:
[insert x here]
- Rate limits / quotas:
[insert x here]
- Failure / retry behavior:
[attempts, backoff, and what happens after the last attempt]
- Technology opportunity:
[none identified / RAG / GraphRAG — with the reason]
Rule. Tools are reasonably abstract. Give the agent a small set of general capabilities it can combine toward the goal — not one hyper-specific tool per anticipated task. A specific tool encodes today's workflow; an abstract one survives the next requirement. The test: if every new task inside the declared scope needs a new tool, the tools are too narrow. Abstraction is bounded by the contract — the combined tool set must not grant reach beyond the data rights in Section 3, and each tool's access is still checked by the scope negative test in Section 7.
Configuration mechanism
- Where the configuration lives: [the file, stored object or console screen that holds this agent's instructions, tool list and model settings]
- What it holds: [instructions or prompt / tool and connector list / model and reasoning settings / attached skills or knowledge / memory settings — and what is set outside it]
- Under version control: [yes — repo and path / no — console-only]
- Versioning and pinning: [whether an edit produces a new version, and whether a run in flight or a consumer may pin to an earlier one]
- Promotion path: [how a change reaches production, and what is checked on the way]
- Who may change it: [named roles with edit rights, and the approval required]
- What differs per environment: [what legitimately varies — scope, credentials, model — and what must not]
Rule. The version in Section 0 and the change control in Section 8 are only as real as the mechanism named here. If the configuration has no versions, the contract has no version — and a consumer cannot say which behaviour it built against. Console-only is a permitted answer; it is recorded as one, and it makes every promise in Section 6 a promise about the configuration as it stood the last time somebody looked.
Section 5 — Trigger
- Fires on:
[insert x here]
- Schedule mechanism:
[owns its own schedule / piggybacks on an upstream contract / event-driven]
- Concurrency:
[how many runs may be in flight, and what prevents collision]
- Idempotency:
[whether re-running with the same inputs returns the same result, and what breaks that guarantee]
- Failure alerting:
[named role, channel, and time to acknowledge]
Section 6 — Guarantees and limits
The section a consumer reads before integrating. Written as promises, in the consumer's language.
A consumer may rely on:
- [insert x here — e.g., every returned item carries a source reference]
- [insert x here]
A consumer must not rely on:
- [insert x here — e.g., ordering is not stable between runs]
- [insert x here — e.g., results are not deterministic where retrieval is semantic]
- Expected latency:
[p50 / p95]
- Expected volume ceiling:
[per run and per period]
- Cost envelope per run:
[insert x here]
Section 7 — Acceptance tests
Every success criterion in Section 2 needs a test that could fail. A criterion with no test is an intention.
| # |
Tests |
Method |
Passes when |
| 1 |
[the success criterion] |
[how it is checked] |
[the observable result] |
| 2 |
Scope negative test |
Attempt access outside the declared scope |
Access is refused, and the refusal is logged |
| 3 |
Failure-path test |
Force the failure condition |
The declared failure output is returned, not a silent empty result |
- Test data location:
[insert x here]
- Run frequency:
[on every change / nightly / per release]
- Last run and result:
[insert x here]
Section 8 — Change control
- Breaking change means: a change to output shape, scope, identity, or any promise in Section 6. Breaking changes require a major version and written notice to every consumer owner in Section 0.
- Non-breaking change means: method, thresholds, prompt wording or performance, with Section 6 promises intact. Minor version.
- Notice period for breaking changes:
[insert x here]
- Deprecation: a contract is retired only after every consumer confirms migration. Record the date and the replacement contract ID.
- Change log:
[version — date — what changed — who approved]
Section 9 — Sign-off
| Role |
Name |
Date |
| Producer owner — the agent behaves as written |
[insert] |
[insert] |
| Consumer owner — the guarantees are sufficient to build against |
[insert] |
[insert] |
| Data owner — the scope in Section 3 is approved |
[insert] |
[insert] |
An unsigned contract is a draft, regardless of how complete it looks.
Worked example — Agent 1, scoped record retrieval
Identity. Contract ID T1-RETRIEVE-01 · version 0.3 draft · producer owner [insert] · consumers: Agent 4 (synthesizer) · instance of: standalone.
Role. Mission: be the single narrow path between System A and everything downstream, so nothing else touches it directly. Owns: raw retrieval of labelled records, nothing else. Does not do: interpret, filter beyond the label, or write back. Upstream: invoked by T1-SYNTH-04. Downstream: T1-SYNTH-04 only.
Skills — record retrieval.
- Input: a trigger event. No natural-language query — a scoped pull, not a search.
- Output: structured record list, schema [insert schema ID].
- Method: (1) connect via the connector. (2) query the scope. (3) return records unmodified.
- Success criteria: every labelled record returned; no records from other initiatives present.
- Failure output: on inconsistent labelling, returns an escalation object naming the ambiguity — never a partial set presented as complete. [insert what "inconsistent" means in practice]
Context. Data accessed: System A, [exact scope]. Never reaches: every other workspace in the tenant, and any write path. Acts as: [insert]. Memory: none — stateless per run. Escalation: flags to T1-SYNTH-04.
Guarantees. A consumer may rely on: completeness within the declared scope; every record unmodified from source. A consumer must not rely on: ordering, or freshness within a run if the source changes mid-run — see idempotency.
Acceptance tests. (1) Seeded base returns all labelled records and nothing else. (2) Negative test: a request for an out-of-scope workspace is refused and logged. (3) Failure path: with deliberately broken labelling, an escalation object is returned rather than a short list.
Open before Build: rate limits, retry behaviour, concurrency, idempotency guarantee, failure alerting recipient, and the configuration mechanism — the prototype is edited in a console and has no versions, so version 0.3 above names a document, not a deployed state. Six fields, each an operational commitment nobody has yet made.