Borrowing it
Nothing to install: this file belongs to Thurbeen/thurbox. Take a copy, put it at the same path in your own repository, and replace the rules that are about this project with yours.
curl -O https://raw.githubusercontent.com/Thurbeen/thurbox/main/.agents/skills/thurbox-testing/SKILL.mdgit clone --depth 1 https://github.com/Thurbeen/thurboxWrote this? Show the measurements
A badge with what this costs and how it scanned, read live from this page, so it follows the numbers instead of freezing them. Markdown for a README, HTML for a documentation site or a project page.
[](https://agentmods.dev/skills/thurbeen/thurbox/thurbox-testing)<a href="https://agentmods.dev/skills/thurbeen/thurbox/thurbox-testing"><img src="https://agentmods.dev/badge/skills/thurbeen/thurbox/thurbox-testing/github.svg" alt="Measured on agentmods" height="20"></a>Or the 80×15 button, for a site that already has a row of RSS and ATOM ones. Only the verdict fits; the numbers stay here.
<a href="https://agentmods.dev/skills/thurbeen/thurbox/thurbox-testing"><img src="https://agentmods.dev/badge/skills/thurbeen/thurbox/thurbox-testing.svg" alt="Reviewed on agentmods" width="80" height="20"></a>- NVIDIA SkillSpector pass
What it costs to keep this loaded
Counted locally with the o200k_base tokenizer, which is exact for GPT models; Claude uses its own tokenizer and its counts differ. Treat this as one consistent yardstick across the catalogue rather than a bill. Prices are per million input tokens.
| Model | Per session | Once invoked |
|---|---|---|
| Fable 5.1 | $0.00000 | $0.06107 |
| Opus 5.5 | $0.00000 | $0.02443 |
| Sonnet 5.5 | $0.00000 | $0.01221 |
| Haiku 4.5 | $0.00000 | $0.00611 |
Grade A, and why
thurbox-testing scanned grade A with 0 findings against 26 rules in 11 categories — prompt injection, anti-refusal, data exfiltration, privilege escalation, supply chain, agent snooping, system-prompt leakage, SSRF and excessive agency — measured 5d ago.
A static scan of the body, not an audit. Every finding is printed with the line that produced it so you can judge whether it matters here. A mod is markdown that instructs an agent; that is exactly why what it instructs is worth reading.
Nothing flagged
None of the 26 patterns this scan looks for appear in this file: no shell pipes, no recursive deletes, no credential paths, no hidden text, no instruction-override or anti-refusal phrasing, no agent-config snooping. That is not a guarantee, it is the absence of the things that are checkable.
How it starts
The opening of the file, as written. The whole thing — 360 lines — stays where its author put it; the contents beside it link to each section on GitHub.
Testing thurbox
Working reference indexed by AGENTS.md. The rationale behind these decisions is owned by the docs under docs/; a change that invalidates what this says updates it in the same PR.
Testing
cargo nextest run --all # Run all tests (preferred runner)
cargo nextest run -E 'test(name)' # Run a single test by name
cargo nextest run --all --profile ci # Run with CI profile
bats scripts/install.bats # Test install script (requires bats-core)
bats extensions/*/scripts/*.bats # Test the extensions' shell scripts
just test-scripts # Both of the above, the way CI runs them
The Nix development shell includes bashInteractive, not merely stdenv's
non-interactive Bash. Real-tmux fixtures exercise Readline's bracketed-paste
mode, including its bind setting, so substituting the stdenv shell changes
the terminal contract those tests are meant to drive.
tests/doc_references.rs keeps the tracked documents honest about each other: every
relative Markdown link, every docs/<NAME>.md and .agents/skills/<name> path
and every github.com/Thurbeen/thurbox/blob/main/… link names a file that
exists, and the names in its RETIRED table appear nowhere. Rename a document
or delete a symbol that docs cite, and that test lists every stale citation.
Add a name to RETIRED once nothing in the tree mentions it any more.
Kernel and interface tests
The interface is Lua on a Rust kernel, so most coverage drives the real
kernel over the real ui/ rather than a harness that imitates either:
tests/kernel_mvp.rs— the kernel's contract: the four node kinds and their count, the plugin environment enumerated global-by-global (no blanket exemption for a leading underscore — that is how a capability once hid under__run_impl), the instruction/memory bounds, snapshot reads, and painting a plugin to aTestBackend.- The per-surface files — one file per surface or contract:
session_list,search,new_session,terminal_pane,session_lifetime,keymap,focus,modals,chrome,mouse,hover,decoration,plugin_{authoring,commands,lifecycle,settings,switching},repo_memory,remote_status,session_status,core_settings,attach_by_name. Several build an interface in a tempdir from the embedded copy, so delivery and loading are exercised together.plugin_switchingalso runs the registry persistence path in an isolated child process under a Unix file-size limit: the forced mid-write failure must preserve every byte of the priorui.jsonand leave no staged file behind. The native interruption probe is Unix-only; Windows replacement is compile-checked and usesMoveFileExW, but is not exercised by that probe. The same file pins config-file symlink preservation on Unix and paths beyondMAX_PATHon Windows. tests/edited_interface.rs— an edited interface keeps working across an upgrade. It holds files frozen from old releases with a user's edit (tests/fixtures/edited_interface/<release>/: v2.22.4's layout, session list and agent pane, v2.32.0's layout and agent pane), and checks that they are preserved, arrange, render and passplugin checkagainst the currentlib/and kernel. It also pins every namelib/exports (lib_surface.txt). This is the check behindlib/'s compatibility promise inui/AGENTS.md. Never refresh the frozen files to followui/. A newlib/export is appended to the pin; a removed one means adding a shim back.tests/kernel_limits.rs— instruction and memory ceilings, in their own file because they mutate process-wide limits.- Lua statics —
selene ui(undefined names + the sandbox, viathurbox.yml),lua-language-server --check(types + withheld libraries, viaui/lib/thurbox.d.lua),stylua(format). The three cover different halves; see Linting & Formatting. scripts/ci/check-lua-types.sh— the definitions' own test. Three panes intests/fixtures/lua_types/each misspell one thing the plugin API otherwise drops in silence (a node prop, a command option, a theme role) and each must still be reported.--check uiproves the panes are clean; this proves the types have teeth. Runs in the Lua Lint job and injust lint.scripts/ci/check-lua-std.sh— the same trick forthurbox.yml.tests/fixtures/lua_std/reads.lua, generated fromsrc/kernel/lua_api.rswith thethurbox.*entries it lints against, reads every declared path and must lint clean, andtypos/holds one pane per table misspelling one field, each of which must not. It asserts on selene'sincorrect_standard_library_usecode from itsJson2output and attributes a finding by the file it came from, so no assertion depends on message wording. A checked path stops at the first[…], so a list has nothing below it to probe, andrunsis the one map whose keys are the plugin's own literals rather than a session id. Those tables were declared without their fields for as long as nothing read them (issue #1133). Same two runners.tests/lua_api.rs— the plugin API againstkernel::lua_api(issue #1476): the generated declaration files equal what it renders (THURBOX_REGENERATE=1, i.e.just lua-api, rewrites them), a pane walking every key of a fully populated publish finds none undeclared, andthurbox.api/requires_apihold; itsmetamodule drivesui.*session meta from the realthurbox-clito the bundled session list.tests/frames.rs— the bundled panes' frames pinned cell for cell, as literals in the file (no snapshot tool): the session list grouped, nested, windowed, narrow and under double-width names; the selection as a style; the agent pane empty, detached, failed, and with a real vt100 screen behind its surface. A failing test prints the new frame as a literal to paste. Every input is pinned (thedefaultpreset by name, a fixedelapsed, a fixed snapshot) — keep it that way; a frame that moves on its own is worse than none.tests/render_props.rs— proptest crash invariants: every bundled pane renders and paints at any size down to one cell, the arrangement places its slots inside the screen and apart, no key sequence makes a pane throw (the creation flow included), and selection extraction survives arbitrary buffers and arbitrary vt100 byte streams.tests/tui_e2e.rs(unix) — the real binary on a real pty, vialibc'sopenpty(no PTY crate), fully isolated (private HOME/config/data, a short privateTMUX_TMPDIR, inheritedINPUTRCscrubbed, network and heartbeat features off). It asserts what noTestBackendtest can: the boot frame, the kernel overlays opening and closing, the search strip taking focus, a column toggle reflowing with no screen clear, a resize storm down to 1×1, a broken pane reported through the Interface tab, exit restoring the terminal (alternate screen, mouse, bracketed paste, cursor) — and, where tmux exists, a headlessly created session attached, painted and typed into (shas the agent), the classic Shell tab raised, lowered and still holding its shell (and replaced by a working one after it exited behind the agent, or its window went while thurbox was closed), and a v2.32.0 layout-preset profile (fixture intests/fixtures/v2_32_0_split_shell/) upgrading back to classic. Also delayed remote shell creation and re-adoption keeping F1 responsive, andjust smoke. It replaced the bash tmux smoke script, which could not see the byte stream and duplicated this harness. Keyboard negotiation covers responsive legacy, kitty and silent terminals;docs/DEVELOPMENT.mdrecords the reply invariant and execution measurements. Two scenarios there cover a remote session whose link has gone bad, which needs a stand-in that a local tmux cannot supply on its own:tmux -C attach-sessionhands its stdin and stdout file descriptors to the tmux server and then only shepherds, so stopping the client changes nothing, while a realsshis a byte relay whose stopping wedges the link. Thesshstand-in therefore runs the control connection through a pair ofcatpumps over fifos — the pids the testSIGSTOPs — andexecs straight through for every other call, whose exit status is load-bearing (has-sessionanswering "no" is howensure_readydecides to create a session). Both scenarios assert only on a kernel-owned overlay, never on the session list: the list returns on a snapshot tick, seconds even on a healthy link, so it cannot tell a frozen interface from a patient one. See ADR-P24.tests/self_update_scratch.rs(unix) — the real update CLI with private config/data/home and bounded fake downloaders, terminated in its own process group mid-download. The leader stays unreaped until group teardown so the harness cannot signal a reused pid. Pins recovery on the next update while preserving an aged live owner's staging; no network or installed binary is touched. A subprocess probe also pins that the system temp fallback never reserves or sweeps unrelated paths.agent::self_update::testscovers the same staging lifecycle in child processes on Unix and native Windows, including normal exit, recent work, legacy names, malformed ownership, and symlinks / Windows junctions.tests/reap_e2e.rs— window-teardown ownership against a real tmux on a throwaway socket (skipped when tmux is absent), because the bug it pins only exists in how tmux resolves a target. 15 tests. Seven pin the reap itself: a stale row's reap spares a live namesake's window (stamped, and unstamped as every psmux window is), a namesake's pane the stale row still remembers, a live window whose name only collides aftersanitize_window_name('fleet 1' and 'fleet_1' share onetb-fleet_1), and a soft-deleted namesake still inside its undo window — while a row whose own pane resolves, and one whose pane id resolves to nothing but whose stamp nobody else answers to, still lose their window. Sparing must not be bought by making the reap a no-op. Force delete,stopandrestartshare the reap's ownership gate (ADR-25,backend::identity::WindowIndex) rather than each resolvingtb-<name>on their own, so one test walks all three against their own live namesake, plus one asserting force delete still kills the row's own window. Two more cover the stamp itself: a row with no pane id at all (the psmux shape) still resolves its own window, and a restore whose name a live session now answers to is refused outright (issue #1192) rather than joining it on the backend —respawn's own ownership gate is walked byrestartin the three-path test above. The last three cover the companion shell and the no-server guarantee (ADR-24/25's remote teardown): force delete and reap both collect the companion shell alongside the agent's window, a teardown spares a live namesake's companion shell, and a teardown never brings a tmux server into being (theensure_readyside effect this path must not trigger). The owed-teardown sweep (retry_owed_remote_teardowns) is unit-tested againsthost_cli::fakeinsession_ops::delete— that a failed remote teardown is written onto the row, that a soft-deleted row is never on its worklist (the undo window), and that a silent host is asked once per pass — and proven end to end on a real process bylinux-container.sh'sremote_teardown_probe. The same file covers a delegated delete whose host never answers at all: it falls back to the local teardown and owes a retry, while any other host error still aborts.restart --if-missingrefusing to relaunch against an unreachable host (rather than reading it as "no window" and starting a second agent) is proven end to end bylinux-container.sh'srestart_if_missing_probe.tests/concurrent_respawn.rs— six sessions relaunching onto a tmux server that does not exist yet, against a real tmux on a throwaway socket (skipped when tmux is absent): every worker'sensure_session_configuredsees "no session" and racesnew-session, and the regression this pins is that a loser must not abort its whole respawn over tmux'sduplicate session— it has to notice the winner's session and continue.tests/spawn_command_resolution.rs(unix) — a local spawn against a real tmux on a throwaway socket (skipped when tmux is absent): starts a server whose ownPATHlacks the agent, then spawns it throughTmuxBackend's control-mode path with the agent only on thurbox'sPATH. Pins the fix inresolve_local_program(docs/CONFIG.md→ Howcommandis resolved): a local window command used to be left for the multiplexer to resolve, which sees the server'sPATH(an attached client's is not copied in), not the one thurbox itself was launched with.tests/spawn_with_failing_tmux_hook.rs(unix) — its own binary and its own socket because it installs a server-global hook, which any suite sharing the socket would then spawn into. Against a real tmux (skipped when tmux is absent): a deadafter-new-windowhook, the shape an uninstalled tmux plugin leaves behind. Pins that the one-shotnew-windowpath believes the pane id on stdout rather than the exit status — tmux hands the client the status of the lastrun-shellits command list triggered, hooks included, so a window that was created came back asexit status: 127and was torn down (#1154). The second test pins the quieter half: the id kept must still resolve to that window and carry its session stamp.tests/path_resolution_absolute.rs(unix) — its own test binary because it moves the process working directory, which a sibling test in the same binary would see. Pins thatresolve_on_path(docs/CONFIG.md→ Howcommandis resolved) skips an emptyPATHcomponent rather than joining it as "the current directory": that join used to answer with a bare relative name, reintroducing the multiplexer-resolves-it dependence the function exists to remove.tests/session_state_agreement.rs— one row, four independent readers (session get,session list,watch --initialvia the real binary, andSnapshotStorein-process): all four must answer the sameSessionState. Pins the concrete regression thesession::hook_statusconsolidation fixed —seen_atis a stored fact only the snapshot used to read, so a turn the interface already showed asidlekept answeringdoneon every headless surface for the rest of the session's life.
What this file has done since we first saw it
Hashed on every crawl. A supply-chain change to an agent config is a question of when, not whether, so the history is kept rather than the latest state alone.
- 5d ago Changed · +22 lines baaa8e4a2c1a
- 7d ago Changed · +1 lines d9094d46468d
- 9d ago Changed · +10 lines 881eea5899e6
- 11d ago Changed · +2 lines 9efce37be5a0
- 15d ago Changed · +1 lines 0af23b807218
- 17d ago Changed · +15 lines e96165741f45
- 19d ago Changed · +6 lines 959abf1eadad
- 20d ago Changed · +9 lines fe72e33c8f60
- 1mo ago Changed · +8 lines 0e02559a155c
- 1mo ago First seen · 286 lines · 0 tokens per session scan A eff22a0240c6
thurbox-testing is a skill published in the GitHub repository Thurbeen/thurbox (115 stars, last pushed today), licensed MIT. It costs nothing until one of its globs matches a file; then it loads 6,107 tokens. A static security scan graded it A with 0 findings. No closer match exists in the catalogue, so it is treated as the original; first seen 2026-08-30.
Other skills, from other repositories
research-engineer
An uncompromising Academic Research Engineer. Operates with absolute scientific rigor, objective criticism, and zero flair. Focuses on theoretical correctness, formal verification, and optimal implementation across any required technology.
tika-eval-compare
Compare extracts from two Tika builds over a corpus to detect regressions in content, encoding, exceptions, and embedded-document handling. Use for "compare before/after extracts", "eval this change against the corpus".
cua-driver
Use Cua Driver for desktop or browser tasks that are awkward or unavailable through Bash/APIs, or when the user explicitly wants GUI interaction: app testing, visual bug reproduction, form filling, calendar entry, screenshots, and demo recording. Also covers Cua setup; not OpenAI Codex Computer Use or web research.
jetson-validate-image
Use after jetson-flash-image to run static BSP checks, on-target smoke/regression tests on a flashed DUT, or both. Not for build or flash steps. Triggers: validate bsp, on-target validation.
atmos-validation
Validate Atmos projects, components, arbitrary JSON Schema inputs, EditorConfig, and GitHub Actions; use affected-file selection and native CI annotations.
skill-benchmark
Benchmark AI skill effectiveness by measuring implementation quality against legacy constraints.