Method and data
How the reports were chosen and read, how the work is checked, and where the data comes from.
Why real reports
Home-care intelligence reads carers' notes with the same method: every finding quotes the words it rests on, and code checks the quote. Its notes are synthetic, written for the project, so they cannot show how the method does on writing by real people. Inspection reports can: real people wrote them, and the inspectors' scores, given independently before this project began, show where the shortfalls are.
Its live demo runs while the author's laptop is on; its code is on GitHub.
How it works
- Sample. From CQC's directory of rated care services: the home care agencies whose Safe rating was published from 1 January 2024, when CQC began scoring each quality statement. Score 1 is rare at random, so agencies were drawn by Safe rating: every Inadequate and Outstanding agency, and seeded random samples of the others.
- Split by provider. One provider's agencies share policies and often wording, so each provider goes wholly to the development set (about 30%) or the test set, by a hash of its ID. Every parsed report was frozen by its SHA-256 hash before any model ran.
- Nothing gives the answer away. The model reads only a section's paragraphs: never the statement's name, its score, the rating banner or the overview. The guard works on the page's HTML structure, not on words.
- Carried-over sections are left out. When CQC did not assess a statement again, its text says so and its score comes from an earlier rating, so the score says nothing about the text.
- One call per section, with at most 8 findings each.
- Findings. Each has a category (one of the eight statements), the exact words that state it and a one-sentence reason. The server holds the reply to a JSON schema and the code checks it again. Each quote is looked up in the section's text: a finding whose quote is not there is dropped and counted.
- Untrusted text. Report text reaches the model as a JSON string, so nothing written in it can end the data field and pose as an instruction.
- Models. Qwen3.5-4B and Gemma 4 E4B (Apache-2.0), as files pinned by SHA-256, served by llama.cpp on one laptop GPU with 8 GB, at temperature 0.
The sample and the two sets
| Safe rating | Sampled | With a scored Safe page |
|---|---|---|
| Inadequate | 54 | 49 |
| Requires improvement | 160 | 152 |
| Good | 100 | 95 |
| Outstanding | 17 | 17 |
| All | 331 | 313 |
| Count | Development | Test |
|---|---|---|
| Reports | 106 | 207 |
| Scored sections | 795 | 1,554 |
| Scored 1 | 131 | 274 |
| Scored 2 | 236 | 449 |
| Scored 3 | 401 | 782 |
| Scored 4 | 27 | 49 |
| Carried-over sections left out | 51 | 102 |
The eight Safe quality statements
As the model is told them, in this project's words.
- Learning culture
- Learning from incidents and concerns: reporting, investigating, acting on them and sharing lessons.
- Safe systems, pathways and transitions
- Care plans and assessments kept up to date, information shared, continuity of care, and moves between services.
- Safeguarding
- Protecting people from abuse and neglect, safeguarding referrals, and consent and mental capacity.
- Involving people to manage risks
- Risks to each person's health and safety assessed and managed, with clear guidance for staff.
- Safe environments
- Equipment and the home environment checked and safe to use.
- Safe and effective staffing
- Enough staff, visits on time and of the planned length, safe recruitment, training and competence.
- Infection prevention and control
- Hygiene, protective equipment and infection risks.
- Medicines optimisation
- Medicines given, recorded and overseen safely.
How it is checked
Every protection has a test that carries out the attack and passes only when the attack fails, and a twin test that switches the protection off and shows the attack then succeeds, so the first test is known to be able to fail.
- A made-up quote is dropped.
- No statement name, score, banner or overview text reaches the model.
- Text that tries to close its data field stays inside it.
- No provider is in both sets.
- A path that robots.txt disallows is never fetched.
- The publishing scan finds a planted CQC ID, the name of a sampled service, or any run of 8 words from a fetched report.
- The results file refuses any field outside its list of allowed ones, and a number that differs from the runs is caught.
- Markup in a model's reading is shown on this site as text, never run.
Run it yourself
Needs uv. A read also needs llama.cpp's llama-server, on PATH or with its full path in LLAMA_SERVER, and the model file in models/, matching its size and SHA-256 in models.json. If either is missing, the command says what to do.
uv sync
uv run python scripts/check.py
uv run inspection-reader read --model qwen3.5-4b site/example-page.htmlThe repository explains how to rebuild the whole study from CQC's files.
Data and credit
Contains CQC information licensed under the Open Government Licence v3.0. This project is not connected with or endorsed by CQC.
- Sources: CQC's care directory of 4 November 2026 and care directory with ratings of 2 November 2026, and the Safe page of each sampled agency's latest report with scored statements, fetched on 4 November 2026.
- No report text, provider name or location name is published, here or in the repository. The results are counts; the only report shown in full is invented.
The code and the whole study: the project on GitHub.