Release Notes
v1.1.1 September 2026
Before comparing reports from this release against earlier ones: two changes affect how many instances are reported. Suppression rules now match more reliably, and the broken-links check confirms a link is unreachable before listing it. On some sites both reduce the number of rows without anything on the site having changed.
Reports now list the components and widgets found on each page. Carousels, book rivers, slideshows, event cards, branch selects, forms, iframes, video, maps, modals, tabs and menus, with a count per page, an example selector and what to check on each. It answers "which pages have a book river" and "where is every carousel and iframe on this site" from the scan itself, rather than by opening pages one at a time. The inventory records which components are present: configuration such as autoplay, pause controls and hover behavior is not expressed in the page markup and is not reported, so those remain manual checks. The section appears in the report viewer, the Markdown report, the PDF and Notion, alongside a new components.csv with one row per page per component.
Related components are grouped. Book rivers, slideshows and standard carousels are listed separately, because each needs a different check, and also totaled together as one family - so asking whether a site has carousels reaches all three. Map embeds and video players are grouped with iframes the same way.
Re-scan comparisons now distinguish a fixed page from one that was not visited. Findings missing from a newer scan are classified as fixed, still present, or not observed, and a page that was not reached in the newer crawl is reported as unproven rather than remediated. Comparisons also note when two scans came from different versions of Vesper, since rules change between releases and a difference can come from the tool rather than the site.
Suppression rules now match containing blocks. A suppression naming a wrapper or block class is tested against the element and the chain of containers around it, so rules written against a block class take effect as intended. Sites using these rules will see fewer reported instances. The scan log continues to flag a suppression that matches nothing, which usually indicates a typo in the rule.
The broken-links report confirms a link is unreachable before reporting it. Links are retried with a full request and browser headers, redirects are followed to their destination, and only a confirmed missing page, an unresolvable domain or a refused connection is reported as broken. Links that cannot be verified automatically - servers that block automated requests, timeouts, rate limits, certificate warnings - are listed separately as unverified, with the reason.
The keyboard focus indicator in the report viewer is now defined per theme rather than relying on the browser default, so the focused control is visible in both light and dark modes.
Map embeds are identified by the embed itself, rather than by page elements that happen to share the name, so the reported example points at the map. Webforms embedded on more than one page are reported under a single name rather than as a separate form per page.
The MCP server carries the component inventory too - see the MCP Server documentation.
v1.0.0 August 2026
The first stable release. Vesper Audit now has a way to pay for itself, and a crawl that no longer stops partway through on sites that publish documents.
A full-site crawl could stop partway through on any site that links to downloadable files. When the crawler reached a link pointing at a PDF, a Word document, a spreadsheet or an installer, the browser began downloading the file instead of opening a page, and the scan waited for a transfer that was never going to finish. On a site with board minutes, budget spreadsheets or meeting recordings, a scan could stall and never complete. Vesper now recognizes links that are files rather than pages and skips them, and it refuses downloads outright as a second layer, so a file served in a way no filename could reveal cannot stall the scan either. Nothing is written to your disk during a scan. If you have had a crawl hang on a document-heavy site, this is why.
Vesper Audit is now paid for by the people who use it. There are no investors and no advertising behind this tool, so a subscription is not a small line in a large budget. It is the budget.
The free tier stays free and needs no license key. Single page scans, the full in-app report viewer with WCAG references and guide links, and the page load timeout are all free, with no account, no sign-up and no expiry. If a single-page scan is what your work needs, that is a complete tool and it stays that way.
A Supporter subscription is $99 a year and covers two Macs. It adds full-site crawls, the PDF, Markdown, CSV and Notion exports, viewport width, saved profiles, exclusions and suppressions, the report filter, and your own name as the auditor on every exported report. You can move a seat between machines at any time by deactivating one.
There is a seven-day trial with everything unlocked, and it does not ask for a card. Start it from Settings, under License and plan.
Your reports and settings are yours whatever happens to a subscription. Everything Vesper has written to disk stays where it is, readable, if a subscription lapses or you stop using the app. Nothing is held hostage and nothing phones home to check before letting you open a file you already have.
The app now tells you when it cannot reach the licensing server. Previously an unreachable server looked exactly like a machine with no license: the app quietly showed the free plan and said nothing. If you are offline, or something is wrong at our end, you will now see a note saying the plan shown may be out of date, and your access does not change while that is true.
v1.0.0-beta.66 August 2026
A new optional check for the colors a site uses on links, and a correction to how contrast is measured on semi-transparent backgrounds.
Please read the note about changed numbers below if you compare reports between versions.
A link color can pass everywhere you look and still be too light. Contrast is measured between text and the background it is actually sitting on, so a brand color used on a white page is checked against white. Put that same color on a pale grey panel and it may fail - but nothing reports it unless some page happens to combine the two. A site whose calendar has no events that month, or which simply has no grey panels yet, gets a clean result and still has the problem sitting in its theme, waiting for a redesign or a new template to expose it.
You can now name the background colors you care about. In Settings there is a new Palette contrast section. Add the backgrounds your platform actually uses - the page white, a panel grey, whatever your templates put behind text - and Vesper measures every link color it finds on the site against each of them, whether or not the site currently combines them. Anything falling below 4.5:1 is reported so you can decide before it becomes visible.
This does not turn the contrast check on or off. The standard contrast check measures text as it is actually rendered and runs on every scan no matter what you put here. The new setting only adds a second, separate question, and it never removes anything. Leave it empty and your reports are exactly as they were.
Findings are informational, not violations. A color and a background the site never puts together is not a failure on any page today, so these are reported for review and are not counted in your totals. Nothing in your severity numbers changes, and reports from before and after this release stay comparable.
Vesper will not waste your time with combinations your design would never make. White link text on a dark brand bar is correct, and measuring it against a white background produces a true but meaningless 1:1. Vesper only reports a pairing when the site already uses that color on a background similar to the one you named, so the question is about a real palette rather than arithmetic. Pairs set aside this way are still listed, with the reason - a result that quietly disappeared would look exactly like one that passed.
It appears in every report format. The PDF, Notion, Markdown, CSV and the in-app viewer all carry the same section. A report should not depend on which format somebody happens to open.
Contrast is now measured correctly on semi-transparent backgrounds, and some numbers will change. A striped table, a tinted panel or a subtle overlay is usually built with a see-through color laid over whatever is beneath it. Vesper was reading that see-through color on its own instead of working out what it actually looks like once the two are combined. On a table with faintly shaded alternate rows, a light grey stripe was being read as solid black.
This mattered most in the direction that hides a problem. Pale text on a barely-shaded row is close to unreadable, and Vesper could report it as a comfortable pass. The reverse also happened: readable text reported as slightly worse than it is. Both are now measured against the color a visitor actually sees.
Your counted violations were never affected. The main color contrast check has always handled see-through backgrounds correctly. What was wrong were the two informational measurements beside it - the link underlining report and the new palette check - which could disagree with the contrast check inside the same report. They now agree.
What to expect on a re-scan. Ratios on striped tables and tinted panels will move, usually by a small amount, and occasionally by a lot where the shading is very light. Nothing about those pages changed; the earlier figure was wrong. If you have a report where a link on a shaded row looked fine, it is worth re-checking.
v1.0.0-beta.62 August 2026
Corrections to the form-field checking introduced in beta.61, and a new guide explaining it.
An address that belongs to something rather than someone is no longer treated as the visitor's own. Where a form asked for the location of an event, a room or a program, Vesper suggested the settings that make a browser fill in the person's home address. Acting on that would autofill a patron's own address into the field for where their event is being held, which is a failure in its own right rather than a fix. Vesper now reads how the fields are named to work out whose information a block holds: a field whose name says "your" is the visitor's, and one whose name says "event", "room" or "program" belongs to that thing and is left alone. If you acted on a beta.61 report and set address purposes on a venue or location field, those should be removed.
A single large Address box now gets the right setting. Where a form used one multi-line box for a whole address instead of separate boxes for street, city and postal code, Vesper had no answer and asked you to decide. It now suggests the whole-address setting.
Vesper is more careful about calling a finding certain. "Certain" means no judgment is involved, and it is the grade you are entitled to skip past. It was being applied to fields naming a role - a "Contact Person Phone Number" on an event booking form - where whether that person is the one filling in the form is genuinely a judgment. Those are now listed for you to confirm instead. A field labeled with two purposes at once, such as "Phone/Email", is also no longer given one of the two arbitrarily; a single field cannot declare two purposes, and leaving it alone is a defensible answer.
A filtered report now says what the filter covered. Narrowing a scan to one category has always narrowed the list of violations only, leaving the standing checks - image sizes, link underlining, overlay detection and the form-field worklist - reported in full. That is deliberate: those are measurements rather than findings, and you are entitled to them either way. But the report never said so, and whoever receives a filtered report is usually not the person who chose the filter. Every format now states it. The Markdown report, which did not mention the filter at all, now discloses it like the others.
Smaller fixes. The notice about pages that may not be real content read "1 soft 404 ... but look like an error"; it now agrees with itself. Links to Vesper's own guidance were built in a form the website redirects to the guides index, so "Learn more" landed on a list rather than on the page it named.
A new guide: Identifying Input Purpose. What these form-field settings are, the full list for common library forms, and how to tell which fields should never get one because they ask about somebody other than the person filling in the form. Linked from every finding of this kind.
v1.0.0-beta.61 August 2026
Vesper Audit now checks something no accessibility tool has been checking: form fields that never say what they are for.
Please read the note about existing reports below before sharing results from this version with a client.
Form fields with no declared purpose (WCAG 1.3.5, Level AA). When a form field says what it is for, a browser can fill it in. That is a convenience for most people and the difference between finishing a form and giving up for others: someone with a tremor for whom every keystroke costs effort, someone who cannot reliably recall their own postal code, or someone whose assistive technology swaps your labels for words they know better. Until now, no checker reported a field that was missing this. The published rules only check whether a value that is already there is spelled correctly, so a field with nothing set was invisible to every tool on the market, including this one. Vesper now finds them.
Where a field asks for the patron's own details and has nothing set, that is a WCAG 1.3.5 failure at Level AA. It is required work, not polish. What Vesper cannot always decide is which fields those are, because the criterion applies only to fields collecting information about the person filling in the form. So findings are split by how much judgment they need, and the grade says how sure Vesper is about who the field is about, not how serious the problem is.
Email and telephone inputs are reported as violations and counted. The input type has already declared what the field holds, so there is no judgment to make. This covers a field with nothing set and a field carrying "on" or "off", which are browser toggles rather than purposes. Expect these to appear in your severity totals from now on, and to see them on the summary page alongside a count of the form elements needing an edit.
Everything else is listed for you to confirm. A field whose name or label makes its purpose clear, or one that only loosely suggests personal data, is reported without being counted. Confirm it is about the patron and it is the same Level AA failure as the ones above, worth the same fix. Setting a purpose on somebody else's details is its own failure, so where a field turns out to be an emergency contact, a nominee, or an ancestor on a genealogy request, leave it alone.
"On" is the trap, and it is the default. In Drupal Webform, every new field arrives with Autocomplete set to On. It looks like the helpful choice, it writes nothing into the page, and it satisfies nothing. A field nobody edited is a field with nothing set.
Fields that ask about somebody else are left alone deliberately. An emergency contact's phone number, a nomination form asking who you are nominating, a genealogy request naming an ancestor, or a backup contact for a homebound patron are not about the person filling in the form, and giving them a purpose would autofill the wrong person's details. Vesper recognizes these both from their labels and from how the fields are grouped together, and reports nothing for them.
Results are grouped by form, not by page. A form that appears in the footer of forty pages is one thing to fix. So is a form served at several web addresses, and so is a form that appears both on its own page and embedded in another. Vesper counts the work once and tells you which addresses share it. The count you see is the number of fields you actually have to edit, which on combined fields like a name or an address is one edit covering several boxes rather than one per box.
A new spreadsheet. Scans that produce CSV output now also write an autocomplete file, listing every field with its form, its current setting, the suggested purpose and the reason. It is built to hand to whoever maintains the site.
About your existing reports, and your severity totals. No accessibility checker has ever reported this, which means every audit anyone has produced is silent on it. A site previously reported as passing this criterion will now show findings, and that is true of every site, not a select few. Because email and telephone fields are counted as violations, a re-scan can show more violations than the last report without anything having got worse. These fields were always like this; there was simply no tool that could see them. If you are re-scanning a site you have already reported on, explain this up front rather than leaving a reader to discover a rising number on their own.
v1.0.0-beta.60 August 2026
The fix in beta.59 for audits that read nothing had a gap. This closes it, and corrects the date printed on every report.
A page that failed to load was being counted as a page that was audited. beta.59 made a scan that read nothing report a failure instead of a clean result. That check counted pages, and the count included pages Vesper had tried to open and could not - so a site whose address did not resolve came back as "1 page audited, no violations found" and wrote a full report bundle, PDF included. The banner in the app said the scan had failed; everything written to disk said otherwise. This is the ordinary case, not an exotic one: a typo in the address, an expired certificate, a firewall or captive portal, a site down for maintenance, a login wall. Pages that could not be opened are now counted separately from pages that were audited, and a scan that opened nothing is treated as a failure in every format. If you hold a report that names a small number of pages but shows no findings at all, check whether those pages actually loaded - "1 page audited, 0 issues" was how this looked.
A scan that failed on part of a site now says so. Previously only a total failure was reported. A crawl that read forty pages and could not open six finished quietly, and nothing in the report - not the summary, not the PDF, not the Notion page - mentioned the six. The site looked fully covered. Every format now states how many pages could not be opened and names them, and they are excluded from the counts rather than quietly counted as clean.
The date on a report could be a day ahead of the scan. Reports printed the date in UTC while printing the time in your own timezone, so any scan run in the evening was dated the following day - on the PDF cover, in the Markdown, in the Notion page, and in the report viewer. The folder the report was saved into used the correct local date all along, so a report and its own folder could disagree. Everything now prints your local date. A delivered report dated a day after you ran it was showing this; the findings in it were never affected.
Two counts of the same thing could disagree. "Pages with issues" was worked out separately by the summary, the PDF and the underlying data, and a page that failed to load was treated as a page with issues by two of the three. A one-page scan of a site that never loaded could report "1 page with issues" beside "0 critical, 0 serious, 0 moderate, 0 minor". It is now counted once.
A report no longer claims axe-core ran when it did not. The PDF cover and the report viewer both stated the testing method unconditionally. On a scan where nothing loaded, no rules ran at all, and the report still said it had been tested automatically.
A suppression that matches nothing no longer guesses why. The warning added in beta.59 ended by suggesting a typo in the selector. On three separate client sites the selector was correct and the site simply used a different variant of the same component, so the hint sent people to edit a working configuration. It now reports what it found without inventing a cause. It also stays quiet when no page was audited, since a suppression cannot match anything on a page that never loaded.
The MCP server returns a file path that opens. Paths to the finished report were being reported through a symbolic link rather than the real location, so a tool that tried to read the results file could fail to find it even though the file was there.
v1.0.0-beta.59 August 2026
Four fixes, two of which affect whether you can trust a report you have already sent.
A suggested phone number could come back missing its area code. When a phone link carried an extension after a comma - tel:+16306270316,405, a common way to write a direct line - Vesper correctly flagged the link as broken and then offered a corrected address to paste in. That correction silently dropped three digits from the front of the number. It looked entirely plausible, it was a valid phone address, and a page "fixed" with it would have passed the check on the next scan while no longer reaching the library. Extensions are now offered in the standard ;ext= form with every digit preserved, and Vesper refuses to print a corrected number at all unless it can account for every digit you wrote. The same fault affected numbers outside North America: a London number written with spaces was being rewritten into an unrelated US number. If you have sent remediation guidance containing a corrected tel: value, it is worth re-checking against the number on the site.
An audit that could not read a single page reported success and produced a report. If the address you gave Vesper could not be reached - a redirect it declined to follow, a block, a firewall, a typo - the scan finished green, said "0 pages scanned", and wrote a full report bundle including a PDF titled with the site's name. Every count in it was zero, and zero findings looks exactly like a clean site. Vesper now treats this as a failure rather than a result: the scan reports an error, says what stopped it, and every format - the in-app report, the PDF, the Markdown, the CSV, the Notion page - states on its face that nothing was audited and must not be read as a pass. If you hold a report showing zero pages audited, it is not a clean bill of health and never was.
A site's address with and without www. is now understood as one site. Giving Vesper yourlibrary.org when the site redirects to www.yourlibrary.org caused it to treat its own destination as somebody else's website and skip it, so the scan came back empty. Both forms are now recognized as the same site. Separate subdomains - a catalog, an events system, a hosted booking tool - are deliberately still treated as separate sites, because they usually belong to a different vendor and need a different fix.
Skipped addresses now say why, and where they went. A page Vesper declined to open used to appear with nothing but its address, leaving no way to tell a real gap in coverage from correct behavior at the edge of the site. Each now carries a reason and, for a redirect, the address it actually resolved to.
An image link's name is now credited to the image. When a link contains nothing but a picture, the name a screen reader announces comes from that picture's alt text. Vesper reported the name correctly but said it came from the link's own text, which pointed anyone reading the report at markup that does not exist.
v1.0.0-beta.58 August 2026
Corrections to how findings are evidenced, and one reliability fix worth reading.
Reports no longer miss stylesheets that arrive through another stylesheet. A theme can pull in a second stylesheet with an @import instead of a link in the page, and the link-underline check never followed those. Two things went wrong at once: any underline rule or exception inside an imported file was invisible, and the report still stated that every stylesheet had been read. A result that had skipped a file was being presented as complete. Imported stylesheets are now followed, including ones that import others in turn, and any that still cannot be read are named individually along with how they were reached. If you have an earlier report on a site whose theme uses @import, its statement about stylesheet coverage was optimistic - a rescan will say so accurately.
"Setting: On" is no longer said about a site where no link is underlined. A theme can carry a rule that underlines links and then cancel it with a later rule, so the setting is technically on and no reader ever sees an underline. The report now says "On, but not reaching any link" and explains that the rule exists but never reaches the page.
Evidence snippets are no longer cut off before the useful part. Each finding carries a piece of the element's markup, trimmed to keep reports readable, and it was always trimmed from the end. An element with a long opening tag - an inline icon, a long list of classes - lost its own text, so a button reading "View All Services" could appear in the report as though it had no text at all. Snippets now keep both ends and say how much was left out in between.
Every finding on an element now carries that element's accessible name - the text a screen reader announces - and where it came from: an aria-label, a title, the element's own text, or nothing at all. Where a rule fires precisely because an element has no accessible name, the report states that outright rather than leaving it to be worked out from a fragment of markup. It appears in the reports, the CSV and the MCP results.
Findings on repeated embeds now say which embed. When a page carries several embeds from the same source without distinct titles, every finding pointed at the same generic location. Each now names the address it embeds.
Link decoration no longer appears in the PDF or the Notion page. Those two are the client-facing report, and a table of links with contrast ratios reads as a list of defects to someone who did not commission the measurement - which, as the report itself says, it is not. It remains in the in-app report, Markdown, CSV and the MCP results, where the audit work happens. The same decision was already in force for the hover and focus measurements.
v1.0.0-beta.52 August 2026
One feature, and the fixes that made its numbers trustworthy.
Vesper Audit now reports which links are distinguished from the text around them by color alone. WCAG 1.4.1 asks that where color is the only difference between a link and its surrounding text, that difference reaches 3:1. No automated rule answered this reliably - the closest one fires on a small fraction of sites, so its silence never meant a site was clean. Vesper now reads the computed style of every link on every page and reports two things: whether the site underlines links by default, and every link that ended up without one, with the CSS rule that removed it, the link's color and weight, and the contrast against the nearest text that is not a link. It appears in the in-app report, Markdown, PDF, Notion, a new link-decoration.csv, and the MCP server's results.
Links inside menus are measured, not skipped. A dropdown or mega menu whose column headings are ordinary bold text sitting above bold link text is one of the most common places this hides, and it is invisible to any check that treats "inside the navigation" as a reason to look away. Vesper measures those links, labels them so you can filter them, and reads them even when the menu is closed - so a whole mega menu is no longer skipped because nobody clicked it open during the scan.
Every measurement says how close the compared text actually was. When a link has no neighboring text, a check that keeps looking outward will eventually find something unrelated and report a convincing ratio against it. Each row carries the distance the search traveled, so a real neighbor and a coincidence are easy to tell apart. The report explains how to read it.
Counts are distinct elements, not instances. A link in a header or footer template appears on every page, so counting instances makes a number grow with the size of the crawl rather than with the size of the site - the same theme scanned at 50 pages and at 150 would report wildly different figures. Every count is now the number of distinct elements, with the instance total shown beside it and the number of pages each one appears on.
Hover and focus are reported too, and kept apart. A link can be underlined at rest and stay underlined on hover, so hovering tells the reader nothing. Vesper reports where that happens. No success criterion requires a hover affordance, so this is a design question rather than a WCAG failure, and it is described that way. Focus is different - WCAG 2.4.7 does require a visible focus indicator - but an outline, a shadow or a background change satisfies it just as well, and those are not measured here, so a focus result is a prompt to go and look rather than a finding.
This is a measurement, not a verdict. Vesper reports what it found and leaves the judgment to you, the same way it handles accessibility-overlay detection. None of it counts toward the Critical, Serious, Moderate or Minor totals. Links presented as buttons, pagers, breadcrumbs or icons are excluded, since their shape already tells you they are interactive, and skip links are excluded because they are hidden until focused and are never findings.
Stylesheets that could not be read are named. A stylesheet served from another domain cannot be inspected, and a result that quietly skipped one is not a clean result. Where that happens the report says so and marks the finding provisional.
Stopping a scan at the page budget now builds the report. When a crawl paused at your page budget, choosing to stop discarded everything it had scanned - the button offered a review it could not produce. Stopping now finishes the crawl properly and writes the full report for the pages already visited, and the report opens by stating that it is partial and how many pages were never reached. The pause itself also reads honestly: it says how many URLs are still queued, only offers to apply exclusions when it has some to suggest, and no longer styles stopping as though it were destructive.
PDF export works from the MCP server. Asking an assistant for a full audit with a PDF returned every other format and an error for that one. The PDF is now produced the same way and to the same page setup wherever the scan was started from.
v1.0.0-beta.47 August 2026
A large release covering everything since beta.42.
An AI assistant can now run a full audit for you. Vesper Audit ships an MCP server, so any client that speaks Model Context Protocol - Claude Desktop, Claude Code, Cursor, Zed, VS Code and others - can be pointed at it and asked to audit a site. It crawls the whole thing and writes the same report bundle you would get from running the scan yourself: the JSON, CSV, Markdown and optionally PDF, in your usual output folder, with the usual folder name. The assistant gets the path and reads the complete results from there, so it works from every finding rather than a sample. Four tools are available: scan_url for a single page, scan_site for a full crawl, scan_status to follow one in progress, and check_contact_links for broken tel: and mailto: links. The workflow this is built for is the remediation loop: change a template, ask for a rescan, see whether the finding cleared. Setup lives in the app under Settings > MCP server and in full on the MCP Server page. Scans still run entirely on your own machine using your own Chrome; nothing is sent anywhere.
Long crawls do not time out, and a site scan audits the whole site. A crawl starts and returns immediately, then reports progress - how many pages so far, and which page it is on - while it runs. It uses the page budget from your Scan settings rather than stopping at an arbitrary cap. And if a scan does hit its limit, the result says it stopped and how many pages it never reached: a partial audit that looks complete is worse than one that refuses, because nothing tells you the pages you cared about were never visited.
Broken phone and email links are now detected. A tel: link whose visible text reads perfectly can still carry an href no dialer can parse - URL-encoded parentheses, literal spaces, a stray plus in the wrong place. The defect is invisible to sighted review and the link simply fails to dial. Vesper Audit now checks every tel: and mailto: link and reports the specific problem alongside a corrected href you can paste in. These are reported as functional defects rather than WCAG failures, and carry no WCAG criterion, because a broken link is broken for everyone - the report says so plainly rather than claiming a success criterion it does not fail.
Pages whose only issues are invisible no longer count as pages with issues. A hidden element in a site template - a phone link inside an inactive tab panel, say - appears on every page, which could make an entire site report zero clean pages when almost all of them were clean to a visitor. Findings on elements that were not being presented at scan time are still reported in full, but they no longer count against the clean-page total, and the Rendered column in violations.csv marks them. That column is a real determination for every finding: Yes means the element was checked and was being presented, No means it was hidden, and an empty cell means no determination could be made - never a default. Screen-reader-only content is deliberately treated as rendered, since it is in the accessibility tree and a defect on it is a real defect.
Large image warnings no longer depend on the order pages were crawled in. When the same oversized image appeared on several pages, only the first page to load it was recorded - the browser served it from its cache everywhere else, so the scan never saw it again. The Large Images Report states how many pages carry each image, and that count could differ between two scans of a site that had not changed at all. Every page using the image is now counted, without re-downloading anything.
Suppressions that match nothing are called out. A suppression with a stale selector looks exactly like one that is working - both leave no trace in the report - so a rule that silently stopped matching could hide findings you believed were being filtered deliberately. Every suppression now reports how many instances it actually removed, and any that matched nothing is flagged in the report and in the live scan log.
Pages that are not real content are surfaced separately. Soft 404s and maintenance pages scan clean simply because there is nothing on them to fail. These are listed in their own section and flagged in summary.csv, so a page that passed for the wrong reason is not mistaken for a page that passed.
The scan log is saved with the report. Skipped pages, off-domain redirects, applied exclusions, per-page errors and suppressions that matched nothing were all recorded during a scan and then discarded when it finished. They are now part of the saved results, so a scan you open months later still explains itself. Every report also records the Vesper Audit and axe-core versions that produced it - rule behavior changes between builds, so when comparing against an earlier scan that is the first thing to check.
The updater can no longer take you backwards, and no longer offers to. Two separate faults produced the same result. The app was willing to treat an older version as an available update, so it would download one and offer it; and a downloaded update installed itself on quit regardless of what was actually running, so you could quietly end up on an older version than you started with with nothing to tell you. Older versions are now never offered, and an update installs when you click Restart now in the banner, only when it is genuinely newer. Anything stale is discarded.
Optional zipped reports. Settings, Report options, "Also save a zip of each report". A report is a folder, so sharing one always meant zipping it by hand first. The zip is written alongside the folder and the folder is kept, because the report viewer reads it.
Smaller page budgets. Scan settings now offers 50 and 100 pages alongside the existing choices. The budget pauses a scan for review at that page count; the smallest option used to be 500, which put the pause and the pattern suggestions it offers out of reach on a typical library site.
Smaller fixes. Container class signatures no longer include layout utility classes such as position-relative and d-flex, so the same component matches across sites that style it differently. Sitewide rolled-up findings now name the specific element each one refers to, so two findings from the same rule are no longer indistinguishable. Dropdown controls in Settings match the rest of the interface, in both light and dark mode. Both modal dialogs trap keyboard focus correctly and return focus where it came from. Documentation and in-app text no longer read as though one particular AI assistant is required. And the scan-time guidance is honest: measured across real scans it is two to three seconds per page with link checking on, not the roughly one second the docs used to claim.
v1.0.0-beta.42 June 22, 2026
Findings without a landmark now name their nearest container. Some flagged elements sit outside every page landmark (header, nav, main, footer), so the report correctly says "Landmark: none" - but on its own that left no way to place the finding without opening the browser. Vesper Audit now adds a Container line directly below the Landmark line, naming the nearest meaningful ancestor: the nearest stable id (auto-generated ids - entity numbers, hashes, framework ids - are skipped in favor of a stable one, for example div#block-branchselect), a dialog or modal, or a meaningful component class. It appears on every element-bound finding in every format - the in-app viewer, PDF, Markdown, Notion, and a new Container column in both violations.csv and sitewide.csv - and is most useful exactly when the landmark is "none". Pure utility wrappers are skipped so the container is always something meaningful.
Color contrast issues show the exact ratio and the colors involved. A color-contrast finding could previously come through with an empty explanation - no ratio and no foreground or background color - which forced a manual check in the browser. Vesper Audit now shows the full detail on every color-contrast finding: the measured contrast ratio, the required ratio, the gap below the threshold, and the foreground and background colors (for example, "4.33:1, required 4.5:1 - 0.17 below threshold, foreground #0f7547 on background #f6d9d9"). This includes findings rolled up in the Sitewide Template Findings section, and the CSV export's sitewide.csv file has dedicated Contrast Ratio, Foreground, Background, and Expected Ratio columns. When a background can't be measured - a gradient, an image, or a semi-transparent color - the report explains that reason instead of leaving the field blank. This affects every report format: the in-app viewer, PDF, Markdown, CSV, and Notion.
v1.0.0-beta.40 June 9, 2026
PDFs served at a clean URL are no longer scored as web pages. When a site links a PDF at a tidy address with no .pdf on the end, the browser opens it in its built-in PDF viewer - a near-empty shell with no page title or language. Earlier builds ran the web-page checks against that shell and reported the missing title and language as Serious issues, even though the address is a PDF and there is no web page to fix. Vesper Audit now recognizes these during the scan and lists them under PDFs Found (marked "served directly at this URL") instead of scoring them as HTML, so they no longer inflate the severity counts or the audited-page total. A normal page that simply embeds a PDF is unaffected.
Findings that repeat across the whole site are now rolled up. A single template element - a phone link in the header, a block in the footer - appears on every page, so one element could previously show up as hundreds of separate findings and make a site look far worse than it is. Vesper Audit now recognizes when the same finding repeats across most of the site and rolls it into one entry labeled "appears sitewide (N pages)" in a new Sitewide Template Findings section. The severity counts now count each distinct finding once rather than once per page, so the headline numbers reflect the real issues to fix. Every affected page is still listed in the detailed per-page results, so nothing is lost. This appears across the in-app viewer, PDF, Markdown, CSV, and Notion reports, with a dedicated sitewide.csv file in CSV exports.
v1.0.0-beta.37 June 5, 2026
Reports now open on a new Summary page, pinned at the top of the report viewer. It shows the whole audit at a glance: two rings - the total issues split by severity, and how many of the audited pages have issues (hover any section for its exact count) - followed by the counts by severity, scan stats, the top issues ranked by how often each occurs, and expandable reports for ambiguous links, broken links, and large images. A reminder that automated checks can produce false positives sits above those reports. Accessibility overlay detection lives here too, with a short explanation of why overlays are not recommended.
v1.0.0-beta.34 June 4, 2026
Accessibility overlay detection. Vesper Audit now detects third-party accessibility overlay and widget products on the sites it scans - UserWay, accessiBe, Recite Me, ReachDeck/Browsealoud, and others - and names the vendor. Detection is informational: it is a vendor-presence signal, not a WCAG violation, and is never included in the severity totals. Each detected overlay carries a recommendation to remove it and remediate the site directly, because overlays do not fix the underlying HTML and frequently interfere with the assistive technology people already use. Results appear in the in-app viewer, PDF, Markdown, and Notion reports, and as a dedicated overlays.csv file in CSV exports.
v1.0.0-beta.33 June 3, 2026
Landmark context on every finding. Element-bound violations now include a Landmark line directly above the selector in every report format, naming the nearest ARIA landmark (header, footer, nav, main, aside, or a named section) plus the chain of meaningful wrappers down to the flagged element. This makes it immediately clear where on the page each issue lives - for example, telling apart two identical links in the header versus the footer - without opening the live page. CSV exports gain a Landmark column.
v1.0.0-beta.32 May 17, 2026
Two long-standing Pattern Detector bugs are fixed in this build. Clicking Apply on a Pattern card during a scan now removes the card and prunes the queue as intended. Scans no longer cascade into hundreds of wasted iterations when a single page hits a fatal browser frame error - the scan recovers cleanly and continues from the next URL in the queue. Pattern cards also now appear at the threshold count of 25 rather than jumping straight to a post-batch number.
v1.0.0 April 24, 2026
Vesper Audit is a macOS desktop application for automated WCAG 2.2 A/AA accessibility auditing. Provide a starting URL and Vesper Audit produces a complete site-wide report.
Scanning
- Full site crawl. Vesper Audit follows every internal link from your starting URL and audits every page it finds - no sitemap required, no page limit. A running log shows each page as it is scanned.
- Single Page mode. Audit one URL without crawling. Useful for quick spot-checks on a specific page before or after making changes.
- WCAG 2.2 A/AA checks via axe-core. Every page is checked against the full axe-core rule set. Violations and best-practices are reported separately, each with its WCAG criterion reference.
- Custom link text checks. Two checks axe-core does not cover: ambiguous link text (click here, read more, details, raw URLs) and duplicate link text pointing to different destinations. Both map to WCAG 2.4.4 Level A.
- Empty heading detection. Flags headings whose accessible name resolves to nothing - broken
aria-labelledbyreferences, emptyaria-label, or genuinely empty elements. Maps to WCAG 2.4.6. - PDF and broken link scanning. All PDF links and external URLs are collected during the crawl. HTTP HEAD checks run after the scan and flag anything returning an error status.
- Report Filter. Narrow a scan to one rule category: Links, Images, Forms, Color & contrast, Page structure, or Keyboard & focus. Run a focused report for a specific person or remediation sprint, then rescan to confirm the fix.
Reports and exports
- In-app report viewer. After every scan, results open immediately in the Reports tab - no file picker, no PDF required. Pages are sorted by violation count. Each violation shows its impact level, WCAG criterion, affected HTML element, and a direct link to the relevant Vesper Guide.
- PDF export. A fully styled, print-ready report with a cover page, summary grid, violations per page, PDFs found, and broken links. Auditor name appears on the cover if set. Generated natively with no external dependencies.
- Markdown export. The full audit in
.mdformat. Paste into Confluence, GitHub, Notion, or any Markdown-rendering tool. - CSV export. Two files per audit:
violations.csvwith one row per violation (rule ID, impact, WCAG criterion, page URL, affected element) andsummary.csvwith per-page counts. Compatible with Excel, Numbers, and Google Sheets. - Notion sync. Publishes a structured page hierarchy to your Notion workspace after each scan: Audit Report, PDFs Found, Broken Links, Audit Log, and Suppressed Errors. Sync runs in the background.
Settings and workflow
- Scan profiles. Save named configurations per client. One click restores the URL, scan mode, exclusions, suppressions, export formats, and report filter for that site. Export and import profiles as JSON.
- Violation suppressions. Hide known false positives or accepted risks from output. The raw audit data is preserved and suppressed items are noted at the bottom of each page's report section.
- Path, query string, and regex exclusions. Skip URL patterns during the crawl - event listings, paginated archives, or any section that would inflate results without adding useful findings.
- Viewport width. Set the browser width used during each scan. Use 375 for mobile, 768 for tablet. Default is 1280.
- Auditor attribution. A Supporter feature. Add your name or agency to display as "Prepared by" in the header of every exported report. Leave blank to omit.
- Vesper Audit attribution. A Supporter toggle, enabled by default. Disable to remove the "Tool: Vesper Audit" credit and footer line from all exports for white-label delivery.
- Import & export settings. Export your full settings to JSON and import them on any machine. Keeps configurations consistent across team members or between client projects.
Platform
- macOS, Apple Silicon and Intel
- Requires Google Chrome
- Signed and notarized by Apple. No Gatekeeper warnings on first launch.
- Automatic updates. Vesper Audit checks for new versions in the background and notifies you in-app when an update is ready to install. A Check for Updates item in the application menu runs a check on demand.
- Light, dark, and system appearance modes.