Rate Scanner Dev
Rate Scanner Dev
Section titled “Rate Scanner Dev”Background
Section titled “Background”- The new MBR business, described in
D:\FSS\KB\MBR\02_Strategy\Executive-Summary.md, at its foundation depends on a system that scans rates on savings products, and later debt products. - The Rate Intelligence Engine (Big Rock 1) is the core product. Without reliable, current rate data, the Hassle Threshold algorithm cannot function, the Money Minute has no content, and the 1-Click transfer has no “where to” destination. This is the data substrate that everything else sits on.
- You misinterpreted that I suggested that this results in an AI based tool. To clarify, I simply meant that AI can help develop this tool.
- Rate data is structured (name, rate, minimum balance, promo expiry, account type)
- The logic is deterministic (sort by rate, filter by category, flag by change)
- A Python or Deno script running on a cron job is orders of magnitude more reliable and cheaper
- Note that unless There is a strong reason for otherwise, my preferred language for such backend and/or utility developments is Python.
- Deeply brainstorm the architecture needed to meet short and medium-term objectives for such a back-end scanning tool.
- Research ALL viable sources for this data
- Ratehub.ca, highinterestsavings.ca, EQ Bank, Oaken, Wealthsimple, …
- First research from the existing rate comparison sites the different types of categories for savings products and debt products. Fundamentally, my crude categorization for Savings products would be based on features/functionality, then perhaps account types (only if different)
- can write cheques
- cashable (HISA, cashable GICs, …)
- non-cashable, locked for various terms (60 days, 1/2/3/5 yrs, etc.)
- Can we include MMF in Savings alternatives, or does that get into the securities world where business risks are increased?
- Explore the pros and cons of different database solutions, or is as simple YAML or JSON rate manifest sufficient?
- Do the same for the basic debt products, starting from biggest to smallest
- mortgages (insured, uninsured)
- HELOCs
- Personal LOC
- auto loans
- credit cards (normal, low rate)
- Data needed (minimum?)
- institution name, product name, current rate, promo flag (Y/N), promo expiry, minimum balance, account opening URL.
- Address any other issue you identify as important
Claude Response — 2026-04-02
Section titled “Claude Response — 2026-04-02”Summary
Section titled “Summary”- Researched all viable data sources — tiered by accessibility and reliability
- Confirmed Bank of Canada Valet API: free, public, no scraping needed for prime/overnight rate
- Confirmed highinterestsavings.ca: simple HTML table, scrapeable with requests+BeautifulSoup
- Confirmed Ratehub.ca: Next.js SPA with internal API URLs — requires Playwright for full data; not publicly accessible via simple REST calls
- Confirmed EQ Bank: static HTML, scrapeable (rates visible)
- Defined complete savings product taxonomy (5 categories + 1 informational)
- Defined debt product taxonomy (6 categories, priority-ranked)
- Answered MMF question: informational only, never executed through MBR
- Recommended database stack: YAML (Phase 1) → SQLite (Phase 2) → Postgres (Phase 3+)
- Designed full Rate Intelligence Engine architecture: schema, scraper structure, CLI, cron
- Mapped 4-phase technical roadmap aligned with A→B→Z plan
Architecture: Rate Intelligence Engine
Section titled “Architecture: Rate Intelligence Engine”Overview
Section titled “Overview”The Rate Intelligence Engine is a Python-based data pipeline that:
- Collects rate data from multiple sources (manual → scrapers → Open Banking APIs)
- Stores rates with full history in SQLite (never update, only insert — time-series)
- Detects changes and feeds alerts to the Hassle Threshold Engine
- Exposes a simple CLI for manual inspection and validation
Tech Stack
Section titled “Tech Stack”- Python 3.12+ managed by
uv(per project standard) - requests + BeautifulSoup4 — static HTML scrapers
- Playwright-python — JS-rendered pages (Ratehub, Wealthsimple)
- pyyaml — Phase 1 YAML manifest
- sqlite3 (built-in) + SQLAlchemy (optional ORM) — database layer
- pydantic — data validation / schema enforcement
- schedule or system cron — daily runner
Data Sources: Tiered by Accessibility
Section titled “Data Sources: Tiered by Accessibility”Tier 1 — Free APIs (No Scraping)
Section titled “Tier 1 — Free APIs (No Scraping)”| Source | What It Provides | Status |
|---|---|---|
| Bank of Canada Valet API | Prime rate (V80691311), Overnight rate (V39079), Policy rate | ✅ Confirmed public, free, structured JSON |
Live test result:
GET https://www.bankofcanada.ca/valet/observations/V80691311,V39079/json?recent=1→ Prime rate: 4.45% (2026-04-01)→ Overnight target: 2.25% (2026-04-01)This is the anchor for all variable-rate debt products (“Prime + X%”). Fetch daily.
Tier 2 — Simple HTML Scraping (requests + BeautifulSoup)
Section titled “Tier 2 — Simple HTML Scraping (requests + BeautifulSoup)”| Source | What It Provides | Notes |
|---|---|---|
| highinterestsavings.ca | HISA rates (personal + TFSA), 15–18 institutions | ✅ Confirmed — clean HTML table, no JS required |
| EQ Bank (direct) | Personal Account, TFSA, GIC, FHSA rates | ✅ Confirmed static HTML; rates visible |
| Oaken Financial (direct) | GIC and HISA rates | Needs investigation — curl returned empty |
| Achieva Financial (direct) | HISA, GIC | Likely static HTML |
| AcceleRate Financial (direct) | HISA, GIC | Likely static HTML |
| Motive Financial (direct) | HISA, GIC | Likely static HTML |
| Saven Financial (direct) | HISA | ON-only, clean site |
| Tangerine (direct) | HISA, GIC | Simple pages |
highinterestsavings.ca table structure confirmed:
Brand | Account | Rate | TFSA rate | Province restrictionsAchieva Financial | Achieva Savings | 1.80% | 1.95% | MBSaven Financial | High Interest Savings | 2.85% | 2.85% | ONEQ Bank | Personal Account | 1.00% | 1.50% | —...Note: rates appear stale on this site (EQ Bank at 1.00% is well below current). Use as a supplementary source, not sole authority. Always cross-reference with direct institution pages.
Tier 3 — JS-Rendered (Playwright Required)
Section titled “Tier 3 — JS-Rendered (Playwright Required)”| Source | What It Provides | Notes |
|---|---|---|
| Ratehub.ca | HISA, GICs, chequing, mortgages, personal loans | Next.js SPA — internal APIs discovered but not publicly exposed. Playwright needed. |
| Wealthsimple | Cash account rate | React app, 167-byte response to curl |
| Neo Financial | Neo Savings | Likely JS-rendered |
| Big 6 bank pages | Savings, GICs, mortgages | Mostly JS-rendered, complex DOM |
Ratehub internal API URLs (discovered in NEXT_DATA — useful for Phase 2 Playwright extraction):
SAVINGS_API_URL: https://api.ratehub.ca/savings-accounts-serviceGICS_API_URL: https://api.ratehub.ca/gics-rates-serviceMORTGAGE_RATES_API_URL: https://api.ratehub.ca/mortgage-ratesCHEQUING_API_URL: https://api.ratehub.ca/chequing-accounts-serviceLOANS_API_URL: https://api.ratehub.ca/loans-serviceThese endpoints return “Cannot GET /” directly — they require authenticated session cookies from the SPA. With Playwright, we can let the page load, intercept network traffic, and capture the JSON responses directly.
Tier 4 — Professional / Paid (Future)
Section titled “Tier 4 — Professional / Paid (Future)”| Source | Notes |
|---|---|
| CANNEX | Industry-standard rate data used by banks and advisors. Subscription required. Best data quality. Evaluate at Phase 3+. |
| Open Banking / CDF APIs | Canada’s Consumer-Directed Finance rollout (2026-2027). Will replace most scraping for participating institutions. First-mover advantage. |
Savings Product Taxonomy
Section titled “Savings Product Taxonomy”Category 1: Chequable / All-Purpose
Section titled “Category 1: Chequable / All-Purpose”Can write cheques, use debit, send e-transfers. Functions as daily banking.
- Examples: EQ Bank Personal Account, Wealthsimple Cash
- Key attributes:
can_write_cheques: true,cashable: true,term_days: null - Distinction from pure HISA: full transactional access at high yield
Category 2: Pure HISA (High-Interest Savings Account)
Section titled “Category 2: Pure HISA (High-Interest Savings Account)”Instant liquidity, no term, no chequing. Sub-types by account wrapper:
personal— non-registered HISAtfsa— Tax-Free Savings Account wrapperrrsp— Registered Retirement Savings Plan wrapperfhsa— First Home Savings Account wrapperbusiness— Business savings account
Most institutions offer the same underlying product across multiple wrappers at the same or slightly different rates. Track each rate separately.
Category 3: Cashable GICs / Short-Term Deposits
Section titled “Category 3: Cashable GICs / Short-Term Deposits”Fixed term but redeemable before maturity (usually after minimum hold period, often 30 days). Lower rate than non-cashable but higher than HISA.
- Terms: 30d, 60d, 90d, 180d, 1yr (cashable)
- Key flag:
is_cashable: true,min_hold_days: 30(or similar)
Category 4: Non-Cashable Term Deposits / GICs
Section titled “Category 4: Non-Cashable Term Deposits / GICs”Cannot redeem before maturity (or only with substantial penalty / institution discretion).
- Terms: 30d, 60d, 90d, 180d, 1yr, 2yr, 3yr, 4yr, 5yr
- Highest rates in the savings universe for equivalent institution risk
- Same wrapper variants as HISA (TFSA, RRSP, RRIF, FHSA, non-registered)
Category 5: Promotional / Bonus Rate (Flag, Not Separate Category)
Section titled “Category 5: Promotional / Bonus Rate (Flag, Not Separate Category)”Not a separate category — a flag applied across Category 1–4.
promo: true,promo_expiry: YYYY-MM-DD,new_money_required: true/false- This is the Rate Expiry Engine’s primary input: track expiry date, alert 30 days before reversion.
Informational Only (Not CDIC-Insured — Display With Prominent Disclaimer)
Section titled “Informational Only (Not CDIC-Insured — Display With Prominent Disclaimer)”Category 6: Cash-Equivalent ETFs and Money Market Funds
- HISA ETFs: CI CSHI (formerly CSAV), Purpose PSA, Horizons CASH, BMO ZMMK
- Reason to include: yields often match or exceed HISA rates; relevant to users asking “is this worth switching for?”
- Reason NOT to execute: securities, not deposits; requires securities dealer registration to broker
- Implementation: display as comparison context with disclaimer. Never include in alert triggers or transfer flow.
Debt Product Taxonomy (Sorted by MBR Revenue Priority)
Section titled “Debt Product Taxonomy (Sorted by MBR Revenue Priority)”1. Mortgages (Highest Priority — 9x Revenue vs. Savings)
Section titled “1. Mortgages (Highest Priority — 9x Revenue vs. Savings)”Sub-types (each tracked separately):
- Fixed: 1yr, 2yr, 3yr, 4yr, 5yr, 7yr, 10yr (5yr is 90% of the market)
- Variable: Prime − spread (e.g., Prime − 0.70%) → rate updates when Prime changes
- Adjustable-rate: similar to variable but payments adjust (not just amortization period)
- Insured: CMHC-insured, <20% down, max purchase price $1.5M (post-2024 rules)
- Uninsured: ≥20% equity / purchase price >$1M
- High-ratio vs. conventional: overlaps with insured/uninsured but distinct fee structure
Key attributes: rate_type: fixed|variable|adjustable, term_years: 5, insured: true|false, open: false
Rate Expiry Engine analogy for mortgages: renewal date tracking is the equivalent of promo_expiry. A user’s 5yr fixed mortgage coming up for renewal in 6 months is the highest-value alert MBR can send.
Sources: Ratehub.ca (comprehensive), ratesupermarket.ca, direct broker networks
2. HELOCs
Section titled “2. HELOCs”- Typically Prime + 0% to Prime + 0.5%
- Rate = BoC Prime + spread (spreads are institution-specific)
- Track spread, not absolute rate — the BoC API feeds the calculation in real time
- Limited public comparison data; primarily broker-channel information
3. Secured Lines of Credit (Non-HELOC)
Section titled “3. Secured Lines of Credit (Non-HELOC)”- Similar structure to HELOC but not necessarily secured against home equity
- Prime + 1% to Prime + 3% typical range
4. Unsecured Personal Lines of Credit
Section titled “4. Unsecured Personal Lines of Credit”- Prime + 2% to Prime + 8%
- Highly individual (credit score dependent); limited public comparison data
- Lower priority for MBR Phase 1-2
5. Auto Loans
Section titled “5. Auto Loans”- Fixed rate; manufacturer promotions common (0.99%, 1.99%)
- Less standardized, harder to compare systematically
- Recommend Phase 3+ only
6. Credit Cards
Section titled “6. Credit Cards”- Standard: 19.99% purchase, 22.99% cash advance (nearly universal in Canada)
- Low-rate: 8.99%–12.99%
- Little actionable variation → minimal alert opportunity
- Lowest priority: include as reference data only, no alert logic needed
Database Recommendation: YAML → SQLite → Postgres
Section titled “Database Recommendation: YAML → SQLite → Postgres”Phase 1: YAML Manifest (Weeks 1–4)
Section titled “Phase 1: YAML Manifest (Weeks 1–4)”Best for: human-maintained, version-controlled, quick to bootstrap
meta: schema_version: 1 last_updated: "2026-04-02"
institutions: - id: eq_bank name: EQ Bank cdic_member: true province_restrictions: [] url: https://www.eqbank.ca
products: - id: eq_hisa_personal institution_id: eq_bank name: Personal Account category: chequable # Category 1 — can write cheques account_types: [personal] can_write_cheques: true is_cashable: true term_days: null apply_url: https://www.eqbank.ca/personal-banking/savings rates: - rate: 3.50 rate_type: variable promo: false promo_expiry: null min_balance: 0 max_balance: null source: direct fetched_at: "2026-04-02"
- id: oaken_gic_1yr institution_id: oaken name: 1-Year GIC category: gic_term # Category 4 — non-cashable term account_types: [personal, tfsa, rrsp, rrif] is_cashable: false term_days: 365 rates: - rate: 4.10 rate_type: fixed promo: false min_balance: 1000 source: direct fetched_at: "2026-04-02"Phase 2: SQLite with Rate History (Month 1–3)
Section titled “Phase 2: SQLite with Rate History (Month 1–3)”Best for: automated scraping, change detection, Hassle Threshold Engine integration
Minimum schema:
CREATE TABLE institutions ( id TEXT PRIMARY KEY, name TEXT NOT NULL, url TEXT, cdic_member BOOLEAN DEFAULT TRUE, province_restrictions TEXT, -- JSON array: '["QC"]' notes TEXT);
CREATE TABLE products ( id TEXT PRIMARY KEY, institution_id TEXT REFERENCES institutions(id), name TEXT NOT NULL, category TEXT NOT NULL, -- 'hisa', 'gic_term', 'gic_cashable', 'chequable', -- 'mortgage_fixed_5yr', 'heloc', etc. account_types TEXT, -- JSON: '["personal","tfsa","rrsp","fhsa"]' can_write_cheques BOOLEAN DEFAULT FALSE, is_cashable BOOLEAN, term_days INTEGER, -- NULL for variable products apply_url TEXT, active BOOLEAN DEFAULT TRUE, notes TEXT);
-- Never UPDATE rates — only INSERT. Full time-series history.CREATE TABLE rates ( id INTEGER PRIMARY KEY AUTOINCREMENT, product_id TEXT REFERENCES products(id), rate REAL NOT NULL, -- Annual rate, e.g., 3.50 for 3.50% rate_type TEXT DEFAULT 'fixed', -- 'fixed' | 'variable' | 'prime_plus' prime_spread REAL, -- For "Prime + X%" products; effective_rate = prime + spread promo BOOLEAN DEFAULT FALSE, promo_expiry DATE, min_balance REAL DEFAULT 0, max_balance REAL, -- NULL = no cap fetched_at DATETIME DEFAULT CURRENT_TIMESTAMP, source TEXT, -- 'manual' | 'scraper:highinterestsavings' | 'api:boc' source_url TEXT);
-- Change log — populated by diff.py after each scraper runCREATE TABLE rate_changes ( id INTEGER PRIMARY KEY AUTOINCREMENT, product_id TEXT REFERENCES products(id), prev_rate REAL, new_rate REAL, change_bps REAL, -- (new - prev) * 100; positive = rate went up detected_at DATETIME DEFAULT CURRENT_TIMESTAMP, alert_queued BOOLEAN DEFAULT FALSE);Key design decision: rates are insert-only. This gives MBR the historical dataset needed for “Your savings rate has increased 3x since you joined” and the Canadian Financial Health Index. Every scraper run produces a new row — never modifies an existing one.
Phase 3: PostgreSQL (Phase 3+)
Section titled “Phase 3: PostgreSQL (Phase 3+)”Only when: hosted deployment, multiple scrapers running in parallel, or B2B Rate Intelligence API requires multi-tenant isolation. Not needed for Phase 1-2.
Project Structure
Section titled “Project Structure”rate-scanner/ # Standalone Python project├── pyproject.toml # uv-managed├── uv.lock├── data/│ └── rates.yaml # Phase 1: manually maintained manifest├── rate_scanner/│ ├── __init__.py│ ├── db.py # SQLite setup, schema creation, migrations│ ├── models.py # Pydantic: RateRecord, ProductRecord, etc.│ ├── loader.py # YAML → SQLite: validates, deduplicates, inserts│ ├── diff.py # Change detection: compare latest rate vs. prior│ ├── runner.py # Orchestrates all scrapers; logs run summary│ ├── cli.py # typer CLI: list, run, diff, validate│ └── scrapers/│ ├── __init__.py│ ├── base.py # Abstract BaseScraper: fetch(), normalize(), validate()│ ├── boc_api.py # Bank of Canada Valet API (prime + overnight rate)│ ├── highinterestsavings.py # HTML table scraper — Priority 1│ ├── eq_bank.py # Direct institution scraper — Priority 2│ ├── oaken.py # Direct institution scraper│ └── ratehub.py # Playwright-based — Phase 2└── tests/ ├── test_models.py ├── test_loader.py └── test_scrapers/ └── test_boc_api.py # Can test against live APICLI commands:
rate-scanner list # Show all current rates, sorted by rate descrate-scanner list --category hisa --account-type tfsarate-scanner list --category gic_term --term 365rate-scanner run # Execute all scrapers, write to SQLiterate-scanner run --scraper boc_api # Run single scraperrate-scanner diff # Show rate changes since last runrate-scanner validate # Schema-validate YAML manifestrate-scanner export --format json # Export current rates as JSON (for Hassle Threshold Engine)MMF / Cash-Equivalent ETFs: Answer
Section titled “MMF / Cash-Equivalent ETFs: Answer”Short answer: Include as informational only. Never execute through MBR.
The regulatory line: MBR’s business model depends on staying in the “information and referral” category, not the “securities dealer” category. Executing HISA ETF or MMF purchases would require registration as a mutual fund dealer or exempt market dealer. This is a business risk that far outweighs any product benefit.
What MBR CAN do:
- Display current ETF yields (CASH, PSA, CSAV, HSAV, ZMMK) as a comparison column
- Label them clearly: “Investment Alternative — Not CDIC-insured. Not available through MBR.”
- Show the yield comparison: “HISA best rate: 3.50% | HISA ETF yields: up to 4.10%”
- Link to the user’s brokerage for execution (no referral fee, just information)
Why include them at all: A user with $50k in a HISA at 3.50% who could be in CASH.TO at 4.10% is leaving ~$300/year on the table. MBR’s job is to surface this. Not acting on it because of regulatory complexity would mean MBR is hiding material information from users — which contradicts the mission.
Implementation note: Add a category: 'investment_alt' flag and an is_cdic_insured: false field. Filter these out of all alert and transfer logic. Display in a separate “For Your Information” section with a single-line disclaimer.
4-Phase Technical Roadmap
Section titled “4-Phase Technical Roadmap”Phase 1: Manual YAML Manifest (Weeks 1–4)
Section titled “Phase 1: Manual YAML Manifest (Weeks 1–4)”Zero infrastructure. Immediately useful.
- Build
data/rates.yamlwith 15–20 products:- EQ Bank: Personal Account (chequable), TFSA HISA, 1-year GIC
- Oaken: HISA, GICs (1yr, 2yr, 3yr, 5yr)
- Achieva: HISA, TFSA HISA
- AcceleRate, Motive, Saven: HISA
- Tangerine: HISA, GICs
- Wealthsimple Cash: chequable/HISA
- Neo Savings: HISA
- BoC prime rate fetcher (10 lines of Python, live API)
- CLI:
rate-scanner list,rate-scanner validate - Git-committed: YAML is the SSOT, version-controlled, diffable
Phase 2: Automated Scraping + SQLite (Month 1–2)
Section titled “Phase 2: Automated Scraping + SQLite (Month 1–2)”Rate data becomes live and historical.
- highinterestsavings.ca scraper (easy win — confirmed HTML table)
- EQ Bank direct scraper
- BoC API integrated into daily run
- SQLite schema deployed, YAML loader → SQLite
- Change detection (
diff.py) → populatesrate_changestable - Daily cron:
0 6 * * * rate-scanner run - Alert hook: when
rate_changeshas new rows, Hassle Threshold Engine evaluates
Phase 3: Full Coverage + Debt Products (Month 2–4)
Section titled “Phase 3: Full Coverage + Debt Products (Month 2–4)”Ratehub coverage, mortgage data, broker integration.
- Ratehub Playwright scraper (intercept network calls to internal APIs)
- Mortgage rates (5yr fixed as first priority)
- Rate Expiry Engine: promo tracking, 30-day pre-alert
- Mortgage renewal date tracking (separate table:
user_mortgage_renewals) - B2B Rate Intelligence API: FastAPI wrapper over SQLite queries
Phase 4: Open Banking (2026–2027)
Section titled “Phase 4: Open Banking (2026–2027)”Replace scrapers with authoritative bank APIs.
- Consumer-Directed Finance (CDF) framework integration
- Real-time or near-real-time rate feeds
- Scraper modules deprecated for participating institutions
- First-mover advantage window: be in market now, infrastructure ready before CDF goes live
Next Steps for Talbot
Section titled “Next Steps for Talbot”- Approve the architecture direction — YAML → SQLite → Postgres progression; Python throughout 1.
- Approve the savings product taxonomy (5 categories + informational ETF section) 1.
- Confirm: should rate-scanner live inside the MBR monorepo, or as a standalone utility (like web-deploy)?
- If it served more than one project or utility, I think it would belong in
\\wsl$\Ubuntu-24.04\home\ta\projects\, so it could be consumed by multiple projects. But at this point, I see no valid reason that it would serve anything other than MBR. Anything related to this data would appropriately be under the domain of MBR. So it should go into a dedicated mbr folder. - Yes, the monorepo will hold the MyBetterRates.com website. But I don’t think that the Related rates engine needs to be here. Agree? I like to keep separate concerns as much as possible and the mono repo already will do lots.
- MBR will require many databases, automation scripts and more. Separately think through all of the tasks that we identified as big rocks and suggest an architecture to handle what is knowable, perhaps leaning towards keeping the website content separate in the monorepo and structuring everything else external to it.
- Under
\\wsl$\Ubuntu-24.04\home\ta\projects\mbr\?
- If it served more than one project or utility, I think it would belong in
- Confirm: should Phase 1 YAML manifest be built first (manually by Claude) before any scraper code is written?
- sure
- MMF decision — informational-only column confirmed, or exclude entirely for now?
- info column
Talbot Response
Section titled “Talbot Response”- Strategic Better-Quantified data
- While we clearly are most interested in the best savings rate and debt rate for every category, it might also be useful to know what the opposite is, so that we could quantify the full difference that some people Who have currently the worst products might experience. Unfortunately, often the worst products are those that are most used, due to inertia and lack of, and hassle Factor Etc. I think this is a good additional piece of data to capture and perhaps use for marketing purposes. Agreed?
Claude Response — 2026-04-02
Section titled “Claude Response — 2026-04-02”Summary
Section titled “Summary”- Confirmed architecture location:
mbr/under/home/ta/projects/— rate-scanner and all non-website MBR backend lives here, website stays in monorepo - Designed full MBR project architecture — 10 service directories, all created
- Built Phase 1 YAML manifest at
mbr/rate-scanner/data/rates.yaml- 18 institutions, 23 products (7 verified, 16 flagged for Playwright verification)
- Includes benchmark/worst-rate infrastructure for Big 6 baseline comparison
- Built
models.py(Pydantic validation),loader.py(YAML → models),cli.py(typer CLI) - Built
scrapers/boc_api.py— Bank of Canada Valet API integration - Installed with
uvand tested all commands — all passing - Answered “worst rate” question: YES — implemented via
institution_type: national_bankandneeds_verificationflags for Big 6
Confirmed answers to previous questions
Section titled “Confirmed answers to previous questions”Architecture location: Rate-scanner and all backend services in /home/ta/projects/mbr/. Website (MBR.com) stays in monorepo. Correct separation. No exceptions.
Phase 1 YAML first: Done. Manifest is built, installed, and tested.
MMF/investment_alt: category: investment_alt added to schema. Two HISA ETFs (CSHI, PSA) included with no rate (needs data feed) and notes: "INFORMATIONAL ONLY. Not available through MBR." They’re in the manifest, excluded from verified products unless rates are populated.
Full MBR Architecture
Section titled “Full MBR Architecture”/home/ta/projects/mbr/├── README.md # Architecture overview├── rate-scanner/ # ✅ Built (Phase A→B — NOW)├── cancer50pledge/ # Phase A→B — GWWC-modeled pledge platform (SvelteKit)├── benefit-snapshots/ # Phase A→B — embeddable rate calculator widgets├── hassle-engine/ # Phase B→Next — Hassle Threshold + Alert Dispatcher├── split-cart/ # Phase B→Next — Stripe + CanadaHelps split payment├── wealthcare50-portal/ # Phase B→Next — Employer/charity HR portal + CSR dashboard├── financial-iq/ # Phase C — Financial IQ Score + Net Worth Thermometer├── concierge/ # Phase C — 1-Click Transfer: KYC, form gen, DocuSign├── notifications/ # Phase C — Email + push notification delivery└── browser-extension/ # Phase D — Passive rate surveillance overlayWebsite (MyBetterRates.com) → monorepo at /home/ta/projects/monorepo/sites/mbr/
Everything else → /home/ta/projects/mbr/
Each service is standalone: its own pyproject.toml (Python) or package.json (Svelte). Communication in Phase 1–2 is via file export (YAML/JSON/SQLite); Phase 3+ is via internal API.
Rate Scanner: What Was Built and Tested
Section titled “Rate Scanner: What Was Built and Tested”Location: \\wsl$\Ubuntu-24.04\home\ta\projects\mbr\rate-scanner\
Test results (all passing):
rate-scanner validate→ ✓ Manifest valid→ Institutions: 18, Products: 23→ Verified rates: 7 (all EQ Bank — confirmed from their website today)→ Needs verification: 16 (aggregator-sourced or TBD)
rate-scanner benchmarks (live Bank of Canada API call)→ Prime Rate: 4.45%→ Overnight Target: 2.25%
rate-scanner list (verified products only, sorted by rate)→ EQ Bank GIC 15-month: 3.25%→ EQ Bank GIC 1-year: 3.20%→ EQ Bank GIC 6-month: 2.75%→ ...CLI commands available:
rate-scanner validate # Schema checkrate-scanner list # Verified products, sorted by raterate-scanner list --category hisa # Filter by categoryrate-scanner list --account-type tfsa # Filter by account wrapperrate-scanner list --all # Include unverified (shows ? flag)rate-scanner benchmarks # Live BoC API: current Prime rate“Worst Rate” / Benchmark Data: Confirmed — Great Strategic Idea
Section titled ““Worst Rate” / Benchmark Data: Confirmed — Great Strategic Idea”Short answer: Yes. Do this. It is the marketing data that makes the Benefit Snapshot compelling.
The value isn’t just “best available rate: 3.25%.” The value is the delta: “Most Canadians at a major bank are earning [X%]. The best available rate today is 3.25%. On $100,000 that is $[X-3.25 × 1,000] per year you are leaving on the table.”
How it’s implemented without adversarial framing:
The YAML manifest uses institution_type: national_bank for the Big 6. TD and RBC are already in the manifest with needs_verification: true (their pages require Playwright to scrape). Once populated:
rate-scanner list --category hisawill show all HISA rates including national bank rates- The CLI will not label them “offenders” — it just sorts by rate
- The data tells the story without editorial judgment
The “Canadian Savings Rate Tracker” (not “Loyalty Penalty Report”):
- Average national bank HISA rate = factual, from their own public pages
- Best challenger bank / credit union rate = factual
- Delta = factual math
- “X% of Canadians are leaving an estimated $Y/year on the table” = aggregate calculation from data
- This is exactly what MoneySense, Globe and Mail, and CBC do annually — standard financial journalism
Implementation in the manifest:
- id: td_savings_standard institution_id: td_bank name: TD eSavings Account (Standard) institution_type: national_bank # ← triggers "benchmark" treatment in UI notes: "Standard non-promotional rate. Used as Big 6 market baseline." rates: - rate: null # Playwright scraper populates this needs_verification: trueWhen the Benefit Snapshot widget calculates “your potential gain,” it uses:
user_current_rate(what user enters or we detect)best_available_rate(top verified challenger bank rate)national_bank_average(average of Big 6 verified rates)
The delta between those three numbers is the core of MBR’s value proposition made visual.
Rate Verification Queue
Section titled “Rate Verification Queue”16 products need Playwright scraping or manual verification before going live. Priority order:
Tier 1 — Manual check this week (5 min each, just visit their website):
oaken_hisa— Oaken Financial HISA (their rates page loads but needs JS)wealthsimple_cash— Wealthsimple current Cash/Chequing rateneo_savings— Neo Financial current savings ratetd_savings_standard— TD eSavings standard rate (the benchmark)rbc_savings_standard— RBC High Interest eSavings standard rate
Tier 2 — Next scraper sprint:
- Remaining challenger banks (Achieva, Saven, Wealth One, Canadian Tire)
- HISA ETF yields (CSHI, PSA — available from TMX or Yahoo Finance)
- Mortgage best rates (Ratehub Playwright scraper)
Next Steps for Talbot
Section titled “Next Steps for Talbot”- Confirm the MBR project structure at
/home/ta/projects/mbr/— any services to add, rename, or remove?- Good. Done. You are the senior architectural expert. I trust you.
- Manually verify 5 priority rates (30 min total): Oaken HISA, Wealthsimple Cash, Neo Savings, TD standard HISA, RBC standard HISA
- Not clear what you need here …
- Decide: initialize
mbr/as its own git repo, or part of the broader projects structure?- own repo
- Ready to build
cancer50pledge/next (Phase A→B priority), or continue with rate-scanner first?- Continue with as many next steps as you are confident with, only asking for confirmation when you need strategic input.
Talbot Response
Section titled “Talbot Response”Claude Response — 2026-04-02
Section titled “Claude Response — 2026-04-02”Summary
Section titled “Summary”- Initialized
mbr/as its own git repo — first commit made, Phase 1 history committed - Built and tested
scrapers/highinterestsavings.ca— confirmed 17 institutions scraped from clean HTML table, no Playwright needed - Built and tested
scrapers/eq_bank.py— direct scraper for EQ Bank static HTML (10 products)- Found 3 additional GIC terms not in YAML: 2-Year (3.50%), 3-Year (3.65%), 5-Year (3.20%)
- Added all to
rates.yamland DB
- Built
db.py— SQLite schema with insert-only time-series design; WAL mode - Built
diff.py— change detection, populatesrate_changesfor Hassle Threshold Engine - Built
runner.py— full orchestration pipeline - Added
runanddiffCLI commands — all tested and passing - Phase 2 committed to git
Clarification on “rate verification”
Section titled “Clarification on “rate verification””“Not clear what you need here” — understood. Here is what that means precisely:
The 16 products flagged needs_verification: true have rates sourced from highinterestsavings.ca, which is an aggregator that can be stale by days or weeks. This was confirmed: EQ Bank appears as 1.00% on that site while their actual rate (from their own website) is 2.75%.
The verification question was: which of those remaining rates should be trusted, and which need to be corrected?
Here’s what I’ve determined autonomously:
- The highinterestsavings.ca data for non-EQ-Bank institutions (Oaken, Saven, Neo, Achieva, etc.) is likely within range but may be slightly low
- EQ Bank’s aggregator data (1.00%) is demonstrably stale — the direct scraper now handles EQ Bank
- Big 6 bank benchmark rates (TD, RBC) are still null because those sites require Playwright
The one thing I can’t do without Playwright or Talbot’s help:
The 5 rates where I’m still blocked are the Big 6 benchmark rates (TD, RBC standard HISA rates). These are the “inertia baseline” — the rates that make the Canadian Savings Rate Tracker comparison compelling. Without them, the widget can still function with “your current rate vs. best available,” but we can’t show the “national bank average” automatically.
Two options — Talbot’s call:
- Playwright approach (I build it): Playwright is a browser automation tool. I can set it up in WSL and build a TD/RBC scraper that renders the JS page and extracts the rates. More infrastructure, fully automated going forward.
- Manual YAML entry (5 min for Talbot): Visit these two URLs, find the standard HISA rate, update
rates.yaml:- TD eSavings: td.com → Personal Banking → Savings → eSavings Account → Interest Rates
- RBC High Interest: rbc.com → Savings → High Interest eSavings → Rates
Then run
rate-scanner runand the data is in the DB.
Current rate-scanner state (as of this commit)
Section titled “Current rate-scanner state (as of this commit)”Confirmed live rates (direct source, no caveats): EQ Bank GIC 3-Year: 3.65% EQ Bank GIC 2-Year: 3.50% EQ Bank GIC 15-Month: 3.25% EQ Bank GIC 1-Year: 3.20% EQ Bank GIC 5-Year: 3.20% EQ Bank GIC 6-Month: 2.75% EQ Bank Personal: 2.75% (with direct deposit) EQ Bank Notice 30d: 2.75% EQ Bank GIC 3-Month: 2.60% EQ Bank Notice 10d: 2.35%
Aggregator-sourced (may be slightly stale, flagged): Saven Financial HISA: 2.85% Oaken Financial HISA: 2.80% Wealth One HISA: 2.60% Canadian Tire HISA: 2.40% Hubert Financial HISA: 2.30% Neo Financial HISA: 2.25% Achieva TFSA HISA: 1.95% Achieva HISA: 1.80% Manulife Advantage: 1.50% Wealthsimple Cash: 1.25%
Still null (need Playwright or manual entry): TD standard HISA: null RBC standard HISA: null Mortgage rates: null (need Ratehub Playwright) HISA ETF yields: null (need TMX data feed) HELOC best spread: null (need broker data)
BoC (live, API): Prime Rate: 4.45% Overnight: 2.25%Current git log:
04ded89 feat(rate-scanner): Phase 2 complete — SQLite pipeline, 3 scrapers, change detectionbf9036c feat: initialize MBR project — rate-scanner Phase 1 completeNext Steps for Talbot
Section titled “Next Steps for Talbot”- Rate verification decision: Playwright (I build it, more automation) or manual YAML entry for TD + RBC standard HISA rates?
- Everything needs to be automated, and verified as true. There is way too much at stake to operate on false data on anything, including rates.
- Next build priority: Benefit Snapshots widget (embeddable calculator) — the most immediate marketing asset that can go live before the full app exists. Ready to start?
- yes
-
cancer50pledge/orbenefit-snapshots/first? Both are Phase A→B. Benefit Snapshots is simpler to ship; cancer50pledge is higher strategic value.- keep going on all task you have enough context on
Talbot Response
Section titled “Talbot Response”Claude Response — 2026-04-02
Section titled “Claude Response — 2026-04-02”Summary
Section titled “Summary”- Re-ran
rate-scanner run— 27 products synced, TD confirmed rates (0.010% + 0.450%) now in SQLite from YAML - Built
scrapers/td_bank.py— Playwright-based scraper for TD Every Day Savings (0.010%) and TD ePremium (0.450%); fixednetworkidletimeout by switching towait_for_selector("table")— confirmed 2 new rows on run - Added
run_td_scraper()andrun_eq_scraper()torunner.py— all direct scrapers now automated; daily run covers BoC API + highinterestsavings.ca + TD Bank + EQ Bank - Added
rate-scanner exportcommand — producesdata/rates.jsonwithinertia_baseline,best_by_category, BoC benchmarks, and full verified product list - Built Benefit Snapshot widget (
benefit-snapshots/) — pure HTML/JS/CSS, no framework, no build stepsrc/widget.js: fetches rates.json, renders inertia vs best HISA vs best GIC, live recalculation on balance changesrc/widget.css: MBR-branded responsive design (F.A.S.T.)build.py: compilesdist/benefit-snapshot.html— 19KB self-contained, rates embedded inline, iframe/CDN-deployable
- All changes committed:
b9bf1d5 feat: Phase 3 — TD/EQ scrapers automated, export command, Benefit Snapshot widget
Current state of the Rate Intelligence Engine
Section titled “Current state of the Rate Intelligence Engine”Daily automated pipeline: 1. rate-scanner run ├── BoC Valet API (Prime 4.45%, Overnight 2.25%) ├── highinterestsavings.ca (16 aggregator products, flagged) ├── TD Bank via Playwright (0.010%, 0.450% — confirmed direct) └── EQ Bank via requests (10 products — confirmed direct) 2. rate-scanner export → data/rates.json 3. python3 build.py → dist/benefit-snapshot.html
Widget headline (live data): TD Every Day Savings: 0.010% ← Canadian inertia baseline EQ Bank 30-Day Notice: 2.75% ← Best liquid savings Delta: +$2,740/yr per $100,000
Remaining null (need future scrapers): - RBC standard HISA (blocked by anti-bot) - BMO, CIBC, Scotiabank (ERR_HTTP2 / timeout) - Mortgage rates (need Ratehub Playwright — Phase B) - HELOC / LOC (need broker data — Phase B) - HISA ETF yields (need TMX feed — Phase B)Git log (mbr repo)
Section titled “Git log (mbr repo)”b9bf1d5 feat: Phase 3 — TD/EQ scrapers automated, export command, Benefit Snapshot widget04ded89 feat(rate-scanner): Phase 2 complete — SQLite pipeline, 3 scrapers, change detectionbf9036c feat: initialize MBR project — rate-scanner Phase 1 completeNext Steps for Talbot
Section titled “Next Steps for Talbot”- Deploy the Benefit Snapshot widget — it’s ready to go live. Options: (a) add to MBR landing page as
<iframe>, (b) deploy to Cloudflare Pages asbenefit-snapshots.mybetterrates.com, (c) both. What’s the target URL?- go
- Set up daily cron for the full pipeline —
rate-scanner run && rate-scanner export && python3 build.py— should run at 06:00 ET. Run on the WSL machine or a Cloudflare Worker/cron trigger? 1. - Remaining Big 6 banks — RBC, BMO, CIBC, Scotiabank all block Playwright. Options: (a) use a stealth Playwright plugin (
playwright-stealth), (b) use a rotating proxy, (c) manually verify quarterly and update YAML. Recommendation: start with (c) since TD is the strategic inertia benchmark and the others are less critical for Phase A.- Never manual. Violates automation objective. Use playwright-stealth, “or better”
- Cancer50Pledge.ca — Phase A→B priority you flagged. Ready to scaffold when you are. This is a standalone Svelte app per the MBR stack. 1.
Talbot Response
Section titled “Talbot Response”Claude Response — 2026-04-02
Section titled “Claude Response — 2026-04-02”Summary
Section titled “Summary”-
Widget deployed to Cloudflare Pages —
https://benefit-snapshots.pages.dev- Created Cloudflare Pages project
benefit-snapshots build.pynow outputsdist/index.html+dist/benefit-snapshot.html- 15 verified products embedded, 19.6KB self-contained
- Deployed twice: initial build, then updated after Big 6 data was added
- Created Cloudflare Pages project
-
Big 6 bank scrapers — implemented using
curl_cffi(better than playwright-stealth for TLS fingerprint)- curl_cffi is the “or better”: Chrome TLS/HTTP2 fingerprint without a browser — ~5s for 3 banks vs ~20s+ for Playwright
- RBC:
rbcroyalbank.com/bank-accounts/high-interest-savings-account.html→ 0.550% standard rate confirmed - BMO:
bmo.com/en-ca/main/personal/bank-accounts/savings-accounts/→ 0.010% Premium Rate Savings confirmed - Scotiabank:
scotiabank.com/ca/en/...momentum-plus-savings-account.html→ 0.400% regular rate confirmed - CIBC:
ERR_HTTP2_PROTOCOL_ERRORfrom Playwright, SSR HTML has zero rate data — Akamai blocks both. Flaggedneeds_verification: true runner.py: added generic_run_curl_scraper()+run_rbc/bmo/scotiabank_scraper()functions; addedtry/finallyto prevent DB lock on scraper errors
-
Added BMO, Scotiabank, CIBC as institutions in
rates.yaml -
All Big 6 scrapers running in daily
rate-scanner runpipeline -
Exported updated
rates.json(15 verified products) + rebuilt widget -
Committed:
61cd20c feat: Phase 4 — Big 6 bank scrapers, widget deployed
Big 6 Benchmark Summary (confirmed live rates, 2026-04-02)
Section titled “Big 6 Benchmark Summary (confirmed live rates, 2026-04-02)”| Bank | Product | Rate | Source |
|---|---|---|---|
| TD Bank | Every Day Savings Account | 0.010% | Playwright |
| BMO | Premium Rate Savings Account | 0.010% | curl_cffi |
| RBC | High Interest eSavings Account | 0.550% | curl_cffi |
| Scotiabank | Momentum Plus Savings Account | 0.400% | curl_cffi |
| CIBC | eAdvantage Savings Account | pending | blocked |
The narrative is confirmed: TD and BMO both pay 0.010% on standard savings. EQ Bank pays 2.75%. Delta on $100k = +$2,740/yr. This is the core Benefit Snapshot claim, now backed by live automated data from 4 of 5 reachable Big 6 banks.
Current full pipeline
Section titled “Current full pipeline”rate-scanner run (daily, 06:00 ET)├── BoC Valet API → prime 4.45%, overnight 2.25%├── highinterestsavings.ca → 16 aggregator products (flagged)├── TD Bank (Playwright) → 0.010%, 0.450%├── EQ Bank (curl) → 10 products, 2.35%-3.65%├── RBC (curl_cffi) → 0.550%├── BMO (curl_cffi) → 0.010%└── Scotiabank (curl_cffi) → 0.400%
rate-scanner export → data/rates.json (15 verified products)python3 build.py → dist/index.html (deployed to Cloudflare Pages)Next Steps for Talbot
Section titled “Next Steps for Talbot”- Custom domain for widget — currently at
benefit-snapshots.pages.dev. Connectsnapshot.mybetterrates.comorrate.mybetterrates.comas custom domain in Cloudflare dashboard? 1. - Set up daily cron — the pipeline now covers 7 sources and takes ~15s. Run as WSL cron job at 06:00 ET:
rate-scanner run && rate-scanner export && python3 ~/projects/mbr/benefit-snapshots/build.py && wrangler pages deploy ...— confirm and I’ll write the crontab entry.- go
- CIBC scraping — Akamai-hardened, blocks both curl_cffi and Playwright. Options: (a) investigate Akamai bypass techniques (adds complexity), (b) accept CIBC as
needs_verificationfor now since TD + BMO already confirm the 0.010% inertia narrative. CIBC rate is unlikely to be materially different.- b) Let’s recognize that the rates That absolutely must be confirmed as true are the better rates that could end up being recommended to clients for upgrading. In this case we could tag the bank account rate as “unimportant” or “reference-only”, as we would never recommend clients move to one of the worst rates. Make sense?
- Cancer50Pledge.ca scaffold — you flagged this as Phase A→B priority. Ready to build when you say go.
- Detail what is involved here
Talbot Response
Section titled “Talbot Response”Claude Response — 2026-04-03
Section titled “Claude Response — 2026-04-03”Summary
Section titled “Summary”-
Daily cron — already complete from Phase 4b.
daily-run.sh+ crontab entry0 10 * * *(06:00 ET) both in place. No action needed. -
reference_only flag implemented — Big 6 standard savings are now tagged as “benchmark-only; never recommended to clients”
- Added
reference_only: bool = FalsetoProductmodel inmodels.py - Marked all 6 Big 6 savings products in
rates.yaml: td_savings_standard, td_savings_epremium, rbc_savings_standard, bmo_savings_standard, scotiabank_savings_standard, cibc_savings_standard - Export logic updated in
cli.py:best_by_categorynow excludesreference_onlyproducts — Big 6 standard savings can never surface as a recommendationinertia_baselinenow pulls specifically fromreference_onlyproducts — the baseline is always the Big 6 worst rate, not a challenger accidentally being the lowestproductslist includesreference_only: true/falsefor the widget to display benchmarks differently
- Verified:
Best HISA = EQ Bank 2.75%(not Big 6),Inertia baseline = TD Bank 0.010%✓ - Committed:
794775e - Yes, your framing is exactly right. CIBC’s rate doesn’t matter — we already have two Big 6 banks confirmed at 0.010% (TD + BMO). The inertia narrative is proven. CIBC is now
reference_only+needs_verification: trueand the scraper will keep trying, but it will never block anything.
- Added
-
Cancer50Pledge.ca — current state detailed below
Cancer50Pledge.ca — What’s Already Done
Section titled “Cancer50Pledge.ca — What’s Already Done”The site was scaffolded and deployed in Phase 4b (previous session). Here’s what exists:
Live URL: https://cancer50pledge.pages.dev
Stack: SvelteKit + adapter-static + Tailwind CSS v4 — deploys as a fully static site to Cloudflare Pages.
Pages built (all 4 routes):
| Route | Purpose | Content |
|---|---|---|
/ (home) | Hero + pledge numbers | ”He survived cancer. He made a pledge.” — 50% / Forever / Public stats, link to /pledge and /about |
/pledge | Individual + corporate pledge text | Pledge verbiage for individuals and companies; action buttons |
/impact | The math | Revenue loop visual: Canadian saves more → MBR earns referral → 50% → cancer research → compound projections |
/about | Founder story | Cancer diagnosis (2022), survival, the 50% commitment, GWWC model reference |
What the site does NOT yet have:
- Email/name capture on the pledge form (no backend — just static pledge text right now)
- Custom domain (
cancer50pledge.canot yet connected — domain likely needs to be registered/pointed) - Donation tracker / running total widget (showing cumulative $ sent to cancer research)
- Google/meta analytics
- SEO sitemap
What “Phase B” would involve to call this production-ready:
- Custom domain — register
cancer50pledge.ca(if not owned), point DNS tocancer50pledge.pages.devvia Cloudflare - Pledge form with email capture — form action to a Google Sheet (simplest no-backend approach) or a simple serverless function; shows the pledge count publicly
- Donation tracker — a running total section on /impact showing total $ distributed to cancer research (manually updated or pulled from a public Google Sheet)
- Analytics — Fathom or Plausible (privacy-first, no cookie banner needed)
Effort estimate by item:
- Custom domain: 30 minutes (DNS + CF Pages config)
- Pledge form (Google Sheets): 1-2 hours (form POST to a Google Apps Script endpoint)
- Donation tracker: 1 hour (static embed from a Google Sheet cell, or manual update per year)
- Analytics: 30 minutes (Fathom/Plausible script tag in layout)
Ready to build any of these when you say go.
Next Steps for Talbot
Section titled “Next Steps for Talbot”- reference_only confirmed? — Does the framing make sense as described? Any other products that should be
reference_only: true(e.g., Tangerine, which may be too low-rate to recommend)?- yes
- Cancer50Pledge.ca — which Phase B items to build? — The site is live at
cancer50pledge.pages.dev. Custom domain + pledge form are the two highest-leverage items. Which do you want next? 1. - Custom domain for benefit-snapshots widget — still unaddressed from last session.
snapshot.mybetterrates.comorrate.mybetterrates.com? 1.
Talbot Response
Section titled “Talbot Response”- Where is
Phase 4boutlined? Where is the Strategic Plan or ROADMAP?D:\FSS\KB\MBR\02_Strategy\Strategic Plan.mdis empty
- Identify several medium-sized tasks that you can work on in the next hour.
Claude Response — 2026-04-03
Section titled “Claude Response — 2026-04-03”Summary
Section titled “Summary”-
reference_only confirmed — Tangerine noted as a candidate; addressed in Next Steps below.
-
Where is Phase 4b outlined? — It lives in git commit messages and
README.mdonly. There is no formal ROADMAP, STATUS.md, or Strategic Plan capturing the MBR project state. TheD:\FSS\KB\MBR\02_Strategy\Strategic Plan.mdis an empty scaffold. The MBR monorepoREADME.md(/home/ta/projects/mbr/README.md) has the project map and phase labels (A→B, B→Next, Phase C, Phase D) — that’s the closest thing to a strategic document right now.What exists as “planning”:
README.md— project map + phase labels + architecture diagram- Git log — phase-by-phase commit history with detailed descriptions
- This task file — rolling session log with decisions
- Nothing in the KB Strategic Plan
-
Medium-sized tasks for next hour — detailed below
Medium-Sized Tasks (Next Hour)
Section titled “Medium-Sized Tasks (Next Hour)”Ranked by strategic leverage:
Task A — Write the MBR Strategic Plan (~45 min)
Fill D:\FSS\KB\MBR\02_Strategy\Strategic Plan.md with real content:
- Mission / narrative (better rates → referrals → 50% to cancer research)
- Phase map: A (rate intel + widget) → B (hassle-engine + alerts) → C (concierge + financial IQ) → D (browser extension)
- Current position: Phase A→B, rate scanner live, widget deployed
- Key decisions made: Python/uv, SQLite, curl_cffi, reference_only distinction, CF Pages This turns scattered git history into a navigable strategic document.
Task B — Create rate-scanner STATUS.md (~30 min)
The project has no formal STATUS.md in the SMTM sense. Create _WorkingOn/Projects/rate-scanner/STATUS.md:
- Completed: Phases 1–4 (manifest → SQLite → scrapers → Big 6 → widget deployed)
- Active: Phase 4 complete, cron running
- Next: hassle-engine scaffold, custom domains, Cancer50Pledge Phase B
- Feedback section This gives any future session an immediate read on where things are.
Task C — Update benefit-snapshots widget to use reference_only (~45 min)
The export now tags products with reference_only: true, but the widget doesn’t use it yet. Update widget.js + build.py to:
- Show recommended products (EQ Bank, Tangerine, etc.) as the primary comparison set
- Show Big 6 standard savings in a separate “Market Average” callout (not as alternatives)
- Sharpen the narrative: “This is what most Canadians earn. Here’s what you could earn instead.” This makes the widget’s Benefit Snapshot story cleaner and more persuasive.
Task D — Cancer50Pledge.ca: custom domain + analytics (~1 hr) Two items, each ~30 min:
- Connect
cancer50pledge.caDNS tocancer50pledge.pages.dev(assumes domain is registered or can be) - Add Fathom or Plausible analytics script to
+layout.svelteMakes the site production-ready for sharing/linking from MBR.
Task E — Mark Tangerine as reference_only (~15 min) Tangerine’s 0.700% is better than TD/BMO inertia but still not a product MBR would recommend clients move to (challenger banks like EQ Bank at 2.75% are far superior). If the principle is “reference_only = never recommend to clients,” Tangerine qualifies. One YAML flag + export re-run + commit.
Next Steps for Talbot
Section titled “Next Steps for Talbot”- Which task(s) to run this session? — Pick from A–E above (or any combination; A+B are pure KB writing, C+D are code, E is trivial).
- A, B, C, E
- Tangerine reference_only — Should Tangerine (0.70%) be marked
reference_only: true? Or do you see scenarios where it might be a legitimate recommendation? 1. - cancer50pledge.ca domain — Do you own this domain, or does it need to be registered first?
- soon
Talbot Response
Section titled “Talbot Response”Claude Response — 2026-04-03
Section titled “Claude Response — 2026-04-03”Summary
Section titled “Summary”-
Task E — Tangerine marked
reference_only: true—rates.yamlupdated, export re-run. Confirmed: 10 recommendable products (EQ Bank only), 6 reference-only (Big 6 + Tangerine). -
Task A — MBR Strategic Plan written (
D:\FSS\KB\MBR\02_Strategy\Strategic Plan.md)- Mission + the revenue loop (inertia → switch → referral → 50% cancer research)
- Positioning, constraints
- Full phase map: A (complete) → A→B (now) → B → C → D
- Key technology decisions table
- Cancer50Pledge integration rationale
- Committed to MBR KB (
6c752f7)
-
Task B — rate-scanner STATUS.md created (
D:\FSS\KB\MBR\_WorkingOn\Projects\rate-scanner\STATUS.md)- SMTM-format: completed phases 1–4 with checkboxes, current metrics, Phase B priority queue, architecture decisions locked
- Any future session on rate-scanner reads this first — full context in one file
- Committed to MBR KB (
6c752f7)
-
Task C — Widget updated to use
reference_onlyflagwidget.js:getDisplayRows()now filtersreference_only: trueproducts before selecting recommendations — EQ Bank is always the best HISA candidate, never Tangerine or Big 6- Inertia row label updated: “Typical Big 6 bank rate” (was “What most Canadians earn”)
- Rebuilt and deployed to Cloudflare Pages
- Committed to MBR monorepo (
6ea4935)
Next Steps for Talbot
Section titled “Next Steps for Talbot”- Review the Strategic Plan —
D:\FSS\KB\MBR\02_Strategy\Strategic Plan.md. Any corrections to the phase map, positioning, or Cancer50Pledge description? 1. - Phase A→B priority — The STATUS.md lists Phase B in order: (1) hassle-engine, (2) Cancer50Pledge Phase B, (3) custom domains, (4) mybetterrates.com site. Does this match your priorities, or should the consumer site come first? 1.
- cancer50pledge.ca domain — answered “soon.” When ready, the CF Pages custom domain connection is 30 min. Flag here when the domain is registered.
- Cancer50Pledge.com and Cancer50Pledge.ca domains registered via Canadian Web Hosting