Changelog
What changed in Vera and when, newest first — new capabilities, fixes, and changes to how something already behaved.
What changed in Vera, newest first. Dates are when the change landed on main.
This page is a committed file (docs/changelog.md), not a feed generated from
commit messages: a commit log records every change, and a changelog records the
ones a customer can tell the difference between. Entries are grouped by the
question they answer — is this new, is this a fix, does it change how something
already behaves.
Something behaving differently and not listed here? That is a bug in this page as much as anywhere else — tell us via the contact page and we will correct it.
2026-10-06
Issues
- When auto-repair gives up on an application bug, it tries to prove it.
If the ladder stops or runs out of options on a failure judged an
application bug with high confidence, the issue it files now gets a repro:
auto-repair proposes and approves one test that should fail for that bug,
holds it for review, and runs it once. The issue reads Bug confirmed
only if that repro fails at its proving step on a wrong value or state.
Anything else (an inconclusive run, a pass, no AI key, a plan limit) leaves
the issue as "repair gave up", with no bug claim. One attempt per issue, and
the repro card says auto-repair made it, not a person. MCP
list_issuesrows gainbugConfirmedandreproProposedBy.
Runs
- Runs started without a queue no longer stall at "pending". On servers that execute runs in-process, a run started by an MCP tool or by approving a repro was abandoned at its first checkpoint and never left pending, so a repro approved there always read inconclusive. They now run to the end.
Intent blocks
- A resolved intent block is now saved, once the run confirms it. After a
resolve, or when Auto-repair or the gardener goes green by re-deriving a
block, the steps that worked replace the ones that broke between the block's
markers. That happens only when the block did what it did on its last green
run, or an outcome assertion after the block passed. Otherwise the steps wait
in Staged repairs. A saved block shows as a repair with strategy
intent, and Revert puts the old steps back. Later runs replay the saved
steps with no model call.
POST /api/tests/:id/resolvenow also returnsresolution, saying whether the steps were written, proposed, or neither, and why. - A broken intent block can be re-derived from its goal. When an intent
block's recorded steps no longer replay, the repair ladder's self-heal
re-run (the gardener, or Auto-repair on a failed run) and a new explicit
POST /api/tests/:id/resolvenow finish the block from the live page, one action at a time: chosen from the page's controls when TypeSafe is on for your workspace, written by your AI model otherwise. It drives only your project's own site and types only the block's declared values. The run shows what was done. Plain runs (Run, CI, schedules, MCP,vera-agent) still replay only and never call a model. Gated on the same plan feature as auto-repair. - Intent blocks export, save over MCP, and run on every
vera-agent. An intent block is a goal (intent) and the steps that achieve it, closed byend-intent. Code export (Playwright, WebdriverIO, TestCafe, Selenium-Python) now writes the block's steps as ordinary code with the goal as a comment above them, where it used to write a "TODO: unsupported action" and a warning; a Selenium-Python block whose body is only comments gets thepassit needs. MCPcreate_testandupdate_test_stepsdescribe blocks to the agent and refuse one that does not balance or is nested, with the same message the dashboard shows.vera-agent0.5.1 and older do not know the markers, so a run leased to one gets the block's steps without them: it replays the same steps and stays green instead of failing on an unknown action. Agent runs always replay a block and never call a model.
Design review
- A design finding must show up twice before it is listed. One vision review is one opinion, so a finding it reports is now held as a candidate: hidden from the run's findings and counts, with "N candidates · Show" to look anyway. When a later run's review reports the same defect, even in other words, it becomes open and stays one finding with a "seen in N runs" count instead of a new row per run. A candidate that later reviews stop reporting expires. Accessibility findings are unchanged.
- The run findings API hides candidates by default.
GET /api/runs/:runId/findingsnow leaves out candidate and expired design findings unless you pass?include=hidden. Run reports carry ahiddenFindingscount, and a shared public report counts candidates without listing them.
Self-heal
- A heal that picks from the page's controls no longer sends your secrets.
Where a heal chooses among the controls already on the page instead of
having the AI write a selector, the failed selector, the step's error and
every control's text are now cleaned of the project's credentials and
variable values before they leave. A selector built from a variable
(
text={{username}}) used to go out with the value filled in. If the project's secrets cannot be read, no pick is made and the heal falls back to the AI-written selector. - Values a run captures as sensitive stay out of heals and intent blocks.
A one-time code, magic link or token saved by an
extract,api-requestorwait-for-emailstep marked sensitive is now removed from everything a heal or an intent-block resolution sends: the failed selector, the error, the page snapshot, the controls offered for a pick, and the stored AI history. This coversvera-agentheals too (needs avera-agentrelease after 0.5.1). Before, only the project's own credentials and variables were removed, so a selector built from a captured value went out with the value in it. The AI-written heal now also removes the run's credentials and variable values before it asks; a heal whose broken selector was such a value may now be declined instead of guessed. - Values a run captures as sensitive stay out of repair and diagnosis.
Auto-repair hands its re-run's secrets, sensitive captures included, to the
repair suggestion and diagnosis steps, which replace them with
***in what they send and in the stored AI history. Before, a one-time code the page also showed went to the AI in the list of controls. Where those values cannot be known (Suggest fix orsuggest_fixon a finished run), a test that captures a sensitive value before its failure gets a suggestion without the page's controls, and Diagnose no longer sends the console and network logs of a run that captured one. - Malformed page markup no longer stalls heal redaction. Repeated unclosed script, style, SVG or comment openers are processed in linear time. A missing closing tag or comment delimiter now removes the remaining contents from the snapshot before it reaches the AI.
2026-10-05
Issues
- A repro run on a queue worker or a local agent now gets its verdict. Approving a repro where runs execute elsewhere used to leave it not run for good. Approving now starts its first run, and when that run completes it writes the verdict onto the issue — nobody has to start it by hand. Approving counts against your workspace's concurrent-run limit, as starting a run does.
- "Reproduced" means it failed for the stated reason. A repro names its proving step, the assertion that encodes the correct behaviour. It counts as reproduced only when that step is the first to fail, on a wrong value or state. A run that failed anywhere else, or never found the element, reads inconclusive, with the step that failed.
- A reproduced repro no longer blocks CI. It is quarantined as a known bug, linked to its issue, until it runs green or the issue is closed. Rule and journey health show known bug instead of failing for it, and auto-repair leaves an open issue's repro alone. A quarantine you set by hand is never changed.
Self-heal
- Typed values no longer leave your machine in a heal request. When a heal
sends page markup to the AI (the WebDriver path and
vera-agent), what the test typed into inputs, text areas and rich-text (contenteditable) editors is now removed first, not just passwords and hidden fields. The markup and its attributes stay, so the AI can still find the control. - Auto-heal review marks heals the run could not confirm. A heal counts as confirmed when a later assertion on the outcome passed in the same run. Unconfirmed heals are listed but start unticked, with the reason.
vera-agent
vera check --run --local --fail-on-healed. When your workspace lets the agent self-heal,vera checknow prints each healed step (old selector → new one), and--fail-on-healed(orVERA_FAIL_ON_HEALED=true) makes a pass that needed a heal exit 5. Off by default, like the GitHub Action'sfail-on-healed. Needs avera-agentrelease after 0.5.1.
MCP
verify_selectortakes locators. Ask by role and name, text, label, placeholder or test id. Vera builds the selector its recorder would write, checks it on the live page, and when it matches exactly once returns a stepcreate_testaccepts as is.inspect_pageonly offers selectors that match one element, and can return the page's accessibility snapshot withincludeAria.
2026-09-22
Issues
- The issues list shows where each issue came from. One filed through the API, by an MCP client or by Vera's own AI is labelled as such in the list, not only once you open it.
- An issue can only point at your own tests and runs. Filing with a test or run id that is not in your workspace is refused, and nothing is filed. It is checked once, when you file: an issue still outlives the run it came from.
Self-hosting
- Built-in accounts can reset a forgotten password. The sign-in page has a
Forgot your password? link where built-in sign-in is in use. The emailed
link works once and for an hour, and using it signs the account out
everywhere. It needs a working mail channel and
QA_PUBLIC_URLset — the link is never built from the incoming request. Hosted sign-in is unchanged.
MCP
verify_selector— check a selector before you save the test. An MCP client can ask, for up to twenty selectors at once, how many elements each one matches on the live page, whether that is exactly one, and whether it is visible. It loads the page as one of your project's sign-in roles and costs nothing: no AI call is made.
Radar
- Radar history can age out. Where a retention period is set, superseded page snapshots and resolved changes older than it are removed. A page's newest snapshot is always kept — it is what the next sweep compares against — and a change nobody has reviewed is never removed for being old.
Daily digest
- Newly staged repairs now reach the digest. It reports repair proposals staged since your last digest. One that is still waiting is mentioned once, not every day.
Load testing
- A load run's stored summary is removed with the run when retention ages the run out, rather than staying in storage indefinitely.
Docs
- The actions reference and the test builder guide list all forty actions.
2026-09-21
Help
- ⌘K now searches the guides. Type a question into the command palette — "captcha", "visual baseline", "mcp token" — and the matching guide sections appear under From the guides, below your projects and pages, each linking straight to the heading that answers it. It runs in your browser against an index built with the app: no AI call, no cost, and it works offline. In Arabic it searches the translated guides first and marks a result that is only available in English.
Load testing
- A load run keeps k6's own summary, and you can download it. A finished run used to keep four numbers and throw the rest away. The run's detail view now has Download engine summary: the document k6 itself writes — every trend, counter, rate, check and group — exactly as you would get it running k6 by hand. It is capped at 1 MiB, and a capped file says so inside itself rather than ending mid-document. A run you stopped, or one that could not execute, has no summary, and the button tells you which of those happened. Runs that finished before today have none either; their existing download is still there.
- Load runs can be started and read from CI and from an MCP client.
POST /api/v1/projects/:id/load-runs,GET /api/v1/load-runs/:id, and the MCP toolsrun_load_testandget_load_run. The threshold verdict is reported beside the status; the CI gate scripts do not fail a pipeline on it yet. A workspace whose plan includes no load runs gets a clear refusal naming the limit, not an error. - A plan with no load runs is told about the plan. On a deployment with no load worker, a workspace whose plan includes no load runs used to be told about the missing worker. It is now told the thing it can act on.
Stopping a run
- The local agent guide now says how long Stop takes. A run executing on
your machine stops within one heartbeat (up to 20 seconds) plus the step in
flight, and ends
cancelled— not failed. Nothing changed in the agent; the bound was undocumented. A chain stopped mid-segment marks the segment in flightcancelledand every later oneskipped. - Stopping a chain tells you which run it stopped. The answer to a chain stop used to list no member runs when the chain was still mid-flight — the only time anyone presses Stop. It now names the run that was executing.
- The guides now cover stopping an ordinary test run — where the Stop button appears, why it takes effect at the end of the step in flight, and what a cancelled run does and does not count towards. See the test builder guide.
AI-written tests
- A test the AI converted during an import is labelled as AI-written. It
used to read as hand-written, including in the review queue it had been put
in precisely because a model wrote it. New imports carry the
✦ AIbadge and count in the AI-generated total and ROI figures; tests imported before today keep their old label. The deterministic importers are unchanged.
AI
- A platform administrator can withdraw a model. Under /admin → Runtime, Denied AI models takes a list of model IDs no workspace may use. A denied model disappears from every model picker, and a save that names one is refused on the exact field, with the reason — it is never quietly swapped for another. It takes effect on the very next AI call: a workspace that already had that model saved is told "Your administrator has restricted … — choose another model in Settings → AI", with a link there, and Settings → AI marks the field as not allowed. Unattended work (automatic repair, background review) skips its AI step rather than failing. An empty list restricts nothing.
- Saving a model that works also verifies your key. When you save a model Vera has to check with your provider, a passing check now clears the "needs attention" badge by itself — it was a real call with your key, so a separate Test connection click proved nothing more.
- Per-feature models show whether they were confirmed. The Generate, Heal and Repair model boxes now carry the same accepted by provider / not confirmed badge the main model box has.
- New cloud workspaces start with AI review on. A test an AI wrote waits for a person before it runs in suites, schedules or CI. Existing workspaces are unchanged, and you can turn it off under Settings → Workspace.
Issues
- CI can file a bug. The public API now creates, lists and reads issues for a project, using the same token your pipeline already has. An issue filed this way is marked as coming from the API — the server decides that, not the request. Filing is not triage: moving an issue through its states stays in the product.
Provenance
- A backup keeps who wrote each test. A workspace export now records
whether a test was written by hand, by AI or through MCP, and restoring the
file keeps it. Before this, every restored test came back as hand-written —
losing its
✦ AIbadge and its place in the ROI figures. A file exported before today restores as it always did. Restored AI tests are not re-queued for review: the restore did not write them. - The API and MCP now say where a test came from. A run started through
the public API reports each test's
sourcebeside its result, and the MCP tools that list and read tests report it too. It never changes a pass or fail.
Docs
- Six guides corrected against the product as it ships today: control
flow, suites, business context, analytics, the Claude Code plugin and the
GitHub integration. Several said things that were no longer true — that an
unbalanced
ifcould be saved, that suite concurrency went above five, that every analytics endpoint needed the same plan. The issues guide now says "bug" where you would look for it.
Fixes
- Settings → Workspace no longer wipes a half-typed number. Flipping the Require review of AI-written tests switch reloaded the card and silently reverted any ROI or journey value you had typed but not saved.
Administration
- Platform operators can close a workspace and delete an account. A closure by an operator honours the same grace window as one you request yourself, and only an operator can undo it. A deleted account is erased rather than removed: its email, name and password are gone and it can never sign in again, while the history it appears in stays readable. A disabled account on a hosted sign-in can no longer create new workspaces. The admin console has the matching actions: closing and reopening a workspace, a separately confirmed immediate purge, and deleting an account, each behind a typed confirmation. Deleting a user or an organization at the identity provider now closes the matching Vera account or workspace too.
- Platform operators can browse and delete inside one workspace. /admin → Workspace data opens a single workspace's projects, tests, runs and issues. The workspace is named on screen at all times, deleting a project or a test needs its name typed exactly, and every list and every delete is written to the audit log against the operator's own account.
2026-09-20
Runs
A file attached by an
upload-filestep is still there when a later step submits the form. The step used to pass and the submit two steps on would fail withnet::ERR_FAILED, the request never reaching your server: the file was handed to the browser as a temporary path and cleaned up before the browser read it. The bytes are now held by the browser for the life of the page. One visible difference: a file whose name has no extension, or one Vera does not recognise, reports the typeapplication/octet-streaminstead of an empty string. Fixed for cloud runs on the day it landed, and for the local agent invera-agent0.5.1 below.A run now shows what it recorded, not just whether it passed. Under each step in the run details — and in the report, the shared report page and the HTML/PDF export — you now see: any browser dialog the step raised, with its message and how it was answered; how many console or network entries an
assert-console/assert-requeststep matched (including zero); and which tab the step ran in, once aswitch-tabhas moved the test off the first one. A dialog Vera dismissed on its own is highlighted, with the reason — your flow raised aconfirmand nothing in the test answered it — and the fix: add ahandle-dialogstep before it. Secrets are scrubbed from these the same way they are from step errors, including on shared links.For now the matched console/network entries are a count; listing the entries themselves is planned.
Settings
- Fix: saving Testing & ROI settings failed. Pressing Save workspace settings under Settings → Workspace was refused by the server, so changes to the ROI minutes and the journey limits did not stick. It saves now, and it sends only the fields on that form — so it can no longer touch your AI, review or visual settings as a side effect.
AI
Choosing a model: suggestions, not a fixed list. Under Settings → AI, the model box and the per-feature boxes (Generate, Heal, Repair…) suggest your provider's current models as you type, and you can still enter any model your provider serves. Suggestions appear as soon as you pick a provider. Until you press Test connection they come from a built-in list, and the page says so; after a successful test they are the models your provider offers today. A model nobody could confirm is marked not confirmed rather than silently replaced, and if your provider refuses a model the refusal is shown beside the field it is about — naming the feature, for a per-feature model.
Per-feature models are no longer silently dropped. A per-feature model Vera did not already list used to vanish on save. It is now checked against your provider the same way the main model is — at most once per new model per save — and either kept or refused with your provider's own message.
AI cost: "unpriced" is no longer shown as free. When a model has no published price Vera cannot compute its cost. Those calls were being counted as $0.00, which made the total look exact. The AI cost panel now marks them unpriced, shows the total as a minimum, and says how many calls were left out. Token counts are unaffected.
MCP
- An MCP client can create, edit and run what sits above a test. New tools:
create_chain/update_chain/get_chain;create_scenario/update_scenario/get_scenario/list_scenariosfor Actor Scenarios, withrun_actor_scenarioandget_scenario_runto run one;create_journey/update_journey/list_journeysfor the coverage map; andlist_project_roles, which gives the role ids and environment names those definitions need (never a credential). Every id a definition names is checked before anything is saved.run_scenariois unchanged — it still runs a one-off, unsaved step list — and its description now says so. Reconnect your client to see the new tools. See the MCP guide. - MCP tokens can start and stop an Actor Scenario. They now carry the
scenarios:runpermission. A personal token is still limited to what its owner's role allows.
vera-agent 0.5.1
Upgrade with npm install -g vera-agent@latest; the GitHub Action's pinned
default moved to 0.5.1 in the same release.
upload-filefollowed by a form submit works on the local agent, the same fix as under Runs above. On 0.5.0 the submit fails withnet::ERR_FAILED.
2026-09-19
Privacy
Fix: text already sitting in a text area could be sent to the AI model. When Vera generates tests it describes the page to the model in two ways. One of them, a list of the page's controls, read each control's visible text — and for a
<textarea>or an editable region, the visible text is whatever is in it. So if your application rendered a page with a text area already filled in — a saved note, an address, a support message — that content was included in the prompt, and stored with the generation's record. Typed values in ordinary inputs were never read, and the accessibility snapshot beside the list was already redacted; this was the one path around both.The list no longer takes text from text areas or editable regions at all, a label's text is read with the fields inside it removed (so "Notes" survives and the note does not), and the same literal scrub that protects the snapshot now runs over the list too. If that scrub cannot run, the text is dropped rather than sent. This applies everywhere Vera reads a page for the model: generation, planning, edge cases, repair, self-heal, journeys, radar and the MCP tools.
What this does not do: it does not reach back into generation records made before today. If a page you generated tests from showed a pre-filled text area, its content may be in those stored records.
Review before it runs
A test an AI wrote can now wait for a person. Turn on Require review of AI-written tests in Settings → Workspace and every test the generator, the planner, the repro builder or an MCP client writes lands as a
draftmarked pending review. A pending test is not scheduled, is skipped by suite and batch runs, does not count toward rule coverage orvera check, and cannot block CI — it does nothing until someone with permission to manage tests approves it. The generator's own first run still happens, because that run is the video you review against.The project header shows how many are waiting. Opening one puts the recording beside the steps with Approve, Reject and Open in builder; a rejection archives the test rather than deleting it. If the steps changed while you were looking, the verdict is refused and the queue reloads — you never sign off on something other than what was on screen.
The setting is off by default for existing workspaces, so nothing about your current tests changes until you switch it on.
Three side doors into service are closed. With review on: automatic repair no longer rewrites a test that is still waiting for review (you can still repair it yourself from the failed run); a copy of a test inherits the original's verdict, so copying a pending test gives you another pending test and copying a rejected one gives you an archived one; and an import that needed AI conversion queues the tests the model actually wrote — the ones a deterministic converter handled go straight in, as before.
Stopping things
Stop now works on everything that runs. Chains, suites and scenario runs had no stop at all; a dataset run had one the dashboard could not reach. Each now has a Stop that takes effect at the next step, not at the end of the test in flight, and a stopped suite does not launch the members it had not started yet. Work that never ran is reported as not run — it is not counted as a pass or a failure.
Stopping a load test now stops the load. Cancel used to change the row and leave k6 sending traffic to your application for up to thirty minutes — after which the finished run overwrote the cancellation with a verdict. The process is now terminated, a stop sent while the run was still queued puts no traffic on the target at all, and a cancelled run shows as cancelled with no threshold verdict rather than "thresholds met". Security scans had no cancel; they have one now.
MCP clients:
cancel_runtakes akind(run,chain,suite,scenario). It defaults torun, so existing callers are unaffected.
New steps
handle-dialog— answer a nativealert,confirmorprompt. Put it before the step that raises the dialog: it arms the answer (accept or dismiss, optional prompt text, optional expected message) for the next one.This changes existing behaviour, for the better: a
confirm()on a delete flow used to hang the run until it timed out. With nohandle-dialogarmed, Vera now dismisses the dialog, records that it did, and carries on — except a "leave this page?" prompt, which it accepts, so navigating away from a half-filled form still works. Playwright only; on WebDriver and Appium the step is refused by name rather than pretending.assert-consoleandassert-request— assert on what the page logged and what it requested over the whole run: "no console errors", "no 5xx during checkout", "the order POST returned 201". Filter by URL glob, method and status.go-back,go-forwardandreload— browser history as steps. A back that goes nowhere fails the step and says so, rather than passing because the call returned; an in-page (single-page-app) back counts as having moved.switch-tab— drive a tab your test opened: by position, by URL, by title, or back to the original. If the tab is not there the step fails and lists the tabs that are. Dialog handling follows you to the new tab.assert-consoleandassert-requestsee the tabs your steps actually drove, not tabs left in the background, and the run video is always the original tab's.drag— drag one element onto another (source and target selector). Self-heal does not rewrite adragstep: with two selectors it cannot know which end broke, and guessing would corrupt the good one.The five above run on Playwright and on WebDriver. On Appium they are refused by name — a native "back" is the device's back button, which is a different thing with the same word.
All are documented in the actions reference.
AI
Generated tests and self-heal now read the page the way a screen reader does. The generator and the healer are grounded on the page's accessibility tree instead of a scraped element list or raw HTML. It is smaller, and it yields role-and-name selectors — the kind that survive a restyle. Values typed into fields are redacted before anything leaves the machine, as before; if the redaction cannot be done, Vera falls back to the previous method rather than sending the page unredacted.
The model you type is the model that runs. With your own AI key you can name any model your provider serves. Until now, a model Vera did not already list was silently replaced with the provider's default — the settings page showed your choice and every call used something else. Now an unlisted model is checked once against your provider when you save it: if the provider accepts it, it is saved and used exactly as typed; if not, the save is refused and you see the provider's own error. With no key saved yet, the model is kept as typed and marked unverified rather than swapped. The check spends one small request on your key, only when you save a new unlisted model.
Fix: saving workspace settings could quietly un-verify your AI key. Any change under Settings → Workspace (a Testing & ROI number, for instance) dropped the "this key was verified" stamp, after which every AI feature answered that a key was required until someone pressed Test again. The stamp now survives. If AI stopped working for your workspace after an unrelated settings change, press Test once under Settings → AI.
Self-hosting: point Vera at any OpenAI-compatible endpoint — Ollama, LM Studio, vLLM or a gateway — with
QA_AI_PROVIDER=openai-compatible,QA_AI_BASE_URLandQA_AI_BASE_MODEL(an API key is optional). This is an operator setting in the server's environment, not something a workspace can choose. Vera refuses to start on a half-filled configuration rather than fail in the middle of a generation. Costs for these calls are recorded as unmeasured, because Vera has no price list for a model it cannot name.Testing your own AI key now also reports which models that key's provider offers today. The list comes from Anthropic, OpenAI or Google directly rather than from a table inside Vera, and is refreshed at most once a day. This is groundwork: the model picker does not read it yet, so nothing about choosing a model changes in this release. If the provider's model list cannot be reached, your key is still reported as verified — the two answers are independent.
Docs
- Eight features that shipped without a guide now have one: load & security, chains, radar, issues, repro, repair proposals, the test explorer and AI planning. The browser guide gains a section on testing behind captchas and bot protection.
2026-09-18
Load testing
You can start a load run from the product. The Load & security tab could list and cancel load runs but not create one — that took a hand-written API call. New load run composes one from target paths, virtual users, ramp, duration and optional p95 / error-rate / throughput budgets, or derives one from a HAR upload or your approved API contract rules. A derived script is previewed before anything starts, including what was dropped and why.
A finished load run shows what it measured — percentiles, throughput and error rate against the budgets you set — and can be downloaded.
AI
- Fix: Google bring-your-own-key workspaces were being pinned to a withdrawn
model. The list of models a workspace may choose still offered
gemini-1.5-proandgemini-1.5-flash, which Google has retired, and any other choice was silently rewritten to that default. The list now offers only models that are currently served and priced; defaults aregemini-3.7-flashfor Google andgpt-5.6-solfor OpenAI. If your workspace uses a Google key, re-check your model under Settings → AI.
2026-09-06
Local agent
A run whose agent dies during a page load no longer replays your whole test. When a local agent lost its lease — the machine crashed, the network went, someone killed the process — the run was handed to another agent, which re-executed the test from step 1. Anything the first attempt had already done was done again: a cart checked out twice, an order placed twice under two different numbers, a confirmation email sent twice. Vera's own records looked perfect throughout — one run row, one set of step results — so the only place the duplicate ever showed up was in your application, which is why this went unnoticed for so long. The agent now reports each step as it completes, the run row keeps those results, and a requeued run starts at the first step that has no result.
The honest limit, and please read it before relying on this: a resumed run gets a fresh browser, so it can only start on a step that does not need the page the lost machine was on — in practice, a navigation. If your agent died on a click, a wait or an assertion, Vera refuses to resume and replays the whole test, exactly as before. So this closes the duplicate for a run lost while loading a page, and not for one lost just after a checkout click. Widening it is being worked on.
The one step that may still have happened twice is named. The step that was running at the instant the machine died is genuinely unknowable — the process that would have told us is gone, so Vera cannot say whether its request reached your app. That step is re-run and marked in the run's step results as possibly-repeated, and the steps inherited from the lost attempt are marked as carried over. If you need to reconcile something, you now have a step to look at instead of a journey to audit.
Two further situations replay, and say so in the run log: when the test was edited between attempts, and when the already-completed steps contain an
ifor aloop, because starting past a branch a dead process chose would run a branch nobody asked for. Full details in the local agent guide.
2026-09-05
Local agent
The agent now checks that a browser is really there, not just that a folder is named after one. Its pre-flight looked for a directory called
chromium-…in Playwright's cache and asked nothing further, so a half-downloaded install, or one a cleanup script had emptied out, looked healthy. The agent would start, take work, and then fail every run at the moment it tried to launch — and because the runs were failing, not the machine, there was nothing pointing at the real problem. It now looks for the browser itself, and refuses to start with one clear message if it is not there.A missing browser now always tells you how to fix it.
Install it with vera-agent install-browserswas only ever printed to someone sitting at a terminal who answered "no" to the install prompt. Anywhere without a terminal — which is every CI runner — you gotPlaywright installer exited with code 1and nothing else. The audience most likely to hit a missing browser was the one audience never told what to do about it. That sentence is now printed on every path that refuses.You can tell the agent not to download a browser:
VERA_AGENT_NO_AUTO_INSTALL=true. Without a terminal to ask, the agent installed Chromium unattended and there was no way to decline — so a fleet of fresh CI images each pulled several hundred megabytes, once per job, without anyone asking for it. Set the variable and the agent refuses immediately instead, with thevera-agent install-browsersremedy. Worth setting on any image that already ships a browser: no download, and a loud failure if the image is wrong. The default is unchanged — on a laptop, the first run still fetches Chromium and gets on with it.
Runs
- A run that dies before it can start the browser now shows its steps. It used to arrive as a failed run with no per-step record whatsoever — not one row, not even a skipped one — so there was no way to tell "the browser never started, so nothing was attempted" from "something was attempted and we are not saying what". Every authored step is now listed as skipped, with the reason, which is the rule the rest of the product already followed.
2026-09-04
Shared reports
- The "Powered by Vera" line on a public report is now a link. It had always been plain text, so someone reading a run report you shared — a colleague, a client, whoever you sent it to — had no way to get from it to Vera except by typing the name into a search engine. It now goes to the site, from both the watermark at the foot of the report and the brand lockup in its header, and opens in a new tab so it does not take a reader out of the report they were sent to read. Self-hosted deployments link the same place: the page is served from your domain, but "Powered by Vera" still means Vera.
Docs
/guide/getting-startednow opens with the answer. It began by explaining that there are two different "getting started" paths and that you should work out which one you are on — true, but it meant the page that exists to answer "how do I start" had no answer in it for anyone skimming, or for an assistant quoting it. It now leads with the command and what it does, and the routing note follows.- Fixed a link in that page that went nowhere. It pointed self-hosters at the repository's README, which is not reachable from the public site, so it rendered as plain text with no destination. It now links the self-hosting guide.
2026-09-03
Local agent
Self-heal on agent runs is now something you switch on. Previously the local agent repaired broken selectors on every run it executed, with no setting anywhere to say yes or no — the only executor that did. Each repair is an AI call billed to your workspace (your own API key, or your free grant), so an agent left running all day was spending on a behaviour nobody had asked for. It is now off unless a workspace admin turns it on (
settings.agent.selfHeal), which matches how repair already worked everywhere else in Vera: the Repair button, the auto-repair setting on a project, and the self-heal option on AI generation are all explicit choices.What this changes for you. If your agent runs were relying on self-heal, they will stop healing until an admin enables it, and a step that would have been repaired now simply fails — which it would have done anyway had the repair not worked. Runs that did not depend on healing are unaffected. This takes effect for every agent, including copies of
vera-agentalready installed: the control plane refuses the repair regardless of the CLI version, so there is nothing to upgrade to get it. On an older CLI the failed step records the reason ("Self-heal is not enabled for this workspace") rather than reporting that the model found nothing.Two things deliberately did not change: healing still requires a plan that includes repair, and that refusal still reads differently from this one; and nothing about the cloud executors moved — a run started from CI or the Run button has never healed and still does not.
vera-agent 0.5.0
The local agent's first release since 0.4.0. Upgrade with
npm install -g vera-agent@latest; the GitHub Action's pinned default moved to
0.5.0 in the same release, so CI picks it up on your next workflow update.
- A run started on the agent can be stopped. Cancelling from the dashboard, the API or MCP already wrote the request down; the packaged agent now acts on it, so the run ends at its next step boundary instead of running to completion with nobody waiting for it. This was fixed in the product before it was in the CLI you install — that gap is what this release closes.
- The environment's engine, grid URL and device now reach an agent run. Picking an environment and then running on the agent used to silently fall back to the test's own settings.
- Self-heal says why. A heal now records the model's reasoning alongside the selector it changed, and — more useful — so does a heal that did not happen. "Self-heal requires the Pro plan" and "no confident match on this page" were previously the same one-word answer.
- An AI outage is no longer recorded as the model declining to heal. If the provider was unreachable, the run says so instead of reporting that nothing could be repaired.
Reliability
- A non-functional job killed by a deploy no longer sits at
runningforever. A load run or security scan still executing when the worker is told to shut down now gets a terminal status and a message saying the deploy ended it — including, honestly, that traffic did reach your target before it stopped.
Notifications
- A run that went green only because self-heal rewrote a selector now reaches people who subscribed to failures only. It is still reported as a pass — in Slack, in email, on the webhook and in CI — because healing rewrites the locator and never the expectation. But the step may no longer drive the control it was written for, which a pass/fail line cannot show, and that is exactly what a failures-only subscription is for. If you have a rule filtered to failures, expect the occasional message about a passing run; it says passed only after self-heal rewrote a selector on its face. A clean pass still does not reach you.
Fixes
- A chain segment that was cancelled is no longer recorded as failed. The status was being overwritten at the engine, so the truth did not survive to any surface that could have shown it.
- On the Selenium/WebDriver engine, a selector the grid cannot parse now fails at once and quotes the grid. It used to be retried until the step's timeout ran out — thirty seconds by default — and then reported as though the element had simply never appeared, which named neither the cause nor the engine. A dead grid session is now reported as a dead session for the same reason. Waiting for an element that is not there yet is unchanged.
2026-08-29
Recording
- Older recordings that target a form control by its
<label>text replay again — and a broken one now takes 30 seconds to fail instead of failing at once. Those steps used to die immediately withUnknown engine "label"; they now resolve and run. The slower failure is the price and is why this is listed: if the label is no longer on the page, the step waits out the full 30-second selector timeout before failing. It costs one step per run — everything after a failed step is skipped either way.
2026-08-20
Reliability
- A redelivered job can no longer run twice. Queued runs are now claimed
under a renewable lease, so if a worker is killed mid-run the job is picked up
by another worker rather than executed twice or stranded in
runningforever. - Runs have a wall-clock ceiling. A run that hangs is now stopped and reported rather than holding a browser indefinitely.
- Deploys drain in-flight runs. A restart waits for running tests to finish writing their results instead of killing them mid-write.
/api/health/readyreports real dependencies. Database, schema version, queue and live workers are each checked, so "the API answers" and "the API can actually take work" stopped being the same signal.
Billing
- A failed card no longer looks like a cancellation. A payment retry
(
past_due) keeps the workspace on its plan while the provider retries; the downgrade happens only when the subscription actually ends. Previously the first failed charge dropped the workspace to Free immediately. - Plan changes are explained. When a workspace changes plan — in either direction — its admins get an email stating what changed about the workspace: concurrency, retention, and which features moved. A downgrade notice says explicitly that projects, tests and history are unchanged.
Consumption
- Usage is visible before it is enforced. Settings → Billing now shows runs, run minutes and artifact storage for the current period against the plan's allowance, and warns at 70/90/100% — once per period per limit, in-product and by email.
Workspaces
- Self-service closure. A workspace can be closed from Settings, with a grace period before its data is purged, and exported first.
2026-08-19
Testing
- Assertion sensitivity works on any test, not only dataset-backed ones. A test can now be checked for whether its assertions would actually catch a regression, regardless of how it was authored.
/proof— a public page explaining what Vera's coverage claims do and do not mean.
Fixes
- Pricing cards no longer omit two features the plans include.
- The Enterprise card no longer advertises self-hosting.
2026-08-18
Local agent
vera-agentruns project setup actions on leased runs, so a test that depends on seeded fixtures behaves the same locally as in the cloud.- Capability scopes on agent tokens — an agent token can be limited to what that machine is allowed to do, and the agent reports any capability it had to drop rather than silently degrading.
- Visual regression works for agent runs.
Privacy
- Self-heal DOM snapshots are redacted before leaving the machine. The snapshot Vera sends to repair a broken selector no longer carries input values.
- Published what Vera stores and where it goes — see data handling.
Operations
- Optional error reporting (Sentry), budgeted so it cannot run away on the free plan.
- Operator email on new signups.