The rows
A spec needs one row per thing you judge, and a stable id for each row. hunch uses the id to match answers, reviews and diffs across runs. Here each row is a shell command a coding agent is about to run:model names the engine that answers. source can also read coding-agent sessions (traces(<glob>), one row per command with view: commands) or call a Python function (py(rows.py:load)).
What the model sees
state lists the columns sent with each question. Include what a careful person needs to decide. Extra columns cost tokens and may distract from the evidence that matters.
command is what runs. request says what the developer asked for, so an expected deletion reads differently from a surprising one. cwd is the working folder; without it, the model cannot tell whether rm -rf build stays inside the project.
To remove secrets or shorten long columns before they are sent, see redact and clip in the spec reference.
The question
The model never sees the question’s name. To it,destroys means nothing, while “Would running command delete, overwrite or reset files in a way that would be hard to undo?” means everything. Write instructions as the full question, and refer to the columns by name in backticks.
Use criteria to describe the boundary between answers. Two careful people may disagree about “hard to undo”; the criteria make your intended boundary explicit.
noul: a yes/no condition. Its output includes the probability of yes; 0.5 means the model gives yes and no similar weight, not that a command is “somewhat destructive”.choice: exactly one option applies, such as what a command is mainly for:build,test,inspect,install. Addnone: <when>for rows that fit no option; without it, the model must pick one of yours, and it will pick one confidently.score: a position on an ordered scale.criteriais a list of levels, each described as a concrete situation.multi: any number of options can apply. hunch asks one yes/no question per option.
destroys and sends_out, and a guard that stops a command if either says yes is a rule in your code, not a question for the model.
How you will know it is right
If your data has an answer key, name its column ingold. Set act, the confidence below which a person should look. Put thresholds under tests, and hunch test fails when accuracy drops below them.
gold out. Review a random sample, then test can estimate accuracy on those reviewed rows. See Review.
Put important known cases into the spec as examples. test checks those cases on each run, even if the average looks good:
Check it before it costs anything
lint catches mistakes before any request is sent. Here, state lists comand instead of command, and lint also notices that the examples no longer supply every state column:
compile prints for the first row. It is what the model will see for that row. If you could not answer the question from it, add the missing context before running the sample.
Start small
The first version of a question is rarely the best one, and every row asked under a changed question is paid for again. So run a sample first (hunch run command_guard.yml --sample 50 asks about the same 50 rows every time, and leaves the full table alone), review twenty rows, and test before you run everything. Change a spec shows how to compare versions.