Files
Rpa_Skills/tests/evals/results/handoff/h-web-portal-screens-r1.md
T
VasanthandClaude Opus 5.5 3942fad6cd Add rpa-bot-handoff skill: ops guide for bot handover
The skill scans a bot with subagents (never runs it) and writes
HANDOVER.md, an 11-section ops guide in the operator's order: where is
what, how to run, how long to wait, after the run, how to see an
exception, exception list, how you will know, how to tell us, don'ts,
issues seen before. Dev material (check against 12 failure classes from
Tebra Auto Post, gaps with file:line, incidents) goes to HANDOVER-DEV.md.

Also adds ADR-0004, glossary terms, five fixture bots and a handoff eval
runner (--resume, --regrade) with results from 47 runs of the earlier
13-section version. The grader still expects that structure and must be
updated before the next eval run.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-28 15:01:42 +05:30

185 lines
20 KiB
Markdown

# Payer portal downloader - ops handover
Version: none (the bot has no version number, see section 10) · Written 2026-10-23 · Escalation: raise a ticket in the **RPA Support** queue
## 1. What the bot does
Every day at 07:00 (Windows Task Scheduler) the bot signs in to the payer web portal and downloads the remittance report of each provider as a CSV file. It reads the input Excel `data/input/providers.xlsx`: the portal username and password are on the **Login** sheet, and the providers are on the **Providers** sheet with their NPI, name and active flag. It produces one CSV per provider in `data/downloads/`, and one result workbook, `data/output/Download_Report_<YYYYMMDD>.xlsx`, with a Status and a Remarks column for each provider. When the report page fails to load it saves a screenshot to `data/screens/<NPI>.png`. The only app it drives is **Google Chrome**: it opens its own Chrome window.
## 2. How it works
```
Windows Task Scheduler (07:00 daily)
└─ starts → bot (no window of its own) ──drives──> its own Chrome window → payer web portal
│ (do not touch this window while it runs)
├─ reads → data/input/providers.xlsx
├─ writes → data/downloads/*.csv (one CSV per provider)
├─ writes → data/screens/<NPI>.png (only when a page did not load)
├─ writes → data/output/Download_Report_<YYYYMMDD>.xlsx
└─ writes → logs/bot.log (ops cannot open this)
```
- **Task Scheduler** starts the bot every morning. You will not see a bot window, only Chrome.
- **The bot** works through the Providers sheet from top to bottom, one provider at a time.
- **The Chrome window** is opened and closed by the bot. Any click in it can break the run.
- **The output workbook** is the place where ops checks the result. It is written once, at the end of the run.
- **The log** records one line per provider and the re-logins. Only the dev team can read it.
**One run, step by step:**
1. Read the input Excel: the login details and the list of providers.
2. Open Chrome and sign in to the portal. If the sign-in fails, every provider is marked Login Failed and the run ends.
3. For each provider: open the provider's remittance page.
4. If the portal sent the bot back to the sign-in page, sign in again and retry the provider.
5. Wait for the report grid. If the page says there are no results, the provider is marked No Data.
6. Click the CSV export and wait for a new CSV file to appear in `data/downloads/`.
7. Write the provider's row to the output workbook and go to the next provider.
8. Close Chrome and save `Download_Report_<YYYYMMDD>.xlsx`.
## 3. Before a run
- [ ] Google Chrome is installed on the machine.
- [ ] These folders exist next to the bot: `logs`, `data/input`, `data/downloads`, `data/screens`, `data/output`. The bot does not create any of them.
- Without `logs`, the bot stops before doing anything.
- Without `data/output`, no report is saved (E02).
- Without `data/screens`, screenshots are lost without any message.
- [ ] The input file is at `data/input/providers.xlsx` and still has the sheet names **Login** and **Providers**.
- [ ] **Login sheet:** username in A2, password in B2. When the portal password changes, update B2, or the next run gives Login Failed for everyone (E01).
- [ ] **Providers sheet**, one provider per row, starting at row 2: column A = NPI, B = provider name, C = active flag.
- Every row needs an NPI in column A. A row with column A empty is dropped without a message (E10).
- Good: `1234567890 | Example Clinic | Y`. Bad: `(empty) | Example Clinic | Y`.
- [ ] **Active flag:** to skip a provider, put a capital **N** in column C, and nothing else.
- Good: `N`.
- Bad: `n`, `No` or `N ` (with a trailing space). The bot treats these as active and downloads the provider (E09).
- [ ] Don't run the bot twice on the same day unless you mean to. A second run replaces that day's report and downloads every CSV again (E11).
- [ ] You can't check which version is running (see section 10).
## 4. During a run
- Don't click, type in, or close the Chrome window the bot opened.
- Don't copy, move or open files in `data/downloads/` while the bot runs. The bot counts **any** new CSV appearing there as the current provider's download (E08).
- **To stop the bot:** close the Chrome window it opened.
- The run then ends after at most about a minute, and the report is saved with the providers done so far. The rest are missing (E03).
- This is our best reading of the code. It has not been tested.
- There is no Stop button.
- **A run looks stuck** when the Chrome window stays on the same page for more than 10 minutes.
- Each step normally gives up by itself within 60 seconds.
- There is no watchdog, so a page that never finishes loading can hold the run.
- In that case, stop the bot as described above and raise a ticket.
## 5. Where to look when something goes wrong
Ops can open the output files and folders below. The log file and Task Scheduler history are for the dev team only.
| Question | Where to look |
|---|---|
| Did the run finish? | `data/output/` has `Download_Report_<today's date>.xlsx`, and it has one row per provider in the input. No file means E02. Fewer rows means E03. |
| Which providers failed? | Report workbook, **Status** column: red cells (Error), and **Login Failed** (no colour). Also check every **Downloaded** row whose Remarks say "portal maintenance - no file" (E04). |
| Why did one provider fail? | The **Remarks** column on the same row. For "Report grid did not load", open `data/screens/<NPI>.png`. |
| Is the CSV there? | `data/downloads/`. Files keep the portal's own names, not the provider's, so you can't tell from the file name which provider a file belongs to. |
| Did the bot already retry? | It retries only after the portal signs it out, and you can only see this in the log. If the Remarks say "Session expired", it already tried 3 times. |
| Which version is running? | You can't check this (section 10). |
## 6. Statuses
The colour is the fill of the Status cell in the report workbook.
| Status | Remarks | Colour | Meaning | What ops does |
|---|---|---|---|---|
| Downloaded | Report saved | green | A new CSV appeared in `data/downloads/` after the export click | Nothing. If the CSV count looks wrong, see E08. |
| Downloaded | portal maintenance - no file | green | **Nothing was downloaded.** The portal showed a maintenance banner. | **Needs follow-up.** Treat it as not downloaded and get it re-run after the maintenance window (E04). |
| No Data | No remittances in the date range | green | The portal shows no remittances for this provider in its default date range | Nothing |
| Skipped - inactive provider | Marked N in the input | green | Column C had `N`, so the bot did not open this provider | Nothing, unless the provider should be active |
| Error | Report grid did not load | red | The report page did not appear within 30 s | E05 |
| Error | Download did not finish | red | No new CSV appeared within 60 s after the export click | E06 |
| Error | Session expired | red | The portal kept signing the bot out, 3 times in a row for this provider | E07 |
| Login Failed | Check the portal username/password | **no colour** (white) | The first sign-in failed. Every provider gets this row and nothing is downloaded. | E01 |
## 7. Exception catalogue
| ID | What you see | How the bot identifies it | Where it is recorded | Type | Who acts | What to do | Escalate when |
|---|---|---|---|---|---|---|---|
| E01 | Every row says **Login Failed** - "Check the portal username/password" (no colour) | After clicking Sign in, it waits 30 s for the portal dashboard. If the dashboard never appears, it stops. A wrong password and a slow portal look the same. | Report workbook, every row. Nothing is in the log. | Business or System | Ops | Sign in to the portal by hand with the Login sheet details. If they fail, fix the password in the Login sheet (B2). If they work, the portal was slow, so request a re-run. | The details work by hand but the next run fails again. Send: report file name, run date. |
| E02 | No `Download_Report_<today>.xlsx` in `data/output/` | Nothing. The bot stopped before it could save: a missing folder, missing input file, Chrome would not start, or the output folder is missing. | Nowhere ops can see. Only the dev team can see it, in Task Scheduler history. | System | Dev | Check the folders listed in section 3 exist, and that the input file is in place. | Always. Send: run date and time, and which folders exist under `data/`. |
| E03 | The report has **fewer rows** than the input. The last providers are missing, with no Error row. | Nothing. An unexpected problem stopped the whole run: the sign-in page or the export button changed, a re-login after a sign-out failed, or the Chrome window was closed. The report is saved with the rows done so far. | Missing rows in the report. The cause is not in the report or the log. | System | Dev | Note the first missing provider. A re-run redoes **all** providers and replaces today's report (E11). | Always. Send: report file name, the first missing provider's NPI, run time, and whether anyone touched Chrome. |
| E04 | **Downloaded** (green) with Remarks "portal maintenance - no file" | The portal page showed a maintenance banner. The bot writes Downloaded and moves on, without retrying. | Report workbook | System | Ops | **No file was downloaded**, although the row is green. Re-run after the portal maintenance ends, then check the row again. | Every provider shows it for 2 days in a row. Send: report file names. |
| E05 | **Error** - "Report grid did not load" | It waits 30 s for the report grid on the provider's page. It does not retry. | Report workbook, plus a screenshot `data/screens/<NPI>.png` | System | Ops | Open the screenshot. If it shows a portal error or a slow page, request a re-run. If it shows a page you don't recognise (a changed layout, or a new prompt), escalate. | The same provider fails on 2 runs in a row. Send: report file name, NPI, screenshot. |
| E06 | **Error** - "Download did not finish" | After clicking Export it checks `data/downloads/` every second for 60 s. No new CSV appeared. No screenshot is taken. | Report workbook | System | Ops | The file may have arrived late. A late file can be counted as the **next** provider's download (E08). Check the next provider's row, and request a re-run. | It happens on several providers in one run, or on the same provider twice. Send: report file name, NPIs, run time. |
| E07 | **Error** - "Session expired" | The portal sent the bot back to the sign-in page. It signed in again and retried, 3 times in total for this provider. | Report workbook. The re-logins appear only in the log. | System | Bot, then Ops | The bot already retried. Request a re-run. | It happens on 2 runs in a row. Send: report file name, NPI, run time. |
| E08 | A provider shows **Downloaded - Report saved** but its CSV is missing, or the CSV holds another provider's data. Or the number of CSVs doesn't match the number of Downloaded rows. | The bot counts **any** new CSV in `data/downloads/` as the current provider's download. Files are not named per provider. | Not recorded. The row looks green and normal. | System | Dev | Don't trust the CSV-to-provider match for that run. Note which providers look wrong. | Always. Send: report file name, run date, the list of CSV files with their times. |
| E09 | A provider marked inactive was downloaded anyway | Only a capital `N` in column C counts as inactive. `n`, `No` and `N ` are treated as active. | Report workbook: the row is not "Skipped - inactive provider" | Business | Ops | Change column C to exactly `N`. | Never - this is an input fix. |
| E10 | A provider from the input is missing from the report, while the rows after it are present | A row with an empty NPI (column A) is dropped without a message. | Not recorded | Business | Ops | Fill in the NPI in column A and re-run. | The NPI is filled in and the row is still missing. |
| E11 | Duplicate CSVs such as `name (1).csv`, or this morning's report changed | A second run on the same day downloads every CSV again (Chrome adds "(1)", "(2)") and **replaces** that day's report file. | `data/downloads/` and `data/output/` | System | Ops | Copy the day's report somewhere else before a same-day re-run. Use the newest copy of each CSV. | Never, unless files are missing. |
## 8. What the bot recovers by itself
| Problem | What the bot does | Limit | After the limit |
|---|---|---|---|
| Portal signs the bot out | Signs in again immediately and retries the provider | 3 tries per provider, no pause between them | Row = Error "Session expired", next provider. If one of these re-logins fails, the whole run stops (E03). |
| Sign-in at the start | Waits for the dashboard | 30 s, no retry | Every row = Login Failed, run ends (E01) |
| Report page slow | Waits for the grid | 30 s, no retry | Row = Error "Report grid did not load", next provider |
| CSV slow to download | Checks the downloads folder every second | 60 s, no retry | Row = Error "Download did not finish", next provider |
| Portal maintenance | Nothing | - | Row = Downloaded "portal maintenance - no file" (E04) |
| Run stuck, or crashed | Nothing: no watchdog, no restart, no resume | - | Ops stops it (section 4) and escalates. A re-run starts again from the first provider. |
## 9. Known incidents
There is no change history, bug log or release notes for this bot. The only trace of past runs is the log, which shows one run.
| When / version | What ops saw | Cause | What to do now | Ops could handle? |
|---|---|---|---|---|
| 2026-09-02 / no version | One provider in Error, right after the portal signed the bot out and it signed in again | The log does not record why. The timing fits "Report grid did not load" or "Download did not finish". | Follow E05 / E06 | Partly |
## 10. Releases and version check
- How an update arrives: there is no updater. A developer replaces the bot's files on this machine.
- How to confirm it applied: you can't. The bot has no version number in its files or its output.
- If you suspect an old build: raise a ticket, and ask the dev team to confirm which files are on the machine.
## 11. Escalating to dev
Raise a ticket in the **RPA Support** queue. Send:
- the run date and time
- the exception ID from section 7
- the report file name (`Download_Report_<YYYYMMDD>.xlsx`)
- the NPIs of the affected providers
- the screenshot from `data/screens/`, if there is one
- whether anyone touched the machine or the Chrome window during the run
Never send: the portal password, the Login sheet, `config.yaml`, the CSV contents, or patient data in chat or in the ticket text.
## 12. Failure-class check
- **F1** Missing prerequisite on the ops machine: covered in section 3 (Chrome, folders, input file and sheet names) and E02.
- **F2** Wrong window or focus: covered in section 4. The bot drives its own Chrome window by handle and does not match windows by title, so the only risk is someone touching that window or its downloads folder (E08).
- **F3** Target slower or different than expected: covered in E01, E05, E06 and E03 (a changed page layout), with the limits in section 8.
- **F4** Input read differently than ops writes it: covered in section 3 input rules, E09 and E10.
- **F5** Marked done when nothing was done: covered in E04 and E08, and Fix before handover #1 and #2.
- **F6** Action happened but not confirmed: covered in E06. A late CSV is not recorded and can be credited to the next provider. The bot only reads from the portal, so a re-run cannot double-post anything, but it does duplicate files (E11).
- **F7** Business exception shown as success: covered in section 6 ("portal maintenance" shown as green Downloaded), E04, and Fix before handover #1.
- **F8** Endless re-runs or watchdog: covered in section 8. There is no re-run loop. There is also no watchdog, so a hang is covered in section 4 and Fix before handover #13.
- **F9** Stopping the bot the wrong way: covered in section 4 (close the bot's Chrome window) and Fix before handover #13.
- **F10** One stuck item blocks the queue: not applicable. There are no batches, queues or locks. Each run is independent, and a failed provider never blocks another one or the next day's run.
- **F11** Cause hidden from ops: covered in section 5, and Fix before handover #3, #4, #5 and #6. The log and the crash messages are outside ops access.
- **F12** Update didn't arrive or old build: covered in section 10 and Fix before handover #14. There is no version number and no updater. The bot writes nothing shared on start.
## 13. Fix before handover (dev team)
| # | Gap | Why it hurts ops | Where (file:line) |
|---|---|---|---|
| 1 | A maintenance banner is recorded as `Downloaded` (green) with no file | Ops believes the report was fetched | `bot.py:54-55` |
| 2 | Any new `*.csv` in the downloads folder counts as success for the current provider, and files are never renamed or linked to the NPI | A late download is credited to the wrong provider, and CSVs can't be matched to providers | `bot.py:63-68`, `bot.py:80` |
| 3 | `Login Failed` rows get no fill (the RED colour is never applied on that path) and are not logged | They don't stand out in the report, and there is no trace in the log | `bot.py:88-91`, `bot.py:27-28` |
| 4 | Unhandled errors end the run with no row for the current or remaining providers. The traceback goes to stderr only, not to `bot.log`. | Ops sees missing rows with no reason (E03) | `bot.py:41-43`, `bot.py:64`, `bot.py:102`, `bot.py:85-110` |
| 5 | Chrome start-up and input loading happen before the `try`/`finally`. A missing `data/output` folder makes the save in `finally` fail and hides the original error. | No report at all, and no reason (E02) | `bot.py:75-81`, `bot.py:110` |
| 6 | Remarks are not written to the log, and the log is outside ops access | The reason for an Error is only in the report, and the retries can't be seen | `bot.py:105`, `bot.py:101` |
| 7 | Folders are not created (`logs`, `data/downloads`, `data/screens`, `data/output`). A screenshot save into a missing folder fails silently. | The bot stops at start-up, or loses evidence | `bot.py:30`, `bot.py:59`, `bot.py:110` |
| 8 | Session-expiry retry: `RELOGIN_TRIES = 2` gives 3 tries and 3 re-logins (the last one is wasted), with no pause between tries | The retry limit is misleading, and it hammers the portal | `bot.py:24`, `bot.py:96-104` |
| 9 | The sign-in failure can't tell a wrong password from a slow portal | Ops changes a password that was correct | `bot.py:44-47` |
| 10 | No retry on a grid timeout or a download timeout. A screenshot is taken only for a grid timeout. | Short portal hiccups become Errors, and download failures leave no evidence | `bot.py:56-70` |
| 11 | The active flag matches only an exact `"N"` (no trimming, case-sensitive) | Providers ops meant to skip are downloaded | `bot.py:77` |
| 12 | Rows with an empty NPI are dropped silently. A same-day re-run overwrites the report and duplicates CSVs. | Missing providers and lost reports go unnoticed | `bot.py:78`, `bot.py:110` |
| 13 | There is no watchdog, no page-load timeout and no Stop button | A hung page holds the run indefinitely, and the only way to stop it is to close Chrome | `bot.py:51`, `bot.py:81` |
| 14 | No version string anywhere, and no update mechanism | Ops can't confirm which build runs | whole repo |
| 15 | Portal credentials are stored in plain text in the input Excel. An unused `api_token` sits in plain text in `config.yaml`. Provider names are written to the log. | Secrets and identifiers are exposed to anyone with folder access | `bot.py:76`, `config.yaml:2`, `bot.py:105` |
| 16 | Every run writes an unexplained `BOT_WAS_RUN` marker file in the bot folder | Unclear purpose, and leftover clutter | `bot.py:74` |