Some checks failed
CI / skinny-install (aco) (push) Successful in 1m1s
CI / skinny-install (api) (push) Successful in 40s
CI / skinny-install (bcda) (push) Successful in 40s
CI / skinny-install (bib) (push) Successful in 45s
CI / skinny-install (bls) (push) Successful in 33s
CI / skinny-install (ccw) (push) Successful in 56s
CI / skinny-install (cli) (push) Successful in 1m20s
CI / lint-test (push) Successful in 6m31s
CI / skinny-install (cms) (push) Successful in 56s
CI / skinny-install (conf) (push) Successful in 1m29s
CI / skinny-install (opps) (push) Successful in 1m15s
CI / skinny-install (perf) (push) Successful in 55s
CI / skinny-install (pfs) (push) Successful in 55s
CI / skinny-install (rex) (push) Successful in 56s
Infra CI / notebooks (push) Successful in 13s
Infra CI / zotero (push) Successful in 13s
Infra CI / docs (push) Failing after 20s
Infra CI / api (push) Successful in 12s
Infra CI / mc (push) Successful in 12s
Deploy / build-scan-report (push) Failing after 3m37s
Harden / build-scan-report (push) Failing after 13m27s
Package Supply Chain / pkg-supply-chain (push) Failing after 58s
Build the `rec` module to drive calculated payments toward 1:1 parity
with CMS-published ground-truth files. The notebook at
notebooks/pfs_calcs.py revealed our pfs.calcs.payment output diverges
from pfs.carrier_locality for some year × locality × HCPCS combos;
rec lets us measure the gap, track it year-over-year, and extend to
OPPS / IPPS / ASC / DMEPOS without touching the engine.
Design — open/closed:
- src/rec/base.py, engine.py, report.py, cli.py are closed for
modification. Adding a new payment system = one new file under
src/rec/pricers/ implementing the Pricer protocol + one line in
rec.pricers.__init__.PRICERS.
- Pricer is a @runtime_checkable Protocol with ClassVar
system/description/join_keys/compare_cols and three methods
(ground_truth, calculated, years_available). isinstance() is used
by the engine to validate conformance without subclassing.
- reconcile(pricer, con, year) returns a frozen Reconciliation
dataclass with scalar counts, a per-row deltas polars DataFrame,
exact/near match counts, and non-fatal warnings. Matched rows are
classified as exact (≤ tolerance_cents) or near (≤ 1¢). The delta
table contains <col>_gt / <col>_calc / <col>_delta + abs_max_delta
+ is_exact / is_near flags, sorted by worst delta first.
- rec.report.as_markdown / as_json format the Reconciliation for
the CLI. markdown includes counts table and top-N deltas.
- src/cli/rec.py is a Typer sub-app registered under `stack rec`:
stack rec list # registered pricers
stack rec pfs --year 2025 # single year
stack rec pfs # all available years
stack rec pfs --format json --output out.json
src/rec/__main__.py mirrors the same via `python -m rec`.
PfsPricer implementation (src/rec/pricers/pfs.py):
- ground_truth: SELECT from pfs.carrier_locality WHERE year = ?
- calculated:
1. RULES[year].conversion_factor replaces the stale
pfs.rvu.conv_factor column (rvu file values are unreliable;
the notebook already did this override).
2. Filters pfs.rvu to status_code IN ('A', 'T') so carrier-priced
codes (status 'C') show up as ground_truth_only instead of
being flagged as bugs.
3. Cross-joins rvu × distinct(mac, locality) from gpci, then
calls pfs.calcs.payment.payment() twice (facility=False /
True), rounds to cents, and joins the two halves.
- join_keys: [year, mac, locality, hcpcs, mod]
- compare_cols: [non_fac_fee, fac_fee] — limiting-charge columns
are omitted because pfs/pipe.py synthesises them from
non_fac_fee × 1.0925 at load time; reconciling against a value
we computed ourselves is circular. Documented in the module
docstring as a tracked gap (#340 gap #3).
Wiring:
- pyproject.toml: new rec optional dep group (stack[conf,pfs] +
duckdb + narwhals + typer), added to stack[all], module-name
list extended to include "rec".
- stack.toml [storage]: rec = "data/rec" for report artifacts.
- src/cli/__init__.py registers rec_app under `stack rec`.
Tests (37, all green):
- tests/rec/conftest.py seeds an in-memory DuckDB with four rows
designed to exercise the full match matrix: exact, 1¢ near, GT-only
(carrier-priced), calc-only. Also defines a FakePricer class for
engine tests that don't need DuckDB.
- tests/rec/test_base.py: protocol conformance, dataclass shape,
pct_exact / is_perfect derived properties, frozen immutability.
- tests/rec/test_engine.py: counts, exact vs near classification,
tolerance promotion, delta table shape and ordering, rejection of
non-conforming objects.
- tests/rec/test_report.py: markdown section headers, JSON
round-trip.
- tests/rec/pricers/test_pfs.py: registration, protocol conformance,
ground_truth row count, status-code filter, cent rounding,
summary counts against the seeded fixture, tolerance promotion,
missing-year KeyError.
Notebook:
- notebooks/pfs_reconciliation.py — marimo interactive runner with
year dropdown, tolerance slider, rendered summary markdown, delta
table, and warnings panel. Mirrors the structure of pfs_calcs.py.
Gaps surfaced by this work (not fixed in this commit, to be tracked
as follow-up issues):
1. pfs.calcs.payment.payment() ignores RuleYear.budget_neutrality_adjustor.
Silently correct for 2014–2025 since the value is 1.0, but a
future non-1 year will drift.
2. _LIMITING_CHARGE_FACTOR = 1.0925 is a magic constant inside
pfs/pipe.py at load time. Should be extracted to pfs.calcs and
the synthesized columns should be superseded by an actual CMS
source if one exists.
3. pfs.rvu.conv_factor is stale / often NULL. Single source of
truth should be pfs.rules.RULES; the column could be dropped.
4. Carrier file doesn't capture the header's stated CF so we can't
cross-check RULES[year].conversion_factor matches the file at
ingest time.
0 B
0 B
The file is empty.