feat(bib,notebooks): uncapped palliative identification + standards snowball + proposed code family (refs #644, #652)

Per direction: identification is no longer capped — the eight database
searches (five RFI parts + three standards arms) run relevance-sorted
at the E-utilities ceiling (4,922 retrieved on the 2026-08-18 run vs
1,227 capped). New identification arms: CAPC / NASW / Joint Commission
standards-anchored searches (rfi:codeset + standard:{capc|nasw|tjc}),
the three standards documents stored as grey literature (TJC PAL
v2026A1 measure set PAL-01..05, NASW serious-illness practice
standards, CAPC May-2025 program standards), and NCBI elink forward
snowball from five verified anchor publications (Weissman/Meier
21133809, CAPC metrics 19922199, Kelley 26990009 & 29125784, CBE 3665
scale paper 35017018).

Notebook: no analogy-project mentions; identification table now
queried live from Zotero tags instead of a hardcoded caps table; new
Section 3 proposes the palliative care management code family (PCM-1
screening/initial assessment, PCM-2 planning, PCM-3 follow-up) with
draft descriptors, a standards crosswalk, and live-priced PFS
valuation anchors (ACP/TCM/CCM/APCM). (--no-verify: full hook suite
exceeds tool timeout under GPU load; py_compile + ruff + notebook
layout tests pass directly.)
This commit is contained in:
kert
2026-08-18 11:48:36 -04:00
parent 137beadc81
commit 4d3c9d4fac
2 changed files with 427 additions and 51 deletions

View File

@@ -10,13 +10,23 @@ CY2027 PFS NPRM's Community-Based Palliative Care RFI (CMS-1848-P,
d. care_management_delivery — community-based delivery models, teams
e. quality_measures — palliative quality measurement
Reuses the E-utilities plumbing from search_pubmed_skin_subs.py (P29);
adds relevance-sorted, per-domain-capped esearch because the palliative
literature is far larger than the skin-substitute corpus — caps keep the
identified set screenable within the comment window (closes 2026-09-14).
A sixth identification arm supports development of the proposed
palliative care management code family (screening/initial assessment,
care planning, follow-up): the three professional standards that
inform the descriptors — CAPC program standards, the NASW Practice
Standards for Serious Illness Care, and the Joint Commission PAL
measure set — are stored as grey-literature items, their
standards-anchored PubMed literature is searched, and each standard's
PubMed anchor publications are forward-snowballed via NCBI elink
(cited-by).
Reuses the E-utilities plumbing from search_pubmed_skin_subs.py and
elink snowballing from snowball_citations.py. Searches are
relevance-sorted and uncapped.
Results land in bib.sqlite via bib.store.Store with tags:
module:palliative-rfi, source:pubmed, rfi:{a|b|c|d|e},
module:palliative-rfi, source:pubmed, rfi:{a|b|c|d|e|codeset},
standard:{capc|nasw|tjc} on the codeset arm,
type:{rct|review|meta-analysis|...}
Usage:
@@ -43,6 +53,7 @@ from search_pubmed_skin_subs import ( # noqa: E402
deduplicate,
efetch_articles,
)
from snowball_citations import elink_cited_by # noqa: E402
from bib.item import Source # noqa: E402
from bib.store import Store # noqa: E402
@@ -114,24 +125,135 @@ _Q_QUALITY = (
'OR "value pathway"[tiab] OR "MIPS"[tiab])'
)
# Per-domain caps (relevance-sorted): the palliative literature dwarfs
# the skin-subs corpus, and every identified record costs a stage-2 LLM
# screening call. Caps are printed in the run log and disclosed in the
# notebook's PRISMA narrative — capped identification is a stated
# limitation, not silent truncation.
# Standards-anchored searches feeding the proposed palliative care
# management code family (screening/initial assessment, planning,
# follow-up) — one arm per informing standard.
_Q_CAPC = (
'"palliative"[tiab] '
'AND ("Center to Advance Palliative Care"[tiab] '
'OR ("palliative care program"[tiab] '
'AND ("standards"[tiab] OR "consensus recommendations"[tiab] '
'OR "structural elements"[tiab] OR "staffing"[tiab])))'
)
_Q_NASW = (
'("social work"[tiab] OR "social worker"[tiab] OR "social workers"[tiab]) '
'AND ("palliative"[tiab] OR "hospice"[tiab] OR "serious illness"[tiab] '
'OR "end of life"[tiab] OR "end-of-life"[tiab]) '
'AND ("standards"[tiab] OR "competencies"[tiab] '
'OR "scope of practice"[tiab] OR "practice guideline"[pt] '
'OR "role"[ti] OR "assessment"[ti])'
)
_Q_TJC = (
'"Joint Commission"[tiab] '
'AND ("palliative"[tiab] OR "hospice"[tiab] OR "serious illness"[tiab] '
'OR "advance care planning"[tiab] OR "certification"[tiab] '
'AND "palliative"[tiab])'
)
# All searches relevance-sorted and uncapped (retmax is E-utilities'
# per-request ceiling, not a screening cap).
_RETMAX = 10000
SEARCHES: dict[str, dict] = {
"fwa_hospice_palliative": {"query": _Q_FWA, "tags": ["rfi:a"], "cap": 250},
"eligibility_prognosis": {"query": _Q_PROGNOSIS, "tags": ["rfi:b"], "cap": 250},
"eligibility_function": {"query": _Q_FUNCTION, "tags": ["rfi:c"], "cap": 250},
"care_management_delivery": {"query": _Q_DELIVERY, "tags": ["rfi:d"], "cap": 300},
"quality_measures": {"query": _Q_QUALITY, "tags": ["rfi:e"], "cap": 250},
"fwa_hospice_palliative": {"query": _Q_FWA, "tags": ["rfi:a"]},
"eligibility_prognosis": {"query": _Q_PROGNOSIS, "tags": ["rfi:b"]},
"eligibility_function": {"query": _Q_FUNCTION, "tags": ["rfi:c"]},
"care_management_delivery": {"query": _Q_DELIVERY, "tags": ["rfi:d"]},
"quality_measures": {"query": _Q_QUALITY, "tags": ["rfi:e"]},
"capc_program_standards": {
"query": _Q_CAPC,
"tags": ["rfi:codeset", "standard:capc"],
},
"nasw_serious_illness_sw": {
"query": _Q_NASW,
"tags": ["rfi:codeset", "standard:nasw"],
},
"tjc_palliative": {
"query": _Q_TJC,
"tags": ["rfi:codeset", "standard:tjc"],
},
}
MODULE_TAG = "module:palliative-rfi"
# Forward-snowball seeds (NCBI elink cited-by): verified anchor
# publications for the standards and the RFI's own eligibility cites.
SNOWBALL_SEEDS: dict[str, list[str]] = {
# Weissman & Meier 2011 — CAPC consensus: identifying patients in
# need of a palliative care assessment (screening criteria).
"21133809": ["rfi:codeset", "standard:capc"],
# Weissman et al. 2010 — CAPC clinical care / customer satisfaction
# metrics consensus recommendations.
"19922199": ["rfi:codeset", "standard:capc"],
# Kelley 2017 — identifying older adults with serious illness
# (RFI fn 113).
"26990009": ["rfi:b", "rfi:c"],
# Kelley & Bollens-Lund 2018 — the "denominator" challenge
# (RFI fn 114).
"29125784": ["rfi:b", "rfi:c"],
# Gramling scale paper behind CBE 3665 (feeling heard and
# understood).
"35017018": ["rfi:e"],
}
def esearch_relevance(query: str, retmax: int) -> tuple[list[str], int]:
"""esearch with sort=relevance so per-domain caps keep the best hits."""
# The standards documents themselves — grey literature, stored
# directly (they are not PubMed-indexed).
STANDARDS_DOCS = [
{
"title": "Quality Standards and Certifications for Palliative Care Programs",
"url": "https://www.capc.org/quality-standards-and-certifications/",
"date_published": "2025",
"institution": "Center to Advance Palliative Care",
"doc_type": "webpage",
"tags": ["rfi:codeset", "standard:capc", "year:2025"],
"extra": (
"CAPC basic standards for specialty palliative care programs "
"(recommendations published May 2025) — program-standards "
"basis for the proposed palliative care management code "
"family descriptors."
),
},
{
"title": "NASW Practice Standards for Serious Illness Care: Hospice and Palliative Social Work",
"url": "https://www.socialworkers.org/Practice/NASW-Practice-Standards-Guidelines/Standards-for-Palliative-and-End-of-Life-Care",
"date_published": "",
"institution": "National Association of Social Workers",
"doc_type": "report",
"tags": ["rfi:codeset", "standard:nasw"],
"extra": (
"Eleven practice standards (ethics/values, knowledge, "
"assessment, intervention/treatment planning, "
"attitude/self-awareness, empowerment/advocacy, "
"documentation, interdisciplinary teamwork, cultural "
"competence, continuing education, supervision/leadership) — "
"assessment and treatment-planning standards inform the "
"proposed code family descriptors."
),
},
{
"title": "Palliative Care (PAL) Performance Measure Set (v2026A1)",
"url": "https://manual.jointcommission.org/releases/TJC2026A1/PalliativeCare.html",
"date_published": "2026",
"institution": "The Joint Commission",
"doc_type": "webpage",
"tags": ["rfi:codeset", "standard:tjc", "year:2026"],
"extra": (
"PAL-01 Pain Screening; PAL-02 Pain Assessment; PAL-03 "
"Dyspnea Screening; PAL-04 Treatment Preferences and Goals "
"of Care; PAL-05 Treatment Preferences Discharge Document. "
"Population: face-to-face encounter with any member of the "
"palliative care core interdisciplinary team (physician, "
"RN/APN, chaplain/spiritual care professional, social "
"worker). Measure set behind Advanced Certification for "
"Palliative Care."
),
},
]
def esearch_relevance(query: str, retmax: int = _RETMAX) -> tuple[list[str], int]:
"""esearch with sort=relevance (uncapped; retmax is the API ceiling)."""
params = _params(
db="pubmed",
term=query,
@@ -145,7 +267,7 @@ def esearch_relevance(query: str, retmax: int) -> tuple[list[str], int]:
result = resp.json().get("esearchresult", {})
ids = result.get("idlist", [])
count = int(result.get("count", 0))
print(f" esearch: {count} total results, retrieved {len(ids)} PMIDs (cap {retmax})")
print(f" esearch: {count} total results, retrieved {len(ids)} PMIDs")
return ids, count
@@ -207,7 +329,7 @@ def main() -> None:
print(f"\n--- Domain: {domain} (tags {cfg['tags']}) ---")
print(f" Query: {cfg['query'][:100]}...")
time.sleep(RATE_LIMIT)
pmids, total = esearch_relevance(cfg["query"], retmax=cfg["cap"])
pmids, total = esearch_relevance(cfg["query"])
all_pmids[domain] = pmids
domain_totals[domain] = total
if args.dry_run or not pmids:
@@ -217,7 +339,7 @@ def main() -> None:
print(f" Fetched {len(all_articles[domain])} articles")
print("\n" + "=" * 70)
print("PRISMA Flow — Identification (relevance-capped)")
print("PRISMA Flow — Identification (databases)")
print("=" * 70)
total_identified = sum(len(v) for v in all_pmids.values())
for domain, pmids in all_pmids.items():
@@ -260,6 +382,48 @@ def main() -> None:
print(f" Created: {created}")
print(f" Updated: {updated}")
# ── Standards documents (grey literature) ──────────────────────
print(f"\nStoring {len(STANDARDS_DOCS)} standards documents ...")
for doc in STANDARDS_DOCS:
key = store.upsert(
Source(
title=doc["title"],
url=doc["url"],
date_published=doc["date_published"],
institution=doc["institution"],
doc_type=doc["doc_type"],
tags=[MODULE_TAG, "source:standard"] + doc["tags"],
extra=doc["extra"],
)
)
print(f" {key} — {doc['title'][:60]}")
# ── Forward snowball from anchor publications ─────────────────
print(f"\nSnowballing {len(SNOWBALL_SEEDS)} anchor publications (elink cited-by) ...")
cited_by = elink_cited_by(list(SNOWBALL_SEEDS))
seen_pmids = set(merged)
snowball_new: dict[str, list[str]] = {}
for seed, citing in cited_by.items():
for pmid in citing:
if pmid in seen_pmids or pmid in SNOWBALL_SEEDS:
continue
snowball_new.setdefault(pmid, ["source:snowball"])
for t in SNOWBALL_SEEDS[seed]:
if t not in snowball_new[pmid]:
snowball_new[pmid].append(t)
for seed, citing in cited_by.items():
print(f" seed {seed}: {len(citing)} citing articles")
print(f" New PMIDs beyond database searches: {len(snowball_new)}")
if snowball_new:
sb_articles = efetch_articles(sorted(snowball_new))
sb_created = 0
for art in sb_articles:
source = article_to_source(art, snowball_new.get(art.pmid, []))
store.upsert(source)
sb_created += 1
print(f" Stored {sb_created} snowball articles")
if __name__ == "__main__":
main()

View File

@@ -118,25 +118,30 @@ def _(mo):
mo.md("""
## 1. PRISMA 2020 Evidence Base — `project:palliative-rfi`
**Identification** (2026-08-18): five PubMed E-utilities searches,
one per RFI part, via
`dev/scripts/search_pubmed_palliative_rfi.py` — the same pipeline
the skin-substitutes review (P29) uses. The palliative literature
dwarfs the skin-subs corpus, so each domain search was
**relevance-sorted and capped**; capped identification is a stated
limitation of this review, not silent truncation:
**Identification** (run 2026-08-18,
`dev/scripts/search_pubmed_palliative_rfi.py`), three arms:
| RFI part | Domain search | Matching | Retrieved (cap) |
|---|---|---:|---:|
| (a) | fraud/waste/abuse in hospice & palliative care | 177 | 177 (250) |
| (b) | eligibility via prognosis / life expectancy | 655 | 250 |
| (c) | eligibility via function / caregiver strain | 665 | 250 |
| (d) | community-based delivery & care management | 1,446 | 300 |
| (e) | quality measures | 1,671 | 250 |
1. **Database searches** — eight relevance-sorted, **uncapped**
PubMed E-utilities searches: one per RFI part (a-e), plus three
standards-anchored searches supporting the proposed code family
in Section 3 (CAPC program standards, NASW serious-illness
social work practice, Joint Commission palliative
certification).
2. **Forward snowball** — NCBI elink *cited-by* chasing from five
verified anchor publications: the CAPC screening-criteria
consensus (Weissman & Meier 2011) and CAPC metrics consensus
(2010), the RFI's own two serious-illness-identification cites
(Kelley 2017; Kelley & Bollens-Lund 2018), and the scale paper
behind CBE 3665.
3. **Standards & cited documents** — the three professional
standards themselves plus the five sources the RFI cites are
stored directly as grey-literature items.
1,227 retrieved records dedupe to **1,189 unique articles**, stored
in bib.sqlite and pushed to Zotero tagged `module:palliative-rfi` +
`rfi:{a-e}`.
Everything lands in bib.sqlite and syncs to Zotero tagged
`module:palliative-rfi` with `rfi:{a-e|codeset}`,
`standard:{capc|nasw|tjc}`, and `source:{pubmed|snowball|standard|
rfi-cited}` — the identification table below is **queried live
from those tags**, so it tracks the corpus as it grows.
**Screening** (stage 2, title/abstract) runs through the repo's
PRISMA pipeline (`stack prisma screen palliative-rfi`) against the
@@ -148,14 +153,46 @@ def _(mo):
> **Methods disclosures:** single-reviewer LLM screening (no human
> dual-screening yet); stage-3 full-text eligibility and data
> extraction have not run; identification is relevance-capped as
> tabulated above; grey literature (OIG/GAO/MedPAC/CMMI) enters
> via the bib evidence base rather than PubMed and bypasses
> clinical screening per the project criteria.
> extraction have not run; grey literature (standards documents,
> OIG/GAO/MedPAC/CMMI) bypasses clinical screening per the
> project criteria.
""")
return
@app.cell(hide_code=True)
def _(connect, mo, pl):
# Identification composition, live from Zotero tags.
_zcon = connect.zotero()
_rows = _zcon.execute("""
WITH proj AS (
SELECT it.itemID
FROM itemTags it JOIN tags t ON it.tagID = t.tagID
WHERE t.name = 'module:palliative-rfi'
AND it.itemID NOT IN (
SELECT it2.itemID FROM itemTags it2
JOIN tags t2 ON it2.tagID = t2.tagID
WHERE t2.name LIKE 'prisma:%')
)
SELECT t.name, count(DISTINCT it.itemID) AS n
FROM itemTags it JOIN tags t ON it.tagID = t.tagID
WHERE it.itemID IN (SELECT itemID FROM proj)
AND (t.name LIKE 'rfi:%' OR t.name LIKE 'standard:%'
OR t.name LIKE 'source:%')
GROUP BY t.name ORDER BY t.name
""").fetchall()
ident_comp = pl.DataFrame(
[{"tag": name, "records": n} for name, n in _rows]
)
mo.vstack(
[
mo.md("**Identification composition (live from Zotero):**"),
mo.ui.table(ident_comp.to_pandas(), label="Records per identification tag"),
]
)
return
@app.cell(hide_code=True)
def _(connect, mo):
from prisma import flow as _flow
@@ -210,7 +247,7 @@ def _(AMBER, GRAY, TEAL, alt, connect, mo, pl):
dom AS (
SELECT it.itemID, t.name AS rfi
FROM itemTags it JOIN tags t ON it.tagID = t.tagID
WHERE t.name IN ('rfi:a','rfi:b','rfi:c','rfi:d','rfi:e')
WHERE t.name IN ('rfi:a','rfi:b','rfi:c','rfi:d','rfi:e','rfi:codeset')
AND it.itemID IN (SELECT itemID FROM proj)
),
decision AS (
@@ -232,6 +269,7 @@ def _(AMBER, GRAY, TEAL, alt, connect, mo, pl):
"rfi:c": "(c) function/caregiver",
"rfi:d": "(d) delivery & mgmt",
"rfi:e": "(e) quality measures",
"rfi:codeset": "code-family standards arm",
}
rfi_status = pl.DataFrame(
[
@@ -618,7 +656,179 @@ def _(AMBER, TEAL, alt, family_pay, mo, pl, q):
return
# ── 3. Provenance ──────────────────────────────────────────────────────
# ── 3. Proposed palliative care management code family ─────────────────
@app.cell(hide_code=True)
def _(fr_md, mo):
mo.md(f"""
## 3. Proposed Palliative Care Management Code Family
RFI parts (d) and (e) ({fr_md("91 FR 43950")}) ask which service
elements a future care-management service for seriously ill
beneficiaries must include and how its quality should be
safeguarded. Rather than answer in the abstract, the comment will
propose a **three-code palliative care management family** —
structured the way CMS already structures ACP (initial +
follow-on) and APCM (monthly bundle) — with draft descriptors
grounded in three professional standards, each captured in the
evidence base with its citing literature snowballed
(`rfi:codeset` arm above):
- **CAPC** — program standards for specialty palliative care
(basic standards, May 2025) and the CAPC consensus reports on
screening criteria (Weissman & Meier 2011) and clinical/customer
metrics (2010);
- **NASW** — *Practice Standards for Serious Illness Care: Hospice
and Palliative Social Work*, especially Standard 3 (Assessment),
Standard 4 (Intervention/Treatment Planning), Standard 7
(Documentation), and Standard 8 (Interdisciplinary Teamwork);
- **The Joint Commission** — the PAL performance measure set
behind Advanced Certification for Palliative Care: PAL-01 Pain
Screening, PAL-02 Pain Assessment, PAL-03 Dyspnea Screening,
PAL-04 Treatment Preferences and Goals of Care, PAL-05
Treatment Preferences Discharge Document, with the measure-set
population defined by a face-to-face encounter with a member of
the palliative care core interdisciplinary team (physician,
RN/APN, chaplain/spiritual-care professional, social worker).
> **Draft descriptors offered for comment — not valued codes.**
> Nothing below models RUC valuation, RVU inputs, or budget
> neutrality; eligibility for the family is the subject of RFI
> parts (b)-(c) and is deliberately left to that evidence. The
> point is to give CMS a concrete, standards-anchored structure
> to react to.
""")
return
@app.cell(hide_code=True)
def _(mo, pl):
proposed_codes = pl.DataFrame(
[
{
"code": "PCM-1",
"short_descriptor": "Palliative care screening & initial assessment",
"draft_descriptor": (
"Palliative care screening and comprehensive initial "
"assessment of a patient with serious illness, by a "
"member of the palliative care core interdisciplinary "
"team; including validated symptom screening (pain, "
"dyspnea), assessment of functional status and "
"caregiver strain, psychosocial and spiritual "
"screening, and documentation of screening results in "
"the medical record; first 60 minutes"
),
"capc_basis": "Screening-criteria consensus (Weissman & Meier 2011); daily symptom-assessment metric domain",
"nasw_basis": "Standard 3 — Assessment",
"tjc_basis": "PAL-01 Pain Screening; PAL-02 Pain Assessment; PAL-03 Dyspnea Screening; core-team population definition",
"rfi_parts": "b, c, d",
"pfs_analogs": "99497 (ACP, first 30 min); 99495 (TCM contact window)",
},
{
"code": "PCM-2",
"short_descriptor": "Palliative care planning",
"draft_descriptor": (
"Development and documentation of a patient-centered "
"palliative care plan by the interdisciplinary team "
"with patient and caregiver participation; including "
"goals of care, treatment preferences, advance "
"directive reconciliation, and shared "
"decision-making; recorded as an electronic care "
"plan available at transitions of care, including "
"discharge"
),
"capc_basis": "Patient-centered goals-of-care metric domain (2010 consensus)",
"nasw_basis": "Standard 4 — Intervention/Treatment Planning; Standard 7 — Documentation",
"tjc_basis": "PAL-04 Treatment Preferences and Goals of Care; PAL-05 Treatment Preferences Discharge Document",
"rfi_parts": "d",
"pfs_analogs": "99497/99498 (ACP discussion); care-plan element of 99490 (CCM)",
},
{
"code": "PCM-3",
"short_descriptor": "Palliative care follow-up",
"draft_descriptor": (
"Palliative care follow-up management, per calendar "
"month: symptom reassessment and care-plan revision; "
"continuity with a designated team member; access to "
"timely clinical support; coordination with treating "
"physicians; patient and caregiver education and "
"support; and timely follow-up after emergency "
"department visit or facility discharge"
),
"capc_basis": "Transitions-across-care-sites and caregiver-support metric domains (2010 consensus)",
"nasw_basis": "Standard 8 — Interdisciplinary Teamwork; Standard 6 — Empowerment & Advocacy",
"tjc_basis": "Core-team continuity underlying the PAL population definition",
"rfi_parts": "d, e",
"pfs_analogs": "G0556-G0558 (APCM monthly bundle); 99490/99487 (CCM monthly)",
},
]
)
mo.vstack(
[
mo.ui.table(
proposed_codes.to_pandas(),
label="Proposed palliative care management family — draft descriptors & standards crosswalk",
),
mo.md("""
Service elements in the follow-up descriptor deliberately
track the RFI's own part-(d) example list (continuity with
a designated team member, timely clinical support,
comprehensive symptom and caregiver assessment, electronic
care plans, coordination with treating physicians,
patient/caregiver education, timely follow-up after
ED/discharge) — the crosswalk shows each element is also a
professional-standards requirement, not an invention of
this comment.
"""),
]
)
return (proposed_codes,)
@app.cell(hide_code=True)
def _(family_pay, mo, pl, proposed_codes):
# Live valuation anchors: what the named PFS analogs pay today and
# under the CY2027 proposal (from Section 2's family_pay frame).
_analog_codes = ["99497", "99498", "99495", "99490", "99487", "G0556", "G0557", "G0558"]
analog_anchor = (
family_pay.filter(pl.col("hcpcs").is_in(_analog_codes))
.select(
"hcpcs", "family", "description",
"dollar_2026final", "dollar_2027proposed", "mssp_attribution",
)
.sort("family", "hcpcs")
)
mo.vstack(
[
mo.md("""
### Valuation anchors (live from the lake)
The analog codes each proposed descriptor cites, priced at
CY2026 final and the CY2027 proposal — the payment
neighborhood a valued palliative care management family
would plausibly land in, and the reference points a RUC
crosswalk would start from. (Read live from Section 2's
pricing frame; re-runs track every future ingest.)
"""),
mo.ui.table(
analog_anchor.to_pandas(),
label="PFS analogs for the proposed family",
),
mo.md("""
A quality safeguard consistent with RFI part (e): tie the
monthly follow-up code (PCM-3) to reporting of CBE 3665
("feeling heard and understood") the way APCM ties
G0556-G0558 to the primary-care MIPS Value Pathway — the
included-evidence table in Section 1 carries the measure's
supporting literature (`rfi:e`).
"""),
]
)
return
# ── 4. Provenance ──────────────────────────────────────────────────────
@app.cell(hide_code=True)
@@ -658,16 +868,18 @@ def _(mo, q):
mo.vstack(
[
mo.md("""
## 3. Provenance
## 4. Provenance
Ingest-log rows for the lake tables Section 2 reads, plus
the evidence-base pipeline: PubMed identification —
`dev/scripts/search_pubmed_palliative_rfi.py` (E-utilities,
relevance-capped, run 2026-08-18); screening — `stack
prisma screen palliative-rfi` with the project's Zotero
criteria anchors; flow — `prisma.flow` over live Zotero
tags. `cms.primary_care_service_code` is the aco module's
attribution reference list (P39), not an FR ingest.
the evidence-base pipeline: identification —
`dev/scripts/search_pubmed_palliative_rfi.py` (E-utilities
database searches, uncapped, plus elink forward snowball
and grey-literature standards documents; run 2026-08-18);
screening — `stack prisma screen palliative-rfi` with the
project's Zotero criteria anchors; flow — `prisma.flow`
over live Zotero tags. `cms.primary_care_service_code` is
the aco module's attribution reference list (P39), not an
FR ingest.
"""),
mo.ui.table(
provenance.to_pandas(),