diff --git a/docs/commercial/execute-api.md b/docs/commercial/execute-api.md index 5d24a3e..48d2df9 100644 --- a/docs/commercial/execute-api.md +++ b/docs/commercial/execute-api.md @@ -115,11 +115,21 @@ Poll `GET /v1/executions/{execution_id}`. The response is an A lifecycle state reports current work. It does not report the final result. +!!! note "Target decision-event contract" + The target Execute integration exposes `decision_required` as a + discriminated signed decision event. Its discriminator distinguishes + `operational_attention` from `business_decision` before a partner handles + the task. This requires the pending `openadapt-types` Execute union and the + matching Cloud relay integration. Until those exact schemas are released, + an integration must support only the signed task variants in its + qualification pack. It must not infer a task type from display copy or + optional fields. + | State | Integration action | |---|---| | `queued` | Wait for dispatch. | | `running` | Wait while the runner acts or verifies. | -| `decision_required` | Let the authorized operator complete the signed decision task. | +| `decision_required` | Let the authorized operator complete the signed task. In the target discriminated event, an `operational_attention` task has recovery actions and a `business_decision` task has finite reviewed policy options. See [typed business decisions](../concepts/typed-business-decisions.md). | | `waiting_for_reconciliation` | Do not repeat the write. Wait for the live effect check. | | `terminal` | Read and validate the receipt. | diff --git a/docs/commercial/oem-brief.md b/docs/commercial/oem-brief.md index 79751bf..2ff0caa 100644 --- a/docs/commercial/oem-brief.md +++ b/docs/commercial/oem-brief.md @@ -88,11 +88,20 @@ fields in the public Execute request. The private-pilot contract uses these states. A state describes current work; it is not a success claim. +!!! note "Target decision-event contract" + The target Execute event uses a signed discriminator to distinguish + `operational_attention` from `business_decision`. The first has bounded + recovery actions. The second has finite reviewed policy options. This + requires the pending `openadapt-types` Execute union and matching Cloud + relay integration. Until the exact schemas are released, a partner must use + only the signed task variants in its qualification pack and must not infer + a task type from presentation content. + | State | Meaning | |---|---| | `queued` | OpenAdapt accepted the request for dispatch. | | `running` | The runner is observing, resolving, acting, or verifying. | -| `decision_required` | A typed attended question needs an authorized person. | +| `decision_required` | An authorized person must answer a signed task. In the target discriminated event, the task is an operational attention task or a typed business choice, with the permitted recovery action or reviewed finite option. | | `waiting_for_reconciliation` | A possible or conflicting effect needs a live read before OpenAdapt can continue. | | `terminal` | The execution has one final transaction outcome and a receipt. | @@ -135,9 +144,12 @@ name, parameters, or a model. If the class is unavailable, it uses `record` or ## Attended decisions and mobile delivery When the runner cannot prove a required condition, it creates one signed, -typed decision task. The operator can answer from the local console or the -authenticated phone/web decision surface. The phone receives a closed context; -the customer runner retains the detailed evidence. +operational attention task. The operator can answer from the local console or +the authenticated phone/web decision surface. The phone receives a closed +context; the customer runner retains the detailed evidence. A qualified +workflow can also pause for a typed business decision with finite reviewed +options. The two paths share delivery infrastructure but have separate +authority contracts. See [typed business decisions](../concepts/typed-business-decisions.md). An operator answer is not a command to repeat a write. The runner first reacquires focus, a fresh observation, the workflow state, identity evidence, diff --git a/docs/concepts/durable-runtime.md b/docs/concepts/durable-runtime.md index 235bee6..797c817 100644 --- a/docs/concepts/durable-runtime.md +++ b/docs/concepts/durable-runtime.md @@ -78,14 +78,19 @@ openadapt flow approve runs/replay-20260712-140233 # a human signs off openadapt flow resume runs/replay-20260712-140233 --require-approval ``` -For attended runs, Flow also emits a signed, bounded decision task. An operator -can use the local console or an enabled hosted phone queue to Continue, Skip -when the declared policy permits it, Teach, Reject, or Escalate. The task is -bound to the exact pause, permitted operation, transition, expiry, and -idempotency scope. A decision does not authorize a blind retry. Before a run -continues, the runtime reacquires live state and re-proves the required +For an **operational halt**, Flow also emits a signed, bounded decision task. +An operator can use the local console or an enabled hosted phone queue to +Continue, Skip when the declared policy permits it, Teach, Reject, or Escalate. +The task is bound to the exact pause, permitted operation, transition, expiry, +and idempotency scope. A decision does not authorize a blind retry. Before a +run continues, the runtime reacquires live state and re-proves the required postcondition, identity, and effect evidence. +A declared business-policy choice is different. It has finite reviewed options, +authorized roles, and a graph successor for each option. It cannot use generic +Continue, Skip, or Teach authority. See +[Typed business decisions](typed-business-decisions.md). + The hosted phone lane uses outbound runner HTTPS and an encrypted Web Push notification. It projects a closed context only; screenshots, OCR, values, and free-text application data stay on the customer-controlled runner. See diff --git a/docs/concepts/halt-learn-loop.md b/docs/concepts/halt-learn-loop.md index 59c333f..bb09a20 100644 --- a/docs/concepts/halt-learn-loop.md +++ b/docs/concepts/halt-learn-loop.md @@ -36,7 +36,7 @@ ambiguity, a human-only step, saved-result verification, uncertain delivery, or a required halt. The runner offers only the actions that are safe for that request. -### Operational decisions are bounded; business judgment stays human +### Operational attention is bounded An attended decision manages an **operational halt**. It can ask an authorized operator to prepare the live state, stop, skip an explicitly permitted step, @@ -44,10 +44,11 @@ escalate, teach a correction, or reconcile a possible effect. The signed task binds the exact run, pause, permitted actions, and revalidation requirements. It does not ask OpenAdapt to make arbitrary business judgment. A workflow that -needs a business choice must either express that choice as a reviewed typed -decision contract with permitted actions and a verifiable outcome, or stop for -a human to complete the action. After either path, the runner rechecks the live -identity, state, and configured effect before it reports `VERIFIED` or resumes. +needs a policy choice uses a separate +[typed business decision](typed-business-decisions.md). That contract has finite +options, authorized roles, and one exact successor for each option. It is not a +halt recovery action. After either path, the runner rechecks the live identity, +state, and configured effect before it reports `VERIFIED` or resumes. The question is closed by construction. `openadapt-flow` projects the pause into a signed task carrying typed categories, bounded counts, and digests; the client diff --git a/docs/concepts/qualification-owned-entity-language.md b/docs/concepts/qualification-owned-entity-language.md index f39bb18..2022705 100644 --- a/docs/concepts/qualification-owned-entity-language.md +++ b/docs/concepts/qualification-owned-entity-language.md @@ -20,10 +20,9 @@ name, account number, claim number, screen text, or another live identifier. ## Availability -The signed V2 decision schema and Cloud receiver now preserve a reviewed entity -class and a neutral fallback. The Flow command and Desktop control that set a -class are part of the coordinated V2 release work. Until that release, do not -edit a signed task or sealed artifact by hand to change its wording. +The signed decision contract and its receivers preserve a reviewed entity class +and a neutral fallback. Do not edit a signed task or sealed artifact by hand to +change its wording. The class is presentation metadata. It does not change authorization, identity checks, actuation, or verification. It is optional and its absence does not @@ -31,10 +30,10 @@ block qualification, certification, or execution. ## Optionally set the label during qualification -With the coordinated Flow and Desktop release, a person or qualification tool -can select one reviewed entity class for an exact workflow step that can create -an attended decision. This does not require a separate author role. The same -person who records, reviews, or deploys the workflow can set it. +A person or qualification tool can select one reviewed entity class for an +exact workflow step that can create an attended decision. This does not require +a separate author role. The same person who records, reviews, or deploys the +workflow can set it. The class belongs to that step in that workflow version. It is not a setting for the whole organization or for all workflows that use the same application. @@ -53,11 +52,9 @@ can use `loan application`. If no class is set, OpenAdapt uses the neutral ## What happens at run time -After the coordinated Flow and Desktop release, when the exact qualified step -halts, Flow copies the approved class into the signed decision task. Cloud and -Desktop show that class only when they can validate the task and recognize its -reviewed remote-safe vocabulary. Desktop does not read this label before that -release. +When the exact qualified step pauses, Flow copies the approved class into the +signed decision task. Cloud and Desktop show that class only when they can +validate the task and recognize its reviewed remote-safe vocabulary. The runner keeps the actual identity evidence in its declared customer boundary. Before it resumes any action, it checks the live identity, current diff --git a/docs/concepts/typed-business-decisions.md b/docs/concepts/typed-business-decisions.md new file mode 100644 index 0000000..c4eb1c0 --- /dev/null +++ b/docs/concepts/typed-business-decisions.md @@ -0,0 +1,124 @@ +--- +description: >- + Define a finite, authorized human policy choice in a qualified OpenAdapt + workflow. Keep it separate from an operational halt and verify all later + actions. +--- + +# Typed business decisions + +A typed business decision is a finite human policy choice inside a qualified +workflow. It preserves human authority when a workflow cannot derive one +business choice from the available facts. + +For example, a request can meet both a standard route and an approved exception +route. The workflow can ask an authorized person which approved route applies. +It does not ask a model to invent a policy. It does not use an answer as proof +that a later write succeeded. + +## Two different human paths + +OpenAdapt has two separate ways to involve a person. + +| Path | Why the run stops | What the person provides | What happens next | +|---|---|---|---| +| **Operational attention** | The runtime cannot prove a target, identity, state, delivery, or effect condition. | A bounded recovery action, such as prepare the live state, reconcile, teach, or escalate. | The runner repeats the required live checks. It resumes only when they pass. | +| **Typed business decision** | The qualified workflow reaches a declared policy choice. | One finite option from the reviewed decision contract. | The runner records the answer, revalidates the live state, then follows only the successor bound to that option. | + +Do not turn an operational halt into a business decision. Do not use a business +decision to bypass an identity, target, policy, postcondition, or effect gate. + +## Define the decision during qualification + +The person who records, reviews, or deploys a workflow can define a decision. +A separate author role is not required. The qualification interface or a +qualification tool can propose the contract, but the certified workflow version +must contain the reviewed result before a production run can use it. + +Each decision contract includes: + +- one reviewed question; +- two or more finite options; +- the roles that can answer; +- one exact successor for each option; +- an expiry time; +- any local evidence required for an option; and +- affirmative live-state checks that must pass after an answer. + +The workflow graph contains a `business_decision` state. That state has no GUI +action. It pauses before the next branch. The certified graph binds every +option to one exact successor. A repair cannot remove, alter, or route around +that decision. A decision change creates a new qualification revision. + +## What the operator sees + +The operator sees a focused question and only the approved options. For +example: + +> This item qualifies for the standard route and an approved exception. Which +> reviewed route applies? + +- Use the standard route +- Send to the exception reviewer +- Stop this item + +The exact wording and option labels are reviewed static workflow content. They +are not inferred from a screenshot, OCR, application name, parameter, or a +model. A customer-controlled local surface can also show the protected evidence +that the decision requires. A hosted phone surface shows only the reviewed +remote-safe presentation and closed status data. + +This distinction lets the same product support institutional choices such as an +exception disposition, a work priority, an approved service route, or a +customer-specific approval path. OpenAdapt records the answer. It does not +learn a new policy from one answer or silently promote that answer into future +workflow behavior. + +## What happens after an answer + +An operator answer is not a click command and it is not a `VERIFIED` result. + +1. The operator route authenticates the person and their role. +2. It submits one signed option with one idempotency key. +3. The runner validates the task, role, option, expiry, evidence bindings, and + one-use answer scope. +4. The runner stores a signed answer receipt. +5. The runner obtains a fresh settled observation and runs the selected + option's declared revalidation checks. +6. The runner follows only the successor bound to that option. +7. Every later consequential action still requires its normal target, identity, + postcondition, and effect verification. + +If the live application no longer matches the declared state, OpenAdapt halts +before the successor action. If the runner stops after it stores an answer, it +recovers the same signed answer on restart. It does not accept a different +answer for the same request. + +The answer receipt proves that an authorized person selected one reviewed +option. The terminal execution receipt separately proves the business effect. +Only the terminal receipt can report `VERIFIED`. + +## Mobile delivery and privacy + +Desktop, Cloud, and a customer-controlled operator service can deliver the +same decision contract. The runner keeps live record values, screenshots, OCR, +and local evidence inside the declared customer boundary. The portable remote +task carries opaque bindings, option IDs, digests, counts, and closed status +values. It does not carry the question or option text. The receiving surface +resolves those reviewed static strings from a presentation artifact whose digest +the signed delivery policy binds to the exact decision contract. + +If an option requires protected local evidence, the decision stays on a local +operator surface. The system does not copy that evidence to a phone or use an +unreviewed free-text field to describe it. + +## Related documentation + +- Use [attended decisions and the halt-learn loop](halt-learn-loop.md) when a + runtime condition needs correction, reconciliation, or teaching. +- Use [qualification-owned entity language](qualification-owned-entity-language.md) + to set an optional static item class for an operator surface. +- Use [run outcomes and halt reasons](../reference/run-outcomes.md) to interpret + `decision_required` and terminal receipts. +- Use [Integrate OpenAdapt Execute](../commercial/execute-api.md) when a partner + must receive the signed decision event. diff --git a/docs/guides/qualify-a-workflow.md b/docs/guides/qualify-a-workflow.md index 3747ab4..6b66186 100644 --- a/docs/guides/qualify-a-workflow.md +++ b/docs/guides/qualify-a-workflow.md @@ -60,12 +60,9 @@ conflicting records remain refusal conditions. ## Safe entity language for attended decisions -The released `HumanDecisionTaskV2` schema and Cloud receiver define the target -contract for an approved entity class and neutral fallback. Flow 1.30.0 emits -only `HumanDecisionTaskV1`: it does not yet store or emit the V2 -qualification-bound entity class. Until the coordinated Flow and Desktop -release, use the neutral `record` or `item` wording and do not edit a signed -task or sealed artifact by hand. +The signed decision contract carries a reviewed entity class and neutral +fallback. The class is qualification-owned presentation metadata. Do not edit a +signed task or sealed artifact by hand to change its wording. The class is optional presentation metadata. It does not require a separate author role, and its absence does not block qualification, certification, or diff --git a/docs/reference/run-outcomes.md b/docs/reference/run-outcomes.md index d2ecf29..9986d5e 100644 --- a/docs/reference/run-outcomes.md +++ b/docs/reference/run-outcomes.md @@ -91,7 +91,7 @@ published status contract. Lifecycle states: |---|---|---| | `queued` | Accepted, not yet running. | Poll or wait for the webhook. | | `running` | Executing under its governed profile. | Wait. | -| `decision_required` | The run paused for an attended human decision (a durable halt an operator can answer). | Answer the decision from the runner-local portal or the hosted lane; the engine re-verifies live state before continuing. See [Attend a paused run](../concepts/halt-learn-loop.md). | +| `decision_required` | The run paused for an attended decision. The target event contract distinguishes operational attention from a declared typed business decision. | Use only the signed actions or finite options in the task. The engine re-verifies live state before continuing. See [attended decisions](../concepts/halt-learn-loop.md) and [typed business decisions](../concepts/typed-business-decisions.md). | | `waiting_for_reconciliation` | A consequential write is uncertain; the run waits for reconciliation against the system of record. | Reconcile; do not re-submit the same request without its idempotency key. | | `terminal` | The run ended; `terminal_outcome` carries the result. | Read the outcome and evidence receipt. | diff --git a/mkdocs.yml b/mkdocs.yml index d7547cf..f75ca86 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -144,6 +144,7 @@ nav: - Run a deployment: guides/run-a-deployment.md - Read and audit run reports: guides/run-reports.md - Run outcomes and halt reasons: reference/run-outcomes.md + - Typed business decisions: concepts/typed-business-decisions.md - Workflow catalog and halt map: guides/workflow-catalog.md - Attend a paused run and teach a correction: concepts/halt-learn-loop.md - Governed self-healing: concepts/self-healing.md