Skip to content

feat(eligibility): API-first 270/271 eligibility waterfall (Stedi client, payer route map, document-hash verified artifacts)#147

Merged
abrichr merged 7 commits into
mainfrom
feat/eligibility-api-first-spike
Jul 21, 2026
Merged

feat(eligibility): API-first 270/271 eligibility waterfall (Stedi client, payer route map, document-hash verified artifacts)#147
abrichr merged 7 commits into
mainfrom
feat/eligibility-api-first-spike

Conversation

@abrichr

@abrichr abrichr commented Jul 18, 2026

Copy link
Copy Markdown
Member

What

Adds the public mechanism for a sanctioned API-first 270/271 eligibility path beneath OpenAdapt's governed execution layer:

  • exact practice/account/payer/service/mode route bindings, with unknown or incomplete routes sent to the attended queue;
  • a bounded Stedi real-time eligibility client using the allowlisted endpoint and bare Authorization API-key contract;
  • qualifier-aware 271 parsing that refuses mixed or mismatched service, subject, provider, identity, date, network, coverage-level, time-period, procedure, payer, or application-mode evidence;
  • explicit HTTP/AAA retry taxonomy: only bounded transient reads retry, and only an explicitly reviewed portal binding can receive fallback;
  • an atomic practice-local PHI artifact boundary with encrypted-volume or AES-256-GCM storage, owner-only paths, enforced retention expiry, verified purge/denial semantics, no-egress policy, formula neutralization, and independent document-hash verification;
  • three env-gated synthetic Stedi TEST-mode trials that never run or make a provider call unless an operator supplies STEDI_API_KEY.

This remains a component of the existing staff-first attended flow, not a second fulfillment runtime.

Independent safety repairs through dd07fa2

Exact-head audit and adversarial repair closed the false-success and evidence-boundary paths in the original spike:

  • subscriber member ID is required and must match the returned 271;
  • every supplied first name, last name, and birth date must be returned and match after conservative Unicode/case/whitespace normalization;
  • the returned provider NPI must exactly match the request;
  • missing, malformed, mismatched, or dependent response subjects refuse; a dependent response cannot satisfy a subscriber request;
  • redirects and every other non-2xx response refuse even if the body resembles a valid 271;
  • active coverage requires an explicit closed or open-ended interval containing the requested service date;
  • explicit network, coverage-level, time-period, and procedure selectors must match patient-responsibility evidence for the requested service; an unrelated active row cannot produce a consumable answer;
  • the subject-evidence digest binds request digest, raw-response digest, and verified subscriber role without adding a standalone low-entropy identity digest or plaintext PHI;
  • artifact promotion reparses the exact raw bytes, requires exact digest and canonical semantic equality, then re-reads and verifies every staged raw, normalized, manifest, hash, and index contract before any transaction becomes consumable;
  • transaction/index promotion rolls back on corruption, write/promotion failure, or independent effect-verification failure;
  • EligibilityResult.is_answer requires an actual application mode plus the exact raw bytes/digest, so a constructed or deserialized raw-less result cannot complete the waterfall;
  • PracticeArtifactPolicy requires TEST or PRODUCTION mode. The mode and exact retention interval are bound into boundary.json, manifest, normalized JSON, and CSV; malformed or policy-mismatched expiry denies consumption/purge;
  • expired PHI transactions are removed from the verified index atomically, quarantined under the artifact lock, securely deleted, and restored if index promotion fails;
  • persisted committed_at is writer-derived; caller-mutated observation timestamps are not stored as audit truth;
  • committed transaction directories and files are rechecked as regular, non-symlink, owner-only paths before reuse or index rebuild;
  • a transient API exhaustion selects portal replay only when that fallback was explicitly reviewed;
  • a pre-existing broad-permission artifact directory is refused rather than silently chmod'd.

The committed registry is synthetic mechanism data only; production route recipes remain practice-scoped deployment data.

Evidence

  • 101 passed, 3 skipped across the eligibility client, routing, artifact, waterfall, and env-gated live-test modules. The skips explicitly report that no live evidence was collected without a Stedi test key.
  • 130 passed across the final eligibility and release-contract gate set.
  • focused Ruff and strict MyPy checks pass for the changed source and tests.
  • release consistency passes.
  • a fresh 1.19.0 wheel and sdist build passes the archive license/source/private-corpus boundary validator; the wheel import exposes the retention-purge API.
  • adversarial tests cover qualifier mismatch, corruption of every staged artifact/index contract, promotion rollback, independent-verification rollback, expiry purge, expiry-denial, and purge rollback.
  • no live/provider/paid API call, deployment, release, production secret, or GUI/input injection was used.

Merge safety versus deployment activation

This draft adds a dormant, lazily imported mechanism and does not activate a provider integration. Production activation remains fail-closed and requires the private reviewed practice/account/payer registry, attended-queue and system-of-record integration, and at least three live Stedi TEST-mode trials under the deployment's reviewed BAA and PHI controls. Those live trials have not been collected in this PR.

Primary provider references:

@abrichr
abrichr marked this pull request as draft July 18, 2026 19:10
@abrichr

abrichr commented Jul 18, 2026

Copy link
Copy Markdown
Member Author

Holding this PR in draft after independent review. The API-first eligibility thesis is sound, but this exact implementation is a contract spike rather than a safe production fulfillment path.

Before it can return to ready:

  1. Rebase onto the independently verified 1.14.1 release boundary.
  2. Bind the reviewed payer route to the exact payer ID sent on the request; unknown or unverified routing must queue/halt.
  3. Parse benefits by requested service type, service date, network, coverage level, and time period; mixed or ambiguous entries must not collapse to an unrelated “active” answer.
  4. Distinguish credential/configuration errors, invalid payer/request errors, throttling, and transient payer failures. Only explicitly transient cases may retry or fall back.
  5. Stage and atomically verify both the raw response and the exact practice-facing normalized result before either is promoted as consumable.
  6. Put raw 271/member data behind an explicit PHI-bearing local storage, encryption, retention, and egress boundary.
  7. Add atomic/locked/symlink-safe artifact writes, spreadsheet-formula neutralization, endpoint allowlisting, response-size limits, and bounded concurrency/retry behavior.
  8. Integrate one exact partner/practice workflow and run at least three live test-mode trials before making product claims.

Current CI is green and the code appears MIT-compatible; the hold is about silent-wrong-answer, PHI, effect-verification, and fulfillment completeness—not general code quality.

@abrichr

abrichr commented Jul 19, 2026

Copy link
Copy Markdown
Member Author

Status refresh (2026-07-19): the MIT-only release boundary is restored, so the remaining hold is the production contract described above. This stays a useful API-first spike but not a merge candidate until exact payer routing, benefit/time/network interpretation, error taxonomy, atomic normalized/raw artifacts, PHI retention/egress, and >=3 effect-oracled integration trials are implemented on current released main. The staff-first attended path and UI execution layer remain the launch critical path; this PR should integrate with them if resumed, not become a parallel fulfillment runtime.

@abrichr
abrichr force-pushed the feat/eligibility-api-first-spike branch from b21725c to 1b597dd Compare July 21, 2026 15:25
abrichr and others added 6 commits July 21, 2026 12:34
…ent, payer route map, document-hash verified artifacts)

The API tier of the dental eligibility offer: where a payer exposes a
sanctioned real-time 270/271 route through a clearinghouse API, the check
hits that route first and compiled portal replay becomes the fallback.

- eligibility/client.py: StediEligibilityClient against Stedi's documented
  JSON endpoint (Authorization: Key header, tradingPartnerServiceId /
  subscriber / encounter.serviceTypeCodes request, benefitsInformation +
  AAA-error response). Normalized EligibilityResult with the raw 271
  retained byte-exact plus its SHA-256 wire digest. parse_271 fails
  CLOSED: malformed or signal-free responses are indeterminate, never a
  guessed benefits answer. Secret-isolated auth per the effect kit
  convention (env-var references only; construction fails loud).
- eligibility/waterfall.py + payer_routes.yaml: the committed per-payer
  capability map (payer -> api | portal | excluded) and the resolver the
  fulfillment loop calls, so route choice is reviewed data, not code.
  Six confirmed dental payers route api-first; Availity is excluded +
  portal_banned with the sanctioned-API conversion path documented;
  unknown payers default to portal. Fallback rule is explicit: a 270 is
  an idempotent READ so no-answer API attempts fall through safely (the
  opposite of ApiActuator's write-path HALT), except banned portals which
  land in the practice queue.
- eligibility/artifact.py: results land in the same practice-local
  artifact set as portal replay (eligibility_results.csv row + byte-exact
  271_<digest16>.json) and are certified by the document-hash verifier
  (record_written + sha256 field_equals against the wire digest) --
  effect verification is source-agnostic.
- docs/ELIGIBILITY_API_WATERFALL.md: honest proof labels
  (contract-proven vs live-proven), practice-held account / click-through
  BAA model, per-check cost, activation steps, backup clearinghouse.

Contract-proven against faithful fakes of Stedi's documented shapes
(including their published dental mock catalog); an env-gated live smoke
test (STEDI_API_KEY, test mode, mock checks are free) graduates the
mocked path to live-proven. Purely additive: no existing file modified,
no new dependencies (httpx and PyYAML are already core), nothing on the
replay hot path.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@abrichr

abrichr commented Jul 21, 2026

Copy link
Copy Markdown
Member Author

Re-audited exact head dd07fa2 against the eight hold conditions after the fail-closed repair pass:

  1. Current release boundary — closed for this source change. The built 1.19.0 wheel and sdist pass release consistency and archive license/source/private-corpus validation; the packaged wheel imports the new public purge API.
  2. Exact payer route/request ID — closed. Route selection remains exact on practice/account/payer/service/mode, with unknown or incomplete routes sent to the attended queue.
  3. Qualifier-safe parsing — closed. Explicit network, coverage-level, time-period, and procedure selectors must match patient-responsibility evidence for the requested service. Adversarial N/FAM and time-period mismatches now return response_ambiguous; unrelated active coverage cannot satisfy the request.
  4. Error taxonomy/retry/fallback — closed. Only classified transient reads retry, and portal fallback still requires an explicitly reviewed binding.
  5. Atomic staged artifacts — closed. Raw bytes, normalized JSON, manifest, storage/plaintext hashes, and the prospective index are independently re-read and verified before promotion. Corruption, promotion failure, or independent effect-verification failure rolls back the new transaction/index.
  6. PHI boundary/retention/no-egress — closed in mechanism. Encryption/no-egress and owner-only path checks remain intact. Commit and expiry are policy-bound; malformed or policy-mismatched expiry denies use. The purge API atomically removes expired rows, quarantines/deletes transaction data, and restores state if index publication fails.
  7. Filesystem/CSV/allowlist/size/concurrency/retry — closed. Existing controls remain preserved and covered.
  8. Exact partner/practice activation evidence — intentionally outstanding. No Stedi call was made. The three env-gated TEST-mode trials skip without STEDI_API_KEY; production activation also still requires the private reviewed practice registry/account boundary and attended-queue/system-of-record integration.

Local verification: 101 passed, 3 skipped focused eligibility set; 130 passed final eligibility + release-contract set; Ruff, strict MyPy, release consistency, git diff --check, fresh wheel/sdist boundary validation, and installed-wheel import all pass. The PR remains draft and was not activated, marked ready, or merged.

@abrichr
abrichr marked this pull request as ready for review July 21, 2026 23:39
@abrichr
abrichr merged commit abe9f36 into main Jul 21, 2026
15 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant