From 4de99fa6f680b3593bb1fc7c543710dc70515086 Mon Sep 17 00:00:00 2001 From: abrichr Date: Tue, 28 Jul 2026 04:02:22 -0400 Subject: [PATCH] docs: prepare phone and runtime v3 release guidance --- docs/concepts/deployment-matrix.md | 7 +-- docs/concepts/halt-learn-loop.md | 7 ++- docs/desktop/install.md | 13 ++++-- docs/ecosystem/index.md | 2 +- docs/get-started/what-works-today.md | 4 +- docs/guides/hosted.md | 50 ++++++++++++++------- docs/guides/run-reports.md | 43 +++++++++++++++--- docs/guides/security-and-data-handling.md | 4 +- docs/guides/security-review.md | 21 +++++---- docs/reference/cli.md | 54 ++++++++++++++++++----- docs/reference/compatibility.md | 4 +- docs/reference/configuration.md | 4 ++ 12 files changed, 158 insertions(+), 55 deletions(-) diff --git a/docs/concepts/deployment-matrix.md b/docs/concepts/deployment-matrix.md index 3418538..6bee62d 100644 --- a/docs/concepts/deployment-matrix.md +++ b/docs/concepts/deployment-matrix.md @@ -66,10 +66,11 @@ before compilation rather than weakening the privacy or runtime gate. Cloud checks the attestation's exact recording and bundle hashes, provenance, report and evidence hashes, policy, engine-derived `low`/`consequential` risk -class, HMAC, freshness, and one-time organization/token challenge. Server-side +class, organization-trusted Ed25519 runner signature, separate ingest-token MAC, +freshness, and one-time organization/token challenge. Server-side signer trust, policy, risk-class, and deployed compiler-version allowlists are additional -restrictions. This is operator self-attestation, not independent certification -or a general safety guarantee. +restrictions and are checked again before dispatch. This is operator +self-attestation, not independent certification or a general safety guarantee. The risk-based launch default is: diff --git a/docs/concepts/halt-learn-loop.md b/docs/concepts/halt-learn-loop.md index 5303500..1892916 100644 --- a/docs/concepts/halt-learn-loop.md +++ b/docs/concepts/halt-learn-loop.md @@ -12,8 +12,10 @@ agent, and neither puts a model call on the runtime path. ## Where a halt goes: the attended decision When a run cannot confirm something, it stops and projects the paused step into -a **bounded question** a member of staff can answer — from a workstation, or -from a phone on your own network through ingress you control. +a **bounded question** a member of staff can answer from a workstation or an +authorized phone. The customer-controlled runner can dial out to the hosted +decision lane, or an organization can publish the full-fidelity local portal +through its own trusted ingress. The question is closed by construction. `openadapt-flow` projects the pause into a signed task carrying typed categories, bounded counts, and digests; the client @@ -208,6 +210,7 @@ consequence in full: | Answer | Effect on this run | Effect on future runs | |---|---|---| | Check and continue | Re-verifies live state, then continues | None — the same drift stops the next run | +| Reject and end run | Ends the run with the operator's rejection recorded | None | | Teach the correction | Continues nothing now | Enters the halt-learn loop below | | Needs more help | Leaves the run paused and untouched | None | diff --git a/docs/desktop/install.md b/docs/desktop/install.md index d2e3196..14fc912 100644 --- a/docs/desktop/install.md +++ b/docs/desktop/install.md @@ -23,7 +23,7 @@ you explicitly push it to a [cloud workspace](connect-to-cloud.md). Get the installer from [openadapt.ai/download](https://openadapt.ai/download). The page detects your OS and architecture and offers the right build. Public Beta release -`desktop-v0.14.0` ships the complete Windows, macOS, and Linux installer set with +`desktop-v0.15.0` ships the complete Windows, macOS, and Linux installer set with `SHA256SUMS`, a CycloneDX SBOM, per-platform metadata, and build-provenance attestations. @@ -118,7 +118,7 @@ first-week failures. ## During a governed run -Desktop 0.14.0 can show a separate always-on-top status surface without adding +Desktop 0.15.0 can show a separate always-on-top status surface without adding anything to the target application. While OpenAdapt is observing or executing, the surface is non-focusable, ignores pointer input, exposes no controls, and is excluded from capture before it becomes visible. Controls become interactive @@ -134,7 +134,14 @@ and disappears if neither corner is safe. These presentation elements are not verification evidence and do not weaken the pointer, focus, or capture-exclusion boundary. [Watch the public demo](https://app.openadapt.ai/demo#footage) or review the exact released -[control-overlay contract](https://github.com/OpenAdaptAI/openadapt-desktop/blob/desktop-v0.14.0/docs/CONTROL_OVERLAY.md). +[control-overlay contract](https://github.com/OpenAdaptAI/openadapt-desktop/blob/desktop-v0.15.0/docs/CONTROL_OVERLAY.md). + +When an attended run halts, Desktop can connect the customer-controlled runner +to the hosted decision lane. The runner uses outbound HTTPS only and sends a +signed, closed, PHI-free context. An authorized operator can answer from a +phone. The answer does not mark the step complete: the runner reacquires the +live application and repeats its identity, state, target, and effect checks +before it continues. This path requires `openadapt-flow` 1.26 or newer. ## Where to go next diff --git a/docs/ecosystem/index.md b/docs/ecosystem/index.md index 32cd0a5..4ec4d8e 100644 --- a/docs/ecosystem/index.md +++ b/docs/ecosystem/index.md @@ -33,7 +33,7 @@ module inside it: | [OpenAdapt](https://github.com/OpenAdaptAI/OpenAdapt) | **Beta** | Installer/meta-package and unified `openadapt flow` dispatcher. | | [openadapt-flow](https://github.com/OpenAdaptAI/openadapt-flow) | **Beta** | Canonical compiler and governed runtime. Drives web, native Windows, native macOS, native Linux, RDP, and Citrix/VDI as first-class substrates behind one backend protocol. | | [OpenAdapt Cloud](https://app.openadapt.ai/) | **Beta** | Proprietary live control plane for the managed subscription: organizations, exact-hash admission, runner orchestration, reports, billing, and usage. | -| [openadapt-desktop](https://github.com/OpenAdaptAI/openadapt-desktop) | **Beta** | Public `desktop-v0.14.0` provides Windows MSI/NSIS, macOS arm64/x64 DMG, and Linux AppImage/DEB installers. Every installer path is installed, launched, and uninstalled in the native release workflow; the release includes exact checksums, a CycloneDX SBOM, platform metadata, and build-provenance attestations. | +| [openadapt-desktop](https://github.com/OpenAdaptAI/openadapt-desktop) | **Beta** | Public `desktop-v0.15.0` provides Windows MSI/NSIS, macOS arm64/x64 DMG, and Linux AppImage/DEB installers, plus the outbound attended-decision connection for authorized phone answers. Every installer path is installed, launched, and uninstalled in the native release workflow; the release includes exact checksums, a CycloneDX SBOM, platform metadata, and build-provenance attestations. | | [openadapt-agent](https://github.com/OpenAdaptAI/openadapt-agent) | **Experimental** | Active v2 bridge that exposes governed Flow bundles to MCP clients and Agent Skills. The pre-v2 model-driven execution wrapper is the deprecated line; the repository itself is active. | | [openadapt-capture](https://github.com/OpenAdaptAI/openadapt-capture) | **Beta** | Canonical native screen, mouse, keyboard, timing, and window-scoped recorder behind Flow's Windows, macOS, Linux, RDP, and Citrix recording paths. Capture 1.1 retains Windows UIA evidence at action time; remote sessions remain externally black-box. Browser recording remains inside Flow's Playwright listener. | | [openadapt-privacy](https://github.com/OpenAdaptAI/openadapt-privacy) | **Experimental** | Optional PII/PHI scrubbing used on configured persist, log, and upload paths. | diff --git a/docs/get-started/what-works-today.md b/docs/get-started/what-works-today.md index ca2e56a..7505d05 100644 --- a/docs/get-started/what-works-today.md +++ b/docs/get-started/what-works-today.md @@ -68,10 +68,10 @@ customer-controlled runtime connected to the same governance model. | Native Linux backend | **Supported** | Required current-main job [`linux-atspi-x11`](https://github.com/OpenAdaptAI/openadapt-flow/actions/runs/30059807758/job/89378981573) at exact Flow commit `3de5fc67acf3024a621f812c5a6ed9be07fac335` ran one fresh GTK3 process per trial on Ubuntu 24.04 X11/AT-SPI. It confirmed 3/3 exact-file effects, 3/3 ambiguous-target refusals, and 3/3 stale-target refusals, with 0 silent incorrect successes, 0 over-halts, 0 operator interventions, and 0 model calls. | Native receipts prove AT-SPI delivery only; independent exact file bytes or confirmed absence prove effects. This is bounded to the in-tree GTK3 fixture and CI Xvfb image; it does not establish Wayland or arbitrary third-party application support. | | RDP backend | **Supported** | Two bounded results exercise complementary RDP paths. Aardwolf 0.2.14 over a Parallels Windows 11 VM completed 3/3 Windows Run-dialog file effects with independent guest-tools readback. The accepted full governed lifecycle at mechanism commit `6031fde` recorded, compiled, and replayed a synthetic note workflow through real FreeRDP3-transported pixels/input: 3/3 healthy effects and 3/3 drift safe-halts, with zero model calls, silent incorrect successes, false completions, drift writes, or healthy over-halts. Consequential remote actions now acquire a fresh frame, re-resolve target and identity, and use a one-shot input lease that refuses changed session context, pixels, dimensions, or readiness before delivery. Review the [Aardwolf/Windows report](https://github.com/OpenAdaptAI/openadapt-flow/blob/6610d24cebba27918b8ea507b2f05a094057ac85/benchmark/rdp/results_82a658a_20260718.sanitized.json), the [FreeRDP lifecycle report](https://github.com/OpenAdaptAI/openadapt-flow/blob/affedc5f1f0de533a0744deaa8e30a203c91c6b3/benchmark/rdp_ladder/results.json), [Flow PR #142](https://github.com/OpenAdaptAI/openadapt-flow/pull/142), [Flow PR #177](https://github.com/OpenAdaptAI/openadapt-flow/pull/177), and [Flow PR #238](https://github.com/OpenAdaptAI/openadapt-flow/pull/238). | The Windows batch qualifies its exact task, snapshot, transport, and oracle. The FreeRDP batch qualifies a synthetic Linux Tk task over a real RDP round trip; it is not Aardwolf, a Windows-app qualification, Citrix ICA/HDX, or WAN-captured drift. The two-phase mechanism is separately covered by runtime and backend refusal tests; it does not enlarge those bounded application results. | | Citrix / VDI backend | **Supported** | The dedicated `--backend citrix` path selects the exact Citrix Workspace/Viewer owner, optionally binds an exact title, requires a readiness marker for governed `run`, carries the closed target into durable resume, and uses the shared pixel identity, effect, policy, and halt contracts. Consequential input reacquires the exact client window, focus, geometry, readiness, fresh pixels, resolved target, and record identity, then refuses any change before the first input edge. The accepted no-DOM qualification completed 3/3 healthy effects and 3/3 severe-drift safe-halts with 0 model calls, silent incorrect successes, false completions, healthy over-halts, or drift writes. Review the [immutable report](https://github.com/OpenAdaptAI/openadapt-flow/blob/f6faac5b900b78cbda5980de0e983a9f987285ac/benchmark/citrix_workspace/results.json), [Flow PR #183](https://github.com/OpenAdaptAI/openadapt-flow/pull/183), and [Flow PR #238](https://github.com/OpenAdaptAI/openadapt-flow/pull/238). | The accepted artifact explicitly records `code_readiness_accepted: true` and `ica_hdx_accepted: false`. It qualifies the shipped Citrix Workspace-window backend contract over a no-DOM canvas stand-in, not a counted real ICA/HDX batch. The exact ICA/HDX client, codec, latency, DPI, lock/readiness, input, identity, and effect matrix is a separate per-deployment qualification boundary. | -| Desktop authoring GUI and tray | **Supported / Beta** | Public `desktop-v0.14.0` provides Windows MSI/NSIS, macOS arm64/x64 DMG, and Linux AppImage/DEB installers. All six installer paths were installed, launched, and uninstalled in the native release workflow; the release includes `SHA256SUMS`, a CycloneDX SBOM, per-platform metadata, and build-provenance attestations. | Windows/Linux remain unsigned and macOS is ad-hoc signed, so verify checksums and provenance before overriding the OS publisher warning. The app and CLI drive the same released compiler/runtime. | +| Desktop authoring GUI and tray | **Supported / Beta** | Public `desktop-v0.15.0` provides Windows MSI/NSIS, macOS arm64/x64 DMG, and Linux AppImage/DEB installers. It can connect the customer-controlled attended console to the hosted phone-decision lane through outbound HTTPS. All six installer paths were installed, launched, and uninstalled in the native release workflow; the release includes `SHA256SUMS`, a CycloneDX SBOM, per-platform metadata, and build-provenance attestations. | Windows/Linux remain unsigned and macOS is ad-hoc signed, so verify checksums and provenance before overriding the OS publisher warning. The app and CLI drive the same released compiler/runtime. A phone answer never bypasses the runner's fresh identity, state, target, or effect checks. | | Hosted CLI connectivity | **Supported / public offer** | `login`, exact-hash artifact preparation/upload, one-time runtime validation, bound replacement activation, and `report-break` connect the local engine to the live control plane. | Upload requires destination policy and an approved sanitized derivative; checkout never bypasses an egress refusal. | | Artifact sanitation and local review | **Supported / launch gate** | The sanitized-derivative pipeline inventories, transforms, rescans, manifests, hashes, and supports local review/approval. | The raw original remains sensitive; unknown or unresolved content is refused; runtime observations can reintroduce PHI/PII. | -| Cross-engine hosted validation | **Supported / launch gate** | `validate-hosted` binds an approved recording and bundle, compiler provenance, strict lint, policy certification, derived risk class, and successful replay report to a one-time Cloud challenge. | It is operator self-attestation signed with the ingest token, not an independently observed certification. Exact deployment policy, risk-class, and deployed compiler-version allowlists still apply. | +| Cross-engine hosted validation | **Supported / launch gate** | Runtime-validation v3 binds an approved recording and bundle, compiler provenance, strict lint, policy certification, derived risk class, and successful replay report to a one-time Cloud challenge. An organization-trusted Ed25519 runner key signs the evidence, and a separate ingest-token MAC binds the submission. | It is operator self-attestation, not an independently observed certification. Cloud rechecks exact signer trust and current deployment policy, risk-class, and compiler-version allowlists before dispatch. | | Hosted browser recorder and runtime health | **Supported / bounded launch component** | A retained non-simulated hosted session on `openadapt-flow` 1.8.0 produced frames and input evidence, assembled a compileable recording, finalized one workflow idempotently, enforced resource limits, and cleaned up ephemeral qualification data. Authenticated live health reports the pinned managed-runtime 1.23.0 runner/compiler identity and checks auth, database, storage, callbacks, scheduler, retention, secrets, validation policy, and billing. | Explicitly initiated, public-HTTPS, non-regulated authoring only. Raw observations remain private inside the declared hosted boundary. Readiness proves deployed dependencies and service identity, not a customer workflow qualification or SLA. | | Hosted dashboard/control plane | **Supported / public offer** | Authentication, organizations, exact-hash bundle ingest, immutable run admission, browser runner orchestration, structural reports, replacement activation, billing, and metering form the managed lifecycle. | Production uses live dependencies and fails unavailable rather than substituting mock behavior. | | Hosted execution | **Supported / public offer** | Live Stripe Checkout connects onboarding and subscription entitlements to managed browser execution; the runner verifies exact admitted bundle bytes and authenticated callbacks. | The public subscription covers approved browser workflows. Other substrates use separately scoped deployments and commercial terms. Checkout does not create an SLA or certification. | diff --git a/docs/guides/hosted.md b/docs/guides/hosted.md index 199a59a..22d57d8 100644 --- a/docs/guides/hosted.md +++ b/docs/guides/hosted.md @@ -98,19 +98,23 @@ The hosted lifecycle is: validation environment. 6. Sanitize, review, and approve the compiled bundle. Bundle sanitation must preserve execution-bearing content. -7. Run `validate-hosted`. It requests an expiring, one-time organization/token - challenge and creates an operator attestation bound to the exact approved - recording, bundle, compiler provenance, policy, risk class, and replay report. -8. Immediately push the approved bundle with that attestation. Cloud consumes +7. Provision one Ed25519 key for the customer-controlled runner. Give its + printed public entry to the Cloud deployment operator, who adds it to the + organization's trust policy. Keep the private key inside the runner boundary. +8. Run `validate-hosted`. It requests an expiring, one-time organization/token + challenge and creates a v3 operator attestation bound to the exact approved + recording, bundle, compiler provenance, policy, risk class, replay report, + organization, and runner. +9. Immediately push the approved bundle with that attestation. Cloud consumes the challenge and admits the bundle only if policy and risk-class allowlists also pass. -9. Configure the vault secret-set reference and optional schedule. The target +10. Configure the vault secret-set reference and optional schedule. The target URL, allowed hosts, and parameter schema are immutable attested bundle properties; supply non-secret parameter values for each run. -10. Teach or repair a halted run locally, revalidate it, and activate the +11. Teach or repair a halted run locally, revalidate it, and activate the attested replacement on the same workflow; promote only a revision that passes its gates. -11. Inspect usage and manage the subscription through the billing portal. +12. Inspect usage and manage the subscription through the billing portal. Checkout does not relax a safety or egress refusal. A paid organization cannot upload an unapproved artifact or execute a workflow that fails its configured @@ -145,7 +149,15 @@ openadapt flow review-sanitized bundle.sanitized --original bundle openadapt flow approve-sanitized bundle.sanitized \ --original bundle --reviewer alice@example.com -# 4. Acquire the one-time challenge and bind the local evidence to it. +# 4. Once per runner, create its signing key. Give the printed public entry to +# the Cloud deployment operator. Keep the private key local. +openadapt flow runtime-keygen \ + --out /secure/runner-ed25519.key \ + --key-id clinic-runner-2026-07 \ + --runner-id clinic-runner-01 \ + --org-id 00000000-0000-4000-8000-000000000001 + +# 5. Acquire the one-time challenge and bind the local evidence to it. openadapt flow validate-hosted \ --recording recording.sanitized \ --bundle bundle.sanitized \ @@ -153,10 +165,14 @@ openadapt flow validate-hosted \ --policy clinical-write \ --risk-class consequential \ --environment validation/mock-emr-v1 \ + --target-kind web \ --target-url https://validation.example/login \ + --signing-key-id clinic-runner-2026-07 \ + --signing-runner-id clinic-runner-01 \ + --signing-private-key-file /secure/runner-ed25519.key \ --out triage.runtime-validation.json -# 5. Consume the challenge by uploading the exact attested bundle once. +# 6. Consume the challenge by uploading the exact attested bundle once. openadapt flow push bundle.sanitized --kind bundle --name "Triage" \ --validation-attestation triage.runtime-validation.json ``` @@ -238,16 +254,20 @@ chain: - the approved bundle archive SHA-256 is the archive uploaded with the attestation. -The client signs this envelope with the ingest token. Cloud verifies the HMAC, +The customer-controlled runner signs this envelope with its organization-trusted +Ed25519 key. A separate ingest-token MAC binds the complete submission to the +one-time challenge. Cloud verifies the signature, runner and organization trust, fresh timestamp, exact bundle hash, configured policy, risk-class, and deployed compiler-version allowlists, and the challenge's organization, token, nonce, -expiry, and unused state. The challenge expires after 15 minutes and is consumed -transactionally by the accepted bundle upload. +expiry, and unused state. It repeats the current signer, policy, risk-class, and +compiler admission checks before dispatch. The challenge expires after 15 +minutes and is consumed transactionally by the accepted bundle upload. This is **operator self-attestation**, not independent certification. It proves -that the token holder produced a tamper-evident envelope over the named local -evidence; Cloud did not observe the local replay and the HMAC is not an auditor -signature. `certify` means only that the bundle passed the selected policy. +that the trusted runner signed a tamper-evident envelope and that the ingest +token holder submitted that exact envelope. Cloud did not observe the local +replay, and neither proof is an auditor signature. `certify` means only that the +bundle passed the selected policy. Independent certification would require a separately controlled evaluator, test environment, evidence custody, and signing identity. Neither mechanism is a blanket safety, compliance, or correctness guarantee. diff --git a/docs/guides/run-reports.md b/docs/guides/run-reports.md index 911c625..5f550b7 100644 --- a/docs/guides/run-reports.md +++ b/docs/guides/run-reports.md @@ -13,7 +13,32 @@ Each replay writes a timestamped directory under `runs/` (override with before sharing. - `report.json`: the machine-readable version, for programmatic auditing. -The final console line names the report path and whether the run succeeded. +The final console line names the report path and its precise execution outcome. + +## Read the final outcome first + +Flow 1.26 records one closed execution outcome in `report.json` and in the +human-readable report: + +| Outcome | Meaning | +|---|---| +| `VERIFIED` | Every contract required by the selected profile passed. This is the only production success. | +| `COMPLETED_UNVERIFIED` | Execution finished, but the evidence did not prove the complete contract. Standard and Regulated execution treat this as non-success. | +| `HALTED` | A policy, identity, state, target, postcondition, or effect gate refused to continue. | +| `FAILED` | An infrastructure or runtime failure stopped the run. | +| `ROLLED_BACK` | A configured compensating action completed and its result was verified. This remains a non-success. | + +The outcome envelope also records which contracts were required and passed, +the evidence classes that support the result, model-call count, external-network +call state, and compensation count. Do not infer success from the legacy +`success` boolean when this envelope is present. + +For a stopped consequential run, read `transaction_outcome` before deciding +what to do next. `HALTED_BEFORE_EFFECT` requires positive evidence that the +effect is absent. `RECONCILIATION_REQUIRED` means delivery or persistence can +be uncertain, conflicting, or unverifiable. Reconcile the current business +state before a retry. An empty evidence list does not prove that no write +occurred. ## What the report tells you, per step @@ -29,7 +54,8 @@ For each step, the report records: verified against the system of record, with its verdict. - **Model calls**: any call to a grounding or state-verification model, so the $0 property is observable, not assumed. -- **Outcome**: success, or a halt naming the violated expectation. +- **Outcome**: the precise execution outcome, its required and passed + contracts, and a halt or reconciliation reason when applicable. ## The identity-coverage line @@ -43,17 +69,20 @@ confirm it afterward. When auditing a consequential run, check: -1. **Did every write verify an effect?** A write with only a screen +1. **Is the final outcome `VERIFIED`?** Standard and Regulated runs have no + other successful outcome. If reconciliation is required, inspect the + current business state before any retry. +2. **Did every write verify an effect?** A write with only a screen postcondition is exactly as silent as the [five transactional faults](../concepts/effect-verification.md). Confirm the effect verdict is CONFIRMED, not just a passing screen check. -2. **Were consequential clicks identity armed?** Cross-check the +3. **Were consequential clicks identity armed?** Cross-check the identity-coverage line against the steps that navigate to or write a record. -3. **Did anything heal?** A heal means the UI drifted. Review the diff and +4. **Did anything heal?** A heal means the UI drifted. Review the diff and confirm the healed target is correct before promoting the healed bundle. -4. **Were there model calls?** On a healthy deterministic run there should be +5. **Were there model calls?** On a healthy deterministic run there should be none. Any call is recorded; understand why it happened. -5. **Read the halt.** The report names the violated expectation. A halt is not +6. **Read the halt.** The report names the violated expectation. A halt is not terminal: demonstrate the fix once and [`openadapt flow teach`](../reference/cli.md#teach) compiles it back into the workflow through the governed induction path, so it stops halting on that diff --git a/docs/guides/security-and-data-handling.md b/docs/guides/security-and-data-handling.md index 402582a..03c2ac1 100644 --- a/docs/guides/security-and-data-handling.md +++ b/docs/guides/security-and-data-handling.md @@ -262,13 +262,13 @@ configured retention component separately from this destructive-operation gate. ## Release integrity -The public Desktop `desktop-v0.14.0` release includes Windows, macOS, and Linux +The public Desktop `desktop-v0.15.0` release includes Windows, macOS, and Linux installers, `SHA256SUMS`, a CycloneDX SBOM, per-platform metadata, and GitHub build-provenance attestations. These prove source and build provenance, not publisher identity. Windows and Linux installers remain unsigned and macOS installers are ad-hoc signed; Apple Developer ID/notarization and Windows Authenticode require the corresponding external identities. Verify the -[release assets](https://github.com/OpenAdaptAI/openadapt-desktop/releases/tag/desktop-v0.14.0) +[release assets](https://github.com/OpenAdaptAI/openadapt-desktop/releases/tag/desktop-v0.15.0) before overriding an operating-system publisher warning. ## Deployment options diff --git a/docs/guides/security-review.md b/docs/guides/security-review.md index a4d0461..1f6ca35 100644 --- a/docs/guides/security-review.md +++ b/docs/guides/security-review.md @@ -45,7 +45,7 @@ enables model grounding and configures an appliance. | What happens during model-assisted repair? | The deterministic ladder runs first. If model grounding is explicitly allowed, a proposal is still subject to the identity and postcondition gates and is counted in the report. A model proposal is not an automatic safety exemption. | | Can model inference run on-prem? | Yes. The optional VLM service is designed for a private-LAN deployment with no retention. Keep model grounding disabled if the deployment does not need it. | | Is upload code physically absent from regulated builds? | The compiler does not currently publish a separate, verified "regulated binary" exclusion guarantee. Enforce no-egress at the host/network boundary and verify the installed artifact. The desktop recorder documents build-time exclusions for its own enterprise builds; that is not a blanket compiler guarantee. | -| What proves an uploaded bundle was tested? | `validate-hosted` checks exact recording/bundle provenance, strict lint, policy certification, risk class, and a successful matching local run report, then signs their hashes with the ingest token under a one-time challenge. Cloud verifies exact policy/risk-class allowlists and consumes the challenge once. This is operator self-attestation, not independent observation or third-party certification. | +| What proves an uploaded bundle was tested? | `validate-hosted` checks exact recording/bundle provenance, strict lint, policy certification, risk class, and a successful matching local run report. Runtime-validation v3 signs that envelope with an organization-trusted Ed25519 runner key and uses a separate ingest-token MAC for the one-time challenge. Cloud verifies signer trust and current compiler, policy, and risk-class allowlists at ingest and dispatch. This is operator self-attestation, not independent observation or third-party certification. | | Can a hosted workflow target a private service? | Not through the managed browser lane. Admission requires public DNS names and the runner resolves them again, refusing literal IPs, special-use names, wildcards, and any private, loopback, link-local, reserved, or otherwise non-global answer. Provider resolver behavior and DNS-rebinding resistance remain live qualification items. Private applications require a qualified customer-controlled execution boundary rather than managed public egress. | | How is the declared runtime boundary enforced? | The qualified boundary ID is hashed into local replay evidence, persisted with the activated workflow, included in every job, installed independently in the runner, and returned by runner health. Cloud and the runner refuse a mismatch. This binds configuration; it does not independently certify that the named infrastructure satisfies a regulatory standard. | | Can a retried run execute twice? | Live clients supply a request-bound idempotency key, and the database permits one queued/running run per workflow. Dispatch is claimed once and the provider call ID is recorded. If acknowledgement is lost, the run remains reserved and single-flight for callback or operator/provider reconciliation; timeout alone does not authorize a refund and retry. | @@ -64,12 +64,14 @@ enables model grounding and configures an appliance. execution-bearing content, parameterize before compiling. !!! note "Self-attestation is not independent certification" - The HMAC shows that the ingest-token holder signed a non-mutated envelope; - Cloud did not witness the local test. The envelope binds approved artifact - hashes, compiler/config and parameter-schema hashes, lint/certification - evidence hashes, policy, derived risk class, report hash, environment hash, - timestamp, and one-time challenge. Independent certification needs a - separately controlled evaluator, evidence custody, and signing identity. + The Ed25519 signature shows that an organization-trusted runner signed the + non-mutated envelope. The separate ingest MAC binds the submission to the + one-time token challenge. Cloud did not witness the local test. The envelope + binds approved artifact hashes, compiler/config and parameter-schema hashes, + lint/certification evidence hashes, policy, derived risk class, report hash, + environment hash, timestamp, and one-time challenge. Independent + certification needs a separately controlled evaluator, evidence custody, + and signing identity. ## Audit and integrity @@ -135,7 +137,8 @@ qualification was run on Flow 1.8.0; the live runner and compiler report the pinned managed-runtime Flow 1.23.0 identity. The public readiness endpoint currently verifies live mode, authentication, database migrations, private storage, runner, compiler, recorder, callbacks, scheduler, retention policy, secret encryption, -runtime-validation allowlists, and live billing configuration. Readiness proves +runtime-validation allowlists, organization-bound signer trust, legacy-artifact +migration state, and live billing configuration. Readiness proves those dependencies and contracts are configured and reachable; it is not a customer workflow qualification or an SLA. @@ -178,7 +181,7 @@ execution](hosted.md) and [Qualification evidence](../get-started/what-works-tod ## Release and secure-development evidence Python releases publish immutable wheel and sdist artifacts with PyPI -provenance attestations. Desktop `desktop-v0.14.0` publishes its complete +provenance attestations. Desktop `desktop-v0.15.0` publishes its complete Windows, macOS, and Linux installer set with checksums, a CycloneDX SBOM, per-platform metadata, and GitHub build-provenance attestations. The native installers are still unsigned on Windows/Linux and ad-hoc signed on macOS; diff --git a/docs/reference/cli.md b/docs/reference/cli.md index 08c180a..d34126d 100644 --- a/docs/reference/cli.md +++ b/docs/reference/cli.md @@ -30,6 +30,7 @@ is a subcommand of `openadapt flow`. | [`disambiguate`](#disambiguate) | Surface and resolve compile-time ambiguities | 2 if a consequential ambiguity is unresolved | | [`connect`](#connect) | Pair this computer to a Cloud workspace (launcher command, needs OpenAdapt 1.7+) | 0/1 | | [`login`](#login) | Validate a hosted ingest token and remember the host | 0/1 | +| [`runtime-keygen`](#runtime-keygen) | Create one Ed25519 runner key and print its public Cloud trust entry | 0/1 | | [`push`](#push) | Explicitly upload a recording or bundle to a control plane | 0/1 | | [`validate-hosted`](#validate-hosted) | Bind local validation evidence to a one-time hosted challenge | 0/1 | | [`report-break`](#report-break) | Send a scrubbed, schema-minimized halt descriptor | 0/1 | @@ -522,6 +523,28 @@ openadapt flow login --token | `--host` | Control-plane base URL. Defaults to the configured host, then `https://app.openadapt.ai`. | | `--no-save` | Validate without writing the host/token to the config file. | +## runtime-keygen + +Create the Ed25519 key that identifies one customer-controlled qualification +runner to an organization. The command refuses an existing output path. It +prints the public trust entry for Cloud and keeps the private key file inside +the runner boundary. + +```bash +openadapt flow runtime-keygen \ + --out /secure/runner-ed25519.key \ + --key-id clinic-runner-2026-07 \ + --runner-id clinic-runner-01 \ + --org-id 00000000-0000-4000-8000-000000000001 +``` + +| Flag | Description | +|---|---| +| `--out` | New private-key file. It must not exist. On POSIX, Flow creates it owner-only. | +| `--key-id` | Stable public key identifier in the Cloud trust map. | +| `--runner-id` | Exact runner identity that Cloud binds to this key. | +| `--org-id` | Exact Cloud organization UUID that trusts this runner. | + ## validate-hosted Acquire an expiring, one-time Cloud challenge and create a signed operator @@ -538,8 +561,12 @@ openadapt flow validate-hosted \ --policy clinical-write \ --risk-class consequential \ --environment validation/mock-emr-v1 \ + --target-kind web \ --target-url https://validation.example/login \ --allowed-host cdn.validation.example \ + --signing-key-id clinic-runner-2026-07 \ + --signing-runner-id clinic-runner-01 \ + --signing-private-key-file /secure/runner-ed25519.key \ --out triage.runtime-validation.json ``` @@ -551,27 +578,34 @@ openadapt flow validate-hosted \ | `--policy` | Named or file-backed policy that must pass again during validation. | | `--risk-class` | `low` or `consequential`; must match the risk derived from the compiled steps and be allowed by Cloud. | | `--environment` | Non-PHI validation-environment identifier; only its SHA-256 is included. | +| `--target-kind` | Optional expected substrate: `web`, `windows`, `macos`, `linux`, `rdp`, or `citrix`. The report supplies the signed value; this flag can only cross-check it. | | `--target-url` | Exact non-PHI HTTPS entry URL. The report must bind the same requested URL and its actual browser origin; credentials, query strings, and fragments are refused. | | `--allowed-host` | Additional exact hostname allowed during hosted execution. Repeatable; the target hostname is included automatically. | +| `--signing-key-id` | Cloud-trusted Ed25519 key ID for the v3 attestation. | +| `--signing-runner-id` | Exact Cloud-trusted runner ID bound to the key. | +| `--signing-private-key-file` | Local raw or canonical-base64 32-byte Ed25519 private key file. | +| `--legacy-hmac-v2` | Emit HMAC-only v2 during a bounded migration. Do not use it for new trust. | | `--compiler-config` | Optional JSON object; its digest must match compiler provenance already sealed in the bundle. | | `--out` | Attestation JSON path. | | `--destination-kind`, `--trusted-host` | Destination policy for managed or exact-allowlisted customer endpoints. | -| `--host`, `--token` | Override the configured control plane and token used for the challenge and HMAC. | +| `--host`, `--token` | Override the configured control plane and token used for the challenge and separate ingest MAC. | The attestation binds the exact recording and bundle archive hashes, compiler identity/configuration, parameter schema, target/host execution boundary, lint/certification evidence, replay report, validation environment, policy, risk class, and challenge. The client also verifies the run report's workflow, bundle digest, source-recording provenance, parameter schema, and actual browser -origin. Cloud verifies its configured exact policy, risk-class, and deployed -compiler-version allowlists, and consumes the organization/token-bound challenge -once when the bundle is accepted. - -This is operator self-attestation, not an independent test or certification. The -ingest-token HMAC proves possession and detects mutation; it does not prove that -Cloud or an auditor observed the local replay. `certify` only evaluates the -selected policy. For independent certification, use independent evidence custody -and a separately controlled signer. +origin. Cloud verifies the organization-bound runner signature, its configured +exact policy, risk-class, and deployed compiler-version allowlists, and consumes +the organization/token-bound challenge once when the bundle is accepted. It +rechecks current signer trust and the deployment allowlists before dispatch. + +This is operator self-attestation, not an independent test or certification. +The Ed25519 signature binds the trusted runner. The separate ingest-token MAC +binds the one-time submission. Neither proves that Cloud or an auditor observed +the local replay. `certify` only evaluates the selected policy. For independent +certification, use independent evidence custody and a separately controlled +evaluator. ## push diff --git a/docs/reference/compatibility.md b/docs/reference/compatibility.md index 6000337..1660f0e 100644 --- a/docs/reference/compatibility.md +++ b/docs/reference/compatibility.md @@ -19,8 +19,10 @@ not a separate product onboarding path. | `openadapt` 1.x | `openadapt-flow >=1.7,<2` | Public installer and `openadapt flow …` CLI | | `openadapt-flow` 1.x + native capture | `openadapt-capture >=1.1.0` | Canonical native demonstration recording for Windows, macOS, Linux, RDP, and Citrix | | Windows action-time UIA handoff | `openadapt-flow >=1.22,<2` + `openadapt-capture >=1.1.0` | Retains the nearest actionable UIA node for native Windows compilation; RDP and Citrix remain externally black-box | +| Hosted attended decisions from Desktop | `openadapt-desktop >=0.15,<0.16` + `openadapt-flow >=1.26,<2` + `openadapt-types >=0.7,<0.8` | Sends a closed halt context through outbound HTTPS so an authenticated operator can answer from a phone; the customer-controlled runner revalidates the live application before action | +| Runtime-validation v3 | `openadapt-flow >=1.26,<2` | Signs the exact qualification envelope with an organization-trusted Ed25519 runner key and binds its one-time ingest with a separate token MAC | | `openadapt-flow` 1.x + privacy extra | `openadapt-privacy[presidio] >=1.0` | Configured local scrub/redaction paths | -| `openadapt-flow` interoperability extra | `openadapt-types >=0.2,<0.4` | Contributor-facing schema boundary | +| `openadapt-flow` interoperability extra | `openadapt-types >=0.7,<0.8` | Contributor-facing schema boundary; Desktop 0.15 pins Types 0.7.0 for the runner-capability and attended-decision contracts | | Python | 3.10-3.12 | Supported runtime range for the current 1.x line | The package metadata is the executable source of truth for these ranges. CI diff --git a/docs/reference/configuration.md b/docs/reference/configuration.md index 4e0bfa2..72f61de 100644 --- a/docs/reference/configuration.md +++ b/docs/reference/configuration.md @@ -142,6 +142,10 @@ forward, no certificate, no reverse proxy, no static address — so a phone reaches the queue from anywhere. Turn it on in the deployment configuration, bound to the exact tenant and runner the control plane issued for this machine: +This Desktop-managed path requires OpenAdapt Desktop 0.15 or newer and +`openadapt-flow` 1.26 or newer. Desktop checks the exact registered runner and +the Flow version before it starts the attended console. + ```yaml human_decisions: remote: