Repository navigation
Conversation
… boundary Field values are compared locally and reduced to match booleans and counts. A DecisionRequest refuses anything outside the fixed feature vocabulary. Signed-off-by: Richard Abrich <richard.abrich@mldsai.com>
…tch approval Only problems_only is triaged. Stopped saves are never scored or batched, a batch approval needs a person and writes labels only, and an uncalibrated group sends every save to a person. The learned score uses a numpy logistic regression, Platt or isotonic calibration, a binomial threshold bound and a digest-pinned artifact. Signed-off-by: Richard Abrich <richard.abrich@mldsai.com>
Signed-off-by: Richard Abrich <richard.abrich@mldsai.com>
…bility Who may answer a save is now a per-run approver policy (person-only by default, so nothing changes without one). An agent, rule or system can answer through the local CLI, MCP or a signed webhook only where the policy allows its kind for the step class; a clinical write needs a pinned opt-in. The report records decided_by, the route and the approver identity. Only a person's decision becomes a triage label. The verifier keeps each field it compared on the local report (StepResult.effect_field_checks), so triage from --run-dir can call a save clean, and Desktop can show the diff. Only an independent read (not through the UI) is clean. Recent declines tolerate one slip among 20 or more items. A new eligibility check gives AutonomyEligibilityV1 from a pinned calibration artifact and an exact Clopper-Pearson bound on the audit miss rate. Mirrors openadapt_types.approval (RFC-0002 names) with a conformance test. Docs: APPROVAL_AND_VERIFICATION.md (incl. the planned Desktop check-admit path), and fixes the stale "Not built yet" in APPROVAL_MODES.md and the button labels in EXCEPTION_INBOX.md. Signed-off-by: Richard Abrich <richard.abrich@mldsai.com>
Signed-off-by: Richard Abrich <richard.abrich@mldsai.com>
Signed-off-by: Richard Abrich <richard.abrich@mldsai.com>
Member
Author
|
Carried over into the monorepo as OpenAdaptAI/OpenAdapt#1190 (merged as 921ba228e1a9ca1403634eacf9f5ae99d128fadf). openadapt-flow now lives in OpenAdapt/packages/flow. |
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.
For Richard's review. Don't merge: openadapt-flow is frozen for the monorepo cutover. The branch is based on the freeze SHA eced892.
What's in it
Decision triage (from Chief Architect's
feat/decision-triage). Commits 4ab7eb29, 1f4e236b and 6fc103fe are cherry-picked as bf02e90, 501a8c2 and 1243141, with authorship kept. The original branch wasn't changed.Delegated approvers (
openadapt_flow/approval_mode/approver.py,item_approval.py,gate.py, CLI)--approver-policy FILE,openadapt.approver-policy/v1). It's written once toitem-approval/approver-policy.jsonand every reader applies it. With no policy, or an unreadable one, only a person may answer, so nothing changes without opt-in.local_cli:item-approval approve|decline --decided-by automation --delegate-kind agent|system --delegate-id IDmcp: the same answer from an MCP tool (openadapt-agent feat: durable tiered runtime — checkpoint + pause/approve/resume from last verified state #80)webhook:run --approver-webhook URL --approver-webhook-id ID, secret fromOPENADAPT_APPROVER_WEBHOOK_SECRET. Flow sends PHI-free facts with HMAC-SHA256 in both directions, and the reply must echo the request digest. Any failure leaves the save to a person.clinical-writeandregulatedpolicies, every save isclinical_write.clinical_writestep takes a non-person approver only with a pinned opt-in digest.ItemApprovalRefrecordsdecided_by: automation, the route and the approver. Person answers keep their old bytes.Read-back field checks (
ir.py,runtime/replayer.py)StepResult.effect_field_checksrecords field, typed value, value on file, matched, and tier, fromfield_equalsand record-match effects. It's local report only and left out when empty.--run-dirbuilds comparisons from it, so a confirmed save can now be clean. Desktop docs: rewrite workflow-program IR as an implemented spec + formalize semantics #203 uses the same data for its Check the record diff.Tier rule (RFC-0002 names, decided rule)
independent_readbackis a read of the system of record that doesn't go through the UI: REST, SQL, FHIR, GraphQL or a file export (Flow tier 1).screen_readback. They are never clean.readback_not_independent.Triage items (a) to (d)
learned_fallbackstaysper_item. Whoever pickslearnedasked for a measured miss rate, and an uncalibrated group has none;rule_v0is an explicit choice.decision/eligibility.pyaddsTriageEligibilityProvider. It needs a pinned, eligible calibration artifact plus audit labels, and computes an exact Clopper-Pearson upper bound (bisection, no scipy) that must be under the target. It raisesEligibilityUnavailablewith a code when evidence is missing.openadapt-flow triage eligibilityexits 0 eligible, 3 not yet, 2 no evidence.Types mirror. Flow's core can't depend on openadapt-types (an optional extra, pinned below 0.22), so
approver.pymirrorsopenadapt_types.approval(types #49). A conformance test checks the two match when both are installed. It passed against the types branch.Docs
docs/APPROVAL_AND_VERIFICATION.md, a design note that includes the planned person-only Desktop path forcheck admit.APPROVAL_MODES.md: replaced the stale "Not built yet" list (Desktop feat: compiled-program visualizer (shared graph spec + CLI render) #184 and Cloud test: fix a Python 3.10 permit parse and a Chromium CDP readiness race #395 shipped).EXCEPTION_INBOX.md: now shows Desktop's real button labels fromsrc/lib/attention.ts.DECISION_TRIAGE.mdupdated.Not in this PR
batchstays a post-save review in triage, not a runtime gate.approvalModeContract.ts, "only a person answers an approval"). A delegated run would be refused there, which fails safe. Showing who approved needs a Cloud change.problems_onlyrequirements yet.Tests
tests/test_approval_delegated.py(21) covers:tests/test_decision_triage.py(67) adds the declines threshold, the tier rule, report field checks, Clopper-Pearson and eligibility.test_qualification_gate_campaign.py, at the 300 s per-test timeout. That file passes on its own (38 passed). A clean rerun is in progress.