Skip to content

Releases

openadapt-verify 0.2.0

Choose a tag to compare

@openadapt-release openadapt-release released this 14 Nov 04:00
Immutable release. Only release title and notes can be modified.
420ccf2

Install without the vision stack

  • Depend on openadapt-flow[receipts]>=3.0.0,<4. Flow 3's base install has
    no vision, OCR, browser or GUI stack, so pip install openadapt-verify
    installs 21 distributions and 41 MB of site-packages instead of 33 and
    302 MB (uv install, Python 3.12, macOS arm64; 67 MB instead of 348 MB with
    pip, which also writes bytecode). The direct Pillow requirement is gone.
  • Support Python 3.10, 3.11 and 3.12. The 3.11 floor came from the Pillow
    advisory, and Pillow is no longer installed.
  • tests/test_import_boundary.py runs every verify module, the quickstart and
    both plain-Python helpers in an interpreter that refuses NumPy, OpenCV,
    Pillow, RapidOCR, ONNX Runtime, Playwright, Torch and the GUI modules.

Features

  • openadapt-verify audit: run your own automation through an HTTP fault
    proxy and count the wrong saves its success check reports as success
    (no_persist, rejected, partial, wrong_value, duplicate,
    extra_write, lost_response, and wrong_record when given a field),
    judged by the contract's independent read path. The fault goes to the
    first write whose body carries a declared value, or that matches
    --write-path. Prints a table and writes a
    JSON report. --demo audits two bundled scripts against a synthetic store.
  • openadapt-verify quickstart: three scripted agent writes (correct, wrong
    value, claimed but not saved) against REST, SQLite and FHIR R4, and
    PostgreSQL and MySQL when given a disposable database. Each gets
    CONFIRMED, REFUTED or UNCERTAIN with a checked signed receipt.
  • @verified(contract): Flow's WriteGuard as a decorator for sync and async
    functions.
  • checked_write(contract, values): the canonical begin_write and
    verify_write pair as a context manager, with a portable write receipt.
  • mysql extra (PyMySQL, MIT). No PostgreSQL extra: its read-only-capable
    drivers are LGPL-3.0.

The verifier, ledger, journal, charset guards and receipt code are Flow's;
this package adds no check of its own.

OpenAdapt Desktop 0.30.1

Choose a tag to compare

@openadapt-release openadapt-release released this 14 Nov 03:26
Immutable release. Only release title and notes can be modified.
9fde2cd

OpenAdapt Desktop 0.30.1: the PyPI package and the native installers.

Signing in this release

  • macOS: ad-hoc signed, not notarized. macOS asks you to confirm the first time you open it (System Settings > Privacy & Security).
  • Windows: unsigned. SmartScreen warns before install; choose More info > Run anyway.
  • Linux: no package signature; the GitHub attestation covers the exact DEB and AppImage bytes.

Verify any download against SHA256SUMS and its GitHub attestation with verify-openadapt-native-release.py, using this release's openadapt-desktop-channel.json.

Native Release Candidates

OpenAdapt Desktop native packages are unadmitted candidates for the
installed authoring, teaching, and local-pairing companion. They bundle and start the
Python sidecar, connect the Tauri/React cockpit to it over local JSON-lines IPC,
and register the openadapt:// operating-system handler. The handler accepts
only the fixed openadapt://connect action and forwards it to the sidecar's
strict, transactional pairing flow.

The canonical compiler and governed runtime remain in openadapt-flow. Each
native installer freezes the exact openadapt-flow[browser,console]==2.4.1
runtime and its playwright==1.61.0 browser automation dependency into the
Desktop sidecar. The console extra is what lets an installed application
serve the attended decision console the mobile decision portal relays; the
browser extra carries the frozen Playwright driver.
Compile, replay, run, and teach therefore work without a separate Python,
openadapt-flow, or playwright installation on PATH. Desktop starts with no
browser download. The first browser workflow downloads the Chromium revision
pinned by the bundled Playwright runtime unless an approved browser cache is
pre-provisioned; native desktop, RDP, and Citrix workflows never enter that
setup path.

The mobile decision portal shows the current phone
interface, one-use pairing flow, local evidence boundary, hosted outbound lane,
runner revalidation, and typed result contract.

Desktop keeps separately licensed media and vision components outside its MIT
installer. On first use, it downloads the exact release-reviewed component for
the current platform, verifies the pinned URL, byte count, and SHA-256, installs
it into a versioned local cache, and re-verifies every extracted file before
loading it. This applies to the managed FFmpeg 8.1.2 runtime used for capture
encoding and the RapidOCR 1.4.4/OpenCV 5.0.0.93 runtime used for visual
resolution. A partial or drifted download is never activated; rerunning the
operation retries it. Enterprise images can pre-provision the same exact cache
without changing the runtime contract. Developer ID builds carry the narrow
macOS library-validation entitlement required to load that independently
signed, hash-verified OpenCV extension; the manifest and full-file cache audit
remain the admission boundary.

Each Desktop version is one immutable openadapt-desktop-vX.Y.Z release in the
OpenAdapt monorepo. It carries the Python wheel and sdist (the same bytes as on
PyPI), these native installers, and the release's own attested channel. The
native version comes from package.json, src-tauri/Cargo.toml, and
src-tauri/tauri.conf.json, with matching entries in both lockfiles; a Desktop
release pull request sets them and the Python version together
(scripts/prepare_release.py). When it merges, the Desktop release workflow
builds and smoke-tests every package, attests the exact bytes, attaches
everything to a draft, publishes the wheel and sdist to PyPI, and publishes the
draft once. If any build fails, nothing is published. OpenAdapt's releases are
immutable, so a published release is never edited; a newer release supersedes
an older one by version. This transaction doesn't change the admission-driven
Production channel. The release policy is in
RELEASES.md.

Artifact labels

Every new filename includes Candidate, the native version, operating system,
architecture, and signing state. The matrix and the signing each platform can
carry:

Platform Architectures Packages Signing labels
macOS Apple Silicon (arm64), Intel (x86_64) DMG adhoc today; developer-id-notarized once credentials exist
Windows x86_64 MSI and NSIS setup executable unsigned, or authenticode once the SignPath policy is release-signing
Linux x86_64 DEB and AppImage github-attested exact bytes

The "Signing in this release" section above states which labels this release
uses. With Authenticode, SignPath signs the MSI and every program file in it,
and the NSIS setup itself; the files the NSIS setup installs are not signed. The build workflow installs
and uninstalls every package on clean hosted runners and verifies the
executable architecture and the declared signing policy: the exact Developer ID
authority and Team ID on macOS when used, and a valid signer and timestamp on
each Windows installer when signed. The workflow launches every installed
application and requires the process to survive a 20-second startup window
(catching launch panics before they ship), and stages the exact tested bytes.
The repository test matrix also checks that only the openadapt scheme is
registered and that its handoff is fixed to connect_uri without a shell or
general navigation escape hatch. These checks do not replace qualification of
a complete real workflow.

Integrity and provenance

Release jobs stage the exact post-signing, smoke-tested files and scan that
assembled installer set with Syft to publish a machine-readable CycloneDX JSON
software bill of materials (SBOM). The workflow refuses an empty or malformed
SBOM, includes it and the public build-provenance identity in the sorted
SHA256SUMS manifest, verifies the exact inventory, and creates a GitHub
artifact attestation over every named file. It also attests SHA256SUMS itself.
The release verifier requires the signed subjects to equal that inventory. It
binds the exact reviewed-main workflow, source commit, published engine tag and
release, run ID, run attempt, and GitHub-hosted runner. Consumers must
authenticate SHA256SUMS before they trust its digests:

gh attestation verify SHA256SUMS \
  --repo OpenAdaptAI/OpenAdapt \
  --cert-identity "https://github.com/OpenAdaptAI/OpenAdapt/.github/workflows/desktop-release.yml@refs/heads/main" \
  --cert-oidc-issuer "https://token.actions.githubusercontent.com" \
  --deny-self-hosted-runners
sha256sum -c SHA256SUMS
python verify-openadapt-native-release.py --directory . --manifest SHA256SUMS

The final helper refuses missing, extra, linked, non-regular, duplicate, or
digest-mismatched files. Each release also carries its own attested
openadapt-desktop-channel.json. It binds this release's SHA256SUMS and
provenance by hash, states every platform's signing mode, and names the
previous release's channel by hash. Pass it with --channel (and the last
channel you accepted with --previous-channel) to authenticate the whole chain
before trusting any digest. A download service must select the newest valid
openadapt-desktop-v* release this way, never from mutable release-note text.
After a native release succeeds, its channel is the authority for that version.

An attestation binds bytes to a build identity; it does not establish that the
software is secure or functionally complete.

Signing credentials

The protected native-release environment of OpenAdaptAI/OpenAdapt holds the
signing credentials. Every set is complete-or-absent: a partial set fails the
build, and an absent set ships the platform's unsigned label instead.

  • Windows Authenticode through SignPath (free for open source projects through
    the SignPath Foundation): SIGNPATH_API_TOKEN, SIGNPATH_ORGANIZATION_ID,
    SIGNPATH_PROJECT_SLUG (OpenAdapt), and
    SIGNPATH_SIGNING_POLICY_SLUG (release-signing). The pipeline policy is in
    .signpath/policies/OpenAdapt/release-signing.yml at the monorepo
    root.
  • macOS Developer ID and notarization, if it is ever configured:
    APPLE_CERTIFICATE, APPLE_CERTIFICATE_PASSWORD, APPLE_SIGNING_IDENTITY,
    APPLE_ID, APPLE_PASSWORD, and APPLE_TEAM_ID. Until then macOS builds are
    ad-hoc signed.
  • Linux uses the GitHub OIDC exact-byte attestation above. It has no secret and
    is not described as native-signed.

The updater stays disabled until its independent public/private signing-key
lifecycle and recovery procedure are established.

The signing runbook lists the secrets to add and the claims each public surface
can make. See CODE_SIGNING.md.

openadapt-flow 3.0.0

Choose a tag to compare

@openadapt-release openadapt-release released this 13 Nov 17:18
Immutable release. Only release title and notes can be modified.
7962352

Breaking: the vision stack is the vision extra (3.0.0)

  • pip install openadapt-flow no longer installs NumPy, OpenCV, Pillow or
    RapidOCR. They are the new vision extra. The base install is the
    record-check verifier, write ledger, protected journal, SQL, REST and FHIR
    read paths and receipt signing: 17 distributions and 40 MB of site-packages
    instead of 29 and 301 MB (uv install, Python 3.12, macOS arm64).
    openadapt-verify depends on this base install.

  • The recording and replay extras (browser, capture, windows, macos,
    linux, rdp, native-ocr, local-grounding, openenv) include
    vision, so pip install 'openadapt-flow[browser]' installs what it did in
    2.x. To record, compile or replay with none of those, install
    openadapt-flow[vision]. Without it, those commands print that install
    command and exit 2.

  • On the base install, openadapt-flow --help, openadapt-flow receipt verify
    and openadapt-flow verify-run work. The perturbation harness, the repair
    campaigns and compile_recording load Pillow and NumPy on first use instead
    of when the CLI builds its parser. The flow-base CI smoke runs those
    commands' help on the base install.

  • The on-prem release installs openadapt-flow[privacy,vision].

  • RemoteFrameContract imports Pillow only when it hashes a frame, so loading
    a deployment config no longer needs it.
    tests/test_verifier_import_boundary.py refuses the vision modules and
    checks that the verifier path imports and signs a receipt without them.

  • No verifier, ledger, journal or guard code changed. Fail-closed behavior is
    unchanged.

  • SQL effect readback now requires opaque SQLite and PostgreSQL adapters to
    declare sql_dialect. Native drivers are still recognized automatically.

  • Keep deferred typing, scrolling and click gestures tied to their emitting
    document. A known document change preserves both actions; uncertain ownership
    or a mixed-document batch refuses publication.

openadapt-flow 2.7.1

Choose a tag to compare

@openadapt-release openadapt-release released this 10 Nov 03:56
Immutable release. Only release title and notes can be modified.
e7a0aff

Flow 2.7.1 fixes loading of programs certified before Nov 8. Two optional
workflow fields added since then changed their certification digest, so they
failed to load. They now load under the reviewed sealed-omission rule, while a
program whose content changed is still refused. The release also makes write
ledger settlement atomic and extends zero-config verifier generation.

Upgrade notes

  • A custom LedgerBackend must provide transaction(key), an exclusive journal transaction shared by events() and append(); a backend without it refuses ledger mutations. A held write is released only by a person: settle_s no longer releases it, and halted_before_effect is now REFUTED with retry_safe=False. See Verifier API.
  • scaffold-verifier --prove no longer accepts the built-in mockmed and effect-e2e fixtures. It runs only against a proof source the caller passes to main(record_check_proof_source=...).

Fixes

  • Programs certified before the Anchor.form_identity and TokenTemplate.bearing fields were added load again. When the current workflow-contract digest does not match, the loader tries the older form, leaving out only fields on the reviewed sealed-omission list for the bundle's format version that are unset and None, and accepts it only if it reproduces the bound digest exactly. A program whose content changed is still refused.
  • Ledger settlements record the journal revision they observed, so a stale or concurrent observation cannot release a hold, grant a retry, complete a recheck or hand back an older result. Rechecks are bound to the original receipt and the exact set of validated later receipts.

Changed

  • scaffold-verifier closes three gaps the zero-config benchmark found. A generated REST read now carries records_complete: true when --complete-read declares it or one unpaged response was seen to hold the whole collection; otherwise it stays incomplete and verify-run returns INDETERMINATE. A step counts as a write when the capture shows the page sending a POST, PUT, PATCH or DELETE to its own origin, or its store snapshots differ, not only when its label looks like Save. --probe-reads (with optional --probe-base) finds a read for an app that never reads the saved record back: it probes the collection and item reads the write implies with GET on the local machine, uses one only when it returns the written values and nothing outside it could change unseen (otherwise it refuses and writes the TODO draft), and records every probe (read_discovery in the proof, or read_discovery.json when none confirms).

v1.21.0

Choose a tag to compare

@openadapt-release openadapt-release released this 09 Nov 21:05
Immutable release. Only release title and notes can be modified.
ae0b5ce

Requirements

  • Require openadapt-flow>=2.7.0,<3.0.0 in the base install and every Flow
    extra. openadapt doctor and openadapt deploy report older Flow releases
    as unsupported. Flow 2.7 supplies the wrap command and the --demo-app
    replay option shown in the launcher's help.

Upgrade notes

  • The launcher rejects abbreviated long options. Spell each option in full.
  • Replay no longer serves the bundled demo app unless asked: pass --url, a
    backend.url in --config, or --demo-app.

Features

  • openadapt wrap runs one operator-configured agent task. The first call
    runs the agent, checks the saved record and compiles the run; later calls
    replay the checked program with new inputs and no model calls.
    openadapt wrap --serve offers the task as a local stdio MCP tool, and
    openadapt wrap --help lists every option.
  • openadapt record, openadapt compile and openadapt run forward to the
    matching Flow commands. Run summaries show the result, the next step and
    where the report is.
  • openadapt --help groups commands into the same 15 tasks as Flow. Earlier
    command names still work.
  • openadapt doctor checks macOS Accessibility and Screen Recording access.
    --recording also checks Capture and FFmpeg for a native backend, and
    --install-browser downloads Playwright's matching Chromium.

openadapt-flow 2.7.0

Choose a tag to compare

@openadapt-release openadapt-release released this 09 Nov 19:09
Immutable release. Only release title and notes can be modified.
960b8ce

Flow adds openadapt wrap, which turns one agent task into a compiled program
that replays with new inputs and no model calls. It also teaches writes in the
browser and on desktop apps under a signed authorization, and checks more of
what a write changed. Verification still refuses a write when the record or its
outcome cannot be established.

Upgrade notes

  • No command falls back to the demo app on its own. replay needs a target:
    --url, backend.url in --config, or --demo-app to serve the bundled
    MockMed (the tutorial and quickstart commands pass it; --drift needs it).
    --demo-app with an attached browser is refused. The variant router's
    first-screen probe captures nothing without a URL. qualify accept's break-it
    check no longer runs every workflow's oracle against MockMed: it builds the
    lie from the workflow itself (a store that did not change, and a screen
    showing the workflow's own success text and every value the run typed). The
    reference Execute worker refuses, before running anything, an admission whose
    target_url it cannot drive.
  • Every command-line parser rejects abbreviated long options. Spell each
    option in full: run --permission no longer selects --permission-trust.
  • Paged REST and FHIR reads must declare an immutable-snapshot contract and
    completeness. A read that does not declare records_complete (or that
    returns a missing or changing snapshot token, duplicate identities or mixed
    identity domains) is indeterminate, not confirmed.
  • FHIR reads refuse query parameters in configured searches, requests,
    effective URLs and self links, because a capped or filtered result cannot
    establish a complete read-back. A collection bundle is accepted only with a
    total equal to its entry count. Standard searchset paging is unchanged.
  • A workflow recorded with locale, date-order and keyboard-layout facts refuses
    replay on a computer whose facts differ or cannot be read. Workflows recorded
    before this release carry no such binding and are not checked.
  • Identity bands are stricter. A recorded token that carries a digit (an id,
    date, age or count) must match the live band raw, label and hint words no
    longer count toward coverage, and a band with no identity-bearing token
    abstains. Some same-name rows that verified before now refuse.
  • SQLite rows are hashed with each cell's storage class, so a value that
    changes from integer to text (or similar) changes the row hash. A connection
    with type converters is refused.
  • All database watch routes in one shadow configuration must share the same
    frame.database settings.

Features

  • openadapt wrap (and python -m openadapt_flow.wrap.cli) runs one
    operator-configured, parameterized task. The first call for a task runs the
    agent once, checks the saved record independently, compiles the run and
    admits it; later calls replay the admitted program with new inputs and no
    model calls. --serve exposes the task as a local stdio MCP tool whose input
    schema is exactly the task's declared parameters. A request ID makes a
    repeated or interrupted call return the original run instead of sending the
    write again. A failed or uncertain replay is held until a person approves a
    repair through the normal signed admission and canaries. Model spend and run
    time are capped before each model call (--max-cost-usd,
    --max-run-seconds), and the run reports its usage.
  • The model never sees the task's own identity or inputs. Where a listing or
    screenshot shows a value bound to the task (a declared on_screen identity
    string or a task input), it is sent as a typed placeholder such as
    ⟦task.identity_1⟧ or ⟦task.note⟧: in text, and as a labelled box in the
    redacted screenshot. Before, the scrubber redacted the task's own patient name
    and MRN, and Claude stopped at read-back because it could not tell the task's
    row from any other. Unbound personal data is still redacted generically. The
    agent may type a placeholder; the harness types the value. The save gate and
    the read-back still check the real values locally.
  • openadapt wrap takes --max-input-bytes. Claude's default ceiling on one
    rendered request is now 4 MiB (was 64 KiB, which ended every
    screenshot-per-turn run on turn 2); OpenAI keeps 64 KiB. No setting may exceed
    32 MiB, and a request above the setting is still never sent.
  • Commands are grouped into 15 tasks in openadapt-flow --help (for example
    setup teach-authorization, verify shadow). Every earlier command name
    still works as an alias.
  • Browser teach writes: an agent can teach a save in the browser under a
    person-signed teach authorization (openadapt.teach-authorization/v1). The
    authorization names the task, inputs, origins, permitted writes and forbidden
    actions; run 1 starts only when it verifies and covers the write, and every
    click, key and select is checked against it. openadapt-flow teach-authorization create, sign and verify manage authorizations.
  • An agent can teach a save on a desktop or remote app over MCP, get it
    admitted, and call the taught tool. Teach authorizations accept desktop and
    remote surface origins, and a desktop teach scope is bound to the app the
    person taught.
  • Native authoring trees: authoring_tree() on the Windows (UI Automation),
    macOS (Accessibility) and Linux (AT-SPI) backends lists each control by its
    element identity. compile-agent --config and serve-execute --config run
    desktop and remote apps from the deployment's backend section.
  • Verifier audit: python -m openadapt_flow.verifier_audit run --target module:factory --out DIR tests an environment's own scorer rather than an
    agent. It replays a reference trajectory with mechanical faults (an
    unauthorized side effect, the wrong record, a wrong value, a duplicate write,
    a partial write, a write after the success claim, a claim with no write) plus
    an incidental-change positive control. It reads the end state independently
    and reports, per family, where the scorer accepted a wrong end state or
    rejected a legitimate one, with counterexamples and Wilson 95% intervals.
    Adapters for AgentDojo and AppWorld ship as examples; private family sets
    plug in with --families-module. Design: docs/VERIFIER_AUDIT.md.
  • Database shadow mode watches clients that write directly to a database. The
    agent announces each action (/begin, /end); Flow checks the action's
    database contract and watches for changes between actions. A change no action
    covers is REFUTED when the app's audit names the agent's user and
    UNCERTAIN otherwise. --guard refuses actions that cannot be checked or
    that follow an unconfirmed result.
  • Writes stay provisional while a history recheck is owed. The recheck reads
    retained versions and deletions, refuses incomplete history, and needs
    server-controlled provenance to attribute another actor's edit.
  • Reusable subroutines: a typed signature plus a program body, identified by
    digest and kept in a versioned library. Certification registers each
    workflow's uses, and every run re-admits embedded subroutines against the
    current library (--subroutine-library), so publishing a new version sends
    older users back to qualification.
  • A small, safe expression language computes parameters between steps and
    evaluates generated effect predicates. It has its own parser and type
    checker (no eval), a closed standard library and hard bounds; anything
    outside it refuses. See docs/EXPRESSIONS.md.
  • API steps cover multipart saves, the clicked submit button's name=value,
    and saves sent by page scripts.
  • A new built-in certification policy, record-write, asks for the same
    evidence as clinical-write for any non-clinical system of record. Select it
    with campaign.policy: record-write or --policy record-write.
  • Setup learns how a selected record reader corresponds to database rows and
    columns (learn_frame_identities), and drafts REST read setups from explicit
    API paging, total, snapshot and equality semantics. Missing or ambiguous
    correspondences refuse setup.
  • verifier.session works for FHIR and GraphQL read-backs, renewed for each
    qualification trial.
  • Taught-tool parameters can declare the intake field they come from. A run is
    refused when a value disagrees with an operator-registered intake grant bound
    to the source document and the exact bundle that runs.
  • Regulated approvals can require a named-person binding (WebAuthn passkey,
    OIDC or SAML evidence), carried in the Seal as digests only.
  • The local console authorizes each request against a deployment-resolved
    identity with reader, operator and administrator permissions.
  • Explicit retention removes finalized sealed runs after a signed policy
    interval (dry run by default), and sealed-set data keys can be rewrapped
    without re-encrypting payloads. OPENADAPT_FLOW_AT_REST=strict encrypts
    every run directory and refuses what it cannot encrypt.
  • Recorded native single-select choices replay by their exact option value.
  • Flow ingests evidence from an optional Manifest V3 Chrome extension: open
    shadow-DOM target paths, cross-origin iframe context and redacted network
    saves, with secrets withheld before they leave the page.
  • Trusted before_capture(backend) preparation runs on the recording's own
    backend before the first capture; publication waits for cleanup.
  • A modal dialog target's identity band is read on the dialog alone, so
    confirm steps in dialogs (such as a duplicate-record prompt) can arm
    identity.

Fixes

  • The scrubber no longer rewrites a listing's element refs: [e3] button "Open"
    came back as [<US_DRIVER_LICENSE>] button "Open". Only page text is
    scrubbed, cell by cell; ref tokens never reach the scrubber.
  • openadapt wrap on a held task reports CACHE_HALTED with the halt reason
    and exits 1. It used to treat the hold as a cache miss and exi...
Read more

OpenAdapt Desktop 0.28.1

Choose a tag to compare

@openadapt-release openadapt-release released this 08 Nov 08:29
Immutable release. Only release title and notes can be modified.
4079995

OpenAdapt Desktop 0.28.1: the PyPI package and the native installers.

Signing in this release

  • macOS: ad-hoc signed, not notarized. macOS asks you to confirm the first time you open it (System Settings > Privacy & Security).
  • Windows: unsigned. SmartScreen warns before install; choose More info > Run anyway.
  • Linux: no package signature; the GitHub attestation covers the exact DEB and AppImage bytes.

Verify any download against SHA256SUMS and its GitHub attestation with verify-openadapt-native-release.py, using this release's openadapt-desktop-channel.json.

Native Release Candidates

OpenAdapt Desktop native packages are unadmitted candidates for the
installed authoring, teaching, and local-pairing companion. They bundle and start the
Python sidecar, connect the Tauri/React cockpit to it over local JSON-lines IPC,
and register the openadapt:// operating-system handler. The handler accepts
only the fixed openadapt://connect action and forwards it to the sidecar's
strict, transactional pairing flow.

The canonical compiler and governed runtime remain in openadapt-flow. Each
native installer freezes the exact openadapt-flow[browser,console]==2.4.1
runtime and its playwright==1.61.0 browser automation dependency into the
Desktop sidecar. The console extra is what lets an installed application
serve the attended decision console the mobile decision portal relays; the
browser extra carries the frozen Playwright driver.
Compile, replay, run, and teach therefore work without a separate Python,
openadapt-flow, or playwright installation on PATH. Desktop starts with no
browser download. The first browser workflow downloads the Chromium revision
pinned by the bundled Playwright runtime unless an approved browser cache is
pre-provisioned; native desktop, RDP, and Citrix workflows never enter that
setup path.

The mobile decision portal shows the current phone
interface, one-use pairing flow, local evidence boundary, hosted outbound lane,
runner revalidation, and typed result contract.

Desktop keeps separately licensed media and vision components outside its MIT
installer. On first use, it downloads the exact release-reviewed component for
the current platform, verifies the pinned URL, byte count, and SHA-256, installs
it into a versioned local cache, and re-verifies every extracted file before
loading it. This applies to the managed FFmpeg 8.1.2 runtime used for capture
encoding and the RapidOCR 1.4.4/OpenCV 5.0.0.93 runtime used for visual
resolution. A partial or drifted download is never activated; rerunning the
operation retries it. Enterprise images can pre-provision the same exact cache
without changing the runtime contract. Developer ID builds carry the narrow
macOS library-validation entitlement required to load that independently
signed, hash-verified OpenCV extension; the manifest and full-file cache audit
remain the admission boundary.

Each Desktop version is one immutable openadapt-desktop-vX.Y.Z release in the
OpenAdapt monorepo. It carries the Python wheel and sdist (the same bytes as on
PyPI), these native installers, and the release's own attested channel. The
native version comes from package.json, src-tauri/Cargo.toml, and
src-tauri/tauri.conf.json, with matching entries in both lockfiles; a Desktop
release pull request sets them and the Python version together
(scripts/prepare_release.py). When it merges, the Desktop release workflow
builds and smoke-tests every package, attests the exact bytes, attaches
everything to a draft, publishes the wheel and sdist to PyPI, and publishes the
draft once. If any build fails, nothing is published. OpenAdapt's releases are
immutable, so a published release is never edited; a newer release supersedes
an older one by version. This transaction doesn't change the admission-driven
Production channel. The release policy is in
RELEASES.md.

Artifact labels

Every new filename includes Candidate, the native version, operating system,
architecture, and signing state. The matrix and the signing each platform can
carry:

Platform Architectures Packages Signing labels
macOS Apple Silicon (arm64), Intel (x86_64) DMG adhoc today; developer-id-notarized once credentials exist
Windows x86_64 MSI and NSIS setup executable unsigned, or authenticode once the SignPath policy is release-signing
Linux x86_64 DEB and AppImage github-attested exact bytes

The "Signing in this release" section above states which labels this release
uses. With Authenticode, SignPath signs the MSI and every program file in it,
and the NSIS setup itself; the files the NSIS setup installs are not signed. The build workflow installs
and uninstalls every package on clean hosted runners and verifies the
executable architecture and the declared signing policy: the exact Developer ID
authority and Team ID on macOS when used, and a valid signer and timestamp on
each Windows installer when signed. The workflow launches every installed
application and requires the process to survive a 20-second startup window
(catching launch panics before they ship), and stages the exact tested bytes.
The repository test matrix also checks that only the openadapt scheme is
registered and that its handoff is fixed to connect_uri without a shell or
general navigation escape hatch. These checks do not replace qualification of
a complete real workflow.

Integrity and provenance

Release jobs stage the exact post-signing, smoke-tested files and scan that
assembled installer set with Syft to publish a machine-readable CycloneDX JSON
software bill of materials (SBOM). The workflow refuses an empty or malformed
SBOM, includes it and the public build-provenance identity in the sorted
SHA256SUMS manifest, verifies the exact inventory, and creates a GitHub
artifact attestation over every named file. It also attests SHA256SUMS itself.
The release verifier requires the signed subjects to equal that inventory. It
binds the exact reviewed-main workflow, source commit, published engine tag and
release, run ID, run attempt, and GitHub-hosted runner. Consumers must
authenticate SHA256SUMS before they trust its digests:

gh attestation verify SHA256SUMS \
  --repo OpenAdaptAI/OpenAdapt \
  --cert-identity "https://github.com/OpenAdaptAI/OpenAdapt/.github/workflows/desktop-release.yml@refs/heads/main" \
  --cert-oidc-issuer "https://token.actions.githubusercontent.com" \
  --deny-self-hosted-runners
sha256sum -c SHA256SUMS
python verify-openadapt-native-release.py --directory . --manifest SHA256SUMS

The final helper refuses missing, extra, linked, non-regular, duplicate, or
digest-mismatched files. Each release also carries its own attested
openadapt-desktop-channel.json. It binds this release's SHA256SUMS and
provenance by hash, states every platform's signing mode, and names the
previous release's channel by hash. Pass it with --channel (and the last
channel you accepted with --previous-channel) to authenticate the whole chain
before trusting any digest. A download service must select the newest valid
openadapt-desktop-v* release this way, never from mutable release-note text.
After a native release succeeds, its channel is the authority for that version.

An attestation binds bytes to a build identity; it does not establish that the
software is secure or functionally complete.

Signing credentials

The protected native-release environment of OpenAdaptAI/OpenAdapt holds the
signing credentials. Every set is complete-or-absent: a partial set fails the
build, and an absent set ships the platform's unsigned label instead.

  • Windows Authenticode through SignPath (free for open source projects through
    the SignPath Foundation): SIGNPATH_API_TOKEN, SIGNPATH_ORGANIZATION_ID,
    SIGNPATH_PROJECT_SLUG (OpenAdapt), and
    SIGNPATH_SIGNING_POLICY_SLUG (release-signing). The pipeline policy is in
    .signpath/policies/OpenAdapt/release-signing.yml at the monorepo
    root.
  • macOS Developer ID and notarization, if it is ever configured:
    APPLE_CERTIFICATE, APPLE_CERTIFICATE_PASSWORD, APPLE_SIGNING_IDENTITY,
    APPLE_ID, APPLE_PASSWORD, and APPLE_TEAM_ID. Until then macOS builds are
    ad-hoc signed.
  • Linux uses the GitHub OIDC exact-byte attestation above. It has no secret and
    is not described as native-signed.

The updater stays disabled until its independent public/private signing-key
lifecycle and recovery procedure are established.

The signing runbook lists the secrets to add and the claims each public surface
can make. See CODE_SIGNING.md.

OpenAdapt Desktop 0.28.0

Choose a tag to compare

@openadapt-release openadapt-release released this 07 Nov 03:15
Immutable release. Only release title and notes can be modified.
d67eb4f

OpenAdapt Desktop 0.28.0: the PyPI package and the native installers.

Signing in this release

  • macOS: ad-hoc signed, not notarized. macOS asks you to confirm the first time you open it (System Settings > Privacy & Security).
  • Windows: unsigned. SmartScreen warns before install; choose More info > Run anyway.
  • Linux: no package signature; the GitHub attestation covers the exact DEB and AppImage bytes.

Verify any download against SHA256SUMS and its GitHub attestation with verify-openadapt-native-release.py, using this release's openadapt-desktop-channel.json.

Native Release Candidates

OpenAdapt Desktop native packages are unadmitted candidates for the
installed authoring, teaching, and local-pairing companion. They bundle and start the
Python sidecar, connect the Tauri/React cockpit to it over local JSON-lines IPC,
and register the openadapt:// operating-system handler. The handler accepts
only the fixed openadapt://connect action and forwards it to the sidecar's
strict, transactional pairing flow.

The canonical compiler and governed runtime remain in openadapt-flow. Each
native installer freezes the exact openadapt-flow[browser,console]==2.4.1
runtime and its playwright==1.61.0 browser automation dependency into the
Desktop sidecar. The console extra is what lets an installed application
serve the attended decision console the mobile decision portal relays; the
browser extra carries the frozen Playwright driver.
Compile, replay, run, and teach therefore work without a separate Python,
openadapt-flow, or playwright installation on PATH. Desktop starts with no
browser download. The first browser workflow downloads the Chromium revision
pinned by the bundled Playwright runtime unless an approved browser cache is
pre-provisioned; native desktop, RDP, and Citrix workflows never enter that
setup path.

The mobile decision portal shows the current phone
interface, one-use pairing flow, local evidence boundary, hosted outbound lane,
runner revalidation, and typed result contract.

Desktop keeps separately licensed media and vision components outside its MIT
installer. On first use, it downloads the exact release-reviewed component for
the current platform, verifies the pinned URL, byte count, and SHA-256, installs
it into a versioned local cache, and re-verifies every extracted file before
loading it. This applies to the managed FFmpeg 8.1.2 runtime used for capture
encoding and the RapidOCR 1.4.4/OpenCV 5.0.0.93 runtime used for visual
resolution. A partial or drifted download is never activated; rerunning the
operation retries it. Enterprise images can pre-provision the same exact cache
without changing the runtime contract. Developer ID builds carry the narrow
macOS library-validation entitlement required to load that independently
signed, hash-verified OpenCV extension; the manifest and full-file cache audit
remain the admission boundary.

Each Desktop version is one immutable openadapt-desktop-vX.Y.Z release in the
OpenAdapt monorepo. It carries the Python wheel and sdist (the same bytes as on
PyPI), these native installers, and the release's own attested channel. The
native version comes from package.json, src-tauri/Cargo.toml, and
src-tauri/tauri.conf.json, with matching entries in both lockfiles; a Desktop
release pull request sets them and the Python version together
(scripts/prepare_release.py). When it merges, the Desktop release workflow
builds and smoke-tests every package, attests the exact bytes, attaches
everything to a draft, publishes the wheel and sdist to PyPI, and publishes the
draft once. If any build fails, nothing is published. OpenAdapt's releases are
immutable, so a published release is never edited; a newer release supersedes
an older one by version. This transaction doesn't change the admission-driven
Production channel. The release policy is in
RELEASES.md.

Artifact labels

Every new filename includes Candidate, the native version, operating system,
architecture, and signing state. The matrix and the signing each platform can
carry:

Platform Architectures Packages Signing labels
macOS Apple Silicon (arm64), Intel (x86_64) DMG adhoc today; developer-id-notarized once credentials exist
Windows x86_64 MSI and NSIS setup executable unsigned, or authenticode once the SignPath policy is release-signing
Linux x86_64 DEB and AppImage github-attested exact bytes

The "Signing in this release" section above states which labels this release
uses. With Authenticode, SignPath signs the MSI and every program file in it,
and the NSIS setup itself; the files the NSIS setup installs are not signed. The build workflow installs
and uninstalls every package on clean hosted runners and verifies the
executable architecture and the declared signing policy: the exact Developer ID
authority and Team ID on macOS when used, and a valid signer and timestamp on
each Windows installer when signed. The workflow launches every installed
application and requires the process to survive a 20-second startup window
(catching launch panics before they ship), and stages the exact tested bytes.
The repository test matrix also checks that only the openadapt scheme is
registered and that its handoff is fixed to connect_uri without a shell or
general navigation escape hatch. These checks do not replace qualification of
a complete real workflow.

Integrity and provenance

Release jobs stage the exact post-signing, smoke-tested files and scan that
assembled installer set with Syft to publish a machine-readable CycloneDX JSON
software bill of materials (SBOM). The workflow refuses an empty or malformed
SBOM, includes it and the public build-provenance identity in the sorted
SHA256SUMS manifest, verifies the exact inventory, and creates a GitHub
artifact attestation over every named file. It also attests SHA256SUMS itself.
The release verifier requires the signed subjects to equal that inventory. It
binds the exact reviewed-main workflow, source commit, published engine tag and
release, run ID, run attempt, and GitHub-hosted runner. Consumers must
authenticate SHA256SUMS before they trust its digests:

gh attestation verify SHA256SUMS \
  --repo OpenAdaptAI/OpenAdapt \
  --cert-identity "https://github.com/OpenAdaptAI/OpenAdapt/.github/workflows/desktop-release.yml@refs/heads/main" \
  --cert-oidc-issuer "https://token.actions.githubusercontent.com" \
  --deny-self-hosted-runners
sha256sum -c SHA256SUMS
python verify-openadapt-native-release.py --directory . --manifest SHA256SUMS

The final helper refuses missing, extra, linked, non-regular, duplicate, or
digest-mismatched files. Each release also carries its own attested
openadapt-desktop-channel.json. It binds this release's SHA256SUMS and
provenance by hash, states every platform's signing mode, and names the
previous release's channel by hash. Pass it with --channel (and the last
channel you accepted with --previous-channel) to authenticate the whole chain
before trusting any digest. A download service must select the newest valid
openadapt-desktop-v* release this way, never from mutable release-note text.
After a native release succeeds, its channel is the authority for that version.

An attestation binds bytes to a build identity; it does not establish that the
software is secure or functionally complete.

Signing credentials

The protected native-release environment of OpenAdaptAI/OpenAdapt holds the
signing credentials. Every set is complete-or-absent: a partial set fails the
build, and an absent set ships the platform's unsigned label instead.

  • Windows Authenticode through SignPath (free for open source projects through
    the SignPath Foundation): SIGNPATH_API_TOKEN, SIGNPATH_ORGANIZATION_ID,
    SIGNPATH_PROJECT_SLUG (OpenAdapt), and
    SIGNPATH_SIGNING_POLICY_SLUG (release-signing). The pipeline policy is in
    .signpath/policies/OpenAdapt/release-signing.yml at the monorepo
    root.
  • macOS Developer ID and notarization, if it is ever configured:
    APPLE_CERTIFICATE, APPLE_CERTIFICATE_PASSWORD, APPLE_SIGNING_IDENTITY,
    APPLE_ID, APPLE_PASSWORD, and APPLE_TEAM_ID. Until then macOS builds are
    ad-hoc signed.
  • Linux uses the GitHub OIDC exact-byte attestation above. It has no secret and
    is not described as native-signed.

The updater stays disabled until its independent public/private signing-key
lifecycle and recovery procedure are established.

The signing runbook lists the secrets to add and the claims each public surface
can make. See CODE_SIGNING.md.

OpenAdapt Desktop 0.27.0

Choose a tag to compare

@openadapt-release openadapt-release released this 06 Nov 15:27
Immutable release. Only release title and notes can be modified.
19ac230

OpenAdapt Desktop 0.27.0: the PyPI package and the native installers.

Signing in this release

  • macOS: ad-hoc signed, not notarized. macOS asks you to confirm the first time you open it (System Settings > Privacy & Security).
  • Windows: unsigned. SmartScreen warns before install; choose More info > Run anyway.
  • Linux: no package signature; the GitHub attestation covers the exact DEB and AppImage bytes.

Verify any download against SHA256SUMS and its GitHub attestation with verify-openadapt-native-release.py, using this release's openadapt-desktop-channel.json.

Native Release Candidates

OpenAdapt Desktop native packages are unadmitted candidates for the
installed authoring, teaching, and local-pairing companion. They bundle and start the
Python sidecar, connect the Tauri/React cockpit to it over local JSON-lines IPC,
and register the openadapt:// operating-system handler. The handler accepts
only the fixed openadapt://connect action and forwards it to the sidecar's
strict, transactional pairing flow.

The canonical compiler and governed runtime remain in openadapt-flow. Each
native installer freezes the exact openadapt-flow[browser,console]==2.4.1
runtime and its playwright==1.61.0 browser automation dependency into the
Desktop sidecar. The console extra is what lets an installed application
serve the attended decision console the mobile decision portal relays; the
browser extra carries the frozen Playwright driver.
Compile, replay, run, and teach therefore work without a separate Python,
openadapt-flow, or playwright installation on PATH. Desktop starts with no
browser download. The first browser workflow downloads the Chromium revision
pinned by the bundled Playwright runtime unless an approved browser cache is
pre-provisioned; native desktop, RDP, and Citrix workflows never enter that
setup path.

The mobile decision portal shows the current phone
interface, one-use pairing flow, local evidence boundary, hosted outbound lane,
runner revalidation, and typed result contract.

Desktop keeps separately licensed media and vision components outside its MIT
installer. On first use, it downloads the exact release-reviewed component for
the current platform, verifies the pinned URL, byte count, and SHA-256, installs
it into a versioned local cache, and re-verifies every extracted file before
loading it. This applies to the managed FFmpeg 8.1.2 runtime used for capture
encoding and the RapidOCR 1.4.4/OpenCV 5.0.0.93 runtime used for visual
resolution. A partial or drifted download is never activated; rerunning the
operation retries it. Enterprise images can pre-provision the same exact cache
without changing the runtime contract. Developer ID builds carry the narrow
macOS library-validation entitlement required to load that independently
signed, hash-verified OpenCV extension; the manifest and full-file cache audit
remain the admission boundary.

Each Desktop version is one immutable openadapt-desktop-vX.Y.Z release in the
OpenAdapt monorepo. It carries the Python wheel and sdist (the same bytes as on
PyPI), these native installers, and the release's own attested channel. The
native version comes from package.json, src-tauri/Cargo.toml, and
src-tauri/tauri.conf.json, with matching entries in both lockfiles; a Desktop
release pull request sets them and the Python version together
(scripts/prepare_release.py). When it merges, the Desktop release workflow
builds and smoke-tests every package, attests the exact bytes, attaches
everything to a draft, publishes the wheel and sdist to PyPI, and publishes the
draft once. If any build fails, nothing is published. OpenAdapt's releases are
immutable, so a published release is never edited; a newer release supersedes
an older one by version. This transaction doesn't change the admission-driven
Production channel. The release policy is in
RELEASES.md.

Artifact labels

Every new filename includes Candidate, the native version, operating system,
architecture, and signing state. The matrix and the signing each platform can
carry:

Platform Architectures Packages Signing labels
macOS Apple Silicon (arm64), Intel (x86_64) DMG adhoc today; developer-id-notarized once credentials exist
Windows x86_64 MSI and NSIS setup executable unsigned, or authenticode once the SignPath policy is release-signing
Linux x86_64 DEB and AppImage github-attested exact bytes

The "Signing in this release" section above states which labels this release
uses. With Authenticode, SignPath signs the MSI and every program file in it,
and the NSIS setup itself; the files the NSIS setup installs are not signed. The build workflow installs
and uninstalls every package on clean hosted runners and verifies the
executable architecture and the declared signing policy: the exact Developer ID
authority and Team ID on macOS when used, and a valid signer and timestamp on
each Windows installer when signed. The workflow launches every installed
application and requires the process to survive a 20-second startup window
(catching launch panics before they ship), and stages the exact tested bytes.
The repository test matrix also checks that only the openadapt scheme is
registered and that its handoff is fixed to connect_uri without a shell or
general navigation escape hatch. These checks do not replace qualification of
a complete real workflow.

Integrity and provenance

Release jobs stage the exact post-signing, smoke-tested files and scan that
assembled installer set with Syft to publish a machine-readable CycloneDX JSON
software bill of materials (SBOM). The workflow refuses an empty or malformed
SBOM, includes it and the public build-provenance identity in the sorted
SHA256SUMS manifest, verifies the exact inventory, and creates a GitHub
artifact attestation over every named file. It also attests SHA256SUMS itself.
The release verifier requires the signed subjects to equal that inventory. It
binds the exact reviewed-main workflow, source commit, published engine tag and
release, run ID, run attempt, and GitHub-hosted runner. Consumers must
authenticate SHA256SUMS before they trust its digests:

gh attestation verify SHA256SUMS \
  --repo OpenAdaptAI/OpenAdapt \
  --cert-identity "https://github.com/OpenAdaptAI/OpenAdapt/.github/workflows/desktop-release.yml@refs/heads/main" \
  --cert-oidc-issuer "https://token.actions.githubusercontent.com" \
  --deny-self-hosted-runners
sha256sum -c SHA256SUMS
python verify-openadapt-native-release.py --directory . --manifest SHA256SUMS

The final helper refuses missing, extra, linked, non-regular, duplicate, or
digest-mismatched files. Each release also carries its own attested
openadapt-desktop-channel.json. It binds this release's SHA256SUMS and
provenance by hash, states every platform's signing mode, and names the
previous release's channel by hash. Pass it with --channel (and the last
channel you accepted with --previous-channel) to authenticate the whole chain
before trusting any digest. A download service must select the newest valid
openadapt-desktop-v* release this way, never from mutable release-note text.
After a native release succeeds, its channel is the authority for that version.

An attestation binds bytes to a build identity; it does not establish that the
software is secure or functionally complete.

Signing credentials

The protected native-release environment of OpenAdaptAI/OpenAdapt holds the
signing credentials. Every set is complete-or-absent: a partial set fails the
build, and an absent set ships the platform's unsigned label instead.

  • Windows Authenticode through SignPath (free for open source projects through
    the SignPath Foundation): SIGNPATH_API_TOKEN, SIGNPATH_ORGANIZATION_ID,
    SIGNPATH_PROJECT_SLUG (OpenAdapt), and
    SIGNPATH_SIGNING_POLICY_SLUG (release-signing). The pipeline policy is in
    .signpath/policies/OpenAdapt/release-signing.yml at the monorepo
    root.
  • macOS Developer ID and notarization, if it is ever configured:
    APPLE_CERTIFICATE, APPLE_CERTIFICATE_PASSWORD, APPLE_SIGNING_IDENTITY,
    APPLE_ID, APPLE_PASSWORD, and APPLE_TEAM_ID. Until then macOS builds are
    ad-hoc signed.
  • Linux uses the GitHub OIDC exact-byte attestation above. It has no secret and
    is not described as native-signed.

The updater stays disabled until its independent public/private signing-key
lifecycle and recovery procedure are established.

The signing runbook lists the secrets to add and the claims each public surface
can make. See CODE_SIGNING.md.

v1.20.0

Choose a tag to compare

@openadapt-release openadapt-release released this 05 Nov 05:01
Immutable release. Only release title and notes can be modified.
9ec50e4

Requirements

  • Require openadapt-flow>=2.6.0,<3.0.0 in the base install and every Flow
    extra. openadapt doctor and openadapt deploy report older Flow releases
    as unsupported. This supplies the persistent owed-recheck API used by
    ledger listing.

Features

  • openadapt verify ledger list shows provisional confirmed writes whose
    rechecks are still owed, with their due time and actor. Owed rechecks remain
    visible after the server restarts and disappear when the recheck completes.
    An empty ledger reports that no held writes, open writes or owed rechecks
    remain.
  • The platform manifest and compatibility report select published component
    releases, including Desktop 0.25.1.