Repository navigation
flow: run an admitted API step under a governed run and Standard/Regulated - #1361
Merged
Merged
Conversation
…lated Every CLI run carries a run authorization, and the API step fell back to the GUI under any of them. Now it runs there, under these rules. - The run authorization lists the admitted API steps (api_steps): the admitted binding's digest, the folded-checks digest and the record check's contract hashes. The runtime runs an API step only when all three still match; anything else runs on the GUI with the reason. The field is left out when empty, so other authorizations and Cloud's dispatch binding digest are unchanged. - api admit --identity KEY=PARAM names the parameter that identifies the record. The request must send its run value as-is in a form field, and the record check must select by it (match, or new_records for a create). The runtime and the outcome check both verify it; form field and record field are tied by the parameter, not by name. - An API step no person admitted is GUI-only in executable_actuation_paths, so a compiled proposal alone no longer fails the Regulated identity gate. An admitted one without --identity is refused by that gate, which now names the step and the flag. - The outcome check accepts api_folded skips only when the API step's own save in the same report ran on the API path, succeeded, and every covered step was folded. The default profile then reads VERIFIED. Qualification cases, production qualification admissions and managed dispatch still use the GUI steps, each with a named reason: qualifying an API step's path needs case support that is the next pull request. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This was referenced Oct 19, 2026
With --identity, a form save's API step now checks that the request and the record check select the same record in ungoverned and durable runs too, not only governed ones, so the durable checkpoint has the save's identity evidence. A save that checks the right record on screen without a contract still runs on the GUI. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
abrichr
added a commit
that referenced
this pull request
Oct 19, 2026
…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>
4 tasks
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Stacked on #1358, which is stacked on #1355. Merge those first.
Third of the small PRs that put the API step, pipelined read-back and self-repair in one production profile. This one handles governed runs.
Why
Every
openadapt-flow runcarries a run authorization, and the API step fell back to the GUI under any of them ("a governed run uses its qualified GUI path"). Separately, a compiled proposal alone made a bundle fail the Standard/Regulated identity gate, because the gate counted the unadmitted API path as executable and that path had no identity contract.What changes
GovernedRunAuthorization.api_stepslists each admitted API step: the digest of the binding the person admitted, the folded-checks digest, and the record check's contract hashes.build_runtime_authorizationfills it in. The runtime runs an API step only when all three still match; otherwise it runs the GUI steps and says why. The field is left out when empty, so other authorizations and Cloud's dispatch binding digest serialize exactly as before.openadapt-flow api admit --identity KEY=PARAM(for examplesubject_name=lname) names the parameter that identifies the record. The request must send that parameter's run value as-is in a form field, and the record check must select by it (inmatch, or innew_recordsfor a create). The runtime checks this before sending and the outcome classifier checks it again. Form field names belong to the page (form_lname), not the record (lname), so for web forms the field and the record check are tied by the shared parameter rather than by name. Both sides use one shared helper.executable_actuation_paths. The runtime never ran it, so the gate and qualification no longer count it. An admitted one without--identityis still refused by the identity gate, whose message now names the step and the flag.api_foldedskips only when the API step's own save in the same report ran on the API path and succeeded, and every covered step was folded. The save is then checked like any API action. The default profile (Regulated, durable, governed,each_item) now readsVERIFIEDwith one person approval.Named refusals, not silent fallback
These run the GUI steps, each with its reason in
api_fallback:main. A run under a production qualification admission therefore uses the GUI. Supporting API-path cases for folded spans is the next PR.Tests
tests/test_api_step_governed.py(new, 13 tests):VERIFIEDandapproved;api admit --identity;api_stepsis serialized only when non-empty;api admit --identitywrites the contract; a bad parameter, a malformed flag or an unknown key is refused; a record check that doesn't select by the parameter is refused.Locally: 1709 passed across the gate, execution profile, qualification, governed authorization, runner/dispatch, approval and API suites.
ruffand strict mypy pass.Synthetic data only.
🤖 Generated with Claude Code