2026-07-28 · continues the 2026-07-23 evaluation at excel-arithmetic-malfeasance
The canonical file is QuestionAudit_PowerBI_TIMED_ONLY_2026-07-23.xlsx: 122
interactions, every one carrying a coach, an agent, a date, an asked time and an answered
time. It is built by one command from a 154-row head file. 107 rows pass the gate directly, 15 are
hand-read from Teams captures, and 47 are dropped and listed by name because no
source on disk holds their times. 107 plus 47 equals the 154 that went in, so nothing vanished
quietly. Median answer time across the 122 is 5 minutes, mean 8.7, 90th percentile
16, slowest 75.
The original evaluation named mixed-type columns as the defect most likely to make a Power BI dashboard misreport timing. That exact defect had come back in the file shipped yesterday, through the code path that appends hand-read Teams rows.
| Defect | What was in the shipped file | Fix |
|---|---|---|
| Mixed-type completeness column was live |
Complete Timing held the string "Complete" on 107 rows and the
boolean True on the 15 appended rows. Power BI type inference splits on that. |
Appended rows now write the same string the head uses. One vocabulary, one type. |
| Stale "No timing" label was live |
One row (Toveta Jenkins, 7/21, Reshmi Saravanan) read No timing while carrying
11:05 to 11:08 and a computed 3 minutes. The label came in on the head row and was never
recomputed. |
Every kept row passed the four-field gate, so the builder now stamps the completeness label itself instead of trusting what arrived. |
| Blank composite datetime was live |
Asked (Date & Time) was empty on all 16 appended rows. Any Power BI visual
sorting or joining on that column silently drops them. |
Rebuilt from the normalized time on every row, so the composite can never disagree with
Time Asked. Verified: 0 blanks, 0 disagreements. |
A generalized type check runs on every build: if any client column carries two Python types across the kept rows, the gate fails and names the column. That check is what caught the boolean, and it would have caught it yesterday. A second check reports category labels that look like one concept under two names. It reports them and does not merge them, because collapsing two client category names is a data decision, and guessing one is the behavior this audit exists to catch.
type check: 0 mixed-type columns (clean)
category check: 2 label collision group(s) -> [['DDE (admin)', 'DDE / DDF Removal'],
['Coach Stamp / OSHA', 'Coach Stamp / OSHA 500']]
recovered=5 kept=122 (from head 107 + appended 15) removed=47 GATE=PASS
reconcile: 107 kept-from-head + 47 removed = 154 (== rows_in 154: True)
39 of the 122 rows are labeled Video OCR (pending verification) with confidence
OCR. The extraction rules for this audit state plainly that 720p screen-recording video
resolves claim IDs and reads times unreliably, with 11:17 coming through as "141Z", and that
upscaling does not fix it. All 39 of those rows fall on 2026-07-22.
Those rows run systematically slower than the verified ones: median 8 minutes against 4, mean 12.3 against 7.0. Whether that gap is real workload or OCR misreads is not decidable from the file. The gap is large enough that any conclusion about 7/22 rests on it.
The distribution of that unverified source across coaches is uneven, which is what makes it a ranking problem rather than a rounding problem:
| Coach | Rows | From video OCR | Share | Exposure |
|---|---|---|---|---|
| Margarita Rosa Del Valle | 29 | 19 | 66% | |
| Raushanah Muro | 19 | 7 | 37% | |
| Fabian Andres Sierra | 13 | 5 | 38% | |
| Tami Bales | 29 | 5 | 17% | |
| Toveta Jenkins | 32 | 3 | 9% |
Two thirds of Margarita's record comes from the unverified source and under a tenth of Toveta's does. Comparing the two on this file compares capture method as much as it compares coaching. The 47 open rows sit mostly on the same day, 40 of 47 on 7/22, so 7/22 is the day to finish before anyone quotes a per-coach number.
Left block is all 122 rows. Right block drops the 39 video-OCR rows and reports only what came off verified captures. Both are honest; they answer different questions.
| Coach | All 122 rows | Verified rows only (83) | ||||||
|---|---|---|---|---|---|---|---|---|
| n | Median | Mean | Max | n | Median | Mean | Max | |
| Toveta Jenkins | 32 | 3.0 | 6.6 | 75 | 29 | 3.0 | 7.0 | 75 |
| Tami Bales | 29 | 3.0 | 9.1 | 60 | 24 | 2.0 | 5.8 | 29 |
| Margarita Rosa Del Valle | 29 | 6.0 | 8.2 | 44 | 10 | 5.5 | 6.1 | 13 |
| Raushanah Muro | 19 | 8.0 | 13.7 | 73 | 12 | 6.5 | 12.0 | 73 |
| Fabian Andres Sierra | 13 | 6.0 | 6.8 | 19 | 8 | 4.0 | 4.8 | 15 |
Every coach reads faster on verified rows alone. Margarita's sample drops from 29 to 10 and her mean falls from 8.2 to 6.1, which is the clearest reason to finish the 7/22 captures before publishing a leaderboard. The original evaluation flagged an unstable ranking built on a sample of two. The sample sizes are healthier now; the provenance is what is still soft.
All 122 timed rows, minutes from agent question to substantive coach answer.
| Answer time | Rows | Share | |
|---|---|---|---|
| 0 to 2 min | 37 | 30% | |
| 3 to 5 min | 26 | 21% | |
| 6 to 10 min | 27 | 22% | |
| 11 to 20 min | 23 | 19% | |
| 21 to 30 min | 3 | 2% | |
| Over 30 min | 6 | 5% |
Just over half of all questions come back inside 5 minutes. The tail is thin: 9 rows of 122 run past 20 minutes, and the slowest is 75. Volume by day: 7/20 has 1 row, 7/21 has 39, 7/22 has 58, 7/23 has 19, 7/24 has 5. The 7/22 peak is also the day carrying every unverified row and 40 of the 47 gaps, so its shape is the least settled.
TBFA and Medical-Indemnity validation is 50 of 122 rows, 41% of everything asked. Lost Time and TAW is 16. After those two, no category clears 10. The long tail runs: Claim Handling 10, DDE/DDF Removal 9, Companion Claims 8, 301 Field 7, Technical/Access/VA 5, then eight categories with 3 or fewer. Two of those small labels are the collision pairs named above, so the true tail is slightly shorter than 16 labels suggests.
The 2026-07-23 evaluation found no malfeasance and 14 named defects. Each one re-run against today's canonical file.
| ID | Original defect | Status | Evidence today |
|---|---|---|---|
| E1 | Mixed-type timing column | Fixed | Answer Time (min) is int on all 122. A boolean recurrence in Complete
Timing was found and fixed today, and a type gate now blocks it. |
| E2 | Escalations undercounted by unlabeled slow rows | Fixed | 10 rows run 20 minutes or longer. All 10 carry a speed label. 0 blanks. |
| E3 | Ranking unstable on tiny samples | Partly | Smallest coach sample rose from 2 to 13. Provenance imbalance replaced sample size as the reason a ranking is still soft. See section 3. |
| E4 | Headline volume stated eight ways | Fixed | One gate-passing file. Every count on this page comes from it and reconciles: 107 + 47 = 154. |
| E5 | Missing date defaulted to a guess | Fixed | No default exists in the builder. A row without a date is dropped and listed by name. |
| E6 | Master led with its least-verified number | Fixed | The 318-row master is retired. The verified split is stated before any headline here. |
| E7 | Day column frozen to Today/Yesterday | Fixed | Date is a real datetime on all 122 rows, spanning 7/20 to 7/24. |
| E8 | Two clock formats merged as one | Fixed | 0 of 122 rows deviate from 24-hour HH:MM. Checked by regex on the saved file. |
| E9 | Category vocabularies do not align | Open | 16 labels, 2 confirmed collision pairs. Reported on the Build Notes sheet as a decision, deliberately not auto-merged. |
| E10 | Duplicate handling inconsistent | Fixed | Append dedupes on claim ID plus asked time. Re-running is safe: 1 duplicate skipped on the last run. |
| E11 | Scorecard undercounted a coach by one row | Fixed | No separate scorecard exists. Per-coach counts are computed from the row set at read time. |
| E12 | Scorecard "Questions" column tied to nothing | Fixed | Same reason. The derived sheet that carried it is gone. |
| E13 | Core minute math correct | Holds | Recomputed independently from the saved times: 0 errors across 122 rows. |
| E14 | Forty near-identical files, no source of truth | Partly | One canonical file is named and reproducible from one command. The historical files still sit in the same folders and none is deleted. |
Ten fixed, two partly, one open, one holding. The malfeasance verdict from 7/23 is unchanged: the arithmetic was correct then and is correct now. What has changed is that the numbers are now reproducible from a single command with a stated gate, and that where evidence is thin the file says so instead of averaging it away.
These are interactions that exist and are missing a clock reading. They are named individually in
QuestionAudit_CAPTURE_WORKLIST_2026-07-27.xlsx with the Teams chat to open for each.
None of them overlap the claims already covered by the 7/23 and 7/24 captures, so they need their
own screenshots.
| Coach | Rows to capture | |
|---|---|---|
| Margarita Rosa Del Valle | 20 | |
| Tami Bales | 14 | |
| Toveta Jenkins | 5 | |
| Fabian Andres Sierra | 4 | |
| Raushanah Muro | 4 |
By date: 40 fall on 7/22, 5 on 7/21, 2 on 7/23. By gap: 30 are missing both times, 15 are missing only the asked time, 2 are missing only the answer. The 15 missing only an asked time are the cheapest to close, since the answer is already recorded and the question sits directly above it in the thread.
Transcribe what the capture shows into teams_reads.jsonl, one JSON object per line,
then re-run the build. A row whose claim ID and asked time already exist is skipped, so re-running
never duplicates. A row missing any of date, coach, asked or answered is skipped rather than
guessed. That path is how the last 15 rows joined.
{"date":"2026-07-22","agent":"John Zapata Rodriguez","coach":"Tami Bales",
"claim":"ARRAIAL, ANTONIO","claim_id":"2805522671","asked":"10:54","answered":"11:13",
"question":"","answer":"","type":"Lost Time / TAW",
"source":"Teams screenshot 7-22 (verified)"}
python3 ~/.claude/skills/question-response-audit/build_audit.py \ --head ~/Projects/_outputs/audit/QuestionAudit_COMPLETE_2026-07-23.xlsx \ --append-jsonl ~/Projects/_outputs/audit/teams_reads.jsonl \ --out ~/Downloads/QuestionAudit_PowerBI_TIMED_ONLY_2026-07-23.xlsx
| File | Role |
|---|---|
| QuestionAudit_PowerBI_TIMED_ONLY_2026-07-23.xlsx | Canonical. 122 rows, gate passing, 0 mixed-type columns. Quote timing from
this file only. In ~/Downloads/ and ~/Projects/_outputs/audit/. |
| QuestionAudit_COMPLETE_2026-07-23.xlsx | Head input, 154 rows, sha256 prefix 30f28c059a6b2a55. Read only. |
| QuestionAudit_CAPTURE_WORKLIST_2026-07-27.xlsx | The 47 open rows, sorted by coach, with the Teams chat to open for each. |
| teams_reads.jsonl | Hand-read Teams times, 16 lines. Append-only. Also indexed as a time source, so a hand-read can rescue a dropped head row by claim ID. |
| build_audit.py | The engine. Four-field gate, time recovery, type check, category collision report, Build Notes reconciliation. |
| backups/2026-07-28-pre-typefix/ | Yesterday's version of the canonical file, kept intact. Nothing deleted. |
QuestionAudit_PowerBI_TIMED_ONLY_2026-07-23.xlsx with openpyxl at build time and
verified against an independent recount of the saved file. The prior evaluation is at
excel-arithmetic-malfeasance.