A small Python script that fetches a published masaladeutsch post and tests it against rules taken from real defects: broken JavaScript, backwards dark-mode media queries, missing disclaimers, unlocked dark palettes. It exits non-zero on a blocker, so it can gate CI.
Open-Source Tools · How-To · Dev & ops tools
How to use blog-consistency-check: a "is this blog post broken?" audit for HTML posts
Revised
· v1.0.0 · what changed
Code: github.com/herrrickshaw/blog-consistency-check
Watch the walkthrough
Watch on YouTube: youtu.be/05JQ4VNF0cc
Why it is useful
- Who benefits: anyone who hand-writes or bulk-edits HTML blog posts with embedded CSS/JS and cannot eyeball every post after every edit.
- What it replaces: screenshot-diff services ask whether a page changed; this asks whether it is broken, which suits posts that rarely change after publishing.
- Evidence from the run: auditing one live post took a few seconds with only curl and node and produced a 10-rule table plus a plain-language list of failures.
- The run found a real BLOCKER (dark palette with no light-mode lock) on a recent post, so the rules do fire on current content.
What it is for
blog-consistency-check is a checker for masaladeutsch.blogspot.com. It lists posts through the public Blogger feed, downloads each page with curl, and applies a fixed set of static rules. An optional Playwright pass adds computed-contrast and overflow checks in light and dark mode.
The rules encode defects that actually happened on the live blog. CHECKLIST.md explains each one, so the checklist and the code stay in step. The repo also has fix.py and helper scripts for repairing the problems; this post covers only the read-only audit.
Who it is for
- Bloggers who publish self-contained HTML posts with their own CSS and JavaScript
- Maintainers who bulk-edit posts with scripts and want a safety net
- Anyone who wants a CI gate that exits non-zero on broken posts
- General websites: several rules are specific to this blog (WPI attribution, index link, translate widget)
- Pixel-perfect visual regression; the repo says baseline screenshots are for eyeballing only
- Fixing posts automatically without review; run audit.py first and read the report
What you need
| Requirement | Why | How to get it |
|---|---|---|
| Python 3 | audit.py and checks.py are plain Python | Preinstalled on most systems |
| curl and node on PATH | curl fetches pages; node syntax-checks each post's scripts | Install Node from nodejs.org or your package manager |
| Playwright + Chromium (optional) | Only for the --rendered contrast/overflow pass | pip install playwright, then python3 -m playwright install chromium |
Get the code and an AI assistant
You do not have to be a programmer. Get the repository, give it to an AI assistant, and ask in plain language. Any of these routes works:
| Tool | What you need | Best for |
|---|---|---|
| GitHub | Free account to fork or star; git to clone, or the green Code button, then Download ZIP, or open in Codespaces | Getting the code and keeping up with updates |
| Claude Code | Claude subscription or API key; run claude inside the cloned folder | Letting the AI read and run the whole repo |
| Gemini CLI | Google account; run gemini inside the cloned folder | The same hands-on workflow with Gemini |
| Claude.ai, Gemini or ChatGPT in the browser | A chat account; upload README.md and the files you care about (or paste the output of git ls-files) | Understanding the project and asking questions without installing anything |
| Other tools (Copilot Chat, Cursor, Codex CLI) | Open the cloned folder in the tool and point it at README.md first | Editing and extending the code |
git clone https://github.com/herrrickshaw/blog-consistency-check.git
cd blog-consistency-check
claude # or: gemini
Install
- Clone the repository.
git clone https://github.com/herrrickshaw/blog-consistency-check.git cd blog-consistency-check - No packages are needed for the static pass. Check the two tools it shells out to.
which curl node
Quick start: commands and what you should see
Audit one public post (static pass).
python3 audit.py --url https://masaladeutsch.blogspot.com/2026/10/how-to-use-ship2shorerag-offline.html
It writes out/report.md and out/report.json, prints the report path, and prints a count of BLOCKER failures. The exit code is non-zero when a blocker fails.
Read the report.
cat out/report.md
A rule-summary table (failing vs checked) followed by a list of posts needing attention, each failure tagged BLOCKER, MAJOR or MINOR.
Sample outputs
Real output from a run on the date shown in the sources line; trimmed to fit.
Rule summary for one live post
python3 audit.py --url <post URL> # then: cat out/report.md
posts audited: 1 · posts with at least one failure: 1
| severity | rule | failing | checked |
| BLOCKER | dark-vars-locked | 1 | 1 |
| BLOCKER | js-parses | 0 | 1 |
| BLOCKER | no-disclaimer-in-script | 0 | 1 |
| BLOCKER | no-inverted-media-query | 0 | 1 |
| MAJOR | wpi-attribution | 0 | 1 |
| MAJOR | disclaimer-present | 0 | 1 |
| MINOR | bw-override | 1 | 1 |
| MINOR | translate-widget | 0 | 1 |
| MINOR | index-link | 0 | 1 |
| MINOR | table-units-in-header | 0 | 1 |
Table reformatted slightly for width. Run on 19 October 2026.
Failure detail and exit summary
tail of the same report
### how-to-use-ship2shorerag-offline.html
- BLOCKER dark-vars-locked: dark palette consumed with no !important light lock
- MINOR bw-override: dark palette present with no BW-override / light lock
1 BLOCKER failures
These are findings about the page's CSS, not about its content. Whether it is a real visual problem is a human call; the contrast pass (--rendered) would confirm it.
Ways to use it
| Method | How it works |
|---|---|
| Spot-check after publishing | Run --url on the new post and read the report before announcing it. |
| Whole-blog sweep | Run python3 audit.py with no arguments to walk the full feed (about 30 seconds for the static pass per the README). |
| CI gate | Because blockers produce a non-zero exit, a workflow can fail when a post regresses. |
| Add your own rule | Write a function in checks.py returning (ok, detail), register it in STATIC_RULES, and add a line to CHECKLIST.md. |
Sample prompts for your AI assistant
Copy, paste and edit the parts in [brackets].
- Claude: Read audit.py and checks.py in this repo and explain each rule in one sentence, then tell me which ones are specific to masaladeutsch.
- Gemini: Run python3 audit.py --url <my post URL> and summarise out/report.md in plain English, ordered by severity.
- ChatGPT: Here is out/report.md. For each failing rule, explain what the reader would see and suggest the smallest CSS change.
- GitHub Copilot: Add a new static rule to checks.py that flags images without alt text, with a matching CHECKLIST.md entry.
- Claude: Adapt this audit to my own blog by listing which constants and rules I would need to change.
Limits and honest caveats
- Hard-coded to masaladeutsch.blogspot.com (BLOG constant in audit.py); other blogs need a code change.
- The README's install line points at a private virtualenv path (~/.venvs/testing/bin/python3); use your own Python instead.
- The static pass checks the HTML source, so a CSS finding like dark-vars-locked is a signal to inspect, not proof of a visible fault.
- The --rendered pass (Playwright contrast/overflow) was not run for this post.
- The fix scripts (fix.py, add_*.py) were not run; they edit content and need review before use. This is not investment, legal or clinical advice; it is a code-quality tool.
Sources: README, CHECKLIST.md, audit.py and checks.py in github.com/herrrickshaw/blog-consistency-check; static audit run read-only on 19 October 2026 against one already-public masaladeutsch post, in a scratchpad clone.
- v1.0.0 — 9 November 2026 — first published.
About this article: Researched, written and edited by Umashankar Triplicane Dwarakanathan, with AI research assistance; every figure is meant to trace to the primary source cited. See the Editorial Policy for how sourcing, AI use and corrections work.