code_family_index kept only the first family per code (setdefault), while anchor_metadata's un-indexed scan unions every qualifying family a code belongs to — so stack llm index (no code_index) and stack llm restamp (always indexed) would write different 'families' values for the same text once a code belongs to two families, which the next slice (CPT headings intersecting hand families) will create. Ruling A6: code_family_index now maps each code to the sorted tuple of every qualifying (>=2-code) family key, and anchor_metadata unions those tuples across all matched codes. The indexed and un-indexed paths are now equivalent by construction. Also drops the dead `fams = ...` computation in anchor_metadata when code_index is given. Does not touch the running background comments restamp — the five live hand families (ACP, CCM, PCM, TCM, APCM) don't share any codes, so its output is unaffected today.
76 lines
2.9 KiB
Python
76 lines
2.9 KiB
Python
"""pfs.anchors — metadata for chunks: codes, families, and element slugs."""
|
|
|
|
from pfs.anchors import anchor_metadata, code_family_index
|
|
from pfs.families import FAMILIES, Family
|
|
|
|
|
|
def test_codes_families_elements():
|
|
md = anchor_metadata(
|
|
"Use 99439 in conjunction with 99490; consent; per calendar month"
|
|
)
|
|
assert md["codes"] == "99439 99490"
|
|
assert md["families"] == "CCM"
|
|
assert (
|
|
"activity=consent" in md["elements"].split()
|
|
and "period=calendar-month" in md["elements"].split()
|
|
)
|
|
assert "relation=addon-of" in md["elements"].split() # detail dropped
|
|
|
|
|
|
def test_empty_and_unknown():
|
|
assert anchor_metadata("nothing here") == {
|
|
"codes": "",
|
|
"families": "",
|
|
"elements": "",
|
|
}
|
|
fams = {"X": Family("X", "X fam", ("12345", "23456"), ("x fam",))}
|
|
assert anchor_metadata("code 12345", families=fams)["families"] == "X"
|
|
|
|
|
|
def test_code_index_matches_unindexed_scan():
|
|
text = "Use 99439 in conjunction with 99490; consent; per calendar month"
|
|
index = code_family_index(FAMILIES)
|
|
assert anchor_metadata(text, code_index=index) == anchor_metadata(text)
|
|
|
|
|
|
def test_code_index_keeps_every_family_on_collision():
|
|
"""Ruling A6: a code shared by two qualifying families must keep
|
|
both in the index — a single-winner index made the indexed path
|
|
(restamp) disagree with the un-indexed scan the moment two families
|
|
shared a code, which the next slice (CPT headings intersecting a
|
|
hand family) will create."""
|
|
fams = {
|
|
"A": Family("A", "A fam", ("12345", "23456"), ("a fam",)),
|
|
"B": Family("B", "B fam", ("12345", "34567"), ("b fam",)),
|
|
}
|
|
index = code_family_index(fams)
|
|
assert index["12345"] == ("A", "B")
|
|
|
|
|
|
def test_code_index_matches_unindexed_scan_on_collision():
|
|
"""The indexed and un-indexed paths must write identical 'families'
|
|
values for the same text once a code belongs to two families."""
|
|
fams = {
|
|
"A": Family("A", "A fam", ("12345", "23456"), ("a fam",)),
|
|
"B": Family("B", "B fam", ("12345", "34567"), ("b fam",)),
|
|
}
|
|
text = "code 12345"
|
|
index = code_family_index(fams)
|
|
assert anchor_metadata(text, families=fams, code_index=index) == anchor_metadata(
|
|
text, families=fams
|
|
)
|
|
assert anchor_metadata(text, families=fams)["families"] == "A B"
|
|
|
|
|
|
def test_single_code_family_never_stamped():
|
|
"""A stem-derived family of exactly one code (~17,182 of 17,187
|
|
derived keys) is not a grouping worth its own anchor — it would just
|
|
echo the code already in 'codes' (Ruling A5)."""
|
|
fams = {"SOLO": Family("SOLO", "Solo", ("54321",), ("solo",))}
|
|
assert "54321" not in code_family_index(fams)
|
|
assert anchor_metadata("code 54321", families=fams)["families"] == ""
|
|
index = code_family_index(fams)
|
|
assert (
|
|
anchor_metadata("code 54321", families=fams, code_index=index)["families"] == ""
|
|
)
|