Skip to content

The review queue

Plune generates test cases. It does not add them.

Everything a machine proposes lands in a queue and waits for a person, and that is the single rule the rest of the product is arranged around. A tool that writes tests into your suite on its own is a tool you stop trusting after the first bad one — and then you stop reading its output at all, which costs more than it ever saved.

They arrive from different directions and take the same decision. Exactly one of the three fields is ever set on an entry, and the database holds that rule, not just the schema.

Proposal — a case a generator wrote. It carries a proposedCase: steps, an expectation, and the mode that produced it. This is what an ingest from Cairn queues.

Discovered test — a test your runner reported that this project has no case for. It carries a discoveredTest, and the difference from a proposal is the whole reason it is its own kind: a reporter sees a result, never the source, so it has no steps to state and no expectation to claim. The entry testifies that a case is missing instead of describing one — keys, title, location, and what the test did on that run. This is what --create and POST /v1/review-items/discovered produce, and it is the ordinary path for onboarding an existing suite: import the report, decide once, and every later import matches instead of offering.

Dispute — a result whose verdict deserves a human look rather than trust. It carries a resultId pointing at the result in question, and its comparison is shown side by side.

An entry is pending until somebody decides, and then it is approved or rejected. Approval is the only way a generated case enters your suite — there is no other door, not through the API and not through the dashboard. A discovered test has a second door, and you are the one who opens it: see trusted sources below.

  1. Read it. GET /v1/review-items/{id} returns the entry with its comparison.

  2. Decide. PATCH /v1/review-items/{id} with approved or rejected. Approving a proposal creates the test case and links it to the entry.

  3. Or decide in bulk. POST /v1/review-items/decisions takes one verdict over an explicit list of ids — explicit, so a batch can never decide something you have not seen.

Re-importing the same report does not re-offer what you already decided. A proposal matches an existing case through its external keys, so the second import of 2 000 tests after you accepted them reports 2000 accepted, 0 unmatched rather than filling the queue again.

That property is what makes onboarding a big suite survivable: the first import is a decision, and every one after it is a no-op.

A discovered test is not something a machine invented. It exists in your repository — Plune did not propose it, it read it. So the queue asks a question whose answer you already know, and it asks it once per test.

That costs more than it looks. The queue holds 1 000 waiting items and one decision covers at most 200, so onboarding a suite of N tests is ceil(N/1000) imports plus ceil(N/200) decisions: 14 actions for 2 000 tests, 120 for 20 000. Neither ceiling is wrong on its own. Their product is.

So the permission is granted to the source, once:

Terminal window
curl -X PATCH https://beta-api.plune.ai/v1/settings \
-H "Authorization: Bearer $PLUNE_TOKEN" \
-H "content-type: application/json" \
-d '{"trustedDiscoverySources": ["playwright"]}'

Or in the dashboard, under Settings → Trusted sources.

From then on a discovered test from that runner becomes a case immediately, active rather than waiting: over a test that already runs in your CI there is no second judgement to make. Every case it creates is written to the audit log with trusted-source as the reason, which is what answers “which of these did I actually read” six months later.

PATCH /v1/settings replaces rather than merges, so send the settings your project has — a key you leave out is one you removed.

Approvals, rejections and corrections all write to the audit log, and a change can be put back from it — including a whole session’s worth at once. The log is not swept along with the data it describes: delete the run and its audit trail is still there, because a log that disappears with its subject only proves that nothing was kept.