bib: ingest Medicare Program Integrity Manual (IOM Pub 100-08) into library #306
Reference in New Issue
Block a user
Delete Branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
The Program Integrity Manual defines fraud detection, medical review, and enforcement procedures. Essential for the skin substitutes fraud analysis.
Key chapters:
Source: https://www.cms.gov/regulations-and-guidance/guidance/manuals/internet-only-manuals-ioms-items/cms019033
Create Manual items with pub_number=100-08.
Closed via #343-tracked sync pipeline. 100-08 (Program Integrity Manual): 15 chapter PDFs ingested, attached, and synced to Zotero under
Healthcare Data Platform / Manuals.Architecture
Landed a full CMS IOM pipeline — not just this manual, every IOM CMS publishes (20 pubs, 177 chapters total).
Modules
src/bib/iom.py(new) — scraper + orchestrator.fetch_index(client)scrapes the CMS IOM index table.fetch_chapters(client, entry)scrapes each manual's landing page. Handles single-file manuals (100-17/18/19/20/21) via_WHOLE_PUBregex fallback; handles split chapters ("Chapter 1 Part 2") via_CHAPTER_PARTfold into composite IDs like1P2; skips supplementals (crosswalks, addenda).ingest_all(store, client, *, pubs=None, prune=True)— idempotent: re-upserts by URL and prunes Manual records whose URL is no longer in the live CMS list, cleaning up stale filename-rename dupes.download_attachments(store, client)— SHA-256-keyed; skips files whose on-disk checksum matches the stored copy.check_future_updates(store, client)— pollsfuturepdf.pdf(CMS upcoming-transmittal schedule); attaches only when checksum changes; designed as the trigger signal for out-of-band refresh cycles.src/bib/sync.py— extended with attachment sync + collection routing.push_to_zotero(items, store=..., ...)now walksstore.attachmentsand copies PDFs into Zotero'sdata/zotero/data/storage/<key>/+ createsitemAttachmentsrows withlinkMode=1(IMPORTED_URL)._zotero_collection_path(item)derives the target hierarchy; Manual items route toHealthcare Data Platform / Manuals / <manual_name>, ensured viaDb.ensure_collectionon the fly.replace_fields(item_id, fields)— wipes existing itemData before rewriting to clean stale garbage from prior buggy syncs.src/cli/bib.py— new commands, all idempotent:stack bib ingest-iom [--pub X]stack bib attach-iom [--pub X] [--force]stack bib watch-iomstack bib sync-zotero [--tag X] [--type manual](wrapsdocker stop/start zotero)stack bib refresh-iom— one-shot: ingest → watch → attach → sync. Safe to cron (follow-up #343).Schema parity fix
Root cause of earlier Zotero corruption was stale
TYPE_MAP/FIELD_MAP/CREATOR_TYPESconstants insrc/zot/db.pyauthored against an older Zotero schema. Modern Zotero 7 assigns different numeric IDs, somanual → 15landed as "email" instead of "report" and attachments as "document" instead of "attachment", tripping Zotero'sgetFilePath()consistency checks._verify_schema_parity()runs on everyDb.__init__and raises immediately if IDs drift — future Zotero upgrades can't silently corrupt data.src/zot/schema.sqlreplaced with a fresh dump (2,499 lines) — the old file had triggers likeitemTypeID != 14for attachments that were valid only in the pre-7 schema.src/zot/ops.pypackagesdump_schema,fix_dates,fix_keys,fix_fieldsas importable + CLI-exposed (stack zot {…}). Olddev/scripts/*.pybecame thin shims that call into the module.Data flow
Verified clean state
report, 177 attachment children typedattachment(linkMode=1)PRAGMA integrity_check= ok,PRAGMA foreign_key_check= ok(itemTypeID, fieldID)pairs valid peritemTypeFieldsCombinedGotchas recorded for future agents
.dockerignoreare required (!infra/marimo/theme/,!infra/gitea/) or the build context lacks theme files.docker stop zotero/start zoteroautomatically (--holddefault on).filenamecolumn inbib.attachmentsis a display label, not a filesystem name. UsePath(storage_path).namewhen copying into Zotero storage.