sandtable plugin gives Claude Code three skills and one subagent that know sandtable’s workflow. They draft a domain from a customer’s documents, make it trustworthy, run it against your agent and work out why trials failed. You describe what you want; Claude runs the CLI and shows you each decision that needs a person.
Install
- In a Claude Code session
- From your shell
sandtable. /plugin install opens the plugin’s details, where you choose a scope. On Claude Code v2.1.275 or later, one command does both steps: /plugin install sandtable --marketplace sandtable-ai/sandtable./sandtable: in a session to check: the skills appear as /sandtable:drafting-a-domain, /sandtable:writing-good-tasks and /sandtable:running-and-reading-results.
- For a team, install at project scope:
claude plugin install sandtable@sandtable --scope projectrecords the plugin in.claude/settings.json, which you commit. Each collaborator runs the same command once to download it. - Updates. Claude Code doesn’t auto-update third-party marketplaces by default. Run
claude plugin update sandtable@sandtable, or turn on auto-update for thesandtablemarketplace in the Marketplaces tab of/plugin. - What it needs. The skills run the CLI as
npx sandtable-ai <command>, which uses the project’s copy whensandtable-aiis a dependency. The machine needs Node.js 20 or later. Commands that call a model needANTHROPIC_API_KEY, or AWS credentials with--provider bedrock.
sandtable-ai npm package, and its version matches the CLI release it was written for. See Claude Code’s plugin docs for scopes and the /plugin panel.
What’s inside
Claude loads a skill when the conversation needs it, from its description. You can also call one by name, such as/sandtable:drafting-a-domain.
Each skill loads its reference files only when it needs them. They hold the spec cheatsheet, how to resolve review notes, more task patterns, the
results.json shape with jq queries, and the failure-attribution procedure.
The failure-triager subagent reads failing trials outside the main conversation, so a run with many failures doesn’t fill your context with transcripts.
- Input: the path to
results.jsonand the domain directory. - Method: it lists the failing trials with
jqand reads each transcript up to the first divergence from the SOP or the task. It attributes each failure to exactly one owner (agent,simulated user,task specorharness), quoting the event as evidence, and groups trials that share a root cause. - Report:
- a summary line
- a table of task, trial, owner, failed check, evidence and proposed fix
- counts per owner
- concrete edits
- the
runcommand that would confirm them
- Limits: it only reads. It has
Read,Grep,GlobandBash, doesn’t edit files, and doesn’t run anything that calls a model. It never proposes deleting a failing task, loosening an expectation the SOP supports, or lowering k or--fail-under.
What runs without asking
The skills ask before any command that calls a model, because it needs keys and costs money:A worked session
This session drafts a domain from the fictional freight brokerage’s sources that ship in the repository,examples/freight/source/openapi.yaml and examples/freight/policy.md, copied into discovery/. Every output below is from a real offline run.
1
Draft the domain
Draft a sandtable domain from discovery/openapi.yaml and discovery/sop.md into ./sandtable.Claude loads
drafting-a-domain and runs the free, deterministic OpenAPI step:review: pending. See Draft a domain with init.2
Resolve the review notes
Walk me through what still needs review.
init could not encode:check that the load is available, and an update op that sets it to booked. It accepts an item only after you agree. It never bulk-accepts to make validate --strict pass: an accepted item is a claim about the customer’s rules. Then it seeds the world, gives every write task a reference, and lints:lint reads:3
Run it offline
Run it offline first: the do-nothing baseline, then the naive demo agent.Claude loads
running-and-reading-results. Both runs are free. The rest of this session uses examples/freight, the reviewed version of the same sources, which ships with rule-based demo agents.pass^1 32.0%: the share of the suite that rewards doing nothing. The naive agent, which books whatever it is asked to, scores pass^1 10.0%:4
Run it against your agent
Now run it against my agent at http://localhost:8787/step.Claude checks the wiring first with the scripted caller. Then it tells you how many trials a run with the Claude caller means (tasks × k) and asks before starting it:
5
Triage the failures
Why did those trials fail?With more than a few failing trials, Claude hands
results.json and the domain directory to failure-triager. It gets back the owner table, the counts and the proposed edits. It changes the agent’s prompt or code for failures owned by the agent, and proposes a YAML change citing the SOP for task-spec failures, which you approve. Then it reruns the affected tasks at the same k:Tips and limits
- Keep data fictional. The skills tell Claude not to paste customer documents into its own prompts or commit them to a public repository.
init --transcriptsscrubs emails, phone numbers and card numbers locally before anything is sent. Seed rows, names and IDs in a domain should be invented. - Review drafted items before trusting a score. While anything is
review: pending, the terminal and the report mark the run provisional, andvalidate --strictfails. See the review workflow. - Read failing trials, not only the score. The simulated caller can be wrong too. The skills attribute every failure before changing the agent or the suite.
- The skills trust
--helpover themselves. If a flag in a skill is rejected, Claude checksnpx sandtable-ai <command> --help. The CLI reference lists every flag. - Other coding agents. The skills are plain
SKILL.mdfiles inplugin/skills, so agents that read Agent Skills can use them without Claude Code. Agents that read docs can use the domain spec, the CLI reference and theresults.jsonschema. Each page is also available as Markdown, by adding.mdto its URL, andsandtable.dev/llms-full.txtholds the whole site in one file.