AI skill: SKILL.md, AI contract, scrubbed references, eval fixture (d)

- rpa-dashboard-ai/SKILL.md: trigger description and the shared question flow;
  points at the no-AI frontend.md, themes and palette instead of copying them.
- templates/contract.md: runs, review rows, endpoints and the server approve gate.
- Superbill extracts: patient names and the client name removed, every file
  carries an EXAMPLE ONLY banner. tests/test_reference_scan.py checks both skills
  for patient data, internal IPs, credentials and keys.
- tests/fixtures/d-ai-extraction and its eval entry, which runs page_check_ai
  on the built folder.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
VasanthandClaude Opus 5.5 committed 2026-10-16 15:13:55 +05:30
1 parent 91495935b9
commit 8951ac05a5
30 files changed
+372 -26

No files matched your search

@@ -1,3 +1,4 @@
# EXAMPLE ONLY: an extract from the Superbill Review prototype, kept as reference for porting. ECW/eClinicalWorks, Tebra, 'Example Client', SPB_* tables and patient/ticket wording are that project's examples. Don't copy them into a new project.
INCLUDE_THINKING_IN_COST = True # thinking tokens bill at output rate
# ═════════════════════════════════════════════════════════════════════════════
@@ -1,3 +1,4 @@
<!-- EXAMPLE ONLY: an extract from the Superbill Review prototype, kept as reference for porting. ECW/eClinicalWorks, Tebra, 'Example Client', SPB_* tables and patient/ticket wording are that project's examples. Don't copy them into a new project. -->
---
name: Superbill Extraction and Automation Tool
description: Extract billing fields from a scan, verify them against the page, post to eClinicalWorks.
@@ -1,3 +1,4 @@
/* EXAMPLE ONLY: an extract from the Superbill Review prototype, kept as reference for porting. ECW/eClinicalWorks, Tebra, 'Example Client', SPB_* tables and patient/ticket wording are that project's examples. Don't copy them into a new project. */
import type {
AuditEntry, Batch, BatchStage, DemographyRecord, DemographyRun, InsuranceMasterRow, LastRun,
ManagedUser,
@@ -84,7 +85,7 @@ export const api = {
for (const f of files) body.append('files', f)
// `project` is which board received the drop. Nothing has detected a
// template yet, and the board a batch appears on is derived from that, so
// without it a Gulf Coast upload surfaces under ECW and reads as a failed
// without it a Example Client upload surfaces under ECW and reads as a failed
// upload on the Tebra board.
return req<Batch>(`/api/batches?${new URLSearchParams({ model, project })}`, {
method: 'POST',
@@ -1,3 +1,4 @@
/* EXAMPLE ONLY: an extract from the Superbill Review prototype, kept as reference for porting. ECW/eClinicalWorks, Tebra, 'Example Client', SPB_* tables and patient/ticket wording are that project's examples. Don't copy them into a new project. */
/**
* The confidence bands, and the exact colours the workbook paints.
*
@@ -1,3 +1,4 @@
/* EXAMPLE ONLY: an extract from the Superbill Review prototype, kept as reference for porting. ECW/eClinicalWorks, Tebra, 'Example Client', SPB_* tables and patient/ticket wording are that project's examples. Don't copy them into a new project. */
import { ThemeSwitcher } from '../theme'
import { ROLE_LABEL } from '../auth'
@@ -1,3 +1,4 @@
/* EXAMPLE ONLY: an extract from the Superbill Review prototype, kept as reference for porting. ECW/eClinicalWorks, Tebra, 'Example Client', SPB_* tables and patient/ticket wording are that project's examples. Don't copy them into a new project. */
/**
* A proportional ring.
*
@@ -1,3 +1,4 @@
/* EXAMPLE ONLY: an extract from the Superbill Review prototype, kept as reference for porting. ECW/eClinicalWorks, Tebra, 'Example Client', SPB_* tables and patient/ticket wording are that project's examples. Don't copy them into a new project. */
import { useCallback, useEffect, useRef, useState } from 'react'
import { useQuery } from '@tanstack/react-query'
import { api } from '../api'
@@ -1,3 +1,4 @@
/* EXAMPLE ONLY: an extract from the Superbill Review prototype, kept as reference for porting. ECW/eClinicalWorks, Tebra, 'Example Client', SPB_* tables and patient/ticket wording are that project's examples. Don't copy them into a new project. */
import { useEffect, useMemo, useRef, useState } from 'react'
import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query'
import { api } from '../api'
@@ -12,7 +13,7 @@ const isOfficeLocation = (t: string | null) =>
// One review card per record on a page. An ECW roster can list the same
// person twice (two Sleep Study encounters for one patient) — line_index
// splits those into separate cards. A Gulf Coast ticket spreads its charges
// splits those into separate cards. A Example Client ticket spreads its charges
// over several line_index values and must stay ONE card, so it is excluded.
// The name stays in the key so runs stored before line_index existed (every
// row LineIndex 0) still group exactly as before.
@@ -100,7 +101,7 @@ type Patient = {
type SaveArgs = { row: ReviewRow; draft: string; verified: boolean }
// ── Office Location ────────────────────────────────────────────────────────
// A Gulf Coast ticket whose yellow note the Office Location rules read. The
// A Example Client ticket whose yellow note the Office Location rules read. The
// backend stores the parsed note on the ticket's first line under this field
// (src/superbill/extraction/office_location.py, ParsedNote); a ticket without
// it is a run from before the rules existed and keeps the flat layout.
@@ -191,11 +192,11 @@ export function ReviewPane({
}) {
const [index, setIndex] = useState(0)
// Drafts live here, not in FieldRow — a correction is no longer committed on
// blur (that is exactly how four ARMSTRONG fields got saved mid-keystroke:
// "ARMSTRONG, CHARLES T" as "\ONG, CHARLES T", "99291" as "992"). Text typed
// blur (that is exactly how four fields of one record got saved mid-keystroke:
// "Doe, Jane A" as "\e, Jane A", "99291" as "992"). Text typed
// into a field is held until an explicit Save, keyed by row_id rather than
// bare field name — a bare name repeats once a page can carry more than one
// row per field (Gulf Coast's repeated CPT lines), and DemographyTab.tsx
// row per field (Example Client's repeated CPT lines), and DemographyTab.tsx
// hit exactly this before switching its own drafts to row_id.
const [drafts, setDrafts] = useState<Record<number, string>>({})
const qc = useQueryClient()
@@ -238,7 +239,7 @@ export function ReviewPane({
// PDF order: page, then where the patient sits on it. line_index is each
// record's position on its page, set by build_field_rows. Sorting by name
// here used to put ANDERSON above the first patient on the sheet, so the
// here used to put a later surname above the first patient on the sheet, so the
// list no longer matched the document the reviewer had open beside it.
// Name is only the tie-break, for runs stored before line_index existed.
return [...byKey.values()].sort(
@@ -254,7 +255,7 @@ export function ReviewPane({
map.get(key)!.push(row)
}
for (const rows of map.values()) {
// Gulf Coast (Template 7) records keep the order the API sent — the flat
// Example Client (Template 7) records keep the order the API sent — the flat
// 20-column superbill layout, Ticket# through Units. Re-sorting by band
// would scatter it (that is what put ICD11 above ICD2 and CPT at the
// bottom). Every other template keeps worst-band-last, which is what the
@@ -280,7 +281,7 @@ export function ReviewPane({
// A field that was never queued (needs_review === false) has no review
// row until this moment on most templates — build_field_rows only emits
// a row when a value exists or the field is billing-critical, so a
// genuinely blank optional field (e.g. Gulf Coast's From DOS / To DOS /
// genuinely blank optional field (e.g. Example Client's From DOS / To DOS /
// Units, always null today) is addressed by the cell it occupies,
// line_index included, rather than by row_id.
if (row.needs_review === false) {
@@ -363,7 +364,7 @@ export function ReviewPane({
const discardAll = () => setDrafts(settledMap)
// Leaving a patient with typed-but-unsaved edits used to be silent — the old
// blur handler saved automatically, which is what produced the ARMSTRONG
// blur handler saved automatically, which is what produced the truncated-name
// corruption. Now nothing commits without Save, so leaving instead has to
// ask, or the edit is just lost with no signal either way.
const guardLeave = (): boolean => {
@@ -711,7 +712,7 @@ function PatientView({
<div className="flex flex-col gap-[9px]">
{/* Keyed on row_id — a real database identity from /all-fields
(SPB_Extraction.RowId), unique across every field on every page.
A page-and-field key would collide on Gulf Coast's repeated CPT
A page-and-field key would collide on Example Client's repeated CPT
lines, where two rows share the same (page, field). */}
{/* No entry animation. Rows are keyed by row_id, so every Next
remounts them all, and the old staggered fade (opacity 0 over
@@ -802,7 +803,7 @@ function PatientView({
* lost by making it editable.
*
* Nothing here commits on its own. An earlier version saved on blur, which is
* exactly how "ARMSTRONG, CHARLES T" got recorded as "\ONG, CHARLES T" — the
* exactly how "Doe, Jane A" got recorded as "\e, Jane A" — the
* moment focus left the box mid-keystroke, whatever half-typed text was there
* became the correction. Typing only updates the shared draft in ReviewPane;
* the patient-level Save bar (here and in PdfPane) is the one place an edit is
@@ -835,7 +836,7 @@ function FieldRow({
const corrected = row.corrected_value != null && row.corrected_value !== row.value
// While being edited the value takes its own full-width line. A DX field is
// five comma-separated codes and a provider name runs past twenty
// characters; in the shared row they were truncated to "ARMSTRONG, C", so a
// characters; in the shared row they were truncated to "Doe, J", so a
// reviewer was correcting a value they could not fully see. Expanding only
// on focus keeps the scan-many-fields-fast layout for reading.
const expanded = focused || dirty
@@ -938,7 +939,7 @@ function FieldRow({
/**
* A Gulf Coast ticket laid out the way its yellow note is: the note itself,
* A Example Client ticket laid out the way its yellow note is: the note itself,
* the page-level rules it fired, the visit, then one tab per encounter.
*
* Hovering a field lights the note line it came from. The page preview is an
@@ -1,3 +1,4 @@
/* EXAMPLE ONLY: an extract from the Superbill Review prototype, kept as reference for porting. ECW/eClinicalWorks, Tebra, 'Example Client', SPB_* tables and patient/ticket wording are that project's examples. Don't copy them into a new project. */
import { useMemo, useState } from 'react'
import { useQuery } from '@tanstack/react-query'
import { api } from '../api'
@@ -95,7 +96,7 @@ type Filter = 'all' | 'priced' | 'unmeasured' | 'failed'
/**
* api.roi() has no project filter — it totals every document. The ROI board
* is per-project (Gulf Coast's spend is not eClinicalWorks' spend), so the
* is per-project (Example Client's spend is not eClinicalWorks' spend), so the
* totals are recomputed here from the already-fetched runs instead of a new
* query param. Every field is a plain sum or count over RoiRun — nothing
* server-side is being second-guessed, just re-scoped to fewer rows.
@@ -138,7 +139,7 @@ export function RoiTab({
}: {
/** Absent on the demography board: its runs have no charge review to open. */
onOpenRun?: (jobId: string) => void
/** Which project's spend this board reports — Gulf Coast tickets and
/** Which project's spend this board reports — Example Client tickets and
* eClinicalWorks documents never share a total. */
project: Project
/** The Demography ROI (ticket 05): its own payload, one Gemini call per PDF
@@ -1,3 +1,4 @@
/* EXAMPLE ONLY: an extract from the Superbill Review prototype, kept as reference for porting. ECW/eClinicalWorks, Tebra, 'Example Client', SPB_* tables and patient/ticket wording are that project's examples. Don't copy them into a new project. */
import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query'
import { api } from '../api'
import { IconDownload } from './icons'
@@ -1,3 +1,4 @@
/* EXAMPLE ONLY: an extract from the Superbill Review prototype, kept as reference for porting. ECW/eClinicalWorks, Tebra, 'Example Client', SPB_* tables and patient/ticket wording are that project's examples. Don't copy them into a new project. */
import { useState } from 'react'
import type { ReactElement } from 'react'
import type { BatchStage, BoardTab } from '../types'
@@ -14,7 +15,7 @@ import { IconSpend, IconPage, IconLoop, IconIdCard, IconPatients } from './icons
* icons are" step from every navigation.
*
* Two projects, one rail: ECW's boards (templates 1-6) and Tebra's (template 7
* / Gulf Coast), each under its own group header. See project.ts for how a
* / Example Client), each under its own group header. See project.ts for how a
* batch or run is assigned to one or the other.
*
* Selection and drag-and-drop-to-move-stage behaviour are unchanged — only the
@@ -136,7 +137,7 @@ export function Sidebar({
tab="tebra-roi"
icon={IconSpend}
label="ROI Dashboard"
hint="What the Gulf Coast pipeline has cost, and what that bought"
hint="What the Example Client pipeline has cost, and what that bought"
active={tab === 'tebra-roi'}
onSelect={onTab}
/>
@@ -146,8 +147,8 @@ export function Sidebar({
dropStage="extraction"
dropTab="tebra-extraction"
icon={IconPage}
label="Gulf Coast Charge Extraction"
hint="Gulf Coast tickets: extract and clear the flagged fields"
label="Example Client Charge Extraction"
hint="Example Client tickets: extract and clear the flagged fields"
active={tab === 'tebra-extraction'}
n={counts.tebra.extraction}
onSelect={onTab}
@@ -159,8 +160,8 @@ export function Sidebar({
dropStage="automation"
dropTab="tebra-automation"
icon={IconLoop}
label="Gulf Coast Charge Automation"
hint="Gulf Coast batches that finished extraction and are ready to post"
label="Example Client Charge Automation"
hint="Example Client batches that finished extraction and are ready to post"
active={tab === 'tebra-automation'}
n={counts.tebra.automation}
onSelect={onTab}
@@ -1,3 +1,4 @@
/* EXAMPLE ONLY: an extract from the Superbill Review prototype, kept as reference for porting. ECW/eClinicalWorks, Tebra, 'Example Client', SPB_* tables and patient/ticket wording are that project's examples. Don't copy them into a new project. */
import { useCallback, useEffect, useRef, useState } from 'react'
const KEY = 'superbill.split'
@@ -1,3 +1,4 @@
/* EXAMPLE ONLY: an extract from the Superbill Review prototype, kept as reference for porting. ECW/eClinicalWorks, Tebra, 'Example Client', SPB_* tables and patient/ticket wording are that project's examples. Don't copy them into a new project. */
import { BAND_VAR } from '../bands'
import type { Run } from '../types'
@@ -1,3 +1,4 @@
/* EXAMPLE ONLY: an extract from the Superbill Review prototype, kept as reference for porting. ECW/eClinicalWorks, Tebra, 'Example Client', SPB_* tables and patient/ticket wording are that project's examples. Don't copy them into a new project. */
import { useEffect, useLayoutEffect, useRef, useState } from 'react'
import { createPortal } from 'react-dom'
@@ -1,3 +1,4 @@
/* EXAMPLE ONLY: an extract from the Superbill Review prototype, kept as reference for porting. ECW/eClinicalWorks, Tebra, 'Example Client', SPB_* tables and patient/ticket wording are that project's examples. Don't copy them into a new project. */
/**
* The icon set.
*
@@ -1,3 +1,4 @@
/* EXAMPLE ONLY: an extract from the Superbill Review prototype, kept as reference for porting. ECW/eClinicalWorks, Tebra, 'Example Client', SPB_* tables and patient/ticket wording are that project's examples. Don't copy them into a new project. */
@import 'tailwindcss';
/* Manual dark mode: Tailwind v4 defaults `dark:` to the OS preference, but this
@@ -1662,7 +1663,7 @@ textarea,
.sb-brand-name { background-position: 0 0; }
}
/* ── Office Location (a Gulf Coast ticket's yellow note) ──────────────────────
/* ── Office Location (a Example Client ticket's yellow note) ──────────────────────
The note is amber because it IS amber on the page; everything else stays on
the neutral surfaces. No brand ramp here -- it is reserved for its six
things (DESIGN.md, "The One Loud Colour Rule"). */
@@ -1,4 +1,5 @@
<!doctype html>
<!-- EXAMPLE ONLY: an extract from the Superbill Review prototype, kept as reference for porting. ECW/eClinicalWorks, Tebra, 'Example Client', SPB_* tables and patient/ticket wording are that project's examples. Don't copy them into a new project. -->
<html lang="en">
<head>
<meta charset="UTF-8" />
@@ -1,3 +1,4 @@
/* EXAMPLE ONLY: an extract from the Superbill Review prototype, kept as reference for porting. ECW/eClinicalWorks, Tebra, 'Example Client', SPB_* tables and patient/ticket wording are that project's examples. Don't copy them into a new project. */
import { createContext, useContext, useEffect, useState } from 'react'
/**
@@ -1,3 +1,4 @@
/* EXAMPLE ONLY: an extract from the Superbill Review prototype, kept as reference for porting. ECW/eClinicalWorks, Tebra, 'Example Client', SPB_* tables and patient/ticket wording are that project's examples. Don't copy them into a new project. */
import type { Band } from './bands'
/**
@@ -21,7 +22,7 @@ export type Project = 'ecw' | 'tebra'
* stage a card can be dropped into.
*
* Two projects live in one rail: the ECW boards (templates 1-6) and the Tebra
* boards (template 7 / Gulf Coast). Tebra ids are prefixed because a bare
* boards (template 7 / Example Client). Tebra ids are prefixed because a bare
* 'extraction' can no longer identify a board on its own — see project.ts for
* the tab -> (project, stage) mapping.
*/
@@ -118,7 +119,7 @@ export interface ReviewRow {
patient: string | null
/**
* 0 for every template except one that can carry more than one row per
* (page, patient, field) — Gulf Coast's repeated CPT lines, one per coder
* (page, patient, field) — Example Client's repeated CPT lines, one per coder
* annotation on the same ticket.
*/
line_index: number