rpa-bot-handoff: email To the developer with their manager in CC, and hand ops a PDF
- Section 5 of the SOP now names a real "To" (the developer) and "CC" (the developer's manager, not the operator's), and the email block to copy starts with To: and CC: lines. The skill asks for both addresses. - to_docx.py --pdf also writes the PDF (Word through PowerShell on Windows, LibreOffice elsewhere) and prints the real page count against MAX_PAGES. The PDF is what ops gets. - Tebra reference and README updated; new test for the To/CC lines. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
717f2c40c5
commit
0188de7403
6 files changed
+62
-22
No files matched your search
@@ -3,12 +3,12 @@
|
||||
A Claude skill that writes a short **Handover SOP** for an RPA bot that is being handed over to an ops team.
|
||||
|
||||
## What you get
|
||||
**`<Project Name> Handover SOP.docx`** (and `HANDOVER-SOP.md`): at most 4 pages, in plain words, for operators who don't read code:
|
||||
**`<Project Name> Handover SOP.pdf`** (plus the `.docx` and `HANDOVER-SOP.md`): at most 4 pages, in plain words, for operators who don't read code:
|
||||
1. How to run: the URL or shortcut, what to click, and what a new click does to the previous results
|
||||
2. What you see while it runs: what shows where, a normal run, how long each step may take
|
||||
3. Result: how a good run ends, where the report is, what each status means
|
||||
4. When something goes wrong: how it shows, each message (E01, E02...) with what to do, the don'ts, how to stop it
|
||||
5. Email us: the address, when to email, and the email to copy
|
||||
5. Email us: To the developer, CC their manager, when to email, and the email to copy
|
||||
|
||||
Problems the scan finds for the dev team are listed in the chat, not in the SOP.
|
||||
|
||||
@@ -18,9 +18,9 @@ Copy this folder to `~/.claude/skills/rpa-bot-handoff/`.
|
||||
## Use
|
||||
In your bot project, ask Claude: *"write the handover SOP for this bot"* or *"document this bot for handover"*. The skill:
|
||||
1. Scans the code with a subagent. It never runs the bot.
|
||||
2. Asks up to two things: the email group ops writes to, and where ops runs the bot.
|
||||
2. Asks up to two things: the developer's and the manager's email (To and CC), and where ops runs the bot.
|
||||
3. Writes the SOP, checks every quoted message and label against the code, and keeps it under 1,400 words.
|
||||
4. Turns it into the Word file you give to ops.
|
||||
4. Turns it into Word and PDF; you give the PDF to ops.
|
||||
|
||||
## Files
|
||||
| File | What it is |
|
||||
@@ -29,4 +29,4 @@ In your bot project, ask Claude: *"write the handover SOP for this bot"* or *"do
|
||||
| `templates/HANDOVER-SOP.md` | The SOP skeleton |
|
||||
| `templates/failure-classes.md` | 12 failure classes from Tebra's first months with ops, used as a scan checklist |
|
||||
| `templates/reference/tebra-auto-post.md` | The SOP filled in for Tebra, scrubbed |
|
||||
| `templates/to_docx.py` | Turns the SOP into Word and prints the word count (`--selfcheck` tests it) |
|
||||
| `templates/to_docx.py` | Turns the SOP into Word, and with `--pdf` into PDF; prints word and page counts (`--selfcheck` tests it) |
|
||||
@@ -1,25 +1,25 @@
|
||||
---
|
||||
name: rpa-bot-handoff
|
||||
description: Writes a short Handover SOP for an RPA bot that is being handed over to an ops/support team - "<Project Name> Handover SOP", at most 4 pages, as Markdown and Word. Scans the bot's code with a subagent (never runs it) and writes, in the operator's order - how to run it (which URL or shortcut, what to click), what shows where once it runs, where the result is and what it means, how a problem shows and what to do, and how to email the dev team about it. Every label, message and wait is copied from the code. Use when the user asks to "hand over a bot", "document a bot for ops", "write a handover doc", "handover SOP", "ops guide", "runbook", "support doc", "operator guide" or "how ops should handle bot errors" for an RPA or automation project.
|
||||
description: Writes a short Handover SOP for an RPA bot that is being handed over to an ops/support team - "<Project Name> Handover SOP", at most 4 pages, as Markdown, Word and PDF. Scans the bot's code with a subagent (never runs it) and writes, in the operator's order - how to run it (which URL or shortcut, what to click), what shows where once it runs, where the result is and what it means, how a problem shows and what to do, and how to email the developer, with their manager in CC. Every label, message and wait is copied from the code. Use when the user asks to "hand over a bot", "document a bot for ops", "write a handover doc", "handover SOP", "ops guide", "runbook", "support doc", "operator guide" or "how ops should handle bot errors" for an RPA or automation project.
|
||||
---
|
||||
|
||||
# RPA bot handoff
|
||||
|
||||
Write one document in the bot's repo: **`<Project Name> Handover SOP`**, as `HANDOVER-SOP.md` and `<Project Name> Handover SOP.docx`. The docx is what ops gets.
|
||||
Write one document in the bot's repo: **`<Project Name> Handover SOP`**, as `HANDOVER-SOP.md`, `<Project Name> Handover SOP.docx` and `<Project Name> Handover SOP.pdf`. The PDF is what ops gets.
|
||||
|
||||
The reader is an **operator who does not read code**. The SOP answers only what they ask, in this order:
|
||||
1. How do I run it? Which URL or shortcut, what do I click.
|
||||
2. What shows where once it runs?
|
||||
3. Where is the result, and what does it mean?
|
||||
4. Something went wrong: how does it show, and what do I do?
|
||||
5. How do I email the dev team about it?
|
||||
5. Who do I email about it, and who goes in CC?
|
||||
|
||||
| File | What it is |
|
||||
|---|---|
|
||||
| `templates/HANDOVER-SOP.md` | The SOP skeleton: 5 sections. Keep their order. |
|
||||
| `templates/failure-classes.md` | 12 failure classes from Tebra Auto Post. A scan checklist so no problem type is missed. |
|
||||
| `templates/reference/tebra-auto-post.md` | A filled example for Tebra, scrubbed. Copy its length and wording, not its content. |
|
||||
| `templates/to_docx.py` | Turns the finished SOP into the Word file and prints the word count. Needs `python-docx`. |
|
||||
| `templates/to_docx.py` | Turns the finished SOP into Word, and with `--pdf` into PDF too (through Word on Windows, LibreOffice elsewhere). Prints the word and page count. Needs `python-docx`. |
|
||||
|
||||
## Rules
|
||||
|
||||
@@ -46,7 +46,7 @@ While it runs, read `templates/failure-classes.md` and `templates/reference/tebr
|
||||
|
||||
## 2. Ask once (one message, at most 2 questions)
|
||||
|
||||
1. **Email:** which email group ops writes to (the address, never a personal phone number), and how fast they get an answer.
|
||||
1. **Email:** the developer's email address (the "To"), the manager's name and email address (the "CC"), and how fast ops gets an answer. Never a personal phone number. The CC is the developer's manager, not the operator's.
|
||||
2. **Where ops runs it:** the URL or machine, when the code allows more than one.
|
||||
|
||||
Skip a question the user already answered. Default the rest: title from the project name, today's date, version from the project's version string.
|
||||
@@ -59,17 +59,17 @@ Copy `templates/HANDOVER-SOP.md` to the bot's repo root and fill every `{{PLACEH
|
||||
2. **What you see while it runs:** a table, one row per area of the screen, in screen order: where, what it shows. Then the normal sequence in 3 to 5 numbered lines. Then the waits table: step, the bot waits at most, then. End with when the operator steps in.
|
||||
3. **Result:** how a good run ends; how a run that needs a look ends (call out misleading greens). Then where the result is, and a small table of the per-item statuses: status, meaning, what you do.
|
||||
4. **When something goes wrong:** where problems show and how (colour, list, column). Then one table row per message, numbered `E01`, `E02`...: message (exact), what it means, what you do. Put "check X **before** re-running" in bold. Say "email us" in the row when the operator can't fix it. Then the don'ts in at most 4 bullets, and the one right way to stop the bot.
|
||||
5. **Email us:** the address and response time, when to email, the subject line and the email body to copy, what to attach, and what never to send (passwords, patient or client data, the result files when they hold patient data).
|
||||
5. **Email us:** "To" the developer and "CC" the developer's manager, both as real addresses, the response time, when to email, the email to copy (To, CC, Subject and body lines), what to attach, and what never to send (passwords, patient or client data, the result files when they hold patient data).
|
||||
|
||||
## 4. Verify
|
||||
|
||||
1. Every message and status in the subagent's report is in section 3 or 4.
|
||||
2. Search the code for each quoted message, label and URL. Each must exist exactly, or be built by the code from the parts shown in italics.
|
||||
3. No file:line, function names, env var names, client names, PHI, credentials or IPs.
|
||||
4. Run `python <skill>/templates/to_docx.py HANDOVER-SOP.md -o "<Project Name> Handover SOP.docx"`. If it reports more than 1,400 words, cut: merge rows, drop explanations, never drop a message.
|
||||
4. Run `python <skill>/templates/to_docx.py HANDOVER-SOP.md -o "<Project Name> Handover SOP.docx" --pdf`. It writes the docx and the PDF. If it reports more than 1,400 words or more than 4 pages, cut: merge rows, drop explanations, never drop a message.
|
||||
5. Open the docx with python-docx: 5 numbered section headings, no `**` or `|---` left.
|
||||
6. When Word is installed, count the real pages (PowerShell: open it with `Word.Application`, read `ComputeStatistics(2)`). More than 4: cut words, then rebuild.
|
||||
6. Section 5 has a real "To" and "CC" address, and the email block starts with `To:` and `CC:` lines.
|
||||
|
||||
## 5. Hand over
|
||||
|
||||
Give the user the path to `<Project Name> Handover SOP.docx`: "Give this to the ops team." Then, in the chat only, list in at most 5 lines the problems the scan found that the dev team should fix (misleading statuses, silent failures, no alerts). They are not part of the SOP.
|
||||
Give the user the path to `<Project Name> Handover SOP.pdf`: "Give this to the ops team." If no PDF could be made (no Word or LibreOffice), say so and give the docx. Then, in the chat only, list in at most 5 lines the problems the scan found that the dev team should fix (misleading statuses, silent failures, no alerts). They are not part of the SOP.
|
||||
@@ -1,6 +1,6 @@
|
||||
# {{PROJECT_NAME}} Handover SOP
|
||||
|
||||
Version {{VERSION}} · {{DATE}} · Problems: email {{EMAIL_GROUP}} (section 5)
|
||||
Version {{VERSION}} · {{DATE}} · Problems: email {{DEV_EMAIL}}, CC {{MANAGER_EMAIL}} (section 5)
|
||||
|
||||
{{ONE_LINE: what the bot does, from which app or portal, and what it produces}}
|
||||
|
||||
@@ -58,9 +58,11 @@ Version {{VERSION}} · {{DATE}} · Problems: email {{EMAIL_GROUP}} (section 5)
|
||||
|
||||
## 5. Email us
|
||||
|
||||
Email **{{EMAIL_GROUP}}** when section 4 says "email us", or when the same error comes back after one re-run. Answer: {{RESPONSE_TIME}}.
|
||||
Email **{{DEV_EMAIL}}** with **{{MANAGER_NAME}}** ({{MANAGER_EMAIL}}) in CC when section 4 says "email us", or when the same error comes back after one re-run. Answer: {{RESPONSE_TIME}}.
|
||||
|
||||
```
|
||||
To: {{DEV_EMAIL}}
|
||||
CC: {{MANAGER_EMAIL}}
|
||||
Subject: {{PROJECT_NAME}} - E<number> - <date>
|
||||
|
||||
Run started: <time from the screen>
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
# Worked example: Tebra Auto Post (v2.5.3), scrubbed
|
||||
|
||||
What the SOP looks like for a real bot: about 2.5 pages. Client names, IDs, amounts, credentials and server addresses are removed, and the email address is an example. **Copy the length and the plain wording, not the content.**
|
||||
What the SOP looks like for a real bot: about 2.5 pages. Client names, IDs, amounts, credentials and server addresses are removed, and the email addresses are examples. **Copy the length and the plain wording, not the content.**
|
||||
|
||||
---
|
||||
|
||||
# Tebra Auto Post Handover SOP
|
||||
|
||||
Version 2.5.3 · 28 Oct 2026 · Problems: email rpa-support@example.com (section 5)
|
||||
Version 2.5.3 · 28 Oct 2026 · Problems: email dev@example.com, CC manager@example.com (section 5)
|
||||
|
||||
Posts insurance ERA payments into the Tebra desktop app, company by company and practice by practice, from the input Excel, then turns each ERA into a PDF.
|
||||
|
||||
@@ -83,9 +83,11 @@ Posts insurance ERA payments into the Tebra desktop app, company by company and
|
||||
|
||||
## 5. Email us
|
||||
|
||||
Email **rpa-support@example.com** when section 4 says "email us", or when the same error comes back after one Resume. Answer: same working day.
|
||||
Email **dev@example.com** with **the RPA manager** (manager@example.com) in CC when section 4 says "email us", or when the same error comes back after one Resume. Answer: same working day.
|
||||
|
||||
```
|
||||
To: dev@example.com
|
||||
CC: manager@example.com
|
||||
Subject: Tebra Auto Post - E<number> - <date>
|
||||
|
||||
Batch ID: <from the Dashboard>
|
||||
|
||||
@@ -1,16 +1,18 @@
|
||||
"""Turn the Handover SOP (HANDOVER-SOP.md) into a Word document ops can open, print and pass around.
|
||||
"""Turn the Handover SOP (HANDOVER-SOP.md) into a Word document, and a PDF, ops can open, print and pass around.
|
||||
|
||||
python to_docx.py HANDOVER-SOP.md # writes HANDOVER-SOP.docx next to it
|
||||
python to_docx.py HANDOVER-SOP.md -o "<Project Name> Handover SOP.docx"
|
||||
python to_docx.py HANDOVER-SOP.md -o "<Project Name> Handover SOP.docx" --pdf # + the .pdf next to it
|
||||
python to_docx.py --selfcheck
|
||||
|
||||
Prints the word count: the SOP must stay at or under MAX_WORDS (about 4 pages).
|
||||
Prints the word count (at most MAX_WORDS) and, with --pdf, the real page count (at most MAX_PAGES).
|
||||
The PDF is made by Word on Windows (through PowerShell) or by LibreOffice (soffice) elsewhere.
|
||||
|
||||
Handles what the template uses: # headings, paragraphs, - bullets, - [ ] checkboxes, 1. steps,
|
||||
| tables |, ``` blocks, **bold**, *italic* and `code`. Needs python-docx (pip install python-docx).
|
||||
"""
|
||||
import argparse
|
||||
import re
|
||||
import subprocess
|
||||
import sys
|
||||
import tempfile
|
||||
from pathlib import Path
|
||||
@@ -19,6 +21,7 @@ from docx import Document
|
||||
from docx.shared import Cm, Pt
|
||||
|
||||
MAX_WORDS = 1400 # about 4 pages with the margins and table font below
|
||||
MAX_PAGES = 4
|
||||
INLINE = re.compile(r"(\*\*[^*]+\*\*|\*[^*\s][^*]*\*|`[^`]+`)")
|
||||
|
||||
|
||||
@@ -96,6 +99,26 @@ def words(md_text):
|
||||
return len(re.findall(r"[A-Za-z0-9][\w'’.-]*", re.sub(r"^\|[\s:|-]+\|\s*$", "", md_text, flags=re.M)))
|
||||
|
||||
|
||||
def to_pdf(docx_path):
|
||||
"""Write the PDF next to the docx. Returns (pdf path, page count or None); pdf path is None on failure."""
|
||||
docx_path = Path(docx_path).resolve()
|
||||
pdf = docx_path.with_suffix(".pdf")
|
||||
pages = None
|
||||
if sys.platform == "win32":
|
||||
q = lambda p: str(p).replace("'", "''") # PowerShell single-quote escape
|
||||
ps = (f"$w = New-Object -ComObject Word.Application; $w.Visible = $false; "
|
||||
f"$d = $w.Documents.Open('{q(docx_path)}', $false, $true); "
|
||||
f"Write-Output ('pages=' + $d.ComputeStatistics(2)); $d.SaveAs2('{q(pdf)}', 17); "
|
||||
f"try {{ $d.Close(0) }} catch {{}}; try {{ $w.Quit() }} catch {{}}")
|
||||
r = subprocess.run(["powershell", "-NoProfile", "-Command", ps], capture_output=True, text=True)
|
||||
if m := re.search(r"pages=(\d+)", r.stdout):
|
||||
pages = int(m[1])
|
||||
else:
|
||||
subprocess.run(["soffice", "--headless", "--convert-to", "pdf", "--outdir", str(pdf.parent), str(docx_path)],
|
||||
capture_output=True)
|
||||
return (pdf if pdf.exists() else None), pages
|
||||
|
||||
|
||||
def selfcheck():
|
||||
example = Path(__file__).parent / "reference" / "tebra-auto-post.md"
|
||||
sop = "# " + example.read_text(encoding="utf-8").split("\n---\n", 1)[1].split("\n# ", 1)[1]
|
||||
@@ -116,6 +139,7 @@ if __name__ == "__main__":
|
||||
ap = argparse.ArgumentParser()
|
||||
ap.add_argument("md", nargs="?")
|
||||
ap.add_argument("-o", "--out")
|
||||
ap.add_argument("--pdf", action="store_true", help="also write the PDF next to the docx")
|
||||
ap.add_argument("--selfcheck", action="store_true")
|
||||
a = ap.parse_args()
|
||||
if a.selfcheck:
|
||||
@@ -129,3 +153,9 @@ if __name__ == "__main__":
|
||||
convert(text, out)
|
||||
n = words(text)
|
||||
print(f"wrote {out} ({n} words{'' if n <= MAX_WORDS else f', OVER the {MAX_WORDS}-word limit: cut it'})")
|
||||
if a.pdf:
|
||||
pdf, pages = to_pdf(out)
|
||||
if not pdf:
|
||||
sys.exit("no PDF: needs Word (Windows) or LibreOffice (soffice). Hand over the docx instead.")
|
||||
over = pages and pages > MAX_PAGES
|
||||
print(f"wrote {pdf} ({pages or '?'} pages{f', OVER the {MAX_PAGES}-page limit: cut it' if over else ''})")
|
||||
Reference in new issue
Block a user