RenewalRate.ca

How we verify every claim

RenewalRate.ca publishes calculators, decoders, and explainers about Canadian mortgage renewals. Mortgage decisions involve real money, and the cost of getting a number wrong is real. This page explains the methodology behind the per-claim verification audit we maintain for every published article: how sources are selected, how math is derived, how evidence is graded, how often claims are re-checked, and how readers report errors. The full audit is published at /audit (also reachable as the audit); the chronological corrections record is at /corrections.

What the verification audit is

The verification audit is a per-article public record of every load-bearing claim, statistic, and computed figure on the site. It is not a footnote list; it is a structured ledger that the deploy pipeline machine-checks before any change goes live. For each claim, the audit lists:

Confidence tiers, plainly stated

Not every claim in mortgage publishing has a primary-source document behind it. Some do (the Interest Act compounding rule, the OSFI MQR exemption). Some sit in lender-filed Standard Charge Terms most readers will never look at. Some are common industry practice with no published source at all. The ledger labels each claim's confidence tier so the strength of the evidence is visible:

Tier A
Primary source: federal statute, OSFI guideline, FSRA bulletin, CMHC report, Bank of Canada publication, or a lender's published Standard Charge Terms or product disclosure. Canonical authority.
Tier B
Trade publication citing internal source, regulator's secondary explanation (e.g., FCAC consumer guidance), or lender investor disclosure. Authoritative but one step removed.
Tier C
Industry practice with broker corroboration, partner-reported data, or named industry sources. The claim is true in pattern but has no single primary document behind it.
Tier D
Anecdotal. Not used in evergreen content. Restricted to opinion columns where the framing is explicit.

If we cannot tier a claim at A or B, the claim is either rewritten with explicit framing, removed, or held in commentary-only content. We do not pretend a Tier C industry pattern is a Tier A statute.

The second axis: GRADE evidence strength

Source authority (Tier A/B/C/D) describes where a claim's source sits in the publishing hierarchy. It does not describe how strong the evidence is for the specific claim being made. A Tier A primary source can still be weak evidence for a particular assertion if the cited passage only loosely supports the claim, if the value lives in dynamic table content, or if the inference chain from source to claim is long. To make that visible, the audit records a second axis on every claim, modeled on the GRADE framework used in evidence-based medicine and adapted for mortgage publishing:

HIGH
The cited verbatim contains the exact load-bearing fact (number, rule, date, regulatory trigger). The screenshot shows the value on the live page. No inference step required.
MODERATE
The cited verbatim supports the claim with a short, named inference step. Calculator parity passes if math is involved. The screenshot shows the source page; the load-bearing value sits in a table cell or dynamic element, but the cell is unambiguous.
LOW
The verbatim establishes the source page is the right page, but the specific value is in dynamic content (rotating rate table, daily yield close) and is verified through screenshot rather than substring match. The claim is reframed to what the source actually proves; the screenshot carries the time-stamped specifics.
VERY LOW
Synthesis claim built from multiple atoms, or a claim where no findable primary source exists for the specific fact and the audit is documenting an industry pattern. The claim text is reframed to remove false specificity; the entry is marked accordingly and is held to a higher review cadence.

The two axes do not collapse into one another. A Tier A source can yield LOW evidence strength for a claim that depends on a value the source page does not statically render. A Tier B aggregator can yield HIGH evidence strength for a claim that the aggregator's own table does carry as static text on the captured day. Both axes are written into every audit entry.

Declared-exemption flags

The deploy linter is intentionally strict. To ship a claim that does not meet the strictest standard (verbatim contains every load-bearing number, source URL resolves on every check, value is statically present in source HTML), the entry must carry an explicit declared-exemption flag that names why a stricter check would be incorrect to enforce. Exemptions are not a way to bypass the linter; they are a way to make the gap legible. The five originating flags are:

Two further flags were added during the May 2026 audit hardening:

Every exemption appears in the rendered audit entry. Exemptions are visible to the reader, not hidden in build metadata.

When a Tier A and Tier B source could both apply

Some claims could plausibly be tiered A or B depending on which source you anchor to. The rule we apply: a claim is Tier A only when its load-bearing facts (specific numbers, regulatory triggers, statutory language) come directly from the canonical document, even if a secondary source paraphrases the same content. A claim is Tier B if the only available source verbatim is the regulator's plain-language explanation, a trade publication citing internal data, or an aggregator's summary. For example: a claim that quotes the exact statutory text of OSFI Guideline B-20 is Tier A; a claim that paraphrases B-20 by quoting an FCAC consumer page is Tier B. A claim that publishes a current Big Six rate sourced from Ratehub's daily rate table is Tier B (Ratehub is an aggregator, not the lender), unless the claim names the lender's own published rate page as a cross-citation, in which case it is Tier A. The verification ledger documents the upgrade criterion in each entry's source-of-formula and history fields.

The verbatim-supports-claim rule

A source quote must verify the specific load-bearing facts of the claim, not merely establish that the source page is topically related. A page title, section heading, navigation label, or generic disclaimer is not adequate verification for a specific numerical claim. If a claim cites a specific rate, dollar figure, percentage, regulatory trigger, or operational quirk, the source quote must contain that specific value or phrasing.

Where a claim contains multiple specific facts (for example, "Big Six discounted 5-year fixed offers cluster between 4.29 and 4.59 per cent: RBC at 4.29 per cent, CIBC and Scotia at 4.49 per cent, BMO at 4.51 per cent, TD at 4.59 per cent"), the verbatim must either include every cited value, or the claim must decompose into separate sub-claims, each backed by its own verbatim from the source. We do not accept structurally weaker verbatims as a substitute for the actual cited facts. If a source genuinely does not carry the cited specifics in static page text (for example, a daily-decay aggregator table whose values rotate), the claim is reframed to what the source actually proves, marked verbatim_check: false, and the screenshot becomes the evidence layer with explicit time-stamped framing.

Synthesis claims that combine multiple sources must show the inference chain from verifiable atoms to the synthesized statement. Each atom is its own ledger entry; the synthesis claim references them through its derivation_chain field. We do not paper over a synthesis with a single weak verbatim from one of its inputs.

Compound claims and the evidence array

When an article makes a compound claim (one sentence with multiple distinct factual assertions, for example "RBC, TD, Scotia, BMO, CIBC, and NBC use posted-rate IRD methodology"), the ledger entry contains an evidence array. Each atom in the array carries its own primary source, verbatim quote, screenshot, and a covers field stating which sub-claim it verifies. The reader sees seven separate sources and seven separate screenshots, not one source standing in for seven. A compound claim with one source quote is theatre; a compound claim with one atom per assertion is verification.

If a sub-claim within a compound has no findable primary source, that specific atom is marked verbatim_check: false with explicit framing. The atom is still rendered in the ledger so the reader sees where the gap is. The ledger does not hide weak atoms behind stronger ones.

Framing language counts

A subtler form of the same problem: a claim can wrap a verifiable fact in qualifiers that themselves assert facts. "A borrower who took a typical five-year fixed at pandemic-era rates can expect to pay $622 more per month" verifies the $622, but "typical", "five-year fixed", and "pandemic-era rates" each add factual specificity. Each of those qualifiers is also a claim and needs its own atom in the evidence array, or an explicit reasoning step in the entry's inference logic. Qualifiers that sit unsupported in prose are claims-without-evidence, regardless of how innocuous they read.

How math is shown

Every dollar figure derived in an article appears in the ledger with its full derivation: inputs, formula, source of formula, and computed result. Canadian mortgage math runs on the semi-annual compounding rule under section 6 of the federal Interest Act. The ledger shows the conversion from nominal to effective monthly rate explicitly, never hidden inside a final number. Math claims that depend on assumptions (an assumed discount margin, an assumed remaining term) surface those assumptions as named inputs, not as a single answer.

The eight claim types

Different categories of claim require different verification standards. The ledger uses eight types, each with its own sourcing ladder:

The deploy gate: thirteen deterministic detectors

Every change to an audit entry runs through a mechanical linter before the site can deploy. The linter is composed of thirteen named detectors, each enforcing one rule. None require a model's judgment; all are pure functions of the JSON entry plus the live source page. A failing detector blocks the deploy.

  1. SOURCE-URL-RESOLVES: every cited primary_source.url returns a 200 from a desktop-Chrome user agent. URLs that 404, redirect to a generic landing page, or hard-time-out block the deploy.
  2. VERBATIM-ON-PAGE: the source quote literally appears as substring text on the live page. Whitespace is normalized; ASCII apostrophe and curly apostrophe are unified before matching.
  3. NUMBER-IN-EVIDENCE-CHAIN: every load-bearing number in claim text (dollar figure, percentage, basis points, rate range, count) appears in the evidence chain (source quote, math derivation inputs, or a decomposed atom's verbatim).
  4. ATOM-COVERS-CLAIM: for each evidence atom in a compound claim, the atom's covers field does not assert specifics the atom's source quote lacks.
  5. NO-META-NARRATION: source quotes prefixed with editor meta-narration ("Industry pattern:", "Synthesis claim:", "Math derivation:") are rejected. Synthesis prose dressed up as a verbatim is blocked.
  6. WAYBACK-SNAPSHOT-PRESENT: every entry has a Wayback Machine archive URL or carries the wayback_pending_revert flag with a queued retry timestamp.
  7. SCREENSHOT-PRESENT: every entry whose evidence type requires a screenshot (capture-log entries, dynamic table values) has a stored screenshot file referenced from evidence.screenshot_path.
  8. CALCULATOR-PARITY: every type: math entry runs the live calculator with the recorded inputs and asserts the recorded result. Drift between recorded and computed result blocks the deploy.
  9. CYCLE-DEPENDENT-CLAIM-STALE: every entry flagged cycle_dependent: true whose cycle_anchor_date + cycle_ttl_days is in the past is queued for review. A stale cycle-dependent claim cannot ship without a refreshed verification timestamp.
  10. SOURCE-VINTAGE-PRESENT: every entry records vintage (publication date of the source) distinct from last_verified (the date we last checked the URL).
  11. TIER-AND-GRADE-PRESENT: every entry carries both a Tier A/B/C/D and a HIGH/MODERATE/LOW/VERY-LOW evidence-strength grade. Missing axes block the deploy.
  12. EXEMPTION-FLAG-LEGAL: any entry that fails another detector must carry one of the seven declared-exemption flags with an editor-written justification. Exemption flags without justification block the deploy.
  13. SPEC-VERSION-CURRENT: every entry records the schema spec version it was last verified under. When the spec increments, entries on the older version are flagged for re-audit.

This linter exists because LLM-based verification on its own is gameable. A model checking another model's work shares the same intuitions about what "sounds rigorous" and is sympathetic to inference paragraphs that hand-wave a missing verbatim. The mechanical gate runs first; LLM verification is only a tie-breaker on judgment calls the linter cannot make. Nothing reaches production without the lint passing.

The linter is open source within the audit directory. Anyone running py sources/lint-ledger.py against the JSON files can reproduce the deploy gate locally.

Wayback snapshots and the daily retry sweep

Every primary source URL is submitted to the Internet Archive's Wayback Machine on the day a claim is verified. Wayback's save-page-now endpoint occasionally fails for reasons unrelated to the source: rate limits, transient 503s, regulator pages with anti-bot rules, large PDFs that time out. When a save fails, the audit entry is flagged wayback_pending_revert and the retry is queued.

The retry queue is processed by a daily sweep (sources/wayback-retry.py). On the build host the sweep runs as a Windows Task Scheduler entry, configured to fire once a day and to persist across reboots. The sweep walks every wayback_pending_revert entry, re-submits the source URL to Wayback, and on success writes the resulting snapshot URL back into the entry and clears the flag. Failed retries stay queued. An entry that has been pending for more than fourteen days is escalated to manual review: either the source page is genuinely unarchivable (in which case the screenshot becomes the durable evidence layer) or the URL has decayed and the claim needs re-sourcing.

Update cadence and 90-day stale check

Many mortgage facts decay. A 5-year Government of Canada bond yield is true on the day it is reported and meaningless a month later. A lender's Standard Charge Terms vintage matters: the version a 2021 borrower signed is not the version on the lender's website today. The audit separates two dates per claim: source vintage (when the cited document was published or filed) and last verified (when we most recently checked that the source URL still resolves to the cited content).

A 90-day stale check runs against every claim whose last_verified date is older than 90 days. Stale claims are surfaced in the build output before any deploy and are queued for manual re-verification. In addition, claims tagged cycle_dependent: true carry their own cycle_ttl_days (typically 30, 60, or 90) anchored to a named event such as a Bank of Canada rate decision or a quarterly CMHC release; the cycle TTL overrides the 90-day default for those entries. Re-verification cadence by claim type:

Schema and spec versioning

The ledger schema is frozen at version 1.0 as of May 1, 2026. Every claim records the spec version it was last verified under. When the spec changes (a stricter rule is added, a new field becomes mandatory), the version increments and any claim still on the older version is flagged for re-audit by the linter. This prevents the slow drift where older articles silently fall below current verification standards as the standards rise. The full schema specification lives in sources/SCHEMA_v1.0.md.

Drift detection (the daily cron)

A second script (sources/recheck-stale.py) runs on a schedule and re-fetches every cited URL, diffs the recorded source quote against the current page text, and writes a drift report. When a regulator restructures a page, when a lender rotates a Standard Charge Terms PDF, when an aggregator's daily rate table moves a value, the drift report flags the affected claim within a day. Each claim carries a last_machine_check timestamp; claims whose timestamp ages out of the re-verification cadence are automatically queued for re-check.

Public corrections

Every audit entry has a "report a correction" link. Readers, brokers, and lender representatives are invited to flag any claim they believe is mis-sourced, out of date, or wrong. Corrections are versioned: each audit entry shows its history, including any change made in response to a reader correction, with the date and a brief description of what changed. The full chronological record is published at /corrections and is generated mechanically from the per-claim history fields, not edited by hand.

Corrections are not editorial concessions. They are operational humility. A publisher whose record never shows a correction is either covering up errors or not auditing closely enough.

What the ledger does not do

The ledger documents what we said and where we sourced it. It does not constitute mortgage advice, financial planning, or a substitute for a licensed mortgage broker. RenewalRate.ca operates within the Ontario Regulation 407/07 referral exemption: we publish facts and route quote requests, we do not solicit, negotiate, or recommend specific mortgage products for specific borrowers. For a recommendation on your specific file, consult a FSRA-licensed mortgage agent.

Why we built this

Most Canadian mortgage publishers cite primary sources inline, in passing, when load-bearing. Few document every claim in a single auditable record. The ledger exists because we believe a reader should be able to verify, without taking our word for any of it, that every dollar figure on the site can be traced to its source, and that every regulatory or operational claim has a document behind it. If we get a claim wrong, we want it to be visible, correctable, and dated. That is the standard we are willing to put a name under.

Last updated: May 5, 2026. Schema version 1.0. Editor: Omar M.S. Hamed. Publisher: O.MS.H Media Inc., Federal corporation #1589366-6, Hamilton, Ontario.