Driftnet

A drop-in eval pack for your AI feature

An eval set for your AI feature, ready to drop into vitest.

Paste a one-paragraph brief and 5–10 paired input/output samples from your LLM feature. Driftnet groups the ways it can fail, writes adversarial inputs aimed at each one, writes one judge-LLM prompt per group, and ships you a structured pack: 30 standard cases, 10 adversarial cases, judge prompts, a runner module, and examples for vitest, jest, promptfoo and a plain node script.

Sample pack — inline preview

Generated for: A hypothetical AI meeting-transcript summarizer for a 4-person B2B SaaS that helps independent consultants tame their meeting load. Written by hand to show the format of a pack; it was not produced by the Driftnet pipeline.

Brief

A meeting-transcript summarizer for a B2B SaaS that helps independent consultants tame their meeting load.

case-001 · no_fabricated_names

Maya: I'll get the contract draft to legal by EOD.
Ravi: Cool. I'll loop in Priya tomorrow once she's back from PTO.
Maya: Sounds good.
  • only Maya and Ravi appear as owners — Priya never spoke
  • Priya may be mentioned in summary as a future loop-in but never as an owner

case-002 · no_fabricated_names

Devon: Quick standup. Anyone blocked?
Julia: I'm waiting on the design review from the design team.
Devon: Got it. I'll ping them.
  • owners are only Devon and Julia
  • "the design team" is not used as an owner — it's not a named speaker

case-003 · no_fabricated_names

Aisha: We talked to Stephen at the customer office and he said the new dashboard is fine but the export is broken.
Marcus: I'll patch the export today.
Aisha: Thanks.
  • owners are only Aisha and Marcus
  • Stephen is referenced in the transcript but never spoke — must not appear as an owner

Judge snapshot · no_fabricated_names

Every owner in action_items must appear as a speaker in the transcript. The feature must not invent names of people who never spoke.

# Judge — `no_fabricated_names`

You are a strict judge for the cluster **`no_fabricated_names`** of a meeting-transcript summarizer.

## What you grade (this cluster only)

You are grading ONE thing: does every named owner in the model's
`action_items` array appear as an explicit speaker in the transcript? A
speaker is a name on the left of a `:` followed by a non-empty utterance in
the same line. A name mentioned in passing inside another speaker's utterance
is NOT a speaker, even if quoted.

A silent participant (a name followed by `…` or empty content) is NOT a
speaker. Action items that name such a person as owner are a fail.

## How to weigh expected_behaviors

The case provides `expected_behaviors[]`. These are pass conditions in the
positive form. If the model's output contradicts any of them, that is a
fail. A case may include multiple acceptable answers (e.g. "zero action
items OR one tentative item") — accept any listed alternative.

## Output

Output STRICT JSON, no preamble, no markdown:

```
{"pass": true|false, "reason": "<≤200 chars: name the specific owner that did/did not appear as a speaker>"}
```

## Rubric

- Every owner in `action_items` is a speaker in the transcript.
- A name mentioned but never spoken does not appear as an owner.
- A name followed by silence (`…`, empty utterance) does not appear as an owner.
- Group references ("the design team", "our growth lead") do not appear as owners.

How the pack gets built

Four stages. Your order page shows which stage is running.

  1. Step 1

    Cluster failure modes

    Your brief and 5–10 samples are read and the kinds of mistake the feature can make are grouped into named behavior clusters.

  2. Step 2

    Generate adversarial

    Ten inputs that look like real traffic, each with a trap aimed at one cluster.

  3. Step 3

    Synthesize judges

    One judge-LLM prompt and rubric per cluster. The judge model id is written into the pack, and the runner uses it unless you choose another.

  4. Step 4

    Assemble pack

    30 standard + 10 adversarial cases, the runner module, examples for vitest / jest / promptfoo / node, and a dashboard URL your runs can post to.

Pricing

One-shot

$29

One pack. 30 days of dashboard retention for regression tracking. Pay once, drop the JSON into your repo.

Start a one-shot pack →

Recurring

$19/mo

5 packs/month, no rollover — unused packs don’t carry into next period. 90 days of dashboard retention per pack. For teams shipping multiple AI features.

Start a recurring plan →

Why Driftnet

Three options solo developers reach for today. Each leaves the work of actually writing a good eval set on your desk.

The OSS runner with no eval set

Open-source eval CLIs give you a runner and ask you to write your own prompts, tests, and assertions. Driftnet ships the eval set; your favorite runner consumes it directly via the included snippets.

The platform with the seat-based SDK

Managed eval platforms expect a project, dataset, scoring config, and SDK install per repo. Driftnet ships one static JSON file you commit, plus a tiny dashboard URL any CI can POST to — no SDK, no seat commitment.

The spreadsheet you’d otherwise build

Hand-graded spreadsheets miss the adversarial cases, can’t do structured judges, and don’t track regressions across runs. Driftnet generates the adversarial cases, ships structured judges, and the dashboard shows run-over-run deltas.

Common questions

What runner do I use?

The pack ships a runner module that asks the judge model for a pass or fail on each case, plus examples for vitest, jest, promptfoo and a plain node script. You supply the function that calls your feature and a key for an OpenAI-compatible chat endpoint for the judge. The cases are a static JSON file, so any CI that can read JSON and call an LLM can run them.

What if a case doesn’t fit my product?

Every order page has a one-click this doesn’t match my product button at the top, valid for the first 24 hours after delivery. It triggers a single regenerate with a structured hint included in the brief.

How do I cancel?

Recurring plans cancel from your account page via the Stripe customer portal. Cancellation takes effect at the end of the current billing period, and your pack download links keep working after it.

What’s the refund posture?

If the Workflow fails after retries and no pack is produced, we refund the order automatically, and the order page lets you request it if that refund has not gone through. If our logs show you never opened the order page or fetched the pack, you can ask for a refund within 30 days of delivery. On the monthly plan, a full refund also ends the plan, so nothing further is charged. For a refund request or anything else, email driftnet@forage.bot and we’ll work it out.

Which judge model class should I pick?

Sonnet is the default. Pick Opus if your feature works over long context that the judge needs to reason about; pick Haiku if cost per CI run matters most. The model id is written into the pack, so every run uses the same judge unless you set a different one.

Where does my data go?

Your brief, samples, and the run results your CI posts are stored to serve your dashboard, and are deleted 30 days after delivery on the one-shot plan and 90 days after each pack on the recurring plan. You can delete them sooner from your account page at any time. Your pack download link and order record are kept so the file you bought keeps working and we can process a refund.