July 6, 2026 — Slice 9: Demo mode & polish ✅ (awaiting founder verification — the timed run is yours)
What was built
npm run demo— one command resets the world to the curated demo story and prints the pre-meeting cheat sheet (tabs to open, sign-in codes, the five beats, the closing numbers). Same reset asnpm run seed, plus the crib notes.- The DEMO WORLD ribbon — a slim amber banner on every screen whenever the app is running on the seeded fictional world. It keys on the DATA itself (the fictional employer + a seeded member code), not a settings flag — so a demo can never be mistaken for real people, and if real people ever replace the demo data the ribbon disappears by itself (
lib/demo.ts). DEMO_SCRIPT.md— the word-for-word 5-minute script: five beats (Sarah's $0 MRI booked live → approving Grace's engine proposal live → Pete's drafted ER-bill fight → the ledger → the employer's payoff numbers), with timings, what to click, what to say, a fix-it box, and the honest asterisks. Every number in it was checked against the database.- Bills desk index (
/console/bills+ a "Bills" nav link) — the missing list of every bill-defense case with status and knocked-off savings; the demo (and daily work) needed a way to reach a bill without hunting.
How it was verified
npm run demoruns clean and prints the sheet. tsc clean, 152/152 tests, production build clean.- Walked every demo station in the browser at demo sizes (member app at phone width): home, Sarah's options ($0 Gem State + the exact deltas the script quotes), mission control with Grace's proposal, Pete's bill page with the drafted letter, the bills index, the ledger, the employer dashboard. Ribbon present everywhere; zero browser errors.
- The script's numbers reconcile with the database: $425 MRI / +$50 / +$465 / +$1,325 deltas; plan spent $2,493.00; saved $4,436.00; members paid $40.00; 11 of 12 took the recommendation.
Founder still to do (the slice's definition of done): run the demo start-to-finish from DEMO_SCRIPT.md, timed, in under 5 minutes, without touching anything broken.
Stage one is now feature-complete. All ten slices built. What remains for the stage-one definition of done: the founder's timed demo run, and the first REAL concierge care event — a real person, a real quote, a real cash payment — recorded end-to-end to produce ledger row #1.
July 5, 2026 (later) — Slice 8: Employer dashboard + the engine's track record ✅ (awaiting founder verification)
Founder gave the go-ahead on the engine session below ("go ahead"), so this same day continued with the next increment.
What was built
- Employer dashboard (
/employer) — the business owner's view, real numbers only: plan spend, saved vs the old way, monthly cost per person (PMPM, explained in plain words), and "recommendation taken" (the capture rate, as "11 of 12"), plus month-by-month spend bars, spend by kind of care, and recent activity. Privacy is built in, not policy: care is shown by category only — never who or what — because in a 27-person company even a service description can identify someone. Only this plan's own transactions; no market analytics, nothing from the wider ledger. - The engine's track record (on
/console/engine, above the dials) — every founder decision on engine work, counted per kind: ran on its own / approved as-is / you fixed it first / rejected / waiting. This table is the evidence autonomy promotions are earned with; superseded drafts never count for or against.
How it was verified
- Dashboard numbers reconciled against the raw database by hand: 12 payments, plan paid $2,493.00, members paid $40.00, saved $4,436.00, capture 11 of 12 — every figure matches a direct SQL sum of the ledger rows.
- Track record renders correctly from the seeded engine story (1 approved, 2 waiting, autos counted).
- tsc clean, 152/152 tests, seed clean, production build clean, zero browser errors. Screenshot shared with the founder.
What's next
- Slice 9: demo mode & polish (the 5-minute demo script,
DEMO_SCRIPT.md) — the last slice. - Then the first real concierge care event: a real person, a real quote, a real cash payment, ledger row #1.
July 5, 2026 — THE ENGINE: the autonomous operator ✅ (awaiting founder verification)
Founder direction (recorded, permanent): "Everything that can be done by hand can be done by automation right now, while still upholding the reasons we would want to do it by hand (collecting training data) — let's create the most autonomous version possible." This session built it. The engine replaces Slices 4–5's manual-first plan with an autonomy-first one: the software does the work, the founder approves it, and every action + decision is recorded as the training data autonomy promotions are earned with (per the working agreement's own autonomy tiers: start conservative, promote on evidence).
What was built (the engine, lib/engine/):
- Emergency check (
triage.ts) — a hard-coded, versioned red-flag rule list (chest pain, stroke signs, anaphylaxis, ~16 more) that scans every request. Never an AI decision, never cost-aware, fails toward the ER. If it sees a red flag the member didn't mark, it escalates the request itself so the member's screen shows the call-911 guidance — widening safety is the one direction the engine moves alone. 91 tests. - Reading the request (
intake.ts) — the member's words → care category + likely billing codes, via AI (only PHI-minimized fields leave the machine: the care text, urgency, an age band, sex — never a name, birth date, code, or address) with a no-AI keyword fallback. - Price lookup (
prices.ts) — every price the company knows, evidence-tiered: verified-by-payment (the ledger) > phone quotes > posted price files (the 9,960 real Treasure Valley prices) > the demo book, each with plain-language provenance. Pure data, no AI. Verified prices are founder-eyes-only intel — never auto-published (ledger secrecy). - The frozen ranking (
rank.ts) — clinically valid → cheapest → alphabetical. Nothing else, ever; AI can never touch the order. Tested. - Drafters (
drafts.ts) — the "why every option here is safe" note, the doctor-office confirmation phone script, member updates. Names never travel to the AI: prompts carry [FIRST_NAME]/[DOCTOR]/[CLINIC] tokens, real words filled in locally. - The bill reader (
bills.ts) — reads uploaded bills (photo/PDF) with AI vision, matches them against the ledger (deliberately high bar: a bill naming a provider we didn't pay can never match a payment to a different provider — a letter must never tell provider A what provider B accepted), and drafts the response letter. - The orchestrator (
run.ts) — runs the whole chain automatically when a member asks for care or uploads a bill; every step degrades gracefully (no API key → fallbacks; any failure → a plain note and the manual path). - Mission control (
/console/engine) — the founder's approval queue: proposals grouped by member, each with its full evidence (every price's origin, how the request was read), one-tap Approve & publish / Edit first / Reject-with-reason; an "everything the engine did on its own" log (autonomy is never hidden); the autonomy dials, with outward-facing work locked to approve-each and a plain statement of what's never automated (money, narrowing, outward sends, the ranking, negotiation — no dial exists). - Every engine action is a row in
engine_actions— proposal, evidence, confidence, the founder's decision, and his edits. That table is the training ledger. - v8 rename done:
same_day_prepay→same_day_paymenteverywhere (schema, console, CSV export, seed), plus the full language sweep — the story everywhere is now "price agreed before the visit, paid in full the day of care."
How it was verified
npx tsc --noEmitclean · 152/152 tests green ·npm run seedclean (9 engine actions in the demo world) ·npm run buildclean.- Live in the browser: signed in as Sarah, typed "my chest feels tight and it's a little hard to breathe" with "sometime soon" urgency → the engine escalated it and her screen showed the call-911 banner on the next load; the console trail shows "RED FLAG — the member's screen shows the call-911 guidance." Mission control renders both seeded proposals (Grace's mammogram options draft with $0 on top + provenance per price; Pete's ER-bill letter) with zero browser errors.
- A 5-lens adversarial review (invariants, correctness, safety/privacy, regressions, plain language) confirmed 35 findings; every one was fixed this session except four accepted-and-documented items below.
Accepted, on purpose (stage-one posture — revisit at stage two):
- Console pages (including mission control) have no sign-in — same as the rest of the console; the app is local-only by the data-safety rule. Real credentials come with the stage-two security review.
- Reading an uploaded bill sends the bill image to the AI, and bills carry the member's name. That is the same act as the founder reading a bill himself today; it's disclosed here, and stage two's review covers it formally.
- The AI's reading of the request picks which billing code gets priced (a human-judgment stand-in). The founder sees the full evidence — every code candidate and every price — on each proposal before anything publishes.
- Quotes gathered on one request resurface as engine evidence on later requests. That's the price map working as designed — breadth is the point.
What's next
- Founder walks the verify checklist (in the chat summary) and says the word.
- Slice 7 (bill defense tracker) is now half-built by the engine; Slice 8 (employer dashboard) and Slice 9 (demo polish) remain.
- Next autonomy increments, each gated on the recorded track record: engine drafts member status messages in real flows; instrumentation view (approve/edit/reject rates per action type) to make promotion decisions evidence-based.
July 3, 2026 — Slice 6: The ledger ✅ (awaiting founder verification)
What was built
- Payment recording — on any booked (or completed, or emergency) request: enter what the provider actually accepted — the moat number. The money engine settles the split itself: the member's share stays exactly what they agreed to at choice time, and any prepay discount you negotiate is the plan's win. Same-day prepay is detected from the two dates. An optional "more detail for the actuary file" section captures list price, posted cash price, Medicare rate (→ % of Medicare computed), the old-way price (→ savings computed), codes, receipt reference, and who took the payment. Emergencies record against whoever got paid, member share always $0.
- The ledger browser (
/console/ledger) — every payment with filters (month, kind of care, member name), live totals for the filtered view (paid / plan's share / members' share / saved vs. the old way), and the average %-of-Medicare where known. Clearing prices live here and never leave the console. - The two actuary files:
ledger-<date>.csv— 45 columns, one row per payment, every Section 8 field plus member age-at-service/sex/ZIP and provider site/metro joined in. Money as plain dollars, dates as dates, yes/no as words — opens clean in Numbers/Excel.pmpm-<date>.csv— month, enrolled members, payments, plan paid, member paid, plan cost per member per month.- PMPM table on the ledger page, same numbers as the CSV.
How it was verified
- Recorded a real payment on Kayla's booked visit: quoted $165, entered $150 actually accepted, Medicare rate $140, old-way price $285 → engine recorded paid $150.00 / member $0.00 / plan $150.00, % of Medicare 107.1, savings $135.00, same-day yes.
- Found it in the browser with correct totals; CSV validated with a real CSV parser: 45 columns, 13 rows, every field in its right column (including quoted commas like "Boise, ID"); only
cpt_modifierempty across all rows (it's rare by nature). - PMPM hand-checked: February = $900 plan paid ÷ 15 members = $60.00 exactly.
- Zero TypeScript/browser/server errors; 32/32 tests; world re-seeded.
- Adversarial review pass: 17 confirmed findings, all fixed and re-verified live. The ones that protect the moat: 1. The member's difference is charged once, ever. Multi-payment care (like a PT course) was re-charging the full difference on every payment row. Now the engine's locked number is collected exactly once across however many payments a care event takes — verified live: $200 deposit collected the $50 difference; the $275 balance charged the member $0.00. 2. The plan can never book a profit off a member. The engine now refuses any settlement below the member's own share (no negative plan-paid rows), and zero-dollar "payments" can't be recorded — every ledger row is a real payment, as Section 8 demands. 3. Money freezes the workflow. A request with ledger rows can't be "closed without care" or unwound — the payments prove care happened. Double-clicks on Record can't book the same payment twice. 4. The actuary files got honest: claim-free months now appear in the PMPM (January's 15 member-months of exposure were being silently dropped — that overstates PMPM to an actuary); the %-of-Medicare headline is now dollar-weighted the way underwriters actually compute it; "saved vs. the old way" says "(where known)"; the posted-cash "as of" date is now enterable instead of silently stamped with today. 5. Plainness: distinct column headers (We paid / Member's share), stale "arrives in Slice 6" copy removed, the locked-share sentence shows the actual dollar amount and what's still uncollected, empty states tell the truth, /data's narration computes its numbers instead of hardcoding the seed story.
- Known stage-one limit (recorded honestly): if a member is ever termed, historical PMPM denominators will need a coverage-end date — flagged in the code for when terming becomes real.
What's next
- Slice 7 — Bill defense tracker (the purchasing desk for the unroutable tail).
July 3, 2026 — Slice 5: Console quotes & routing ✅ (awaiting founder verification)
What was built
- The quote workbench — on any request in "Finding prices," the console now has the real workflow, laid out in the order of your actual work: 1. Check the baseline: search the real Treasure Valley price map (9,960 procedures from the hospitals' own published files) by code or plain words — every system's posted cash price, sorted cheapest first. Console-only; never member- or employer-visible. One click carries a code + description into the quote form. 2. Record every quote: provider (from the providers list), plain description, price, source (phone / posted file / website / in person), who confirmed it, reference #, notes for the member — and a "show this to the member" switch, because some quotes are intelligence, not offers. Every quote becomes a permanent row in the price map you own. 3. The routing decision: pick the recommended option and write the why-it's-safe note (required — no routing without it), then Publish to the member. The money engine itself gatekeeps the publish: a set with no recommendation or bad prices is refused.
- Providers page (
/console/providers) — the directory, plus add-a-provider (name, type of place, city, system, phone, NPI, cash notes) for when real operations start. Quotes can only attach to real provider rows. - Hidden quotes can be shown/hidden/deleted freely; the member's chosen option is untouchable. The price-book shortcut remains only when zero quotes exist.
How it was verified
- The brief's exact checklist, on Janet's seeded colonoscopy: revealed the seeded Eagle View quote ($1,350), hand-entered two more (Meridian Outpatient $1,850 phone quote w/ reference; Cottonwood Pavilion $3,400 posted file), looked up "colonoscopy" in the real map alongside (TVH $1,346 / St. Luke's $2,509 / Saint Al's $2,962 — real posted prices), recommended Eagle View with a written validity note, published — and Janet's member app instantly showed all three with exact engine math: $0 / +$500.00 / +$2,050.00, choose buttons live.
- Caught in verification: a seeded operator-facing note would have shown to the member once the quote was revealed — reworded. Zero TypeScript/browser/server errors; 31/31 tests; world re-seeded.
- Three-auditor adversarial review pass: 16 confirmed findings, all fixed and re-verified. The important ones: 1. Published sets are now immutable. Quotes could be added to, hidden on, or deleted from a member's LIVE options screen (stale tab, no guard) — including deleting the recommended option, which would have silently zeroed a member's agreed pay-the-delta difference. Now: quotes are only editable before publishing; to change a live set you unpublish first ("go back one step"); quotes on booked/completed requests are permanent records. 2. The diagnosis rule got a mechanical gate. "No order → doctor-visit options only" was just an amber note; now the provider dropdown on diagnosis requests only contains offices and urgent cares, and both the add-quote and publish actions refuse anything else. 3. No booking on a broken set. If the money engine refuses an option set, neither the console nor the member app will book it (previously it would book with corrupted capture data). 4. Blank-looking prices ("$", a space) no longer become real $0.00 quotes; absurdly large prices are refused kindly instead of crashing. 5. A quote typed during a phone call is never lost — validation errors send every field back into the form. 6. Evening-entered quote dates and enrollments no longer record as tomorrow (Boise time vs. computer time). 7. Smaller: providers can carry a non-Boise area (mail-order); hospital-file jargon no longer prefills the member-visible description (code only, "write it in your own plain words"); searching the map no longer wipes form prefills; all-quotes-hidden now explains itself; a missing price-map file says so instead of "no matches."
What's next
- Slice 6 — The ledger: payment recording, ledger browser, actuary CSV export, PMPM summary.
July 3, 2026 — Slice 4: Console intake & workflow ✅ (awaiting founder verification)
What was built
- The queue (
/console) — every care request with plain status chips, filter buttons with live counts (All / Just arrived / Finding prices / Options sent / Booked / Done / Closed), urgent and emergency requests floated to the top. Doctor orders awaiting confirmation stay pinned above everything — nothing routes past that gate. - Request detail page — the workflow cockpit for one request: who it's for (linked to their profile), how it came in (doctor-ordered with confirmation state, or needs-a-diagnosis), a status trail (Just arrived → Finding prices → Options sent → Booked → Done), the options on the table with each one's member-pays number from the money engine, and a "What's next" panel that always shows exactly one next real-world action:
- confirm/decline the doctor's order → Start finding prices → Publish options (diagnosis requests can only ever publish doctor-visit options; procedures only after a confirmed order; emergencies never) → Mark booked (pick which option the member chose — records the capture flag) → book & prepay instructions → Mark done with an outcome note.
- Plus "go back one step" for mis-clicks and "close without care" with a reason, from any non-final state.
- Operator intake (
/console/requests/new) — a member calls or texts; you type it in: member picker, their words, diagnosis vs. doctor-ordered (with doctor fields), urgency. Doctor-ordered requests land in the confirmation queue, same as app-submitted ones. - Member profiles (
/console/members/[id]) — demographics (age, DOB, sex, ZIP — what actuaries price on), coverage, every care request, every bill. - Manual enrollment (
/console/members) — stage one has no payroll feeds by design: enroll a member by hand, and their member code (TRM-016…) and private access code (e.g. GLACIER-39) are generated on save. The code is shown once, on the enrollment banner, for you to hand over — it appears nowhere else in the app.
How it was verified
- Walked the exact checklist: created a request for Miguel from the console → Just arrived → Start finding prices → Finding prices → Publish doctor-visit options → Options sent (3 clinics, $0/$30/$115 member-pays from the engine) → picked North End, Mark booked → Booked (with book-and-prepay instructions) → outcome note, Mark done → Done ✓. Database confirms capture flag "yes" and the outcome note.
- Abandon path: created and closed a second request with a reason → "Closed without care."
- Enrolled a test member end-to-end: TRM-016 with generated access code, shown once.
- Zero TypeScript/browser/server errors; 31/31 money tests still green; world re-seeded clean.
- Caught and fixed during build: the publish action originally allowed procedure options on a diagnosis-path request (rule-B violation) — now diagnosis requests can only publish visit options, procedures only behind a confirmed order.
- Three-auditor adversarial review pass: 17 confirmed findings (several duplicates), all fixed and re-verified in the browser. The ones that mattered: 1. (Important) The zombie: closing a doctor-ordered request while its order was unconfirmed left it sitting in the confirmation queue, where one click would resurrect it into live, bookable member options for care the member was told was closed. Fixed on both sides: closing resolves the pending confirmation, and the confirm button refuses closed requests. 2. Capture-rate protection: closing a booked request now resets its "took the recommended option" flag to not-applicable — cancelled care can never count for or against the capture rate Slice 8 reports to employers. 3. Emergencies get an honest ending: they can now be marked "Done ✓" directly (with a note) instead of being forced through "Closed without care" — and their console page no longer offers "Start finding prices" or falsely says "order could not be confirmed." 4. One name for one thing: the booked state now reads "Booked" everywhere (was "Scheduled"/"Booked" mixed). 5. Smaller: undo/redo no longer duplicates the safety note; enrollment validates birth dates (no future babies) and ZIPs, speaks plainly ("didn't parse" is gone), and the access-code banner tells the truth about where the code lives.
What's next
- Slice 5 — Console: quotes & routing (hand-entered quotes, the real price map at data/price-map.json as a standing source, recommendation + validity note, publish to member).
July 3, 2026 — Slice 3: the plan-logic engine (money math) ✅ (awaiting founder verification)
What was built
- The engine (
lib/plan-logic.ts) — one small, pure module that computes every money outcome: $0 when the member takes the recommended option; exact-to-the-cent pay-the-delta when they pick pricier (plan still fronts the full price; member settles the difference with us, never at the desk); $0 for cheaper/equal picks (the price signal steers, never punishes); $0 member / audited-settlement plan cost for emergencies; and hard refusals for anything unpriceable (no options, no recommendation, unknown choice, corrupted prices). All money is whole cents — no rounding errors possible. It also produces the exact ledger split Slice 6 will record (amount_paid = member_paid + plan_paid, always). - The scenario table (
lib/plan-scenarios.ts) — 12 plain-English situations with expected numbers, including the brief's required edge cases (member picks the priciest option; only one valid option exists) plus cheaper-pick, tie-price, diagnosis visit, emergency settlement, and four "refuse, don't guess" rows. - Automated tests (
npm test) — 25 tests: every scenario row, plus invariants that must always hold (member never owes negative, ledger always balances, fractional cents refused, ambiguous recommendations refused, deltas exact to the cent). - The /scenarios page — the same table, rendered live in the browser with the real engine; every row shows member pays / plan pays up front / plan's final cost with a ✓, and the banner turns red if the engine ever disagrees with the table. Linked from the home page.
- One source of truth: the options screen, confirm screen, handled screen, and console "to book" list all now get their numbers from the engine — no hand-rolled arithmetic left in the screens (verified in-browser: same numbers as before, to the cent).
How it was verified
npm test: 30/30 pass./scenarios: "All 15 scenarios come out exactly as written," zero mismatches.- Member options screen re-checked after the rewiring: $0 recommended, +$50.00 / +$465.00 / +$1,325.00 deltas unchanged.
- Adversarial review pass: a 200,000-run randomized fuzz found ZERO money-math violations in the core engine. Confirmed contract gaps, all fixed:
1. Emergencies now report "not applicable" for the capture flag (they sit outside the capture rate — previously they'd have counted as a "yes" and inflated Slice 8's number).
2. New engine capability + policy row (
settleChoice): when the desk clears a price below the quote at payment time (Grace's $450→$425; Mark's $650→$595 in the seed), the member's share is LOCKED at choice time — the negotiating win belongs to the plan. This was a genuinely undecided question; the rule is now written in the scenario table for the founder to confirm or veto. Slice 6 will record amount_paid = what was actually accepted (the moat number), never the quote. 3. New scenario pinning the delta's anchor: the difference is measured against the RECOMMENDED price, never the cheapest quote. 4. Refusal rows now check the reason for refusing, not just that it refused (on the page and in tests) — a wrong-reason refusal turns red. 5. Last hand-written money sentence on the options screen replaced with the engine's story. - Founder still to do: read the /scenarios table and confirm every row matches intent — especially the "locked when they choose" rule in "Pricier pick, then settled below the quote."
Product decision recorded (July 3, 2026) — pharmaceuticals
- Meds route like everything else: cheapest clinically-valid option, $0 routed, pay-the-delta off it. For maintenance fills (90-day generics), that's usually Cost Plus Drugs (costplusdrugs.com) — mail-order, ~5-day shipping, published cost+15% prices. For a med needed today, mail order isn't clinically valid, so the local pharmacy becomes the recommended $0 option. "Cheapest valid" covers it; no special case needed. A prescription is a doctor's order, so pharmacy rides the existing order-confirmation gate.
- Built the same day: Cost Plus Drugs seeded as the demo world's one REAL provider (real because its prices are public by design); Deb's in-flight refill demos the flow ($12 Cost Plus at $0 / Hyde Park +$16 / Ridgeline +$22); scenario row "Maintenance medication — mail order is cheapest" pins the rule in the tested table (now 16 scenarios, 31 tests, all green).
July 3, 2026 — Real Treasure Valley price collection (founder request, pre-Slice 4)
What was done
- Ran the autonomous price-map collector (
ingest.py) against every source: all 7 existing sources healthy and current (St. Luke's Boise/Meridian + Nampa, Saint Alphonsus Boise + Nampa, West Valley Caldwell, Treasure Valley Hospital, Tellica flat prices). Hospital files are their latest published versions (March 2026 for the big systems). - Widened the map: probed both health systems' transparency pages for facilities we were missing. St. Luke's other files are all outside the valley (Magic Valley, Wood River, McCall) — coverage was already complete. Added Saint Alphonsus Ontario (western Treasure Valley, where Payette/Fruitland members go): +2,759 procedure prices.
- The map now: 8 facilities, 5 systems, 9,960 procedures with real cash prices. Copied to
data/price-map.jsonso the console can use it as a standing quote source from Slice 5 on. Refresh anytime withserver/.venv/bin/python ingest.py. Browsable attreasure-valley-price-map.html. - Reality check on the demo procedures (real cash prices): knee MRI $550 (Tellica) → $816 (TVH) → $1,857 (St. Luke's) → $2,287 (West Valley); colonoscopy $1,346 (TVH) vs $2,962 (Saint Al's); CT head $350 (Tellica) vs $2,253 (West Valley). The 4x spreads the product monetizes are real and documented.
- Provider intelligence (not map data): Primary Health (biggest urgent-care chain in the valley) posts self-pay deposits, not prices — $200 minimum for an urgent-care visit, "may not cover the full cost." Deliberately NOT added to the price map (a deposit isn't a price); belongs in cash_pay_notes when real providers are entered via the console.
- What can't be collected programmatically: ASCs, imaging centers (besides Tellica), urgent cares, and labs aren't required to publish machine-readable files — those prices come from phone quotes, which is exactly what the console's Slice 5 quote-capture workflow is for.
What's next
- Slice 4 — Console: intake & workflow (request queue with statuses, member profiles, urgency flags).
July 2, 2026 — Slice 2: confirm → handled → bills → history ✅ (awaiting founder verification)
What was built
- Booking. Every option now has a "Choose this one" button → a "Lock it in?" confirmation screen with the two numbers side by side (you pay / the plan pays up front; the delta explained when they pick a pricier option) → "Yes — book it." Double-taps can't double-book. Booking only exists on requests that already passed the doctor-order gate.
- "Your care is handled" screen. After booking: where you're going (name, address, phone), what happens next ("we're booking and paying the full price up front — we'll text your appointment time"), and the front-desk promise ("you pay nothing and sign nothing about money"; delta case: "your difference is settled with us directly, never at the desk").
- Bill upload. "📄 Send us a bill" on the member home → photo/PDF (15 MB max), who it's from, amount if readable, notes. The file lands in
uploads/bills/(local only, gitignored) and a bill-defense case opens in "We're reviewing it" — feeding straight into Slice 7's tracker. Members can view their own uploaded file; nobody else's. - History. Member home now shows both care (with status chips through booked/done) and every bill they've sent, including "We knocked $X off" once resolved.
- Console: "To book & prepay" list — members who confirmed, which provider, exactly what to prepay and any member-owed difference.
- Schema:
care_requests.chosen_option_idrecords the confirmed choice (capture-rate integrity);bill_defense_cases.original_bill_amountis now optional (members often can't read the amount — the operator fills it in during review).
How it was verified
- Phone-sized window, as Sarah: MRI request → chose Gem State ($0) → confirmation screen → booked → "Your care is handled" with address, phone, and the $0 front-desk promise. Console showed it under "To book & prepay ($425, member owes $0)" alongside Kayla's seeded booking.
- Uploaded a fake bill image (generated "St. Anselm — $1,912.00" statement) → confirmation banner → history entry with "We're reviewing it" chip → "See what you sent" serves the image back (verified 200, image/png, correct bytes; file present on disk; database row exact).
- Zero TypeScript/browser/server errors. Demo world re-seeded clean afterward.
- Adversarial review pass: 3 confirmed findings, all fixed and re-verified. The one that mattered: on a pricier pick, the confirm screen called the plan's share what it "pays up front" — but the plan actually fronts the chosen option's full price and the member settles the difference with us afterward. All screens now tell that one story ("you pay $465 / full price $890 — we pay it all up front"). Also fixed: Pete's seeded bill showed a dead "see what you sent" link (his was a paper bill; no link now). Honest caveat: the file-handling audit lane stalled and never finished — upload validation was verified by hand (type/size rejects, amount parsing, path containment, ownership) but got less independent scrutiny than the rest; worth a second look when Slice 7 builds on it.
What's next
- Slice 3 — the plan-logic money-math engine with the plain-English scenario table (tests required per working agreement 7).
July 2, 2026 — Two founder rules built: verified identity + doctor-order verification ✅ (awaiting founder verification)
Product rules recorded (permanent, founder-set)
- Verify people are who they say they are. No more pick-your-name list. Every member signs in with a private access code handed to them at enrollment (e.g. Sarah:
BIRCH-52). Codes are deliberately shown nowhere in the app — they print in the Terminal when you runnpm run seed. Stage-one level by design — real credentials come with the stage-two security review. - Never route a procedure on the member's say-so. Tests, scans, therapy, surgery: the member tells us which doctor ordered it, and we confirm with that office before any options or prices appear. The one exception: when the member needs a diagnosis ("something's wrong, help me figure it out"), we route them immediately — but only to doctor-visit options; that visit produces the order for everything after. Emergencies are never shopped, under either path.
What was built
members.access_code+ sign-in screen (wrong code → friendly error + lost-code help; codes normalize, so "birch 52" works).- Request form now has two doors: "Something's wrong — help me figure it out" vs. "A doctor already told me what I need" (reveals doctor name/clinic fields; name required).
- Doctor-ordered requests: status chip "Checking with your doctor," a plain-words explanation screen, zero prices shown.
- Console confirmation queue (early piece of Slice 4): every doctor-ordered request waits there; one click ("Order confirmed with the office") publishes price-book options to the member — or moves it to "Finding prices" when we don't have pre-researched quotes. Chris Bannon's seeded sleep-study referral sits in the queue for demos.
- Diagnosis path: instant doctor-visit options — North End Family Medicine at $0 (plan pays $145), Overland +$30, Express Care +$115; urgent versions route to walk-in clinics.
- Seed updated: every care request (in-flight and completed) now records its intake path, order status, and ordering doctor.
How it was verified
- In a phone-sized window: wrong code rejected;
birch-52signs Sarah in. - Doctor-ordered knee MRI → "We're checking with your doctor" with no prices → console queue showed it (count 2 with Chris's) → one click confirmed → member instantly saw Gem State $0, +$50, +$465, +$1,325, with "Dr. Lena Ferris's order confirmed with their office" leading the safety note.
- Symptoms request ("knee hurting for weeks") → instant visit options, $0 North End, +$30 delta.
- Zero TypeScript/browser/server errors. Demo world re-seeded clean.
- A 25-agent adversarial review pass confirmed 16 findings — all fixed and re-verified, the big ones being: the /data page and the sign-in example were both leaking real access codes (removed; codes now live only in the Terminal); the "which doctor?" error used to wipe the member's typed request (now everything is preserved); the console queue only had a "confirm" outcome (a "couldn't confirm — close it" path now exists, and the member sees an honest closed-state message); the console now previews exactly which options will publish before you click confirm; double-clicking confirm can no longer publish options twice; "BIRCH 52" with a space now signs in; assorted jargon ("CPT 73721," "BI-RADS," "system-owned") replaced with plain words.
What's next
- Slice 2 — Member app: confirm → "your care is handled" → bill upload → history. (Booking will respect the confirmation gate.)
July 2, 2026 — Slice 1: Member app, request → options ✅ (awaiting founder verification)
What was built
- Mobile-first member flow at
/member: - Who are you? — a one-tap member picker; the phone remembers the choice. (Deliberately demo-grade identity — real sign-in is stage two, after the security review.)
- Member home — greeting, "+ Ask for care" button, and the member's own care list with plain-language status chips ("Your options are ready", "Finding prices", "Done"). Members see only their own care.
- Ask for care — plain-words description box plus a "how soon?" choice. The Emergency choice tells the member in red: call 911 / go to the nearest ER now, send us every bill after. Emergencies are never shopped.
- Options screen — the recommended option on top in green with a big $0; every alternative shows "+$X — what you'd pay" with the exact difference; the clinical-validity note ("Why every option here is safe") sits above the options; footer says any provider works (pay only the difference) and how to book (call/text us — in-app booking is Slice 2).
- Price book (
lib/demo-price-book.ts) — pre-researched quotes for 5 common needs (MRI, X-ray, blood panel, mammogram, ultrasound). When a new request matches, options appear instantly; anything else lands in intake with an honest "We're on it" screen. This is a stage-one stand-in for the console's quote workflow and gets replaced by Slice 5. The recommended option is always the cheapest clinically-valid one — there is no other input to ranking, and never will be.
How it was verified
- Walked the exact checklist in a phone-sized (375px) window: picked Sarah → typed "I need an MRI of my knee" → options screen showed Gem State Imaging at $0 and the deltas exactly right (+$50.00 Riverline, +$465.00 Cottonwood Imaging, +$1,325.00 hospital outpatient).
- Fallback verified: a migraine request (not in the price book) lands on "We're on it / Just arrived."
- Privacy verified: as Sarah, opening Janet's request URL returns Not Found.
- Zero TypeScript errors, zero browser/server errors. Demo world re-seeded clean afterward.
- Three-auditor review pass (invariants, correctness/privacy, demo fidelity) with adversarial verification. Four confirmed findings, all fixed and re-verified in the browser: 1. (Important) The price-book matcher was too loose — "brain MRI" would have shown knee-MRI options under a confident safety note. Matching is now strict ("knee" + "MRI" must both appear); anything ambiguous falls to the safe "We're on it" path for human research. 2. The emergency screen promised price options that emergencies (correctly) never get — it now says "Get care first. We handle everything after" with bill-forwarding instructions. 3. "Facility fee" jargon now carries its inline explanation ("an extra charge hospitals add just for using their building"). 4. Requests submitted in the evening no longer show tomorrow's date.
- Founder still to do: walk the checklist and say "Slice 1 verified."
What's next
- Slice 2 — Member app: confirm → "your care is handled" → bill upload → history.
July 2, 2026 — Slice 0: Foundation ✅ (awaiting founder verification)
What was built
- Renamed the build brief to
CLAUDE.md(it now loads automatically every session). - Scaffolded the stage-one app: Next.js (App Router) + TypeScript + Tailwind CSS, living in this same folder alongside the earlier price-map collector (untouched).
- Full database schema (
prisma/schema.prisma) — all seven tables from CLAUDE.md Section 8: employers, members, providers, care_requests, options, transactions (the ledger), bill_defense_cases. SQLite database is one local file:data/health-plan.db(copying that file is a complete backup). All money is stored in whole cents so the math is always exact. - Seed script (
npm run seed) — resets the database to a fake Boise demo world: Table Rock Millwork (27 covered lives, level-funded), 15 members (including Sarah Whitfield, the demo protagonist, whose knee-MRI request already has 4 priced options), 27 fictional Treasure Valley providers across every site type, 6 in-flight care requests, 12 completed ledger payments (11 at $0 to the member, 1 pay-the-delta example: Alyssa paid $40 to use the closer ultrasound), and 1 bill-defense case (Pete's inflated ER bill, in negotiation). Providers are deliberately fictional so demos never pin fake prices on real businesses. - Home page with the three areas (
/member,/console,/employer— placeholders that say which slice builds them) and the/dataseeded-data check page.
How it was verified
npm run seedruns clean twice in a row; prints counts.- TypeScript check passes with zero errors; all five pages load with zero console errors.
/datatotals cross-checked by hand: plan paid $2,493.00, members paid $40.00, savings vs. the old way $4,436 — all match the seeded rows exactly.- A four-auditor review pass checked the schema field-by-field against Section 8 (zero findings), the Section 2 invariants, the seed math, and the working agreements. Its two confirmed findings — an unexplained "level-funded" jargon label and one seeded payment timestamped before its care request — were fixed and re-verified.
- Founder still to do: walk the "How you verify" checklist in the browser and say "Slice 0 verified."
Decisions worth remembering
- Money = integer cents in the database, formatted to dollars only on screen (protects Slice 3's money math from rounding errors).
- SQLite can't do enums, so fixed-list fields (statuses, site types…) are text with the allowed values documented in the schema.
npm run devmay pick a port other than 3000 if 3000 is busy — the terminal prints the right address.
Product decision recorded (July 2, 2026) — how "bill fighting" really works
- On routed, prepaid care there are no bills to fight — prevention replaces defense. The only residual is anomaly cleanup (a statement mailed for something already paid → "here's the receipt").
- On the unroutable tail (ER, emergencies, admissions), bill defense = a purchasing desk: gather every bill from the episode (facility, physician group, radiology often bill separately) → audit coding → compare to the % -of-Medicare benchmark → use prompt-pay discounts as the lever → pay fast when the audited number clears the benchmark → dispute specific line items when it doesn't. Fighting is the last step and the minority case.
- Founder's field research: St. Luke's takes 30% off any bill paid in full same-day, including ER. That discount exists for everyone but is only capturable by an instant, liquid payer — i.e., this plan. It also caps tail cost at ~70% of charges at the dominant local system, before auditing. Two follow-up calls pending: does the 30% survive an inpatient admission, and do the separate physician groups have their own prompt-pay policies.
- Build implications: Slice 3's scenario table gets an "unroutable/emergency" row ($0 member, plan pays audited amount). Slice 7 is built as this purchasing desk — "paid promptly at a discount, cleared benchmark" is a first-class outcome, recorded via amount_saved/savings_vs_billed. When real providers are entered (Slices 4–5), the St. Luke's prompt-pay policy is the first real cash_pay_notes entry. No schema changes needed — billed_charge, savings_vs_billed, pct_of_medicare, and multi-case-per-episode bill_defense_cases already support all of it.
What's next
- Slice 1 — Member app: request → options screen (mobile-first, $0 recommended option on top, pay-the-delta alternatives).