Skip to main content
A score means little until you know what doing nothing scores, and whether each task could be passed at all. sandtable gives you both before you spend anything on model calls.

The noop baseline

--agent noop never calls a tool and answers every message with “Sorry, I can’t help with that right now.” With a scripted user, it runs offline:
It passes exactly the tasks whose success is “nothing happened”: refusals, handoffs that only need a polite answer, and missing-information cases. On the freight example it scores 32%:
So read any agent’s score on this suite against that floor, not against zero. The per-tag scores show where the floor comes from: noop gets 82% on refusal for free, and nothing on the hard tier, whose refusals all require a lookup or a handoff.
Make refusal tasks discriminate. “Nothing was booked” is passed by an agent that never does anything. Add what a correct refusal requires, such as called: [verify_carrier] (it looked the carrier up before declining), and the do-nothing agent fails it. See Write tasks that discriminate.

sandtable lint

lint proves, without any model call, that each task is worth grading: A task that expects a write but has no reference gets a warning, since its solvability is unproven. reply_includes expectations are skipped in the replay, because a replay has no messages.
solvable ? means the task has no reference to replay. It exits 1 on any error, so it belongs in CI next to validate --strict.

Why both matter

Lint catches broken tasks; noop shows how much of a suite is easy. Drafted suites need both: in the live init run, lint flagged both drafted tasks as not ready because a tool did not yet model a side effect. Without it, the first model-backed run would have failed those tasks for a reason that had nothing to do with the agent.