Skip to content

Version provenance

Every write to a test version, and every component version, records who made it, why, how the request came in and, for a self-healing fix, which run found it. The editor’s History tab shows it (see Versions), and the REST API returns it as provenance, lastChange and changes.

The server writes it from the request. A client cannot send or change it: a test document with a provenance field is refused (422).

{
"author": { "kind": "user", "id": "usr_…", "name": "Ann" },
"trigger": "heal-auto",
"via": "system",
"at": "2026-10-20T14:03:11.512Z",
"run": { "runId": "run_…", "ranVersion": 3 },
"from": { "suggestionId": "hs_…" },
"assisted": "ai"
}
Field Meaning
author.kind user (a member), token (an API token), rule (a self-healing rule) or system (a script, no request)
author.id The member or token id, or rule:<rule id>@v<rule version>
author.name The name today. A member or token that no longer exists keeps the name it had, and removed: true is added
trigger Why the write happened. See Triggers
via web (a browser session), api (a token), mcp or cli (a token whose client says so), system (a rule or a script)
at When it was written: the same moment as the version’s savedAt
run For a self-healing fix: the run that found it, and the version that run executed
from What it was made from: version (and testId) for a restore, a new revision or a duplicate; suggestionId for a fix; componentId (and the base version) for a component upgrade or a fixed component version
assisted "ai" when the write saved steps the AI step writer produced, for the first time. Recorded from 2026-10-20

Fields that do not apply are left out.

The History label is what the History tab shows. Use the value with GET /api/tests/:id/versions?trigger=….

Value History label Written when
create Created A new, empty test is created
import Imported A test document is imported
duplicate Duplicated A test is copied. from is the version copied
edit Edited A Draft is saved with changed content
status Status changed A Draft is marked Ready or Deprecated as it stands, or a Ready test is deprecated
new-revision New revision New revision starts the next Draft of a Ready test. from is the version it copies
restore Restored An old version is brought back. from is that version
tags Tags changed Tags are added or removed, including from the list and a project-wide rename or removal
suite-rename Suite renamed The test’s suite is renamed
component-upgrade Component upgraded A bulk upgrade moves the test to a newer component version. from.componentId is the component
Value History label Written when
heal-approve Fix approved A person approves a fix. run and from.suggestionId are set
heal-auto Fixed automatically A rule applies a fix. The author is the rule
heal-revert Fix reverted A fix is undone. No run: no run caused it
component-heal Component fix A fix to a step inside a component: on the new component version, and on the component’s source test when the fix is carried into it
Value History label Written when
component-publish Published A component is created, or a new version is published. from is the source test’s version

An unknown value in ?trigger= is answered with 422, listing the real ones.

A Draft is saved over the same version, so one version can have many writes. Its history entry keeps:

  • provenance: who opened the version, and why. It never changes afterwards.
  • lastChange: the latest write.
  • changes: every write, oldest first, at most 200. Over that, the oldest go, but the first is always kept.

Editor saves in a row by the same person, the same way in, are one change: its at moves to the latest save. Any other write, or anyone else saving in between, starts a new change. A merged change keeps assisted: "ai" if any of its saves had it.

Versions written before provenance existed have none of these fields. The History tab shows their author as it was recorded, and no filter matches them.

GET /api/runs/:id returns produced: every version the run’s fixes were written into.

"produced": [
{ "of": "test", "id": "tc_…", "name": "Toolbar", "version": 2, "trigger": "heal-auto" },
{ "of": "component", "id": "cmp_…", "name": "Login", "version": 4, "trigger": "component-heal" }
]

It is worked out from the versions when the run is read, so it is always current. Tests you cannot see are left out. The run report shows it as the Led to line.

A version’s author, a test’s updatedBy and a component version’s publishedBy still hold the author’s name, for readers written before provenance. For a rule it is the rule’s name; provenance.author.kind says it was a rule. Versions written before provenance named a rule as Rule "<name>" (rule:<id>@v<version>).