Plugins · CCPP Tester
Writing tests
How ccpp-tester finds what the user asked, writes tests with a source for every expectation, and attacks them with mutations.
ccpp-tester runs with model: inherit and effort: high, and the tools Bash, Read, Grep, Glob, Write and Edit.
Its task message comes from the agent whose code it tests, which wants green. The tester treats that message as a
claim to check, never as the specification.
Sources
Every expected value in a test must have a source the tester can cite:
| Source | Not a source |
|---|---|
| The user's words in the parent transcript (message uuid) | The code's behavior |
| A documentation page, a schema, a spec file (path or URL) | A value the main agent printed from a run |
| An existing test, an earlier ccpp-tester's report | "The user wants…" without a quote |
No source, no expectation: the tester asks for it in its report instead of guessing.
The steps
- What the user asked. The tester finds the parent session's transcript and extracts its steps: the user's messages, the answers to questions, what the agent did and said. Thinking blocks are skipped: they are the parent arguing for itself.
- Earlier testers. It looks for the ccpp-testers that already wrote tests for the same files, and reads what each test was for.
- Conventions. The runner, its config, the nearest tests and helpers. It writes tests the way the repository already does, in its own framework: bun test, Vitest, Jest…
- Write. Exact assertions (
toStrictEqual, the error's code), inputs the task message did not mention (boundaries, empty and invalid input, refusals, the user's own examples), and titles that state what the body asserts. A hard-coded implementation must fail. - Run. Only its own files. A test failing on an assertion is a finding and stays red; a test that cannot run (syntax, import path, fixture) is the tester's own bug to fix.
- Attack, with the mutation skill below.
Dictation
The main agent may write "verbatim", paste assertions, give expected values, ask for toContain, or ask to raise
a timeout. Pasted code is a wish: the tester keeps what a source backs, replaces or refuses the rest, and lists
each refusal with its reason. Thresholds and timeouts come from the user or the docs; "it took 5.9 s" is not one.
Mutation testing
A green test proves nothing if a wrong implementation passes it too. The skill cpo:ccpp-tester, preloaded into
the agent and refused to every other one, runs a mutation library on the code under test: StrykerJS for
TypeScript and JavaScript. It injects small faults (< becomes <=, a branch is removed, a string is emptied),
reruns the tests on each mutant, and every survivor is a wrong implementation the suite accepts.
- Integrity first. With the exact campaign command, the tester shows that a false assertion fails it, that an empty selection fails it, and that the tests load the mutated code, not a stale build.
- One campaign per task, on the task's files only, at most 2 workers; then one focused rerun on the mutants it targeted. More than about 150 mutants means the scope is too wide.
- Survivors as diffs. The tester reads place, mutator and replacement through the skill's
outcomes.jqfilter: the raw report holds the code whole (enforcement). - Each survivor is killed by a new assertion with a source, or recorded as equivalent with the reasoning, or becomes a question for the user. A mutant shows where the contract decides; only a source says what.
- Boundary probes the library does not generate: a dependency that rejects, duplicates, or answers for the wrong tenant, through the test doubles the tester controls.
Stryker and its config are installed outside the repository, in ~/.cache/ccpp-tester/ or /tmp/ccpp-mut-<name>/.
For other languages the tester applies the same test design and reports mutation as not-run.
Moves that do not count
Lowering a threshold, excluding a mutator family, a disable comment, narrowing the scope to drop a survivor, raising a timeout until a mutant times out, counting compile or runtime errors as kills, asserting what the code returns instead of what the source says, or presenting a focused rerun as the full campaign.