From d41583c68b5b80faa419f37e0f700e683b06ba3d Mon Sep 17 00:00:00 2001 From: Yashas Date: Wed, 16 Sep 2026 15:38:50 +0530 Subject: [PATCH] copy: an application, not a transcript MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Every user-facing string rewritten from a narrator's voice into an application's. "What she wants you to approve" is now "Recommended actions"; "Her evidence" is "Query log"; "Watch how she did it" is "Activity trace"; "The full story" is "Analysis"; "Ava is reviewing" is "Review in progress"; "Nothing needs your attention this morning" is "No findings". Chart captions state what the chart shows ("Gray: 8-week baseline · Blue: last 6 weeks") instead of commenting on it ("One insurer moved"). The AI is an attribution — "AI analysis · Ava · Confidence 97%" — not a character the page talks about. Labels are nouns, hints are facts, and the queue and action names use the workflow's own vocabulary (Approve actions, Request changes, Resume review, Close case). Same treatment on the exported slides: Summary, Trend, Comparison, Recovery, Recommended actions, Method. Co-Authored-By: Claude Fable 5.1 --- src/api/config.ts | 28 ++++++++++----------- src/components/AvaLive.tsx | 30 +++++++++++----------- src/components/Briefing.tsx | 18 +++++++------- src/components/Findings.tsx | 39 +++++++++++++++-------------- src/layout/Shell.tsx | 2 +- src/lib/slides.ts | 28 ++++++++++----------- src/pages/Login.tsx | 2 +- src/screens/CaseScreen.tsx | 44 ++++++++++++++++----------------- src/screens/QueueScreen.tsx | 26 +++++++++---------- src/screens/RunReviewScreen.tsx | 31 ++++++++++++----------- 10 files changed, 125 insertions(+), 123 deletions(-) diff --git a/src/api/config.ts b/src/api/config.ts index c3771be..eb37adc 100644 --- a/src/api/config.ts +++ b/src/api/config.ts @@ -90,12 +90,12 @@ export interface Queue { } export const QUEUES: Queue[] = [ - { path: 'review', label: 'Awaiting Review', stage: 'Awaiting Review', hint: 'Findings on your desk' }, - { path: 'investigating', label: 'Investigating', stage: 'Investigating', hint: 'Ava is working' }, - { path: 'monitoring', label: 'Monitoring', stage: 'Monitoring', hint: 'Waiting on the re-check' }, - { path: 'needs-human', label: 'Needs Human', stage: NEEDS_HUMAN, hint: 'Ava could not finish' }, - { path: 'closed', label: 'Closed', stage: 'Closed', hint: 'Done, with an outcome' }, - { path: 'all', label: 'All Investigations', stage: null, hint: 'Every case' }, + { path: 'review', label: 'Awaiting Review', stage: 'Awaiting Review', hint: 'Awaiting your decision' }, + { path: 'investigating', label: 'In Progress', stage: 'Investigating', hint: 'Review running' }, + { path: 'monitoring', label: 'Monitoring', stage: 'Monitoring', hint: 'Awaiting scheduled re-check' }, + { path: 'needs-human', label: 'Escalated', stage: NEEDS_HUMAN, hint: 'Requires a person' }, + { path: 'closed', label: 'Closed', stage: 'Closed', hint: 'Completed cases' }, + { path: 'all', label: 'All Cases', stage: null, hint: 'Every review' }, ]; // --------------------------------------------------------------------------- @@ -124,34 +124,34 @@ export const STAGE_ACTIONS: Record = { 'Awaiting Review': [ { activity: ACT.APPROVE, - label: 'Approve Actions', + label: 'Approve actions', roles: ['revenue_cycle_manager'], kind: 'primary', - hint: 'Books the re-check; Ava reports back on whether it worked', + hint: 'Schedules the follow-up re-check', }, { activity: ACT.CHANGES, - label: 'Send Back to Ava', + label: 'Request changes', roles: ['revenue_cycle_manager'], kind: 'secondary', // The only way a person asks Ava anything: in the context of something // she already found. There is deliberately no "ask a question" door. - hint: 'She re-runs the review with your note', + hint: 'Re-runs the review with your note attached', }, { activity: ACT.REJECT, label: 'Reject', roles: ['revenue_cycle_manager'], kind: 'danger' }, ], Approved: [ - { activity: ACT.CLOSE, label: 'Close Case', roles: ['revenue_cycle_manager'], kind: 'secondary' }, + { activity: ACT.CLOSE, label: 'Close case', roles: ['revenue_cycle_manager'], kind: 'secondary' }, ], 'Needs Human': [ { activity: ACT.RESUME, - label: 'Resume Investigation', + label: 'Resume review', roles: ['revenue_cycle_manager'], kind: 'primary', - hint: 'Send it back to Ava with guidance', + hint: 'Re-runs the review with your guidance attached', }, - { activity: ACT.CLOSE, label: 'Close Case', roles: ['revenue_cycle_manager'], kind: 'secondary' }, + { activity: ACT.CLOSE, label: 'Close case', roles: ['revenue_cycle_manager'], kind: 'secondary' }, ], }; diff --git a/src/components/AvaLive.tsx b/src/components/AvaLive.tsx index 423a8c2..9f46055 100644 --- a/src/components/AvaLive.tsx +++ b/src/components/AvaLive.tsx @@ -39,14 +39,14 @@ const TYPE_META: Record< string, { label: string; icon: typeof Database; tone: 'violet' | 'sky' | 'slate' | 'emerald' } > = { - context: { label: 'Read the case file', icon: FileSearch, tone: 'slate' }, - tool: { label: 'Read the case file', icon: FileSearch, tone: 'slate' }, - knowledge: { label: 'Checked her notes', icon: FileSearch, tone: 'slate' }, - llm: { label: 'Thought about it', icon: Brain, tone: 'violet' }, - plan: { label: 'Planned', icon: Brain, tone: 'violet' }, - api: { label: `Asked the data (${LAKEHOUSE.platform})`, icon: Database, tone: 'sky' }, - decision: { label: 'Wrote up her decision', icon: Gavel, tone: 'emerald' }, - escalation: { label: 'Asked for a person', icon: AlertTriangle, tone: 'slate' }, + context: { label: 'Read case data', icon: FileSearch, tone: 'slate' }, + tool: { label: 'Read case data', icon: FileSearch, tone: 'slate' }, + knowledge: { label: 'Knowledge lookup', icon: FileSearch, tone: 'slate' }, + llm: { label: 'Reasoning', icon: Brain, tone: 'violet' }, + plan: { label: 'Planning', icon: Brain, tone: 'violet' }, + api: { label: `${LAKEHOUSE.platform} query`, icon: Database, tone: 'sky' }, + decision: { label: 'Decision submitted', icon: Gavel, tone: 'emerald' }, + escalation: { label: 'Escalated', icon: AlertTriangle, tone: 'slate' }, }; function meta(type: string) { @@ -95,19 +95,19 @@ export function AvaLive({
-

How Ava is working this out

+

Activity trace

- Every step she takes, recorded by the platform as she takes it + Step-by-step execution log, recorded by the platform

{working && ( - working + in progress )} {queries.length} queries - {failed > 0 && {failed} corrected} + {failed > 0 && {failed} query error{failed === 1 ? '' : 's'}} {elapsed > 0 && {Math.round(elapsed)}s} {spend > 0 && {money(spend.toFixed(2))}}
@@ -117,7 +117,7 @@ export function AvaLive({

{working && } {working - ? 'Ava has picked up the case. Her first question to the data appears here within a few seconds.' + ? 'Review started. Steps appear here as they complete.' : 'No steps recorded for this case.'}

) : ( @@ -202,14 +202,14 @@ export function AvaLive({
- Read-only against{' '} + Read-only access ·{' '} {LAKEHOUSE.platform} · {LAKEHOUSE.catalog}.{LAKEHOUSE.schema} - She can only read — nothing she does can change the data + No write access to any source system
diff --git a/src/components/Briefing.tsx b/src/components/Briefing.tsx index 6ec919f..480a4ab 100644 --- a/src/components/Briefing.tsx +++ b/src/components/Briefing.tsx @@ -155,8 +155,8 @@ function SpikeChart({ data, slice, c, title }: { data: BriefingData; slice: Slic const rows = pts.map((p) => ({ ...p, label: shortDate(p.week) })); return ( [r.label, isSlice ? r.denied : `${r.pct}%`]) }} > @@ -179,7 +179,7 @@ function SpikeChart({ data, slice, c, title }: { data: BriefingData; slice: Slic x={shortDate(spike)} stroke={c.ai} strokeDasharray="4 3" - label={{ value: 'rule change', position: 'insideTopLeft', fill: c.ai, fontSize: 11 }} + label={{ value: 'policy effective', position: 'insideTopLeft', fill: c.ai, fontSize: 11 }} /> )} @@ -193,8 +193,8 @@ function PayerChart({ data, slice, c }: { data: BriefingData; slice: Slice | nul const rows = data.payers.map((p) => ({ ...p, short: p.payer.replace(' Health Plan', '').replace(' Health', '').replace(' Mutual', '') })); return ( [r.payer, `${r.rateBase}%`, `${r.rateRecent}%`]) }} > @@ -221,8 +221,8 @@ function RecoveryChart({ data, c, title }: { data: BriefingData; c: typeof HUES. const one = Object.fromEntries(data.recovery.map((b) => [b.bucket, b.billed])) as Record; return ( [b.bucket, b.claims, money(b.billed)]) }} >
@@ -264,8 +264,8 @@ function ExpiringChart({ data, c }: { data: BriefingData; c: typeof HUES.light } const total = rows.reduce((t, r) => t + r.billed, 0); return ( a.firstDeadline.localeCompare(b.firstDeadline))[0]?.firstDeadline ?? null)}`} table={{ head: ['Insurer', 'Claims', 'Billed', 'First deadline'], rows: rows.map((r) => [r.payer, r.claims, money(r.billed), shortDate(r.firstDeadline)]) }} > diff --git a/src/components/Findings.tsx b/src/components/Findings.tsx index 2d2692b..97f7dd0 100644 --- a/src/components/Findings.tsx +++ b/src/components/Findings.tsx @@ -44,18 +44,19 @@ export function Verdict({ row }: { row: Row }) { return (
-

What Ava found

+

Summary

{line}

- {reconciled ? 'Numbers checked against Finance' : 'Numbers NOT yet checked against Finance'} + {reconciled ? 'Reconciled with finance summary' : 'Not reconciled with finance summary'} {confidence != null && ( - Ava is {pct(confidence * 100, 0)} sure + Confidence {pct(confidence * 100, 0)} )} + AI analysis · Ava
@@ -86,8 +87,8 @@ export function Recommendations({ row }: { row: Row }) { return (
-

What she wants you to approve

-

Ranked by money. Each has an owner.

+

Recommended actions

+

Ranked by financial impact. Each names an owner.

    {recs.map((block, i) => { @@ -123,22 +124,22 @@ export function FullStory({ row }: { row: Row }) { open={open} onToggle={() => setOpen(!open)} icon={} - title="The full story" - hint={hasSecondary ? 'Analysis, root cause, and a second pattern she noticed' : 'Her full analysis and the root cause'} + title="Analysis" + hint={hasSecondary ? 'Full analysis, root cause, and a secondary finding' : 'Full analysis and root cause'} tone="ai" >

    {summary}

    {cause && (
    -

    Why it happened

    +

    Root cause

    {cause}

    )} {hasSecondary && (

    - A second, separate problem + Secondary finding

    {secondary}

    @@ -175,11 +176,11 @@ export function SqlEvidence({ row, steps, decisions }: { row: Row; steps: AvaTra open={open} onToggle={() => setOpen(!open)} icon={} - title="Her evidence" + title="Query log" hint={ queries.length - ? `${queries.length} database queries, exactly as she ran them — anyone can re-run these` - : `${notes.length} steps, in her own words` + ? `${queries.length} queries executed against Databricks — reproducible` + : `${notes.length} analysis steps` } > {queries.length > 0 ? ( @@ -189,7 +190,7 @@ export function SqlEvidence({ row, steps, decisions }: { row: Row; steps: AvaTra

    Query {i + 1} {q.query_state === 'FAILED' ? ( - error — corrected next + error — corrected in next query ) : q.rows_returned != null ? ( {q.rows_returned} row{q.rows_returned === 1 ? '' : 's'} ) : null} @@ -225,17 +226,17 @@ export function Recheck({ row }: { row: Row }) { return ( {better ? 'back to normal' : 'still elevated'}} + title="Re-check result" + subtitle="Scheduled re-check after approval" + actions={{better ? 'Within baseline' : 'Still elevated'}} >

    {summary}

    diff --git a/src/layout/Shell.tsx b/src/layout/Shell.tsx index b27b6cf..8adfde0 100644 --- a/src/layout/Shell.tsx +++ b/src/layout/Shell.tsx @@ -33,7 +33,7 @@ export function Shell() { decides what is worth a person's time. */} {user && ( diff --git a/src/lib/slides.ts b/src/lib/slides.ts index b9a9890..52bfc22 100644 --- a/src/lib/slides.ts +++ b/src/lib/slides.ts @@ -46,7 +46,7 @@ const RECOVERY_COLOR: Record = { export async function buildDeck(row: Row, data: BriefingData, slice: Slice | null): Promise { const pres = new pptxgen(); pres.layout = 'LAYOUT_WIDE'; // 13.33 x 7.5 in - pres.author = 'Ava — Denials Analyst, Northlake Health'; + pres.author = 'Northlake Health — Denials Desk (AI analyst: Ava)'; pres.title = `Denials briefing — case #${str(row.instance_id)}`; const caseNo = str(row.instance_id); @@ -57,13 +57,13 @@ export async function buildDeck(row: Row, data: BriefingData, slice: Slice | nul s.addShape(pres.ShapeType.rect, { x: 0, y: 0, w: 13.33, h: 0.08, fill: { color: BRAND } }); if (kicker) s.addText(kicker.toUpperCase(), { x: 0.6, y: 0.35, w: 12, h: 0.3, fontSize: 10, bold: true, color: AI, charSpacing: 1 }); s.addText(title, { x: 0.6, y: kicker ? 0.62 : 0.4, w: 12.1, h: 0.7, fontSize: 22, bold: true, color: INK, valign: 'top' }); - s.addText(`Northlake Health · Denials Desk · case #${caseNo} · prepared by Ava`, { x: 0.6, y: 7.0, w: 12, h: 0.3, fontSize: 9, color: FAINT }); + s.addText(`Northlake Health · Denials Desk · Case #${caseNo} · AI analysis (Ava) · for manager review`, { x: 0.6, y: 7.0, w: 12, h: 0.3, fontSize: 9, color: FAINT }); }; // ---- 1. What happened ------------------------------------------------------- { const s = pres.addSlide(); - chrome(s, headline(row.summary, 240), 'What Ava found'); + chrome(s, headline(row.summary, 240), 'Summary'); const tiles: Array<[string, string, string]> = [ ['Claims denied', num(row.affected_claims)?.toLocaleString('en-US') ?? '—', INK], ['Money at stake', money(row.amount_at_risk), 'B31E23'], @@ -77,7 +77,7 @@ export async function buildDeck(row: Row, data: BriefingData, slice: Slice | nul }); const cause = str(row.root_cause); if (cause) { - s.addText('WHY IT HAPPENED', { x: 0.6, y: 3.95, w: 12, h: 0.3, fontSize: 10, bold: true, color: MUTED, charSpacing: 1 }); + s.addText('ROOT CAUSE', { x: 0.6, y: 3.95, w: 12, h: 0.3, fontSize: 10, bold: true, color: MUTED, charSpacing: 1 }); s.addText(cause, { x: 0.6, y: 4.25, w: 12.1, h: 2.5, fontSize: 13, color: INK, valign: 'top' }); } } @@ -87,7 +87,7 @@ export async function buildDeck(row: Row, data: BriefingData, slice: Slice | nul if (spikePts.length) { const s = pres.addSlide(); const isSlice = data.weeklySlice.length > 0; - chrome(s, isSlice ? `Denied claims per week — ${sliceTitle}` : 'Hospital denial rate per week', 'The spike'); + chrome(s, isSlice ? `Weekly denied claims — ${sliceTitle}` : 'Weekly denial rate — all claims', 'Trend'); const labels = spikePts.map((p) => shortDate(p.week)); const spike = slice?.spikeStart; if (isSlice) { @@ -114,13 +114,13 @@ export async function buildDeck(row: Row, data: BriefingData, slice: Slice | nul valGridLine: { color: GRID, size: 0.5 }, catGridLine: { style: 'none' }, showLegend: false, }); } - if (spike) s.addText(`Rule change effective ${shortDate(spike)}. Everything to the right of it is the spike.`, { x: 0.6, y: 6.65, w: 12, h: 0.3, fontSize: 11, color: AI, italic: true }); + if (spike) s.addText(`Payer policy effective ${shortDate(spike)}. Weeks from that date shown in blue.`, { x: 0.6, y: 6.65, w: 12, h: 0.3, fontSize: 11, color: AI, italic: true }); } // ---- 3. Where it sits ------------------------------------------------------- if (data.payers.length) { const s = pres.addSlide(); - chrome(s, 'Denial rate by insurer — before vs now', 'Where it sits'); + chrome(s, 'Denial rate by insurer', 'Comparison'); const labels = data.payers.map((p) => p.payer); s.addChart( pres.ChartType.bar, @@ -138,14 +138,14 @@ export async function buildDeck(row: Row, data: BriefingData, slice: Slice | nul ); if (slice?.payer) { const p = data.payers.find((x) => x.payer === slice.payer); - if (p) s.addText(`${p.payer}: ${p.rateBase}% → ${p.rateRecent}%. Every other insurer is within noise.`, { x: 0.6, y: 6.55, w: 12, h: 0.35, fontSize: 12, bold: true, color: INK }); + if (p) s.addText(`${p.payer}: ${p.rateBase}% → ${p.rateRecent}%. Other insurers within normal variation.`, { x: 0.6, y: 6.55, w: 12, h: 0.35, fontSize: 12, bold: true, color: INK }); } } // ---- 4. Where the money stands ---------------------------------------------- if (data.recovery.length || data.expiring.length) { const s = pres.addSlide(); - chrome(s, 'Where the money stands', 'The money'); + chrome(s, 'Financial position', 'Recovery'); if (data.recovery.length) { const ordered = RECOVERY_ORDER.filter((b) => data.recovery.some((r) => r.bucket === b)); s.addText(sliceTitle.toUpperCase(), { x: 0.6, y: 1.45, w: 6, h: 0.3, fontSize: 10, bold: true, color: MUTED, charSpacing: 1 }); @@ -197,7 +197,7 @@ export async function buildDeck(row: Row, data: BriefingData, slice: Slice | nul const recs = recommendations(row.recommendations); if (recs.length) { const s = pres.addSlide(); - chrome(s, 'What she recommends', 'For your approval'); + chrome(s, 'Recommended actions', 'For approval'); let y = 1.5; recs.slice(0, 5).forEach((block, i) => { const { title, body } = splitRecommendation(block); @@ -217,18 +217,18 @@ export async function buildDeck(row: Row, data: BriefingData, slice: Slice | nul // ---- 6. How she got there ---------------------------------------------------- { const s = pres.addSlide(); - chrome(s, 'How she got there', 'Method'); + chrome(s, 'Method', 'Method'); const reconciled = row.data_reconciled === true || str(row.data_reconciled) === 'true'; const conf = num(row.confidence); const bullets = [ str(row.scanned_summary) || 'Reviewed every payer, department and front desk against an 8-week baseline.', reconciled ? 'Claims data reconciled against the finance report before any analysis.' : 'Claims data could not be fully reconciled against finance — treat numbers as provisional.', `Cause matched to the payer's own policy bulletin${slice?.spikeStart ? ` effective ${shortDate(slice.spikeStart)}` : ''}.`, - conf != null ? `Ava's stated confidence: ${Math.round(conf * 100)}%.` : '', - 'Read-only against Databricks (workspace.rcm). Every query is recorded and reviewable on the case.', + conf != null ? `Stated confidence: ${Math.round(conf * 100)}%.` : '', + 'Read-only access to Databricks (workspace.rcm). Every query is logged and reproducible from the case.', ].filter(Boolean); s.addText(bullets.map((b) => ({ text: b, options: { bullet: true, breakLine: true, fontSize: 13, color: INK, paraSpaceAfter: 8 } })), { x: 0.6, y: 1.5, w: 12.1, h: 4.8, valign: 'top' }); - s.addText('Ava proposes; a revenue-cycle manager decides. She has no write access to any system.', { x: 0.6, y: 6.4, w: 12, h: 0.4, fontSize: 11, italic: true, color: AI }); + s.addText('AI analysis requires manager approval before any action. The analyst has no write access to any system.', { x: 0.6, y: 6.4, w: 12, h: 0.4, fontSize: 11, italic: true, color: AI }); } await pres.writeFile({ fileName: `Northlake-denials-briefing-case-${caseNo}.pptx` }); diff --git a/src/pages/Login.tsx b/src/pages/Login.tsx index 6dad13c..d08d079 100644 --- a/src/pages/Login.tsx +++ b/src/pages/Login.tsx @@ -57,7 +57,7 @@ export function Login() {

    Sign in

    - Denials Desk — revenue cycle, Northlake Health. + Revenue cycle — denials management.

    diff --git a/src/screens/CaseScreen.tsx b/src/screens/CaseScreen.tsx index a088267..6bddb74 100644 --- a/src/screens/CaseScreen.tsx +++ b/src/screens/CaseScreen.tsx @@ -103,23 +103,23 @@ export function CaseScreen() { const work = ; return ( -
    +
    Back Case #{str(row.instance_id)} - {quiet ? 'Nothing to report' : state} + {quiet ? 'No findings' : state} {kind && FINDING_KIND[kind] && {FINDING_KIND[kind]}} - Daily review · {dateTime(row.created_at)} + Daily review · opened {dateTime(row.created_at)} {str(row.review_as_of) ? ` · as of ${str(row.review_as_of).slice(0, 10)}` : ''} {hasFindings && ( - )}
    @@ -131,13 +131,13 @@ export function CaseScreen() { <>

    - Ava is reviewing + Review in progress

    - Every payer, department and front desk — checking whether anything is materially off. + Checking all payers, departments and front desks against the 8-week baseline.

    - Takes about four minutes. If nothing clears the bar, she closes this case herself. + Typical duration 4–5 minutes. If no change clears the materiality threshold, the case closes with no findings.

    {work} @@ -148,10 +148,10 @@ export function CaseScreen() { {quiet && (

    - Reviewed — nothing to report + Review complete

    - Nothing needs your attention this morning. + No findings. No material change across payers, departments or front desks.

    {scanned &&

    {scanned}

    }
    @@ -160,7 +160,7 @@ export function CaseScreen() { {/* ---------- Needs a human ---------- */} {state === NEEDS_HUMAN && (
    -

    Ava stopped and asked for you

    +

    Escalated — requires a decision

    {str(row.escalation_reason) || 'No reason recorded.'}

    @@ -180,7 +180,7 @@ export function CaseScreen() { {/* ---------- The decision ---------- */} {actions.length > 0 && (
    -

    Your decision

    +

    Review decision

    {actions.map((a) => (
    @@ -204,8 +204,8 @@ export function CaseScreen() { open={showWork} onToggle={() => setShowWork(!showWork)} icon={} - title="Watch how she did it" - hint="Her every step, from the platform's own trace — read the case, think, query, think, decide" + title="Activity trace" + hint="Step-by-step execution log for this review" tone="ai" >
    {work}
    @@ -221,8 +221,8 @@ export function CaseScreen() { open={showWork} onToggle={() => setShowWork(!showWork)} icon={} - title="Watch how she did it" - hint="Her every step — the proof that a quiet morning was checked, not skipped" + title="Activity trace" + hint="Step-by-step execution log — the checks performed for this no-findings result" tone="ai" >
    {work}
    @@ -235,11 +235,11 @@ export function CaseScreen() {
    @@ -292,6 +292,6 @@ function Rail({ state }: { state: string }) { function defaultApprovalNote(row: Record): string { const recoverable = row.recoverable_amount; return recoverable - ? `Approved. Proceed with the appeals and the process fix as recommended; expected recovery $${Number(recoverable).toLocaleString('en-US')}. Re-check when the timer fires.` - : 'Approved. Proceed as recommended and re-check when the timer fires.'; + ? `Approved. Proceed with the recommended appeals and process changes. Expected recovery $${Number(recoverable).toLocaleString('en-US')}.` + : 'Approved. Proceed with the recommended actions.'; } diff --git a/src/screens/QueueScreen.tsx b/src/screens/QueueScreen.tsx index 5a59b5f..ce274f2 100644 --- a/src/screens/QueueScreen.tsx +++ b/src/screens/QueueScreen.tsx @@ -41,7 +41,7 @@ export function QueueScreen() { const list = rows.data ?? []; return ( -
    +
    navigate('/review')} />
    @@ -55,7 +55,7 @@ export function QueueScreen() { {rows.error && {rows.error}} {rows.loading && !rows.data && } {rows.data && list.length === 0 && ( - Nothing here.{queue.stage === 'Awaiting Review' && ' When Ava finds something worth your time, it lands here.'} + No cases in this queue. )}
    @@ -84,28 +84,28 @@ function Briefing({ rows, onRun }: { rows: Row[]; onRun: () => void }) {

    - This morning{latest ? ` · last review ${dateTime(latest.updated_at)}` : ''} + Daily review{latest ? ` · last run ${dateTime(latest.updated_at)}` : ''}

    {waiting.length === 0 && working.length === 0 && needsHuman.length === 0 - ? 'Nothing needs your attention.' + ? 'No cases awaiting decision.' : [ waiting.length > 0 && - `${waiting.length} decision${waiting.length === 1 ? '' : 's'} waiting for you${ - recoverable > 0 ? ` — ${money(recoverable)} recoverable` : '' + `${waiting.length} case${waiting.length === 1 ? '' : 's'} awaiting decision${ + recoverable > 0 ? ` · ${money(recoverable)} recoverable` : '' }`, - working.length > 0 && `${working.length} case${working.length === 1 ? '' : 's'} Ava is working on`, - needsHuman.length > 0 && `${needsHuman.length} she could not finish`, + working.length > 0 && `${working.length} review${working.length === 1 ? '' : 's'} in progress`, + needsHuman.length > 0 && `${needsHuman.length} escalated`, ] .filter(Boolean) .join(' · ')}

    - Ava reviews every payer, department and front desk each morning and only opens a case when something clears the bar. + Automated review of all payers, departments and front desks. A case is opened only when a change clears the materiality threshold.

    @@ -133,7 +133,7 @@ function CaseCard({ row, onOpen }: { row: Row; onOpen: () => void }) { >
    - {quiet ? 'Nothing to report' : waiting ? 'Needs your decision' : state} + {quiet ? 'No findings' : waiting ? 'Awaiting decision' : state} {kind && FINDING_KIND[kind] && {FINDING_KIND[kind]}} @@ -146,8 +146,8 @@ function CaseCard({ row, onOpen }: { row: Row; onOpen: () => void }) { {summary ? headline(summary, 160) : quiet - ? 'Reviewed everything — nothing needs attention.' - : 'Ava is reviewing every payer, department and front desk…'} + ? 'No material change detected across payers, departments or front desks.' + : 'Review in progress…'}

    {recoverable != null && recoverable > 0 && ( diff --git a/src/screens/RunReviewScreen.tsx b/src/screens/RunReviewScreen.tsx index 29156d4..d472a89 100644 --- a/src/screens/RunReviewScreen.tsx +++ b/src/screens/RunReviewScreen.tsx @@ -45,10 +45,11 @@ export function RunReviewScreen() { return (
    -

    Daily review

    +

    Run daily review

    - Ava looks at every payer, department and front desk, and only opens a case if - something clears the bar. Most mornings she reports nothing. + Runs the full review now across all payers, departments and front desks. A case is + opened only if a change clears the materiality threshold; otherwise the run closes + with no findings.

    @@ -60,19 +61,19 @@ export function RunReviewScreen() {
    -

    What she checks

    +

    Checks performed

      -
    • That the claims data reconciles with the finance report
    • -
    • Denial rate vs baseline — by payer, reason code, department, front desk, week
    • -
    • Money about to fall out of an appeal window unfiled
    • +
    • Claims data reconciled against the finance monthly summary
    • +
    • Denial rate vs 8-week baseline: by payer, reason code, department, front desk, week
    • +
    • Unfiled appeals with deadlines within 14 days

    - The bar: a denied count up more than 40% on meaningful volume, or more than $100K - expiring. Below it, she watches and says nothing. + Materiality threshold: denied count up more than 40% on at least 25 claims, or more + than $100K in appeals expiring. Items below the threshold are listed, not flagged.

    - Read-only against {LAKEHOUSE.platform} · {LAKEHOUSE.catalog}.{LAKEHOUSE.schema} + Read-only · {LAKEHOUSE.platform} · {LAKEHOUSE.catalog}.{LAKEHOUSE.schema}

    @@ -81,20 +82,20 @@ export function RunReviewScreen() {

    - Normally fires at 6am on its own. This is the same activity. + Scheduled daily at 06:00. This runs the same activity immediately.

    - Anchored on {QUIET_MORNING_AS_OF}, before anything went wrong — to see what - “nothing to report” looks like. + Runs the review against data as of this date — a period with no material change, + to show a no-findings outcome.