Commit Graph

26 Commits

Author SHA1 Message Date
811a0ca283 fix: review coverage renders as a comparison and a list, not chip soup
The key=value row was being humanised before it was parsed, so the period
tiles never appeared and raw window=... chips showed instead. Parse the raw
text; humanise only what is displayed. Findings are now a bulleted list at
reading size, and the watched / checked lines are one small line each.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-17 15:49:42 +05:30
245a6a8f75 feat: review coverage draws the comparison — this period vs compared with
REVIEWED is now key=value fields from Ava (window, baseline, counts, pending,
scope, ceiling); the console renders two period tiles and one plain sentence
instead of sentence-fragment chips. Older free-text rows keep the chip fallback.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-17 15:35:49 +05:30
400f9ec3a0 fix: recommendations run together on one line split into ranked items; old re-check prose falls back to bullets
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-17 13:53:54 +05:30
35d4d97504 fix: re-check verdict comes from the decision, and renders as labelled rows
'Within baseline' was re-derived by the console from two rates — a 0% rate on
a mostly-pending window read as recovery. The badge now follows the activity
Ava chose (Confirm Recovery closes the case; Flag Still Elevated does not),
and the four-line re-check summary (since approval / actions / rate / verdict)
renders as rows like the review coverage.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-17 13:46:44 +05:30
f86a87af38 fix: custom run is one of two modes — replay a morning, or analyse a period
The three-date form let 'data as of' and 'window to' overlap and resolved the
clash by a hidden rule. Now a two-card choice: Replay (one date; 6 weeks
before it vs the 8 before those) or Period (from–to vs the 8 weeks before
it). Each mode sends only its own fields; the preview names the exact periods.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-17 13:30:54 +05:30
77cf90e40b fix: a review window needs a baseline — say which one, refuse ones that have none
- charter: a window starting before the data or longer than 12 weeks is split
  (last 6 weeks vs the 8 before); REVIEWED always names the compared periods,
  never the requested span or the whole table
- Run review: shows the data's span, previews the exact recent and baseline
  periods, blocks a window whose baseline would fall before the first claim,
  and sends 'data as of' only when no window end is given

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-17 12:26:49 +05:30
91002b11c4 fix: deep links reproduce Ava's counts — slice identity, window ceiling, cohort dates
- slice now carries site / desk / provider (14_slice_dims.sql), so a front-desk
  or provider finding opens the right rows, not every CO-27 in the hospital
- every link is capped at the review's ceiling date (review_to / as-of); a
  custom-window run no longer opens claims Ava never looked at
- slow-payer link filters to claims SENT 31–60 days before the latest submitted
  date (from the stats view), matching her 1,352 instead of all 2,753 pending
- 'first deadline' ignores dates before the review (it was picking the spike week)
- header says 'Custom run' when dates were chosen; page changes scroll to top
  and dim the table while loading

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-17 11:39:52 +05:30
b4bff014b3 feat: review coverage as rows of facts, not a paragraph
Ava now writes the work statement as four labelled lines (REVIEWED / FOUND /
WATCHED / CLEAR, items separated by ';'); the case page renders each as a row
of short chips under 'Review coverage'. Older prose falls back to sentence
bullets. Charter also asks for a <=25-word first sentence and plain English —
no column names or SQL in prose.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-16 22:53:27 +05:30
f32545ed92 copy: lakehouse labels describe the data, not the AI
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-16 19:23:14 +05:30
4087d2c2e0 fix: dates in Ava's prose read as 'Jul 26, 2026', not 2026-07-26
Display-only rewrite (format.prose) on every surface that shows her text —
headline, work statement, full story, recommendations, re-check, queue cards,
slides, notes. Stored text keeps ISO dates so deadline and spike parsers still
read them.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-16 19:17:08 +05:30
75483f347e fix: stable claims paging and a deep link that does not lose its date window
- claims paging ordered by claim_id (unique) instead of service_date: each page
  is a separate Spark query, and with thousands of ties the engine repeated rows
  across pages
- the case's anchor date comes from the review's own ceiling or the lakehouse
  stats view, not from the briefing, which loads seconds later; an
  expiring-appeals link with no anchor is now suppressed rather than opening
  every unfiled denial

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-16 19:11:02 +05:30
1c81912b17 feat: Lakehouse — every table Ava reads, with counts; claims gets total, search and filters
- /lakehouse: one card per Databricks table from the lakehouse_tables stats view
  (rows, date span, dollars); reference tables open a plain row view
- /claims: exact total (stats view when unfiltered; platform count, capped at
  10,000, when filtered), search on claim id / provider / CPT, dropdown filters
  fed by the API's distinct values, service-date range
- sidebar: 'Lakehouse' replaces 'Claims'; claims pages light it too
- pairs with 13_lakehouse.sql (rdbms templates + record views)

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-16 19:00:10 +05:30
5e0649fb7e feat: reviewer chooses the dates — data as-of and the analysis window
Run review keeps the one-click default; a Custom run card takes 'data as of',
'window from' and 'window to' (all optional) and previews the window Ava will
use. Case page shows the chosen window. Pairs with 12_review_window.sql
(review_from / review_to on Run Daily Review) and the charter's THE WINDOW rule.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-16 18:49:26 +05:30
e8741f6333 feat: claims explorer — the lakehouse rows behind every number
- /claims: Databricks claims table through the record-view API, server-side
  paging and filters (exact on dimensions, ranges on dates); URL is the filter set
- finding tiles link to the exact rows: affected set, and the unfiled-inside-window
  subset behind 'still recoverable'; kind-aware (expiring, slow payer, underpayment)
- 'What Ava reviewed' work statement shown under the headline
- client: range / multi-value filters

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-16 18:45:34 +05:30
1d2dc4a1b9 fix: briefing picks charts by finding kind, folds partial slices, honours replay dates
- expiring_appeals / slow_payer / underpayment no longer get the denial-spike
  charts sliced by payer alone (one bar per department x code)
- weekly and recovery rows folded to their chart grain
- replayed mornings show only the trend, cut at the replay date
- new charts: payer speed (slow_payer) and appeal scorecard
- y-axis ticks no longer clipped at two digits

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-16 16:31:43 +05:30
03ff478e4a fix: chart skeleton while the lakehouse answers; sentence splits survive decimals and initials
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-16 16:22:19 +05:30
de86cd9859 feat: slow-payer and appeal-scorecard checks on the Run review page
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-16 16:16:58 +05:30
6af647b462 feat: two more finding kinds — single-provider coding, underpayment
The review now cuts by procedure and by provider, and checks paid vs allowed
for short-payments. The Run review page lists the checks and the thresholds
that apply to each.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-16 15:53:28 +05:30
d41583c68b copy: an application, not a transcript
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 <noreply@anthropic.com>
2026-09-16 15:38:50 +05:30
5df97f989c fix: "$1.56M" is not two sentences, and one attempt is not two
Recommendation titles were cut at the first period, so "$1.56M billed"
rendered as a title of "$1" and a body starting "56M". The split now breaks
only on a period followed by a space, a colon, or a newline — decimals and
codes like CO-197 survive.

Her evidence counted every attempt on the case: a run that failed to submit
leaves its queries in the trace beside the run that succeeded, and 16 + 20
read as "36 database queries". The panel now scopes to the attempt whose
decision was submitted (trace events carry decision_id), so the count is
what she actually did to reach these findings.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-16 15:17:01 +05:30
5eb0890e97 feat: the briefing — four charts on the case, and six slides to take away
A case now carries pictures, and a button that turns it into a deck.

THE CHARTS (Briefing.tsx) answer the same three questions the page does,
visually: the spike (the flagged slice's weekly denials, with the payer's
rule change drawn as a line — weeks after it in the accent, before in gray),
where it sits (denial rate by insurer, baseline vs now), where the money
stands (the slice's denied dollars by what can still happen to them), and
appeals about to expire by insurer. Every chart has a table twin.

Data comes from six pre-aggregated Databricks views (sm2/…/chart_views.py)
read through the ordinary record-view API, filtered by the slice Ava now
records in four structured fields (slice_payer, slice_department,
slice_reason_code, spike_start). Nothing is computed from raw claims in the
browser.

COLOUR WAS COMPUTED, NOT EYEBALLED. The palette is the dataviz reference
set (blue 1, orange 2, green 6, violet 7, gray) run through
validate_palette.js against this console's own surfaces, both themes — all
checks pass. Two things the validator caught: the brand teal fails the
chroma floor and would read as gray on a chart, so it is never a data hue;
and red beside orange in the recovery stack fails adjacent-pair separation
even for normal vision (ΔE 7.1), so "lost on appeal" is violet.

THE SLIDES (lib/slides.ts) are six native-chart PowerPoint slides built in
the browser with pptxgenjs from the same rows: what happened, the spike,
where it sits, the money, the recommendations, the method. Text is Ava's
verbatim. Lazy-imported so the 700 KB library is paid for only on click.

Backend counterpart: sm2/custom-apps/denials-investigator/10_briefing.sql.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-16 14:24:31 +05:30
92ea27d27e fix: her evidence comes from the trace, not from a form field
Case 58325 died submitting findings: the submit_decision call arrived with
no `data` at all. The final model reply was exactly 4,096 output tokens —
the service's cap — so the JSON was cut off mid-call. Asking Ava to paste
16 full SQL statements into sql_log, on top of a summary, root cause, five
recommendations and a scanned-summary, is what pushed one tool call past
the limit and lost the whole investigation.

The platform already records every statement the agentic tool sends,
verbatim, with Databricks' own SUCCEEDED/FAILED and the row count. So
SqlEvidence now renders from the trace and treats sql_log as a one-line
index per step. Her charter gained hard per-field character limits to
match (sm2/custom-apps/denials-investigator/05_ai_employee.sql).

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-16 13:56:52 +05:30
e294df6eba design: three questions, three sizes
Rebuilt the two screens for a person with ninety seconds, not an analyst.

Every screen now answers, in order and at descending size: what happened
(one sentence, 21px), how much (three numbers you can read across a
table — claims denied, money at stake, still recoverable with its first
deadline), and what she wants approved (the ranked list, with the decision
buttons directly under it). The full analysis, her SQL and the live trace
sit behind disclosures — one click for the reviewer who wants to check,
zero clutter for the manager who does not.

The queue opens on a briefing strip: "1 decision waiting for you —
$1,091,000 recoverable". A manager who reads only that line has the day.
Cards lead with the verdict sentence and the recoverable figure; a waiting
case says "Needs your decision", not "Awaiting Review".

Jargon translated where a business reader meets it: "data reconciled"
became "Numbers checked against Finance"; "97% confident" became "Ava is
97% sure"; the trace steps read "Asked the data" and "Thought about it".
Ava's SHOUTED recommendation headings are sentence-cased.

While Ava is still working, the trace is the page — there is nothing else
to show yet, and watching her query is the demo.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-16 13:38:09 +05:30
76e2eddd05 refactor: one front door
Start Investigation is gone. The daily review is the only way a case is
born — "she isn't asked" should not ship with a button for asking her. A
person still steers Ava, but only about something she already found:
Send Back to Ava carries the note.

Removed the ask-a-question screen, route and ghost button; the case page's
"request" card now says how the review came to exist (live, or a replay of
a past morning) instead of echoing a question nobody typed.

Backend counterpart: sm2/custom-apps/denials-investigator/09_one_front_door.sql.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-16 13:15:21 +05:30
b2377b4645 feat: Ava stops waiting to be asked — the daily review
The primary action is now "Run daily review": no form, no question. It
starts the new INIT door dni-act-review, which is the same activity a
scheduler performs at 6am; the button exists so a room does not have to
wait until 6am. Ava sweeps every payer, department and front desk against a
materiality bar and, if nothing clears it, records "nothing to report" and
closes the case herself — it never reaches a desk. "Ask a question" stays,
demoted to a ghost button, for the follow-up path.

A second button replays a quiet morning: the demo data is static, so every
live sweep would flag the same August spike. Anchoring one run on
2026-07-26 lets it genuinely come back empty, and the contrast — one quiet
morning beside one $1.09M morning — is the pitch.

Queue cards and the case page now carry the sweep outcome: what she
reviewed, how many patterns she flagged, and what kind (payer rule change,
front desk, expiring appeals, …). A closed quiet case reads "Nothing to
report" rather than "Closed", because those are different outcomes.

Backend counterpart: sm2/custom-apps/denials-investigator/08_daily_review.sql
and the sweep-first charter in 05_ai_employee.sql.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-16 13:12:40 +05:30
1c1c120202 feat: the denials desk, and Ava working where you can watch her
The operator console for Northlake Health's Denials Investigator (dev, org
900000109 / app 900000102). A revenue-cycle manager asks why claim denials
rose; Ava — an AI employee — investigates the hospital's Databricks lakehouse
and comes back with a cause, a dollar figure and a recommendation. He approves,
and she re-checks on her own two minutes later.

THE POINT OF THE SCREEN is that her work is checkable. Anyone can be told an
agent analysed their denials; AvaLive shows the actual SQL she sent to
Databricks, in order, with what came back and how long each query took — and it
does NOT hide a query she got wrong and corrected, because that is the most
convincing thing on the page.

Two decisions worth knowing about:

* Her trace does not come from the AI-employee monitor API. That endpoint needs
  an org-scoped studio token and answers "no organization scope on this
  account" for every user of this console. It comes instead from two views
  (northlake_app.ava_trace / ava_decisions) exposed as ordinary rdbms record
  views, behind a login role that cannot read the aiemployee schema at all.
  Seeded by sm2/custom-apps/denials-investigator/07_console_views.sql.

* Ava's own activities — Record Findings, Confirm Recovery, Flag Still
  Elevated, Escalate — are deliberately absent from STAGE_ACTIONS. Putting them
  on screen would only let a person sign in as the agent and press its button,
  which is a person impersonating an agent rather than an agent working.

Violet is the AI and nothing else is violet; amber is the one queue a human
owns. No API URL is compiled in — config.js carries it at placement time.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-15 23:47:19 +05:30