Inspiration

Canada has dozens of federal, provincial and municipal benefits, and the people who need them most are often the least likely to find them. Newcomers, single parents, seniors and people with disabilities face a maze of pages written in legal English, spread across canada.ca, ontario.ca and toronto.ca. Rules change quietly, and a new bill can change who qualifies.

I wanted a tool where you just describe your life, in your own words and your own language, and get an honest answer: what you likely qualify for, about how much, and the official page to apply. The one rule I refused to break: an AI must never be the one deciding whether you're eligible.

What it does

  • Talk or type, in any language. Speech is transcribed with ElevenLabs, and Gemini turns the description into structured facts (age, household, income range, status in Canada) plus life events and needs, such as lost a job or behind on rent.
  • You confirm first. Every fact appears as an editable chip labelled from your profile or from what you said, so a misunderstanding never becomes a wrong answer.
  • A deterministic rules engine decides. It checks 13 federal, Ontario and Toronto programs (the Canada Child Benefit, Canadian Dental Care Plan, Canada Disability Benefit, Old Age Security, OSAP, Fair Pass and more). Each is likely, possibly or not eligible, and every reason links to the government page it came from.
  • Personal estimates. Where the government publishes the formula, you see your amount, e.g. "≈ $16,314 a year" for the Canada Child Benefit.
  • Questions that matter. It only asks follow-ups whose answer could actually change a result, and says how many results it could move.
  • Laws that affect you. A background worker tracks federal and Ontario bills. A reviewer approves who each bill affects, and results show "Affects you" or "May affect you".
  • Accessible and private. Grade 6 plain language, read aloud, English and French, WCAG 2.2 AA. No account needed; an optional Google sign-in saves an AES-256-GCM encrypted profile.

How I built it

  • Frontend: Next.js 16 (App Router), React 19, Tailwind v4, shadcn/ui, bilingual throughout, dark mode.
  • AI, strictly bounded: Gemini does only four things: extract facts, translate, summarize official text, and draft things for human reviewers. Its output schema is generated from one Zod schema, so the prompt, the forms and the database never drift apart. ElevenLabs handles speech-to-text and text-to-speech.
  • Rules engine: program rules are JSON Logic, each criterion citing a source URL and an exact quote. The engine is tri-state. If a fact is unknown, the answer is "unknown", never a guess. Income is collected as a range $[I_{\min}, I_{\max}]$, so every rule is evaluated at both ends:

  • Estimates use the published formulas at both ends of the income band. Each figure carries an expiry date. After it, the estimate is hidden and a test fails until the official page is re-checked.

  • Freshness: a Docker worker on Vultr polls LEGISinfo, the Ontario Legislature and the Canada Gazette, and re-checks every program page every 6–24 hours. Any change goes to a human review queue before a rule can change.

  • Data and auth: Postgres on Supabase (Canada Central), Auth0 with Google, the website on Vercel.

  • Testing: Vitest, including a golden set of 20 hand-worked people × 13 programs; Playwright end-to-end tests with axe accessibility scans; and database integration tests.

Challenges I ran into

  • JSON Logic treats a missing value as a value. undefined < 90000 is true, which would make unknown people "eligible". I built a tri-state evaluator that refuses to guess.
  • Keeping the AI in its lane. The model never writes rule logic. When it drafts a bill impact or a new program, it picks conditions from fixed lists; code builds the logic, and a human approves it.
  • Honest numbers under uncertainty. For the Canada Disability Benefit, income depends on work income the app doesn't ask about. I encoded only what the published figures prove for everyone and marked the rest "check the official page".
  • Production surprises. A "Gemini returned invalid output" error was really the free-tier quota, so I added quota detection and a fallback model. I also hit Supabase's certificate chain failing TLS verification, an Auth0 Google connection that wasn't enabled, and ElevenLabs rejecting library voices on the free plan.
  • Accessibility on real devices. Things like 24 px targets, French labels overflowing buttons, and a header that wrapped in French at 1280 px.

Accomplishments that I'm proud of

  • Zero AI eligibility decisions. Every verdict is reproducible, explained, and cited to an official page.
  • The landing page's example result is computed live by the same engine, so the pitch can't drift from the product.
  • A golden set that fails the build if a rule change flips anyone's result.
  • Fully bilingual, WCAG 2.2 AA, with speech in and out, from the landing page to the admin review queue.
  • Built solo, end to end: frontend, rules engine, AI pipeline, ingestion worker, deployment and tests.

What I learned

  • Where to use an LLM: turning messy human language into structure. Where not to: rules people's money depends on.
  • "Possibly eligible, and here's exactly what to check" is more useful, and more trustworthy, than a confident wrong answer.
  • Government data changes constantly, so freshness dates, source quotes and human review are features, not overhead.

What's next for Benefit Bridge

  • Grow the catalogue. Reviewers paste an official page and the worker drafts the program for approval, prioritized using anonymous counts of needs the app couldn't match.
  • More provinces and cities beyond Ontario and Toronto.
  • Estimates for more programs as formulas are verified.
  • Partner with settlement agencies and caseworkers, with a caseworker mode and printable checklists in the client's language.
  • Deadline reminders for signed-in users.

Built With

Share this project:

Updates

Submission history