1. The source: Campaign Lab scrape, April 2025
Every record starts from Campaign Lab’s April 2025 scrape of UK candidate websites. The dataset covers 2,375 candidates and 2,375 websites, keyed on Democracy Club person IDs — the stable public identifier for UK candidates.
2. The audit: re-checked after the election
Websites rot. Roughly 17 months after the scrape we re-requested every URL and recorded what happened: 1,513 responding, 441 DNS or connection failures, and the remaining URLs had HTTP errors, timeouts or other technical failures.
The stored status “live” means a successful HTTP response after redirects. It does not establish that campaign content survived. Surname matching searches the response body and can match a domain-sale page or unrelated text; it is a weak signal, not content verification. Redirects are tracked separately and overlap HTTP outcomes.
| Status | Meaning |
|---|---|
| Responding (live) | Successful HTTP response after redirects at the audit |
| Unreachable (gone) | DNS failure or connection failure at the audit |
| HTTP error | Server responds with 4xx/5xx |
| Timed out / SSL / Conn. failed | Unreachable for technical reasons — retry before concluding |
| ↳ redirect | URL sent visitors elsewhere at the audit (destination shown; overlaps HTTP outcomes) |
3. The public record: ENS names
3 of 2,375 candidates have a public name of the form p5693.civicord.eth on the Ethereum Name Service (Sepolia testnet today). Core fields are the campaign website URL, the audit status, and the candidate's name — readable by anyone, without an account, a wallet, or our permission.
Updates to resolver fields are on-chain transactions with a public history. This makes changes observable; it does not prove a political claim is true, preserve full website content, or establish candidate ownership of a record. Today that history lives on Sepolia; the mainnet path is in §4.
To verify a record yourself: open any candidate page, click “Verify on-chain”, and independently read the url, status, and vnd.civicord.person_name text records on the resolver contract. Compare them with the claims on the page — they should match exactly.
4. Permanence, honestly: testnet prototype
Records currently live on the Sepolia testnet — free and public, but a test network. The path to a permanent home is deliberately boring and already scoped in docs/onchain-plan.md:
- Now (Sepolia): public audit fields — name, original URL and HTTP audit status — are written and publicly verifiable on Etherscan.
- Next (mainnet): migration to Ethereum mainnet is planned via the same ENSv2 contracts. Sepolia records are rehearsal data, not the citable record of truth.
- Planned (durable content): content hashes plus durable storage for source snapshots — not yet implemented.
The claim we make today is the narrow, checkable one: public audit fields can be read on Sepolia and compared with this ledger. Source excerpts and archive links must be evaluated separately.
5. Limits and honesty
- Source excerpts are short extracts, not complete archived pages.
- The scrape is a snapshot: it shows what sites said in April 2025, not today.
- The audit is a snapshot too: a site marked “timed out” may simply have been down that day.
- Candidate-name matching is a heuristic with false positives — a responding URL is not proof that campaign content survived.
- HTTP outcomes say nothing about intent: we do not infer deliberate deletion or retention.
- Records live on the Sepolia testnet — free and public, but a test network, not mainnet (see §4 for the migration path).
- Civicord tracks campaign websites only, not social media, leaflets, or hustings claims.
6. What is verified, and what is not
Verified here means an observation you can trace to a stored source. It does not mean a political sentence is true.
Observed and stored
- The HTTP result of each audited URL on 7 September 2026, including redirects recorded that day.
- Short excerpts and page filenames from the Campaign Lab April 2025 scrape. An excerpt is the opening of a stored extract, not the whole page and not the later text.
- Where a sentence comparison exists: sentences from that April site-wide text that were not found in a later homepage fetch, and sentences on that homepage that were not in the April text. The record shows that before and after wording. The two sides are not paired as edits of one sentence. A missing sentence is a candidate for review, not proof it was deliberately withdrawn, and the later fetch does not cover the rest of the site.
- Where a Wayback comparison exists: a significance class and a coverage score. That snapshot does not include the before and after wording, so the page does not invent it.
- On Sepolia: the candidate name, original URL, and HTTP audit status. Full page content is not on-chain.
Not verified
- Whether a campaign sentence is true, or why it is absent from a later homepage.
- Surname matches. They are a heuristic, not a reading of the page.
- Correction requests. Anyone can submit one from a candidate record, with a source URL. The submission is stored in the review queue with status “queued”. It does not change the audit, the scrape, the sentence comparison, the citation, or the Sepolia record. A maintainer may later append an accepted correction as a new fact. Submitting the form is not that acceptance, and the queue is not a second copy of the audit.
7. Reproduce it
Pipeline, audit, frontend, and publishing scripts are open source (AGPL-3.0) at github.com/sneldao/civicord. Raw scrape → CSVs → audit → site → on-chain records: every step is scripted and re-runnable.