core/rules.py format-tolerant readers + stable registry (R001-R004 plan-scoped, R100-R102 universal per LCD L33822). payer_rules.json wrapped in the same commit as both engine readers (coupling hazard closed). Every DocItem now cites the rule that decided it; NOT_EVALUATED cites nothing. Independent audit: SHIP (registry-drift test added per its L2 finding). 138 tests green. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
52 lines
1.8 KiB
Python
52 lines
1.8 KiB
Python
"""
|
|
rules.py
|
|
Signal — STTIL Solutions
|
|
|
|
Format-tolerant readers for payer_rules.json plus the stable rule-ID registry
|
|
(build plan 02, item P2; design: readiness-model-design-phase2 section 3.1).
|
|
|
|
A rule value may be FLAT (legacy: `"visit_renewal_days": 180`) or WRAPPED with
|
|
its citation (`"visit_renewal_days": {"value": 180, "rule_id": "R001"}`).
|
|
Both engines read through these helpers so the JSON format can carry citation
|
|
IDs without breaking either reader.
|
|
|
|
RULE IDS ARE STABLE — never change an ID after shipping. The ID names the rule
|
|
KIND; the plan type plus the value together are the citation.
|
|
"""
|
|
|
|
from __future__ import annotations
|
|
|
|
from typing import Optional
|
|
|
|
# Universal claim/coverage requirements per LCD L33822, independent of plan
|
|
# type. They live in code (no plan-type dependency) but carry rule IDs for
|
|
# citation consistency.
|
|
UNIVERSAL_RULE_IDS = {"swo": "R100", "visit": "R101", "diagnosis": "R102"}
|
|
|
|
# Plan-scoped keys in payer_rules.json and their registry IDs.
|
|
PLAN_KEY_RULE_IDS = {
|
|
"visit_renewal_days": "R001",
|
|
"refill_window_days": "R002",
|
|
"pa_required": "R003",
|
|
"pecos_required": "R004",
|
|
}
|
|
|
|
|
|
def rule_value(cfg: Optional[dict], key: str, default=None):
|
|
"""Read a rule value, accepting flat (180) and wrapped
|
|
({'value': 180, 'rule_id': 'R001'}) formats."""
|
|
if not cfg:
|
|
return default
|
|
raw = cfg.get(key, default)
|
|
if isinstance(raw, dict) and "value" in raw:
|
|
return raw["value"]
|
|
return raw
|
|
|
|
|
|
def rule_id_for(cfg: Optional[dict], key: str) -> Optional[str]:
|
|
"""The citation ID for a plan-scoped rule: from the wrapped config when
|
|
present, else the registry default for that key."""
|
|
raw = cfg.get(key) if cfg else None
|
|
if isinstance(raw, dict) and "rule_id" in raw:
|
|
return raw["rule_id"]
|
|
return PLAN_KEY_RULE_IDS.get(key)
|