Skip to content

Changelog

The beta at beta.plune.ai ships continuously, so entries are dated, not versioned: an entry here is on the beta. Only what you can see or call is listed — screens, endpoints, rules. The road in — @plune-ai/cli and the @plune-ai/playwright reporter — is versioned and keeps its own changelog.

2026-09-14 — Retire a case, bring it back, confirm it

Section titled “2026-09-14 — Retire a case, bring it back, confirm it”
  • The case page moves the case. The menu on a case offers exactly what the lifecycle table allows a person from where the case stands — Retire, Return to work, Confirm (an approved case out of in_review), Activate (a draft) — through the same was → becomes dialog as “Move to…”, with an optional Why. The reason and the date show beside the state badge for as long as the case stays there; the audit log keeps every reason for good. The lifecycle of a case.
  • Retired, but still reported. Results for a retired case are recorded as before and the state stays deprecated; the case page counts the results that arrived after the retirement and dates the last one — the cue to take the test out of the code too.
  • The form no longer sends a state. The Status select is gone from the edit form; saving a title or a description never moves a case again. deprecated reads as retired everywhere the dashboard shows a state.
  • allowedStates on a single case. GET /v1/test-cases/:id says where the caller may move the case from here — a session and a token get different answers (additive; the list does not carry it).

2026-09-14 — A refused token mint says so

Section titled “2026-09-14 — A refused token mint says so”
  • A refused mint is visible. Generating a token past a limit used to do nothing on screen — the refusal was never caught. Now it shows above the list with the server’s reason and, for a throttle, how long to wait.
  • Ten live tokens per account, three seconds between mints. The ceiling was twenty and the mint throttle five per hour — which locked out exactly the person looking around on their first day. Volume is now bounded by the ceiling (every token listed and revocable), the throttle only turns a burst of clicks into one mint. The list says “N of 10”; at the ceiling the button is disabled with the way out named. GET /v1/tokens gains limit (additive).
  • Retry-After tells the truth. Every throttled answer now says the seconds until a slot frees, not the length of the whole window — sign-in included.
  • The suite tree is a filesystem. A folder holds folders and suites, a suite holds cases — nothing holds both, and every write that would break the rule is refused with the same sentence. A non-empty suite becomes a folder through POST /v1/suites/:id/convert-to-folder; its cases move into a child suite of the same name in one transaction. Organizing cases.
  • An automated case files itself. On every road a case is born — created, approved from the queue, or trusted on arrival — its specRef decides where it lives: directories become folders, the file becomes a suite, and the suite remembers its file.
  • Case fields. priority (five levels), precondition, description, and position among siblings. Tags live in the title@smoke at the end of a name is the tag; tags[] in the API is sugar that rewrites that tail. Settings → Tags lists them with counts, renames and merges. Case fields.
  • The filter is the URL. GET /v1/test-cases?suiteId&tag&priority&priorityMin&type&state&q — repeats inside one dimension are OR, dimensions are AND, a folder expands to its descendants, and an unknown value answers 400 with the allowed ones spelled out. The dashboard reads the same object from the address bar, so a selection is a link. Filtering.
  • Screens. Cases grouped in tree order with breadcrumb headings, priority glyphs and tag chips; Move to… and Delete with a “was → becomes” dialog; suites created with a type, reordered with ↑/↓, converted in place; filters in a drawer and the tree as a drill-down below 1024 px.

2026-09-10 — The beta gets a door, and a source can be trusted

Section titled “2026-09-10 — The beta gets a door, and a source can be trusted”
  • Invite-only. Sign-up is limited to an allowlist of mailboxes (an address and its +alias forms are one mailbox). A sign-in request for an address that is neither invited nor already registered gets the same 202 as any other and no email — the answer is not a way to ask whether an address is on the list; the sign-in screen says the beta is invite-only and links to the waitlist. GET /health reports door: invite-only | open.
  • Trust a source once, instead of a test at a time. Settings → Trusted sources (PATCH /v1/settings {trustedDiscoverySources: ["junit"]}): tests a listed runner finds become cases on arrival — the verdict is created — instead of waiting in the review queue; everything created this way is marked as trusted in the audit log, and the setting has a writer, a date and a way back. --create on the reporter is still the offer; what becomes of it is decided here.
  • An approved case can be deleted. A case born from the review queue used to refuse deletion because the decision that created it pointed at it. Now the case goes and the decision stays — verdict, category, note and time untouched, with an audit row saying the case is gone. Results still refuse: they are evidence of past runs. The delete button asks first.

2026-09-09 — The first run tells the truth; a run can be deleted

Section titled “2026-09-09 — The first run tells the truth; a run can be deleted”
  • A first run no longer says nothing happened. Results from a suite that has no cases yet do not become results — they wait in the review queue as discovered tests. The run page used to show 0 of 0 and “recorded no results”; now it says how many tests are waiting and links to the queue. Only pending entries count: an approved one has become a case and is no longer waiting for you.
  • A run can be deleted, and put back. DELETE /v1/runs/:id — the account owner, no confirmation, recursively (results, disputes, discovered tests); a second call is 404. POST /v1/runs/:id/restore exists for the application owner only. A run was the one thing the platform could create and not remove.
  • Settings shows what this account is — the address and the role — above the tokens, and GET /v1/me returns role next to the address.
  • The token screen names both homes. A CLI token goes into plune login on the generating road and into a CI environment variable on the free road; the screen used to mention only the first.
  • One voice. The Ukrainian interface addresses the reader one way throughout; 34 strings changed. English is unaffected.

2026-09-08 — A run has a name; the queue learns discovered tests

Section titled “2026-09-08 — A run has a name; the queue learns discovered tests”
  • Runs carry title, environment and labels. The reporter variables PLUNE_RUN_TITLE, PLUNE_ENV and PLUNE_LABELS now land somewhere: the title heads the run page, the other two show as tags. GET /v1/runs?environment= splits the histories of a suite run against staging and against production. PLUNE_GROUP is still refused — run groups wait for their own feature.
  • Discovered tests are a third kind of queue entry. A reporter that ran a test the platform has no case for offers it through POST /v1/review-items/discovered; the answer is 200 with a verdict per test — queued, duplicate, refused, known, or created when the source is trusted. Approving one creates the case and attaches every key, so from the next run the test resolves instead of being found again. A refusal outlives the run that provoked it. The review queue.
  • A proposal shows where it came from. Source (page, operation, or requirement) and technique on every queue row; rationale and the cost of the proposing run when you open it. An approved case shows the same on its own page — for cases created before this change too.
  • Breaking. technique on a proposal is limited to 32 characters; a longer name is refused where it used to pass.
  • The runs table gives its width to the column with something to read; an environment tag no longer wraps inside itself.

2026-09-07 — The queue reads in pages and remembers why

Section titled “2026-09-07 — The queue reads in pages and remembers why”
  • Breaking. GET /v1/review-items is paginated. The answer is {items, nextCursor}, limit 1–200 (default 50). A client that read items and stopped sees the first page only — read until nextCursor is null, and pass the cursor back verbatim; an invalid one answers 400 rather than silently restarting from the top.
  • One decision over an explicit list. POST /v1/review-items/decisions takes {itemIds, state, rejectionCategory?, note?} for up to 200 items and answers with a report — {applied, casesCreated, skipped[], duplicates[]} — because one stale item must not undo the other nineteen. There is deliberately no “approve everything pending”.
  • Breaking. A rejection needs a reason. rejectionCategory — one of duplicate, incorrect, out-of-scope, low-value, not-testable, otherand a note of 10–2000 characters, on any write after which the item stays rejected, from the dashboard and from the API alike. The reason is visible on the card and can be changed; the previous pair stays in the audit log.
  • Queue rows are lighter than a single item: proposedTitle and the names of the fields that differ from an existing case; the full body comes from GET /v1/review-items/{id}.

2026-09-05 — Where the public record starts

Section titled “2026-09-05 — Where the public record starts”

The beta as invitees first saw it: a bilingual dashboard (English by default, Ukrainian as the second language), and data model v2 underneath — case states, external keys as identity, run statuses, and an audit log on every change. Earlier history belongs to the team, not to this page.