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>
21 KiB
Payer portal downloader - ops handover
Version: not versioned (see section 10) · Written 2026-10-23 · Escalation: RPA dev team, Teams channel #rpa-support
1. What the bot does
Every day at 07:00 Windows Task Scheduler starts the bot. It signs in to the payer web portal and downloads the remittance report (a CSV file) for each provider listed in the input Excel file, data/input/providers.xlsx. It skips providers marked as inactive. When it finishes it writes a result report with one row per provider, showing a status and a remark. The only thing it drives is a Google Chrome window that it opens itself. There is no app window, no database and no email or alert.
2. How it works
Windows Task Scheduler (07:00 daily)
└─ starts → bot script ──drives──> its own Chrome window → payer web portal
│ (do not touch or close while it runs)
├─ reads → data/input/providers.xlsx (Login + Providers sheets)
├─ writes → data/downloads/*.csv (the downloaded reports)
├─ writes → data/screens/<NPI>.png (screenshot when a page didn't load)
├─ writes → data/output/Download_Report_<YYYYMMDD>.xlsx (result per provider)
└─ writes → logs/bot.log (one line per provider, all runs in one file)
- Task Scheduler starts the run. Nobody has to click anything.
- The bot script runs in the background and does all the work.
- The Chrome window is opened and controlled by the bot. Chrome shows a bar saying it is being controlled by automated software.
- providers.xlsx is the input. Ops maintains it.
- data/downloads receives the CSV files with Chrome's own file names. They are not renamed per provider.
- data/screens holds a screenshot named after the provider's NPI. One is taken only when the report page didn't load.
- Download_Report_.xlsx is the main place to check results. It has the columns Provider, NPI, Status and Remarks.
- logs/bot.log gets one line per provider, plus a warning each time the bot had to sign in again.
One run, step by step:
- Read the input file: the login details and the provider list.
- Open Chrome and sign in to the portal. The bot waits up to 30 s for the portal dashboard.
- For each provider, in input order:
- inactive → mark "Skipped" and move on;
- otherwise → open the provider's remittance page;
- wait up to 30 s for the report grid;
- click Export CSV;
- wait up to 60 s for a new CSV file to appear in
data/downloads.
- Write the provider's status to the result report and the log, then move to the next provider.
- Close Chrome and save the result report. The report is saved even if the run stopped early, unless the output folder is missing.
3. Before a run
- Google Chrome is installed on the machine.
- Python packages are installed: selenium, openpyxl and pyyaml.
- These folders exist in the bot's folder. The bot does not create them:
logs- without it, the bot fails at start and writes nothing at all;data/output- without it, the result report cannot be saved;data/downloads- the CSV files go here;data/screens- without it, screenshots are lost silently.
- The settings file
config.yamlis in the bot's folder and holds the portal address. - Input file - sheet
Login:- cell A2 holds the portal username;
- cell B2 holds the portal password;
- when the portal password changes, update B2 the same day.
- Input file - sheet
Providers:- data starts at row 2, one provider per row;
- column A is the NPI, column B the provider name, column C the active flag;
- a row with an empty column A is ignored silently, so never leave the NPI blank.
- Active flag in column C: only a capital
Nmarks a provider inactive. Anything else, including a blank, means active.- Bad:
n,No,N(with a space),Inactive. The bot will try to download these providers. - Good:
N.
- Bad:
- Need a second run on the same day? Copy that morning's
Download_Report_<today>.xlsxsomewhere safe first. A second run replaces it, downloads every provider's CSV again, and Chrome saves the duplicates asname (1).csv. - Version: there is no version number yet (see section 10).
4. During a run
- Don't touch the Chrome window the bot opened. Don't click in it, close it or sign out of the portal in it. You can use the rest of the machine; the bot doesn't use the mouse or keyboard.
- Don't sign in to the portal with the same username anywhere else during the run. The portal may end the bot's session (see E05).
- To stop the bot: close the Chrome window the bot opened (the one with the "controlled by automated software" bar).
- The bot stops and normally saves the result report with the providers finished so far.
- Ending the task in Task Scheduler also stops it, but then no report is written, and Chrome may stay open. Close Chrome by hand afterwards.
- A run looks stuck when
logs/bot.loggets no new line for more than 10 minutes. One provider takes at most about 5 minutes, even with every retry.- The bot has no watchdog: a page that never finishes loading can hang it forever.
- If it is stuck, stop it as described above and raise it with dev (E04).
5. Where to look when something goes wrong
| Question | Where to look |
|---|---|
| Did the run finish? | data/output/Download_Report_<today>.xlsx exists and has one row per provider in the input (blank-NPI rows excluded). Fewer rows means the run stopped early (E04). No file at all: see E03. |
| Which providers failed? | The result report, Status column: red Error rows, uncoloured Login Failed rows. Also check green rows whose Remarks say "portal maintenance - no file" (E08). |
| Why did one provider fail? | The result report, Remarks column for that NPI. For "Report grid did not load", open data/screens/<NPI>.png. |
| Did the bot already retry? | logs/bot.log: lines saying "session expired, re-login 1/2/3" just before that provider's line. No such lines means no retry: only an expired session is retried. |
| Which CSV belongs to which provider? | You can't tell reliably today. The files keep the portal's names. Open the CSV and check its contents, or download it again by hand from the portal. |
| Which version is running? | Not shown anywhere (see section 10). |
6. Statuses
All statuses appear in the result report's Status column. Only the Status cell is coloured.
| Status - Remarks | Colour | Meaning | What ops does |
|---|---|---|---|
| Downloaded - "Report saved" | green | A new CSV appeared in data/downloads after Export was clicked |
Nothing. Rarely, the file is a late download from the provider before (see section 13). |
| Downloaded - "portal maintenance - no file" | green | Needs follow-up. Nothing was downloaded. The portal showed its maintenance banner. | Download it again later (E08) |
| No Data - "No remittances in the date range" | green | The portal said there are no remittances for this provider in its default date range | Nothing, unless remittances were expected (E09) |
| Skipped - inactive provider - "Marked N in the input" | green | Column C is N, so the bot did not look at this provider |
Nothing |
| Login Failed - "Check the portal username/password" | no colour | The bot could not sign in. Every provider in the run gets this row. | Fix the login (E01) |
| Error - "Report grid did not load" | red | The provider's report page did not load within 30 s | E06 |
| Error - "Download did not finish" | red | Export was clicked, but no new file appeared within 60 s | Check the downloads folder first (E07) |
| Error - "Session expired" | red | The portal signed the bot out three times in a row on this provider | E05 |
| (provider has no row) | - | The run stopped before reaching this provider | E04 |
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 signing in it waits 30 s for the portal dashboard; if it never appears, it gives up the whole run | Result report only. Nothing in the log for this run. | Business (usually wrong password) / System (portal slow) | Ops | Sign in to the portal by hand with the username and password in the Login sheet. If that fails, fix A2/B2 (or reset the password). If it works, the portal was slow: run again. | Manual sign-in works but the bot keeps failing. Send: date and time of the run, the result report, logs/bot.log. |
| E02 | Result report exists but has only the header row; nothing for today in the log | The sign-in page didn't show the username/password/sign-in fields (portal changed or down); the bot stops at once | Nowhere readable: the error only goes to the console, which isn't kept | System | Dev | Check whether the portal sign-in page opens normally in your own browser. If the portal is down, run again later. | The portal sign-in page works normally. Send: date and time, the result report, logs/bot.log, E02. |
| E03 | No result report for today | The bot stopped before the report could be saved: Chrome couldn't start, the input file was missing or unreadable, or the logs or data/output folder is missing |
Nowhere readable (console only). A missing logs folder also means no log. |
System | Ops, then Dev | Check the section 3 list: Chrome installed, folders exist, input file at data/input/providers.xlsx and not open in Excel, config.yaml present. Then run again. |
Everything in section 3 is in place and there is still no report. Send: date and time, E03, screenshot of the folder. |
| E04 | Result report has fewer rows than the input (later providers missing), or the run hangs with no new log line for 10+ minutes | The run crashed or hung partway: signing in again failed after the portal ended the session, the Export button was missing, Chrome closed, or a page never finished loading | Result report (rows up to the crash). The log's last line is the last provider finished. The cause is not recorded anywhere. | System | Dev (Ops checks first) | Check the portal by hand: sign-in works, and the next provider's remittance page shows an Export CSV button. Download the missing providers by hand if they are needed today. | Always, if it happens two days running. Send: date, the NPI of the last row in the report, logs/bot.log, the result report, E04. |
| E05 | Error - "Session expired" | Opening a provider's page lands on the sign-in page. The bot signs in again and retries, 3 tries in total. | Result report; "session expired, re-login 1/2/3" lines in logs/bot.log |
System | Bot, then Ops | Make sure nobody else uses the same portal login during the run. Download this provider by hand, or run again (see section 3, second run). | More than 2 providers per run, or it happens on several days. Send: date, NPI(s), logs/bot.log, E05. |
| E06 | Error - "Report grid did not load" | It waits 30 s for the remittance grid on the provider's page; if it doesn't appear, it takes a screenshot and moves on. No retry. | Result report; data/screens/<NPI>.png (missing if the data/screens folder is missing) |
System | Ops | Look at the screenshot. If the portal shows an error for this provider (wrong NPI, no access), fix the input. Otherwise download it by hand or run again later. | Same provider fails 3 days in a row and the page works by hand. Send: NPI, date, the screenshot, E06. |
| E07 | Error - "Download did not finish" | It clicks Export CSV and waits 60 s for a new CSV file name in data/downloads. No retry. |
Result report | System | Ops | Check data/downloads first. The file may have arrived after 60 s, or under a name that was already there. Open the newest CSV and check it is this provider's. If there is no file, download it by hand from the portal. |
It happens for many providers in one run. Send: date, NPIs, logs/bot.log, E07. |
| E08 | Green Downloaded with Remarks "portal maintenance - no file" | The provider's page shows the portal's maintenance banner. The bot records this as Downloaded without downloading anything. No retry. | Result report (Remarks column only) | System (portal down) | Ops | Filter the Remarks column for "maintenance" after every run. When the portal is back, download those providers by hand or run again. | Never needed for the maintenance itself. The green status is a known gap (section 13). |
| E09 | No Data - "No remittances in the date range" (green) | The portal page shows its "no results" message for the provider | Result report | Business | Ops (only if unexpected) | Usually nothing. If remittances were expected, open the provider in the portal by hand. The bot uses the portal's default date range and cannot set its own. | Remittances are visible by hand but the bot says No Data. Send: NPI, date, E09. |
| E10 | A provider you meant to skip was processed, or one you expected is missing from the report | Only a capital N in column C counts as inactive. A row with an empty NPI is left out of the run completely. |
Result report (row present or missing) | Business | Ops | Fix the input: put N exactly in column C; make sure column A has the NPI on every row. |
Never |
8. What the bot recovers by itself
| Problem | What the bot does | Limit | After the limit |
|---|---|---|---|
| Portal ended the session (provider page shows sign-in) | Signs in again and retries the same provider | 3 tries per provider. Each sign-in waits up to 30 s. | Provider = Error "Session expired", bot moves to the next provider. If signing in again itself fails, the run stops (E04). |
| Report grid doesn't load | Nothing: takes a screenshot and moves on | 30 s, no retry | Error "Report grid did not load" |
| Download doesn't appear | Nothing: moves on | 60 s, no retry | Error "Download did not finish" |
| First sign-in fails | Nothing | 30 s, no retry | Every provider = Login Failed, run ends |
| Maintenance banner | Nothing | no retry | Green Downloaded "portal maintenance - no file" (E08) |
| Page never finishes loading / bot hangs | Nothing - no watchdog | none | Hangs until someone stops it (E04) |
So: apart from an expired session, the bot never retries. Ops never needs to wait for an automatic recovery once the run has ended.
9. Known incidents
Only one run is on record: one day of log, no change history, no bug log.
| When / version | What ops saw | Cause | What to do now | Ops could handle? |
|---|---|---|---|---|
| 2026-09-02 / unversioned | One provider red Error, about 80 s after a "session expired, re-login 1" line in the log | The portal ended the session. The bot signed in again, but the retry then failed with a grid or download timeout. The log doesn't say which, because remarks aren't logged. | Read the Remarks column, check data/screens/<NPI>.png, and download that provider by hand (E05-E07) |
Partly |
10. Releases and version check
- How an update arrives: by hand. A developer replaces the bot's files on the machine. There is no launcher or automatic update.
- How to confirm it applied: you can't yet. The bot has no version number on screen, in the log or in the report (section 13). Ask dev to confirm in #rpa-support which files changed and when.
- If an update seems not to have taken effect: report it in #rpa-support with the date and the behaviour you still see.
- The bot writes to no shared database, so a machine running an older copy cannot undo a newer one. Each machine only affects its own folders.
11. Escalating to dev
Post in #rpa-support (Teams). Send:
- the exception ID from section 7 (for example E04);
- the date and approximate time of the run;
- the NPI(s) affected - the NPI only, not provider or patient details;
- the result report
data/output/Download_Report_<date>.xlsx; logs/bot.log;- for E06, the screenshot
data/screens/<NPI>.png.
Never send: the portal password, the Login sheet, config.yaml, the downloaded CSV files (they contain remittance data), or patient data in chat.
12. Failure-class check
- F1 Missing prerequisite - covered in section 3 (Chrome, packages, folders, settings file) and in E03. The missing folders are also in section 13 #7.
- F2 Wrong window / focus - covered in section 4: don't touch the bot's Chrome window. Otherwise the bot controls its own Chrome directly, with no window matching or focus.
- F3 Target slower or different - covered in E02, E04, E06 and E07, with the limits in section 8. There is no page-load timeout (section 13 #6).
- F4 Input read differently - covered in section 3 (the exact
Nand blank-NPI rules, with examples) and E10. Also in section 13 #10. - F5 Marked done when nothing was done - covered in E08 (maintenance = Downloaded). Also in section 13 #1 and #2 (any new CSV counts as a success).
- F6 Action happened but not confirmed - covered in E07: check the downloads folder before re-running.
- F7 Business exception shown as success - covered in section 6 (maintenance row marked "needs follow-up") and E08. Also in section 13 #1.
- F8 Endless re-runs / watchdog - covered in section 8 (the only retry is bounded at 3) and in section 4 (the stuck sign). There is no watchdog (section 13 #6).
- F9 Stopping the wrong way - covered in section 4: close the bot's Chrome window, not the task. Also in section 13 #12.
- F10 One stuck item blocks the queue - not applicable: there are no batches or completion gates, and each run starts fresh. The nearest risk, a same-day re-run replacing the report, is covered in section 3 and section 13 #9.
- F11 Cause hidden from ops - covered in section 5. Also in section 13 #3, #4 and #5 (remarks, crashes and login failures not logged).
- F12 Update didn't arrive - covered in section 10. Also in section 13 #8 (no version number).
13. Fix before handover (dev team)
| # | Gap | Why it hurts ops | Where (file:line) |
|---|---|---|---|
| 1 | Maintenance banner is recorded as status "Downloaded" (green) with no file | Ops treats the provider as done; the missing file is found later, if at all | bot.py:54-55, colour map bot.py:27-28 |
| 2 | Download check accepts any new CSV in the folder, and files are not renamed per provider | A late file from the previous provider can be counted as this one's. Nobody can tell which CSV belongs to which NPI. | bot.py:63-68, bot.py:80 |
| 3 | The remark is not written to the log; only the status is | The log can't tell the three "Error" reasons apart (see the 2026-09-02 incident) | bot.py:105 |
| 4 | Unexpected errors are not caught or logged. A failed re-login, a missing page element or a Chrome crash ends the whole run. The traceback goes only to the console, which Task Scheduler doesn't keep. | Run stops partway with no recorded cause (E02, E03, E04) | bot.py:41-43, :64, :81, :102, :108-110 |
| 5 | A first-login failure writes nothing to the log, and "Login Failed" rows get no colour | It is easy to miss in the report, and invisible in the log | bot.py:88-91 (returns before :107) |
| 6 | No page-load timeout and no watchdog | A hung page hangs the run forever; nobody is told | bot.py:40, :51, :79-81 |
| 7 | logs, data/output, data/downloads and data/screens are never created |
Missing logs = bot dies at start with no trace. Missing data/output = the report save fails and hides the original error. Missing data/screens = screenshots lost silently. |
bot.py:20-21, :30, :59, :110 |
| 8 | No version string anywhere; dependencies unpinned | Ops can't confirm an update applied, and a package upgrade can change behaviour silently | bot.py:1-2, README.md, requirements.txt:1-3 |
| 9 | A re-run downloads everything again and overwrites the same-day report | Duplicate CSVs, and the morning's results are lost | bot.py:63-68, :110 |
| 10 | Inactive flag must be exactly "N", and a blank NPI drops the row silently | Lower-case or "No" providers are processed; blank-NPI rows vanish from the report | bot.py:77-78 |
| 11 | Plaintext secrets: an unused API token in config.yaml, and the portal password in the input workbook |
Anyone with the input file or the folder has the credentials. Rotate or remove the token. | config.yaml:2, bot.py:76 |
| 12 | No clean stop: ending the task loses the report, and closing Chrome is the only partial-save path | Ops must use a workaround to stop safely | bot.py:85-110 |
| 13 | README promises "screenshots of failed pages", but only a grid timeout takes one | Ops look for screenshots that don't exist | README.md:5, bot.py:59 |
| 14 | "No Data" depends on the portal's default date range; the bot sets no range | A change in the portal default silently changes what "No Data" means | bot.py:61-62 |
| 15 | Provider name and NPI written to the log on every line | The log file needs the same handling as the input file | bot.py:105 |