refactor(canopy-medicaid): move CMD cascade priority + TMA branching + denial-reason synthesis from Rust to JDM (ADR-003 drift)

Context

ADR-003 mandates "all eligibility logic in versioned JDM files evaluated by shared canopy-rules" and explicitly bans inline Rust evaluators bypassing the rules client. Two surfaces in canopy-medicaid currently violate this:

1. CMD cascade priority hardcoded in Rust (cmd_cascade.rs:34-88)

The PAMMS 2052 evaluation priority orders (abd_evaluation_order, family_evaluation_order) are hardcoded Vec<MedicaidCategory> lists in Rust. The debug_assert! at determine.rs:619-624 reconciling the cascade's local pick against the medicaid-eligibility-hierarchy.json ruleset is itself an explicit acknowledgement that the same priority lives in two places. Risk: the cascade and ruleset can drift; debug-only check won't fire in release builds.

2. TMA Phase 1/2 + denial-reason synthesis inline (determine.rs:445-471 + 475-533)

determine.rs:445-471 encodes TMA Phase 1 vs Phase 2 income-test branching (PAMMS 2502) inline, including a hand-written <= tma_threshold comparison.

determine.rs:475-533 synthesizes a hardcoded denial-reason string in Rust for every COA — bypassing what the rules engine could output via denial_reasons array.

Acceptance criteria

  • PAMMS 2052 priority order lives in medicaid-eligibility-hierarchy.json only; cmd_cascade.rs reads from it OR is removed in favour of the ruleset's output
  • TMA Phase 1/2 logic lives in medicaid-magi.json or a dedicated TMA ruleset; determine.rs calls evaluate and consumes the result
  • Denial-reason synthesis moves into the JDM rulesets' denial_reasons outputs; determine.rs strips the denial_reason_fn closure
  • debug_assert! removed (no longer needed)
  • Integration tests cover at least one TMA Phase 1, TMA Phase 2, and per-COA denial path through the rules engine
  • CHANGELOG entry under Changed

Why filed now

Multi-agent plan-vs-code audit (2026-05-05) flagged this as the largest behavioural ADR drift. The drift was created during the medicaid Phase A-F implementation when stretching the JDM grammar would have slowed delivery; ADR-003 calls for the eventual cleanup.

Surfaced by

Multi-agent audit.