Files
stack/tests/pfs/test_origin.py
kert 85663894f3
Some checks failed
CI / lint (push) Successful in 53s
CI / notebooks-smoke (push) Successful in 2m23s
Deploy / changes (push) Successful in 15s
CI / test (push) Failing after 4m54s
Infra CI / notebooks (push) Successful in 1m32s
Infra CI / zotero (push) Successful in 20s
Infra CI / api (push) Successful in 1m29s
Infra CI / docs (push) Successful in 1m35s
Infra CI / llm (push) Successful in 1m20s
Infra CI / mc (push) Successful in 21s
Deploy / notebooks (push) Has been skipped
Deploy / zotero (push) Has been skipped
Deploy / docs (push) Has been skipped
Infra CI / bcda (push) Successful in 3m17s
Deploy / api (push) Successful in 1m24s
Deploy / llm (push) Successful in 1m40s
Deploy / mc (push) Has been skipped
Deploy / bcda (push) Successful in 2m8s
Deploy / report (push) Successful in 22s
fix(pfs): origin — deletion rows from lineage; final-rule coverage rows tell a finalized removal; CFR part check for title 42 only
A family code with deleted + cpt_panel events at one FR paragraph gets a
cpt_panel row 'The CPT Editorial Panel deleted <code>, effective CY<year>.'
(extractor lineage) where a plain sentence reads as the Panel deleting it and
the paragraph writes the year; a model Panel row from the same rule that tells
a lineage-deleted code as merged, revised or retained is dropped. IOM/MLN rows
cited from FR paragraphs count only from final rules; a provision whose
removal the rule finalizes becomes a row saying what was removed and when,
citing the finalizing paragraph (ref_p_id = the citing one). Only title-42
parts outside the cited chapters are FR typos.
2026-11-12 04:00:47 -05:00

1658 lines
59 KiB
Python

"""pfs.origin — origin and formation rows (dossier task 6).
The EPUBs below are built in ``tmp_path`` from synthetic strings: the repo
holds no AMA text.
"""
from __future__ import annotations
import zipfile
from pathlib import Path
from types import SimpleNamespace
import duckdb
import pytest
from bib.item import Rule
from bib.store import Store
from pfs.codetables import (
ORIGIN_KINDS,
GuidanceRow,
OriginRow,
ensure_tables,
read_origin,
write_guidance,
write_origin,
)
from pfs.origin import (
ORIGIN_PROMPT_VERSION,
ORIGIN_SCHEMA,
_anchor,
_kind_of,
_longest_span,
_page_of,
action_of,
book_candidates,
book_deleted,
book_support,
extract_origin,
family_origin,
fr_origin_candidates,
guidance_origins,
origin_inventory,
origins_from_output,
resolve_book,
shares_run,
)
from pfs.runlog import RunLog
FAM = SimpleNamespace(
key="HOME-VISITS",
codes=("99341", "99342", "99350"),
synonyms=("home or residence services",),
)
CODES = FAM.codes
_CONTAINER = (
'<?xml version="1.0"?><container version="1.0" '
'xmlns="urn:oasis:names:tc:opendocument:xmlns:container"><rootfiles>'
'<rootfile full-path="OPS/book.opf" media-type="application/oebps-package+xml"/>'
"</rootfiles></container>"
)
_OPF = (
'<?xml version="1.0"?><package xmlns="http://www.idpf.org/2007/opf" version="3.0">'
'<manifest><item id="c1" href="c1.xhtml" media-type="application/xhtml+xml"/>'
'</manifest><spine><itemref idref="c1"/></spine></package>'
)
def make_epub(path: Path, pages: dict[str, str]) -> Path:
body = "".join(
f'<span id="page_{label}"/>'
+ "".join(f"<p>{para}</p>" for para in text.split("|"))
for label, text in pages.items()
)
with zipfile.ZipFile(path, "w") as zf:
zf.writestr("mimetype", "application/epub+zip")
zf.writestr("META-INF/container.xml", _CONTAINER)
zf.writestr("OPS/book.opf", _OPF)
zf.writestr("OPS/c1.xhtml", f"<html><body>{body}</body></html>")
return path
# synthetic stand-ins; the sentences are invented for the tests
PAGE12 = (
"\u25b6(99339 has been deleted. For other services see the care codes.)\u25c0"
"|Rationale|Codes 99341 and 99350 have been revised for 2023 to use total "
"time. Home visit code 99343 has been deleted."
)
BOOK_PAGES = {
"ix": "Preface with no code at all.",
"12": PAGE12,
"13": "Another page about 99342 only in an unrelated table.",
}
FR_STATUTE = (
"Section 1861(m) of the Act establishes the home health benefit, and CPT "
"code 99341 describes a home visit for a new patient."
)
FR_RECAP = (
"In the CY 2019 PFS final rule, we established the homebound exception "
"for CPT code 99342."
)
FR_REQUEST = (
"Commenters requested that section 1834(m) of the Act cover CPT code 99341."
)
FR_HYPO = (
"If we were to repeal section 1862(a)(1) of the Act, CPT code 99350 "
"would need to be revised."
)
FR_PLAIN = "CPT code 99350 is not subject to the demonstration."
def ask_with(items, calls=None):
def ask(system, user, schema):
if calls is not None:
calls.append((system, user, schema))
return {"origins": items}
ask.model = "qwen-test"
return ask
def item(**kw):
base = dict(
kind="statute",
reference="Section 1861(m) of the Act",
year=None,
codes=["99341"],
summary="The Act sets up the home health benefit.",
)
return {**base, **kw}
# ── pure guards ──────────────────────────────────────────────────────
def test_shares_run_is_case_and_punctuation_insensitive():
text = "The Panel, in 2022, adopted these Home-Visit entries for everyone."
assert shares_run(
"it said: the panel in 2022 adopted these home visit entries", text
)
assert not shares_run("the panel adopted entries about home visits", text)
assert not shares_run("too short", "too short") # fewer words than n
def test_book_summary_copy_guard():
page = PAGE12.replace("|", "\n")
copied = item(
kind="cpt_panel",
reference="CPT Editorial Panel action",
codes=["99341"],
summary="Codes 99341 and 99350 have been revised for 2023 to use total time.",
)
fresh = item(
kind="cpt_panel",
reference="CPT Editorial Panel action",
codes=["99350"],
summary="Editors revised the visit codes to be reported by time.",
)
out = origins_from_output(
{"origins": [copied, fresh]}, page, source="book", codes=CODES
)
assert [o["summary"] for o in out] == [fresh["summary"]]
# the reference is guarded as well
leaky = {
**fresh,
"reference": "codes 99341 and 99350 have been revised for 2023 to use",
}
assert origins_from_output({"origins": [leaky]}, page, source="book") == []
def test_fr_reference_must_appear():
ok = item()
missing = item(reference="section 1861(s)(1) of the Act")
out = origins_from_output(
{"origins": [missing, ok]}, FR_STATUTE, source="fr", codes=CODES
)
assert [o["reference"] for o in out] == ["Section 1861(m) of the Act"]
@pytest.mark.parametrize(
"text",
[FR_RECAP, FR_REQUEST, FR_HYPO],
ids=["recap", "commenter-request", "hypothetical"],
)
def test_fr_reference_must_sit_in_a_plain_sentence(text):
ref = {
FR_RECAP: "the homebound exception",
FR_REQUEST: "section 1834(m) of the Act",
FR_HYPO: "section 1862(a)(1) of the Act",
}[text]
code = {FR_RECAP: "99342", FR_REQUEST: "99341", FR_HYPO: "99350"}[text]
out = origins_from_output(
{"origins": [item(kind="program", reference=ref, codes=[code])]},
text,
source="fr",
codes=CODES,
rule_year=2023,
)
assert out == []
def test_fr_recap_of_the_same_year_is_a_plain_statement():
text = "In the CY 2023 PFS final rule, we established the homebound exception for CPT code 99342."
out = origins_from_output(
{
"origins": [
item(
kind="program", reference="the homebound exception", codes=["99342"]
)
]
},
text,
source="fr",
codes=CODES,
rule_year=2023,
)
assert len(out) == 1
def test_codes_outside_the_family_or_not_named_are_dropped():
out = origins_from_output(
{"origins": [item(codes=["99341", "99999", "99342", "99341"])]},
FR_STATUTE,
source="fr",
codes=CODES,
)
assert out[0]["codes"] == ["99341"] # 99999 foreign, 99342 not in the text
gone = origins_from_output(
{"origins": [item(codes=["99999"])]}, FR_STATUTE, source="fr", codes=CODES
)
assert gone == []
def test_code_ranges_in_the_text_name_every_code():
text = "Section 1861(m) of the Act covers CPT codes 99341-99342."
out = origins_from_output(
{"origins": [item(codes=["99342"])]}, text, source="fr", codes=CODES
)
assert len(out) == 1
def test_year_and_numbers_must_be_in_the_text():
ok = item(year=2023, summary="Section 1861 and 2023 set it up.")
text = "Section 1861(m) of the Act, effective 2023, sets it up for CPT code 99341."
[row] = origins_from_output({"origins": [ok]}, text, source="fr", codes=CODES)
assert row["year"] == 2023
# a year the text never states is dropped to null, not guessed
[row] = origins_from_output(
{"origins": [item(year=1965)]}, text, source="fr", codes=CODES
)
assert row["year"] is None
# a summary number the text lacks drops the item
assert (
origins_from_output(
{"origins": [item(summary="It began in 1988 under the Act.")]},
text,
source="fr",
codes=CODES,
)
== []
)
def test_origins_from_output_tolerates_missing_codes_filter_and_empty_output():
out = origins_from_output({"origins": [item()]}, FR_STATUTE, source="fr")
assert out[0]["codes"] == ["99341"]
assert origins_from_output({}, FR_STATUTE, source="fr") == []
assert (
origins_from_output({"origins": [item(codes=[])]}, FR_STATUTE, source="fr")
== []
)
def test_schema_and_version():
assert ORIGIN_PROMPT_VERSION == "origin-v1"
kinds = ORIGIN_SCHEMA["properties"]["origins"]["items"]["properties"]["kind"]
assert tuple(kinds["enum"]) == ORIGIN_KINDS
assert ORIGIN_KINDS == (
"statute",
"regulation",
"program",
"demonstration",
"cpt_panel",
"cms_gcode",
"coverage",
)
def test_extract_origin_asks_with_the_schema_and_filters():
calls: list = []
out = extract_origin(
FR_STATUTE,
ask_with([item(), item(reference="not in the text")], calls),
source="fr",
codes=CODES,
)
assert [o["reference"] for o in out] == ["Section 1861(m) of the Act"]
system, user, schema = calls[0]
assert schema is ORIGIN_SCHEMA and "99341" in user and FR_STATUTE in user
assert "never quote" in system.lower() or "paraphras" in system.lower()
def test_extract_origin_failed_reply_is_empty():
ask = lambda s, u, sc: None # noqa: E731
assert extract_origin(FR_STATUTE, ask, source="fr") == []
def test_extract_origin_book_system_differs_from_fr():
calls: list = []
extract_origin(BOOK_PAGES["12"], ask_with([], calls), source="book", codes=CODES)
extract_origin(FR_STATUTE, ask_with([], calls), source="fr", codes=CODES)
assert calls[0][0] != calls[1][0]
assert "8" in calls[0][0] or "eight" in calls[0][0].lower()
def test_extract_origin_rejects_an_unknown_source():
with pytest.raises(ValueError):
extract_origin("x", ask_with([]), source="web")
# ── candidates ───────────────────────────────────────────────────────
def test_book_candidates(tmp_path):
path = make_epub(tmp_path / "b.epub", {"": "Lead 99341 text.", **BOOK_PAGES})
got = book_candidates(path, CODES)
assert [label for label, _ in got] == ["12", "13"] # unlabeled text can't be cited
assert book_candidates(path, ()) == []
def test_book_candidates_see_code_ranges(tmp_path):
path = make_epub(tmp_path / "b.epub", {"4": "Codes 99341-99342 were revised."})
assert [label for label, _ in book_candidates(path, ("99342",))] == ["4"]
TITLE = "Medicare Program; CY 2023 PFS Final Rule"
def _store(tmp_path):
s = Store(":memory:", storage_dir=tmp_path / "st")
key = s.create(
Rule(title=TITLE, document_number="22-1", date_published="2022-11-18")
)
other = s.create(
Rule(
title="Home Health Rule",
document_number="22-2",
date_published="2022-06-01",
)
)
corr = s.create(
Rule(
title="CY 2023 PFS Final Rule; Correction",
document_number="22-3",
date_published="2023-01-01",
)
)
anchors = [
(key, 1, 100, 1, "An unrelated opening paragraph."),
(key, 2, 100, 2, FR_STATUTE),
(key, 3, 101, 3, "CPT code 99341 appears here with nothing about origins."),
(
key,
4,
101,
4,
"The home or residence services family includes a new benefit.",
),
(
other,
7,
55,
1,
"Section 1895 of the Act created the demonstration for 99350.",
),
(corr, 9, 1, 1, FR_STATUTE),
]
s._con().executemany(
"INSERT INTO fr_anchors (item_key, p_id, page, ordinal, text) VALUES (?,?,?,?,?)",
anchors,
)
for k, doc in ((key, "22-1"), (other, "22-2"), (corr, "22-3")):
s._con().execute(
"INSERT INTO fr_anchor_docs (item_key, document_number, html_url, start_page,"
" end_page, fr_volume) VALUES (?,?,'u',1,2,87)",
(k, doc),
)
s._con().commit()
return s, key, other
def test_fr_origin_candidates_filter(tmp_path):
s, key, other = _store(tmp_path)
got = fr_origin_candidates(s, CODES, FAM.synonyms)
assert [(g["item_key"], g["p_id"]) for g in got] == [(other, 7), (key, 2), (key, 4)]
first = got[1]
assert first["page"] == 100 and first["rule_year"] == 2023
assert first["rule_kind"] == "final" and first["text"] == FR_STATUTE
assert fr_origin_candidates(s, (), ()) == []
def test_resolve_book(tmp_path):
s = Store(":memory:", storage_dir=tmp_path / "st")
from bib.item import Source # noqa: PLC0415
key = s.create(Source(title="Synthetic Changes 2023"))
assert resolve_book(s, key) is None # no attachment
epub = make_epub(tmp_path / "book.epub", BOOK_PAGES)
s.attach_file(key, epub)
label, path = resolve_book(s, key)
assert label == "Synthetic Changes 2023" and path.name.endswith(".epub")
txt = tmp_path / "n.txt"
txt.write_text("x")
k2 = s.create(Source(title="No epub"))
s.attach_file(k2, txt)
assert resolve_book(s, k2) is None
# ── guidance ─────────────────────────────────────────────────────────
def _con():
c = duckdb.connect(":memory:")
ensure_tables(c)
return c
def _g(code, kind, locator, src="K1", p_id=5, page=100, item_key=""):
return GuidanceRow("HOME-VISITS", code, kind, locator, item_key, src, p_id, page)
def test_guidance_origins_map_kinds():
c = _con()
g = [
_g("99341", "cfr", "42 CFR 425.400(c)(1)(v)(A)"),
_g("99341", "cfr", "42 CFR 425.400(c)(1)(vi)", src="K2", p_id=9, page=200),
_g("99341", "cfr", "42 CFR 425.400(c)"),
_g("99341", "iom", "100-04 ch.12 §30.6.4", item_key="IOM1", p_id=6),
_g("99350", "mln", "MLN 907166", src="K3", p_id=0, page=0),
_g("99350", "cfr", "42 CFR 410.78(a)(3)"), # telehealth listing
_g("99350", "cfr", "a CFR cite we cannot parse"),
]
write_guidance(c, "HOME-VISITS", g)
rows = guidance_origins(c, "HOME-VISITS")
by = {(r.code, r.cite_kind, r.reference): r for r in rows}
# sub-paragraph variants are one row per CFR section; 410.78 is no origin
assert len(rows) == 4
cfr = by[("99341", "cfr", "42 CFR 425.400")]
assert (cfr.kind, cfr.extractor, cfr.ref_p_id) == ("regulation", "guidance", 0)
assert (cfr.item_key, cfr.p_id, cfr.page_label, cfr.year) == ("K1", 5, "100", None)
assert cfr.locator == "42 CFR 425.400" and len(cfr.summary) <= 240
assert by[("99341", "iom", "100-04 ch.12 §30.6.4")].kind == "coverage"
mln = by[("99350", "mln", "MLN 907166")]
assert mln.kind == "coverage" and mln.page_label == "" and mln.p_id == 0
assert ("99350", "cfr", "a CFR cite we cannot parse") in by
def test_guidance_drops_manual_provisions_the_citing_sentence_removes(tmp_path):
s, key, other = _store(tmp_path)
s._con().executemany(
"INSERT INTO fr_anchors (item_key, p_id, page, ordinal, text) VALUES (?,?,?,?,?)",
[
(
key,
50,
1,
50,
"We are removing the rule in Section 30.6.14.1 of the manual.",
),
(
key,
51,
1,
51,
"Section 30.6.14.2 is cited here. We remove other things.",
),
(key, 52, 1, 52, ""),
(key, 53, 1, 53, "We are eliminating Chapter 8 of the manual."),
(
key,
54,
1,
54,
"Chapter 26 sets place of service codes. We rescind nothing here.",
),
],
)
c = _con()
write_guidance(
c,
"HOME-VISITS",
[
_g("99341", "iom", "100-04 ch.12 §30.6.14.1", src=key, p_id=50),
_g("99341", "iom", "100-04 ch.12 §30.6.14.2", src=key, p_id=51),
_g("99341", "iom", "100-04 ch.26", src=key, p_id=54),
_g("99350", "iom", "100-04 ch.9", src=key, p_id=52),
_g("99350", "iom", "100-04 ch.8", src=key, p_id=53),
_g("99350", "iom", "100-04 ch.7", src=key, p_id=999),
_g("99350", "cfr", "42 CFR 425.20", src=key, p_id=50),
_g("99350", "cfr", "42 CFR 25.400(c)(1)(vi)", src=key, p_id=50),
],
)
kept = {(r.code, r.reference) for r in guidance_origins(c, "HOME-VISITS", s)}
# removal must be in the sentence that cites the section; a title-42
# CFR part that does not exist is an FR typo
assert kept == {
("99341", "100-04 ch.12 §30.6.14.2"),
("99341", "100-04 ch.26"),
("99350", "100-04 ch.9"),
("99350", "100-04 ch.7"),
("99350", "42 CFR 425.20"),
}
def test_the_cfr_part_check_is_for_title_42_only():
c = _con()
cites = [
"45 CFR 170.315(b)",
"45 CFR 164.502",
"21 CFR 882.5801",
"42 CFR 8.12",
"42 CFR 2.11",
"42 CFR 10.10",
"42 CFR 1001.952(h)",
"42 CFR 1008.1",
"42 CFR 425.20",
"42 CFR 25.400(c)(1)(vi)",
"42 CFR 160.103",
]
write_guidance(c, "HOME-VISITS", [_g("99341", "cfr", x) for x in cites])
kept = {r.reference for r in guidance_origins(c, "HOME-VISITS")}
assert kept == {
"45 CFR 170.315",
"45 CFR 164.502",
"21 CFR 882.5801",
"42 CFR 8.12",
"42 CFR 2.11",
"42 CFR 10.10",
"42 CFR 1001.952",
"42 CFR 1008.1",
"42 CFR 425.20",
}
# public FR text: CY 2019 PFS proposed rule (83 FR 35835, CWGP3WJG ¶702)
# and final rule (83 FR 59630, 9V89NVZG ¶1622-¶1624), CY 2023 final
# (PETM225D ¶3607)
P702 = (
"Medicare pays for E/M visits furnished in the home (a private residence) "
"under CPT codes 99341 through 99350. However, there is a Medicare Claims "
"Processing Manual provision requiring that the medical record must "
"document the medical necessity of the home visit made in lieu of an office "
"or outpatient visit (Pub. 100-04, Medicare Claims Processing Manual, "
"Chapter 12, Section 30.6.14.1.B). We agree, so we are proposing to remove "
"the requirement that the medical record must document the medical "
"necessity of furnishing the visit in the home rather than in the office."
)
P1622 = P702.replace("We agree, so we are proposing", "We agreed, so we proposed")
P1623 = (
"Comment: Commenters were generally supportive of our proposal to remove the "
"requirement that the medical record must document the medical necessity of "
"furnishing the visit in the home rather than in the office."
)
P1624 = (
"Response: We are finalizing this policy change to remove the requirement "
"that the medical record must document the medical necessity of furnishing "
"the visit in the home rather than in the office, as proposed, effective "
"January 1, 2019."
)
P3607 = (
"As described in Medicare Claims Processing Manual, Publication 100-04, "
"Chapter 26, place of service codes are two-digit codes placed on health care "
"professional claims for CPT codes 99341 through 99350."
)
def _cy2019_store(tmp_path):
s = Store(":memory:", storage_dir=tmp_path / "st")
prop = s.create(
Rule(
title="Medicare Program; CY 2019 PFS Proposed Rule",
document_number="18-1",
date_published="2018-07-27",
)
)
final = s.create(
Rule(
title="Medicare Program; CY 2019 PFS Final Rule",
document_number="18-2",
date_published="2018-11-23",
)
)
s._con().executemany(
"INSERT INTO fr_anchors (item_key, p_id, page, ordinal, text) VALUES (?,?,?,?,?)",
[
(prop, 702, 35835, 1, P702),
(final, 1622, 59630, 1, P1622),
(final, 1623, 59630, 2, P1623),
(final, 1624, 59631, 3, P1624),
(final, 3607, 59700, 4, P3607),
(final, 3608, 59700, 5, "We remove the requirement that X be done."),
(final, 3609, 59700, 6, "We are finalizing the removal of Y."),
],
)
s._con().execute(
"INSERT INTO fr_anchor_docs (item_key, document_number, html_url, start_page,"
" end_page, fr_volume) VALUES (?,?,'u',1,2,83)",
(final, "18-2"),
)
s._con().commit()
return s, prop, final
def test_coverage_rows_cite_final_rules_and_tell_a_finalized_removal(tmp_path):
s, prop, final = _cy2019_store(tmp_path)
c = _con()
sec = "100-04 ch.12 §30.6.14.1"
write_guidance(
c,
"HOME-VISITS",
[
_g("99341", "iom", sec, src=prop, p_id=702, page=35835),
_g("99341", "iom", sec, src=final, p_id=1622, page=59630),
_g("99342", "iom", sec, src=prop, p_id=702, page=35835),
_g("99341", "iom", "100-04 ch.26", src=prop, p_id=702, page=35835),
_g("99341", "iom", "100-04 ch.26", src=final, p_id=3607, page=59700),
_g("99341", "iom", "100-04 ch.9", src=final, p_id=3608, page=59700),
_g("99350", "mln", "MLN 907166", src=prop, p_id=702, page=35835),
_g("99350", "mln", "MLN 1", src="CPT2023", p_id=0, page=0),
],
)
rows = guidance_origins(c, "HOME-VISITS", s)
by = {(r.code, r.reference): r for r in rows}
# proposal-cited rows are gone (99342 has only the proposal), a CPT
# edition's MLN cite stays
assert set(by) == {
("99341", sec),
("99341", "100-04 ch.26"),
("99341", "100-04 ch.9"),
("99350", "MLN 1"),
}
gone = by[("99341", sec)]
assert gone.summary == (
"The CY2019 final rule removed the requirement in 100-04 ch.12 §30.6.14.1 "
"that the medical record must document the medical necessity of "
"furnishing the visit in the home rather than in the office, effective "
"January 1, 2019."
)
assert (gone.kind, gone.cite_kind, gone.year, gone.extractor) == (
"coverage",
"iom",
2019,
"guidance",
)
assert (gone.item_key, gone.p_id, gone.ref_p_id, gone.page_label) == (
final,
1624,
1622,
"59631",
)
assert gone.locator == f"{sec}; 83 FR 59631, ¶1624 (reference ¶1622)"
pos = by[("99341", "100-04 ch.26")]
assert (pos.item_key, pos.p_id, pos.ref_p_id) == (final, 3607, 0)
assert pos.summary == "CMS guidance for 99341 points to 100-04 ch.26."
# "remove the requirement that X" never finalized: no removal row
assert by[("99341", "100-04 ch.9")].p_id == 3608
def test_removal_row_without_a_volume_year_or_effective_date(tmp_path):
from pfs.origin import _removal_row # noqa: PLC0415
g = _g("99341", "iom", "100-04 ch.12 §1", src="K", p_id=7)
found = {"p_id": 7, "page": 12, "req": "x " * 150, "effective": ""}
row = _removal_row(g, "100-04 ch.12 §1", ("final", None, ""), found)
# too long for 240 characters: the requirement is left out
assert row.summary == "The final rule removed a requirement in 100-04 ch.12 §1."
assert row.locator == "100-04 ch.12 §1; FR p. 12, ¶7" and row.year is None
# ── deletions from lineage ───────────────────────────────────────────
FAM_DEL = SimpleNamespace(
key="HOME-VISITS",
codes=("99324", "99339", "99341", "99343", "99350"),
synonyms=(),
)
# public FR text, CY 2023 PFS final rule (87 FR 69440 ¶390, 87 FR 69608 ¶1672)
P390 = (
"That said, in February 2021, the AMA CPT Editorial Panel deleted the family "
"of domiciliary codes, CPT codes 99324 to 99340, and merged the services "
"described by those codes into the existing family of home-based E/M visits, "
"CPT codes 99341 to 99350 (a range of codes that includes CPT codes 99344, "
"99345, 99349, and 99350). We stated that we were not considering these "
"home-based E/M visits as potentially misvalued for CY 2023."
)
P1672 = (
"More specifically, in its February 2021 meeting, effective beginning in 2023, "
"the CPT Editorial Panel deleted the nine CPT codes in the Domiciliary, Rest "
"Home (for example, Boarding Home), or Custodial Care Services code family "
"(CPT codes 99324-99328, and 99334-99337), and one CPT code in the Home "
"Services family (CPT code 99343), to merge these services with the eight "
"remaining home visit services. The eight remaining home services CPT codes "
"(99341, 99342, 99344, 99345, and 99347-99350) were revised to describe Home "
"or Residence Services."
)
MERGED = (
"The AMA CPT Editorial Panel deleted domiciliary codes 99324-99340 and merged "
"them into the existing home-based E/M visit codes 99341-99350."
)
def _ev(code, kind, key, p_id, year=2023):
from pfs.codetables import EventRow # noqa: PLC0415
return EventRow(code, year, kind, "", "", key, p_id, 1, "fr", True, "")
def _deletion_store(tmp_path):
s, key = _chain_store(
tmp_path,
[
(390, 69440, P390),
(1672, 69608, P1672),
(1700, 69610, "The CPT Editorial Panel deleted CPT code 99324 then."),
(
1701,
69610,
"In the CY 2021 PFS final rule, the CPT Editorial Panel deleted CPT "
"code 99324, effective 2023.",
),
],
)
corr = s.create(
Rule(
title="CY 2023 PFS Final Rule; Correction",
document_number="22-9",
date_published="2023-01-01",
)
)
s._con().execute(
"INSERT INTO fr_anchors (item_key, p_id, page, ordinal, text) VALUES (?,?,?,?,?)",
(corr, 5, 1, 5, "In 2023 the CPT Editorial Panel deleted CPT code 99324."),
)
s._con().commit()
return s, key, corr
def test_deletions_come_from_lineage_and_misstated_fates_are_dropped(tmp_path):
from pfs.codetables import write_events # noqa: PLC0415
s, key, corr = _deletion_store(tmp_path)
c = _con()
both = ("deleted", "cpt_panel")
write_events(
c,
"99324",
[_ev("99324", k, key, p) for k in both for p in (390, 1672, 1700, 1701)]
+ [_ev("99324", k, corr, 5) for k in both]
+ [_ev("99324", "deleted", key, 999), _ev("99324", "cpt_panel", key, 999)]
+ [_ev("99324", "telehealth_list", key, 1672)],
)
write_events(c, "99339", [_ev("99339", k, key, 390) for k in both])
write_events(c, "99343", [_ev("99343", k, key, 1672) for k in both])
write_events(c, "99341", [_ev("99341", "cpt_panel", key, 1672)])
def ask(system, user, schema):
passage = user.split("PASSAGE:")[1]
if "That said" in passage:
return {
"origins": [
item(
kind="cpt_panel",
reference="AMA CPT Editorial Panel",
codes=["99324", "99339", "99341", "99343", "99350"],
year=2021,
summary=MERGED,
)
]
}
if "More specifically" in passage:
# the model leaves out 99343
return {
"origins": [
item(
kind="cpt_panel",
reference="CPT Editorial Panel",
codes=["99324", "99341", "99350"],
year=2023,
summary="The panel deleted and revised codes to merge "
"the services into a single family.",
)
]
}
return {"origins": []}
ask.model = "qwen-test"
rows, _ = family_origin(
c, s, FAM_DEL, ask=ask, log=RunLog(tmp_path / "l"), books=[]
)
got = {(r.code, r.p_id, r.year, r.extractor[:7]) for r in rows}
assert got == {
# ¶390: the model row stands for the deleted codes it tells as
# deleted and for the merge targets; 99343 (deleted in this rule)
# is no merge target
("99324", 390, 2021, "model:q"),
("99339", 390, 2021, "model:q"),
("99341", 390, 2021, "model:q"),
("99350", 390, 2021, "model:q"),
# ¶1672: the deleted codes from lineage (the sentence writes 2023),
# the survivors from the model
("99324", 1672, 2023, "lineage"),
("99343", 1672, 2023, "lineage"),
("99341", 1672, 2023, "model:q"),
("99350", 1672, 2023, "model:q"),
# ¶390 is the only paragraph deleting 99339 in 2023
("99339", 390, 2023, "lineage"),
}
r = next(r for r in rows if (r.code, r.p_id) == ("99343", 1672))
assert r.summary == "The CPT Editorial Panel deleted 99343, effective CY2023."
assert (r.kind, r.reference, r.cite_kind, r.item_key, r.ref_p_id) == (
"cpt_panel",
"CPT Editorial Panel",
"fr_para",
key,
1672,
)
assert (r.page_label, r.locator) == ("69608", "87 FR 69608, ¶1672")
def test_lineage_origins_need_a_supporting_paragraph(tmp_path):
from pfs.origin import lineage_origins # noqa: PLC0415
s, key, corr = _deletion_store(tmp_path)
both = ("deleted", "cpt_panel")
events = {
# ¶1700 does not write the year; ¶1701 recaps another year's rule;
# the correction notice and a missing paragraph support nothing
"99324": [_ev("99324", k, key, p) for k in both for p in (1700, 1701, 999)]
+ [_ev("99324", k, corr, 5) for k in both],
# deleted and cpt_panel at different paragraphs
"99343": [_ev("99343", "deleted", key, 390), _ev("99343", "cpt_panel", key, 1)],
# ¶390 names 99341 only as a merge target
"99341": [_ev("99341", k, key, 390) for k in both],
}
assert lineage_origins(s, FAM_DEL, events) == []
def test_misstates_deletion():
from pfs.origin import misstates_deletion # noqa: PLC0415
assert misstates_deletion(MERGED, "99343") # a merge target
assert not misstates_deletion(MERGED, "99324")
assert misstates_deletion("The Panel revised CPT code 99343.", "99343")
assert misstates_deletion("The Panel revised the home visit codes.", "99343")
assert not misstates_deletion("The Panel deleted and revised codes.", "99343")
assert not misstates_deletion("The Panel acted on the codes.", "99343")
# ── family run ───────────────────────────────────────────────────────
def test_origin_rows_carry_page_label_for_book(tmp_path):
s, key, other = _store(tmp_path)
epub = make_epub(tmp_path / "b.epub", BOOK_PAGES)
book_item = ("BOOK1", "Synthetic Changes 2023", epub)
paraphrase = item(
kind="cpt_panel",
reference="CPT Editorial Panel action",
codes=["99341", "99350"],
summary="Editors revised the visit codes to be reported by time.",
year=2023,
)
gone = {**paraphrase, "codes": ["99339"], "summary": "Editors deleted the code."}
ask = ask_with([paraphrase, gone])
c = _con()
rows, counts = family_origin(
c, s, FAM, ask=ask, log=RunLog(tmp_path / "l.jsonl"), books=[book_item]
)
book = [r for r in rows if r.cite_kind == "cpt_book"]
# 99339 is not a family code; page 13 has no prose
assert {(r.code, r.page_label, r.p_id, r.item_key) for r in book} == {
("99341", "12", 0, "BOOK1"),
("99350", "12", 0, "BOOK1"),
}
r = book[0]
assert r.locator == "Synthetic Changes 2023, p. 12" and r.year == 2023
assert r.extractor == f"model:qwen-test@{ORIGIN_PROMPT_VERSION}"
assert r.ref_p_id == 0
assert all(len(r.summary) <= 240 for r in rows)
assert counts["failed"] == 0
def test_family_origin_fr_rows_cite_the_paragraph(tmp_path):
s, key, other = _store(tmp_path)
ask = ask_with(
[
item(codes=["99341"]),
item(reference="not in the paragraph", codes=["99341"]),
]
)
c = _con()
write_guidance(
c,
"HOME-VISITS",
[GuidanceRow("HOME-VISITS", "99341", "cfr", "42 CFR 425.20", "", key, 2, 100)],
)
rows, counts = family_origin(
c, s, FAM, ask=ask, log=RunLog(tmp_path / "l.jsonl"), books=[]
)
fr = [r for r in rows if r.cite_kind == "fr_para"]
assert [(r.code, r.item_key, r.p_id, r.ref_p_id, r.page_label) for r in fr] == [
("99341", key, 2, 2, "100")
]
assert fr[0].locator == "87 FR 100, ¶2" and fr[0].kind == "statute"
assert [r.cite_kind for r in rows if r.extractor == "guidance"] == ["cfr"]
assert counts == {"done": 2, "skipped": 0, "failed": 0, "failed_pending": 0}
def _chain_store(tmp_path, paras, *, volume="87"):
s = Store(":memory:", storage_dir=tmp_path / "st")
key = s.create(
Rule(title=TITLE, document_number="22-1", date_published="2022-11-18")
)
s._con().executemany(
"INSERT INTO fr_anchors (item_key, p_id, page, ordinal, text) VALUES (?,?,?,?,?)",
[(key, p, pg, p, t) for p, pg, t in paras],
)
if volume:
s._con().execute(
"INSERT INTO fr_anchor_docs (item_key, document_number, html_url, start_page,"
" end_page, fr_volume) VALUES (?,?,'u',1,2,?)",
(key, "22-1", volume),
)
s._con().commit()
return s, key
def test_the_reference_may_come_from_a_context_paragraph(tmp_path):
s, key = _chain_store(
tmp_path,
[
(
8,
100,
"Section 1833(x)(2)(B) of the Act defines primary care services:",
),
(
9,
101,
"( printed page 101) The benefit covers CPT codes 99341 through 99350.",
),
],
)
it = item(
reference="Section 1833(x)(2)(B) of the Act",
codes=["99341", "99342", "99350"],
summary="A payment incentive for primary care.",
)
calls: list = []
rows, _ = family_origin(
_con(), s, FAM, ask=ask_with([it], calls), log=RunLog(tmp_path / "l"), books=[]
)
assert {(r.code, r.p_id, r.ref_p_id, r.kind) for r in rows} == {
("99341", 9, 8, "statute"),
("99342", 9, 8, "statute"),
("99350", 9, 8, "statute"),
}
r = rows[0]
assert r.page_label == "100" and r.locator == "87 FR 100, ¶9 (reference ¶8)"
# the model saw the preceding paragraph as context
assert "[¶8] Section 1833(x)(2)(B)" in calls[-1][1]
assert "PASSAGE:" in calls[-1][1]
def test_a_reference_in_a_context_paragraph_needs_the_codes_in_the_passage(tmp_path):
s, key = _chain_store(
tmp_path,
[
(8, 100, "Section 1833(x)(2)(B) of the Act defines primary care services:"),
(9, 101, "The benefit covers CPT codes 99200 through 99210 and 99350."),
],
)
it = item(
reference="Section 1833(x)(2)(B) of the Act",
codes=["99341"],
summary="A payment incentive.",
)
rows, _ = family_origin(
_con(), s, FAM, ask=ask_with([it]), log=RunLog(tmp_path / "l"), books=[]
)
assert rows == []
def test_fr_page_is_the_printed_page_before_the_reference_sentence(tmp_path):
text = (
"We note the earlier meeting. ( printed page 45883) The CPT Editorial "
"Panel deleted CPT code 99341 in 2021."
)
s, key = _chain_store(tmp_path, [(5, 45882, text)])
it = item(
kind="cpt_panel",
reference="CPT Editorial Panel",
codes=["99341"],
year=2021,
summary="The panel deleted the code.",
)
rows, _ = family_origin(
_con(), s, FAM, ask=ask_with([it]), log=RunLog(tmp_path / "l"), books=[]
)
assert (rows[0].page_label, rows[0].locator) == ("45883", "87 FR 45883, ¶5")
# no volume on file: no volume in the locator; no marker: the paragraph page
s2, _ = _chain_store(
tmp_path / "b",
[(5, 45882, text.replace("( printed page 45883)", ""))],
volume="",
)
rows, _ = family_origin(
_con(), s2, FAM, ask=ask_with([it]), log=RunLog(tmp_path / "l2"), books=[]
)
assert (rows[0].page_label, rows[0].locator) == ("45882", "FR p. 45882, ¶5")
def test_fr_rows_dedupe_across_paragraphs_prefer_the_final_rule(tmp_path):
s = Store(":memory:", storage_dir=tmp_path / "st")
prop = s.create(
Rule(
title="Medicare Program; CY 2023 PFS Proposed Rule",
document_number="22-0",
date_published="2022-07-01",
)
)
final = s.create(
Rule(title=TITLE, document_number="22-1", date_published="2022-11-18")
)
s._con().executemany(
"INSERT INTO fr_anchors (item_key, p_id, page, ordinal, text) VALUES (?,?,?,?,?)",
[
(
prop,
3,
10,
1,
"The AMA CPT Editorial Panel deleted CPT code 99341 in 2021.",
),
(
final,
7,
20,
1,
"The CPT Editorial Panel deleted CPT code 99341 in 2021.",
),
(
final,
8,
20,
2,
"The CPT Editorial Panel deleted CPT code 99350 in 2021.",
),
],
)
s._con().commit()
def ask(system, user, schema):
ref = "AMA CPT Editorial Panel" if "AMA CPT" in user else "CPT Editorial Panel"
return {
"origins": [
item(
kind="cpt_panel",
reference=ref,
codes=["99341", "99350"],
year=2021,
summary="The panel deleted it.",
)
]
}
ask.model = "qwen-test"
rows, _ = family_origin(
_con(), s, FAM, ask=ask, log=RunLog(tmp_path / "l"), books=[]
)
got = {(r.code, r.item_key, r.p_id, r.reference) for r in rows}
# one row per code; the final rule's paragraph wins; "AMA" is normalised away
assert got == {
("99341", final, 7, "CPT Editorial Panel"),
("99350", final, 8, "CPT Editorial Panel"),
}
def test_family_origin_resumes_and_replays_without_a_model(tmp_path):
s, key, other = _store(tmp_path)
epub = make_epub(tmp_path / "b.epub", BOOK_PAGES)
books = [("BOOK1", "Synthetic Changes 2023", epub)]
log = RunLog(tmp_path / "l.jsonl")
calls: list = []
ask = ask_with([item()], calls)
first, c1 = family_origin(_con(), s, FAM, ask=ask, log=log, books=books)
n = len(calls)
assert c1["done"] == n and n > 0
# a second run with the same ledger asks nothing
again, c2 = family_origin(_con(), s, FAM, ask=ask, log=log, books=books)
assert len(calls) == n and c2["skipped"] == n and again == first
# no model: the finished ledger is replayed, model rows are kept
replay, c3 = family_origin(
_con(),
s,
FAM,
ask=None,
log=RunLog(tmp_path / "l.jsonl"),
books=books,
replay_model="qwen-test",
)
assert replay == first and c3 == {
"done": 0,
"skipped": 0,
"failed": 0,
"failed_pending": 0,
}
# no model and nothing to replay: only the deterministic guidance rows
none, _ = family_origin(_con(), s, FAM, ask=None, log=None, books=books)
assert none == []
def test_family_origin_ledger_holds_no_copied_book_text(tmp_path):
s, key, other = _store(tmp_path)
epub = make_epub(tmp_path / "b.epub", BOOK_PAGES)
copied = item(
kind="cpt_panel",
reference="CPT Editorial Panel",
codes=["99341"],
summary="Codes 99341 and 99350 have been revised for 2023 to use total time.",
)
log = RunLog(tmp_path / "l.jsonl")
rows, _ = family_origin(
_con(),
s,
FAM,
ask=ask_with([copied]),
log=log,
books=[("BOOK1", "Synthetic Changes 2023", epub)],
)
assert not [r for r in rows if r.cite_kind == "cpt_book"]
lines = (tmp_path / "l.jsonl").read_text().splitlines()
book = [ln for ln in lines if '"unit": "book:BOOK1:12' in ln]
assert book and all("have been revised for 2023 to use" not in ln for ln in book)
def test_family_origin_limit_failed_and_retry(tmp_path):
s, key, other = _store(tmp_path)
log = RunLog(tmp_path / "l.jsonl")
ask = ask_with([item()])
_, c = family_origin(_con(), s, FAM, ask=ask, log=log, books=[], limit=1)
assert c["done"] == 1
failing = lambda sy, u, sc: None # noqa: E731
failing.model = "qwen-test"
_, c = family_origin(_con(), s, FAM, ask=failing, log=log, books=[])
assert c["failed"] == 1 and c["skipped"] == 1
_, c = family_origin(_con(), s, FAM, ask=failing, log=log, books=[])
assert c["failed_pending"] == 1
_, c = family_origin(_con(), s, FAM, ask=ask, log=log, books=[], retry_failed=True)
assert c["done"] == 1
def test_origin_inventory(tmp_path):
s, key, other = _store(tmp_path)
epub = make_epub(tmp_path / "b.epub", BOOK_PAGES)
paras, pages = origin_inventory(s, FAM, [("BOOK1", "Synthetic Changes 2023", epub)])
assert len(paras) == 2 and pages == {"BOOK1": ["12", "13"]}
# ── writers ──────────────────────────────────────────────────────────
def _row(**kw):
base = dict(
family="HOME-VISITS",
code="99341",
kind="statute",
reference="Section 1861(m) of the Act",
year=None,
summary="A paraphrase.",
cite_kind="fr_para",
item_key="K",
p_id=2,
page_label="100",
locator="FR p. 100, ¶2",
extractor="m",
)
return OriginRow(**{**base, **kw})
def test_write_read_origin_round_trip_and_replace():
c = duckdb.connect(":memory:")
rows = [_row(), _row(code="99350", year=2023), _row(year=1965, reference="A")]
assert write_origin(c, "HOME-VISITS", rows) == 3
write_origin(c, "OTHER", [_row(family="OTHER")])
got = read_origin(c, "HOME-VISITS")
assert len(got) == 3 and got[0].year is None and got[1].year == 1965
assert write_origin(c, "HOME-VISITS", [_row()]) == 1
assert len(read_origin(c, "HOME-VISITS")) == 1 and len(read_origin(c, "OTHER")) == 1
assert write_origin(c, "HOME-VISITS", []) == 0
def _fr(it, text, **kw):
return origins_from_output({"origins": [it]}, text, source="fr", codes=CODES, **kw)
def test_kind_follows_what_the_reference_is():
# a section of the Act is a statute whatever the model called it
[row] = _fr(item(kind="regulation"), FR_STATUTE)
assert row["kind"] == "statute"
text = "Section 425.20 of 42 CFR defines primary care services for CPT code 99341."
[row] = _fr(item(kind="statute", reference="of 42 CFR"), text)
assert row["kind"] == "regulation"
# a statute/regulation claim no reference supports is dropped
assert (
_fr(
item(kind="regulation", reference="the CY 2026 MPFS"),
"The CY 2026 MPFS covers CPT code 99341.",
)
== []
)
# a G-code creation must name a HCPCS code
g = "CMS created HCPCS code G2211 to pay for visits with CPT code 99341."
assert _fr(item(kind="cms_gcode", reference="HCPCS code G2211"), g)
assert (
_fr(
item(kind="cms_gcode", reference="a new add-on"),
"A new add-on exists for CPT code 99341.",
)
== []
)
def test_pointers_into_the_same_rule_and_proposals_are_no_origin():
ptr = "Section II.F. of this proposed rule covers the program for CPT code 99341."
assert (
_fr(item(kind="program", reference="section II.F. of this proposed rule"), ptr)
== []
)
text = "The program for CPT code 99341 is described in the telehealth section."
assert (
_fr(
item(
kind="program",
reference="The program",
summary="Proposes to add the codes.",
),
text,
)
== []
)
assert _fr(
item(kind="program", reference="The program", summary="It adds the codes."),
text,
)
def test_codes_must_sit_near_the_sentence_that_writes_the_reference():
text = (
"Section 1861(m) of the Act establishes the home health benefit. "
"That is all it does. Unrelated sentence here. "
"Later we discuss CPT code 99341 in a different context."
)
# 99341 is three sentences from the reference sentence: no origin for it
assert _fr(item(codes=["99341"]), text) == []
near = (
"Section 1861(m) of the Act establishes the home health benefit. "
"It covers CPT code 99341."
)
assert _fr(item(codes=["99341"]), near)
def test_a_summary_naming_codes_applies_only_to_those_codes():
text = "Section 1861(m) of the Act covers CPT codes 99341, 99342 and 99350."
out = _fr(
item(
codes=["99341", "99342", "99350"],
summary="The Act covers codes 99341-99342.",
),
text,
)
assert out[0]["codes"] == ["99341", "99342"]
# a summary naming no code keeps every named code
assert _fr(item(codes=["99341", "99350"]), text)[0]["codes"] == ["99341", "99350"]
def test_book_rows_are_one_per_code_kind_action_on_the_subject_page(tmp_path):
s, key, other = _store(tmp_path)
pages = {
# conforming change elsewhere: names 99341 but only conforms a section
"5": "Rationale|In accordance with the revision of codes 99341, the notes were revised.",
# a section note only (deleted), earlier than the subject page
"6": "\u25b6(99339 has been deleted. See care codes.)\u25c0|Plain text.",
# the subject page: a Rationale sentence about the code
"7": "\u25b6(99339 has been deleted. See care codes.)\u25c0|Rationale|Codes 99341 and 99350 have been revised for 2023.|Code 99343 has been deleted.",
# a later restatement
"8": "Rationale|Code 99341 has been revised to use time.",
}
epub = make_epub(tmp_path / "b.epub", pages)
it = item(
kind="cpt_panel",
reference="CPT Editorial Panel action",
codes=["99341", "99350", "99343", "99339"],
summary="Editors revised the visit codes to be reported by time.",
)
fam = SimpleNamespace(
key="HOME-VISITS", codes=("99341", "99350", "99339", "99343"), synonyms=()
)
rows, _ = family_origin(
_con(),
s,
fam,
ask=ask_with([it]),
log=RunLog(tmp_path / "l"),
books=[("B", "Synthetic Changes 2023", epub)],
)
book = {(r.code, r.page_label) for r in rows if r.cite_kind == "cpt_book"}
# revised: the subject page 7 (not the conforming 5, not the later 8);
# the deleted codes are never "revised"
assert book == {("99341", "7"), ("99350", "7")}
gone = {**it, "summary": "Editors deleted these codes."}
rows, _ = family_origin(
_con(),
s,
fam,
ask=ask_with([gone]),
log=RunLog(tmp_path / "l2"),
books=[("B", "Synthetic Changes 2023", epub)],
)
book = {(r.code, r.page_label) for r in rows if r.cite_kind == "cpt_book"}
# a Rationale sentence beats a section note; 99339 has only the note (page 6 first)
assert book == {("99343", "7"), ("99339", "6")}
def test_book_support_levels_and_guards():
deleted = {"99339", "99343"}
page = (
"\u25b6(99339 has been deleted. For services see other codes.)\u25c0\n"
"Rationale\n"
"Code 99343 has been deleted. Codes 99341-99343 have been revised for time. "
"In accordance with the deletion of codes 99350, the notes were revised. "
"Code 99350 has been revised."
)
assert book_support(page, "99339", deleted) == {"deleted": "note"}
assert book_support(page, "99343", deleted) == {"deleted": "own"} # never revised
assert book_support(page, "99341", deleted) == {"revised": "own"}
# deleted only when the book marks the code deleted
assert book_support(page, "99350", deleted) == {"revised": "own"}
assert book_support(page, "99342", deleted) == {"revised": "own"}
# no heading and no note: nothing; an index page: nothing
assert book_support("99341 Home visit, 20 minutes.", "99341", deleted) == {}
index = (
" ".join(f"{n} (deleted) 1, 2" for n in range(99320, 99326))
+ " Rationale 99341 revised"
)
assert book_support(index, "99341", deleted) == {}
# a sentence with a verb for another code only
assert book_support("Rationale\nCode 99342 has been revised.", "99341", ()) == {}
def test_book_deleted_and_action_of():
pages = [
("1", "Codes 99324-99328 and 99334, 99336 have been deleted."),
(
"2",
"In accordance with the deletion of codes 99339 and 99340, the note changed.",
),
("3", "99350 (deleted) 4, 5 and 99351 (revised) 6"),
("4", "Codes 99360 through 99362 have been deleted."),
]
assert book_deleted(pages) == {
"99324", "99325", "99326", "99327", "99328", "99334", "99336",
"99339", "99340", "99350", "99360", "99361", "99362",
} # fmt: skip
assert action_of("Deleted the codes.") == "deleted"
assert action_of("Revised and combined codes.") == "revised"
assert action_of("The panel added a new code.") == "created"
assert action_of("Editors did something.") is None
def test_anchor_keeps_trims_or_rejects_the_models_wording():
text = "In February 2021 the CPT Editorial Panel deleted codes under section 1861(m) of the Act."
# verbatim
assert _anchor("CPT Editorial Panel", text) == (
"CPT Editorial Panel",
"CPT Editorial Panel",
)
# the longest verbatim span of the wording that holds the body is stored
# ("decision"/"meeting" are not in the text, so they are never stored)
assert _anchor("CPT Editorial Panel meeting in February 2021", text) == (
"CPT Editorial Panel",
"CPT Editorial Panel",
)
assert _anchor("the CPT Editorial Panel deleted codes yesterday", text) == (
"the CPT Editorial Panel deleted codes",
"CPT Editorial Panel",
)
assert _longest_span("CPT Editorial Panel x", "CPT Editorial Panel", "y") == (
"CPT Editorial Panel"
)
# the body inside the wording has other casing: nothing verbatim around it
assert _longest_span("a CPT editorial panel b", "CPT Editorial Panel", "x") == (
"CPT Editorial Panel"
)
# else trimmed to the longest verbatim body
assert _anchor("CPT Editorial Panel meeting in March 2021", text) == (
"CPT Editorial Panel",
"CPT Editorial Panel",
)
assert _anchor("under section 1861(m) of the Act, as amended", text)[1] == (
"section 1861(m) of the Act"
)
cfr = "The rule at 42 CFR 425.400(c) says so, and § 425.20 too."
assert _anchor("the 42 CFR 425.400(c)(1) rule", cfr) == (
"42 CFR 425.400(c)",
"42 CFR 425.400(c)",
)
assert (
_anchor("the rule in § 425.20(a)", cfr) is None
) # never cut to a bare section
# "of the Act" cut off; a deeper subsection the text lacks is no match
assert (
_anchor("section 1861(m) as amended", "See section 1861(m) there.")[1]
== "section 1861(m)"
)
assert _anchor("section 1861(s)(1) of the Act", text) is None
assert _anchor("a program we never name", text) is None
assert _anchor("the Act of 1965 and section 1861(m)", "Nothing about it.") is None
def test_kind_of_settles_statute_and_regulation_by_reference():
k = lambda kind, ref: _kind_of({"kind": kind, "reference": ref}) # noqa: E731
assert k("regulation", "42 U.S.C. § 1395x") == "statute" # bare § is not CFR
assert k("statute", "section 1866E of the Act") == "statute"
assert k("statute", "42 CFR 425.20") == "regulation"
assert k("regulation", "§ 425.20") == "regulation"
assert k("regulation", "the CY 2026 MPFS") is None
assert k("statute", "§ 1395x") is None
# a program that cites the Act stays a program
assert k("program", "the program under section 1866E of the Act") == "program"
assert k("demonstration", "Independence at Home") == "demonstration"
assert k("cms_gcode", "a new add-on") is None
assert k("cms_gcode", "HCPCS code G2211") == "cms_gcode"
def test_page_of_falls_back_when_the_anchor_is_split_by_a_marker():
text = "The CPT ( printed page 9) Editorial Panel acted."
assert _page_of(text, "CPT Editorial Panel", 5) == 5
assert _page_of(text, "The CPT", 5) == 5
assert (
_page_of("( printed page 7) The CPT Editorial Panel", "CPT Editorial Panel", 5)
== 7
)
def test_ensure_tables_adds_ref_p_id_to_an_old_table():
c = duckdb.connect(":memory:")
c.execute("CREATE SCHEMA pfs")
c.execute(
"CREATE TABLE pfs.code_origin (family VARCHAR, code VARCHAR, kind VARCHAR, "
"reference VARCHAR, year INTEGER, summary VARCHAR, cite_kind VARCHAR, "
"item_key VARCHAR, p_id INTEGER, page_label VARCHAR, locator VARCHAR, "
"extractor VARCHAR)"
)
c.execute(
"INSERT INTO pfs.code_origin VALUES ('F','99341','statute','r',NULL,'s',"
"'fr_para','K',1,'2','l','x')"
)
ensure_tables(c)
[row] = read_origin(c, "F")
assert row.ref_p_id == 0 and row.code == "99341"
def test_a_sentence_proposing_now_states_no_origin_but_finalizing_one_does():
prop = "We are proposing to create HCPCS code G2211 for CPT code 99341."
it = item(
kind="cms_gcode", reference="HCPCS code G2211", summary="The code exists."
)
assert _fr(it, prop) == []
fin = "We proposed, and are finalizing, HCPCS code G2211 for CPT code 99341."
assert _fr(it, fin)
process = item(
kind="cms_gcode",
reference="HCPCS code G2211",
summary="Panels are reviewing the codes.",
)
assert _fr(process, fin) == []
def test_the_most_comprehensive_final_statement_wins(tmp_path):
s, key = _chain_store(
tmp_path,
[
(3, 10, "The CPT Editorial Panel deleted CPT code 99341 in 2021."),
(
4,
11,
"The CPT Editorial Panel deleted CPT codes 99341, 99342 and 99350 in 2021.",
),
],
)
def ask(system, user, schema):
codes = ["99341", "99342", "99350"] if "99342" in user else ["99341"]
return {
"origins": [
item(
kind="cpt_panel",
reference="CPT Editorial Panel",
codes=codes,
year=2021,
summary="The panel deleted them.",
)
]
}
ask.model = "qwen-test"
rows, _ = family_origin(
_con(), s, FAM, ask=ask, log=RunLog(tmp_path / "l"), books=[]
)
assert {(r.code, r.p_id) for r in rows} == {
("99341", 4),
("99342", 4),
("99350", 4),
}
def test_context_reaches_three_paragraphs_back(tmp_path):
s, key = _chain_store(
tmp_path,
[
(1, 10, "Section 1833(x)(2)(B) of the Act defines primary care services:"),
(2, 10, "99201 through 99215 for office visits;"),
(3, 10, "99304 through 99340 for nursing facility visits; and"),
(4, 10, "99341 through 99350 for new and established patient home visits."),
],
)
it = item(
reference="Section 1833(x)(2)(B) of the Act",
codes=["99341"],
summary="Defines primary care services.",
)
rows, _ = family_origin(
_con(), s, FAM, ask=ask_with([it]), log=RunLog(tmp_path / "l"), books=[]
)
assert {(r.p_id, r.ref_p_id) for r in rows} == {(4, 1)}
def test_fr_rows_with_different_years_are_both_kept(tmp_path):
s, key = _chain_store(
tmp_path,
[
(3, 10, "In February 2021 the CPT Editorial Panel deleted CPT code 99341."),
(4, 11, "Effective 2023 the CPT Editorial Panel deleted CPT code 99341."),
],
)
def ask(system, user, schema):
year = 2023 if "Effective 2023" in user.split("PASSAGE:")[1] else 2021
return {
"origins": [
item(
kind="cpt_panel",
reference="CPT Editorial Panel",
codes=["99341"],
year=year,
summary="The panel deleted it.",
)
]
}
ask.model = "qwen-test"
rows, _ = family_origin(
_con(), s, FAM, ask=ask, log=RunLog(tmp_path / "l"), books=[]
)
assert {(r.p_id, r.year) for r in rows} == {(3, 2021), (4, 2023)}
def test_a_model_range_entry_lists_every_code_in_it():
text = "Section 1861(m) of the Act covers CPT codes 99341 through 99350."
out = _fr(item(codes=["99341-99342", "99350", "99999"]), text)
assert out[0]["codes"] == ["99341", "99342", "99350"]
def test_only_a_paragraph_that_introduces_a_list_lends_its_reference(tmp_path):
s, key = _chain_store(
tmp_path,
[
(8, 100, "Section 1833(x)(2)(B) of the Act establishes the incentive."),
(9, 101, "The benefit covers CPT codes 99341 through 99350."),
],
)
it = item(
reference="Section 1833(x)(2)(B) of the Act",
codes=["99341"],
summary="A payment incentive.",
)
rows, _ = family_origin(
_con(), s, FAM, ask=ask_with([it]), log=RunLog(tmp_path / "l"), books=[]
)
assert rows == [] # paragraph 8 does not introduce what follows
def test_telehealth_listing_regulation_is_no_origin():
text = "Under 42 CFR 410.78 we added CPT code 99341 to the telehealth list."
it = item(
kind="regulation", reference="42 CFR 410.78", summary="It lists the code."
)
assert _fr(it, text) == []
def test_a_reference_in_the_passage_is_backed_by_the_passage_alone(tmp_path):
# 73DU6WUG-style: the section is cited in the passage; the context
# paragraph's wording and numbers must not leak into the summary
s, key = _chain_store(
tmp_path,
[
(1, 10, "Rural clinics may bill 5000 services under the plan."),
(
2,
10,
"Section 1899(c) of the Act assigns beneficiaries; see CPT code 99341.",
),
],
)
leak = item(
reference="section 1899(c) of the Act",
codes=["99341"],
summary="It allows 5000 services by rural clinics.",
)
own = item(
reference="section 1899(c) of the Act",
codes=["99341"],
summary="It assigns beneficiaries to the program.",
)
rows, _ = family_origin(
_con(), s, FAM, ask=ask_with([leak, own]), log=RunLog(tmp_path / "l"), books=[]
)
assert [r.summary for r in rows] == [own["summary"]]
# lent by a context paragraph, the context may back the summary
s2, key = _chain_store(
tmp_path / "b",
[
(
1,
10,
"Section 1899(c) of the Act assigns 5000 beneficiaries, as follows:",
),
(2, 10, "The benefit counts CPT code 99341."),
],
)
lent = {**own, "summary": "It assigns 5000 beneficiaries using the codes."}
rows, _ = family_origin(
_con(), s2, FAM, ask=ask_with([lent]), log=RunLog(tmp_path / "l2"), books=[]
)
assert len(rows) == 1 and rows[0].ref_p_id == 1