Skip to content

batch: API-step fixes, compatibility matrix and local-edit classification (#1370 #1371 #1372 #1364 #1374 #1366) - #1383

Merged
abrichr merged 26 commits into
mainfrom
batch/api-and-fast-path
Oct 20, 2026
Merged

abrichr merged 26 commits into
mainfrom
batch/api-and-fast-path

Conversation

@abrichr

@abrichr abrichr commented Oct 19, 2026

Copy link
Copy Markdown
Member

Batch merge of six reviewed PRs, so CI runs once instead of six times. Merging this marks each one merged, because their commits land on main.

Included, merged in this order onto main:

Each PR was reviewed on its own and its CI passed, or was pending with no failures. This branch adds one commit that registers #1374's result files in the artifact inventory: 42 added, 0 removed. Locally, the capability map and release consistency checks pass, llms-full is current, and the name guard is clean.

If CI fails here, the failing PR is taken out of the batch and the rest merge.

🤖 Generated with Claude Code

abrichr and others added 26 commits October 19, 2026 13:08
openadapt_flow/compatibility.py holds every feature (API step, pipelined
read-back, self-repair, standard changes, parallel workers, multi-surface)
against every run profile (default gated, durable, governed, pinned,
qualified, managed), plus the API step with each other feature. Each cell
works or is refused with its reason verbatim, and names the tests behind
it. docs/COMPATIBILITY.md is generated from it
(scripts/build_compatibility_doc.py) and linked from CAPABILITIES.md.

tests/test_compatibility_matrix.py runs the API-step and read-back cells
through the real replayer under each profile and fails when a cell that
should work falls back, or a refusal gives another reason. The pool and
self-repair cells call the refusals the CLI uses (the pool's is now
cli_worklist_pool.pool_profile_refusal). Two workers each running a
Regulated, durable, gated API-step item read VERIFIED.

Building that probe surfaced a race in the durable authority database's
first creation (fixed separately in #1363 and carried here).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… + durable

benchmark/openemr_api_tier/approval_durable.py runs the OpenEMR referral
with API steps off and on, both under ApprovalGate("each_item") and a
durable run, interleaved, with the setup's own SQL read-back. The harness
answers each approval as a stand-in for the person and its wait is
measured and excluded. Every number it writes carries the label "API step
under each_item approval + durable, no run gate; harness answers
approvals; approval wait excluded": the referral bundle doesn't pass the
run gate yet, so this is not the governed production profile.

The approval view now lists each record-check selector once: the real
bundle's 11 record checks select the same record, which repeated the
rows 11 times and pushed the phone view past its row limit.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Draft for the founder; not for merging until decided
(docs/design/LOCAL_EDIT_CLASSIFICATION.md).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
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>
… to the GUI

Review of #1269: only validate.js presence rules were enforced. A browser
also checks native HTML constraints, and a form's own script can validate
or rewrite values before it submits.

- build_body checks required, minlength, maxlength, pattern, min, max and
  the email, url, number and date input types on what it sends, and the
  validate.js presence, length, format, numericality and email rules.
- A form whose script the API step can't run stays on the GUI: an on*
  handler on the form or on a sent field (OpenEMR's capitalizeMe rewrites
  the typed name), a page script listening for submit, or a validate.js rule
  of another kind (OpenEMR's pastDate). Refused at proposal; unavailable at
  run time when the live form has it.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…t replaces

Review of #1269: folded_checks_digest hashed only the folded steps' on-screen
checks, so changing what a replaced step does (its action, value, parameter,
target or identity, a guard, the save itself) left the admitted API step
running in its place.

The digest now covers every replaced step's complete definition, the save
included, minus only the save's own API binding. Any change keeps the API
step on the GUI with the reason until it is proposed and admitted again.
Bindings proposed before this need proposing again (they fail closed).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… runs per arm

Label: API step under each_item approval + durable, no run gate; harness
answers approvals; approval wait excluded. Not the governed production
profile: the referral bundle doesn't pass the run gate yet on its GUI path.

On the local OpenEMR test copy (synthetic patients), interleaved blocks:
- API step: 20/20 correct by SQL read-back, 18 saved through the API
  (r6, the possible duplicate, fell back and created nothing, twice),
  median 1.12 s engine time, 1 approval per item.
- API steps off: 19/20 correct plus 1 fail-closed safe stop (nothing
  saved), median 15.95 s, 2 approvals per new referral.
- No wrong or duplicate chart.

The run paused for a shared quiet window after 19 runs and resumed into a
second directory; approval_durable.py gains --from-block, --skip-done and a
summarize command that rebuilds runs.csv and summary.json from the items.
Only the CSV, the summary and each item's result.json are committed (the
21 MB of screenshots and engine reports are kept outside the repository).

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

# Conflicts:
#	packages/flow/openadapt_flow/runtime/replayer.py
…ed-step digest

After merging main (#1361): the run authorization's admitted_api_step
compared folded_checks_digest over the steps before the save, while #1372
now digests every replaced step including the save. It uses the same range
as the replayer and the proposal. Tests that edit the save re-propose its
digest first, as openadapt-flow api propose does.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…eld and a dialog's dismiss

Every pattern now needs network capture showing no write in the step's window,
URL, title and page count unchanged, and equal record-store snapshots when
the recorder took them. Control+a no longer classifies without capture.

New patterns: confirm_entry (Enter after typing into a text field; the
field_value check reads the text field's exact value) and dismiss_dialog
(an informational dialog's dismiss, e.g. MockMed's What's New 'Continue to
tasks'; checks the page is unchanged and the label is gone). A dismiss is
reconsidered only when 'continue' or 'next' are its only write words and its
risk is still the per-step keyword inference, so effect mining no longer
attaches a placeholder record_written to it (#1377).

Fixes the CI crash on a structural target with no frame_path and the mypy
index error.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
# Conflicts:
#	packages/flow/public-artifacts.json
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@abrichr
abrichr merged commit e481d10 into main Oct 20, 2026
40 checks passed
@abrichr
abrichr deleted the batch/api-and-fast-path 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