antithesis-debug
Skill304 starsChanged 18 days agoApache-2.0View on GitHub
Run a bash script inside an Antithesis run at a chosen moment with `snouty runs exec`, from the terminal and without a browser. Use it for scripted forensics on a run: process and container inspection, on-disk evidence, gdb attach, and general debugging. Covers command usage, the live-session requirement, common workflows and errors, and how virtual time and perturbation limit what a debugger can see.
We split this skill into the rules it gives an agent
22 rules. About 0 are common, 10 are distinctive, and 12 are very specific to this project.
≈0
Common · estimate
Many files like this have a rule of this kind.
≈10
Distinctive · estimate
This author's own choices. Worth a look.
12
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Distinctive: line 30
Use a debugging session if you want to avoid these kinds of false positives.
- Very specific: line 35
DO NOT PROCEED if snouty is not installed.
- Very specific: line 36
DO NOT PROCEED if snouty is older than 0.8.0, the first release where runs exec is stable.
- Distinctive: line 53
If the user gives a debugging-session URL, that session may already be running.
- Very specific: line 74
Use --source-run-id <run> for the first command because the moment isn't warm yet.
- Distinctive: line 76
If exec answers 404 or "Moment not warm", the session is still loading.
- Very specific: line 82
If the user didn't give you a moment, read references/moments.md for where to find one.
- Distinctive: line 84
If you can't pin down both an input hash and a vtime from a clear source, ask the user rather than guessing.
- Very specific: line 109
Use --container over podman exec inside the script to run a command on a single container.
- Very specific: line 118
Don't use --container and run on host, if you need a snapshot across multiple containers.
- Very specific: line 152
Always save --events output to a file.
- Distinctive: line 165
After one exec with a source succeeds, that moment stays warm in the session.
- Distinctive: line 183
Always ask the user before canceling any run or debugging session, even when you think you have everything you need.
- Distinctive: line 184
Make sure you are completely done with a run or debugging session before canceling, as if you want to run more commands you will have to …
- Distinctive: line 202
No debugging session is needed.
- Distinctive: line 255
If necessary give the user the moment, the script, and the relevant output, so they can rerun it.
- Very specific: line 269
Before choosing a moment or probing a transient event, read references/virtual-time.md.
- Very specific: line 272
If the earlier moment isn't warm, add --source-run-id.
- Very specific: line 276
If exec returns an error, read references/errors.md.
- Distinctive: line 280
Before reporting back, check your work against these criteria:
- Very specific: line 282
Every finding comes from actual exec output, not inferred or assumed.
- Very specific: line 290
After snouty runs cancel, the run's status may show completed instead of cancelled.
≈ “Common” is an estimate: at least 1 in 5 of the 308,232 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
Antithesis Debug
Skill version: 2026-10-30 d5d7b3b
Execute a bash script at a moment in a run. Each call branches the multiverse and repeated calls from the same moment reproduce. Can use a currently running run or an active MVD session.
When to use this skill
- The user gives you Antithesis debugging-session run ID or URL
- The user asks you to debug or investigate a failing property, bug, or any result from a past run
- The user makes a request to inspect container filesystem, runtime state, or events inside Antithesis
- Triage suggested this skill because logs alone haven't explained a failure
Failed property warning
Commands run with runs exec on a live run can trigger a run's assertions, which will result in a failing property that looks exactly like a real bug.
Use a debugging session if you want to avoid these kinds of false positives. Preference using a currently running run for speed, ease of use, and less core hours for commands you do not think will cause this problem.
Prerequisites
- DO NOT PROCEED if
snoutyis not installed. Seehttps://raw.githubusercontent.com/antithesishq/snouty/refs/heads/main/README.mdfor installation options. - DO NOT PROCEED if
snoutyis older than 0.8.0, the first release whereruns execis stable. Usesnouty --versionto find the version. Usesnouty updateto update. - You must have a session from a live run or MVD session to use this command. See get a live session first for more info.
- You must be logged into an Antithesis tenant from snouty. Run
snouty doctorto confirm. Ask your user to log you in or use an API key if you are not logged in.
Get a live session first
execneeds a live session. A session can either be tied to a run or MVD session. In snouty both runs and debugging sessions show as runs.- A run holds one while it runs, and for a short time after it ends. It will work a few minutes after completion but not hours.
To see if a run has an active session use:
snouty --json runs show <run> | jq -r '[.status, .sub_status // empty] | join(":") | ascii_downcase'This prints the status and the sub-status together.
in_progress:readymeans you can run commands against the run.in_progresswith any other sub-status, such asin_progress:loading, means the session is still loading.snouty runs wait <run> --until readyreturns once the run is ready to use, or once it has already finished. It prints the status it stopped at, so check that it isin_progress:readybefore you exec.If the user gives a debugging-session URL, that session may already be running. Find its run ID among the sessions, matching on title, description or creation time.
runs listshows only the status, so pick anin_progresssession, then check thatruns showreports itin_progress:ready:snouty --json runs list --launcher debugging \ | jq -c '{run_id, status, created_at, title: .parameters["antithesis.test_name"], source_run: .parameters["antithesis.debugging.run_id"]}'source_runis the value to pass to--source-run-id.For an older run, make a debugging session first:
snouty debug --run-id <run> --input-hash <hash> --vtime <vtime> \ --title "Counter property failure 2026-10-13"- Always pass a
--titlethat is unique and easy to find later, for example the property name plus a date or ticket id. It is the namesnouty runs listshows for the session. Add--descriptiononly if the reason won't fit in the title.--recipientstakes semicolon-separated emails to notify. - This returns a new run ID. Wait with
snouty runs wait <new run ID> --until ready, thenexecagainst it. - Use
--source-run-id <run>for the first command because the moment isn't warm yet. With the source, the call blocks and prints rewarming moment: N% until the moment is ready. - Expect 2 to 20 minutes from snouty debug to the first successful exec: a few minutes of 404s while the session loads, then a rewarm that takes longer the later the moment's vtime. After that, the moment is warm and later commands on that moment don't need the source.
- If exec answers 404 or "Moment not warm", the session is still loading. Retry. Look at get a moment to find the right input-hash and vtime for your users request.
- Always pass a
Get a moment (input hash and vtime)
input-hash and vtime pin the single moment to debug. Extract the input hash and vtime from context and pass them to the command.
If the user didn't give you a moment, read references/moments.md for where to find one.
If you can't pin down both an input hash and a vtime from a clear source, ask the user rather than guessing.
Required input
RUN_IDis a live run, or a debugging session's run id.INPUT_HASHandVTIMEare a moment from that run, taken together as a pair from one source: aruns propertiescounterexample, aruns streamsample line, or aruns searchevent.INPUT_HASHis often negative, for example-1520695250096255483. Pass it as-is: snouty reads it as the hash, not as a flag, so you don't need--. Adding--turns every flag after it into a positional argument and breaks the command.snouty runs exec "$RUN_ID" -1520695250096255483 67.7622960046865 'uptime'SCRIPTis the bash to run. Pass it as the last argument, or omit it and pipe it in, for example < script.sh.
Optional flags
--timeout DURATIONis how long the server waits for the script to exit. It takes units:90s,5m,1h. A bare number means seconds. The default is 10m (as of release 64.0). Rewarming a cold moment does not count against it.--container NAMEruns the script inside that container. Without it, the script runs on the host.--source-run-id IDnames the run a cold moment comes from. When the target is a debugging session, this is the run you opened the session from, not the session id. Use this flag on your first command after starting a debugging session.--source-session-id IDis the session alternative to--source-run-id. You can't use both.--eventsstreams every event on the timeline while the script runs, not just the script's output.--jsonprints machine-readable json output.
Execution Tips
- Use
--containerover podman exec inside the script to run a command on a single container. --containerneeds a container name, and works only on Docker Compose tests (see Kubernetes tests below). If you've already runsnouty runs searchorsnouty runs logs, take the name from any container log event'ssource.container. Otherwise, list them by running this once without--container, so it runs on the host:snouty runs exec "$TARGET" "$HASH" "$VTIME" 'podman ps -a --format "{{.Names}} {{.Status}}"'On a Docker Compose test, names are the same at every moment of a run, so list them once.
--containerworks only on a container that is running at your moment. If it crashed or exited earlier,podman ps -ashows it asExited, and--containerfails. Exec from an earlier moment when it was still up. Find one withsnouty runs searchon that container's last log lines.- Don't use
--containerand run on host, if you need a snapshot across multiple containers. To get a file out of the run, print it to stdout and redirect locally:
# text snouty runs exec "$TARGET" "$HASH" "$VTIME" --container app 'cat /var/log/app.log' > app.log # binary or a directory: tar + base64, then decode locally snouty runs exec "$TARGET" "$HASH" "$VTIME" --container app \ 'tar czf - /data/db | base64' | base64 -d > db.tgz
Kubernetes tests
--container doesn't work on a Kubernetes test (the launcher in snouty runs show
contains "Kubernetes" or "k8s"). Leave it out and read references/kubernetes.md.
Run a Script from a File
For anything longer than one line, write the script to a file and redirect it in:
cat > script.sh <<'EOF' echo "host: $(hostname)" ps aux EOF snouty runs exec "$RUN_ID" "$INPUT_HASH" "$VTIME" < script.shThe quotes around
'EOF'keep$(hostname)from running on your machine on accident.- Reuse one script across moments. Run the same file at several moments and compare the outputs.
- Save output to a file named after the moment.
Always save --events output to a file. The stream is long, so grep the file afterwards:
snouty runs exec --events $RUN $HASH $VTIME < oracle.sh > out.txt grep -E "FAIL|HIT|exit" out.txt
Picking a Timeout and Timing
- Size
--timeoutto the script alone. A cold moment is rewarmed first, which can take minutes (longer the later the moment's vtime), but that time doesn't count against--timeout. Raise it only for slow scripts, for example--timeout 30m. - A timeout doesn't mean the script didn't run. Search the run for its output (
snouty runs search) before re-running anything that changes state. - Your script advances virtual time. Keep snapshots short. Take one query at the right moment rather than polling, because polling can change the timing you're trying to observe.
- The same command from the same moment gives the same branch. Repeating it doesn't sample new timings.
- After one exec with a source succeeds, that moment stays warm in the session. Later commands there need no source and return quickly.
- Earlier moments on the session's own timeline are warm too, so they need no rewarm.
Rewarm progress
A cold moment shows progress while it rewarms. By default the command prints rewarming moment: N% lines on stderr. With --json, it prints {"status":"rewarming","percent_complete":N} frames on stdout, ahead of the script's output.
- A rising percentage means the rewarm is working. Don't retry or cancel while it climbs.
- The percentage can stay at 0% for several minutes and then jump to near 100%. A stall at 0% is not a failure. Leave the call running.
Cancel when done
Runs and debugging sessions use core hours until they end. A debugging session doesn't end when you stop using it: by default it expires only after 6 hours. Cancel any session you opened as soon as you no longer need it, or won't need it soon:
snouty runs cancel "$TARGET"- Always ask the user before canceling any run or debugging session, even when you think you have everything you need. Cancelling a live run stops their test, and they may want to keep a session for more debugging.
- Make sure you are completely done with a run or debugging session before canceling, as if you want to run more commands you will have to wait for a new session to get setup.
Example Workflow
1. Prerequisites
snouty --version # 0.8.0 or newer
RUN=<run_id>
snouty --json runs show "$RUN" | jq -r '[.status, .sub_status // empty] | join(":") | ascii_downcase'in_progress:ready→ 2a. Live run.starting, orin_progresswith another sub-status →snouty runs wait "$RUN" --until ready, then 2a if it printsin_progress:ready.- Anything else → 2b. Past run.
2a. Live run: stream a moment, exec on the run itself
No debugging session is needed.
snouty runs stream "$RUN"
# sample <property id> counterexample <hash> <vtime>
TARGET="$RUN"; HASH=<hash>; VTIME=<vtime>For a counterexample from before the stream opened, take its moment from snouty runs properties.
2b. Past run: search a moment, open a debugging session
Find moments with snouty runs search, and query for exactly the events you want. For example, the failing evaluations of one property:
snouty --json runs search "$RUN" \
'filter(ev => ev.antithesis_assert?.hit
&& ev.antithesis_assert.id == "<property name>"
&& !ev.antithesis_assert.condition)' \
| jq -r '.moment | "\(.input_hash) \(.vtime)"'Drop the ! for passing evaluations. To find a log line, use contains({output_text: "<error text>"}). To find an assertion by its message, use filter(ev => ev.antithesis_assert?.message?.includes("<message text>")). Assertions have no output_text, so the log-line query won't find them. See references/moments.md.
runs search returns at most 50 results by default. Add --limit 999 if you need more than a few.
Then open a session at that moment and wait for it. Retry exec on 404 or "Moment not warm" while it loads.
snouty debug --run-id "$RUN" --input-hash "$HASH" --vtime "$VTIME" --title "<property> <date>"
TARGET=<runId from the output>
snouty runs wait "$TARGET" --until readyPass --source-run-id "$RUN" on the first exec.
3. Exec
cat > probe.sh <<'EOF'
hostname
ps aux | head -20
EOF
snouty runs exec "$TARGET" "$HASH" "$VTIME" < probe.sh > out.txt4. Use the results
Apply the output to the user's goal, usually finding the cause of a bug. If the
output doesn't answer the question, exec again at an earlier moment, or from the
end moment line to continue forward.
If necessary give the user the moment, the script, and the relevant output, so they can rerun it.
5. Clean up
snouty runs cancel "$TARGET" # only after the user says yesgdb
To inspect a process with gdb, read references/gdb.md.
Virtual time
Before choosing a moment or probing a transient event, read
references/virtual-time.md.
If the earlier moment isn't warm, add --source-run-id.
Common Errors
If exec returns an error, read references/errors.md.
Self-Review
Before reporting back, check your work against these criteria:
- Every finding comes from actual
execoutput, not inferred or assumed. - The evidence chain is clear: the moment (input hash and vtime), the script, what it returned, and what follows from it.
- The summary separates what the output shows from what you interpret or recommend.
- You've asked the user before cancelling any run or debugging session, or the user knows it is still running.
Known issues
execcan still return 404 for several minutes aftersnouty runs wait --until readyreturns. Keep retrying; the session is still loading.- After
snouty runs cancel, the run's status may showcompletedinstead ofcancelled. The cancel worked.
Other versions1 project uses a version of this.
Word for word · 0
None found.
Edited · 1
- ghuntley/loom★ 1.6k89% same
Wrote their own version · 0
None found.
How matches are found. Word for word: the exact same text. Edited: shares passages with this file (“99% same” means 99% of its five-word phrases also appear here; 10% or more counts). Their own version: similar meaning, or, weakest, the same name. We can’t tell which project had it first. Projects are counted among the 200 most-starred candidates, and mentions are links to the repository we found, up to 50 per site, so both counts are a floor.
In this repository14 other files it gives its agents.
- AGENTS.mdAGENTS.md
- CLAUDE.mdCLAUDE.md
- antithesis-documentationSkill
- antithesis-feature-workloadSkill
- antithesis-launchSkill
- antithesis-mutation-testingSkill
- antithesis-researchSkill
- antithesis-review-inputsSkill
- antithesis-setup-k8sSkill
- antithesis-setupSkill
- antithesis-skills-feedbackSkill
- antithesis-triageSkill
- antithesis-workloadSkill
- test:triageSkill
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
Reviews can't be read right now.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

