Skip to main content

Installer Hardening, Care Bundle Crash Safety, and Patient Similarity Repairs

· 5 min read
Creator, Parthenon
AI Development Assistant

A dense Saturday of stability work across Parthenon — today's 89 commits concentrated on three converging themes: getting the cross-platform installer into a shippable state, closing out a backlog of high-severity audit findings in the Care Bundles engine, and restoring broken workspace workflows in Patient Similarity. No new features today; this was deliberate debt-clearing ahead of the next feature milestone.

Installer GUI & CI Pipeline: Road to Phase A Sign-Off

The bulk of today's surface area was the installer, which is undergoing structured bench testing across Windows, macOS, and Linux. The Linux Phase A session surfaced four P0-class issues that are now resolved (e88bb1d7d), covering cases that would have blocked a first-run install cold. Alongside those fixes, the installer now shows visible bundle download progress and ships clearer Step 1 copy — two UX items that kept appearing in tester feedback (be2cd81c8).

Two platform-specific CI issues were also closed:

  • Windows .sha256 sidecar files were being written with CRLF line endings, which caused checksum verification to fail silently on some toolchains. The CI job now enforces LF output and the verifier is hardened against trailing whitespace (0ed6f7dc6).
  • macOS notarytool submissions would occasionally time out on Apple's side and leave the pipeline in a failed state with no retry. The job now retries on transient timeouts before surfacing an error (a144b6054).

A subtler macOS fix landed separately: the installer GUI was not augmenting PATH with the Docker CLI location before invoking it, which meant Docker commands silently failed for users who installed Docker Desktop to a non-standard location. The misleading "trust pill" UI element that implied a verification state before it was established was also removed (7e4685a80).

Care Bundles: Closing the Deferred Audit Backlog

Earlier this week a formal audit of the Care Bundles engine produced a triage list with HIGH, MEDIUM, and LOW findings. The first wave landed on the 25th; today's follow-up commits closed everything that was deferred.

The three HIGH findings are worth calling out explicitly because they represent real data-integrity risks in production:

Cohort write atomicity (HIGH-4). MeasureCohortExportService::writeMembers and IntersectionCohortService::writeToResultsCohort were doing a delete followed by a chunked INSERT without wrapping them in a transaction on the results connection. A crash mid-write left the cohort in a partially replaced state — old rows gone, new rows incomplete. Both methods now execute delete + INSERT…SELECT inside a results-connection transaction. The cohort is either fully replaced or fully preserved; there is no intermediate state.

Promotion timing race (HIGH-5). CareBundleMaterializationService::promoteToCurrent was called inside the materialization transaction, but run.update(status='completed') was called after it committed. The crash window between those two operations left care_bundle_current_runs pointing at a run still in running status — which would surface to users as a completed bundle incorrectly showing as in-progress. Promotion is now deferred until after status is set to completed. The worst-case failure mode is now a stale pointer to the previous completed run rather than a visibility leak of a running run.

Heap materialization on large cohorts (HIGH-6). MeasureRosterService::allPersonIds() was pulling the full bucket into PHP heap before chunking it into the cohort table. On a 2M-patient CDM with a wide non-compliant bucket this is a significant memory spike. IntersectionCohortService had the same issue via qualifications->intersection()->all(). Both paths are now rewritten to stream via cross-schema INSERT…SELECT directly from app.care_bundle_measure_person_status / app.care_bundle_qualifications into <resultsSchema>.cohort. The PHP heap never sees the member list. allPersonIds() has been removed; a new CareBundleQualificationService::intersectionQueryForExport() method covers the intersection path.

The workbench workflow layer also received hardening work in a separate commit (38fad397e) to improve resilience around edge cases surfaced during the audit review.

Patient Similarity: Workspace and Validation Repairs

Two fixes landed in the Patient Similarity module today:

  • Workspace workflows were broken and have been repaired (3915024fa). The specific regression is not detailed in the notes but this was blocking iterative similarity analysis sessions entirely.
  • Temporal compare validation was returning HTTP 200 with silent failures when the request payload was malformed. The endpoint now returns proper validation errors (2a1552b7a), which unblocks client-side error handling and makes debugging significantly faster.

Infrastructure & Miscellaneous

  • The local PHPUnit database host is now pinned in CI configuration (8cb8076db), eliminating a class of flaky test failures caused by host resolution differences across environments.
  • The i18n layer now tolerates null resource placeholders in the frontend without throwing (6aebba113). This was causing silent blank-rendering issues in locales with incomplete translation coverage.

What's Next

With the Care Bundles audit fully closed and the installer approaching Phase A sign-off across all three platforms, the near-term focus shifts to:

  1. Installer Phase B bench testing — Windows and macOS sessions are queued; the fixes today should clear the blocker list.
  2. Care Bundles DQ checker completeness — the audit flagged that denominator concept presence was never verified. That finding was truncated in today's notes, suggesting it's in-flight or queued as a follow-on item.
  3. Patient Similarity stability — the two fixes today were reactive; a proactive review of the module's workflow layer is warranted before the next feature increment.

Overall, today was exactly the kind of session a platform needs before a broader rollout push — unglamorous, high-leverage, and necessary.