ci(audit): point audit validator at our HTS terminology server (#183)#184
ci(audit): point audit validator at our HTS terminology server (#183)#184mauripunzueta wants to merge 6 commits into
Conversation
The audit-events workflow validated extracted AuditEvent codes against the public HL7 test server tx.fhir.org, which is rate-limited, sometimes unreachable, and outside our control. Point it at our own terminology server at hts.heliossoftware.com instead. - audit-events.yml: --tx-base-url -> https://hts.heliossoftware.com - validate_report.py: DEFAULT_TX_BASE_URL -> https://hts.heliossoftware.com, rename source id tx-r5-live-validation -> hts-live-validation, and generalize the report heading (the base URL is already printed below it). HTS serves terminology operations at the root (no /r4 or /r5 path segment) and needs no auth; $validate-code resolves the audit code systems (audit-event-type, restful-interaction, audit-event-action, audit-event-outcome). The hts.yml comparison oracle is intentionally left on tx.fhir.org as the source of truth.
Code review1 issue found. Bug: stale source name in
|
Codecov Report✅ All modified and coverable lines are covered by tests. 📢 Thoughts on this report? Let us know! |
The source entry was renamed tx-r5-live-validation -> hts-live-validation, but the lookup in build_terminology_context() still checked the old name, making the per-run tx_base_url override dead code. With a custom --tx-base-url the report would show the stale default instead of the URL actually validated against.
|
@mauripunzueta When I ran this GitHub action on this branch, I'm seeing errors: https://github.com/HeliosSoftware/hfs/actions/runs/28484701168 |
smunini
left a comment
There was a problem hiding this comment.
I'm seeing errors: https://github.com/HeliosSoftware/hfs/actions/runs/28484701168
hts.heliossoftware.com is fronted by Cloudflare, whose bot protection rejects the default Python urllib User-Agent with HTTP 403 (Error 1010: browser_signature_banned) before the request reaches the terminology server. Every extracted code then surfaced as an invalid system+code pair, so the audit coverage validation step failed across all backends. Present a browser-like User-Agent on the $validate-code requests so the Cloudflare filter is cleared and the real validation response is used.
hts.heliossoftware.com holds two versions of http://terminology.hl7.org/CodeSystem/audit-event-type for the same canonical URL: the FHIR-core 4.0.1 fragment (only `rest`) and the complete THO 1.0.0 (adds hl7-v2, hl7-v3, document, object). Bare $validate-code default-resolves to the 4.0.1 fragment, so `object` - which AuditEvent.type legitimately uses - was rejected as an unknown code. The previous tx.fhir.org/r5 backend default-resolved to 1.0.0, so this only surfaced after migrating to HTS. Pin the complete CodeSystem version (1.0.0) for that system so validation resolves against the full concept list. Verified live: object and rest both validate, and the unaffected systems are unchanged.
|
@smunini Thanks for catching this — resolved now. The run is green: https://github.com/HeliosSoftware/hfs/actions/runs/28806280943 Two transport-level issues surfaced by pointing the validator at
Filed a follow-up for the deeper server-side cause (HTS default-picking the incomplete fragment): #200. |
…onstant Address code-review feedback: TX_SYSTEM_VERSION_OVERRIDES repeated the audit-event-type canonical URL as a magic string instead of reusing the existing AUDIT_EVENT_TYPE_SYSTEM constant. Reuse the constant so the system URL has a single source of truth and the version pin cannot silently miss on a future edit to one copy.
The hts.yml integration-test job compared every HTS operation live against tx.fhir.org/r4 and /r5 as the source of truth, with skip-if-unavailable probes. Per #183, drop that public-server dependency entirely rather than repointing it at our own HTS (which would keep a network call and reduce the test to a self-comparison). Assert each operation against pinned golden values instead — the stable, HL7-defined displays, expansion totals, and outcomes for the UTG code systems these tests exercise (identical for R4 and R5, confirmed against the last green main run): - lookup displays: gender M/F/UN -> Male/Female/Undifferentiated; v3-ActStatus displays == codes - validate-code (CS + VS): valid -> true, invalid / wrong-display -> false - expand totals: v3-AdministrativeGender = 3, v3-ActStatus = 10 - subsumes: same -> equivalent, M/F -> not-subsumed - translate: v2-0001 source -> true, gender source -> false, unmapped -> false, reverse -> true Replace compare_bool/compare_str (HTS-vs-tx) with expect_bool/expect_str (HTS-vs-golden); remove tx_base from the matrix, TX_BASE from the env, the tx_post helper, and the translate availability probe. The job now makes zero external terminology calls and is fully deterministic. Also gitignore __pycache__/ and *.pyc.
Summary
Closes #183 — migrate CI off the public HL7 test terminology server
tx.fhir.org.Two GitHub Actions workflows reached out to
tx.fhir.orgduring their runs. That server is rate-limited, occasionally unreachable, community-shared, and its server-side content drifts — so our baselines drifted with it and workflows carried "probe availability / skip if down" workarounds. This removes both live dependencies.Changes
1.
audit-events.yml— validation backend → our HTS.github/workflows/audit-events.yml:--tx-base-url→https://hts.heliossoftware.comcrates/hfs/tests/audit/validate_report.py:DEFAULT_TX_BASE_URL→https://hts.heliossoftware.com; rename source idtx-r5-live-validation→hts-live-validation; generalize the report heading (base URL is printed dynamically beneath it)User-Agenton$validate-coderequests (Cloudflare bot filter — see below)2.
hts.yml— comparison oracle → pinned golden valuesPreviously the integration-test job hit
tx.fhir.org/r4and/r5live as the "source of truth" and compared every HTS operation against it (with skip-if-unavailable probes). Rather than repoint the oracle at our own server — which would keep a network dependency and reduce the test to a self-comparison (CI build vs. our own deploy) — this removes the oracle entirely and asserts each operation against pinned golden values: the stable, HL7-defined displays / expansion totals / outcomes for these UTG code systems.tx_basefrom the matrix,TX_BASEfrom the env, and thetx_posthelper.compare_bool/compare_str(HTS-vs-tx) withexpect_bool/expect_str(HTS-vs-golden).mainrun (identical for R4 and R5): genderM/F/UN→Male/Female/Undifferentiated; v3-ActStatus displays == codes;$expandtotals gender = 3, actStatus = 10; subsumes same→equivalent,M/F→not-subsumed; translate v2-0001-source→true, gender-source→false, unmapped→false, reverse→true.$translateloses its tx probe/skip branch — it already ran HTS-only in practice (tx was unreachable from the self-hosted runner) and is fully deterministic since the ConceptMap is seeded by the workflow.Issue checklist (#183)
audit-events.yml's--tx-base-urlat our server → §1hts.yml's oracle and revisit the availability-probe / skip logic → §2 (removed entirely via golden values; probes deleted)hts.yml; separately verifiedhts.heliossoftware.comdoes serve the audit + UTG systems these workflows exercisehts.ymlnow makes no server call at alltx.fhir.org— see belowAudit of remaining
tx.fhir.orgreferenceshts-ig-conformance.yml— already runs against a local HTS; thetx.fhir.orgstrings are comments / intentionally upstream-gated (mode: tx.fhir.org) fixtures. No change.crates/fhirpath/src/terminology_client.rs— unit-test assertions about URL trimming; no network. No change.crates/fhirpath/src/evaluator.rs:645— the FHIRPath runtime library default terminology server. Intentionally left as-is: this is shipped product behavior (not a CI workflow), changing it alters the default for every FHIRPath consumer and would needtest_r5_test_suite's oracle-derived expectations re-derived. Tracked separately from this CI-scoped issue.crates/hts/src/**comments describing "tx.fhir.org behaviour" — documentation only.Notes
/r4or/r5path segment (those 404), and no auth.hfs.heliossoftware.comis the FHIR server (hfsbinary, no terminology ops); the terminology server ishts.heliossoftware.com(htsbinary).__pycache__/+*.pycto.gitignore.Follow-up: Cloudflare bot filter (addresses @smunini review)
The first dispatch failed the "Validate audit coverage and generate report" step across all backends. Root cause:
hts.heliossoftware.comis fronted by Cloudflare, whose bot protection rejects the default PythonurllibUser-Agent with HTTP 403 — Error 1010 (browser_signature_banned) before the request reaches the origin, so every extracted code surfaced as "invalid" (18 unique pairs / 285 occurrences).Fix: present a browser-like
User-Agenton$validate-code. Verified live — plain client → 403; with the header →200and a validParametersresponse for every affected code system.