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).
The record
Section titled “The record”{ "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.
Triggers
Section titled “Triggers”The History label is what the History tab shows. Use the value with
GET /api/tests/:id/versions?trigger=….
People and tokens
Section titled “People and tokens”| 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 |
Self-healing
Section titled “Self-healing”| 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 |
Components
Section titled “Components”| 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 version written more than once
Section titled “A version written more than once”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.
What a run led to
Section titled “What a run led to”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.
Older readers
Section titled “Older readers”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>).