Part 3 closes the workbench. Companion to design.html (M1–7), flow.html (M8–10) and flow2.html (M11–14). Here: M15 — Onboarding, M16 — Paywall, M17 — restructure consilium, M18 — post-paywall Setup, M19 — the illustration & hero asset system, M20 — the user-action matrix, and M21 — the Coach engine (RAG × DeepSeek). Best practice borrowed from Folik & Calibrum's onboarding consilia and Cysta AI & Salvora's Coach & Setup patterns.
Hepatica's siblings Folik and Calibrum both locked the same onboarding shape — and both measured +6–11pp trial-to-paid against a plain question funnel. We adopt it as Hepatica's onboarding framework. Seven beats; the WOW is the hinge.
CohortResultView is a text reveal; TrustMethodView is credentials. It collects seven anchors and never cashes one in — the user reaches the paywall having been interrogated, not answered. Module 15 inserts the missing catharsis.
Three ways to shape the pre-auth funnel. The 6 cohorts vote with the standard audience weights. The question: keep the built question funnel, restructure it WOW-then-justify, or strip it to the bone.
| Candidate | Shape | Risk | Verdict |
|---|---|---|---|
| A · Question funnel, as-built | The scaffolded 9-step Swift flow as-is: Welcome → Pain → Triage → Labs → Meds → Goals → Diet → CohortResult (text reveal) → TrustMethod → Paywall. | Collects 7 anchors and never pays one back. CohortResult is a paragraph, not a moment. The paywall arrives cold — nothing earned the trial. This is Folik's measured losing variant. | ✗ Rejected |
| B · WOW-then-justify ⭐ | Pain → Lane → compressed quiz → pre-WOW breath → personalised WOW (future-self dashboard mock) → post-WOW breath → Paywall. The quiz answers render the WOW. | None material — adds one net screen (§15.5). The WOW must stay an honest projection, never a fabricated personal prediction — handled in copy + the disclaimer strip. | ✓ Ships |
| C · Ultra-lean | Pain → Lane select → instant WOW → Paywall. Drop the quiz entirely; the WOW is cohort-generic, not answer-personalised. | Fastest, but the WOW is generic — no labs, no meds, no goal — so it can't show the user's numbers. Loses the anchoring that makes B's WOW land. | ✗ Rejected |
| Cohort | aud % | A · as-built | B · WOW ⭐ | C · ultra-lean |
|---|---|---|---|---|
| 🍷 Nick | 25 | 3 | 5 | 3 |
| 💉 Greta | 15 | 2 | 5 | 3 |
| 🍔 Pete | 20 | 2 | 5 | 2 |
| 💊 Rachel | 8 | 3 | 5 | 1 |
| 🧬 Patricia | 15 | 2 | 5 | 3 |
| 🍺 Robert | 17 | 3 | 5 | 4 |
| Weighted Σ | 100 | 2.50 | 5.00 | 2.81 |
B is unanimous (Σ 5.00) — rare, and it says something. Every cohort arrives carrying a fear — and a question funnel never answers a fear, it only interrogates it. The WOW screen is the first time the app says something back.
Pete (20%) kills A and C hardest: his job is "where do I even start with metabolic syndrome" — he needs to see the HbA1c + ALT dual projection, which only B's answer-personalised WOW can draw. Rachel (8%, highest WTP) kills C outright — a generic WOW can't show her FibroScan staircase or the insurance-PDF preview, and that preview is the single thing that justifies the price to her. Robert half-likes C (=4): his pain is simple — "GGT 240→80, is it real?" — and even a generic curve moves him; but B's curve is his curve, so he still scores B=5. A loses everywhere — it is literally the measured-loser funnel.
B won the structure vote — but WOW-then-justify can be run in 6 screens or 12. Every screen costs drop-off; every anchored screen earns conversion. The 6 cohorts vote on the screen count.
| Candidate | Screens | Trade | Verdict |
|---|---|---|---|
| A · Lean | 6 — Pain · Lane · 1-card quiz · WOW · breath+proof merged · Paywall | Fastest, lowest raw drop-off. But one quiz card can't anchor a rich WOW, and merging the proof into the breath buries it at the commitment moment. | ✗ Rejected |
| B · Balanced ⭐ | 8 onboarding screens + paywall — Welcome · Pain · Lane · compressed Quiz · pre-WOW breath · WOW · post-WOW breath · Proof | Every screen does one job: plant an anchor, deliver the WOW, or earn trust. Matches Folik (8) and Calibrum (6 + WOW). No filler. | ✓ Ships |
| C · Thorough | 12 — the 5 built quiz steps kept separate + everything else | Maximal data capture. But four extra quiz screens add drop-off for zero extra anchor value — the WOW only needs labs + goal + lane. | ✗ Rejected |
| Cohort | aud % | A · lean 6 | B · balanced 8 ⭐ | C · thorough 12 |
|---|---|---|---|---|
| 🍷 Nick | 25 | 4 | 5 | 2 |
| 💉 Greta | 15 | 3 | 5 | 3 |
| 🍔 Pete | 20 | 3 | 5 | 4 |
| 💊 Rachel | 8 | 2 | 5 | 5 |
| 🧬 Patricia | 15 | 3 | 5 | 3 |
| 🍺 Robert | 17 | 4 | 4 | 2 |
| Weighted Σ | 100 | 3.34 | 4.83 | 2.94 |
Lean (A) is tempting — anxious Nick and keep-it-simple Robert both reward it (=4). But cutting the pre-WOW breath removes the trust setup that makes the WOW credible, and merging the proof away wastes the one beat that does the converting. Thorough (C) only Rachel loves (=5, high intent, will answer anything) — every other cohort punishes the four redundant quiz screens. The number is 8: the five built Swift quiz steps must compress to one (§15.7), and nothing else gets cut.
Hepatica launches with zero users. It cannot — and must not — claim a userbase it doesn't have. So where does pre-auth trust come from, and where does it sit? The 6 cohorts vote.
| Candidate | Trust mechanism | Risk | Verdict |
|---|---|---|---|
| A · Method line only | Trust = the "grounded in AASLD / AGA / EASL" line tucked inside the pre-WOW breath. Nothing dedicated. | Too quiet for the commitment decision. The user hits the price having seen the evidence claim for one second, in passing. | ✗ Rejected |
| B · Dedicated proof screen ⭐ | A full screen right before the paywall — one big, honest number about the evidence base: the research and sources Hepatica is built on. | Adds one screen. Must be scrupulously honest — about the research, never a fake userbase (see the copy table below). | ✓ Ships |
| C · Persistent source strip | A small AASLD/AGA/EASL chip strip on every onboarding screen. | Wallpaper. Always present, never noticed — and it competes with each screen's actual job. | ✗ Rejected |
| Cohort | aud % | A · method line | B · proof screen ⭐ | C · source strip |
|---|---|---|---|---|
| 🍷 Nick | 25 | 3 | 5 | 3 |
| 💉 Greta | 15 | 3 | 5 | 3 |
| 🍔 Pete | 20 | 2 | 5 | 3 |
| 💊 Rachel | 8 | 2 | 5 | 3 |
| 🧬 Patricia | 15 | 3 | 5 | 3 |
| 🍺 Robert | 17 | 3 | 5 | 3 |
| Weighted Σ | 100 | 2.72 | 5.00 | 3.00 |
Unanimous (Σ 5.00). Every cohort came with a fear, every cohort is one tap from a price — and a brand-new app has no reviews, no "10M downloads", no testimonials to lean on. What it does have is real: the evidence base. The proof screen makes that the trust anchor, full-screen, right where the conversion decision happens. Robert (=5) in particular — his whole question is "is this real?" — a guideline-grade evidence screen answers it. A (method line) is too quiet; C (strip) is ignored wallpaper.
The founder's instinct is right: a big credibility number near the paywall converts. The trap is what number. Hepatica has no users — so the number is the evidence base, not a userbase. The corpus is a hard fact: DECISIONS.md D12 — 408 source documents → 1,819 research passages (PubMed NAFLD abstracts + AASLD/AGA/ACG/EASL/NICE/WHO guideline PDFs + FDA labels). And those guidelines distil epidemiology of a disease studied across millions of patients. That is the honest, substantiated "wow number".
DECISIONS.md D12 — 400+ sources, 1,800+ passages, the source chips are the real corpus. Apple 2.3.1 wants claims substantiated; these are.sc-disc states plainly: this is the research base, not a user count. It strengthens trust — and removes any rejection surface.| Proof-line candidate | The copy | Apple-safe? |
|---|---|---|
| 1 · Research-base "millions" ⭐ | "Millions of liver patients in the studies your plan is built on." + "400+ AASLD · AGA · EASL & PubMed sources." | ✓ Safe — the number is the research literature, attached to named bodies; substantiated. |
| 2 · Corpus count | "400+ clinical sources. 1,800+ research passages. Every answer drawn from guidelines, never generic advice." | ✓ Safest — hard facts from D12. Less emotionally big, zero risk. Good as the subline. |
| 3 · Guideline-grade seal | A seal: "Guideline-grade" + AASLD · AGA · EASL. "Hepatica only says what the liver guidelines say." | ✓ Safe — authority framing, no number to substantiate. |
| 4 · Userbase claim | "Join millions improving their liver" / "Trusted by millions of users". | ✗ Banned — false (zero users), Apple 2.3.1 rejection, deceptive. Never ship. |
The recommended funnel — 8 screens then the paywall — worked for Recovering Robert, the way §8.3 worked Today. Robert's tone rule governs every word: non-judgmental — never "addiction", never "alcoholic", never "relapse".
COMPLIANCE.md).CohortTriageView.CohortResultView + TrustMethodView collapse into this single breath (§15.7).sc-disc strip is non-negotiable. Never "cured/healed" — "into range", "the view you'll build".Screen 6 is the same shell for everyone — a hero chart, three stats, one CTA — but the chart, the projection and the headline swap to the cohort. Same screen, six future selves. Every chart keeps the grammar: actual solid, projection dashed, guidance band, gold reference line.
The iOS app already scaffolds a 9-step onboarding (OnboardingContainer.swift, steps 0–8). It is a pure question funnel — no WOW. Here is the exact mapping from the 9 built steps to the recommended B flow: what to keep, compress, merge, replace, and add.
| Built Swift step | → B-flow screen | Action | Notes |
|---|---|---|---|
| 0 · WelcomeView | S1 · Welcome | KEEP | Already a single-promise hero — minor copy polish only. |
| 1 · PainHookView | S2 · Pain hook | KEEP | Already the emotional hook — verify the per-cohort pain strings (Robert = GGT 240→80). |
| 2 · CohortTriageView | S3 · Lane select | KEEP | 6 doors + "just exploring" — 1:1 match. Restyle door copy to the user-voice lines in §15.5. |
| 3 · LabsKnownView | S4 · Quiz card 1 | COMPRESS | First card of the merged quiz scroll. Add the optional inline value field. |
| 4 · MedicationsQuizView | S4 · Quiz (conditional) | MERGE | Folded into the scroll, shown only when the cohort needs it — skipped for Robert. Still feeds CohortDetector. |
| 5 · GoalsView | S4 · Quiz card 3 | COMPRESS | Becomes the "goal in one line" card. |
| 6 · DietPrefView | S4 · Quiz (conditional) | MERGE | Folded in, cohort-conditional — Nick/Pete/Greta see it, Robert can skip. |
| 7 · CohortResultView | S5 · pre-WOW breath | REPLACE | The text reveal is demoted — its resolveCohort() / CohortDetector logic is kept and now picks which WOW chart renders. The paragraph becomes the breath. |
| 8 · TrustMethodView | S5 breath + S8 Proof | SPLIT | The AASLD/AGA/EASL method line moves into the pre-WOW breath; the full evidence content is elevated into the new Proof screen near the paywall (§15.4a). |
| — (not built) | S6 · WOW screen | ADD | The personalised future-self chart — the one screen the Swift build is missing entirely. |
| — (not built) | S7 · post-WOW breath | ADD | "Your plan is ready" confirmation beat. |
| — (not built) | S8 · Proof screen | ADD | The honest evidence-base badge (§15.4a) — partly from TrustMethod's content, elevated to a full screen at the commitment moment. |
CohortDetector and OnboardingAnswers are untouched — the resolved cohort now selects the WOW chart instead of selecting a paragraph; OnboardingState gains wow / wowConfirm / proof steps and loses the standalone cohortResult / trustMethod cases. The WOW chart is the same SwiftUI chart component as the Progress hero (§11.2) — built once, shown in onboarding as a projection and post-purchase as the live Progress tab.
DECISIONS.md D12; §15.7 mapped the 9 built Swift steps → 8 B-flow screens. Compliance: pre-auth throughout (no email / Sign in with Apple before the paywall), every WOW chart an honest dashed projection, no diagnosis, no "cured", no fabricated userbase claim. To compliance sign-off: the proof-screen copy, the WOW headlines, the pain-hook lines. Next — Module 16 · Paywall.
The founder asked for a Cysta-style "You're in good company" user-reviews screen in onboarding. But Cysta's locked design ships no reviews screen — it deliberately avoids social proof "until 25+ real reviews exist". Hepatica launches with 0 users / 0 reviews — a reviews screen pre-launch is fabricated social proof and a flat Apple 2.3.1 rejection. §15.9 resolves it honestly: the screen is designed now as a real artefact, but ships hidden and switches itself on only once enough real App Store reviews exist. Until then, §15.4a's evidence-base proof screen carries the social-proof beat alone.
com.love8ko.hepatica in the user's storefront — Cysta's threshold. Below that it is skipped entirely; the funnel runs §15.4a Proof → Paywall with no gap. Every card is a verbatim, attributed real App Store review pulled from App Store Connect — never written, never composited, never reordered to mislead. First names only, no avatars, no fabricated counts; the rating number is the live App Store aggregate. The screen is feature-flagged off at launch and turned on by config once the threshold is met — no app update needed.
Module 15 hands the paywall one rule — the headline must echo the WOW the user just saw. The consilium tests it: one fixed paywall, a cohort-routed fear-playbook, or a hard high-pressure variant? The 6 cohorts vote.
| Candidate | Shape | Risk | Verdict |
|---|---|---|---|
| A · One static paywall | A single screen, identical for all 6 cohorts — a generic H1 ("Reverse fatty liver — a plan that fits you"), one fixed bullet set, one default tier. The as-built PaywallView. | Breaks the M15 hand-off — the WOW just showed Robert his GGT curve, then the paywall says nothing about it. The funnel's anchor goes uncashed at the commitment moment. | ✗ Rejected |
| B · Cohort-routed fear-playbook ⭐ | One scaffold; the H1 swaps per cohort to echo that cohort's WOW, the 4 value bullets swap to what the cohort cares about, the proof band is constant. Tiers, prices, layout identical for all six. | Six H1 strings + six bullet sets to keep compliant — handled in §16.3, all to sign-off. No fabricated claims — the H1 echoes a projection the user already saw. | ✓ Ships |
| C · Hard aggressive | Countdown timer, "discount expiring", loss-framed H1 ("Your liver won't wait"), pre-checked priciest tier, dismissal friction ("Are you sure?"). | Fear-mongering on a health app — Apple 4.5.4 / 3.1.2 scrutiny; corrodes the "Clinical Authority" brand; punishes anxious Nick and burned-by-judgment Robert. Refund-prone. | ✗ Rejected |
| Cohort | aud % | A · static | B · routed ⭐ | C · aggressive |
|---|---|---|---|---|
| 🍷 Nick | 25 | 3 | 5 | 1 |
| 💉 Greta | 15 | 3 | 5 | 2 |
| 🍔 Pete | 20 | 2 | 5 | 2 |
| 💊 Rachel | 8 | 3 | 5 | 1 |
| 🧬 Patricia | 15 | 2 | 5 | 1 |
| 🍺 Robert | 17 | 2 | 5 | 1 |
| Weighted Σ | 100 | 2.48 | 5.00 | 1.35 |
B is unanimous (Σ 5.00). The paywall is one screen from a price, and M15 spent eight screens planting a cohort-specific anchor — a static paywall (A) lets that anchor die unspent. Robert kills A hardest: his WOW was his GGT 240→80 curve; a generic H1 makes the eight screens feel like a bait-and-switch. C is rejected with prejudice (Σ 1.35) — a countdown clock on a liver-disease app reads as predatory; Nick (anxious, 25%) and Robert (burned by judgmental apps, 17%) score it 1, and it threatens the whole "Clinical Authority" brand the design system locks. B keeps the proven Loveiko paywall layout and swaps only the words that echo the WOW.
PaywallView preselects the cohort default tier (Family / Lifetime / Standard). For this design the paywall preselects Weekly $4.99/wk for every cohort — lowest sticker, habit-lock entry — with the other three tiers visible and one tap away. Weekly carries a 7-day free trial (consistent with the built "7-DAY TRIAL" badge and M15's "Start my 7-day trial" hand-off; resolves the CLAUDE.md "weekly no trial" line in favour of the trial). The fear-playbook routes the copy, never the price — every cohort sees the same four tiers at the same prices.
The single scrollable paywall, B-variant, worked for Recovering Robert — his WOW was GGT 240→80 into range; the H1 continues that sentence. Non-judgmental throughout — never "addiction", "alcoholic", "relapse".
One scaffold, six fear-playbooks. The H1 echoes each cohort's WOW; the three lead value bullets swap to what that cohort cares about; the proof band, the four tier cards with Weekly preselected, the prices and the layout are constant.
PaywallView.swift already renders all four tiers, the shimmer CTA, the badges, the footer links and the fine print in the Clinical palette. Three pure-UI changes bring it to the B design; RevenueCat wiring is the fourth.
| Element | Built PaywallView does | B design needs | Action |
|---|---|---|---|
| Tier preselect | defaultTier → greta/patricia = family, rachel = lifetime, else standard. | Weekly preselected for every cohort (founder override). | CHANGE |
| Headline | One hardcoded H1 — "Reverse fatty liver — a plan that fits you". | Per-cohort H1 echoing the WOW — the 6 strings in §16.3. | ADD |
| Value bullets | 4 fixed bullet rows, identical for all. | First 3 bullets swap per cohort; the 4th ("Doctor PDF") constant. | ADD |
| Proof band | None. | One-line "Built on 400+ AASLD/AGA/EASL & PubMed sources" above the tier stack. | ADD |
| Tiers · badges · shimmer · footer | 4 tier tiles, gold/teal/deep badges, shimmer CTA, Restore/Terms/Privacy, fine print. | Unchanged. | KEEP |
| CTA + then-line | Switch on selectedTier; weekly already "Start 7-day free trial" / "Free for 7 days, then $4.99/wk". | Same — with Weekly preselected the trial CTA shows by default. | KEEP |
| Purchase | Placeholder — purchase() sets isPro = true, no SDK. | Real RevenueCat purchase. | WIRE |
hepatica.weekly / hepatica.yearly / hepatica.family.yearly / hepatica.lifetime, entitlement premium. The build replaces the placeholder purchase() with a Purchases.shared.purchase(package:) call mapping selectedTier → RC package, sets isPro from the premium entitlement on success, and wires Restore to restorePurchases(). Tier prices should read from the RC Offering rather than hardcoded strings, so a price change needs no app update. The three UI changes above (Weekly preselect · per-cohort H1 · proof band) are pure SwiftUI and land independently of the SDK work.
PaywallView.swift → the B design: three pure-UI changes (preselect Weekly · per-cohort H1 · proof band) plus the RevenueCat wiring of the placeholder purchase. Compliance: Health & Fitness disclaimer on the paywall, no diagnosis, no fake reviews or userbase, light-mode forced, hero image deferred. To compliance sign-off: the 6 paywall H1s, the 6 bullet sets, the §15.9 reviews-screen activation rule. The pre-auth funnel — Modules 15 + 16 — is complete. Continues below — M17 is a fresh-eyes restructure pass over the whole flow, M18 designs the post-paywall Setup walkthrough, and M19 settles the illustration style; the workbench now covers Modules 1–19.
Seven findings from reading M1–18 end to end. Most are drift — a later module made an earlier one stale — and were fixed in place this pass. Two are workbench↔code gaps where the built Swift app and the workbench disagree; those become Swift V1 rework items. One is a real gap — a sequence the workbench never drew — filled by M18.
| Area | What the fresh-eyes pass found | Type | Resolution |
|---|---|---|---|
| flow.html §8.1 · flow2.html §14.1 — flow maps | Onboarding & Paywall still drawn as dashed "TODO · own consilium" gates, lede "deliberately not designed yet" — but M15 & M16 designed them. | drift | Both flow maps rebuilt — Onboarding→M15, Paywall→M16, a Setup→M18 stage added, Disclaimer marked post-paywall. Fixed. |
flow.html §8.2 — Disclaimer vs built DisclaimerView.swift | The workbench mockup shows four info points + one "Continue" button. The built screen has "what Hepatica DOES / DOES NOT" blocks and two mandatory consent checkboxes — educational-use + AI-processing consent. | wb ↔ code | §18.2 redraws the Disclaimer reconciled — the AI-consent checkbox is compliance-required (Coach sends labs & messages to DeepSeek). §8.2 stands as the calm-framing reference. |
RootTabView.swift — tab order | The built bar is Today · Labs · +Log · Coach · Progress — the pre-re-evaluation order. The workbench locked Today · Coach · +Log · Progress · Labs at §4.3 (Coach promoted, Labs to the calm edge). | wb ↔ code | §17.2 re-confirms the workbench order by a 6-cohort vote; RootTabView is a Swift V1 rework item. |
| flow2.html §14.4 — open questions | Listed "Onboarding & Paywall — still dashed TODO gates" as the next workbench set — stale once M15/M16 shipped. | drift | Replaced with the live open item — Swift reconciliation (tab order, the no-WOW onboarding, the paywall preselect). Fixed. |
| flow3.html — Module 15 banner | Section cross-references off by two — "§15.3 works the flow… §15.5 reconciles" where the real sections are §15.5 / §15.6 / §15.7. | drift | Banner cross-refs corrected. Fixed. |
| flow2.html §14.2 — cross-tab gaps | Coach & Progress empty states, the Log alcohol safety strip, and the Coach verdict-pill decision — flagged honestly, still not drawn. | carried | Not closed in this pass — they are real screens, not drift. Carried to the Swift V1 build as tracked TODOs; recommend a small follow-up workbench pass. |
| Post-paywall sequence | RootRouter gates Paywall → Disclaimer → Setup (5 cards) → Tabs. The 5-card Setup walkthrough existed only in Swift — the workbench never designed it. | gap | M18 designs the post-paywall Setup walkthrough — consilium, the Disclaimer reconciled, the 5 cards worked, all 6 cohorts. Fixed. |
The one place the workbench and the built Swift app openly disagree. RootTabView.swift was written before §4.3 re-evaluated the bar by interaction frequency. Two orders, the 6 cohorts vote — the winner is the canonical order both the workbench and the Swift V1 rework adopt.
| Candidate | Order (left → right · centre FAB) | Rationale |
|---|---|---|
| A · built-Swift | Today · Labs · +Log · Coach · Progress | The order RootTabView.swift ships today — Labs second. Pre-dates the §4.3 frequency re-evaluation. |
| B · workbench ⭐ | Today · Coach · +Log · Progress · Labs | §4.3's re-evaluated order — Coach is a near-daily surface (incl. the 2 a.m. anxiety check) so it sits at slot 2; Labs is consulted ~quarterly so it moves to the calm outer edge. |
| Cohort | aud % | A · built | B · workbench ⭐ |
|---|---|---|---|
| 🍷 Nick | 25 | 3 | 5 |
| 💉 Greta | 15 | 3 | 5 |
| 🍔 Pete | 20 | 3 | 5 |
| 💊 Rachel | 8 | 4 | 5 |
| 🧬 Patricia | 15 | 3 | 5 |
| 🍺 Robert | 17 | 2 | 5 |
| Weighted Σ | 100 | 2.91 | 5.00 |
B is unanimous (Σ 5.00). Every cohort opens Coach far more often than Labs — Coach is the daily question surface, Labs is where a new panel lands once a quarter. Robert scores A=2: putting Labs at slot 2 buries the two surfaces he lives in — his Coach ("is it healing?") and his Progress recovery curve. Rachel is softest on A (=4) — she is the most Labs-heavy cohort, so Labs near the front costs her least — but even she prefers B. The vote settles it: the canonical order is Today · Coach · +Log · Progress · Labs; RootTabView.swift is re-ordered to match in the Swift V1 rework.
RootTabView re-order, the Disclaimer's two consent checkboxes (§18.2), the no-WOW onboarding (§15.7), the paywall tier preselect (§16.4). Carried as a follow-up workbench pass: the §14.2 cross-tab gaps — Coach & Progress empty states, the Log safety strip, the Coach verdict-pill decision. Logged in DECISIONS.md D20.
The post-paywall Setup is the bridge between "I paid" and "I have a habit". Cysta AI runs five cards; the built Swift app runs a different five. Three card-sets, the 6 cohorts vote with the standard audience weights.
| Candidate | The five cards | Risk | Verdict |
|---|---|---|---|
| A · built-Swift, as-is | Welcome → Tabs tour → Log first labs → Personalize → Ready. | "Tabs tour" is a generic feature tour with no cohort anchor. "Personalize" re-asks what the M15 lane-select already established. "Log first labs" as its own card pressures a day-1 action many users can't do yet — and a fail there sours the whole setup. | ✗ Rejected |
| B · Cysta semantics, literal | Welcome → Focus → Baseline → Daily 90s plan → Ready. | Faithful to Cysta's proven funnel and every card carries a cohort anchor — but Baseline is display-only, dropping the built app's genuinely useful "scan your first lab now" capture. | ✗ Rejected |
| C · Merge ⭐ | Welcome → Focus → Baseline (+ optional on-the-spot lab scan) → Daily 90s plan → Ready. | None material. Keeps Cysta's anchored funnel, folds the built "log first labs" into Baseline as an optional scan, and drops "Personalize" as redundant — the cohort is already set in onboarding (M15). | ✓ Ships |
| Cohort | aud % | A · as-built | B · Cysta | C · merge ⭐ |
|---|---|---|---|---|
| 🍷 Nick | 25 | 3 | 4 | 5 |
| 💉 Greta | 15 | 2 | 4 | 5 |
| 🍔 Pete | 20 | 3 | 4 | 5 |
| 💊 Rachel | 8 | 3 | 4 | 5 |
| 🧬 Patricia | 15 | 2 | 4 | 5 |
| 🍺 Robert | 17 | 3 | 4 | 5 |
| Weighted Σ | 100 | 2.70 | 4.00 | 5.00 |
C is unanimous (Σ 5.00). The cohorts reject A because two of its five cards waste the user's attention: a generic tab tour teaches nothing the cohort cares about, and "Personalize" asks a question already answered three screens earlier. Greta & Patricia score A=2 hardest — their setup needs to feel like the app already knows them (GLP-1, PCOS), and a generic tour signals it doesn't. B fixes the anchoring but leaves the lab-capture on the table; C keeps it as an optional Baseline action — there if the user has a report to hand, never a blocker if not.
setup-welcome · setup-focus · setup-baseline · setup-plan · setup-ready (§ASSET_PROMPTS).
The first post-paywall screen. flow.html §8.2 drew it as a calm four-point info screen with one Continue button — but the built DisclaimerView.swift carries two mandatory consent checkboxes: educational-use and AI-processing. The AI checkbox is not optional polish — the Coach sends labs and messages to DeepSeek, so explicit consent is a compliance requirement. §18.2 reconciles the two: §8.2's calm framing, the built screen's consent gate.
DisclaimerView.swift.--cta-deep, not an alert tone. Diagnosis, staging and doctor-replacement are explicitly disclaimed.disclaimerAcceptedAt / aiConsent.COMPLIANCE.md. Supersedes the §8.2 single-button mockup; §8.2 stays the reference for the calm-framing tone. Copy to founder + compliance sign-off.The 5-card C-variant walkthrough, worked for Newly Diagnosed Nick (25% — the mass cohort). Each card is a single job: a 5-pill progress capsule, a 1:1 illustration zone (asset deferred), one idea, one button. Skippable throughout.
One 5-card spine, six fittings. The Baseline card is the most cohort-distinct — shown here for all six. Its three day-1 entries swap to what that cohort tracks; the Focus surfaces and the Ready send-off swap with it.
The Swift app already has a SetupContainer + SetupState and five screen files — but candidate A's five, not C's. Bringing it to the C design is two renames, one merge, one drop, two new screens.
| Element | Built Swift Setup does | C design needs | Action |
|---|---|---|---|
| SetupContainer / SetupState | 5-step container, 5-pill progress, Back + Skip, slide transitions, finish() → setupComplete. | Same container — the step list changes to Welcome / Focus / Baseline / Daily-plan / Ready. | KEEP |
| SetupWelcomeView · SetupReadyView | Welcome card + "you're all set" card. | Kept — polish copy; Ready gets a per-cohort send-off line + entry tab. | KEEP |
| SetupTabsTourView | Generic 4-tab feature tour. | Becomes SetupFocusView — the cohort's top-3 surfaces. | CHANGE |
| SetupLabEntryOfferView | Standalone "log your first labs" card. | Folded into Baseline as an optional "scan a lab report" row — no longer its own step. | MERGE |
| SetupCohortSetupView | "Personalize to your situation." | Dropped — the cohort is already set at M15 lane-select; re-asking is the rejected candidate A. | REMOVE |
| SetupBaselineView (new) | — | 3 cohort-specific day-1 entries, all skippable, + the optional lab-scan shortcut. | ADD |
| SetupDailyPlanView (new) | — | The Today→+Log→Coach loop card, "90 seconds a day". | ADD |
| Baseline data | — | Entries persist to onboardingAnswersJSON + the lab store, so Today opens populated. | WIRE |
DisclaimerView → SetupContainer → RootTabView behind disclaimerAcceptedAt / setupComplete — the chain is correct and stays. The §18.2 reconcile is copy-only on DisclaimerView (the two consent checkboxes already exist there). The Setup work is the five screens above; the cohort is read from cohortRaw, never re-asked. All Setup screens force light mode and reuse the shared ContinueButton / HeroImage components.
DisclaimerView (educational-use + AI-processing consent). §18.3 worked all 5 cards for Nick; §18.4 fitted Baseline + Focus + Ready to all 6 cohorts. §18.5 mapped the built Swift Setup → the C design: keep the container, rename TabsTour→Focus, merge LabEntryOffer into Baseline, drop CohortSetup, add Baseline + DailyPlan. Compliance: Health & Fitness throughout, two explicit consent checks, no diagnosis, light-mode forced, hero images deferred to the asset sprint. To compliance sign-off: the Disclaimer copy, the Setup card copy. With M17 + M18 the workbench covers Modules 1–18 — the whole flow, pre-launch through the first daily loop. M19 below settles the in-app illustration style.
Two locked documents already point the way. DESIGN_SYSTEM.md names the aesthetic «Mayo Clinic × Headspace» and its onboarding rule says «Illustrations only до disclaimer-accept» — the visuals were always conceived as illustration. And design.html §7.3 locks an anti-pattern: «no glowing livers, no detox juices — the category is clinical authority, not wellness». Editorial apothecary still-life (dried botanicals, herbal tea, linen) is exactly the wellness register that anti-pattern rejects. Three directions, the 6 cohorts vote.
| Candidate | Shape | Risk | Verdict |
|---|---|---|---|
| A · Editorial photography | The first-draft style — editorial product photography, apothecary still-life, dried liver botanicals, linen, no faces. Sibling Cysta / Folik / Salvora DNA, re-palettised teal/gold. | It is the wellness register §7.3 explicitly rejects; reads precious / lifestyle-boutique to the older, male-skewing NAFLD cohorts; mismatched to the «Headspace» half of the locked design system. | ✗ Rejected |
| B · Calm clinical illustration ⭐ | Soft semi-flat vector illustration — gentle gradients + paper grain, warm rounded forms, generous negative space, abstract metaphors (a line easing into a band, a path, a calm horizon); the liver only as the brand's abstract teal→gold lobe. | None material. Must be rich craft-illustration (Headspace-grade depth & texture), never cheap flat clip-art — handled in §19.2's style DNA. | ✓ Ships |
| C · Hybrid | Illustration as the base system, plus a few photographic heroes on the highest-stakes screens (paywall, proof). | Re-imports the wellness/photography problem exactly on the paywall, where it costs most; two vocabularies for a solo founder to keep coherent. | ✗ Rejected |
| Cohort | aud % | A · photo | B · illustration ⭐ | C · hybrid |
|---|---|---|---|---|
| 🍷 Nick | 25 | 3 | 5 | 4 |
| 💉 Greta | 15 | 4 | 4 | 5 |
| 🍔 Pete | 20 | 2 | 5 | 4 |
| 💊 Rachel | 8 | 2 | 4 | 5 |
| 🧬 Patricia | 15 | 4 | 5 | 4 |
| 🍺 Robert | 17 | 2 | 5 | 4 |
| Weighted Σ | 100 | 2.85 | 4.77 | 4.23 |
B wins clearly (Σ 4.77). It is not a new idea — it is what DESIGN_SYSTEM.md already specifies («Mayo Clinic × Headspace», «illustrations only до disclaimer-accept»). Pete (20%) and Rachel (8%) kill A hardest (=2): a practical pre-diabetic man and a $40K-drug MASH patient read apothecary still-life as lifestyle fluff, not clinical authority. Robert (17%) scores B=5 — Headspace's calm illustration is the visual language of recovery apps; it lowers health anxiety where a precious photograph cannot. Greta & Patricia (the wellness-leaning cohorts) are the only ones who warm to A — and even they prefer B or C. C is rejected not on taste but on incoherence: a photographic paywall hero drops the user back into the wellness register at the exact moment authority matters most, and two vocabularies are a consistency tax a solo founder shouldn't pay. Runoff note: B only wins if it is executed as rich illustration — Headspace-grade craft, depth, gradient, texture — never flat clip-art. The earlier photography pick (D22) is superseded; logged D23.
One coherent illustration language across every generated asset — onboarding heroes, paywall heroes, the Setup cards, empty states and icons. The detailed per-asset prompts live in private/ASSET_PROMPTS.md; this is the system it is built on.
| Dimension | The B system |
|---|---|
| Register | Calm clinical illustration — «Mayo Clinic × Headspace»: clinical clarity meets Headspace calm. Reassuring, never anxious; authoritative, never cold. |
| Render | Soft semi-flat vector — gentle gradients, subtle paper-grain texture, soft diffused light, warm rounded organic forms, generous negative space, no harsh outlines. Rich craft-illustration, not flat clip-art, not 3D, not photoreal. |
| Palette | The locked tokens only — teal #2D7B7E + warm gold #D4A574 + off-white #EEF3F2; warm severity (amber → clay) used sparingly. No clinical red, no neon. |
| Subjects | Abstract calm metaphors — a line easing into a guidance band, a path of stepping stones, a low calm horizon at sunrise, concentric rings, a single unfurling leaf, a tide going out. The liver appears only as the brand's abstract teal→gold lobe glyph — never anatomical, never a literal organ. |
| Carry-over rules | No faces / no people; no liver-anatomy close-ups (locked anti-pattern); no clinical red; zero alcohol imagery anywhere (Robert hard rule + veto); no cute mascots or organs-with-eyes. |
| Inventory | 23 imagesets — Sprint B (7 onboarding heroes, 3:4) · Sprint C (6 paywall heroes 3:4 + 5 Setup cards 1:1) · Sprint E (5 empty-state / icon, 1:1). Slugs, screens and aspect ratios unchanged from the first draft. |
| Aspect matrix | 3:4 — full-screen heroes (onboarding + paywall, contained) & pdf-cover. 1:1 — Setup cards, empty states, icons. 9:16 not used in V1. |
private/ASSET_PROMPTS.md (gitignored, founder-only) is rewritten to this system: a calm-illustration master skeleton, all 23 per-asset concepts re-imagined as illustration metaphors, the 7-point WOW QA gate, and a 6-cohort weighted Σ≥7.5 lock per asset. Hero images are generated in a later visual-assets sprint; the workbench mockups (M15/M16/M18) keep the dashed placeholder zones until then. The shared Swift HeroImage component renders each asset with a Color.hepBrandSoft fallback until its PNG lands.
private/ASSET_PROMPTS.md is rewritten to match (23 assets, illustration prompts). Supersedes D22 — logged DECISIONS.md D23. The workbench now covers Modules 1–19; the whole product is designed end to end — flow, funnel, post-paywall, and the visual system.
Every user action down the side; every state across the top. ✓ designed · ⚠ gap to close in §20.2 · — not applicable. The Light/Dark column tracks whether the surface has been contrast-audited in both appearances — dark mode was deferred to the Swift build, so the core tabs read ⚠ until audited.
| User action | Happy | Empty | Error | Offline | Edge | Light/Dark |
|---|---|---|---|---|---|---|
| PRE-AUTH FUNNEL | ||||||
| Cold launch / resume | ✓ | ✓ | ✓ | ✓ | — | ✓ |
| Onboarding triage / WOW | ✓ | — | ✓ | ✓ | ✓ | ✓ |
| Paywall — view & purchase | ✓ | — | ⚠ | ⚠ | ✓ | ✓ |
| Paywall — back / skip | ✓ | — | — | — | ⚠ | ✓ |
| Disclaimer · Setup walkthrough | ✓ | — | ✓ | ✓ | ✓ | ✓ |
| TODAY | ||||||
| Open Today / cohort dashboard | ✓ | ✓ | ✓ | ✓ | ✓ | ⚠ |
| Toggle light/dark theme | ⚠ | — | — | — | — | ⚠ |
| +LOG (5 MINI-FLOWS) | ||||||
| Log meal photo | ✓ | — | ⚠ | ✓ | ⚠ | ⚠ |
| Log drink / sober day | ✓ | — | ✓ | ✓ | ⚠ | ⚠ |
| Log lab / medication / symptom | ✓ | — | ⚠ | ✓ | ⚠ | ⚠ |
| COACH | ||||||
| Ask the Coach | ✓ | ⚠ | ✓ | ⚠ | ✓ | ✓ |
| Follow-up · switch view · export PDF | ✓ | — | ✓ | ✓ | ✓ | ✓ |
| LABS · PROGRESS · SETTINGS | ||||||
| Scan lab → OCR confirm | ✓ | ✓ | ⚠ | ✓ | ✓ | ⚠ |
| View analyte grid / trends | ✓ | ⚠ | ✓ | ✓ | ✓ | ⚠ |
| Milestone · doctor PDF export | ✓ | — | ✓ | ✓ | ✓ | ✓ |
| Switch cohort · customise Today | ✓ | — | ✓ | ✓ | ✓ | ⚠ |
| Restore / manage subscription | ✓ | — | ⚠ | ⚠ | ✓ | ✓ |
The nine gaps, resolved. The two empty states are drawn (the §8.6 ghost-skeleton pattern); the rest are decisions + rules the Swift build inherits.
#if DEBUG + TestFlight check as §20.3, stripped from App Store builds. The four tiers, prices and Weekly-preselect (M16) are unchanged.
--night-* tokens (already in DESIGN_SYSTEM.md) define both modes; every screen is checked in both before merge. A light/dark toggle sits on the Today tab, writing a theme @AppStorage override (System / Light / Dark). Coach keeps its 22:00–06:00 night-auto. The workbench's own M9 Coach chat mockups were re-checked — bubbles use var(--ink) on tinted backgrounds, no white-on-white.
API_REGISTRY.md), never a spinner that hangs. Failed capture / OCR — meal, lab and OCR failures show a retry + a manual-entry path, never a dead end. Purchase / restore failure — a plain inline error + retry, the paywall stays usable. Undo a log — every +Log capture shows an undo on its confirmation toast (a mis-logged drink or meal is reversible). Log safety strip — the drink log carries the COMPLIANCE.md alcohol-support line ("for alcohol-use-disorder support, talk to a professional"). Coach verdict stays prose, not a triad pill — confirmed deliberate (a chat answer is not a lab row).
A coverage matrix is only honest if a tester can actually reach every cell. The standard tool — already scaffolded in the Swift app — is an in-app floating debug overlay with a jump-to teleporter.
@AppStorage keys; (b) presets — Day-0 (wipe) and Day-30 (seed a power-user with mock labs/streaks); (c) manual flag toggles. Buttons grouped by phase. The built DebugFloatingButton + DebugPanelView + DemoSeed already implement this.
#if DEBUG OR the app is a TestFlight build — detected by the sandbox App Store receipt (appStoreReceiptURL path ends sandboxReceipt), the check already in Utils/BundleDebugFlags.swift. Result: the panel is live for the founder in Xcode and for TestFlight testers on-device, and is compiled out of the public App Store release. Locked as the Loveiko standard — any new project wires it from this section in ~30 minutes.
The Coach is not invented here. Cysta AI and Salvora shipped a cited, RAG-grounded chat; Hepatica copies the five components and re-points them at the liver corpus and the 6 cohorts.
| Component | Copied from | What changes for Hepatica |
|---|---|---|
| RAGService | Cysta Services/RAGService.swift | Loads liver_knowledge.sqlite instead of pcos_knowledge.sqlite; identical in-memory cosine retrieval. |
| CoachService | Cysta Services/CoachService.swift | Liver intent-classifier triggers (jaundice, withdrawal, Rezdiffra dosing); same retrieve → prompt → DeepSeek path. |
| PromptLibrary | Cysta + Salvora Services/PromptLibrary.swift | Liver-coach base prompt; 6 Hepatica cohorts; the 3 specialist views (M9); liver compliance rules. |
| CoachThreadStore | Salvora Core/Stores/ChatThreadStore.swift | Per-thread cohort snapshot (Salvora snapshots persona); UserDefaults-JSON threads. |
| Coach UI | Cysta Features/Coach/* | ChatThreadDetailView · MessageBubble · SourceBlock · CoachFollowupParser — re-themed Clinical; the M9 specialist-view panel. |
Services/API.swift + APIClient.swift route to the deployed Worker hepatica-api.veribag.workers.dev (/deepseek, /openai). liver_knowledge.sqlite is built and sits in Hepatica/Hepatica/Resources/. The build only adds the five Swift components above — no new infrastructure.
The on-device knowledge base — how it ships, how it loads, how a query finds its sources. No sqlite-vec extension: retrieval is pure-Swift cosine over an in-memory cache.
| Stage | What happens |
|---|---|
| Ship | liver_knowledge.sqlite (~7.6 MB — meta / sources / chunks; each chunk a 512-float embedding as a BLOB) is bundled in Resources/ — add it to the bundle target in project.yml. Built by the scripts/rag/ pipeline from AASLD · AGA · EASL · FDA · PubMed (per RAG.md). |
| Load | At app launch RAGService.shared opens the DB, reads every chunk + source into memory (~3–8 MB resident), then closes the file. All later queries hit the in-memory cache. DB missing/corrupt → silent graceful degrade (RAG returns empty). |
| Embed the query | The user's question is embedded via the Worker /openai route — text-embedding-3-small @ 512 dimensions (same model + dims the corpus was built with). An LRU cache (≤100 entries) avoids re-embedding repeats. |
| Retrieve | Brute-force cosine similarity of the query vector against every cached chunk; sort; take top-K (K≈5). Dimension mismatch (≠512) → return empty, never crash. |
| Hand off | The top-K chunks + their source citations are passed to PromptLibrary for the system-prompt RAG block. Zero hits → the no-RAG-hit honest hedge (§21.4). |
What happens between the user tapping send and the answer appearing. Seven steps; the intent classifier and the no-hit hedge are the compliance guards.
/deepseek — deepseek-chat, temp 0.4, max 1200, non-streaming, 30s timeout.[cN] citations and the [follow_ups] block → CoachAnswer → render.The system prompt is assembled from blocks. The base role + compliance rules are constant; the specialist view and the cohort tone swap per thread; the RAG block swaps per query.
| Block | Content |
|---|---|
| Base role | "An educational liver-health coach grounded in AASLD / AGA / EASL / Mayo / PubMed. Not a physician — does not diagnose, prescribe or stage." |
| Compliance rules | From COMPLIANCE.md — no diagnosis ("consistent with", never "you have NAFLD"); no "cure / reverse" as a cure claim; no FibroScan/FIB-4 staging; no medication dosing; Rezdiffra disclaimer; alcohol framed as recovery, never judgment; every answer cites or pivots. |
| 3 specialist views | 🫀 Hepatology (AASLD · EASL · Mayo — enzymes, fibrosis, diet) · 🍺 Recovery (NIAAA · AGA — alcohol, recovery timelines, non-judgmental) · ⚖️ Metabolic (ADA · Endocrine Society — glucose, weight, GLP-1, PCOS). A view is a guideline perspective, never a named person. |
| Cohort → default view | 🍷 Nick → Hepatology · 💉 Greta → Metabolic · 🍔 Pete → Metabolic · 💊 Rachel → Hepatology · 🧬 Patricia → Metabolic · 🍺 Robert → Recovery. The answer leads with that view; the other two collapse into "+ 2 more views" (M9 v2). |
| Cohort tone | 6 tones (M9 v3) — Nick empathetic-educator · Greta progress-focused · Pete triage-guide · Rachel clinical-partner · Patricia hormonal-systems · Robert non-judgmental-recovery. |
| Escalation triggers | Jaundice · vomiting blood · severe abdominal pain · alcohol-withdrawal symptoms · suicidal ideation → an immediate "seek urgent care / 988" pivot, ahead of any RAG answer. |
| Response shape | Verdict-first (M9 v2) — a plain bold answer, then the cited reasoning, then a calm disclaimer. Inline [cN] citation markers; a closing [follow_ups] block of ≤2 next questions. |
| No-RAG-hit hedge | Zero chunks retrieved → the prompt instructs an explicit hedge ("I don't have a specific reference for this — here's general guidance, confirm with your doctor"). Never fabricate a citation. |
M9 designed the screen; the built app has a CoachView stub. The UI is copied from Cysta's Coach feature and re-themed Clinical.
| Element | Built today | The build | Action |
|---|---|---|---|
| CoachView | Tabs/CoachView.swift — a StubScreen. | Thread list → ChatThreadDetailView (scroll + composer), the M9 specialist-view panel. | BUILD |
| MessageBubble | — | User right / assistant left + safety strip + SourceBlock + follow-up chips. Renders **bold** / *italic* via AttributedString(markdown:) and strips inline [cN] markers — so asterisks become bold, never literal text. | BUILD |
| SourceBlock | — | Collapsible "N sources" chip → numbered citation cards, tap → in-app browser. | BUILD |
| API routes | API.swift — /deepseek + /openai defined & reachable. | Unchanged — CoachService / RAGService call them. | KEEP |
| Corpus | liver_knowledge.sqlite in Resources/. | Add to the project.yml bundle target so it ships in the app. | WIRE |
**bold**) and inline [c1] citation markers. Rendered verbatim, the asterisks show as literal characters — the "system error" the founder flagged. The fix is the Cysta MessageBubble pattern, copied as-is: convert the text with AttributedString(markdown: .inlineOnlyPreservingWhitespace) so **…** renders bold and *…* italic, and regex-strip the [cN] markers from the body (the citations render in SourceBlock instead). Locked into the M21 build spec.
RAGService, CoachService, PromptLibrary, CoachThreadStore, the Coach UI — re-pointed at liver_knowledge.sqlite and the 6 cohorts. §21.2 documents how the RAG ships, loads and retrieves (in-memory cosine, 512-d, top-K); §21.3 the 7-step pipeline with the client-side intent classifier; §21.4 the prompt library — 3 specialist views, 6 cohort tones, the compliance rules, the no-hit hedge; §21.5 the Coach UI + the Markdown-rendering fix for the asterisks bug. With M20 + M21 the workbench covers Modules 1–21 — the product is designed end to end. The Swift V1 build is the next track, starting with the D20 funnel reconcile.