---
name: agent-contract
description: Make sure to use this skill whenever you are about to implement something from a ticket, issue, Slack message, PR description, or a one-line ask - before writing any code. It scores how well the task is actually specified, quotes the evidence behind every finding, and names the decisions you would otherwise make silently on the author's behalf. Reach for it when a request feels thin, when you catch yourself about to guess at a requirement or invent a default, when someone says "just build X", and whenever the user asks whether a task is ready to hand over, wants a brief reviewed, or mentions an agent contract, delegation readiness, or checking a task before starting.
---

# Agent Contract

> You can only delegate what you have actually specified.

Most agent failures are not coding failures. The request left something out,
the agent picked something, and nobody noticed until review or production.
This skill finds what was left out **before** any code is written.

## The rule that makes this worth anything

**You never invent a score.** Your only job is to find evidence in the task
text and quote it. The arithmetic is fixed and published below. If you cannot
quote it, it is not there — and "not there" is a normal, expected answer, not
a failure to try harder.

Judge the text **as written**. Never infer what the author probably meant.
Their meaning is exactly the thing that did not survive the handoff.

## Procedure

### 1. Take the task exactly as given

Use the literal text of the request. If the user pointed at an issue or file,
read it and use that text. Do not paraphrase it first — paraphrasing silently
adds the specificity you are trying to measure.

### 2. Answer 18 questions with quotes

For each signal below, answer yes or no. **Every yes needs a verbatim quote
copied from the task text.** Before you accept a quote, check the characters
actually appear in the text. If they do not, the answer is no.

Do not reason out loud through all eighteen. Answer them.

### 3. Score it

Add the weights of the satisfied signals within each axis. Each axis totals
100. Delegation readiness is the mean of the four axes, rounded to the
nearest 5. Do not round to a finer number — the instrument is not that
accurate.

### 4. Report, then stop

Print the contract (format below). If any judgment call is unsigned,
**stop and ask** rather than implementing. That is the entire point: the
unsigned decisions are the ones that are not yours to make.

## The signals

### Intent — do we know what "done" looks like?

| | Signal | w | Yes when the text… |
|---|---|--:|---|
| I1 | goal_stated | 35 | names a specific outcome or capability to be produced |
| I2 | behaviour_specified | 30 | describes observable behaviour, not just a noun phrase ("users can sign in with Google", not "add auth") |
| I3 | scope_bounded | 20 | says what is in or out of scope |
| I4 | actor_identified | 15 | says who or what the change is for |

### Verification — could a third party tell whether it worked?

| | Signal | w | Yes when the text… |
|---|---|--:|---|
| V1 | acceptance_criteria | 30 | states a condition that would make the work done |
| V2 | observable_outcome | 25 | names something concrete you could inspect to confirm success — a status code, a threshold, a metric, a log, a screen state. The feature existing is not itself evidence |
| V3 | failure_defined | 20 | says what must not happen, or what breaking looks like |
| V4 | tests_referenced | 15 | mentions tests, existing or new |
| V5 | rollback_or_recovery | 10 | mentions rollback, migration safety, or reversibility |

### Context — does the agent know the system it is changing?

| | Signal | w | Yes when the text… |
|---|---|--:|---|
| C1 | system_named | 25 | names where the work happens — a service, repo, file, endpoint, screen, or feature area someone could go and find. Informal names count ("the settings page", "checkout"). Only a whole-product reference with no narrowing ("the app") fails |
| C2 | current_state_described | 25 | describes how the thing works today |
| C3 | invariants_stated | 20 | states something that must keep working |
| C4 | constraints_stated | 20 | states a limit the finished work must respect — a performance target, size or time budget, deadline, or regulation. "must fit in a 90-second build" bounds the solution; "poll every 5 seconds" is the feature being built |
| C5 | dependencies_identified | 10 | names an external system, library, or team |

### Judgment — have the human-only decisions been made?

| | Signal | w | Yes when the text… |
|---|---|--:|---|
| J1 | business_rules_specified | 30 | states a decision that is a product or policy call, not a technical one |
| J2 | decision_authority_clear | 30 | says what the agent may decide alone versus must ask about |
| J3 | tradeoffs_acknowledged | 20 | weighs one option against another |
| J4 | ambiguity_flagged | 20 | explicitly names an open question |

## Calling the close ones

These rulings decide most of the disagreements. They come from hand-labelling
thirty real tickets, and without them two careful readers score the same text
differently.

- **A complaint is not a description.** "The app is slow" says something is
  wrong, not how it works today. `current_state_described` is no.
- **A constraint bounds the solution; it is not the thing being built.** "Must fit
  a 90-second build", "before the audit closes" are limits. "Poll every 5
  seconds" and "give them a 14-day trial" are the feature itself, and so is
  "scalable" — which bounds nothing at all.
- **Behaviour that must survive is C3, not C4.** "Must stay backwards
  compatible" is an invariant. "p99 must stay under 200ms" is a constraint,
  because it has a number attached.
- **Naming the whole product is not naming a system.** "The app", "our
  frontend", "the web app" all fail `system_named`. "The settings page",
  "checkout", "billing-api", "test/invoices_test.go" all pass.
- **One clause can satisfy two signals.** "Existing password login must keep
  working" is both an invariant and a statement of what breaking looks like.
  Count it for both; that is not double-counting, it is one sentence doing two
  jobs.
- **A stated value is a decision.** "Change the session timeout to 8 hours"
  settles a policy question rather than a technical one, so
  `business_rules_specified` is yes.
- **Size is not specification.** "Split the monolith into services" is months
  of work and one satisfied signal. A long rambling message can score near
  zero and three precise sentences can score seventy. Never let length, tone
  or seniority move a score.
- **Naming a team is naming a dependency.** "Compliance asked for it" and
  "marketing has a script that hits it" both satisfy
  `dependencies_identified`.
- **Uncertainty said out loud counts.** "I am not sure", "I have not decided
  yet" satisfy `ambiguity_flagged`. Silence does not — an author who mentions
  no open questions is implying there are none.

## Bands

| Score | Band | What it means for you |
|---|---|---|
| 80–100 | Delegable | Proceed. You are not inventing decisions. |
| 60–79 | Delegable with review | Proceed, but flag the gaps as you go. |
| 40–59 | Agent fills the gaps | Ask about the unsigned judgment calls first. |
| 0–39 | Agent decides for you | Do not start. Ask. |

Band names describe what *you* will do with the task as written, not the
quality of the author's work. A thin ticket is normal. Roughly half of real
engineering tickets land in the bottom band.

## Output

```
AGENT CONTRACT — <score>/100, <band>

Intent         ████████░░  80
Verification   ████░░░░░░  40
Context        ██████░░░░  60
Judgment       ██░░░░░░░░  20

INTENT
  <one line: what will exist afterwards that does not now>

MUST STAY TRUE
  <each invariant found, quoted>
  (none stated) — if so, say so plainly

VERIFICATION
  <each check found, quoted>
  (none stated) — if so, say so plainly

CONTEXT I STILL NEED
  <what you would have to read or be told before starting>

UNSIGNED — I will decide these unless you tell me otherwise
  <one line per absent Judgment signal, and per absent invariant>

ASSUMPTIONS I WOULD MAKE
  <the specific choice you would make for each, so it can be corrected>
```

Keep it short. One line per item. Quote, do not summarise.

Then either start work, or ask about the unsigned items — per the band.

## Notes

- Absence is the finding. A task that scores 20 is not a broken task; it is a
  conversation that has not happened yet.
- Never soften a score because the author is present, senior, or in a hurry.
  A rubric that flatters is worthless.
- If you find yourself wanting to award a signal on the strength of what was
  clearly intended, that is exactly the signal to mark absent.

The full specification, the hand-labelled fixtures, and the measured
agreement figures live with the project. This skill is one implementation of
that specification; the web analyser is another.
