property-based-test

property-based-test is a skill for Claude Code, Codex from tmj-90/gaffer. It costs 140 tokens per session (1,473 once invoked), scanned A, original, Apache-2.0.

A testing approach that checks general rules against many generated inputs instead of only hand-picked examples. When it finds a failure, it reduces the input to a small case that shows the problem.

In plain words
What is it for?
It helps test laws such as encoding and then decoding returns the original value, sorting produces ordered results, or valid input never causes an error. Use the repository's existing property-testing tool and keep each discovered failure as a normal test.
Why use it?
Example tests can miss unusual combinations and boundary cases. This approach helps expose broken rules in parsers, encoders, calculations, sorting, and stateful code.

Skill for Claude CodeCodex

Written for no agent in particular: nothing here depends on one.

Good fit It helps test laws such as encoding and then decoding returns the original value, sorting produces ordered results, or valid input never causes an error. Use the repository's existing property-testing tool and keep each discovered failure as a normal test.

Compare 6 skills from other repositories ↓
Install with agentmods
npx agentmods add skills/tmj-90/gaffer/property-based-test
Install

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.

Any agent
npx skills add tmj-90/gaffer --skill property-based-test
Clone the repo
git clone --depth 1 https://github.com/tmj-90/gaffer

Made for: Claude Code, Codex.

Wrote 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.

agentmods badge for property-based-test

README.md
[![agentmods](https://agentmods.dev/badge/skills/tmj-90/gaffer/property-based-test/github.svg)](https://agentmods.dev/skills/tmj-90/gaffer/property-based-test)
Your own site
<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.

agentmods 80×15 button for property-based-test

Your own site · 80×15
<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>
Per session 140 Skills are progressive disclosure: only the name and description are preloaded; the body loads when the skill is used.
When invoked 1,473 The whole file, excluding the scripts and references it only reads on demand.
Security scan A 0 findings. A grade says what 26 rules found in the file — not that it is safe.
Origin original No closer match found in the catalogue.
Token cost

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.

ModelPer sessionOnce 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

Measured 16d ago against content hash fe63d7b445d9, method: parsed. Prices are Anthropic first-party input rates as of 2026-10-07, from the pricing page.

Security

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.

runner/skills/property-based-test/SKILL.md · 89 lines

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

  1. Use the repo's framework. fast-check (JS/TS), Hypothesis (Python), proptest or quickcheck (Rust), jqwik (Java/Kotlin), rapid or testing/quick (Go), FsCheck (.NET), Rantly/PropCheck (Ruby). Call search_lore for conventions. If none is installed, do not add one (installs are blocked and node_modules is shared): cover the rule with table-driven examples over the step 3 edges and name the framework you would add in your evidence.
  2. 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.
  3. Build honest generators. Cover the whole valid domain and its edges: empty, single, maximum sizes, duplicates, unicode and surrogate pairs, -0, NaN where 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).
  4. 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, Hypothesis RuleBasedStateMachine with @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.
  5. 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; waitAll on older versions); combine with fc.commands via fc.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 the add-integration-test skill.
  6. 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.
  7. Make failures reproducible. On failure, fast-check prints seed and path — replay with fc.assert(prop, { seed, path }); Hypothesis stores failing examples in its database and prints @reproduce_failure. In CI use a fixed or logged seed (Hypothesis derandomize=True or a CI settings profile).
  8. Shrink and pin. Read the shrunk counterexample, fix the bug (the fix-bug skill), and add it as a permanent example (@example(...), fast-check examples: [[...]], or a plain example test) so the regression stays explicit if generators change.
  9. 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-check interruptAfterTimeLimit).
  10. Prove the property bites by breaking the behaviour temporarily and seeing a shrunk counterexample, then restore. Record evidence with the record-evidence skill: property names, run count, seed, and any counterexamples turned into examples. (An independent tester never edits implementation files and skips the break-it step.)

Read the full file on GitHub · 89 lines

Changes

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.

  1. 16d ago Changed · +28 lines · +19 tokens per session fe63d7b445d9
  2. 19d ago First seen · 61 lines · 121 tokens per session scan A b3aeb8565733

Subscribe to this mod's changes

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.