| name | snf-document-map |
| description | Page-level document-type map and OCR/readability triage for large, disorganized nursing-facility PDFs ONLY — classifies each page, groups contiguous segments, separates records that are genuinely absent (not_found) from records that are merely unreadable (indeterminate_ocr), compares a supplied records request against what arrived, and produces a reviewer packet plan. This is narrow triage, not a review — for the complete review use snf-review. Use when the user says "map this chart", "what document types did we actually receive", "which records are missing from the production", "this PDF is 700 pages with no separators", or "/snf-document-map". |
SNF Document Map
Create a conservative, source-cited map of what document types appear in a large SNF records production before the adversarial findings review begins. This skill is for the hard case: one or more 500-1000+ page PDFs containing mixed scanned pages, vitals, MAR/eMAR, TAR, therapy, case notes, billing, signed forms, and other chart artifacts without reliable section separators.
Inputs to collect from the user
- PDF directory — absolute path to the folder containing source PDFs from the HIPAA production.
- Stay window —
--stay-start and --stay-end dates (YYYY-MM-DD). If uncertain, use the best-known admission date through today and flag the assumption.
- Output directory — default:
<pdf-dir>/../document-map or <review-root>/document-map if this is part of /snf-review.
- Case context ledger — optional path to
case-context/; if present, read case_profile.md, document_index.md, and open_questions.md first so expected-document gaps are framed correctly.
- Source records request — optional path to the HIPAA/document request letter, email, Markdown/text, or PDF. Use this to compare what was requested against what the production appears to contain.
Execution
Run the mapper script from the bundled snf-records-review skill:
python3 ${CLAUDE_PLUGIN_ROOT}/skills/snf-records-review/scripts/build_document_map.py \
--in-dir "<pdf-dir>" \
--out-dir "<out-dir>" \
--stay-start <YYYY-MM-DD> \
--stay-end <YYYY-MM-DD>
If the source records request is available, append:
--request-file "<records-request.md|txt|pdf>"
It writes:
document_map.json — machine-readable page records, segments, expected-document checklist, OCR/readability actions, and review-packet plan.
document_map.md — human-readable coverage report, including requested-vs-received delta when --request-file is supplied.
review_packet_plan.json — reviewer-sized source page ranges suitable for materialize_packet_plan.py.
If reviewers need physical packet PDFs, materialize the plan:
python3 ${CLAUDE_PLUGIN_ROOT}/skills/snf-records-review/scripts/materialize_packet_plan.py \
--packet-plan "<out-dir>/review_packet_plan.json" \
--source-dir "<pdf-dir>" \
--out-dir "<review-root>/review-packets"
Use --dry-run first when working with a very large corpus. Packet materialization prefers qpdf; if unavailable, it falls back to Poppler pdfseparate + pdfunite.
Local PDF toolkit
Prefer the installed local tools before inventing a custom parser. The mapper records tool availability in document_map.json / document_map.md and uses the best available utility for each job:
| Tool | Primary use in this workflow |
|---|
pdftotext -layout | Preferred text extraction for narrative notes, MAR/TAR tables, flow sheets, and therapy-minute tables. Falls back to pypdf per page if unavailable or weaker. |
pdfinfo | PDF-level metadata, page count cross-checks, producer/export hints. |
pdfimages -list | Detect scanned/image-heavy pages and distinguish image-only pages from text-bearing pages. |
pdffonts | Detect whether a PDF likely has embedded text fonts; no fonts plus many images usually means scanned/OCR-needed. |
qpdf | Preferred lossless packet page copying. |
pdfseparate + pdfunite | Packetization fallback when qpdf is unavailable. |
pdfdetach / pdfattach | Inspect or preserve embedded attachments if a facility exports attachments inside a PDF container. |
pdfsig | Check signature metadata when signed admissions, consents, or financial forms appear digitally signed. |
pdftoppm / pdftocairo | Render pages for targeted visual/OCR remediation. |
pdftohtml, pdf2json, pdfcpu | Secondary structure extraction, validation, attachment, and repair workflows when the map flags a hard PDF problem. |
Adobe Acrobat Pro is available locally as a manual remediation tool: use it for OCR, page rotation, visual confirmation, redaction, or cleaner-copy export when automated tooling marks a page ocr_light / image_or_no_text, a reviewer marks a finding OCR-partial, or a page is visually suspect. Do not automate Acrobat against PHI unless the user explicitly asks and the output path is a private local case folder.
How to interpret the map
Document types
The mapper classifies each page into likely document types and groups contiguous pages into contextual segments. Typical types include:
- Face sheet / admission record
- H&P and physician orders
- MAR/eMAR and TAR
- Vitals, flow sheets, pulse ox, respiratory/O2 records
- Nursing/progress notes
- PT/OT/ST and therapy-minute records
- Care plans and MDS, including Section Q
- Social services / case management / discharge planning
- Incident reports and risk assessments
- Consents, HIPAA/ROI, admission agreements, arbitration, financial paperwork
- Medicaid/PASSPORT documents
- Billing, invoices, itemized charges
- Payer / utilization-review correspondence
When --request-file is supplied, the mapper also records conservative keyword matches between the source request and the expected-document checklist. The output fields requested_in_source_request and request_match_terms help route follow-up requests, but they are not a substitute for human verification of the request text.
Location discipline
Every page, segment, packet, and follow-up must preserve original source location:
- Use
<source PDF> p.<page> for single pages.
- Use
<source PDF> pp.<start>-<end> for segments/packets.
- If packets are materialized, citations still point to the original source PDF/page unless a packet manifest is the only available location bridge.
OCR discipline
The mapper deliberately separates absence from unreadability:
-
Page-level OCR statuses are text, ocr_light, and image_or_no_text.
-
Human reviewer verification labels are verified, OCR-partial, and image-only-needs-OCR.
-
present — enough page-level evidence exists to route reviewers.
-
possible — some evidence exists but confidence is low; reviewer should verify.
-
not_found — not detected in sufficiently text-readable material; good candidate for narrow HIPAA follow-up.
-
indeterminate_ocr — not detected, but OCR/readability is too weak to call it absent; run OCR or request a cleaner copy first.
Never tell the user a record was omitted solely because text search did not find it in image-only or OCR-light pages.
Output summary for the user
After reading document_map.md and document_map.json, summarize only non-PHI metadata in chat:
- Total PDFs/pages and text-readable percentage.
- Count of contextual segments and planned review packets.
- Expected document coverage table: present / possible / not_found / indeterminate_ocr.
- OCR remediation actions by PDF/page range.
- Narrow follow-up request items to feed into
hipaa-records-request.
- Whether the corpus is ready for
/snf-review or needs OCR/remediation first.
Follow-up routing
- Add the production and
document_map.md to case-context/document_index.md via case-context-ledger.
- Add unresolved
not_found / indeterminate_ocr items to case-context/open_questions.md.
- Use
hipaa-records-request for narrow supplement requests generated from the expected-document checklist.
- Use
/snf-review once OCR-critical issues are remediated or explicitly accepted as scope limitations.
Guardrails
- This is document intake, triage, and evidence logistics — not medical or legal advice.
- Keep PHI in local output files. Do not paste snippets from
document_map.json into chat unless the user explicitly asks.
- For weak OCR, report uncertainty; do not guess document content.
- Do not overwrite or delete raw PDFs. Derived packet PDFs belong in the review output folder, not in the raw records folder.