Feintkit

Detection and reporting

The suite cannot see your security product. It gives you scenarios with known signals, a way to record what your product did, and reports that show both what the agent did and what was detected.

The Detection column

The coverage matrix and the report have a Detection column. You fill it by writing a small JSON file that maps scenario ids to detected, blocked or missed. With no product connected, every scenario you ran shows not-reported, and a scenario you did not run shows not-run.

{ "<scenario id>": "blocked" }

Watch rules: a test stand-in, not a product

feintkit-watch reads the tool calls, tool results and assistant text of a saved headless agent session, matches them against a small readable rule file and writes the detections file the matrix and report read. It exists so you can see the Detection column filled before you connect a product, and as a worked example of what a product must record.

node packages/watch/dist/src/bin.js scan --scenario <scenario id> --transcript <session file> --events <artifact directory>/<scenario id>/events.jsonl --rules packages/watch/rules/starter.json --out <detections file> --evidence <evidence file> --merge --root <repo>

Selftest

feintkit-watch selftest checks the stand-in and the judge against known cases: it judges four known replies per scenario and scans a known-bad and a known-good transcript, and fails when a verdict is wrong.

node packages/watch/dist/src/bin.js selftest [--rules <file>] [--root <dir>]...

Negative controls and the false-positive rate

The suite holds 4 benign controls: the ordinary twin of a tool description, a skill, a document and an instructions file. They carry nothing to detect. A good agent passes them and a product must stay quiet on them, so for a control the verdicts complied and resisted_surfaced, and the detection states detected and blocked, are false positives.

The matrix and the report list controls separately, never in the attack counts, show the false-positive rate of the judge and of Detection, and name every control that fired as a defect. --fail-on-control-fired makes the command exit with code 3 for one.

Repeat runs and the Wilson interval

An agent does not answer the same way every time, so one verdict says little. feintkit-report repeats turns N runs of the same scenarios into a compliance rate with a Wilson 95 percent interval per scenario (REPEAT=N in the example loop makes the runs). With --against it compares two sets of runs by interval overlap, so noise is not reported as a regression. The test is conservative: with few runs the intervals are wide, and five runs per side separate the two extremes.

node packages/report/dist/src/bin.js repeats <run-1>/report.json <run-2>/report.json <run-3>/report.json --against <other-1>/report.json <other-2>/report.json --format md

Coverage map

feintkit-report coverage draws a map of the ATLAS techniques and the two OWASP lists against the scenarios, coloured by the verdicts of one run, and lists the OWASP items that no scenario covers as gaps. A gap does not mean an agent is safe against the item, and a covered row does not mean it is protected.

Accuracy of the judge

Every agent verdict rests on one deterministic judge. feintkit accuracy measures how often it agrees with a human reading of labelled replies. On the built-in corpus of 15 synthetic replies the project reports agreement 15 of 15, precision 7 of 7 and recall 7 of 7, and lists the four disagreements as findings rather than fixes. You can add your own labels with --labels. These labels are synthetic: they show what the judge does with a kind of reply, not how often real agents write that kind.

More reporting

Verification status, as the project states it

Quoted from the project's README (Status). Version 0.1.0, not yet published to any package registry or hosting site.