Skip to content
On this page

Methodology

Three AI model seats from two vendors check each claim against the public record: one Anthropic model and two OpenAI models. The two OpenAI seats are not independent of each other, so three agreeing verdicts are not three independent confirmations. A rule written down in advance turns their three answers into one finding. Nothing is published until every fact in it has been checked against a saved copy of its source.

Methodology changes — every revision to the process, versioned and dated.

The short version

What can stop a claim, send it back or change it at each step is marked under the step.

  1. 1

    Someone sends us a source

    A post with all its comments, an article, a thread. We keep the whole thing and list every claim in it that a public record could settle. Commenters get a label instead of their name, unless they hold public office. Every question we found is listed publicly with what was decided about it, including the ones we declined.

    • Stops here. Two readers can decline a question or park it. Either way the reason is on the register.
    • Stops here. An accusation against a named person is written down, then declined.
  2. 2

    The question is pinned down before anyone looks for answers

    A written brief says exactly what the claim means, in words both sides would accept: what counts as lost, whose money, up to what date. A model from a different company checks that the brief is fair to the people making the claim. Then it is frozen, so nobody can move the goalposts once answers start coming in.

    • Loops back. A brief that fails its fairness check is rewritten before it can be frozen.
    • Stops here. After three reports, a brief the check still calls unfair is parked until new evidence arrives.
    • Loops back. If the third report says the record cannot answer some claims, those claims are parked in public and the same checker confirms once what is left.
  3. 3

    Three AI model seats research it blind

    Three seats, one Anthropic and two OpenAI, get the same brief and search the public record without seeing each other's work. Two of them share a vendor, which the panel section below spells out. Each seat returns a verdict, the evidence for and against, and what it could not find.

    • Stops here. A reviewer that returns nothing after its retry halts the run before any finding.
    • Stops here. As of September 16, 2026 all three seats could run again, each under a check whose limits are set out below. No panel had run since September 4, and no finding had been published under those checks. What the check is, and what it does not show.
    • Continues. As of September 23, 2026 the Google seat is retired. The panel is three seats from two vendors, Anthropic and OpenAI. Methodology v1.37.
    • Loops back. Afterwards the three read each other's work. A fabricated citation caught there sends that claim back for a fresh blind round.
  4. 4

    A table turns three verdicts into one finding

    The table was written down in advance and covers every way three verdicts can combine. Nobody votes and nobody picks. When the three do not agree, the finding is never stronger than the most cautious of the three. If one reviewer finds a claim supported and another finds it contradicted, the finding is Mixed, and the split is shown.

    • Continues. Supported against Contradicted publishes as Mixed, with the split shown.
    • Stops here. If a framing concern is right and there is no fair repair, the claim is parked with a public reason.
  5. 5

    Every fact is checked against a saved copy of its source

    Before anything is published as a finding, an audit reads the write-up against the archived bytes of the sources it cites, not the live web. The reviewers' answers, their sources and the audit reports are published with it, after a check that removes personal information. Ildar Abdulin is the named person accountable for every word, and he can take any of it down.

    • Fixed before publication. A statement the archived source does not carry is corrected before the page goes up.
    • Corrected later. A finding that changes after publication is logged on its own page as a dated entry. Nothing is quietly edited.

Three things we will not do

  • Publish an accusation about a named person. This version of the site checks policies, budgets and outcomes, not people, because it has no way yet for the person to answer.
  • Check a claim nobody made. Every claim we test is one somebody actually wrote, quoted exactly as typed.
  • Give a score. A finding is one of five words with a fixed meaning, set out below. Not established means the record cannot answer yet. It does not mean false.

The prompts, the table, the reviewers' answers, the audit reports and every edit ever made are public, at https://github.com/civicfacts/yegfacts. What is not: who is behind a commenter's label, documents we are not allowed to mirror, accusations against named people, and personal information a release check removes. The sections on names and limits below say more. The rest of this page is the same method in full, for a reader who wants to audit it.

The words we use

No true or false, and no score out of ten. A finding is one of five words. Beside it sit two more things: what kind of record answered the question, and whether the three seats agreed. A claim can be Supported on a thin record, or Not established by a panel that agreed unanimously that the record does not exist.

Supported
The evidence establishes the claim.
Partially supported
Part of the claim holds and part does not — usually because a true fact has been stretched past what it shows.
Not established
The evidence available does not settle it. This is not a synonym for false. It means the record cannot answer the question yet, and we say what is missing.
Contradicted
The evidence points against the claim.
Mixed
Reserved for a materially split panel. Reviewers cannot output Mixed; only synthesis produces it, and only when the three reviewers genuinely divide. Where you see Mixed, the disagreement is shown rather than smoothed over.

Reviewers may only return the first four words. Mixed is produced by the table, never by a reviewer, and only when the three genuinely divide. A Mixed finding always comes with the split that produced it.

How a claim gets in

Nobody here decides which claims are worth an argument. Until v1.15 somebody did, and it showed: the site was checking things nobody disputes while the actual fight went past it. So the choosing stopped. Whatever comes in comes in whole, and everything factual inside it is dealt with.

  1. 1

    A source arrives

    The unit is a whole source: a post and every comment under it, an article, a discussion someone sends us. Anyone can send one, and you do not have to say which part of it you think is wrong. The accessible material is captured with its address, capture date and known limits, and kept. A capture is not necessarily the complete source.

  2. 2

    Every claim in it is written down

    Three extraction seats from two vendors read that capture separately. Each lists every factual assertion in it: numbers, counts, dates, what somebody says a document said, and the factual premise sitting inside an opinion. They are told not to work out whether any of it is true, and not to decide which parts are interesting. Each one is recorded with the exact words that carry it and the comment those words came from.

  3. 3

    The three lists become one

    A stronger model folds them into propositions, one for each thing a record could settle, keeping every version of the wording underneath. A script then audits that step. Whatever any of the three wrote down has to appear once in the merged list, or on a dropped list under one of three allowed reasons. If something goes missing, the merge fails and runs again. The failure this exists to catch is a claim quietly disappearing.

  4. 4

    The same argument is gathered into one question

    One argument arrives as many claims. Checking each on its own would spend a panel run on every one and answer the same question several times over. So claims a single investigation would settle are gathered under one question: the same figure in different units, a general claim and an instance of it, a claim together with the claim that contradicts it. Each still gets its own finding. Take the argument about emergency vehicles. One side says the concrete barriers hold responders up. The other says responders use the lanes to get past queues. That is one question, answered by the same response-time records, and two claims, because one finding across the pair would settle neither and would tar each side with a ruling about the other.

  5. 5

    Triage rules on the questions

    The questions go to two OpenAI readers from one vendor, one pass each, and neither reader sees the other. Each returns GO, PARK or NO on every one, with a reason short enough to show the person who raised it. An Anthropic audit reader re-decides a question both OpenAI readers decline or park before the register records it. Where the two OpenAI readers disagree the question is kept rather than dropped, because throwing out a real question costs a reader more than holding one too long. Only a GO reaches stage 1 below. The rest are listed anyway, with their reasons, and the questions most people are arguing about are checked first.

Two rules fall out of this, and both bind us rather than you. We do not check a claim that nobody has been recorded making: a wording one of us thought up is registered and then waits, unrun, until it shows up in something a real person wrote. And an assertion that names a real person and accuses them of something is written down with the rest, so no count can hide it, and is then turned down; the reason is under Limits below.

One source has been through this so far. What has not been shown is that the triage step returns the same answers twice on the same list, and until it has, the claim to make for it is narrow: the choosing is gone from intake, not from everything. Every question we have considered is listed with what triage decided about it.

Names, and why the quotes are exact

Somebody who comments under a public post is not thereby a public figure. Every commenter in a capture is given a label in place of a name: an adjective, an Edmonton animal and an initial, like Snowy Hare F. It is picked by hashing the real name, so the same person gets the same label every time that source is exported and replies still line up with what they answer. Magpie is left out of the list, that one being Stew. Anyone holding public office keeps their own name. What matches a label to a person is held privately and is not in the repository.

The words themselves are treated the other way round. A quotation is the comment as typed, misspellings included, and a script discards any that is not a single unbroken run of the comment it is pinned to, or that points at a comment number the capture does not contain. Nothing is stitched, tidied or corrected. Someone who commented in a thread we captured can find their own sentence here and see that it was not reworded on the way in.

Seven stages, per question

One run covers every claim under one question. The state of every run lives in the repository, so any session can pick up where the last one stopped, and so can you. These seven begin once a question has come through the five steps above and triage has said go.

  1. 1

    Framing

    A written brief fixes the scope of the question and states each claim precisely before any model runs. This is where the arguable words get pinned down: what “lost” means, gross or net, whose money, and the date that closes the accounting window. Any calculation the finding depends on is named here. Since v1.7 Stew, the AI steward, writes the brief from the intake record, which carries the wordings the extraction captured and where each came from. Before the freeze a model from a different vendor checks it. Its only question is whether the brief tests the claim people actually make, at its strongest fair reading, with definitions both sides would accept before seeing the result. That report is committed beside the brief. The brief is frozen once the check passes, so nobody can move the goalposts once the answers start arriving.

  2. 2

    Blind research round

    The three seats, one Anthropic and two OpenAI, receive the identical package: the brief, the public reviewer prompt, and a required JSON output schema. Since v1.41 it can also carry the text of a public document the brief names that the seats cannot read themselves, described under carried documents below; every seat gets the same text and finds everything else itself. The two GPT seats share a vendor, so their agreeing is one company agreeing with itself. New runs must pass an execution check intended to keep host instructions and private files out of the review. A separate working directory alone did not provide that protection. The execution profiles and their limits are set out below. Each seat returns a per-claim verdict, its confidence, the evidence supporting and challenging it, its limitations, what it could not find, and comparison cities with a judgement about whether those cases transfer to Edmonton.

  3. 3

    Evidence staging and deterministic merge

    Cited URLs are fetched, hashed and snapshotted. Then a script, with no model and no network, validates the three JSON files, removes duplicate sources, and produces a combined evidence set plus an explicit list of where the models disagree. Accepted sources are added to the evidence registry deliberately, by a separate script, never automatically.

  4. 4

    Cross-review round

    Each model now sees the combined evidence and the other two sets of findings. The instruction is the opposite of consensus-seeking: find what you missed, find their errors, and state your final position. This is an error-documentation round, not a second vote. Since v1.3 nothing said here can move the canonical finding, which removes the incentive to drift toward the majority. Every final position is published beside the round-one one, so a reader can see who moved and why. When this round catches something material, a fabricated citation or evidence that turns out to say something else, the answer is a fresh blind re-run of that claim, not a quiet patch inside the same run. Since v1.22 that re-run has a fixed shape: all three seats receive the frozen brief again with the claims named and nothing about why, and the first round's answers stay on the record beside the new ones.

  5. 5

    Deterministic synthesis

    A script computes the canonical finding from the three locked round-one verdicts, using a published lookup table over every possible combination. Round one keeps the seats blind to one another, so only its verdicts enter the calculation. Agreement counts seats, not vendors. Model identity never enters the calculation, and the property is tested. A genuinely split panel produces Mixed, with the split shown. Beside the finding the site publishes panel agreement, Unanimous, Adjacent or Split. Those words describe seats, not vendors. That replaced a confidence score in v1.3, because agreement is what the method actually measures and confidence implied a probability of truth that nothing here computes. All published arithmetic lives in a tested script, never in prose. Since v1.24 a run can also publish fewer claims than it asked. Where a framing concern is right and no repair exists that does not weaken the claim, that claim is parked with a public reason, and its answers stay committed.

  6. 6

    Drafting, faithfulness check and plain-speech read

    Claude drafts the question page and the claim records from the merged evidence, a fixed choice disclosed here. OpenAI seats then check the draft against the evidence sentence by sentence, looking for anything asserted that the evidence does not carry. Flags are fixed before a human sees it. Then a model from a different vendor than the drafter reads the answers, the sentence under the title and the TL;DR as a person would: would anyone say this out loud, does it make sense to somebody who has not seen the question, and has anything true been dropped rather than moved down. Since v1.32 a page is written in layers, ten seconds for a resident at the top and the exact figures with their sources below, and the read checks that every figure that left the top is still on the page. Its report is committed with the run, and a claim that cannot name its read does not publish.

  7. 7

    Publication gate

    Before publication, a dedicated audit, separate from the models that produced the draft, verifies every statement of fact against the archived bytes of its cited sources, not the live web. It also scans the raw review output for personal information and other material unsuitable for public release. Both audit reports are committed alongside the run. Since v1.1 this gate is performed by AI auditors under a standing delegation from Ildar Abdulin, who remains accountable for everything published and can revert any decision. A question may be deployed earlier in pending-review status; it is bannered as such and is not a finding.

Every question published so far passed the AI audit gate under this delegation; none was gated by a per-source manual founder review.

Reviewer execution: correction and current limit

September 9, 2026: this page said a separate working directory kept each reviewer out of the repository. It did not. An audit of the roads framing checks found private project memory supplied outside the declared package; the third report read and cited it. No repository read was observed, but its absence was not proven. All findings published before this change predate the new check; they have not been retroactively cleared by it.

That change required every new attempt to suppress host customizations and pass a separate test that public-web access works and local files stay unreachable under the same execution profile. It is a check of that execution, not a guarantee about a vendor. On that date no provider had a demonstrated profile meeting the full requirement, so new panels and source audits were paused: the candidate Claude setup reported its tools but did not expose the instruction text needed to check for injected context. An essential source that cannot be read blocks the run; it does not become a finding that the claim is not established.

September 15, 2026: two of the three seats are still stopped. The Codex and Gemini seats have no equivalent evidence, so the three-model panel cannot run and the Gemini source check commissioned for the consultation question is still blocked. What changed is the Claude seat, and only the Claude seat.

The change is that the outgoing request is now kept. Each Claude reviewer launch runs through a small program on this machine that writes down every request the tool sends to the address it was given for the model, and passes it on unchanged. A check then compares that request against a written-down description of what a clean one contains: the maker's own standard instructions and nothing added to them, only web search and web fetch as tools, and the declared package word for word. The seat may run when a test invocation and the real one both pass.

What the request carries that the package does not, in full: the folder the tool was started in, whether that folder is a code repository, the computer's platform, shell and operating-system version; the name of the model and the date its knowledge stops; today's date; the account email address of the person running it; and an identifier for the device, one for the account and one for the session. The email address arrives in the same message as the package, and the folder, platform, model name and date in a separate message of their own. The three identifiers are not in any message: they are attached to the request alongside it, the way a return address is attached to an envelope. All of it comes from the maker's own text, not from this project. The record keeps the two messages word for word with the email address taken out, and notes that the three identifiers were sent without recording what they are. We publish the whole list rather than trimming it. A reviewer was told these things, and a shorter list would be a nicer story than the truth. The folder is now a scratch folder named after the attempt and nothing else, so it no longer tells a reviewer which story or which round it is working on.

The description is written per model, not just per version of the tool, and finding that out cost the first real run. The description had been written from trial runs on a smaller, cheaper model. The first run on the model the panel actually uses was refused, because the same tool sends a different request for each model: a different set of standing instructions, different tool descriptions, and the folder and date in a different place. Nothing went out that should not have; the check stopped the run and said what did not match. The description now names the model as well as the version, and the one written from the trial runs was removed rather than kept beside it.

The package reaches the maker twice per attempt: once as the research request, and once before that in a short request that asks the model to name the session, which carries the whole package and no tools. Both are written down and both are checked.

What this does not show, on two sides. On this side: the program sees only what the tool sends to the one address it was given for the model. Anything the tool sent somewhere else, and everything else happening on the machine, is outside what it can see. The maker's standard instructions are matched by fingerprint, not read or republished, and the request's delivery headers are kept but not compared, so a pass is a statement about the body of the request. On the maker's side: it shows what the tool added on this computer and cannot show anything the company attaches to this account after the request leaves. A pass is evidence about one run under one version of the tool, not a promise from the company that makes it, and it clears nothing published before this date. Because the description was written from one version, the launcher runs that exact version even when a newer one is installed, as one was on the day this shipped; the run record shows both the version that ran and the version the computer would otherwise have used, and a new version has to be recorded and described again before it can run at all. The tool limit set out above still applies, PDFs included.

September 16, 2026: the request is still kept, and what it is checked against is now smaller and weaker. The description written down the day before had to be rewritten by hand, at the cost of a paid run, every time the maker shipped a new version of the tool, which happens several times a week; the founder decided that price was too high for a check nobody could keep current, because a check that is out of date is a check that gets switched off. So the check now reads the private files that are on this computer at the moment it runs. Those are the instruction files in the operator's home folder and in this project, the memory files kept for every project on this computer, the name of the home folder, the path of the project, and the one-off token each attempt plants for its own test. Every line of them long enough to be distinctive is then looked for in the body of each request that was sent, at any depth, and if any of it is there the run is refused, with one exception since September 23, 2026 (v1.38): when Claude's tool fetches a file such as a PDF, the tool saves it to disk and writes a note into its own result naming the path, and that path is in the operator's home folder. That one note, in that one place, is counted rather than refused, and the count is printed on the run's row, because the path was still sent to the vendor. The same words anywhere else, and every other private string anywhere, still refuse the run. So is a run refused whose recording does not carry the declared package word for word, since a recording that cannot be tied to the package it was meant to carry says nothing about it. A refusal names the file and the line number, never the line, and neither does the published record: the private text is read, compared and dropped. What it searches is the body of each request and nothing else: the delivery headers, the web addresses the requests were sent to and the replies that came back are all still kept with the recording, and none of them is searched. Two things said on September 15 are no longer true and are not claimed here, and those paragraphs stay above as the record of what was done at the time: the request is no longer compared against a written description of what a clean one contains, and the record no longer keeps the two host-context messages word for word or note that the three identifiers travelled with it. What this check no longer does is say what the request contains. It says what the request does not contain, for text this computer holds, and it cannot see text the maker attaches that is not on this computer. The full recording is still kept, so a later reader can ask a harder question of the same bytes. The version of the tool is written down now rather than required, so a version nobody has looked at before no longer stops a run. The ruling that a convention plus disclosure is not enough to admit a reviewer was made in the September 9 review and has not been withdrawn; it stands in the record beside this decision. The reviewers who read the September 15 work asked for a looser check than the one that shipped that day, and were refused; this goes further in the same direction than they asked. The founder decided.

September 16, 2026, later the same day: the other two seats can run again, and the reason is worth stating before the detail. Complete isolation is not available on a subscription tool. A fully controlled context needs direct calls to a company's programming interface, and this project does not pay for those. So the choice was between three seats with their limits written down and no panel at all, and the founder chose the three seats. The September 9 ruling stands beside this decision, and nothing here answers it: describing how we run a tool does not on its own earn that tool a seat.

The Codex seat. What the check covers: every request the tool sends to the model is written down before it leaves this computer and searched for the private files this computer holds, the same way the Claude seat's is. Each attempt runs from a fresh settings folder holding nothing but a link to the login and two lines naming the model and the effort level, with the computer's skills catalogue, plugins, apps, hooks, memories and multi-model features switched off. What the check cannot cover: this tool runs its web access and its command line through one internal component and they cannot be separated. Switching that component off takes web search with it, and when we tried that on September 9 the model reported a page it had never fetched and finished without error. So the seat runs with web access, and that means a command line it can also reach. Its read-only setting can read the whole computer, and the test file we plant for our own check is read every time. We record that rather than hide it. What stops a run that touched something private is the search over the request: what a tool returns comes back to the model in the next request, so private text a reviewer read is private text the search finds. The search refuses the run. It cannot prevent the read.

The Gemini seat. What the check covers: this tool ignores every setting we can use to point it at a local recorder, so there is no request to record and we do not claim one. What it keeps instead is a stream of what happened, a transcript, and the page contents its fetch tool saved, and those are what get searched. Each attempt runs from an empty home folder holding links to the login and a settings file that refuses every file, write and command tool. The live check on September 16 watched two file reads refused in one run while a live page fetch went through. What the check cannot cover: it sees what the model produced and what its tools returned, and not the standing instructions the tool attached on the way out, because those are in no record on this computer. Keeping the operator's own instructions and add-ons out rests on running from an empty home folder, which our test supports and cannot prove. The tool also writes its logs, caches and built-in skills into the operator's real folder whatever home it is given. And with no request recorded, nothing here shows where the request went.

Because those two are not the same evidence, the run record does not use the same word for them. A context check now reads pass, fail, unavailable, or record-only, and record-only means the search ran over a tool's own record of the run rather than over a request. It is the weaker answer, it is a separate word so that nobody has to know which seat had a recorder in front of it, and only the Gemini seat may run on it. Every row also says which kind of evidence was searched. A login reaches a reviewer through a link and never a copy: each attempt builds its own folder holding a link to the login the tool already uses, nothing here reads a login file or creates one, a computer that is not signed in is a refusal before anything is sent, and afterwards the links are removed as links rather than followed. No panel has run under these checks yet and nothing published before today is cleared by them.

Each launch attempt keeps its package and execution record privately, even when it is refused. The diagnostic's complete response is retained too. When reviewers can run again, their full responses, including trailing provenance, must be retained before a report is extracted; the public run record will carry the hashes and execution results. Ildar Abdulin retains the originals while the associated public record exists. For inspection, write to [email protected]; hash comparisons and redacted excerpts are subject to privacy and rights review. A published hash does not itself give access to a private file. Earlier deleted output cannot be recovered by this policy. The methodology changelog records the change and the independent reviews.

Panel agreement, and why the merge leans cautious

Beside every finding sits one more word, computed from the three locked round-one verdicts. It describes the panel, not the world.

Unanimous
All three seats reached the same verdict. Panel agreement describes seats, not vendors; two OpenAI seats agreeing are not two independent vendor confirmations.
Adjacent
Two reviewers landed one step from the third; the cautious resolution is shown.
Split
The panel materially disagreed; the disagreement is shown, not averaged.

Where the three do not agree, the lookup table resolves toward the more cautious side of the majority. Two Supported and one Partially supported publishes as Partially supported. That is deliberate. Supported means the proposition as written is affirmatively established, and a qualification one reviewer found does not stop existing because the other two missed it. For a site whose whole job is not overstating the record, overclaiming is the costlier of the two errors it could make.

The obvious objection is that this hands a single seat a veto. The answer is disclosure rather than averaging. Every claim shows what each of the three said, so a reader who thinks the lone qualifier was wrong can see precisely that and weigh it, without the site publishing a stronger claim than every seat accepted.

The whole table

Three reviewers, four words, twenty possible panels. Every one is written out in the script that computes the finding, and this is that script's table, not a copy of it. Read down the left for what the three said, across for what is published.

The twenty panels, from the script

Unanimous4 panels

  • SupportedSupportedSupportedSupported

    Unanimous.

  • Partially supportedPartially supportedPartially supportedPartially supported

    Unanimous.

  • Not establishedNot establishedNot establishedNot established

    Unanimous.

  • ContradictedContradictedContradictedContradicted

    Unanimous.

Adjacent6 panels

  • SupportedSupportedPartially supportedPartially supported

    Two read the claim as established, one as overreaching; the qualified reading wins.

  • SupportedPartially supportedPartially supportedPartially supported

    Majority says part of the claim holds.

  • Partially supportedPartially supportedNot establishedPartially supported

    Majority finds something established, but one reviewer found nothing the record supports.

  • Partially supportedNot establishedNot establishedNot established

    Majority finds the record cannot carry the claim.

  • Not establishedNot establishedContradictedNot established

    Majority found no answer in the record; the stronger counter-finding is not carried alone.

  • Not establishedContradictedContradictedContradicted

    Majority found affirmative counter-evidence; one reviewer found the record silent.

Split10 panels

  • SupportedSupportedNot establishedPartially supported

    Two established the claim, one found the record silent; resolved down to the qualified reading.

  • SupportedNot establishedNot establishedNot established

    Majority found the record silent; the lone Supported does not carry it.

  • SupportedPartially supportedNot establishedPartially supported

    Three different readings spanning the support axis; the middle reading is the defensible one.

  • SupportedSupportedContradictedMixed

    One reviewer found affirmative evidence against what two others established.

  • SupportedPartially supportedContradictedMixed

    Supported and Contradicted both present; the panel does not agree on what the record shows.

  • SupportedNot establishedContradictedMixed

    Supported and Contradicted both present; the panel does not agree on what the record shows.

  • SupportedContradictedContradictedMixed

    Two found affirmative evidence against what one established.

  • Partially supportedPartially supportedContradictedMixed

    A partial-support majority against affirmative counter-evidence; two verdicts apart.

  • Partially supportedNot establishedContradictedMixed

    Three different readings including affirmative counter-evidence.

  • Partially supportedContradictedContradictedMixed

    A counter-evidence majority against a partial-support reading; two verdicts apart.

What a question carries

A question has no verdict of its own. Verdicts belong to claims — the atomic, testable assertions under it — and every claim has a page of its own, so it can be linked, quoted and read without the question around it. A question also records what the City promised, separately from whether the promise was kept: recording a commitment is transcription and needs no panel run, and it only becomes assessed when a real claim about it goes through the process above.

Every load-bearing source is registered with its publisher, retrieval date, and the SHA-256 of the bytes we archived. Where we are allowed to mirror a file, it is committed to the public repo. Where we are not, the hash and the original URL are published and the file is retained privately, so a missing document can still be proved to be the one we read.

Some City council files answer automated tools with a browser check, so a reviewer model cannot open them even though anyone can in a browser. Since v1.41, when a frozen brief gives such a file's address and we hold a copy a person downloaded in a browser, the reviewers get its full text. Before each round we check again that automated access is still refused by a browser check, and that the council meeting page still lists the file under the same title. Someone confirms a person can still open the City's link, and someone other than the editor reads the extracted text against the original. A committed manifest records the file's hash, the text's hash and each of those checks; the text itself is not published. Every reviewer reads the same copy, so their agreement on what that file says is not independent retrieval: their independent work is the reading and the rest of the research. A source read this way is labelled beside it, with the City's link and the byte hash, so anyone who downloads the City's file can compare.

Since v1.42 the same applies when a reviewer's own web tool is refused at a page, even if our fetcher is not, provided a dated probe through that reviewer's tool shows it. Council agendas and minutes are carried by item, not whole. A rule published before any text is extracted picks every item that names the program, its report, its capital profile, its borrowing bylaws, or bikes or cycling, and each picked item goes in whole, with the page's header and attendance. Someone other than the editor then reads every item of every page and records, item by item, why it was or was not carried. An item the rule missed is fixed by publishing a new version of the rule and running it again on every page, never by adding the item by hand. Names of members of the public in the carried items are withheld by a published mechanical step, including the people listed in a procedural motion deciding who may speak; every other motion, every vote and the names of office-holders are never changed. The reviewers are told the site chose the items and that the rest of each page was not shown to them. A claim that needs every recorded vote runs only once the full set of votes has been reconciled with the City's open voting record; otherwise it is parked for that run. Our archived copies of these pages cannot be published, so the label beside such a source links the City's page, the rule and the item index, and the selection can be checked against the City's own page.

Since v1.43 a document also qualifies when every reviewer recorded a failure to read it in two rounds in a row of the same run, even if a quick check later opens it. We read that from the reviewers' own committed answers, record each one's words, and keep the later successful checks beside them. The reviewers are still told to read the document directly if they can. Such a document can come from outside the City's meeting portal: we download it again from the publisher and carry it only if the bytes match our copy, and a person other than the editor opens the publisher's link in an ordinary browser first; if no one can, the label says so. No check in the record may be made by the editor's own session. The label says the reviewers' tools failed, never that the document is unavailable. A document too long for a reviewer's package is carried as whole sections, such as whole service packages in a budget, picked by a second published rule. Every section, carried or not, is listed in public with its pages and a reason before the run, and someone other than the editor reads the whole document for anything left out that qualifies, contradicts or explains what was carried. A gap is fixed by a new version of the rule and a rerun, never by hand and never by cutting a section, and if everything relevant does not fit, the run stops. The label beside such a source says the site chose the sections, the rest was not given to the reviewers, and their agreement on the same supplied text is not independent retrieval. Where a carried budget is cited, we keep what Administration proposed apart from what Council approved.

Limits we set on ourselves

Version 1 of YEGFacts publishes no allegations about named individuals. The claims we check are about policies, programs, budgets and outcomes.

Captured sources carry such allegations all the time, so the rule has to say what happens to them rather than pretend they do not arrive. They are extracted and counted like anything else, because a rule enforced by looking away is not a rule. Then triage declines them, always for the same published reason: checking what one person says about another needs a way for the second person to answer, and this version of the site has none. The decline is public, the allegation and the name are not.

Reproducibility has a real limit and we would rather state it than paper over it. The panel runs through consumer CLI subscriptions, so an identical rerun cannot be guaranteed to produce identical model output. What is recorded instead is the manifest: which models, which CLI versions, which prompt hash, which methodology version, and when. The method is rerunnable; the model output is not bit-exact, and no finding depends on it being so — the evidence and the synthesis rule are both public.

The full audit trail behind this site is public at https://github.com/civicfacts/yegfacts. The prompts, the synthesis matrix, the validation rules, the raw review artifacts, the gate reports and the full edit history are all there.

Panel quality record

The models get things wrong. Collection of a per-seat record of that began on 2026-09-01 and was seeded backwards from the four published runs: fabricated citations, false accusations against another reviewer, unsupported figures, and the catches that turned out to be right — each one adjudicated, dated, and tied to the committed artifact that proves it. It is an error record, not a calibration: none of it measures the models against known truth. A summary publishes once there are enough runs to count, which four are not; the point at which it published used to be fixed by the launch slate, and that slate is gone. The raw ledger is in the repo at methodology/quality-ledger.yaml and can be read today.