Skip to content

clinical-write treats the OpenEMR duplicate-check opener (#create) as a write, though the compiler marks it reversible #1533

Open

Description

@abrichr

What certify reports

A freshly recorded and compiled OpenEMR referral (see #1431) fails openadapt-flow certify BUNDLE --policy clinical-write with two violations on the click that opens OpenEMR's duplicate-check dialog (#create, labelled "Create New Patient"):

(require_system_effects_for) [step_039] step matches require_system_effects_for but declares no system-of-record effect for executable path(s): gui — one path's contract cannot cover another
(require_idempotency_key_for) [step_039] step matches require_idempotency_key_for but no declared system-of-record effect carries an idempotency key — a retried/duplicated submission could land as a silent duplicate write

lint warns about the same step: (under_classified_risk) [step_039] text looks write-shaped but the step is marked reversible.

This click saves nothing. The save is the next click, #confirmCreate (step_040), which carries the record check.

Why a fresh recording hits it

The compiler already knows this. confirmation_opener_step_ids and the loop at packages/flow/openadapt_flow/compiler/compile.py:2972-2984 mark the opener reversible ("opens a confirmation dialog; the save is the next click (step_040)") with risk_review_required=False.

The policy does not accept that. effective_step_risk (packages/flow/openadapt_flow/policy.py:367-389) re-runs classify_step_risk, which sees the word "Create" in the label and returns irreversible. Because the step has no operator override, its effective risk becomes irreversible, step_tags adds write, and clinical-write requires a system-of-record effect and an idempotency key on a step that writes nothing. Only a qualification override clears it.

Suggested fix

Make the confirmation-opener classification something the policy can re-derive, the same way it accepts sealed local edits (is_local_edit, risk.py:71):

  • In compile.py:2976, seal the evidence on the opener: an explanation prefix plus a postcondition that the dialog opened (for the referral, text_present "Confirm Create New Patient", which apply_referral_rules already adds), and the confirm step id.
  • In infer_step_risk (openadapt_flow/risk.py), return reversible for a click whose sealed opener evidence is present, before the write-keyword branch at risk.py:789. A run where the dialog does not open then halts on the postcondition instead of being treated as a save.

The other violations on the same fresh bundle: #1532 (six field clicks) and #1534 (step_040).

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions