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.