Inspiration
Most websites ship with accessibility barriers (images with no alt text, unlabeled buttons, unreadable contrast) and silent JavaScript errors that quietly break features. Teams know, but fixing hundreds of small issues by hand is tedious, and an AI that edits code without checking its own work is a liability. We wanted an agent whose fixes you can trust because every one is proven, not just proposed.
What it does
SiteMortem audits a static website in a real headless Chromium browser, using axe-core for WCAG 2.0/2.1 A and AA checks plus captured JavaScript errors and failed network requests. It groups the findings, writes a minimal code patch for each group, applies it to a temporary copy, and runs the same audit again. A patch is kept only if the targeted issues are gone and nothing new appeared. Otherwise it is rolled back and retried once with a stronger model.
You get a before/after dashboard, every accepted and rejected attempt with its evidence, a downloadable .patch, and a ready-to-use pull request description. A demo coffee-shop site with planted bugs is bundled, and you can upload a .zip of your own static site.
How we built it
Detect → Triage → Investigate → Patch → Verify → Retry → Report
- Nemotron Nano triages every issue group in parallel (priority, complexity, summary).
- Tavily fetches current fix guidance from WCAG, MDN and web.dev for each defect class. It is passed to the model as untrusted reference text.
- Nemotron Ultra does root-cause analysis with reasoning on, writes the retry patch after a failed verification, and writes the PR description.
- Nemotron Super writes the first-attempt patch as exact-match search/replace edits.
- Software, not the model, decides what is kept: strict validation → apply to a temp copy → browser re-audit → keep or roll back.
All model calls go through Nebius Token Factory's OpenAI-compatible API in a single client module, with tier discovery from /v1/models, JSON mode, bounded retries, and token usage shown only when the provider reports it. Live mode never silently falls back to scripted output; it stops with a clear error instead.
The backend is Python and FastAPI with Playwright; the dashboard streams real backend events (resumable if the connection drops) and is tested with axe-core on its own UI in light and dark themes and at five screen sizes.
Security by design
Uploaded sites are untrusted code running in a browser on a server, so we treated them that way: safe ZIP extraction (path traversal, symlinks, zip bombs and executables rejected), a network lock-down so the audit browser can only reach the local copy of the site (SSRF protection), validation of every model edit (allowed file types, no new external URLs, exact-once matches, size limits), the original files hashed before and after every run, and prompts that treat page content and search results as untrusted data.
Challenges we ran into
- Making verification fair. The same page can be reachable as
/and/index.html, and issue IDs shift between audits, so issues are fingerprinted to tell "newly introduced" from "already there". - Real-world uploads. Testing on public website templates showed that real project zips contain READMEs, Sass sources and OS junk files. We now skip harmless non-web files instead of rejecting the whole upload, while still blocking executables.
- Honest reporting. A fix that exposes a latent bug looks like a regression, so every rejection and rollback is explained in the UI rather than hidden.
What we learned
Agentic coding becomes trustworthy when the model proposes and software verifies. Splitting work across Nemotron tiers (a fast model for triage, a mid-size model for patches, the largest model for hard reasoning and retries) kept the loop responsive while reserving heavy reasoning for the cases that need it.
Known limitations
Automated testing finds only part of WCAG, so a clean result is not a compliance certificate. Generated alt text and labels need human review. SiteMortem works on static sites (HTML, CSS, JS), audits the initial load of up to 6 linked pages, and blocks external CDNs during the audit. It produces a patch and PR text but does not open the pull request itself.
What's next
Opening the pull request through the GitHub API, interaction scripts (keyboard traversal, forms) in the audit, build-aware edits for React and Vue projects, and a human review step for generated alt text.
Built With
- axe-core
- css3
- docker
- fastapi
- html5
- javascript
- nebius-token-factory
- nvidia-nemotron
- openai-sdk
- playwright
- pytest
- python
- tavily
Log in or sign up for Devpost to join the conversation.