Skip to content

fix(flow): refuse an API step whose span also wrote - #1370

Merged
abrichr merged 2 commits into
mainfrom
fix/api-proposal-refuse-other-writes
Oct 20, 2026
Merged

abrichr merged 2 commits into
mainfrom
fix/api-proposal-refuse-other-writes

Conversation

@abrichr

@abrichr abrichr commented Oct 19, 2026

Copy link
Copy Markdown
Member

Fourth of six fixes from an external review of #1269. Stacked on #1369 (then #1368), because all three change api_proposal.py.

Bug

An earlier write inside the span (for example POST /reserve.php) was only listed in other_writes_seen, and the API step still replaced the whole span. A run therefore skipped that write.

Fix

  • Proposal: refused when any POST, PUT, PATCH or DELETE other than the save was sent while the replaced steps ran. The reason names the write.
  • Admission: api admit refuses a binding that lists other writes.
  • Run: a binding admitted before this rule runs on the GUI, and api_fallback names the write.

Impact on the OpenEMR referral (needs a decision)

This refuses the referral's API step. OpenEMR's background POST /library/ajax/execute_background_services.php lands inside the span:

the steps the API step would replace also sent POST /library/ajax/execute_background_services.php; one request can't stand in for them

That is the rule as asked, and it fails closed. If background polls like this should be allowed, a person would have to declare a recorded write as unrelated at admission. That is a follow-up for the founder; it isn't in this PR.

Tests

tests/test_api_proposal_other_writes.py (new, 7 tests):

  • the reviewer's /reserve.php case for POST, PUT, DELETE and PATCH;
  • a read inside the span is still fine;
  • admission refuses;
  • a binding admitted before the rule runs on the GUI with the write named.

54 pass with the API-tier, provenance and URL tests.

Synthetic values only.

🤖 Generated with Claude Code

Review of #1269: an earlier POST inside the span (for example /reserve.php)
was only listed in other_writes_seen, and the API step still replaced the
whole span, so a run skipped that write.

A proposal is refused when any POST, PUT, PATCH or DELETE other than the
save was sent while the replaced steps ran. Admission refuses such a
binding, and a binding admitted before this rule runs on the GUI with the
reason.

On the OpenEMR referral this refuses the API step: OpenEMR's background
POST /library/ajax/execute_background_services.php lands inside the span.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…se-other-writes

# Conflicts:
#	packages/flow/openadapt_flow/runtime/replayer.py
@abrichr

abrichr commented Oct 19, 2026

Copy link
Copy Markdown
Member Author

Included in batch #1383, which runs CI once for several reviewed PRs. This PR is marked merged when #1383 merges. Please don't push here unless asked; a new commit leaves it out of the batch.

abrichr added a commit that referenced this pull request Oct 20, 2026
batch: API-step fixes, compatibility matrix and local-edit classification (#1370 #1371 #1372 #1364 #1374 #1366)
@abrichr
abrichr merged commit 1500fb6 into main Oct 20, 2026
40 checks passed
@abrichr
abrichr deleted the fix/api-proposal-refuse-other-writes branch October 20, 2026 00:24
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