A zero-install, zero-upload TODS validator that runs entirely in the browser via
Pyodide. index.html loads Pyodide, installs the
published tods-validate wheel with micropip, writes the chosen files into
Pyodide's virtual filesystem, and calls validate_feed + render_html. Because
nothing leaves the browser, it is safe for non-public operational data.
This page needs a real browser, so it is not covered by the Python test suite
(only the API it depends on is, in tests/test_playground.py). Serve the folder
and open it:
python -m http.server -d web 8000
# then open http://localhost:8000Select the files in examples/sample-feed/ to confirm a clean pass, then a feed
with problems to confirm findings render. If Pyodide fails to load, update the
version in the <script src=".../pyodide/vX.Y.Z/..."> tag to the current
Pyodide release.
The playground is published at
https://chelseakr.github.io/tods-validate/. GitHub Pages uses the GitHub
Actions build source; the Deploy playground workflow
(.github/workflows/pages.yml) publishes this folder as the last stage of a
release, called from pypi-publish.yml only after the released wheel has been
confirmed on PyPI, and can still be dispatched manually for an out-of-band
fix. Either way it refuses to deploy a page whose TODS_VALIDATE_VERSION pin
is not on PyPI, since the page installs that exact wheel in the browser.
The deployment is then checked against the live URL, not assumed from a green deploy job:
scripts/check-deployed-playground.shfails if the served page is not byte-identical to the page this repository publishes — run right after each deploy against the tree that was just uploaded, and weekly (.github/workflows/playground-deployment.yml) againstweb/index.htmlat the most recent release tag.scripts/pa11y-ci-live.cjsruns axe and HTML_CodeSniffer at WCAG2AA against the live page.make a11yaudits this folder's copy, which is the source of the deployment and not the deployment itself; this is what holds the artifact people actually open to the same standard.
tests/test_playground.py pins TODS_VALIDATE_VERSION to the version in
pyproject.toml, so the repository copy cannot be left behind either.
rules/ holds one permanent HTML page per rule ID plus an index.html
catalog, generated by scripts/generate_rules_doc.py from the rule registry
(the same run that regenerates docs/rules.md). Do not hand-edit files here;
run python scripts/generate_rules_doc.py to regenerate, and
python scripts/generate_rules_doc.py --check to verify they match the
registry (CI runs this). SARIF helpUri and the language server's hover text
link to https://<pages-domain>/rules/<RULE_ID>.html, so these URLs are a
permanence contract: filenames are the rule ID verbatim, and rule IDs are
never renumbered once released.