pfs: exposure calendar from code lineage — effective dates, exposure types, control code sets #693
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?
Spec docs/superpowers/specs/2026-09-09-code-family-longitudinal-design.md (§P50).
Derive from
pfs.code_event(P49): one row per (code or family, effective date, exposure kind ∈ becomes-payable | revalued | status-change | ends | telehealth-listed). Effective date = 1 January of the rule year, or the correction-rule date where a correction changed the row (pfs.rules.RULESknows the FR cites; corrections are anchored items, e.g.6N8FPFHFCY2015 correction). Control sets = families with no event in the window, matched on status and RVU band.Fixture events: 99490 payable 2015-01-01; 99487/99489 A-status 2017-01-01; 99439 replaces G2058 2021-01-01; 99424–99427 replace G2064/G2065 2022-01-01; G2211 A-status 2024-01-01; G0556–G0558 payable 2025-01-01; 99441–99443 end 2025-01-01.
Done when the calendar is a DuckDB table with anchors carried through from the lineage rows and a notebook lists every exposure with its FR jump link.
Merged to main as
4bd86b0(branch commits79ab2ebfeature,4894acd+57ed2c7CLI docs). Live calendar built and published the same day.What landed
pfs.code_exposure(DDL +ExposureRow/write_exposures/read_exposuresinpfs.codetables): one row per (code, effective date, kind) forbecomes-payable/revalued/status-change/ends/telehealth-listed, with family key, the year's RVU status, prior status, decile band ofnon_fac_totalamong that year's payable codes, revaluation delta, and the FR anchor (item_key/p_id/page/anchor_kind) carried frompfs.code_event.pfs.exposure:rvu_series/rvu_bands/derive(pure) +build(con, store)+control_codes(con, code, year, window=2)— never-treated codes with the same status + band and no exposure within ±window.pfs.valuation.PAID_STATUSES); left-censored at the 2015 file (a first-year payable code needs an FR created/adopted_cpt/replaces event that year); right-censored at the newest file; telehealth listed once per run of consecutive years; anchors prefer non-correction rules, then nearest year, then kind-matched, then lowest ¶. Effective date is 1 January of the rule year, or the correction notice's publication date when the event's own year is anchored only by a correction (32 rows, all CY20156N8FPFHF).stack pfs exposure [--code|--family] [--write] [--controls N --year Y --window W]; notebookcode_families.pysection 7c lists a family's exposures with FR jump links and a control-set preview; provenance counts include the table.Live numbers (
stack pfs exposure --write, 1.3 s): 6,314 rows / 4,796 codes — revalued 3,738, becomes-payable 1,948, ends 417, telehealth-listed 206, status-change 5; 915 anchored to an FR paragraph. Every fixture event in this issue is present: 99490 2015-01-01 (DE2VH9PD ¶1244), 99487/99489 2017-01-01, 99439 2021-01-01 (YBM4IZUS ¶686) + G2058 ends 2021-01-01, 99424 2022-01-01 + G2064 ends 2022-01-01, G2211 2024-01-01 (JJV3R692 ¶1735), G0556 2025-01-01 (JJ6AM5HJ ¶1526), 99441 ends 2025-01-01 (VXSUDWCR ¶489 deleted).Tests: 18 unit (
tests/pfs/test_exposure.py), 6 CLI, notebook structure + live run green; pre-commit suites (cli, pfs, notebooks) passed on the feature commit.Known limits for #696 to weigh: 99487/99489's 2017 becomes-payable anchor is a
bundledparagraph (no kind-matched event that year → any-kind fallback); revalued rows only exist from the ±10% lineage threshold; families for non-hand codes are the derived CPT-heading families, so control matching by family is coarse.Ops note: while building I ran
--writefrom a worktree that lacked adata/aco.duckdblink, which created an empty primary there and published it over the shared replica for about a minute; I republished from the real primary immediately (connect.publish_replica) and verified 1,088 tables / 209,267 rvu rows are back.