Getting it into your agent
One page per mod, every tool's command on it. A separate URL per tool would split the same page into five that compete with each other.
npx skills add tmj-90/gaffer --skill property-based-testgit clone --depth 1 https://github.com/tmj-90/gafferWrote 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/tmj-90/gaffer/property-based-test)<a href="https://agentmods.dev/skills/tmj-90/gaffer/property-based-test"><img src="https://agentmods.dev/badge/skills/tmj-90/gaffer/property-based-test/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/tmj-90/gaffer/property-based-test"><img src="https://agentmods.dev/badge/skills/tmj-90/gaffer/property-based-test.svg" alt="Reviewed on agentmods" width="80" height="20"></a>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.00140 | $0.01473 |
| Opus 5.5 | $0.00056 | $0.00589 |
| Sonnet 5.5 | $0.00028 | $0.00295 |
| Haiku 4.5 | $0.00014 | $0.00147 |
Grade A, and why
property-based-test 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 16d 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 — 89 lines — stays where its author put it; the contents beside it link to each section on GitHub.
Write property-based tests
An example test proves one point in the input space; a property test states a law, lets the framework hunt for a counterexample, and shrinks it to the smallest failing case. Use it where the acceptance criterion is a rule ("decode(encode(x)) == x", "output is sorted", "never loses an acknowledged write"), keep the generators honest, and turn every found failure into a permanent example.
Procedure
- Use the repo's framework. fast-check (JS/TS), Hypothesis (Python), proptest or
quickcheck (Rust), jqwik (Java/Kotlin),
rapidortesting/quick(Go), FsCheck (.NET), Rantly/PropCheck (Ruby). Callsearch_lorefor conventions. If none is installed, do not add one (installs are blocked andnode_modulesis shared): cover the rule with table-driven examples over the step 3 edges and name the framework you would add in your evidence. - State the property as a law, named after the AC. Common shapes:
- round-trip:
parse(print(x)) == x; - invariant:
isSorted(sort(xs)), totals preserved by a split, ids unique; - idempotence:
f(f(x)) == f(x)(retries, normalisers, upserts); - oracle:
fast(x) == simpleReference(x), or new == old implementation for a refactor; - metamorphic:
search(q)⊇search(q + " filter"); - robustness: valid input never throws; invalid input throws only the documented error. Avoid restating the implementation in the assertion — that tests nothing.
- round-trip:
- Build honest generators. Cover the whole valid domain and its edges: empty, single,
maximum sizes, duplicates, unicode and surrogate pairs,
-0,NaNwhere allowed, leap days, DST transitions, extreme timezones. Build values with combinators (fc.record,st.builds,map/chain); filter only rare exclusions — heavy filtering starves the generator (Hypothesis raises a health-check failure, fast-check stalls). - For stateful systems, test sequences, not single calls (model-based testing). Define
commands (create, update, delete, restart, …) that run against both the real system and
a simple model, asserting they agree after each step: fast-check
fc.commands+fc.asyncModelRun, HypothesisRuleBasedStateMachinewith@rule/@invariant, proptest-state-machine. Include "restart/reopen" as a command when the AC is about persistence — it catches data that only lived in memory. - For async concurrency, explore interleavings. fast-check's
fc.scheduler()wraps promises so the framework chooses the resolution order and shrinks a failing schedule (s.schedule,s.scheduleFunction,await s.waitIdle()from v4.2;waitAllon older versions); combine withfc.commandsviafc.scheduledModelRun. Assert invariants such as "no acknowledged write is lost" and "final count equals successful operations". This explores in-process orderings only; a criterion about multiple processes, files or crashes still needs the real-process schedule in theadd-integration-testskill. - Keep bodies pure and fast. No network, no shared state across runs, no randomness outside the framework's; reset any store per run. Hundreds of runs must fit the test time budget.
- Make failures reproducible. On failure, fast-check prints
seedandpath— replay withfc.assert(prop, { seed, path }); Hypothesis stores failing examples in its database and prints@reproduce_failure. In CI use a fixed or logged seed (Hypothesisderandomize=Trueor a CI settings profile). - Shrink and pin. Read the shrunk counterexample, fix the bug (the
fix-bugskill), and add it as a permanent example (@example(...), fast-checkexamples: [[...]], or a plain example test) so the regression stays explicit if generators change. - Tune run counts to the repo's convention: 100 (the default in fast-check and
Hypothesis) to ~1000 locally, more in a nightly profile if one exists. Set a per-test
time limit (Hypothesis
deadline, fast-checkinterruptAfterTimeLimit). - Prove the property bites by breaking the behaviour temporarily and seeing a shrunk
counterexample, then restore. Record evidence with the
record-evidenceskill: property names, run count, seed, and any counterexamples turned into examples. (An independent tester never edits implementation files and skips the break-it step.)
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.
- 16d ago Changed · +28 lines · +19 tokens per session fe63d7b445d9
- 19d ago First seen · 61 lines · 121 tokens per session scan A b3aeb8565733
property-based-test is a skill published in the GitHub repository tmj-90/gaffer (2 stars, last pushed 17d ago), licensed Apache-2.0. It adds 140 tokens to every session and 1,473 once invoked, about $0.0006 per session on Opus 5.5. 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-09-28.
Other skills, from other repositories
test-audit
Audit test suites for T1-T4 violations using AST analysis, mock detection, and multi-stage synthesis. Invoke when user asks to audit tests, check test quality, find mock violations, review test effectiveness, or inspect test suites for over-mocking. Triggers automatic rewrites when quality gates fail.
mock-detection
Deep mock appropriateness analysis for Test Audit pipeline.
bug-magnet-data
Curated edge case test data for boundary testing, verification scripts, and test generation. Provides pre-curated reference data organized by data type with context-specific loading guidance.
assertion-patterns
Real output verification vs mock calls. Use when transforming T1-T4 violating tests to verify observable behavior.
test-classification
Prompt template for test classification stage in Test Audit pipeline.
fix-bug
Run the Fix Validation pipeline to investigate, fix, and validate a bug. Ensures deterministic pipeline execution with IssueAnalyzer, FixWriter, TestWriter (conditional), TestAudit (conditional), and FixValidator stages.