diff --git a/packages/flow/environments/openenv/_windows/README.md b/packages/flow/environments/openenv/_windows/README.md
new file mode 100644
index 0000000000..a0c9fc5362
--- /dev/null
+++ b/packages/flow/environments/openenv/_windows/README.md
@@ -0,0 +1,108 @@
+# Windows desktop environments
+
+Four OpenEnv environments on two Windows line-of-business apps, each backed by
+a SQLite database. The reward is verify-run's verdict on that database, read
+outside the agent's session, so an agent earns reward only when the record
+shows what it reports.
+
+| Environment | App | Surface | What the agent observes |
+|---|---|---|---|
+| `win-patient-chart` | Patient Chart (WinForms) | UI Automation | Screen and the window's UI Automation elements |
+| `win-patient-chart-rdp` | Patient Chart (WinForms) | Remote Desktop | Screen pixels only |
+| `win-claims-desk` | Claims Desk (WPF) | UI Automation | Screen and the window's UI Automation elements |
+| `win-claims-desk-rdp` | Claims Desk (WPF) | Remote Desktop | Screen pixels only |
+
+The two variants of an app share one task set, so a policy's score on pixels
+alone compares directly with its score with an accessibility tree.
+
+## Tasks
+
+Each app has 24 public tasks, generated from one seed by
+[`make_tasks.py`](make_tasks.py):
+
+- 12 feasible tasks: write a chart note on a patient, or record a decision
+ (status, allowed amount, note) on a claim. In three, the first save is
+ lost while the screen says "saved"; the reference solution re-opens the
+ record, sees the count unchanged and saves again. Three show a misleading
+ banner, such as "Note saved for Nell Sorensen (MRN-104812)" or "Batch
+ posting complete: all decisions saved". Three use a reordered list.
+- 12 tasks with a planted write fault. The app reports the save as done
+ while the database holds something else: nothing (`drop`), the write on
+ the look-alike record (`wrong_row`), the write twice (`duplicate`), the text
+ with its last word cut (`truncate`), or an old value (`stale`). The correct
+ outcome is to report failure, after trying the save: a failure report pays
+ only when the app was asked to save the task's values.
+
+Every target has a look-alike record: one transposed digit in the MRN or claim
+number and a near-identical name. Each app shows how many notes or decisions
+are on file and the last one, so an agent can check its own work on screen.
+
+Task ids are opaque and tags never name the fault. `tasks/MANIFEST.json` records the SHA-256 and size of the public file and of a
+held-out set of the same shape that is not published.
+
+## Windows is yours
+
+Nothing here contains Windows. Like Windows Agent Arena, the environments run
+on a Windows machine you provide: a VM built from your own Windows image or
+evaluation ISO, or an Azure or AWS Windows template.
+
+1. Run [`provision/setup_guest.ps1`](provision/setup_guest.ps1) on it as an
+ administrator. It turns on WinRM and Remote Desktop, sets the session host
+ to prefer H.264/AVC444, installs CPython and the in-guest agent's packages,
+ and creates `C:\oa\pack`.
+2. Sign the desktop account in to its desktop.
+3. On the server, set `OPENADAPT_WINENV_HOST`, `OPENADAPT_WINENV_USER`,
+ `OPENADAPT_WINENV_PASSWORD` and `OPENADAPT_WINENV_PYTHON` (the path the
+ script printed), then serve an environment:
+
+```bash
+pip install 'openadapt-flow[openenv]' pywinrm aardwolf
+python -m openadapt_flow.rl_env.desktop environments/openenv/win-patient-chart --port 8000
+```
+
+The server copies the apps in, then resets each episode in one WinRM call:
+it stops the app, restores the database from its pristine copy, sets the
+episode's fault and banner, and starts the app. It compares the restored
+database's digest with a digest it computes from the same seed and refuses
+the episode if they differ.
+
+## Surfaces
+
+- **UI Automation**: input goes through the in-guest agent (`win_agent`) over
+ TLS with a pinned certificate. Observations carry the screenshot and the
+ window's elements (role, name, automation id, bounds), without field values.
+- **Remote Desktop**: input and frames go over an RDP session. The client is
+ FreeRDP 3 under Xvfb, asking for H.264/AVC444 (`rdp.avc444: true`), as
+ against a production session host. It needs Linux; see
+ [`rdp-client/Containerfile`](rdp-client/Containerfile). On any other host,
+ `OPENADAPT_WINENV_RDP_TRANSPORT=aardwolf` uses a pure-Python client that
+ negotiates RDP's bitmap codecs instead.
+
+Actions are `click`, `double_click`, `right_click` and `scroll` at session
+coordinates, `type`, `press` and `done` with a claim. The Windows key and the
+Ctrl+Esc and Ctrl+Shift+Esc chords are refused. The agent has no network
+action.
+
+## Results
+
+On a Windows 11 Pro x64 machine (2026-11-04), all four environments passed every check:
+- every reference solution earned 1, and every feasible task earned 0 with a write fault planted;
+- random actions earned 0, and an agent trusting the "saved" message earned exactly the feasible half;
+- no state carried between episodes.
+
+Median reset was 6.6–7.3 s on the UI Automation surface and 3.2–3.3 s over Remote Desktop with AVC444. Details and the full episode logs are in [`results/windows11-x64-2026-11-04/`](results/windows11-x64-2026-11-04/README.md).
+
+## Validate
+
+```bash
+OPENADAPT_ENV_REFERENCE=1 python -m openadapt_flow.rl_env.validate_desktop \
+ environments/openenv/win-patient-chart --out results.json
+```
+
+The run checks that every task's reference solution earns 1, that an agent
+trusting the "saved" message earns 1 only on feasible tasks, that each
+feasible task's solution earns 0 with a write fault planted, that random
+actions stay at least 0.1 below the maximum, and that no state carries from
+one episode to the next. It also records each reset's duration.
+`OPENADAPT_ENV_REFERENCE=1` lets the reference solutions name elements by
+automation id on the pixels-only surface; never set it for an agent.
diff --git a/packages/flow/environments/openenv/_windows/apps/claims_desk.ps1 b/packages/flow/environments/openenv/_windows/apps/claims_desk.ps1
new file mode 100644
index 0000000000..6e1d093593
--- /dev/null
+++ b/packages/flow/environments/openenv/_windows/apps/claims_desk.ps1
@@ -0,0 +1,203 @@
+# Claims Desk (WPF): find a claim, adjudicate it (status, allowed amount, note), save.
+#
+# A self-built line-of-business app for the Windows environment pack, the
+# WPF counterpart of patient_chart.ps1 (WinForms). Persistence goes through
+# pack_db.py (SQLite); the oracle reads the database outside the session. The
+# app never reads the planted fault and always reports the save as done.
+#
+# UI knobs come from C:\oa\pack\data\claims_desk_ui.json, written at reset:
+# banner : text in a yellow strip at the top (a misleading notice).
+# window : "maximized" (default: full screen over the taskbar) or
+# "windowed"; size "WxH" forces windowed.
+#
+# Usage: powershell -STA -ExecutionPolicy Bypass -File claims_desk.ps1
+
+param(
+ [string]$Python = "",
+ [string]$DbCli = "C:\oa\pack\pack_db.py"
+)
+
+Add-Type -AssemblyName PresentationFramework
+Add-Type -AssemblyName PresentationCore
+Add-Type -AssemblyName WindowsBase
+
+if (-not $Python) { $Python = (Get-Content "C:\oa\pack\python.txt" -Raw).Trim() }
+
+$cfg = @{ banner = ""; window = "maximized"; size = "" }
+$cfgPath = "C:\oa\pack\data\claims_desk_ui.json"
+if (Test-Path $cfgPath) {
+ try {
+ $j = Get-Content $cfgPath -Raw | ConvertFrom-Json
+ foreach ($k in @("banner", "window", "size")) {
+ if ($null -ne $j.$k) { $cfg[$k] = $j.$k }
+ }
+ } catch {}
+}
+
+function Invoke-Db {
+ param([string[]]$DbArgs)
+ $psi = New-Object System.Diagnostics.ProcessStartInfo
+ $psi.FileName = $Python
+ $psi.Arguments = (@("-I", "`"$DbCli`"") + $DbArgs) -join ' '
+ $psi.RedirectStandardOutput = $true
+ $psi.UseShellExecute = $false
+ $psi.CreateNoWindow = $true
+ $p = [System.Diagnostics.Process]::Start($psi)
+ $out = $p.StandardOutput.ReadToEnd()
+ $p.WaitForExit()
+ return $out
+}
+
+[xml]$xaml = @"
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+"@
+
+$window = [Windows.Markup.XamlReader]::Load((New-Object System.Xml.XmlNodeReader $xaml))
+$c = @{}
+foreach ($n in @("noticeBanner", "searchBox", "searchButton", "claimsGrid", "claimHeader",
+ "statusApproved", "statusDenied", "statusPended", "amountBox", "noteBox",
+ "statusText", "saveButton", "historyText")) { $c[$n] = $window.FindName($n) }
+
+if ([string]$cfg["banner"]) {
+ $c.noticeBanner.Text = [string]$cfg["banner"]
+ $c.noticeBanner.Visibility = "Visible"
+}
+# Full screen by default: no chrome and maximized, so the window covers the
+# taskbar and an agent's clicks cannot reach the Start menu or another app.
+if ([string]$cfg["window"] -ne "windowed" -and -not [string]$cfg["size"]) {
+ $window.WindowStyle = "None"
+ $window.ResizeMode = "NoResize"
+ $window.WindowState = "Maximized"
+}
+if ([string]$cfg["size"]) {
+ $wh = ([string]$cfg["size"]) -split 'x'
+ $window.Width = [int]$wh[0]; $window.Height = [int]$wh[1]
+}
+
+$script:current = $null
+
+function Clear-Detail {
+ $script:current = $null
+ $c.claimHeader.Text = ""
+ $c.historyText.Text = ""
+ foreach ($r in @("statusApproved", "statusDenied", "statusPended")) { $c[$r].IsChecked = $false }
+ $c.amountBox.Text = ""
+ $c.noteBox.Text = ""
+}
+
+function Load-Claims {
+ param([string]$Filter)
+ $json = Invoke-Db -DbArgs @("cd-list", "`"$Filter`"")
+ $rows = @()
+ if ($json.Trim().Length -gt 0) { $rows = @($json | ConvertFrom-Json) }
+ $c.claimsGrid.ItemsSource = $rows
+ $c.claimsGrid.UnselectAll()
+ Clear-Detail
+ $c.statusText.Text = "Found " + $rows.Count + " claims"
+}
+
+$c.searchButton.Add_Click({ Load-Claims -Filter $c.searchBox.Text })
+$c.searchBox.Add_KeyDown({
+ if ($_.Key -eq "Return") { Load-Claims -Filter $c.searchBox.Text; $_.Handled = $true }
+})
+
+function Open-Claim {
+ param([string]$ClaimNo)
+ $p = (Invoke-Db -DbArgs @("cd-get", "$ClaimNo")) | ConvertFrom-Json
+ if ($p) {
+ Clear-Detail
+ $script:current = $p.claim_no
+ $c.claimHeader.Text = "Claim " + $p.claim_no + " " + $p.member + " " + $p.member_id + " billed " + $p.billed + " (" + $p.status + ")"
+ if ($p.last_decision) {
+ $c.historyText.Text = "" + $p.decision_count + " decisions on file. Last: " + $p.last_decision.status + " " + $p.last_decision.allowed_amount + " - " + $p.last_decision.note
+ } else { $c.historyText.Text = "No decisions on file" }
+ }
+}
+
+$c.claimsGrid.Add_SelectionChanged({
+ $item = $c.claimsGrid.SelectedItem
+ if ($null -ne $item) { Open-Claim $item.claim_no }
+})
+
+# A click on the row that is already selected raises no SelectionChanged;
+# re-open the claim anyway, so its history and an empty form show again.
+$c.claimsGrid.Add_PreviewMouseLeftButtonUp({
+ $node = $_.OriginalSource
+ while ($null -ne $node -and -not ($node -is [System.Windows.Controls.DataGridRow])) {
+ if ($node -is [System.Windows.Media.Visual]) { $node = [System.Windows.Media.VisualTreeHelper]::GetParent($node) }
+ else { $node = $node.Parent }
+ }
+ if ($null -ne $node -and $node.IsSelected -and $null -ne $node.Item) {
+ if ($script:current -eq $node.Item.claim_no) { Open-Claim $node.Item.claim_no }
+ }
+})
+
+$c.saveButton.Add_Click({
+ if (-not $script:current) { $c.statusText.Text = "Open a claim first"; return }
+ $decision = ""
+ if ($c.statusApproved.IsChecked) { $decision = "Approved" }
+ elseif ($c.statusDenied.IsChecked) { $decision = "Denied" }
+ elseif ($c.statusPended.IsChecked) { $decision = "Pended" }
+ if (-not $decision) { $c.statusText.Text = "Choose a decision"; return }
+ $amount = $c.amountBox.Text.Trim()
+ if (-not ($amount -match '^\d+(\.\d{1,2})?$')) { $c.statusText.Text = "Allowed amount must be a number"; return }
+ $b64 = [Convert]::ToBase64String([Text.Encoding]::UTF8.GetBytes($c.noteBox.Text))
+ [void](Invoke-Db -DbArgs @("cd-save", "$($script:current)", $decision, $amount, "$b64"))
+ $c.statusText.Text = "Decision saved for $($script:current)"
+})
+
+Load-Claims -Filter ""
+[void]$window.ShowDialog()
diff --git a/packages/flow/environments/openenv/_windows/apps/pack_db.py b/packages/flow/environments/openenv/_windows/apps/pack_db.py
new file mode 100644
index 0000000000..fa18eef95a
--- /dev/null
+++ b/packages/flow/environments/openenv/_windows/apps/pack_db.py
@@ -0,0 +1,442 @@
+"""System of record for the Windows environment packs (SQLite, guest side).
+
+Two self-built line-of-business apps keep their data here: Patient Chart
+(WinForms; write a note on a patient's chart) and Claims Desk (WPF;
+adjudicate a claim). The apps read and write only through this CLI. The
+environment's oracle reads the same file through ``dump``, over a channel the
+agent never touches (WinRM from the host), so the reward comes from the
+database, never from the screen.
+
+Planted faults live in ``_fault.json`` beside the database (``data``). The apps
+never read that file and always report the save as done, so the screen says
+"saved" whatever the database holds:
+
+* ``ok``: the write lands once.
+* ``drop``: nothing is written.
+* ``drop_first``: the first save is lost, later ones land (a save that
+ silently fails once; the screen still says "saved").
+* ``wrong_row``: the write lands on the target's look-alike record.
+* ``duplicate``: the write lands twice.
+* ``truncate``: the text lands with its last word cut.
+* ``stale``: an old value is written instead of the new one (Patient Chart
+ re-saves the chart's previous note; Claims Desk writes the claim's billed
+ amount instead of the allowed amount entered).
+
+Commands (all print one line of JSON or ``OK``)::
+
+ seed [--fault F] [--variant V] restore the pristine database
+ digest sha256 over every table
+ attempts the saves the app asked for this episode
+ dump {"records": [...]} for the oracle
+ pc-list | pc-get | pc-save
+ cd-list | cd-get | cd-save
+
+Text travels base64 so quotes and unicode survive the shell. Standard library
+only: the guest has a stock CPython and nothing else.
+"""
+
+from __future__ import annotations
+
+import base64
+import hashlib
+import json
+import os
+import shutil
+import sqlite3
+import sys
+from datetime import datetime, timezone
+
+# The data directory (writable by the desktop account); the code beside it is not.
+ROOT = os.environ.get("OA_PACK_DIR", r"C:\oa\pack\data")
+APPS = ("patient_chart", "claims_desk")
+FAULTS = ("ok", "drop", "drop_first", "wrong_row", "duplicate", "truncate", "stale")
+
+# Fictional roster. Look-alike pairs differ by one transposed MRN digit and a
+# near-identical name, so a wrong click is easy to make and hard to see.
+PATIENTS = [
+ ("MRN-104821", "Neil", "Sorenson", "1984-03-12"),
+ ("MRN-104812", "Nell", "Sorensen", "1986-07-09"),
+ ("MRN-220931", "Maria", "Alvarez", "1979-11-02"),
+ ("MRN-220913", "Mario", "Alvarez", "1979-11-20"),
+ ("MRN-318470", "Priya", "Chandra", "1990-02-14"),
+ ("MRN-318407", "Priya", "Chandran", "1990-12-04"),
+ ("MRN-402215", "Wei", "Chen", "1975-09-30"),
+ ("MRN-402251", "Wei", "Cheng", "1975-03-09"),
+ ("MRN-517736", "Fatima", "Noor", "1988-12-01"),
+ ("MRN-517763", "Fatma", "Nour", "1988-10-21"),
+ ("MRN-603318", "Oskar", "Bakke", "1992-06-18"),
+ ("MRN-709924", "Robert", "Kowalski", "1968-08-08"),
+ ("MRN-709942", "Roberta", "Kowalska", "1968-08-18"),
+ ("MRN-811045", "Grace", "Okafor", "1995-04-25"),
+ ("MRN-912260", "Tomas", "Lindqvist", "1971-01-30"),
+ ("MRN-912206", "Thomas", "Lindquist", "1971-10-03"),
+]
+PATIENT_TWIN = {
+ a: b
+ for a, b in [
+ ("MRN-104821", "MRN-104812"),
+ ("MRN-220931", "MRN-220913"),
+ ("MRN-318470", "MRN-318407"),
+ ("MRN-402215", "MRN-402251"),
+ ("MRN-517736", "MRN-517763"),
+ ("MRN-709924", "MRN-709942"),
+ ("MRN-912260", "MRN-912206"),
+ ]
+ for a, b in ((a, b), (b, a))
+}
+# Notes already on file, so a lost or misplaced note is not the only row.
+PRIOR_NOTES = [
+ ("MRN-104821", "Annual review, no changes", "2026-09-14T10:02:00Z"),
+ ("MRN-220913", "Flu vaccine given, left arm", "2026-10-01T15:40:00Z"),
+ ("MRN-709924", "BP 142/90, recheck in 1 month", "2026-10-19T09:15:00Z"),
+]
+
+CLAIMS = [
+ # claim_no, member, member_id, service_date, billed, status
+ ("CLM-2026-00417", "Ana Petrovic", "MEM-55120", "2026-10-02", "412.50", "Open"),
+ ("CLM-2026-00471", "Ana Petrovic", "MEM-55102", "2026-10-20", "421.50", "Open"),
+ ("CLM-2026-01388", "Daniel Osei", "MEM-60871", "2026-09-28", "1290.00", "Open"),
+ ("CLM-2026-01838", "Daniela Osei", "MEM-60817", "2026-09-28", "1209.00", "Open"),
+ ("CLM-2026-02254", "Hiro Tanaka", "MEM-71344", "2026-10-11", "86.40", "Open"),
+ ("CLM-2026-02245", "Hiro Tanaka", "MEM-71434", "2026-10-11", "68.40", "Open"),
+ ("CLM-2026-03109", "Leila Haddad", "MEM-80233", "2026-10-05", "2750.00", "Open"),
+ ("CLM-2026-03190", "Layla Haddad", "MEM-80323", "2026-10-15", "2570.00", "Open"),
+ ("CLM-2026-04462", "Samuel Reyes", "MEM-91005", "2026-08-30", "155.00", "Pended"),
+ ("CLM-2026-04426", "Samuel Reyes", "MEM-91050", "2026-08-03", "515.00", "Open"),
+ ("CLM-2026-05531", "Ines Carvalho", "MEM-12409", "2026-10-22", "640.00", "Open"),
+ ("CLM-2026-06027", "Marek Novak", "MEM-23116", "2026-10-09", "980.25", "Open"),
+ ("CLM-2026-06072", "Marek Nowak", "MEM-23161", "2026-10-09", "908.25", "Open"),
+ ("CLM-2026-07714", "Chloe Martin", "MEM-34877", "2026-10-17", "220.00", "Open"),
+]
+CLAIM_TWIN = {
+ a: b
+ for a, b in [
+ ("CLM-2026-00417", "CLM-2026-00471"),
+ ("CLM-2026-01388", "CLM-2026-01838"),
+ ("CLM-2026-02254", "CLM-2026-02245"),
+ ("CLM-2026-03109", "CLM-2026-03190"),
+ ("CLM-2026-04462", "CLM-2026-04426"),
+ ("CLM-2026-06027", "CLM-2026-06072"),
+ ]
+ for a, b in ((a, b), (b, a))
+}
+PRIOR_ADJUDICATIONS = [
+ (
+ "CLM-2026-04462",
+ "Pended",
+ "0.00",
+ "Awaiting itemized bill",
+ "2026-09-02T11:00:00Z",
+ ),
+]
+
+
+def _db(app: str) -> str:
+ return os.path.join(ROOT, f"{app}.db")
+
+
+def _pristine(app: str) -> str:
+ return os.path.join(ROOT, f"{app}.pristine.db")
+
+
+def _fault_path(app: str) -> str:
+ return os.path.join(ROOT, f"{app}_fault.json")
+
+
+def _conn(app: str) -> sqlite3.Connection:
+ con = sqlite3.connect(_db(app))
+ con.row_factory = sqlite3.Row
+ return con
+
+
+def _now() -> str:
+ return datetime.now(timezone.utc).strftime("%Y-%m-%dT%H:%M:%SZ")
+
+
+def _build(path: str, app: str, variant: str) -> None:
+ if os.path.exists(path):
+ os.remove(path)
+ con = sqlite3.connect(path)
+ if app == "patient_chart":
+ con.execute(
+ "CREATE TABLE patients (mrn TEXT PRIMARY KEY, first TEXT, last TEXT, "
+ "dob TEXT, sort INTEGER)"
+ )
+ con.execute(
+ "CREATE TABLE notes (id INTEGER PRIMARY KEY AUTOINCREMENT, mrn TEXT, "
+ "note TEXT, written_at TEXT)"
+ )
+ rows = list(PATIENTS)
+ if variant == "reorder":
+ rows.reverse()
+ con.executemany(
+ "INSERT INTO patients VALUES (?,?,?,?,?)",
+ [(*row, i) for i, row in enumerate(rows)],
+ )
+ con.executemany(
+ "INSERT INTO notes (mrn, note, written_at) VALUES (?,?,?)", PRIOR_NOTES
+ )
+ else:
+ con.execute(
+ "CREATE TABLE claims (claim_no TEXT PRIMARY KEY, member TEXT, "
+ "member_id TEXT, service_date TEXT, billed TEXT, status TEXT, sort INTEGER)"
+ )
+ con.execute(
+ "CREATE TABLE adjudications (id INTEGER PRIMARY KEY AUTOINCREMENT, "
+ "claim_no TEXT, status TEXT, allowed_amount TEXT, note TEXT, written_at TEXT)"
+ )
+ rows = list(CLAIMS)
+ if variant == "reorder":
+ rows.reverse()
+ con.executemany(
+ "INSERT INTO claims VALUES (?,?,?,?,?,?,?)",
+ [(*row, i) for i, row in enumerate(rows)],
+ )
+ con.executemany(
+ "INSERT INTO adjudications (claim_no, status, allowed_amount, note, "
+ "written_at) VALUES (?,?,?,?,?)",
+ PRIOR_ADJUDICATIONS,
+ )
+ con.commit()
+ con.close()
+
+
+def seed(app: str, fault: str = "ok", variant: str = "none") -> None:
+ """Restore the pristine database (built once per variant) and set the fault.
+
+ A restore is a file copy of a database built from the fixed seed, so two
+ episodes start from byte-identical tables whatever the last one did.
+ """
+ if app not in APPS:
+ raise SystemExit(f"unknown app {app!r}")
+ if fault not in FAULTS:
+ raise SystemExit(f"unknown fault {fault!r}")
+ os.makedirs(ROOT, exist_ok=True)
+ pristine = _pristine(app) + ("" if variant == "none" else f".{variant}")
+ if not os.path.exists(pristine):
+ _build(pristine, app, variant)
+ for suffix in ("", "-journal", "-wal", "-shm"):
+ if os.path.exists(_db(app) + suffix):
+ os.remove(_db(app) + suffix)
+ shutil.copyfile(pristine, _db(app))
+ with open(_fault_path(app), "w", encoding="ascii") as fh:
+ json.dump({"fault": fault}, fh)
+ if os.path.exists(_attempts_path(app)):
+ os.remove(_attempts_path(app))
+
+
+def _fault(app: str) -> str:
+ """The planted fault for this save; ``drop_first`` drops only the first."""
+ try:
+ with open(_fault_path(app), encoding="ascii") as fh:
+ state = json.load(fh)
+ except (OSError, ValueError):
+ return "ok"
+ fault = str(state.get("fault") or "ok")
+ if fault == "drop_first":
+ if state.get("dropped"):
+ return "ok"
+ with open(_fault_path(app), "w", encoding="ascii") as fh:
+ json.dump({"fault": fault, "dropped": True}, fh)
+ return "drop"
+ return fault
+
+
+def digest(app: str) -> str:
+ con = _conn(app)
+ h = hashlib.sha256()
+ for (name,) in con.execute(
+ "SELECT name FROM sqlite_master WHERE type='table' AND name NOT LIKE 'sqlite_%' "
+ "ORDER BY name"
+ ):
+ h.update(name.encode())
+ for row in con.execute(f"SELECT * FROM {name} ORDER BY 1"):
+ h.update(json.dumps(list(row)).encode())
+ return h.hexdigest()
+
+
+def dump(app: str) -> dict:
+ con = _conn(app)
+ if app == "patient_chart":
+ rows = con.execute(
+ "SELECT n.id, n.mrn, p.first, p.last, n.note, n.written_at FROM notes n "
+ "LEFT JOIN patients p ON p.mrn = n.mrn ORDER BY n.id"
+ )
+ else:
+ rows = con.execute(
+ "SELECT a.id, a.claim_no, c.member, a.status, a.allowed_amount, a.note, "
+ "a.written_at FROM adjudications a LEFT JOIN claims c "
+ "ON c.claim_no = a.claim_no ORDER BY a.id"
+ )
+ records = [
+ {k: ("" if v is None else str(v)) for k, v in dict(r).items()} for r in rows
+ ]
+ return {"records": records}
+
+
+def _attempts_path(app: str) -> str:
+ return os.path.join(ROOT, f"{app}_attempts.jsonl")
+
+
+def _log_attempt(app: str, values: dict) -> None:
+ """Record what the app asked to save, before any fault changes it.
+
+ The environment pays an honest failure report on an infeasible task only
+ when the agent tried the save; this log, cleared at every seed, is how it
+ knows. It holds the request, not the outcome.
+ """
+ with open(_attempts_path(app), "a", encoding="utf-8") as fh:
+ fh.write(json.dumps(values, sort_keys=True) + "\n")
+
+
+def attempts(app: str) -> list:
+ try:
+ with open(_attempts_path(app), encoding="utf-8") as fh:
+ return [json.loads(line) for line in fh if line.strip()]
+ except OSError:
+ return []
+
+
+def _cut_last_word(text: str) -> str:
+ head, _, _ = text.rstrip().rpartition(" ")
+ return head or text[:-1]
+
+
+def pc_save(mrn: str, note: str) -> None:
+ _log_attempt("patient_chart", {"mrn": mrn, "note": note})
+ fault = _fault("patient_chart")
+ con = _conn("patient_chart")
+ if fault == "drop":
+ return
+ if fault == "wrong_row":
+ mrn = PATIENT_TWIN.get(mrn, mrn)
+ if fault == "truncate":
+ note = _cut_last_word(note)
+ if fault == "stale":
+ last = con.execute(
+ "SELECT note FROM notes WHERE mrn=? ORDER BY id DESC LIMIT 1", (mrn,)
+ ).fetchone()
+ note = last["note"] if last else ""
+ times = 2 if fault == "duplicate" else 1
+ for _ in range(times):
+ con.execute(
+ "INSERT INTO notes (mrn, note, written_at) VALUES (?,?,?)",
+ (mrn, note, _now()),
+ )
+ con.commit()
+
+
+def cd_save(claim_no: str, status: str, amount: str, note: str) -> None:
+ _log_attempt(
+ "claims_desk",
+ {
+ "claim_no": claim_no,
+ "status": status,
+ "allowed_amount": amount,
+ "note": note,
+ },
+ )
+ fault = _fault("claims_desk")
+ con = _conn("claims_desk")
+ if fault == "drop":
+ return
+ if fault == "wrong_row":
+ claim_no = CLAIM_TWIN.get(claim_no, claim_no)
+ if fault == "truncate":
+ note = _cut_last_word(note)
+ if fault == "stale":
+ row = con.execute(
+ "SELECT billed FROM claims WHERE claim_no=?", (claim_no,)
+ ).fetchone()
+ amount = row["billed"] if row else amount
+ times = 2 if fault == "duplicate" else 1
+ for _ in range(times):
+ con.execute(
+ "INSERT INTO adjudications (claim_no, status, allowed_amount, note, written_at) "
+ "VALUES (?,?,?,?,?)",
+ (claim_no, status, amount, note, _now()),
+ )
+ con.execute("UPDATE claims SET status=? WHERE claim_no=?", (status, claim_no))
+ con.commit()
+
+
+def _b64(value: str) -> str:
+ return base64.b64decode(value.encode("ascii")).decode("utf-8")
+
+
+def main(argv: list[str]) -> int:
+ if not argv:
+ print(__doc__)
+ return 2
+ cmd, args = argv[0], argv[1:]
+ if cmd == "seed":
+ app = args[0]
+ opts = dict(zip(args[1::2], args[2::2]))
+ seed(app, opts.get("--fault", "ok"), opts.get("--variant", "none"))
+ print(json.dumps({"seeded": app, "digest": digest(app)}))
+ elif cmd == "digest":
+ print(json.dumps({"digest": digest(args[0])}))
+ elif cmd == "attempts":
+ print(json.dumps({"attempts": attempts(args[0])}))
+ elif cmd == "dump":
+ print(json.dumps(dump(args[0])))
+ elif cmd == "pc-list":
+ like = f"%{args[0] if args else ''}%"
+ rows = _conn("patient_chart").execute(
+ "SELECT mrn, first, last, dob FROM patients WHERE first LIKE ? OR last LIKE ? "
+ "OR mrn LIKE ? ORDER BY sort",
+ (like, like, like),
+ )
+ print(json.dumps([dict(r) for r in rows]))
+ elif cmd == "pc-get":
+ con = _conn("patient_chart")
+ p = con.execute("SELECT * FROM patients WHERE mrn=?", (args[0],)).fetchone()
+ last = con.execute(
+ "SELECT note FROM notes WHERE mrn=? ORDER BY id DESC LIMIT 1", (args[0],)
+ ).fetchone()
+ count = con.execute(
+ "SELECT COUNT(*) FROM notes WHERE mrn=?", (args[0],)
+ ).fetchone()[0]
+ out = dict(p) if p else {}
+ out["last_note"] = last["note"] if last else ""
+ out["note_count"] = count
+ print(json.dumps(out))
+ elif cmd == "pc-save":
+ pc_save(args[0], _b64(args[1]))
+ print("OK")
+ elif cmd == "cd-list":
+ like = f"%{args[0] if args else ''}%"
+ rows = _conn("claims_desk").execute(
+ "SELECT claim_no, member, member_id, service_date, billed, status FROM claims "
+ "WHERE claim_no LIKE ? OR member LIKE ? OR member_id LIKE ? ORDER BY sort",
+ (like, like, like),
+ )
+ print(json.dumps([dict(r) for r in rows]))
+ elif cmd == "cd-get":
+ con = _conn("claims_desk")
+ row = con.execute(
+ "SELECT * FROM claims WHERE claim_no=?", (args[0],)
+ ).fetchone()
+ last = con.execute(
+ "SELECT status, allowed_amount, note FROM adjudications WHERE claim_no=? "
+ "ORDER BY id DESC LIMIT 1",
+ (args[0],),
+ ).fetchone()
+ count = con.execute(
+ "SELECT COUNT(*) FROM adjudications WHERE claim_no=?", (args[0],)
+ ).fetchone()[0]
+ out = dict(row) if row else {}
+ out["last_decision"] = dict(last) if last else None
+ out["decision_count"] = count
+ print(json.dumps(out))
+ elif cmd == "cd-save":
+ cd_save(args[0], args[1], args[2], _b64(args[3]))
+ print("OK")
+ else:
+ print(f"unknown command {cmd!r}", file=sys.stderr)
+ return 2
+ return 0
+
+
+if __name__ == "__main__":
+ raise SystemExit(main(sys.argv[1:]))
diff --git a/packages/flow/environments/openenv/_windows/apps/patient_chart.ps1 b/packages/flow/environments/openenv/_windows/apps/patient_chart.ps1
new file mode 100644
index 0000000000..5bbc35269a
--- /dev/null
+++ b/packages/flow/environments/openenv/_windows/apps/patient_chart.ps1
@@ -0,0 +1,205 @@
+# Patient Chart (WinForms): search a patient, write a chart note, save.
+#
+# A self-built line-of-business app for the Windows environment pack. All
+# persistence goes through pack_db.py (SQLite); the environment's oracle reads
+# the same database outside the session, so the reward never comes from this
+# screen. The app never reads the planted fault: it always reports the save as
+# done, the way a real client trusts its backend.
+#
+# UI knobs come from C:\oa\pack\data\patient_chart_ui.json, written at reset:
+# banner : text shown in a yellow strip at the top (a misleading notice,
+# for example "Note saved for MRN-104812").
+# window : "maximized" (default: full screen over the taskbar) or
+# "windowed"; size "WxH" forces windowed.
+#
+# Usage: powershell -STA -ExecutionPolicy Bypass -File patient_chart.ps1
+
+param(
+ [string]$Python = "",
+ [string]$DbCli = "C:\oa\pack\pack_db.py"
+)
+
+Add-Type -AssemblyName System.Windows.Forms
+Add-Type -AssemblyName System.Drawing
+[System.Windows.Forms.Application]::EnableVisualStyles()
+
+if (-not $Python) { $Python = (Get-Content "C:\oa\pack\python.txt" -Raw).Trim() }
+
+$cfg = @{ banner = ""; window = "maximized"; size = "" }
+$cfgPath = "C:\oa\pack\data\patient_chart_ui.json"
+if (Test-Path $cfgPath) {
+ try {
+ $j = Get-Content $cfgPath -Raw | ConvertFrom-Json
+ foreach ($k in @("banner", "window", "size")) {
+ if ($null -ne $j.$k) { $cfg[$k] = $j.$k }
+ }
+ } catch {}
+}
+
+function Invoke-Db {
+ param([string[]]$DbArgs)
+ $psi = New-Object System.Diagnostics.ProcessStartInfo
+ $psi.FileName = $Python
+ $psi.Arguments = (@("-I", "`"$DbCli`"") + $DbArgs) -join ' '
+ $psi.RedirectStandardOutput = $true
+ $psi.UseShellExecute = $false
+ $psi.CreateNoWindow = $true
+ $p = [System.Diagnostics.Process]::Start($psi)
+ $out = $p.StandardOutput.ReadToEnd()
+ $p.WaitForExit()
+ return $out
+}
+
+$form = New-Object System.Windows.Forms.Form
+$form.Text = "Patient Chart"
+$form.Name = "patientChartForm"
+$form.Size = New-Object System.Drawing.Size(900, 620)
+$form.StartPosition = "Manual"
+$form.Location = New-Object System.Drawing.Point(40, 40)
+$form.AutoScaleMode = [System.Windows.Forms.AutoScaleMode]::Dpi
+$form.Font = New-Object System.Drawing.Font("Segoe UI", 9.0)
+$form.BackColor = [System.Drawing.Color]::White
+# Full screen by default: borderless and maximized, so the window covers the
+# taskbar and an agent's clicks cannot reach the Start menu or another app.
+if ([string]$cfg["window"] -eq "windowed") { $form.WindowState = "Normal" } else {
+ $form.FormBorderStyle = "None"
+ $form.WindowState = "Maximized"
+}
+if ([string]$cfg["size"]) {
+ $wh = ([string]$cfg["size"]) -split 'x'
+ $form.WindowState = "Normal"
+ $form.Size = New-Object System.Drawing.Size([int]$wh[0], [int]$wh[1])
+}
+$form.TopMost = $true
+
+$banner = New-Object System.Windows.Forms.Label
+$banner.Name = "noticeBanner"
+$banner.Location = New-Object System.Drawing.Point(20, 8)
+$banner.Size = New-Object System.Drawing.Size(720, 26)
+$banner.TextAlign = "MiddleLeft"
+$banner.BackColor = [System.Drawing.Color]::FromArgb(255, 241, 168)
+$banner.Text = [string]$cfg["banner"]
+$banner.Visible = [bool]([string]$cfg["banner"])
+$form.Controls.Add($banner)
+
+$searchBox = New-Object System.Windows.Forms.TextBox
+$searchBox.Name = "searchBox"
+$searchBox.AccessibleName = "Search patients"
+$searchBox.Location = New-Object System.Drawing.Point(20, 44)
+$searchBox.Size = New-Object System.Drawing.Size(500, 28)
+$form.Controls.Add($searchBox)
+
+$searchButton = New-Object System.Windows.Forms.Button
+$searchButton.Name = "searchButton"
+$searchButton.Text = "Search"
+$searchButton.Location = New-Object System.Drawing.Point(530, 42)
+$searchButton.Size = New-Object System.Drawing.Size(100, 30)
+$form.Controls.Add($searchButton)
+
+$grid = New-Object System.Windows.Forms.DataGridView
+$grid.Name = "patientGrid"
+$grid.AccessibleName = "Patients"
+$grid.Location = New-Object System.Drawing.Point(20, 82)
+$grid.Size = New-Object System.Drawing.Size(720, 230)
+$grid.ReadOnly = $true
+$grid.AllowUserToAddRows = $false
+$grid.SelectionMode = "FullRowSelect"
+$grid.MultiSelect = $false
+$grid.AutoSizeColumnsMode = "Fill"
+$grid.RowHeadersVisible = $false
+$grid.RowTemplate.Height = 36
+$grid.ColumnHeadersHeight = 34
+$grid.AllowUserToResizeRows = $false
+$form.Controls.Add($grid)
+
+$noteLabel = New-Object System.Windows.Forms.Label
+$noteLabel.Text = "Chart note:"
+$noteLabel.Location = New-Object System.Drawing.Point(20, 324)
+$noteLabel.Size = New-Object System.Drawing.Size(120, 22)
+$form.Controls.Add($noteLabel)
+
+# Names the open chart, the way a chart header does. No AccessibleName, so UI
+# Automation reports its text as Name and Control.Name as AutomationId.
+$patientHeader = New-Object System.Windows.Forms.Label
+$patientHeader.Name = "patientHeader"
+$patientHeader.Text = ""
+$patientHeader.Location = New-Object System.Drawing.Point(150, 324)
+$patientHeader.Size = New-Object System.Drawing.Size(590, 22)
+$form.Controls.Add($patientHeader)
+
+$noteBox = New-Object System.Windows.Forms.TextBox
+$noteBox.Name = "noteBox"
+$noteBox.AccessibleName = "Chart note"
+$noteBox.Multiline = $true
+$noteBox.Location = New-Object System.Drawing.Point(20, 350)
+$noteBox.Size = New-Object System.Drawing.Size(720, 110)
+$form.Controls.Add($noteBox)
+
+$lastLabel = New-Object System.Windows.Forms.Label
+$lastLabel.Name = "lastNoteLabel"
+$lastLabel.Text = ""
+$lastLabel.Location = New-Object System.Drawing.Point(20, 466)
+$lastLabel.Size = New-Object System.Drawing.Size(600, 22)
+$lastLabel.ForeColor = [System.Drawing.Color]::DimGray
+$form.Controls.Add($lastLabel)
+
+$saveButton = New-Object System.Windows.Forms.Button
+$saveButton.Name = "saveButton"
+$saveButton.Text = "Save Note"
+$saveButton.Location = New-Object System.Drawing.Point(630, 494)
+$saveButton.Size = New-Object System.Drawing.Size(110, 34)
+$form.Controls.Add($saveButton)
+
+$status = New-Object System.Windows.Forms.Label
+$status.Name = "statusLabel"
+$status.Text = "Ready"
+$status.Location = New-Object System.Drawing.Point(20, 500)
+$status.Size = New-Object System.Drawing.Size(600, 22)
+$form.Controls.Add($status)
+
+function Load-Patients {
+ param([string]$Filter)
+ $json = Invoke-Db -DbArgs @("pc-list", "`"$Filter`"")
+ $rows = @()
+ if ($json.Trim().Length -gt 0) { $rows = @($json | ConvertFrom-Json) }
+ $dt = New-Object System.Data.DataTable
+ foreach ($c in @("MRN", "First", "Last", "DOB")) { [void]$dt.Columns.Add($c) }
+ foreach ($r in $rows) { [void]$dt.Rows.Add($r.mrn, $r.first, $r.last, $r.dob) }
+ $grid.DataSource = $dt
+ $grid.ClearSelection()
+ $patientHeader.Text = ""
+ $noteBox.Text = ""
+ $lastLabel.Text = ""
+ $status.Text = "Found " + $rows.Count + " patients"
+}
+
+$searchButton.Add_Click({ Load-Patients -Filter $searchBox.Text })
+$searchBox.Add_KeyDown({
+ if ($_.KeyCode -eq "Enter") { Load-Patients -Filter $searchBox.Text; $_.SuppressKeyPress = $true }
+})
+
+$grid.Add_CellClick({
+ if ($grid.SelectedRows.Count -gt 0) {
+ $mrn = $grid.SelectedRows[0].Cells["MRN"].Value
+ if ($mrn) {
+ $p = (Invoke-Db -DbArgs @("pc-get", "$mrn")) | ConvertFrom-Json
+ if ($p) {
+ $patientHeader.Text = "Chart: " + $p.first + " " + $p.last + " " + $p.mrn + " DOB " + $p.dob
+ $noteBox.Text = ""
+ if ($p.last_note) { $lastLabel.Text = "" + $p.note_count + " notes on file. Last: " + $p.last_note } else { $lastLabel.Text = "No notes on file" }
+ }
+ }
+ }
+})
+
+$saveButton.Add_Click({
+ if ($grid.SelectedRows.Count -lt 1 -or -not $patientHeader.Text) { $status.Text = "Open a chart first"; return }
+ if (-not $noteBox.Text.Trim()) { $status.Text = "Note is empty"; return }
+ $mrn = $grid.SelectedRows[0].Cells["MRN"].Value
+ $b64 = [Convert]::ToBase64String([Text.Encoding]::UTF8.GetBytes($noteBox.Text))
+ [void](Invoke-Db -DbArgs @("pc-save", "$mrn", "$b64"))
+ $status.Text = "Note saved for $mrn"
+})
+
+Load-Patients -Filter ""
+[void]$form.ShowDialog()
diff --git a/packages/flow/environments/openenv/_windows/make_tasks.py b/packages/flow/environments/openenv/_windows/make_tasks.py
new file mode 100644
index 0000000000..1b0f273db3
--- /dev/null
+++ b/packages/flow/environments/openenv/_windows/make_tasks.py
@@ -0,0 +1,401 @@
+"""Generate the Windows packs' task sets: a public sample and a held-out half.
+
+ python environments/openenv/_windows/make_tasks.py --heldout-out
+
+Each app gets 48 parameterized tasks from one seed, split evenly and
+disjointly (no note text, amount or target/fault pair appears in both
+halves). The public half is written into every environment directory that
+serves the app (the UIA and the pixels-only variant share tasks). The
+held-out half goes only to ``--heldout-out``, outside this repository; its
+SHA-256 and counts are recorded in ``tasks/MANIFEST.json`` beside the public
+file, so a held-out score can be tied to the exact set without publishing it.
+The held-out half comes from a secret seed (``OPENADAPT_HELDOUT_SEED``, kept
+with it), so this file cannot rebuild it.
+
+Per half and app: 12 feasible tasks and 12 infeasible ones.
+
+* Feasible: 3 where the first save is lost while the screen says "saved"
+ (the reference solution re-opens the record, sees the count unchanged and
+ saves again), 3 under a misleading banner, 3 on a reordered list, 3 plain.
+* Infeasible, a planted write fault the screen does not show: drop 3,
+ wrong_row 3, duplicate 2, truncate 2, stale 2.
+
+Every target has a look-alike record (one transposed digit, a near-identical
+name). Task ids are opaque and tags never name the fault, so neither tells
+an agent what the record will hold.
+"""
+
+from __future__ import annotations
+
+import argparse
+import hashlib
+import json
+import os
+import random
+import sys
+from pathlib import Path
+
+HERE = Path(__file__).resolve().parent
+sys.path.insert(0, str(HERE / "apps"))
+import pack_db # noqa: E402
+
+ENVS = {
+ "patient_chart": ["win-patient-chart", "win-patient-chart-rdp"],
+ "claims_desk": ["win-claims-desk", "win-claims-desk-rdp"],
+}
+FAULTS = (
+ ["drop"] * 3
+ + ["wrong_row"] * 3
+ + ["duplicate"] * 2
+ + ["truncate"] * 2
+ + ["stale"] * 2
+)
+SEED = 20261103
+#: The held-out half's secret seed, kept with the held-out files (private).
+HELDOUT_SEED_ENV = "OPENADAPT_HELDOUT_SEED"
+
+NOTES = [
+ "BP 128/82, continue lisinopril, recheck in 2 weeks",
+ "Left knee swelling, ice and rest, review in 1 week",
+ "A1c 7.9, increase metformin to 1000 mg twice daily",
+ "Rash on forearm resolving, stop hydrocortisone",
+ "Cough 10 days, chest clear, no antibiotics",
+ "Migraine twice weekly, start propranolol 40 mg",
+ "Ankle sprain grade 1, brace for 3 weeks",
+ "Vitamin D low, start 2000 IU daily",
+ "Sleep improved on melatonin, continue 3 mg",
+ "Ear infection right side, amoxicillin 7 days",
+ "Weight down 3 kg, keep current diet plan",
+ "Back pain after lifting, physio referral sent",
+ "Flu vaccine given, left deltoid, no reaction",
+ "TSH normal, keep levothyroxine at 75 mcg",
+ "Anxiety stable, continue sertraline 50 mg",
+ "Asthma well controlled, inhaler technique reviewed",
+ "Wound check day 7, healing well, sutures out",
+ "Iron 6 weeks done, ferritin to be repeated",
+ "Palpitations, ECG normal, holter booked",
+ "Smoking down to 5 a day, nicotine patch 14 mg",
+ "Gout flare big toe, colchicine for 3 days",
+ "Allergic rhinitis, start cetirizine 10 mg",
+ "Heel pain on waking, stretching plan given",
+ "Cholesterol 6.1, start atorvastatin 20 mg",
+]
+CLAIM_NOTES = [
+ ("Approved", "Covered under plan section 4.2, in network"),
+ ("Denied", "Duplicate of an earlier claim"),
+ ("Pended", "Missing itemized bill, pend for documents"),
+ ("Approved", "Prior authorization on file"),
+ ("Approved", "Out of network, member responsibility applies"),
+ ("Approved", "Coding corrected to the lower level visit"),
+ ("Denied", "Service before coverage start date"),
+ ("Approved", "Allowed at the contracted rate"),
+ ("Pended", "Pend for medical review of necessity"),
+ ("Pended", "Coordination of benefits, secondary payer"),
+ ("Approved", "Approved after appeal, see attached letter"),
+ ("Denied", "Not a covered benefit under this plan"),
+]
+
+
+def _task_id(app: str, split: str, n: int, seed: str = str(SEED)) -> str:
+ return (
+ f"{app}-"
+ + hashlib.sha256(f"{seed}:{app}:{split}:{n}".encode()).hexdigest()[:10]
+ )
+
+
+def _sha(path: Path) -> str:
+ return hashlib.sha256(path.read_bytes()).hexdigest()
+
+
+def _twin_name_pc(mrn: str) -> str:
+ twin = pack_db.PATIENT_TWIN[mrn]
+ row = next(p for p in pack_db.PATIENTS if p[0] == twin)
+ return f"{row[1]} {row[2]} ({twin})"
+
+
+def _banners_pc(target: tuple, rng: random.Random) -> list[str]:
+ mrn, first, last, _ = target
+ return [
+ f"Note saved for {_twin_name_pc(mrn)}",
+ f"Today's note for {first} {last} is already on file",
+ "Chart sync complete: all notes saved",
+ f"Reminder: {first} {last} was merged into {pack_db.PATIENT_TWIN[mrn]}",
+ ]
+
+
+def _banners_cd(target: tuple) -> list[str]:
+ claim_no, member = target[0], target[1]
+ twin = pack_db.CLAIM_TWIN[claim_no]
+ return [
+ f"Decision saved for {twin}",
+ f"Claim {claim_no} was already approved by auto-adjudication",
+ "Batch posting complete: all decisions saved",
+ f"Notice: {member}'s claims moved to {twin}",
+ ]
+
+
+def _pc_task(
+ n: int, split: str, target: tuple, note: str, fault: str, setup: dict
+) -> dict:
+ mrn, first, last, dob = target
+ feasible = fault in ("ok", "drop_first")
+ instruction = (
+ f"In Patient Chart, open the chart for {first} {last} ({mrn}, born {dob}) and "
+ f'save exactly this note on it once: "{note}". Other patients have similar '
+ "names and numbers. The chart shows how many notes are on file and the last one. "
+ "Finish with done: claim success only if that patient's chart now holds this "
+ "note exactly once, otherwise claim failure."
+ )
+ solution = [
+ {"kind": "click", "target": "searchBox"},
+ {"kind": "type", "text": mrn},
+ {"kind": "press", "text": "enter"},
+ {"kind": "wait", "seconds": 2},
+ {"kind": "click", "target": "patientGrid", "at": [0.11, 0.226]},
+ {"kind": "wait", "seconds": 2},
+ {"kind": "click", "target": "noteBox"},
+ {"kind": "type", "text": note},
+ {"kind": "click", "target": "saveButton"},
+ {"kind": "wait", "seconds": 3},
+ ]
+ if fault == "drop_first":
+ # Re-open the chart: the count did not move, so save again.
+ solution += [
+ {"kind": "click", "target": "patientGrid", "at": [0.11, 0.226]},
+ {"kind": "wait", "seconds": 2},
+ {"kind": "click", "target": "noteBox"},
+ {"kind": "type", "text": note},
+ {"kind": "click", "target": "saveButton"},
+ {"kind": "wait", "seconds": 3},
+ ]
+ solution.append({"kind": "done", "claim": "success" if feasible else "failure"})
+ tags = [f"lookalike:{pack_db.PATIENT_TWIN[mrn]}"]
+ if setup.get("ui", {}).get("banner"):
+ tags.append("misleading_banner")
+ if setup.get("variant", "none") != "none":
+ tags.append(f"variant:{setup['variant']}")
+ return {
+ "id": _task_id("winchart", split, n, _SEEDS[split]),
+ "split": split,
+ "instruction": instruction,
+ "params": {"mrn": mrn, "note": note},
+ "setup": setup,
+ "feasible": feasible,
+ "fault": fault,
+ "solution": solution,
+ "tags": tags,
+ }
+
+
+def _cd_task(
+ n: int,
+ split: str,
+ target: tuple,
+ decision: str,
+ amount: str,
+ note: str,
+ fault: str,
+ setup: dict,
+) -> dict:
+ claim_no, member, member_id, service_date, billed, _ = target
+ feasible = fault in ("ok", "drop_first")
+ instruction = (
+ f"In Claims Desk, open claim {claim_no} ({member}, member {member_id}, service "
+ f"{service_date}, billed {billed}) and record one decision: {decision}, allowed "
+ f'amount {amount} (typed exactly as written), note "{note}". Other claims have '
+ "similar numbers and members. "
+ "The claim shows how many decisions are on file and the last one. Finish with "
+ "done: claim success only if that claim now holds exactly this decision once, "
+ "otherwise claim failure."
+ )
+ solution = [
+ {"kind": "click", "target": "searchBox"},
+ {"kind": "type", "text": claim_no},
+ {"kind": "press", "text": "enter"},
+ {"kind": "wait", "seconds": 2},
+ {"kind": "click", "target": "claimsGrid", "at": [0.05, 0.196]},
+ {"kind": "wait", "seconds": 2},
+ {"kind": "click", "target": f"status{decision}"},
+ {"kind": "click", "target": "amountBox"},
+ {"kind": "type", "text": amount},
+ {"kind": "click", "target": "noteBox"},
+ {"kind": "type", "text": note},
+ {"kind": "click", "target": "saveButton"},
+ {"kind": "wait", "seconds": 3},
+ ]
+ if fault == "drop_first":
+ # Re-open the claim: no new decision on file, so record it again.
+ solution += [
+ {"kind": "click", "target": "claimsGrid", "at": [0.05, 0.196]},
+ {"kind": "wait", "seconds": 2},
+ {"kind": "click", "target": f"status{decision}"},
+ {"kind": "click", "target": "amountBox"},
+ {"kind": "type", "text": amount},
+ {"kind": "click", "target": "noteBox"},
+ {"kind": "type", "text": note},
+ {"kind": "click", "target": "saveButton"},
+ {"kind": "wait", "seconds": 3},
+ ]
+ solution.append({"kind": "done", "claim": "success" if feasible else "failure"})
+ tags = [f"lookalike:{pack_db.CLAIM_TWIN[claim_no]}"]
+ if setup.get("ui", {}).get("banner"):
+ tags.append("misleading_banner")
+ if setup.get("variant", "none") != "none":
+ tags.append(f"variant:{setup['variant']}")
+ return {
+ "id": _task_id("winclaims", split, n, _SEEDS[split]),
+ "split": split,
+ "instruction": instruction,
+ "params": {
+ "claim_no": claim_no,
+ "status": decision,
+ "allowed_amount": amount,
+ "note": note,
+ },
+ "setup": setup,
+ "feasible": feasible,
+ "fault": fault,
+ "solution": solution,
+ "tags": tags,
+ }
+
+
+def _plan(rng: random.Random) -> list[tuple[str, dict]]:
+ """24 (fault, setup) slots: 12 feasible, 12 with a planted write fault."""
+ slots: list[tuple[str, dict]] = []
+ for i in range(12):
+ fault = "drop_first" if i < 3 else "ok"
+ setup: dict = {"variant": "reorder" if 6 <= i < 9 else "none"}
+ if 3 <= i < 6:
+ setup["ui"] = {"banner": i - 3} # index, filled per target
+ slots.append((fault, setup))
+ for i, fault in enumerate(FAULTS):
+ setup = {"variant": "none"}
+ if i % 3 == 0:
+ setup["ui"] = {"banner": 2}
+ slots.append((fault, setup))
+ rng.shuffle(slots)
+ return slots
+
+
+#: Seed per split. The held-out one is secret (set by ``build``), so the
+#: held-out half cannot be rebuilt from this public file.
+_SEEDS = {"public": str(SEED), "heldout": ""}
+
+
+def build(app: str, heldout_seed: str) -> dict[str, list[dict]]:
+ if len(heldout_seed) < 16:
+ raise SystemExit(
+ f"{HELDOUT_SEED_ENV} must be a secret of at least 16 characters"
+ )
+ _SEEDS["heldout"] = heldout_seed
+ rng = random.Random(f"{SEED}:{app}")
+ # Its own stream for the held-out half: plan, targets, amounts and
+ # suffixes all come from the secret seed.
+ rngs = {"public": rng, "heldout": random.Random(f"{heldout_seed}:{app}")}
+ out: dict[str, list[dict]] = {"public": [], "heldout": []}
+ if app == "patient_chart":
+ targets = [p for p in pack_db.PATIENTS if p[0] in pack_db.PATIENT_TWIN]
+ notes = list(NOTES)
+ rng.shuffle(notes)
+ pools = {"public": notes[:12], "heldout": notes[12:]}
+ else:
+ targets = [c for c in pack_db.CLAIMS if c[0] in pack_db.CLAIM_TWIN]
+ notes = list(CLAIM_NOTES)
+ rng.shuffle(notes)
+ pools = {"public": notes[:6], "heldout": notes[6:]}
+ for split in ("public", "heldout"):
+ rng = rngs[split]
+ for n, (fault, setup) in enumerate(_plan(rng)):
+ target = targets[rng.randrange(len(targets))]
+ setup = json.loads(json.dumps(setup))
+ if "ui" in setup:
+ banners = (
+ _banners_pc(target, rng)
+ if app == "patient_chart"
+ else _banners_cd(target)
+ )
+ setup["ui"]["banner"] = banners[setup["ui"]["banner"]]
+ # Variant and fault ride in setup for the reset hook; fault is also
+ # a top-level field so the scorer can group by it.
+ note = pools[split][n % len(pools[split])]
+ if app == "patient_chart":
+ # A per-task suffix keeps every (patient, note) pair unique.
+ text = f"{note} [{_suffix(split, n, rng)}]"
+ out[split].append(_pc_task(n, split, target, text, fault, setup))
+ else:
+ decision, note = note
+ # Below the billed amount, so a stale (billed) write is visible.
+ billed = int(round(float(target[4]) * 100))
+ cents = rng.randrange(billed // 2, billed - 1)
+ amount = (
+ f"{cents // 100}.{cents % 100:02d}"
+ if decision == "Approved"
+ else "0.00"
+ )
+ text = f"{note} [{_suffix(split, n, rng)}]"
+ out[split].append(
+ _cd_task(n, split, target, decision, amount, text, fault, setup)
+ )
+ return out
+
+
+def _suffix(split: str, n: int, rng: random.Random) -> str:
+ """The public half keeps its index; the held-out half gets a random tag,
+ so a held-out text says nothing about its slot in the plan."""
+ if split == "public":
+ return f"p{n:02d}"
+ return "h" + "".join(rng.choice("abcdefghjkmnpqrstuvwxyz") for _ in range(3))
+
+
+def main(argv: list[str] | None = None) -> int:
+ parser = argparse.ArgumentParser(description=__doc__.splitlines()[0])
+ parser.add_argument("--heldout-out", type=Path, required=True)
+ args = parser.parse_args(argv)
+ root = HERE.parent
+ if args.heldout_out.resolve().is_relative_to(root.resolve().parents[2]):
+ parser.error("--heldout-out must be outside this repository")
+ args.heldout_out.mkdir(parents=True, exist_ok=True)
+ for app, envs in ENVS.items():
+ sets = build(app, os.environ.get(HELDOUT_SEED_ENV, ""))
+ heldout = args.heldout_out / f"{app}.heldout.jsonl"
+ heldout.write_text(
+ "".join(json.dumps(t, sort_keys=True) + "\n" for t in sets["heldout"]),
+ encoding="utf-8",
+ )
+ for env in envs:
+ tasks_dir = root / env / "tasks"
+ tasks_dir.mkdir(parents=True, exist_ok=True)
+ public = tasks_dir / "public.jsonl"
+ public.write_text(
+ "".join(json.dumps(t, sort_keys=True) + "\n" for t in sets["public"]),
+ encoding="utf-8",
+ )
+ manifest = {
+ "schema": "openadapt.rl-env-task-manifest/v1",
+ "app": app,
+ "generator": "environments/openenv/_windows/make_tasks.py",
+ "public_seed": SEED,
+ "public": {
+ "file": "public.jsonl",
+ "sha256": _sha(public),
+ "tasks": len(sets["public"]),
+ "feasible": sum(t["feasible"] for t in sets["public"]),
+ },
+ "heldout": {
+ "location": "private",
+ "file": heldout.name,
+ "sha256": _sha(heldout),
+ "tasks": len(sets["heldout"]),
+ "feasible": sum(t["feasible"] for t in sets["heldout"]),
+ },
+ }
+ (tasks_dir / "MANIFEST.json").write_text(
+ json.dumps(manifest, indent=2, sort_keys=True) + "\n", encoding="utf-8"
+ )
+ print(app, {k: len(v) for k, v in sets.items()}, "held-out ->", heldout)
+ return 0
+
+
+if __name__ == "__main__":
+ raise SystemExit(main())
diff --git a/packages/flow/environments/openenv/_windows/provision/setup_guest.ps1 b/packages/flow/environments/openenv/_windows/provision/setup_guest.ps1
new file mode 100644
index 0000000000..721e497ca8
--- /dev/null
+++ b/packages/flow/environments/openenv/_windows/provision/setup_guest.ps1
@@ -0,0 +1,85 @@
+# Prepare a Windows machine you supply for the OpenAdapt Windows environments.
+#
+# Run once, as an administrator, on a Windows 10/11 or Windows Server
+# 2019/2022/2025 machine built from your own image (or an Azure or AWS Windows
+# template). This script does not download or ship Windows. It:
+#
+# 1. turns on WinRM (the environment server's control channel: reset and
+# the database read-out) and Remote Desktop (the pixels-only surface);
+# 2. sets the Remote Desktop host to prefer H.264/AVC444 graphics, as a
+# production session host would, and keeps the desktop session inside
+# the app (machine shell policies);
+# 3. installs CPython (official, signature-checked) and the in-guest UI
+# Automation agent's packages;
+# 4. creates C:\oa\pack for the apps (the server copies them in and makes
+# the code read-only to the desktop account; only C:\oa\pack\data is
+# writable by it).
+#
+# The desktop account must be a standard user, or an administrator with UAC
+# on, so its desktop session cannot rewrite the code the oracle runs; the
+# server checks this and refuses the guest otherwise. The WinRM account must
+# be an administrator.
+#
+# Usage (elevated PowerShell):
+# powershell -ExecutionPolicy Bypass -File setup_guest.ps1 -User
+#
+# The desktop account must be signed in to its desktop (console or RDP) while
+# episodes run: the apps and the agent start in that session.
+
+param(
+ [Parameter(Mandatory = $true)][string]$User,
+ [string]$PythonVersion = "3.12.10"
+)
+
+$ErrorActionPreference = "Stop"
+$ProgressPreference = "SilentlyContinue"
+
+# 1. WinRM over HTTP with NTLM message encryption, and Remote Desktop.
+Enable-PSRemoting -Force -SkipNetworkProfileCheck | Out-Null
+Set-Item WSMan:\localhost\Service\AllowUnencrypted -Value $false
+Set-ItemProperty "HKLM:\System\CurrentControlSet\Control\Terminal Server" -Name fDenyTSConnections -Value 0
+Enable-NetFirewallRule -DisplayGroup "Remote Desktop" | Out-Null
+Add-LocalGroupMember -Group "Remote Desktop Users" -Member $User -ErrorAction SilentlyContinue
+
+# 2. Prefer the AVC444 graphics mode (group policy "Prioritize H.264/AVC 444
+# graphics mode for Remote Desktop Connections") and allow the software
+# encoder when there is no GPU.
+$ts = "HKLM:\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services"
+New-Item -Path $ts -Force | Out-Null
+Set-ItemProperty $ts -Name AVC444ModePreferred -Value 1 -Type DWord
+Set-ItemProperty $ts -Name AVCHardwareEncodePreferred -Value 1 -Type DWord
+
+# 2b. Keep the desktop session inside the app. The apps run full screen over
+# the taskbar and the environment refuses the Windows key, Alt and the
+# function keys; these machine policies close the remaining exits (Win
+# key shortcuts, Run, Task Manager). Use a machine dedicated to the
+# environments: they apply to every account.
+$ex = "HKLM:\Software\Microsoft\Windows\CurrentVersion\Policies\Explorer"
+$sy = "HKLM:\Software\Microsoft\Windows\CurrentVersion\Policies\System"
+New-Item -Path $ex -Force | Out-Null
+New-Item -Path $sy -Force | Out-Null
+Set-ItemProperty $ex -Name NoWinKeys -Value 1 -Type DWord
+Set-ItemProperty $ex -Name NoRun -Value 1 -Type DWord
+Set-ItemProperty $sy -Name DisableTaskMgr -Value 1 -Type DWord
+
+# 3. CPython for this machine's architecture, and the agent's packages.
+$arch = if ($env:PROCESSOR_ARCHITECTURE -eq "ARM64") { "arm64" } else { "amd64" }
+$dir = "C:\Program Files\Python312-$arch"
+$py = Join-Path $dir "python.exe"
+if (-not (Test-Path $py)) {
+ New-Item -ItemType Directory -Force C:\oa\dl | Out-Null
+ $exe = "C:\oa\dl\python-$PythonVersion-$arch.exe"
+ curl.exe -s -f -L -o $exe "https://www.python.org/ftp/python/$PythonVersion/python-$PythonVersion-$arch.exe"
+ $sig = Get-AuthenticodeSignature $exe
+ if ($sig.Status -ne "Valid" -or $sig.SignerCertificate.Subject -notmatch "Python Software Foundation") {
+ throw "the Python installer's signature is not valid"
+ }
+ Start-Process -Wait -FilePath $exe -ArgumentList '/quiet', 'InstallAllUsers=1', 'Include_test=0', "TargetDir=`"$dir`""
+}
+& $py -m pip install --disable-pip-version-check -q "uiautomation==2.0.29" "comtypes==1.4.17" "pyautogui==0.9.54" "pillow==13.0.0" "mss==10.2.0"
+
+# 4. The pack directory. The server sets its permissions at deploy.
+New-Item -ItemType Directory -Force C:\oa\pack\data | Out-Null
+Set-Content -Encoding ascii -Path C:\oa\pack\python.txt -Value $py
+
+Write-Output "ready: python=$py; set OPENADAPT_WINENV_PYTHON to this path on the server"
diff --git a/packages/flow/environments/openenv/_windows/rdp-client/Containerfile b/packages/flow/environments/openenv/_windows/rdp-client/Containerfile
new file mode 100644
index 0000000000..9b131aa815
--- /dev/null
+++ b/packages/flow/environments/openenv/_windows/rdp-client/Containerfile
@@ -0,0 +1,17 @@
+# The pixels-only surface's RDP client: FreeRDP 3 under Xvfb, so the session
+# negotiates the server's H.264/AVC444 graphics pipeline. Runs the desktop
+# environment server (openadapt_flow.rl_env.desktop) inside the container.
+#
+# podman build -t openadapt-winenv-rdp -f Containerfile ../../../..
+FROM docker.io/library/debian:trixie-slim
+RUN apt-get update && apt-get install -y --no-install-recommends \
+ freerdp3-x11 xvfb xdotool openbox ca-certificates curl && rm -rf /var/lib/apt/lists/*
+WORKDIR /src
+COPY packages/types packages/types
+COPY packages/flow packages/flow
+# openadapt-flow supports Python <3.13; trixie ships 3.13, so uv installs 3.12.
+RUN curl -LsSf https://astral.sh/uv/0.8.17/install.sh | env UV_INSTALL_DIR=/usr/local/bin sh \
+ && uv venv -p 3.12 /venv && VIRTUAL_ENV=/venv uv pip install --no-cache \
+ -e packages/types -e packages/flow "openenv>=0.11,<0.12" fastapi uvicorn pywinrm
+ENV PATH=/venv/bin:$PATH
+WORKDIR /src/packages/flow
diff --git a/packages/flow/environments/openenv/_windows/results/windows11-x64-2026-11-04/README.md b/packages/flow/environments/openenv/_windows/results/windows11-x64-2026-11-04/README.md
new file mode 100644
index 0000000000..02951f9e34
--- /dev/null
+++ b/packages/flow/environments/openenv/_windows/results/windows11-x64-2026-11-04/README.md
@@ -0,0 +1,51 @@
+# Validation on Windows 11 Pro x64, 2026-11-04
+
+Each environment ran in full with `python -m openadapt_flow.rl_env.validate_desktop` against a real Windows guest, with no model calls. The JSON files here hold every episode.
+
+**Guest.** Windows 11 Pro x64 (AMD Ryzen 7 7730U, 16 GB, 2880×1800 at 200% display scaling), controlled over SSH from a macOS host. Results on other Windows builds, display scalings and hardware may differ.
+
+**Surfaces.**
+
+- **UI Automation:** the in-guest agent over TLS, at the guest's own 2880×1800 desktop.
+- **Remote Desktop, pixels only:** FreeRDP 3 under Xvfb in a Linux container, at 1280×800. The guest's RdpCoreTS log recorded `AVC available: 1, Initial profile: 2048`, so H.264/AVC444 was negotiated.
+
+**Reset scope.** The guest's desktop ran other software, so the reset scope was `pack` (`OPENADAPT_WINENV_RESET_SCOPE=pack`): only the pack's own processes were stopped between episodes.
+
+## Results
+
+| Environment | Solutions pay 1 | Planted faults refuted | Random mean | Screen-trusting mean | No state leaks | Reset median (p95) |
+|---|---:|---:|---:|---:|---|---:|
+| `win-patient-chart` | 24 / 24 | 12 / 12 | 0.0 | 0.5 | yes (2 / 2) | 7.3 s (9.6 s) |
+| `win-claims-desk` | 24 / 24 | 12 / 12 | 0.0 | 0.5 | yes (2 / 2) | 6.6 s (6.9 s) |
+| `win-patient-chart-rdp` | 24 / 24 | 12 / 12 | 0.0 | 0.5 | yes (2 / 2) | 3.3 s (3.6 s) |
+| `win-claims-desk-rdp` | 24 / 24 | 12 / 12 | 0.0 | 0.5 | yes (2 / 2) | 3.2 s (3.6 s) |
+
+How to read the columns:
+
+- **Solutions pay 1.** Each task's reference solution earned the maximum reward. On the 12 infeasible tasks, that means the app was asked to save, the record refutes the write, and the solution reports failure.
+- **Planted faults refuted.** Each feasible task's solution was run again with a write fault planted at reset (drop, wrong record, duplicate, truncate or stale) and claimed success. The record refuted every one, and each earned 0.
+- **Screen-trusting mean.** An agent that always believes the "saved" message earns 0.5: exactly the 12 feasible tasks out of 24.
+- **Reset.** Stop the app, restore the database from its pristine copy, check its digest against the seed, set the fault and banner, start the app, and wait until it takes input. The first reset of a run also deploys the pack and starts the in-guest agent, which takes 26–52 s; that is the maximum in each file, and it is left out of the median. The Remote Desktop session runs at 1280×800 and 100% scaling, so its app starts faster.
+
+**Leak check.** After an episode that wrote twice (a planted duplicate), the next reset's database digest equals the pristine seed's. The record holds only the seed's rows, the note field is empty, and one app process runs.
+
+## RDP false stops before and after #1743 and #1773
+
+These are 70 replays of one compiled Patient Notes workflow over Remote Desktop, using `benchmark/rdp_avc_real`'s protocol and outcome classes. The database, read outside the session, decides each outcome. Both builds ran on the same guest through the same client: aardwolf, at 1280×800, with RDP bitmap codecs.
+
+| Condition | Runs | Before | After #1743 and #1773 |
+|---|---:|---|---|
+| Healthy | 20 | 20 saves | 20 saves |
+| Rows reordered | 10 | 10 saves | 10 saves |
+| 16-bit colour | 10 | 10 saves | 10 saves |
+| Decoy patient above the target | 10 | 10 false stops | 10 false stops |
+| Near-identical sibling | 10 | 10 stops on the look-alike | 10 stops on the look-alike |
+| 1440×900 session | 10 | 10 false stops | 10 false stops |
+| **All** | **70** | **40 saves, 20 false stops, 0 wrong records** | **40 saves, 20 false stops, 0 wrong records** |
+
+Both builds stopped with the same message at the same step. The false stops come from two checks that the identity changes don't touch:
+
+- **Decoy.** A screen check on the Search step. Search selects the first row, so the recording expects the header to name the target; with a decoy above the target, it names the decoy.
+- **1440×900.** The run refuses a session whose size differs from the recording, before any identity check.
+
+The sibling stops are the intended outcome: a stop on a look-alike, never a save on it. No run made a model call.
diff --git a/packages/flow/environments/openenv/_windows/results/windows11-x64-2026-11-04/rdp-false-stop-ab/after.meta.json b/packages/flow/environments/openenv/_windows/results/windows11-x64-2026-11-04/rdp-false-stop-ab/after.meta.json
new file mode 100644
index 0000000000..ce1fd55d14
--- /dev/null
+++ b/packages/flow/environments/openenv/_windows/results/windows11-x64-2026-11-04/rdp-false-stop-ab/after.meta.json
@@ -0,0 +1,7 @@
+{
+ "protocol": "benchmark/rdp_avc_real, Patient Notes arm",
+ "transport": "aardwolf 0.2.14 (pure-Python RDP), macOS client -> Windows 11 Pro x64",
+ "codec": "RDP bitmap codecs negotiated by aardwolf; not H.264/AVC444",
+ "candidate_commit": "21043e168e6ccd90f3f9a9c900ff443094a88c35",
+ "started_at": "2026-11-04T06:53:53.799549+00:00"
+}
diff --git a/packages/flow/environments/openenv/_windows/results/windows11-x64-2026-11-04/rdp-false-stop-ab/after.trials.json b/packages/flow/environments/openenv/_windows/results/windows11-x64-2026-11-04/rdp-false-stop-ab/after.trials.json
new file mode 100644
index 0000000000..0f899e610a
--- /dev/null
+++ b/packages/flow/environments/openenv/_windows/results/windows11-x64-2026-11-04/rdp-false-stop-ab/after.trials.json
@@ -0,0 +1,2032 @@
+[
+ {
+ "trial": 1,
+ "condition": "healthy",
+ "drift": "none",
+ "bpp": 32,
+ "desktop": [
+ 1280,
+ 800
+ ],
+ "success": true,
+ "error": null,
+ "stop": null,
+ "model_calls": 0,
+ "rung_counts": {
+ "template": 5
+ },
+ "db_outcome": "correct",
+ "note_holders": [
+ 1
+ ],
+ "class": "verified_save",
+ "must_save": true,
+ "elapsed_s": 16.64,
+ "held_for_load_s": 0.0,
+ "load1_start": 21.8,
+ "load1_end": 23.1,
+ "first_frame_sha256": "268c9b81bcded5652d5241527734358fe7a67e1f605617b4dc2293a175409eb0"
+ },
+ {
+ "trial": 2,
+ "condition": "healthy",
+ "drift": "none",
+ "bpp": 32,
+ "desktop": [
+ 1280,
+ 800
+ ],
+ "success": true,
+ "error": null,
+ "stop": null,
+ "model_calls": 0,
+ "rung_counts": {
+ "template": 5
+ },
+ "db_outcome": "correct",
+ "note_holders": [
+ 1
+ ],
+ "class": "verified_save",
+ "must_save": true,
+ "elapsed_s": 23.42,
+ "held_for_load_s": 0.0,
+ "load1_start": 25.7,
+ "load1_end": 35.3,
+ "first_frame_sha256": "268c9b81bcded5652d5241527734358fe7a67e1f605617b4dc2293a175409eb0"
+ },
+ {
+ "trial": 3,
+ "condition": "healthy",
+ "drift": "none",
+ "bpp": 32,
+ "desktop": [
+ 1280,
+ 800
+ ],
+ "success": true,
+ "error": null,
+ "stop": null,
+ "model_calls": 0,
+ "rung_counts": {
+ "template": 5
+ },
+ "db_outcome": "correct",
+ "note_holders": [
+ 1
+ ],
+ "class": "verified_save",
+ "must_save": true,
+ "elapsed_s": 27.13,
+ "held_for_load_s": 0.0,
+ "load1_start": 35.4,
+ "load1_end": 34.1,
+ "first_frame_sha256": "53fa7512f06b98375de9001c8e68e1e285f55d74b12a8c76ddf63657d863b66c"
+ },
+ {
+ "trial": 4,
+ "condition": "healthy",
+ "drift": "none",
+ "bpp": 32,
+ "desktop": [
+ 1280,
+ 800
+ ],
+ "success": true,
+ "error": null,
+ "stop": null,
+ "model_calls": 0,
+ "rung_counts": {
+ "template": 5
+ },
+ "db_outcome": "correct",
+ "note_holders": [
+ 1
+ ],
+ "class": "verified_save",
+ "must_save": true,
+ "elapsed_s": 19.59,
+ "held_for_load_s": 0.0,
+ "load1_start": 30.5,
+ "load1_end": 25.7,
+ "first_frame_sha256": "53fa7512f06b98375de9001c8e68e1e285f55d74b12a8c76ddf63657d863b66c"
+ },
+ {
+ "trial": 5,
+ "condition": "healthy",
+ "drift": "none",
+ "bpp": 32,
+ "desktop": [
+ 1280,
+ 800
+ ],
+ "success": true,
+ "error": null,
+ "stop": null,
+ "model_calls": 0,
+ "rung_counts": {
+ "template": 5
+ },
+ "db_outcome": "correct",
+ "note_holders": [
+ 1
+ ],
+ "class": "verified_save",
+ "must_save": true,
+ "elapsed_s": 27.49,
+ "held_for_load_s": 0.0,
+ "load1_start": 22.0,
+ "load1_end": 20.9,
+ "first_frame_sha256": "f6018dc4e63394079904c170f717270428c08636ef10d2cda232b6c99fe3dedf"
+ },
+ {
+ "trial": 6,
+ "condition": "healthy",
+ "drift": "none",
+ "bpp": 32,
+ "desktop": [
+ 1280,
+ 800
+ ],
+ "success": true,
+ "error": null,
+ "stop": null,
+ "model_calls": 0,
+ "rung_counts": {
+ "template": 5
+ },
+ "db_outcome": "correct",
+ "note_holders": [
+ 1
+ ],
+ "class": "verified_save",
+ "must_save": true,
+ "elapsed_s": 25.37,
+ "held_for_load_s": 0.0,
+ "load1_start": 18.4,
+ "load1_end": 23.6,
+ "first_frame_sha256": "d6649f8e61bc0430cd8d1c6802d0515d037cedd0069a32d6ed089c133f5114c1"
+ },
+ {
+ "trial": 7,
+ "condition": "healthy",
+ "drift": "none",
+ "bpp": 32,
+ "desktop": [
+ 1280,
+ 800
+ ],
+ "success": true,
+ "error": null,
+ "stop": null,
+ "model_calls": 0,
+ "rung_counts": {
+ "template": 5
+ },
+ "db_outcome": "correct",
+ "note_holders": [
+ 1
+ ],
+ "class": "verified_save",
+ "must_save": true,
+ "elapsed_s": 10.64,
+ "held_for_load_s": 0.0,
+ "load1_start": 21.8,
+ "load1_end": 22.7,
+ "first_frame_sha256": "d6649f8e61bc0430cd8d1c6802d0515d037cedd0069a32d6ed089c133f5114c1"
+ },
+ {
+ "trial": 8,
+ "condition": "healthy",
+ "drift": "none",
+ "bpp": 32,
+ "desktop": [
+ 1280,
+ 800
+ ],
+ "success": true,
+ "error": null,
+ "stop": null,
+ "model_calls": 0,
+ "rung_counts": {
+ "template": 5
+ },
+ "db_outcome": "correct",
+ "note_holders": [
+ 1
+ ],
+ "class": "verified_save",
+ "must_save": true,
+ "elapsed_s": 22.04,
+ "held_for_load_s": 0.0,
+ "load1_start": 23.6,
+ "load1_end": 23.7,
+ "first_frame_sha256": "7f42b8e100f38ea4e1cebbd031895740415afe58bbd8c48291a5c51f2a0e90d2"
+ },
+ {
+ "trial": 9,
+ "condition": "healthy",
+ "drift": "none",
+ "bpp": 32,
+ "desktop": [
+ 1280,
+ 800
+ ],
+ "success": true,
+ "error": null,
+ "stop": null,
+ "model_calls": 0,
+ "rung_counts": {
+ "template": 5
+ },
+ "db_outcome": "correct",
+ "note_holders": [
+ 1
+ ],
+ "class": "verified_save",
+ "must_save": true,
+ "elapsed_s": 5.4,
+ "held_for_load_s": 0.0,
+ "load1_start": 20.5,
+ "load1_end": 21.8,
+ "first_frame_sha256": "7f42b8e100f38ea4e1cebbd031895740415afe58bbd8c48291a5c51f2a0e90d2"
+ },
+ {
+ "trial": 10,
+ "condition": "healthy",
+ "drift": "none",
+ "bpp": 32,
+ "desktop": [
+ 1280,
+ 800
+ ],
+ "success": true,
+ "error": null,
+ "stop": null,
+ "model_calls": 0,
+ "rung_counts": {
+ "template": 5
+ },
+ "db_outcome": "correct",
+ "note_holders": [
+ 1
+ ],
+ "class": "verified_save",
+ "must_save": true,
+ "elapsed_s": 17.26,
+ "held_for_load_s": 0.0,
+ "load1_start": 18.5,
+ "load1_end": 17.2,
+ "first_frame_sha256": "1be90849066a718f5cce4cc148bdf27c3a2a141095f212e7743a36cb2d38562c"
+ },
+ {
+ "trial": 11,
+ "condition": "healthy",
+ "drift": "none",
+ "bpp": 32,
+ "desktop": [
+ 1280,
+ 800
+ ],
+ "success": true,
+ "error": null,
+ "stop": null,
+ "model_calls": 0,
+ "rung_counts": {
+ "template": 5
+ },
+ "db_outcome": "correct",
+ "note_holders": [
+ 1
+ ],
+ "class": "verified_save",
+ "must_save": true,
+ "elapsed_s": 4.34,
+ "held_for_load_s": 0.0,
+ "load1_start": 14.3,
+ "load1_end": 14.3,
+ "first_frame_sha256": "1be90849066a718f5cce4cc148bdf27c3a2a141095f212e7743a36cb2d38562c"
+ },
+ {
+ "trial": 12,
+ "condition": "healthy",
+ "drift": "none",
+ "bpp": 32,
+ "desktop": [
+ 1280,
+ 800
+ ],
+ "success": true,
+ "error": null,
+ "stop": null,
+ "model_calls": 0,
+ "rung_counts": {
+ "template": 5
+ },
+ "db_outcome": "correct",
+ "note_holders": [
+ 1
+ ],
+ "class": "verified_save",
+ "must_save": true,
+ "elapsed_s": 9.87,
+ "held_for_load_s": 0.0,
+ "load1_start": 12.0,
+ "load1_end": 11.6,
+ "first_frame_sha256": "6efd1eeff5c5e1f5365b4732c539006f7d866655d45aa1e89b3846c142dbfbdb"
+ },
+ {
+ "trial": 13,
+ "condition": "healthy",
+ "drift": "none",
+ "bpp": 32,
+ "desktop": [
+ 1280,
+ 800
+ ],
+ "success": true,
+ "error": null,
+ "stop": null,
+ "model_calls": 0,
+ "rung_counts": {
+ "template": 5
+ },
+ "db_outcome": "correct",
+ "note_holders": [
+ 1
+ ],
+ "class": "verified_save",
+ "must_save": true,
+ "elapsed_s": 5.46,
+ "held_for_load_s": 0.0,
+ "load1_start": 10.1,
+ "load1_end": 9.8,
+ "first_frame_sha256": "6efd1eeff5c5e1f5365b4732c539006f7d866655d45aa1e89b3846c142dbfbdb"
+ },
+ {
+ "trial": 14,
+ "condition": "healthy",
+ "drift": "none",
+ "bpp": 32,
+ "desktop": [
+ 1280,
+ 800
+ ],
+ "success": true,
+ "error": null,
+ "stop": null,
+ "model_calls": 0,
+ "rung_counts": {
+ "template": 5
+ },
+ "db_outcome": "correct",
+ "note_holders": [
+ 1
+ ],
+ "class": "verified_save",
+ "must_save": true,
+ "elapsed_s": 12.7,
+ "held_for_load_s": 0.0,
+ "load1_start": 8.8,
+ "load1_end": 10.7,
+ "first_frame_sha256": "3d032acaceecd8e38a82341c9669fa1c12e82d75f2e4f5608c588e0e80564014"
+ },
+ {
+ "trial": 15,
+ "condition": "healthy",
+ "drift": "none",
+ "bpp": 32,
+ "desktop": [
+ 1280,
+ 800
+ ],
+ "success": true,
+ "error": null,
+ "stop": null,
+ "model_calls": 0,
+ "rung_counts": {
+ "template": 5
+ },
+ "db_outcome": "correct",
+ "note_holders": [
+ 1
+ ],
+ "class": "verified_save",
+ "must_save": true,
+ "elapsed_s": 18.8,
+ "held_for_load_s": 0.0,
+ "load1_start": 10.4,
+ "load1_end": 11.9,
+ "first_frame_sha256": "54e23368b9ce584ac10a5ab94b541a15e70adb38c76d56d8470ba2c8bdbf88c0"
+ },
+ {
+ "trial": 16,
+ "condition": "healthy",
+ "drift": "none",
+ "bpp": 32,
+ "desktop": [
+ 1280,
+ 800
+ ],
+ "success": true,
+ "error": null,
+ "stop": null,
+ "model_calls": 0,
+ "rung_counts": {
+ "template": 5
+ },
+ "db_outcome": "correct",
+ "note_holders": [
+ 1
+ ],
+ "class": "verified_save",
+ "must_save": true,
+ "elapsed_s": 14.56,
+ "held_for_load_s": 0.0,
+ "load1_start": 10.9,
+ "load1_end": 14.0,
+ "first_frame_sha256": "3638491667bffca60fd1f2fa7710648fdfe1ae1c67c12659d02bdae146ae6fb6"
+ },
+ {
+ "trial": 17,
+ "condition": "healthy",
+ "drift": "none",
+ "bpp": 32,
+ "desktop": [
+ 1280,
+ 800
+ ],
+ "success": true,
+ "error": null,
+ "stop": null,
+ "model_calls": 0,
+ "rung_counts": {
+ "template": 5
+ },
+ "db_outcome": "correct",
+ "note_holders": [
+ 1
+ ],
+ "class": "verified_save",
+ "must_save": true,
+ "elapsed_s": 16.29,
+ "held_for_load_s": 0.0,
+ "load1_start": 12.5,
+ "load1_end": 14.0,
+ "first_frame_sha256": "032ef87cf2957716de6a8b871dda46f3cd813a2dfc87973eff1d2e4ee8553cd1"
+ },
+ {
+ "trial": 18,
+ "condition": "healthy",
+ "drift": "none",
+ "bpp": 32,
+ "desktop": [
+ 1280,
+ 800
+ ],
+ "success": true,
+ "error": null,
+ "stop": null,
+ "model_calls": 0,
+ "rung_counts": {
+ "template": 5
+ },
+ "db_outcome": "correct",
+ "note_holders": [
+ 1
+ ],
+ "class": "verified_save",
+ "must_save": true,
+ "elapsed_s": 5.63,
+ "held_for_load_s": 0.0,
+ "load1_start": 13.5,
+ "load1_end": 12.9,
+ "first_frame_sha256": "032ef87cf2957716de6a8b871dda46f3cd813a2dfc87973eff1d2e4ee8553cd1"
+ },
+ {
+ "trial": 19,
+ "condition": "healthy",
+ "drift": "none",
+ "bpp": 32,
+ "desktop": [
+ 1280,
+ 800
+ ],
+ "success": true,
+ "error": null,
+ "stop": null,
+ "model_calls": 0,
+ "rung_counts": {
+ "template": 5
+ },
+ "db_outcome": "correct",
+ "note_holders": [
+ 1
+ ],
+ "class": "verified_save",
+ "must_save": true,
+ "elapsed_s": 17.4,
+ "held_for_load_s": 0.0,
+ "load1_start": 11.3,
+ "load1_end": 13.4,
+ "first_frame_sha256": "0d462bfab8747976fbe4f8cfa9db7a72a3b6674c8a5e3f54d9cf2299d10ace18"
+ },
+ {
+ "trial": 20,
+ "condition": "healthy",
+ "drift": "none",
+ "bpp": 32,
+ "desktop": [
+ 1280,
+ 800
+ ],
+ "success": true,
+ "error": null,
+ "stop": null,
+ "model_calls": 0,
+ "rung_counts": {
+ "template": 5
+ },
+ "db_outcome": "correct",
+ "note_holders": [
+ 1
+ ],
+ "class": "verified_save",
+ "must_save": true,
+ "elapsed_s": 20.1,
+ "held_for_load_s": 0.0,
+ "load1_start": 12.4,
+ "load1_end": 14.2,
+ "first_frame_sha256": "9869b27a11a9f65c081797938b6600c424957f2920d2d2924ab50e62327bf76b"
+ },
+ {
+ "trial": 21,
+ "condition": "reorder",
+ "drift": "reorder",
+ "bpp": 32,
+ "desktop": [
+ 1280,
+ 800
+ ],
+ "success": true,
+ "error": null,
+ "stop": null,
+ "model_calls": 0,
+ "rung_counts": {
+ "template": 5
+ },
+ "db_outcome": "correct",
+ "note_holders": [
+ 1
+ ],
+ "class": "verified_save",
+ "must_save": true,
+ "elapsed_s": 29.8,
+ "held_for_load_s": 0.0,
+ "load1_start": 12.8,
+ "load1_end": 17.9,
+ "first_frame_sha256": "aaa1763a8aae017afca65e61bbb84a5072eca3b3efc18a087dae47c25642134a"
+ },
+ {
+ "trial": 22,
+ "condition": "reorder",
+ "drift": "reorder",
+ "bpp": 32,
+ "desktop": [
+ 1280,
+ 800
+ ],
+ "success": true,
+ "error": null,
+ "stop": null,
+ "model_calls": 0,
+ "rung_counts": {
+ "template": 5
+ },
+ "db_outcome": "correct",
+ "note_holders": [
+ 1
+ ],
+ "class": "verified_save",
+ "must_save": true,
+ "elapsed_s": 18.47,
+ "held_for_load_s": 0.0,
+ "load1_start": 14.2,
+ "load1_end": 19.6,
+ "first_frame_sha256": "9dd1ca36489fd6f9369849490269f3c82b767ffd04e110edb2a0bea721ca1482"
+ },
+ {
+ "trial": 23,
+ "condition": "reorder",
+ "drift": "reorder",
+ "bpp": 32,
+ "desktop": [
+ 1280,
+ 800
+ ],
+ "success": true,
+ "error": null,
+ "stop": null,
+ "model_calls": 0,
+ "rung_counts": {
+ "template": 5
+ },
+ "db_outcome": "correct",
+ "note_holders": [
+ 1
+ ],
+ "class": "verified_save",
+ "must_save": true,
+ "elapsed_s": 4.77,
+ "held_for_load_s": 0.0,
+ "load1_start": 20.8,
+ "load1_end": 19.7,
+ "first_frame_sha256": "d6532ab00c76fb284761f10aff96855cb4e17d454e2a9451c5f647ca1a13158e"
+ },
+ {
+ "trial": 24,
+ "condition": "reorder",
+ "drift": "reorder",
+ "bpp": 32,
+ "desktop": [
+ 1280,
+ 800
+ ],
+ "success": true,
+ "error": null,
+ "stop": null,
+ "model_calls": 0,
+ "rung_counts": {
+ "template": 5
+ },
+ "db_outcome": "correct",
+ "note_holders": [
+ 1
+ ],
+ "class": "verified_save",
+ "must_save": true,
+ "elapsed_s": 10.61,
+ "held_for_load_s": 0.0,
+ "load1_start": 15.3,
+ "load1_end": 15.4,
+ "first_frame_sha256": "f25d058fe5ea904b7f138811a25c2c03b2104c3c4a292593773747c98ea26e14"
+ },
+ {
+ "trial": 25,
+ "condition": "reorder",
+ "drift": "reorder",
+ "bpp": 32,
+ "desktop": [
+ 1280,
+ 800
+ ],
+ "success": true,
+ "error": null,
+ "stop": null,
+ "model_calls": 0,
+ "rung_counts": {
+ "template": 5
+ },
+ "db_outcome": "correct",
+ "note_holders": [
+ 1
+ ],
+ "class": "verified_save",
+ "must_save": true,
+ "elapsed_s": 7.85,
+ "held_for_load_s": 0.0,
+ "load1_start": 12.2,
+ "load1_end": 12.2,
+ "first_frame_sha256": "e74087e6c581c6d24ba53b0e63bb5948c44db98dccb456ccf3e1701383fbc615"
+ },
+ {
+ "trial": 26,
+ "condition": "reorder",
+ "drift": "reorder",
+ "bpp": 32,
+ "desktop": [
+ 1280,
+ 800
+ ],
+ "success": true,
+ "error": null,
+ "stop": null,
+ "model_calls": 0,
+ "rung_counts": {
+ "template": 5
+ },
+ "db_outcome": "correct",
+ "note_holders": [
+ 1
+ ],
+ "class": "verified_save",
+ "must_save": true,
+ "elapsed_s": 32.56,
+ "held_for_load_s": 0.0,
+ "load1_start": 14.1,
+ "load1_end": 29.8,
+ "first_frame_sha256": "53a5fb2b19583e9649df2a9b1f4cdc197a724e4b630ecd8df32ba933c0a979bc"
+ },
+ {
+ "trial": 27,
+ "condition": "reorder",
+ "drift": "reorder",
+ "bpp": 32,
+ "desktop": [
+ 1280,
+ 800
+ ],
+ "success": true,
+ "error": null,
+ "stop": null,
+ "model_calls": 0,
+ "rung_counts": {
+ "template": 5
+ },
+ "db_outcome": "correct",
+ "note_holders": [
+ 1
+ ],
+ "class": "verified_save",
+ "must_save": true,
+ "elapsed_s": 24.6,
+ "held_for_load_s": 0.0,
+ "load1_start": 30.4,
+ "load1_end": 36.3,
+ "first_frame_sha256": "462cf98801e2cdd549888faceeffa35c9b9d6e2aca224fff361e4d8be2c9a261"
+ },
+ {
+ "trial": 28,
+ "condition": "reorder",
+ "drift": "reorder",
+ "bpp": 32,
+ "desktop": [
+ 1280,
+ 800
+ ],
+ "success": true,
+ "error": null,
+ "stop": null,
+ "model_calls": 0,
+ "rung_counts": {
+ "template": 5
+ },
+ "db_outcome": "correct",
+ "note_holders": [
+ 1
+ ],
+ "class": "verified_save",
+ "must_save": true,
+ "elapsed_s": 21.22,
+ "held_for_load_s": 0.0,
+ "load1_start": 32.2,
+ "load1_end": 31.1,
+ "first_frame_sha256": "3209eab0d5cb1524d6e3c6636e45ff840d2a5e920f16e436f05b647cf6aa23a8"
+ },
+ {
+ "trial": 29,
+ "condition": "reorder",
+ "drift": "reorder",
+ "bpp": 32,
+ "desktop": [
+ 1280,
+ 800
+ ],
+ "success": true,
+ "error": null,
+ "stop": null,
+ "model_calls": 0,
+ "rung_counts": {
+ "template": 5
+ },
+ "db_outcome": "correct",
+ "note_holders": [
+ 1
+ ],
+ "class": "verified_save",
+ "must_save": true,
+ "elapsed_s": 12.67,
+ "held_for_load_s": 0.0,
+ "load1_start": 25.0,
+ "load1_end": 23.6,
+ "first_frame_sha256": "79e286dd15e50fb21e5cd6ce270259e96af156365523101aed755e48eb23f830"
+ },
+ {
+ "trial": 30,
+ "condition": "reorder",
+ "drift": "reorder",
+ "bpp": 32,
+ "desktop": [
+ 1280,
+ 800
+ ],
+ "success": true,
+ "error": null,
+ "stop": null,
+ "model_calls": 0,
+ "rung_counts": {
+ "template": 5
+ },
+ "db_outcome": "correct",
+ "note_holders": [
+ 1
+ ],
+ "class": "verified_save",
+ "must_save": true,
+ "elapsed_s": 16.59,
+ "held_for_load_s": 0.0,
+ "load1_start": 18.2,
+ "load1_end": 17.9,
+ "first_frame_sha256": "fb072ff65163fcf3ed2386176a10605b887208762e865be674804488b0c527a1"
+ },
+ {
+ "trial": 31,
+ "condition": "bpp16",
+ "drift": "none",
+ "bpp": 16,
+ "desktop": [
+ 1280,
+ 800
+ ],
+ "success": true,
+ "error": null,
+ "stop": null,
+ "model_calls": 0,
+ "rung_counts": {
+ "template": 5
+ },
+ "db_outcome": "correct",
+ "note_holders": [
+ 1
+ ],
+ "class": "verified_save",
+ "must_save": true,
+ "elapsed_s": 17.63,
+ "held_for_load_s": 0.0,
+ "load1_start": 14.6,
+ "load1_end": 15.3,
+ "first_frame_sha256": "55d8e0fefc3b511325a05e1e0b9b6818730938ded090b1dba5e965876c5e2207"
+ },
+ {
+ "trial": 32,
+ "condition": "bpp16",
+ "drift": "none",
+ "bpp": 16,
+ "desktop": [
+ 1280,
+ 800
+ ],
+ "success": true,
+ "error": null,
+ "stop": null,
+ "model_calls": 0,
+ "rung_counts": {
+ "template": 5
+ },
+ "db_outcome": "correct",
+ "note_holders": [
+ 1
+ ],
+ "class": "verified_save",
+ "must_save": true,
+ "elapsed_s": 13.05,
+ "held_for_load_s": 0.0,
+ "load1_start": 13.3,
+ "load1_end": 16.0,
+ "first_frame_sha256": "1e9db5d05c0ff6cdcd658bd62c724507240e9780d6ee920d91b839da1095869a"
+ },
+ {
+ "trial": 33,
+ "condition": "bpp16",
+ "drift": "none",
+ "bpp": 16,
+ "desktop": [
+ 1280,
+ 800
+ ],
+ "success": true,
+ "error": null,
+ "stop": null,
+ "model_calls": 0,
+ "rung_counts": {
+ "template": 5
+ },
+ "db_outcome": "correct",
+ "note_holders": [
+ 1
+ ],
+ "class": "verified_save",
+ "must_save": true,
+ "elapsed_s": 16.96,
+ "held_for_load_s": 0.0,
+ "load1_start": 14.1,
+ "load1_end": 15.8,
+ "first_frame_sha256": "1e9db5d05c0ff6cdcd658bd62c724507240e9780d6ee920d91b839da1095869a"
+ },
+ {
+ "trial": 34,
+ "condition": "bpp16",
+ "drift": "none",
+ "bpp": 16,
+ "desktop": [
+ 1280,
+ 800
+ ],
+ "success": true,
+ "error": null,
+ "stop": null,
+ "model_calls": 0,
+ "rung_counts": {
+ "template": 5
+ },
+ "db_outcome": "correct",
+ "note_holders": [
+ 1
+ ],
+ "class": "verified_save",
+ "must_save": true,
+ "elapsed_s": 15.35,
+ "held_for_load_s": 0.0,
+ "load1_start": 12.7,
+ "load1_end": 12.3,
+ "first_frame_sha256": "cfe924fa107222b54bd26b3d0e526ade82c14b48b9aafe7f8788a731606bb585"
+ },
+ {
+ "trial": 35,
+ "condition": "bpp16",
+ "drift": "none",
+ "bpp": 16,
+ "desktop": [
+ 1280,
+ 800
+ ],
+ "success": true,
+ "error": null,
+ "stop": null,
+ "model_calls": 0,
+ "rung_counts": {
+ "template": 5
+ },
+ "db_outcome": "correct",
+ "note_holders": [
+ 1
+ ],
+ "class": "verified_save",
+ "must_save": true,
+ "elapsed_s": 6.17,
+ "held_for_load_s": 0.0,
+ "load1_start": 11.2,
+ "load1_end": 12.2,
+ "first_frame_sha256": "cfe924fa107222b54bd26b3d0e526ade82c14b48b9aafe7f8788a731606bb585"
+ },
+ {
+ "trial": 36,
+ "condition": "bpp16",
+ "drift": "none",
+ "bpp": 16,
+ "desktop": [
+ 1280,
+ 800
+ ],
+ "success": true,
+ "error": null,
+ "stop": null,
+ "model_calls": 0,
+ "rung_counts": {
+ "template": 5
+ },
+ "db_outcome": "correct",
+ "note_holders": [
+ 1
+ ],
+ "class": "verified_save",
+ "must_save": true,
+ "elapsed_s": 12.59,
+ "held_for_load_s": 0.0,
+ "load1_start": 10.6,
+ "load1_end": 11.3,
+ "first_frame_sha256": "2025905e76f28980c8a1ce137805a9334699a97982d7d09e9d459ef539f3fc0e"
+ },
+ {
+ "trial": 37,
+ "condition": "bpp16",
+ "drift": "none",
+ "bpp": 16,
+ "desktop": [
+ 1280,
+ 800
+ ],
+ "success": true,
+ "error": null,
+ "stop": null,
+ "model_calls": 0,
+ "rung_counts": {
+ "template": 5
+ },
+ "db_outcome": "correct",
+ "note_holders": [
+ 1
+ ],
+ "class": "verified_save",
+ "must_save": true,
+ "elapsed_s": 17.44,
+ "held_for_load_s": 0.0,
+ "load1_start": 9.8,
+ "load1_end": 10.9,
+ "first_frame_sha256": "7ffb5f2fe6aaf501116b92ad903401f77f80797616a4115707b1949f2de43ef0"
+ },
+ {
+ "trial": 38,
+ "condition": "bpp16",
+ "drift": "none",
+ "bpp": 16,
+ "desktop": [
+ 1280,
+ 800
+ ],
+ "success": true,
+ "error": null,
+ "stop": null,
+ "model_calls": 0,
+ "rung_counts": {
+ "template": 5
+ },
+ "db_outcome": "correct",
+ "note_holders": [
+ 1
+ ],
+ "class": "verified_save",
+ "must_save": true,
+ "elapsed_s": 18.53,
+ "held_for_load_s": 0.0,
+ "load1_start": 9.2,
+ "load1_end": 10.4,
+ "first_frame_sha256": "a3f5378f47528d492eac0234c4b82300f25ecf631b4a5861ef7275afbf63eb94"
+ },
+ {
+ "trial": 39,
+ "condition": "bpp16",
+ "drift": "none",
+ "bpp": 16,
+ "desktop": [
+ 1280,
+ 800
+ ],
+ "success": true,
+ "error": null,
+ "stop": null,
+ "model_calls": 0,
+ "rung_counts": {
+ "template": 5
+ },
+ "db_outcome": "correct",
+ "note_holders": [
+ 1
+ ],
+ "class": "verified_save",
+ "must_save": true,
+ "elapsed_s": 7.3,
+ "held_for_load_s": 0.0,
+ "load1_start": 9.9,
+ "load1_end": 10.2,
+ "first_frame_sha256": "a3f5378f47528d492eac0234c4b82300f25ecf631b4a5861ef7275afbf63eb94"
+ },
+ {
+ "trial": 40,
+ "condition": "bpp16",
+ "drift": "none",
+ "bpp": 16,
+ "desktop": [
+ 1280,
+ 800
+ ],
+ "success": true,
+ "error": null,
+ "stop": null,
+ "model_calls": 0,
+ "rung_counts": {
+ "template": 5
+ },
+ "db_outcome": "correct",
+ "note_holders": [
+ 1
+ ],
+ "class": "verified_save",
+ "must_save": true,
+ "elapsed_s": 37.04,
+ "held_for_load_s": 0.0,
+ "load1_start": 9.8,
+ "load1_end": 20.6,
+ "first_frame_sha256": "6c4f4d9ce11bf423eac7a15e0f131f1505e3816a5aa476931f3e01dcddd901d7"
+ },
+ {
+ "trial": 41,
+ "condition": "decoy",
+ "drift": "decoy",
+ "bpp": 32,
+ "desktop": [
+ 1280,
+ 800
+ ],
+ "success": false,
+ "error": null,
+ "stop": {
+ "step_id": "step_002",
+ "intent": "click 'Search'",
+ "error": "Postconditions failed for step 'step_002' (click 'Search'): expected screen state not reached (semantic drift) \u2014 failed: text_present 'Patient: Neil Sorenson (1984-03-12)' \u2014 run aborted",
+ "safety_halt": true
+ },
+ "model_calls": 0,
+ "rung_counts": {
+ "template": 1
+ },
+ "db_outcome": "no_write",
+ "note_holders": [],
+ "class": "false_stop",
+ "must_save": true,
+ "elapsed_s": 9.51,
+ "held_for_load_s": 0.0,
+ "load1_start": 17.2,
+ "load1_end": 15.8,
+ "first_frame_sha256": "7376ec499329d5b647e3deda60d2f70c223c054b96b13745f8fe56d1819ba70b"
+ },
+ {
+ "trial": 42,
+ "condition": "decoy",
+ "drift": "decoy",
+ "bpp": 32,
+ "desktop": [
+ 1280,
+ 800
+ ],
+ "success": false,
+ "error": null,
+ "stop": {
+ "step_id": "step_002",
+ "intent": "click 'Search'",
+ "error": "Postconditions failed for step 'step_002' (click 'Search'): expected screen state not reached (semantic drift) \u2014 failed: text_present 'Patient: Neil Sorenson (1984-03-12)' \u2014 run aborted",
+ "safety_halt": true
+ },
+ "model_calls": 0,
+ "rung_counts": {
+ "template": 1
+ },
+ "db_outcome": "no_write",
+ "note_holders": [],
+ "class": "false_stop",
+ "must_save": true,
+ "elapsed_s": 8.13,
+ "held_for_load_s": 0.0,
+ "load1_start": 13.8,
+ "load1_end": 13.6,
+ "first_frame_sha256": "7a4bf322fc988193c4f12704d556ce73d940474b9df7aebe3eeb3f53af622aac"
+ },
+ {
+ "trial": 43,
+ "condition": "decoy",
+ "drift": "decoy",
+ "bpp": 32,
+ "desktop": [
+ 1280,
+ 800
+ ],
+ "success": false,
+ "error": null,
+ "stop": {
+ "step_id": "step_002",
+ "intent": "click 'Search'",
+ "error": "Postconditions failed for step 'step_002' (click 'Search'): expected screen state not reached (semantic drift) \u2014 failed: text_present 'Patient: Neil Sorenson (1984-03-12)' \u2014 run aborted",
+ "safety_halt": true
+ },
+ "model_calls": 0,
+ "rung_counts": {
+ "template": 1
+ },
+ "db_outcome": "no_write",
+ "note_holders": [],
+ "class": "false_stop",
+ "must_save": true,
+ "elapsed_s": 9.99,
+ "held_for_load_s": 0.0,
+ "load1_start": 11.9,
+ "load1_end": 10.9,
+ "first_frame_sha256": "31342f86bff87ee95b0c680a9bef46a8e9553d217bc178c21e509d09b41abe4e"
+ },
+ {
+ "trial": 44,
+ "condition": "decoy",
+ "drift": "decoy",
+ "bpp": 32,
+ "desktop": [
+ 1280,
+ 800
+ ],
+ "success": false,
+ "error": null,
+ "stop": {
+ "step_id": "step_002",
+ "intent": "click 'Search'",
+ "error": "Postconditions failed for step 'step_002' (click 'Search'): expected screen state not reached (semantic drift) \u2014 failed: text_present 'Patient: Neil Sorenson (1984-03-12)' \u2014 run aborted",
+ "safety_halt": true
+ },
+ "model_calls": 0,
+ "rung_counts": {
+ "template": 1
+ },
+ "db_outcome": "no_write",
+ "note_holders": [],
+ "class": "false_stop",
+ "must_save": true,
+ "elapsed_s": 9.28,
+ "held_for_load_s": 0.0,
+ "load1_start": 10.3,
+ "load1_end": 13.1,
+ "first_frame_sha256": "2a4d50ac7a4940e16970b3c1ddb9757b7c568147a3751aee48df676923b32f51"
+ },
+ {
+ "trial": 45,
+ "condition": "decoy",
+ "drift": "decoy",
+ "bpp": 32,
+ "desktop": [
+ 1280,
+ 800
+ ],
+ "success": false,
+ "error": null,
+ "stop": {
+ "step_id": "step_002",
+ "intent": "click 'Search'",
+ "error": "Postconditions failed for step 'step_002' (click 'Search'): expected screen state not reached (semantic drift) \u2014 failed: text_present 'Patient: Neil Sorenson (1984-03-12)' \u2014 run aborted",
+ "safety_halt": true
+ },
+ "model_calls": 0,
+ "rung_counts": {
+ "template": 1
+ },
+ "db_outcome": "no_write",
+ "note_holders": [],
+ "class": "false_stop",
+ "must_save": true,
+ "elapsed_s": 19.97,
+ "held_for_load_s": 0.0,
+ "load1_start": 11.7,
+ "load1_end": 21.6,
+ "first_frame_sha256": "d4e4626596d9da4caff1aaf33b42f4e0f42782ec7eaec2a6fb6c7965849d6c29"
+ },
+ {
+ "trial": 46,
+ "condition": "decoy",
+ "drift": "decoy",
+ "bpp": 32,
+ "desktop": [
+ 1280,
+ 800
+ ],
+ "success": false,
+ "error": null,
+ "stop": {
+ "step_id": "step_002",
+ "intent": "click 'Search'",
+ "error": "Postconditions failed for step 'step_002' (click 'Search'): expected screen state not reached (semantic drift) \u2014 failed: text_present 'Patient: Neil Sorenson (1984-03-12)' \u2014 run aborted",
+ "safety_halt": true
+ },
+ "model_calls": 0,
+ "rung_counts": {
+ "template": 1
+ },
+ "db_outcome": "no_write",
+ "note_holders": [],
+ "class": "false_stop",
+ "must_save": true,
+ "elapsed_s": 7.47,
+ "held_for_load_s": 0.0,
+ "load1_start": 24.0,
+ "load1_end": 26.4,
+ "first_frame_sha256": "e5a0e8541751c489e3b493d620ab096f07e12e1d4b4c14277c5b20416ed72e46"
+ },
+ {
+ "trial": 47,
+ "condition": "decoy",
+ "drift": "decoy",
+ "bpp": 32,
+ "desktop": [
+ 1280,
+ 800
+ ],
+ "success": false,
+ "error": null,
+ "stop": {
+ "step_id": "step_002",
+ "intent": "click 'Search'",
+ "error": "Postconditions failed for step 'step_002' (click 'Search'): expected screen state not reached (semantic drift) \u2014 failed: text_present 'Patient: Neil Sorenson (1984-03-12)' \u2014 run aborted",
+ "safety_halt": true
+ },
+ "model_calls": 0,
+ "rung_counts": {
+ "template": 1
+ },
+ "db_outcome": "no_write",
+ "note_holders": [],
+ "class": "false_stop",
+ "must_save": true,
+ "elapsed_s": 12.29,
+ "held_for_load_s": 0.0,
+ "load1_start": 26.2,
+ "load1_end": 25.7,
+ "first_frame_sha256": "4129eb96af62aa0ba3898148ba67aa3990554930843cfaaf6db79b3e0d8a1486"
+ },
+ {
+ "trial": 48,
+ "condition": "decoy",
+ "drift": "decoy",
+ "bpp": 32,
+ "desktop": [
+ 1280,
+ 800
+ ],
+ "success": false,
+ "error": null,
+ "stop": {
+ "step_id": "step_002",
+ "intent": "click 'Search'",
+ "error": "Postconditions failed for step 'step_002' (click 'Search'): expected screen state not reached (semantic drift) \u2014 failed: text_present 'Patient: Neil Sorenson (1984-03-12)' \u2014 run aborted",
+ "safety_halt": true
+ },
+ "model_calls": 0,
+ "rung_counts": {
+ "template": 1
+ },
+ "db_outcome": "no_write",
+ "note_holders": [],
+ "class": "false_stop",
+ "must_save": true,
+ "elapsed_s": 27.42,
+ "held_for_load_s": 0.0,
+ "load1_start": 21.6,
+ "load1_end": 24.8,
+ "first_frame_sha256": "5efc1bc4e8b4c3beeabd812ebf39a53f87703ceb74739c2477b0424c0ea4241e"
+ },
+ {
+ "trial": 49,
+ "condition": "decoy",
+ "drift": "decoy",
+ "bpp": 32,
+ "desktop": [
+ 1280,
+ 800
+ ],
+ "success": false,
+ "error": null,
+ "stop": {
+ "step_id": "step_002",
+ "intent": "click 'Search'",
+ "error": "Postconditions failed for step 'step_002' (click 'Search'): expected screen state not reached (semantic drift) \u2014 failed: text_present 'Patient: Neil Sorenson (1984-03-12)' \u2014 run aborted",
+ "safety_halt": true
+ },
+ "model_calls": 0,
+ "rung_counts": {
+ "template": 1
+ },
+ "db_outcome": "no_write",
+ "note_holders": [],
+ "class": "false_stop",
+ "must_save": true,
+ "elapsed_s": 20.07,
+ "held_for_load_s": 0.0,
+ "load1_start": 22.7,
+ "load1_end": 24.0,
+ "first_frame_sha256": "a830c43a4e0b1a5c6d854694d495b7b543726c74671137ee4223e044f5349578"
+ },
+ {
+ "trial": 50,
+ "condition": "decoy",
+ "drift": "decoy",
+ "bpp": 32,
+ "desktop": [
+ 1280,
+ 800
+ ],
+ "success": false,
+ "error": null,
+ "stop": {
+ "step_id": "step_002",
+ "intent": "click 'Search'",
+ "error": "Postconditions failed for step 'step_002' (click 'Search'): expected screen state not reached (semantic drift) \u2014 failed: text_present 'Patient: Neil Sorenson (1984-03-12)' \u2014 run aborted",
+ "safety_halt": true
+ },
+ "model_calls": 0,
+ "rung_counts": {
+ "template": 1
+ },
+ "db_outcome": "no_write",
+ "note_holders": [],
+ "class": "false_stop",
+ "must_save": true,
+ "elapsed_s": 20.09,
+ "held_for_load_s": 0.0,
+ "load1_start": 20.2,
+ "load1_end": 19.8,
+ "first_frame_sha256": "3330413bc91a78f32e71bcdf2fe978a080b987226b24a49e20c379535557b067"
+ },
+ {
+ "trial": 51,
+ "condition": "siblings",
+ "drift": "siblings",
+ "bpp": 32,
+ "desktop": [
+ 1280,
+ 800
+ ],
+ "success": false,
+ "error": null,
+ "stop": {
+ "step_id": "step_003",
+ "intent": "click 'Neil'",
+ "error": "Identity check failed for step 'step_003' (click 'Neil'): a target was found positionally (rung 'ocr', confidence 1.00) but its surrounding text does not match the recorded target's \u2014 expected 'recorded identifier crop', observed 'identifier pixels differ locally (spike 0.076, floor 0.000) \u2014 a different identifier' (coverage 0.00) \u2014 refusing to act; run aborted",
+ "safety_halt": true
+ },
+ "model_calls": 0,
+ "rung_counts": {
+ "template": 2
+ },
+ "db_outcome": "no_write",
+ "note_holders": [],
+ "class": "stop_on_lookalike",
+ "must_save": false,
+ "elapsed_s": 12.8,
+ "held_for_load_s": 0.0,
+ "load1_start": 18.1,
+ "load1_end": 17.9,
+ "first_frame_sha256": "f18221fda96233a3aaf2d8d1e26854c30754146b96e664245357ea87102e13b0"
+ },
+ {
+ "trial": 52,
+ "condition": "siblings",
+ "drift": "siblings",
+ "bpp": 32,
+ "desktop": [
+ 1280,
+ 800
+ ],
+ "success": false,
+ "error": null,
+ "stop": {
+ "step_id": "step_003",
+ "intent": "click 'Neil'",
+ "error": "Identity check failed for step 'step_003' (click 'Neil'): a target was found positionally (rung 'ocr', confidence 1.00) but its surrounding text does not match the recorded target's \u2014 expected 'recorded identifier crop', observed 'identifier pixels differ locally (spike 0.076, floor 0.000) \u2014 a different identifier' (coverage 0.00) \u2014 refusing to act; run aborted",
+ "safety_halt": true
+ },
+ "model_calls": 0,
+ "rung_counts": {
+ "template": 2
+ },
+ "db_outcome": "no_write",
+ "note_holders": [],
+ "class": "stop_on_lookalike",
+ "must_save": false,
+ "elapsed_s": 7.35,
+ "held_for_load_s": 0.0,
+ "load1_start": 15.2,
+ "load1_end": 15.3,
+ "first_frame_sha256": "2c5334214ba4120c48a5edee527d2f27be06b985a3e92427d0d44cec8ebf342c"
+ },
+ {
+ "trial": 53,
+ "condition": "siblings",
+ "drift": "siblings",
+ "bpp": 32,
+ "desktop": [
+ 1280,
+ 800
+ ],
+ "success": false,
+ "error": null,
+ "stop": {
+ "step_id": "step_003",
+ "intent": "click 'Neil'",
+ "error": "Identity check failed for step 'step_003' (click 'Neil'): a target was found positionally (rung 'ocr', confidence 1.00) but its surrounding text does not match the recorded target's \u2014 expected 'recorded identifier crop', observed 'identifier pixels differ locally (spike 0.076, floor 0.000) \u2014 a different identifier' (coverage 0.00) \u2014 refusing to act; run aborted",
+ "safety_halt": true
+ },
+ "model_calls": 0,
+ "rung_counts": {
+ "template": 2
+ },
+ "db_outcome": "no_write",
+ "note_holders": [],
+ "class": "stop_on_lookalike",
+ "must_save": false,
+ "elapsed_s": 11.91,
+ "held_for_load_s": 0.0,
+ "load1_start": 13.1,
+ "load1_end": 14.1,
+ "first_frame_sha256": "03eb807636505daea595546a80c39f1e781a6bfa1d8014ccd3b340514fbb4f33"
+ },
+ {
+ "trial": 54,
+ "condition": "siblings",
+ "drift": "siblings",
+ "bpp": 32,
+ "desktop": [
+ 1280,
+ 800
+ ],
+ "success": false,
+ "error": null,
+ "stop": {
+ "step_id": "step_003",
+ "intent": "click 'Neil'",
+ "error": "Identity check failed for step 'step_003' (click 'Neil'): a target was found positionally (rung 'ocr', confidence 1.00) but its surrounding text does not match the recorded target's \u2014 expected 'recorded identifier crop', observed 'identifier pixels differ locally (spike 0.076, floor 0.000) \u2014 a different identifier' (coverage 0.00) \u2014 refusing to act; run aborted",
+ "safety_halt": true
+ },
+ "model_calls": 0,
+ "rung_counts": {
+ "template": 2
+ },
+ "db_outcome": "no_write",
+ "note_holders": [],
+ "class": "stop_on_lookalike",
+ "must_save": false,
+ "elapsed_s": 19.89,
+ "held_for_load_s": 0.0,
+ "load1_start": 14.2,
+ "load1_end": 15.7,
+ "first_frame_sha256": "2620438ab895c03656955a027e3f66ca7dd8a4fa830f31808ae1d7971eddc8a6"
+ },
+ {
+ "trial": 55,
+ "condition": "siblings",
+ "drift": "siblings",
+ "bpp": 32,
+ "desktop": [
+ 1280,
+ 800
+ ],
+ "success": false,
+ "error": null,
+ "stop": {
+ "step_id": "step_003",
+ "intent": "click 'Neil'",
+ "error": "Identity check failed for step 'step_003' (click 'Neil'): a target was found positionally (rung 'ocr', confidence 1.00) but its surrounding text does not match the recorded target's \u2014 expected 'recorded identifier crop', observed 'identifier pixels differ locally (spike 0.076, floor 0.000) \u2014 a different identifier' (coverage 0.00) \u2014 refusing to act; run aborted",
+ "safety_halt": true
+ },
+ "model_calls": 0,
+ "rung_counts": {
+ "template": 2
+ },
+ "db_outcome": "no_write",
+ "note_holders": [],
+ "class": "stop_on_lookalike",
+ "must_save": false,
+ "elapsed_s": 14.17,
+ "held_for_load_s": 0.0,
+ "load1_start": 16.2,
+ "load1_end": 15.4,
+ "first_frame_sha256": "191555670add161f5e49974350decd40a187d3407759e3520478cda7666d3128"
+ },
+ {
+ "trial": 56,
+ "condition": "siblings",
+ "drift": "siblings",
+ "bpp": 32,
+ "desktop": [
+ 1280,
+ 800
+ ],
+ "success": false,
+ "error": null,
+ "stop": {
+ "step_id": "step_003",
+ "intent": "click 'Neil'",
+ "error": "Identity check failed for step 'step_003' (click 'Neil'): a target was found positionally (rung 'ocr', confidence 1.00) but its surrounding text does not match the recorded target's \u2014 expected 'recorded identifier crop', observed 'identifier pixels differ locally (spike 0.076, floor 0.000) \u2014 a different identifier' (coverage 0.00) \u2014 refusing to act; run aborted",
+ "safety_halt": true
+ },
+ "model_calls": 0,
+ "rung_counts": {
+ "template": 2
+ },
+ "db_outcome": "no_write",
+ "note_holders": [],
+ "class": "stop_on_lookalike",
+ "must_save": false,
+ "elapsed_s": 3.28,
+ "held_for_load_s": 0.0,
+ "load1_start": 13.6,
+ "load1_end": 13.6,
+ "first_frame_sha256": "86729f7ea144c6bcb703b044274f7e074595539e374f9c606076886bca5d164a"
+ },
+ {
+ "trial": 57,
+ "condition": "siblings",
+ "drift": "siblings",
+ "bpp": 32,
+ "desktop": [
+ 1280,
+ 800
+ ],
+ "success": false,
+ "error": null,
+ "stop": {
+ "step_id": "step_003",
+ "intent": "click 'Neil'",
+ "error": "Identity check failed for step 'step_003' (click 'Neil'): a target was found positionally (rung 'ocr', confidence 1.00) but its surrounding text does not match the recorded target's \u2014 expected 'recorded identifier crop', observed 'identifier pixels differ locally (spike 0.076, floor 0.000) \u2014 a different identifier' (coverage 0.00) \u2014 refusing to act; run aborted",
+ "safety_halt": true
+ },
+ "model_calls": 0,
+ "rung_counts": {
+ "template": 2
+ },
+ "db_outcome": "no_write",
+ "note_holders": [],
+ "class": "stop_on_lookalike",
+ "must_save": false,
+ "elapsed_s": 4.37,
+ "held_for_load_s": 0.0,
+ "load1_start": 13.4,
+ "load1_end": 13.1,
+ "first_frame_sha256": "bc538713640309f2921d06755d5473cca0a2f535ad91265f7b7540cb3f4da114"
+ },
+ {
+ "trial": 58,
+ "condition": "siblings",
+ "drift": "siblings",
+ "bpp": 32,
+ "desktop": [
+ 1280,
+ 800
+ ],
+ "success": false,
+ "error": null,
+ "stop": {
+ "step_id": "step_003",
+ "intent": "click 'Neil'",
+ "error": "Identity check failed for step 'step_003' (click 'Neil'): a target was found positionally (rung 'ocr', confidence 1.00) but its surrounding text does not match the recorded target's \u2014 expected 'recorded identifier crop', observed 'identifier pixels differ locally (spike 0.076, floor 0.000) \u2014 a different identifier' (coverage 0.00) \u2014 refusing to act; run aborted",
+ "safety_halt": true
+ },
+ "model_calls": 0,
+ "rung_counts": {
+ "template": 2
+ },
+ "db_outcome": "no_write",
+ "note_holders": [],
+ "class": "stop_on_lookalike",
+ "must_save": false,
+ "elapsed_s": 9.56,
+ "held_for_load_s": 0.0,
+ "load1_start": 12.9,
+ "load1_end": 13.1,
+ "first_frame_sha256": "dc2c36c5e79a79fcfaa1ec4559674b8eb18611fff18dcf5fec08a9527d7cdc27"
+ },
+ {
+ "trial": 59,
+ "condition": "siblings",
+ "drift": "siblings",
+ "bpp": 32,
+ "desktop": [
+ 1280,
+ 800
+ ],
+ "success": false,
+ "error": null,
+ "stop": {
+ "step_id": "step_003",
+ "intent": "click 'Neil'",
+ "error": "Identity check failed for step 'step_003' (click 'Neil'): a target was found positionally (rung 'ocr', confidence 1.00) but its surrounding text does not match the recorded target's \u2014 expected 'recorded identifier crop', observed 'identifier pixels differ locally (spike 0.076, floor 0.000) \u2014 a different identifier' (coverage 0.00) \u2014 refusing to act; run aborted",
+ "safety_halt": true
+ },
+ "model_calls": 0,
+ "rung_counts": {
+ "template": 2
+ },
+ "db_outcome": "no_write",
+ "note_holders": [],
+ "class": "stop_on_lookalike",
+ "must_save": false,
+ "elapsed_s": 3.53,
+ "held_for_load_s": 0.0,
+ "load1_start": 11.3,
+ "load1_end": 12.8,
+ "first_frame_sha256": "38e2fe075a0914359225a9404da760c77f555db59e980221dbd9d609aef168c0"
+ },
+ {
+ "trial": 60,
+ "condition": "siblings",
+ "drift": "siblings",
+ "bpp": 32,
+ "desktop": [
+ 1280,
+ 800
+ ],
+ "success": false,
+ "error": null,
+ "stop": {
+ "step_id": "step_003",
+ "intent": "click 'Neil'",
+ "error": "Identity check failed for step 'step_003' (click 'Neil'): a target was found positionally (rung 'ocr', confidence 1.00) but its surrounding text does not match the recorded target's \u2014 expected 'recorded identifier crop', observed 'identifier pixels differ locally (spike 0.076, floor 0.000) \u2014 a different identifier' (coverage 0.00) \u2014 refusing to act; run aborted",
+ "safety_halt": true
+ },
+ "model_calls": 0,
+ "rung_counts": {
+ "template": 2
+ },
+ "db_outcome": "no_write",
+ "note_holders": [],
+ "class": "stop_on_lookalike",
+ "must_save": false,
+ "elapsed_s": 18.41,
+ "held_for_load_s": 0.0,
+ "load1_start": 14.7,
+ "load1_end": 18.3,
+ "first_frame_sha256": "a1c2ffaa182d63ee625ef2e69dc9d31f6a6085ae4fae5b83b5af2bf8949fa3c9"
+ },
+ {
+ "trial": 61,
+ "condition": "desktop1440",
+ "drift": "none",
+ "bpp": 32,
+ "desktop": [
+ 1440,
+ 900
+ ],
+ "success": false,
+ "error": null,
+ "stop": {
+ "step_id": "step_000",
+ "intent": "click recorded visual target",
+ "error": "Layout drift before step 'step_000' (click recorded visual target): resolution_changed: frame is 1440x900, recorded 1280x800 \u2014 the screen no longer matches the recording; refusing to act.",
+ "safety_halt": true
+ },
+ "model_calls": 0,
+ "rung_counts": {},
+ "db_outcome": "no_write",
+ "note_holders": [],
+ "class": "false_stop",
+ "must_save": true,
+ "elapsed_s": 2.84,
+ "held_for_load_s": 0.0,
+ "load1_start": 15.6,
+ "load1_end": 15.6,
+ "first_frame_sha256": "85d993a2668ae62a60ca0bdba701dd678350421746cb909f883336176ae70492"
+ },
+ {
+ "trial": 62,
+ "condition": "desktop1440",
+ "drift": "none",
+ "bpp": 32,
+ "desktop": [
+ 1440,
+ 900
+ ],
+ "success": false,
+ "error": null,
+ "stop": {
+ "step_id": "step_000",
+ "intent": "click recorded visual target",
+ "error": "Layout drift before step 'step_000' (click recorded visual target): resolution_changed: frame is 1440x900, recorded 1280x800 \u2014 the screen no longer matches the recording; refusing to act.",
+ "safety_halt": true
+ },
+ "model_calls": 0,
+ "rung_counts": {},
+ "db_outcome": "no_write",
+ "note_holders": [],
+ "class": "false_stop",
+ "must_save": true,
+ "elapsed_s": 3.11,
+ "held_for_load_s": 0.0,
+ "load1_start": 14.2,
+ "load1_end": 14.6,
+ "first_frame_sha256": "092dc62acee5763bc62bd8857710088f55cc7fccea5c388aaaf7ab48ad5172cb"
+ },
+ {
+ "trial": 63,
+ "condition": "desktop1440",
+ "drift": "none",
+ "bpp": 32,
+ "desktop": [
+ 1440,
+ 900
+ ],
+ "success": false,
+ "error": null,
+ "stop": {
+ "step_id": "step_000",
+ "intent": "click recorded visual target",
+ "error": "Layout drift before step 'step_000' (click recorded visual target): resolution_changed: frame is 1440x900, recorded 1280x800 \u2014 the screen no longer matches the recording; refusing to act.",
+ "safety_halt": true
+ },
+ "model_calls": 0,
+ "rung_counts": {},
+ "db_outcome": "no_write",
+ "note_holders": [],
+ "class": "false_stop",
+ "must_save": true,
+ "elapsed_s": 0.26,
+ "held_for_load_s": 0.0,
+ "load1_start": 13.1,
+ "load1_end": 13.1,
+ "first_frame_sha256": "092dc62acee5763bc62bd8857710088f55cc7fccea5c388aaaf7ab48ad5172cb"
+ },
+ {
+ "trial": 64,
+ "condition": "desktop1440",
+ "drift": "none",
+ "bpp": 32,
+ "desktop": [
+ 1440,
+ 900
+ ],
+ "success": false,
+ "error": null,
+ "stop": {
+ "step_id": "step_000",
+ "intent": "click recorded visual target",
+ "error": "Layout drift before step 'step_000' (click recorded visual target): resolution_changed: frame is 1440x900, recorded 1280x800 \u2014 the screen no longer matches the recording; refusing to act.",
+ "safety_halt": true
+ },
+ "model_calls": 0,
+ "rung_counts": {},
+ "db_outcome": "no_write",
+ "note_holders": [],
+ "class": "false_stop",
+ "must_save": true,
+ "elapsed_s": 0.22,
+ "held_for_load_s": 0.0,
+ "load1_start": 15.3,
+ "load1_end": 15.3,
+ "first_frame_sha256": "092dc62acee5763bc62bd8857710088f55cc7fccea5c388aaaf7ab48ad5172cb"
+ },
+ {
+ "trial": 65,
+ "condition": "desktop1440",
+ "drift": "none",
+ "bpp": 32,
+ "desktop": [
+ 1440,
+ 900
+ ],
+ "success": false,
+ "error": null,
+ "stop": {
+ "step_id": "step_000",
+ "intent": "click recorded visual target",
+ "error": "Layout drift before step 'step_000' (click recorded visual target): resolution_changed: frame is 1440x900, recorded 1280x800 \u2014 the screen no longer matches the recording; refusing to act.",
+ "safety_halt": true
+ },
+ "model_calls": 0,
+ "rung_counts": {},
+ "db_outcome": "no_write",
+ "note_holders": [],
+ "class": "false_stop",
+ "must_save": true,
+ "elapsed_s": 0.22,
+ "held_for_load_s": 0.0,
+ "load1_start": 16.3,
+ "load1_end": 16.3,
+ "first_frame_sha256": "092dc62acee5763bc62bd8857710088f55cc7fccea5c388aaaf7ab48ad5172cb"
+ },
+ {
+ "trial": 66,
+ "condition": "desktop1440",
+ "drift": "none",
+ "bpp": 32,
+ "desktop": [
+ 1440,
+ 900
+ ],
+ "success": false,
+ "error": null,
+ "stop": {
+ "step_id": "step_000",
+ "intent": "click recorded visual target",
+ "error": "Layout drift before step 'step_000' (click recorded visual target): resolution_changed: frame is 1440x900, recorded 1280x800 \u2014 the screen no longer matches the recording; refusing to act.",
+ "safety_halt": true
+ },
+ "model_calls": 0,
+ "rung_counts": {},
+ "db_outcome": "no_write",
+ "note_holders": [],
+ "class": "false_stop",
+ "must_save": true,
+ "elapsed_s": 1.8,
+ "held_for_load_s": 0.0,
+ "load1_start": 14.8,
+ "load1_end": 14.8,
+ "first_frame_sha256": "0f484f622c21a98780f26f39cdddcfaa7c101ea138694d1417fbb52b46b0ac5f"
+ },
+ {
+ "trial": 67,
+ "condition": "desktop1440",
+ "drift": "none",
+ "bpp": 32,
+ "desktop": [
+ 1440,
+ 900
+ ],
+ "success": false,
+ "error": null,
+ "stop": {
+ "step_id": "step_000",
+ "intent": "click recorded visual target",
+ "error": "Layout drift before step 'step_000' (click recorded visual target): resolution_changed: frame is 1440x900, recorded 1280x800 \u2014 the screen no longer matches the recording; refusing to act.",
+ "safety_halt": true
+ },
+ "model_calls": 0,
+ "rung_counts": {},
+ "db_outcome": "no_write",
+ "note_holders": [],
+ "class": "false_stop",
+ "must_save": true,
+ "elapsed_s": 0.26,
+ "held_for_load_s": 0.0,
+ "load1_start": 13.3,
+ "load1_end": 13.3,
+ "first_frame_sha256": "0f484f622c21a98780f26f39cdddcfaa7c101ea138694d1417fbb52b46b0ac5f"
+ },
+ {
+ "trial": 68,
+ "condition": "desktop1440",
+ "drift": "none",
+ "bpp": 32,
+ "desktop": [
+ 1440,
+ 900
+ ],
+ "success": false,
+ "error": null,
+ "stop": {
+ "step_id": "step_000",
+ "intent": "click recorded visual target",
+ "error": "Layout drift before step 'step_000' (click recorded visual target): resolution_changed: frame is 1440x900, recorded 1280x800 \u2014 the screen no longer matches the recording; refusing to act.",
+ "safety_halt": true
+ },
+ "model_calls": 0,
+ "rung_counts": {},
+ "db_outcome": "no_write",
+ "note_holders": [],
+ "class": "false_stop",
+ "must_save": true,
+ "elapsed_s": 0.26,
+ "held_for_load_s": 0.0,
+ "load1_start": 17.1,
+ "load1_end": 17.1,
+ "first_frame_sha256": "0f484f622c21a98780f26f39cdddcfaa7c101ea138694d1417fbb52b46b0ac5f"
+ },
+ {
+ "trial": 69,
+ "condition": "desktop1440",
+ "drift": "none",
+ "bpp": 32,
+ "desktop": [
+ 1440,
+ 900
+ ],
+ "success": false,
+ "error": null,
+ "stop": {
+ "step_id": "step_000",
+ "intent": "click recorded visual target",
+ "error": "Layout drift before step 'step_000' (click recorded visual target): resolution_changed: frame is 1440x900, recorded 1280x800 \u2014 the screen no longer matches the recording; refusing to act.",
+ "safety_halt": true
+ },
+ "model_calls": 0,
+ "rung_counts": {},
+ "db_outcome": "no_write",
+ "note_holders": [],
+ "class": "false_stop",
+ "must_save": true,
+ "elapsed_s": 0.79,
+ "held_for_load_s": 0.0,
+ "load1_start": 15.3,
+ "load1_end": 15.0,
+ "first_frame_sha256": "d42847af1adf0b570d47c00e87c49c165b18f1624cd29664bf050d787cd12ed5"
+ },
+ {
+ "trial": 70,
+ "condition": "desktop1440",
+ "drift": "none",
+ "bpp": 32,
+ "desktop": [
+ 1440,
+ 900
+ ],
+ "success": false,
+ "error": null,
+ "stop": {
+ "step_id": "step_000",
+ "intent": "click recorded visual target",
+ "error": "Layout drift before step 'step_000' (click recorded visual target): resolution_changed: frame is 1440x900, recorded 1280x800 \u2014 the screen no longer matches the recording; refusing to act.",
+ "safety_halt": true
+ },
+ "model_calls": 0,
+ "rung_counts": {},
+ "db_outcome": "no_write",
+ "note_holders": [],
+ "class": "false_stop",
+ "must_save": true,
+ "elapsed_s": 0.19,
+ "held_for_load_s": 0.0,
+ "load1_start": 13.2,
+ "load1_end": 13.2,
+ "first_frame_sha256": "d42847af1adf0b570d47c00e87c49c165b18f1624cd29664bf050d787cd12ed5"
+ }
+]
\ No newline at end of file
diff --git a/packages/flow/environments/openenv/_windows/results/windows11-x64-2026-11-04/rdp-false-stop-ab/before.meta.json b/packages/flow/environments/openenv/_windows/results/windows11-x64-2026-11-04/rdp-false-stop-ab/before.meta.json
new file mode 100644
index 0000000000..f475cb2b84
--- /dev/null
+++ b/packages/flow/environments/openenv/_windows/results/windows11-x64-2026-11-04/rdp-false-stop-ab/before.meta.json
@@ -0,0 +1,7 @@
+{
+ "protocol": "benchmark/rdp_avc_real, Patient Notes arm",
+ "transport": "aardwolf 0.2.14 (pure-Python RDP), macOS client -> Windows 11 Pro x64",
+ "codec": "RDP bitmap codecs negotiated by aardwolf; not H.264/AVC444",
+ "candidate_commit": "5c984f38d9f7915867dc2f8a91475f9ac0f562cf",
+ "started_at": "2026-11-04T06:06:16.048113+00:00"
+}
diff --git a/packages/flow/environments/openenv/_windows/results/windows11-x64-2026-11-04/rdp-false-stop-ab/before.trials.json b/packages/flow/environments/openenv/_windows/results/windows11-x64-2026-11-04/rdp-false-stop-ab/before.trials.json
new file mode 100644
index 0000000000..32b0cde4e4
--- /dev/null
+++ b/packages/flow/environments/openenv/_windows/results/windows11-x64-2026-11-04/rdp-false-stop-ab/before.trials.json
@@ -0,0 +1,2032 @@
+[
+ {
+ "trial": 1,
+ "condition": "healthy",
+ "drift": "none",
+ "bpp": 32,
+ "desktop": [
+ 1280,
+ 800
+ ],
+ "success": true,
+ "error": null,
+ "stop": null,
+ "model_calls": 0,
+ "rung_counts": {
+ "template": 5
+ },
+ "db_outcome": "correct",
+ "note_holders": [
+ 1
+ ],
+ "class": "verified_save",
+ "must_save": true,
+ "elapsed_s": 14.14,
+ "held_for_load_s": 0.0,
+ "load1_start": 49.2,
+ "load1_end": 61.3,
+ "first_frame_sha256": "54f07e069136fc62cb602cd88a709f54cad1547ac87df242c22a91f55aebb61c"
+ },
+ {
+ "trial": 2,
+ "condition": "healthy",
+ "drift": "none",
+ "bpp": 32,
+ "desktop": [
+ 1280,
+ 800
+ ],
+ "success": true,
+ "error": null,
+ "stop": null,
+ "model_calls": 0,
+ "rung_counts": {
+ "template": 5
+ },
+ "db_outcome": "correct",
+ "note_holders": [
+ 1
+ ],
+ "class": "verified_save",
+ "must_save": true,
+ "elapsed_s": 8.57,
+ "held_for_load_s": 0.0,
+ "load1_start": 51.5,
+ "load1_end": 50.2,
+ "first_frame_sha256": "000d8696f4cf94f1e22a40865c3b41373cbbe8a11a45f70da74f5040d33c788d"
+ },
+ {
+ "trial": 3,
+ "condition": "healthy",
+ "drift": "none",
+ "bpp": 32,
+ "desktop": [
+ 1280,
+ 800
+ ],
+ "success": true,
+ "error": null,
+ "stop": null,
+ "model_calls": 0,
+ "rung_counts": {
+ "template": 5
+ },
+ "db_outcome": "correct",
+ "note_holders": [
+ 1
+ ],
+ "class": "verified_save",
+ "must_save": true,
+ "elapsed_s": 7.77,
+ "held_for_load_s": 0.0,
+ "load1_start": 42.1,
+ "load1_end": 41.8,
+ "first_frame_sha256": "55294ce7c8632cd9ccca5755b98dffdd1d71694674e7ffa73414f6442447bfb9"
+ },
+ {
+ "trial": 4,
+ "condition": "healthy",
+ "drift": "none",
+ "bpp": 32,
+ "desktop": [
+ 1280,
+ 800
+ ],
+ "success": true,
+ "error": null,
+ "stop": null,
+ "model_calls": 0,
+ "rung_counts": {
+ "template": 5
+ },
+ "db_outcome": "correct",
+ "note_holders": [
+ 1
+ ],
+ "class": "verified_save",
+ "must_save": true,
+ "elapsed_s": 8.25,
+ "held_for_load_s": 0.0,
+ "load1_start": 35.5,
+ "load1_end": 36.5,
+ "first_frame_sha256": "c0567554a4bed93759902949c9ef07de4fa6b6688d7bbf8501da33845a73f411"
+ },
+ {
+ "trial": 5,
+ "condition": "healthy",
+ "drift": "none",
+ "bpp": 32,
+ "desktop": [
+ 1280,
+ 800
+ ],
+ "success": true,
+ "error": null,
+ "stop": null,
+ "model_calls": 0,
+ "rung_counts": {
+ "template": 5
+ },
+ "db_outcome": "correct",
+ "note_holders": [
+ 1
+ ],
+ "class": "verified_save",
+ "must_save": true,
+ "elapsed_s": 6.57,
+ "held_for_load_s": 0.0,
+ "load1_start": 31.6,
+ "load1_end": 31.2,
+ "first_frame_sha256": "77ef3a5e3faa927e31efc84b5ab3bbfa13bde8e0c5693b9d0c33e042a55c7d24"
+ },
+ {
+ "trial": 6,
+ "condition": "healthy",
+ "drift": "none",
+ "bpp": 32,
+ "desktop": [
+ 1280,
+ 800
+ ],
+ "success": true,
+ "error": null,
+ "stop": null,
+ "model_calls": 0,
+ "rung_counts": {
+ "template": 5
+ },
+ "db_outcome": "correct",
+ "note_holders": [
+ 1
+ ],
+ "class": "verified_save",
+ "must_save": true,
+ "elapsed_s": 16.31,
+ "held_for_load_s": 0.0,
+ "load1_start": 27.2,
+ "load1_end": 29.8,
+ "first_frame_sha256": "c0567554a4bed93759902949c9ef07de4fa6b6688d7bbf8501da33845a73f411"
+ },
+ {
+ "trial": 7,
+ "condition": "healthy",
+ "drift": "none",
+ "bpp": 32,
+ "desktop": [
+ 1280,
+ 800
+ ],
+ "success": true,
+ "error": null,
+ "stop": null,
+ "model_calls": 0,
+ "rung_counts": {
+ "template": 5
+ },
+ "db_outcome": "correct",
+ "note_holders": [
+ 1
+ ],
+ "class": "verified_save",
+ "must_save": true,
+ "elapsed_s": 18.43,
+ "held_for_load_s": 0.0,
+ "load1_start": 29.3,
+ "load1_end": 29.5,
+ "first_frame_sha256": "7fd7b167214e1c995b9a83492a152f4b83fa8b7e06bf8996297307ef73c2325d"
+ },
+ {
+ "trial": 8,
+ "condition": "healthy",
+ "drift": "none",
+ "bpp": 32,
+ "desktop": [
+ 1280,
+ 800
+ ],
+ "success": true,
+ "error": null,
+ "stop": null,
+ "model_calls": 0,
+ "rung_counts": {
+ "template": 5
+ },
+ "db_outcome": "correct",
+ "note_holders": [
+ 1
+ ],
+ "class": "verified_save",
+ "must_save": true,
+ "elapsed_s": 16.54,
+ "held_for_load_s": 0.0,
+ "load1_start": 27.6,
+ "load1_end": 28.0,
+ "first_frame_sha256": "32306092536b82137139493d6518c9e3593190fd5e6b0983a0d5ee0bc4126391"
+ },
+ {
+ "trial": 9,
+ "condition": "healthy",
+ "drift": "none",
+ "bpp": 32,
+ "desktop": [
+ 1280,
+ 800
+ ],
+ "success": true,
+ "error": null,
+ "stop": null,
+ "model_calls": 0,
+ "rung_counts": {
+ "template": 5
+ },
+ "db_outcome": "correct",
+ "note_holders": [
+ 1
+ ],
+ "class": "verified_save",
+ "must_save": true,
+ "elapsed_s": 6.76,
+ "held_for_load_s": 0.0,
+ "load1_start": 29.2,
+ "load1_end": 28.3,
+ "first_frame_sha256": "32306092536b82137139493d6518c9e3593190fd5e6b0983a0d5ee0bc4126391"
+ },
+ {
+ "trial": 10,
+ "condition": "healthy",
+ "drift": "none",
+ "bpp": 32,
+ "desktop": [
+ 1280,
+ 800
+ ],
+ "success": true,
+ "error": null,
+ "stop": null,
+ "model_calls": 0,
+ "rung_counts": {
+ "template": 5
+ },
+ "db_outcome": "correct",
+ "note_holders": [
+ 1
+ ],
+ "class": "verified_save",
+ "must_save": true,
+ "elapsed_s": 17.15,
+ "held_for_load_s": 0.0,
+ "load1_start": 24.4,
+ "load1_end": 29.3,
+ "first_frame_sha256": "2c26939d7fcb4c0fa4db78d48c704dd2853e2188c55befc51892f62a3512929a"
+ },
+ {
+ "trial": 11,
+ "condition": "healthy",
+ "drift": "none",
+ "bpp": 32,
+ "desktop": [
+ 1280,
+ 800
+ ],
+ "success": true,
+ "error": null,
+ "stop": null,
+ "model_calls": 0,
+ "rung_counts": {
+ "template": 5
+ },
+ "db_outcome": "correct",
+ "note_holders": [
+ 1
+ ],
+ "class": "verified_save",
+ "must_save": true,
+ "elapsed_s": 14.72,
+ "held_for_load_s": 0.0,
+ "load1_start": 24.8,
+ "load1_end": 23.4,
+ "first_frame_sha256": "567333c91d7c7f403f79a939493132ad0c3397ab3efa854ea2a493eaa44552f0"
+ },
+ {
+ "trial": 12,
+ "condition": "healthy",
+ "drift": "none",
+ "bpp": 32,
+ "desktop": [
+ 1280,
+ 800
+ ],
+ "success": true,
+ "error": null,
+ "stop": null,
+ "model_calls": 0,
+ "rung_counts": {
+ "template": 5
+ },
+ "db_outcome": "correct",
+ "note_holders": [
+ 1
+ ],
+ "class": "verified_save",
+ "must_save": true,
+ "elapsed_s": 5.0,
+ "held_for_load_s": 0.0,
+ "load1_start": 20.5,
+ "load1_end": 19.6,
+ "first_frame_sha256": "567333c91d7c7f403f79a939493132ad0c3397ab3efa854ea2a493eaa44552f0"
+ },
+ {
+ "trial": 13,
+ "condition": "healthy",
+ "drift": "none",
+ "bpp": 32,
+ "desktop": [
+ 1280,
+ 800
+ ],
+ "success": true,
+ "error": null,
+ "stop": null,
+ "model_calls": 0,
+ "rung_counts": {
+ "template": 5
+ },
+ "db_outcome": "correct",
+ "note_holders": [
+ 1
+ ],
+ "class": "verified_save",
+ "must_save": true,
+ "elapsed_s": 18.23,
+ "held_for_load_s": 0.0,
+ "load1_start": 18.5,
+ "load1_end": 25.0,
+ "first_frame_sha256": "20309ca533fff91173d3012759fe471df5f1aac5ef66ce1fea1be1e59cfaa714"
+ },
+ {
+ "trial": 14,
+ "condition": "healthy",
+ "drift": "none",
+ "bpp": 32,
+ "desktop": [
+ 1280,
+ 800
+ ],
+ "success": true,
+ "error": null,
+ "stop": null,
+ "model_calls": 0,
+ "rung_counts": {
+ "template": 5
+ },
+ "db_outcome": "correct",
+ "note_holders": [
+ 1
+ ],
+ "class": "verified_save",
+ "must_save": true,
+ "elapsed_s": 22.91,
+ "held_for_load_s": 0.0,
+ "load1_start": 25.0,
+ "load1_end": 31.8,
+ "first_frame_sha256": "16edc965c762af8af521f4f35ae1305fca679150743bee9607a96b700c8303c5"
+ },
+ {
+ "trial": 15,
+ "condition": "healthy",
+ "drift": "none",
+ "bpp": 32,
+ "desktop": [
+ 1280,
+ 800
+ ],
+ "success": true,
+ "error": null,
+ "stop": null,
+ "model_calls": 0,
+ "rung_counts": {
+ "template": 5
+ },
+ "db_outcome": "correct",
+ "note_holders": [
+ 1
+ ],
+ "class": "verified_save",
+ "must_save": true,
+ "elapsed_s": 18.61,
+ "held_for_load_s": 0.0,
+ "load1_start": 29.4,
+ "load1_end": 31.8,
+ "first_frame_sha256": "c69f53ec56cefff62e3be0b33fd5c26c9efb9a3b0d92fd96ccdeb862129e84af"
+ },
+ {
+ "trial": 16,
+ "condition": "healthy",
+ "drift": "none",
+ "bpp": 32,
+ "desktop": [
+ 1280,
+ 800
+ ],
+ "success": true,
+ "error": null,
+ "stop": null,
+ "model_calls": 0,
+ "rung_counts": {
+ "template": 5
+ },
+ "db_outcome": "correct",
+ "note_holders": [
+ 1
+ ],
+ "class": "verified_save",
+ "must_save": true,
+ "elapsed_s": 30.28,
+ "held_for_load_s": 0.0,
+ "load1_start": 27.4,
+ "load1_end": 30.4,
+ "first_frame_sha256": "9ffb218fffe527a0b0196efd4532e6ad8eafe7ec31d7f55802df33e24b108cf4"
+ },
+ {
+ "trial": 17,
+ "condition": "healthy",
+ "drift": "none",
+ "bpp": 32,
+ "desktop": [
+ 1280,
+ 800
+ ],
+ "success": true,
+ "error": null,
+ "stop": null,
+ "model_calls": 0,
+ "rung_counts": {
+ "template": 5
+ },
+ "db_outcome": "correct",
+ "note_holders": [
+ 1
+ ],
+ "class": "verified_save",
+ "must_save": true,
+ "elapsed_s": 25.59,
+ "held_for_load_s": 0.0,
+ "load1_start": 27.7,
+ "load1_end": 25.0,
+ "first_frame_sha256": "eefd53803a57e897684f0666f1537c195f52c9d97b835e1f9024564bfd29bd0a"
+ },
+ {
+ "trial": 18,
+ "condition": "healthy",
+ "drift": "none",
+ "bpp": 32,
+ "desktop": [
+ 1280,
+ 800
+ ],
+ "success": true,
+ "error": null,
+ "stop": null,
+ "model_calls": 0,
+ "rung_counts": {
+ "template": 5
+ },
+ "db_outcome": "correct",
+ "note_holders": [
+ 1
+ ],
+ "class": "verified_save",
+ "must_save": true,
+ "elapsed_s": 28.69,
+ "held_for_load_s": 0.0,
+ "load1_start": 22.6,
+ "load1_end": 49.5,
+ "first_frame_sha256": "654e4b65b74d88245ec9c86eaf3af3138b9625c10840ebbb856804241e907069"
+ },
+ {
+ "trial": 19,
+ "condition": "healthy",
+ "drift": "none",
+ "bpp": 32,
+ "desktop": [
+ 1280,
+ 800
+ ],
+ "success": true,
+ "error": null,
+ "stop": null,
+ "model_calls": 0,
+ "rung_counts": {
+ "template": 5
+ },
+ "db_outcome": "correct",
+ "note_holders": [
+ 1
+ ],
+ "class": "verified_save",
+ "must_save": true,
+ "elapsed_s": 15.81,
+ "held_for_load_s": 0.0,
+ "load1_start": 40.9,
+ "load1_end": 37.8,
+ "first_frame_sha256": "796a1597ae8fc0246719bea862e95ce3697a6e5d654abaa9c7408c73910079cb"
+ },
+ {
+ "trial": 20,
+ "condition": "healthy",
+ "drift": "none",
+ "bpp": 32,
+ "desktop": [
+ 1280,
+ 800
+ ],
+ "success": true,
+ "error": null,
+ "stop": null,
+ "model_calls": 0,
+ "rung_counts": {
+ "template": 5
+ },
+ "db_outcome": "correct",
+ "note_holders": [
+ 1
+ ],
+ "class": "verified_save",
+ "must_save": true,
+ "elapsed_s": 11.67,
+ "held_for_load_s": 0.0,
+ "load1_start": 35.4,
+ "load1_end": 35.8,
+ "first_frame_sha256": "796a1597ae8fc0246719bea862e95ce3697a6e5d654abaa9c7408c73910079cb"
+ },
+ {
+ "trial": 21,
+ "condition": "reorder",
+ "drift": "reorder",
+ "bpp": 32,
+ "desktop": [
+ 1280,
+ 800
+ ],
+ "success": true,
+ "error": null,
+ "stop": null,
+ "model_calls": 0,
+ "rung_counts": {
+ "template": 5
+ },
+ "db_outcome": "correct",
+ "note_holders": [
+ 1
+ ],
+ "class": "verified_save",
+ "must_save": true,
+ "elapsed_s": 40.36,
+ "held_for_load_s": 0.0,
+ "load1_start": 33.3,
+ "load1_end": 42.0,
+ "first_frame_sha256": "2886e3542c88d30f9bb121e4df6474a71e9b7609d9297a5492cec638b7ffdf0e"
+ },
+ {
+ "trial": 22,
+ "condition": "reorder",
+ "drift": "reorder",
+ "bpp": 32,
+ "desktop": [
+ 1280,
+ 800
+ ],
+ "success": true,
+ "error": null,
+ "stop": null,
+ "model_calls": 0,
+ "rung_counts": {
+ "template": 5
+ },
+ "db_outcome": "correct",
+ "note_holders": [
+ 1
+ ],
+ "class": "verified_save",
+ "must_save": true,
+ "elapsed_s": 28.23,
+ "held_for_load_s": 0.0,
+ "load1_start": 33.9,
+ "load1_end": 33.6,
+ "first_frame_sha256": "d45e20504475e9f6589810aa9584b1705a747bab3ab07835857b74e3e36bd472"
+ },
+ {
+ "trial": 23,
+ "condition": "reorder",
+ "drift": "reorder",
+ "bpp": 32,
+ "desktop": [
+ 1280,
+ 800
+ ],
+ "success": true,
+ "error": null,
+ "stop": null,
+ "model_calls": 0,
+ "rung_counts": {
+ "template": 5
+ },
+ "db_outcome": "correct",
+ "note_holders": [
+ 1
+ ],
+ "class": "verified_save",
+ "must_save": true,
+ "elapsed_s": 28.73,
+ "held_for_load_s": 0.0,
+ "load1_start": 27.7,
+ "load1_end": 30.1,
+ "first_frame_sha256": "324847f182f9ad0d67da67349bbe28fad811c08984510e9997e6b5d7bc8c1d49"
+ },
+ {
+ "trial": 24,
+ "condition": "reorder",
+ "drift": "reorder",
+ "bpp": 32,
+ "desktop": [
+ 1280,
+ 800
+ ],
+ "success": true,
+ "error": null,
+ "stop": null,
+ "model_calls": 0,
+ "rung_counts": {
+ "template": 5
+ },
+ "db_outcome": "correct",
+ "note_holders": [
+ 1
+ ],
+ "class": "verified_save",
+ "must_save": true,
+ "elapsed_s": 19.26,
+ "held_for_load_s": 0.0,
+ "load1_start": 26.3,
+ "load1_end": 24.6,
+ "first_frame_sha256": "a13cecc15eee413eb0e5353a0ed74ff6511231bcc9322d1a3bea332c065d1f44"
+ },
+ {
+ "trial": 25,
+ "condition": "reorder",
+ "drift": "reorder",
+ "bpp": 32,
+ "desktop": [
+ 1280,
+ 800
+ ],
+ "success": true,
+ "error": null,
+ "stop": null,
+ "model_calls": 0,
+ "rung_counts": {
+ "template": 5
+ },
+ "db_outcome": "correct",
+ "note_holders": [
+ 1
+ ],
+ "class": "verified_save",
+ "must_save": true,
+ "elapsed_s": 20.28,
+ "held_for_load_s": 0.0,
+ "load1_start": 21.8,
+ "load1_end": 23.4,
+ "first_frame_sha256": "364cf4af47f18408c15c125f47c07712e97dcaf14d5e5cf7536755f32ebfe240"
+ },
+ {
+ "trial": 26,
+ "condition": "reorder",
+ "drift": "reorder",
+ "bpp": 32,
+ "desktop": [
+ 1280,
+ 800
+ ],
+ "success": true,
+ "error": null,
+ "stop": null,
+ "model_calls": 0,
+ "rung_counts": {
+ "template": 5
+ },
+ "db_outcome": "correct",
+ "note_holders": [
+ 1
+ ],
+ "class": "verified_save",
+ "must_save": true,
+ "elapsed_s": 50.38,
+ "held_for_load_s": 0.0,
+ "load1_start": 28.6,
+ "load1_end": 66.3,
+ "first_frame_sha256": "451520b355d18e58f1fd4572f31b50dd69769879ad1a9fa4f8da5a17c0d8f6c0"
+ },
+ {
+ "trial": 27,
+ "condition": "reorder",
+ "drift": "reorder",
+ "bpp": 32,
+ "desktop": [
+ 1280,
+ 800
+ ],
+ "success": true,
+ "error": null,
+ "stop": null,
+ "model_calls": 0,
+ "rung_counts": {
+ "template": 5
+ },
+ "db_outcome": "correct",
+ "note_holders": [
+ 1
+ ],
+ "class": "verified_save",
+ "must_save": true,
+ "elapsed_s": 21.43,
+ "held_for_load_s": 0.0,
+ "load1_start": 57.8,
+ "load1_end": 48.8,
+ "first_frame_sha256": "1ff975c92468a6542c5efd338b9ce124c343dd273838a3f497798837dfa08a9a"
+ },
+ {
+ "trial": 28,
+ "condition": "reorder",
+ "drift": "reorder",
+ "bpp": 32,
+ "desktop": [
+ 1280,
+ 800
+ ],
+ "success": true,
+ "error": null,
+ "stop": null,
+ "model_calls": 0,
+ "rung_counts": {
+ "template": 5
+ },
+ "db_outcome": "correct",
+ "note_holders": [
+ 1
+ ],
+ "class": "verified_save",
+ "must_save": true,
+ "elapsed_s": 17.59,
+ "held_for_load_s": 0.0,
+ "load1_start": 41.3,
+ "load1_end": 43.7,
+ "first_frame_sha256": "9233272def6bc31075bd74ecfde63d3fd4ef9c513360633f9368c8415fb9e6ed"
+ },
+ {
+ "trial": 29,
+ "condition": "reorder",
+ "drift": "reorder",
+ "bpp": 32,
+ "desktop": [
+ 1280,
+ 800
+ ],
+ "success": true,
+ "error": null,
+ "stop": null,
+ "model_calls": 0,
+ "rung_counts": {
+ "template": 5
+ },
+ "db_outcome": "correct",
+ "note_holders": [
+ 1
+ ],
+ "class": "verified_save",
+ "must_save": true,
+ "elapsed_s": 15.5,
+ "held_for_load_s": 0.0,
+ "load1_start": 39.4,
+ "load1_end": 49.5,
+ "first_frame_sha256": "2d336c23452cbd4b8a5d335dde50162812f0af0c5339b95533e80455e2ae3081"
+ },
+ {
+ "trial": 30,
+ "condition": "reorder",
+ "drift": "reorder",
+ "bpp": 32,
+ "desktop": [
+ 1280,
+ 800
+ ],
+ "success": true,
+ "error": null,
+ "stop": null,
+ "model_calls": 0,
+ "rung_counts": {
+ "template": 5
+ },
+ "db_outcome": "correct",
+ "note_holders": [
+ 1
+ ],
+ "class": "verified_save",
+ "must_save": true,
+ "elapsed_s": 23.88,
+ "held_for_load_s": 0.0,
+ "load1_start": 44.1,
+ "load1_end": 46.6,
+ "first_frame_sha256": "81516b376b44097f713f076ad255a9f5dc7083b2b3f2006482a2ab91da7dc136"
+ },
+ {
+ "trial": 31,
+ "condition": "bpp16",
+ "drift": "none",
+ "bpp": 16,
+ "desktop": [
+ 1280,
+ 800
+ ],
+ "success": true,
+ "error": null,
+ "stop": null,
+ "model_calls": 0,
+ "rung_counts": {
+ "template": 5
+ },
+ "db_outcome": "correct",
+ "note_holders": [
+ 1
+ ],
+ "class": "verified_save",
+ "must_save": true,
+ "elapsed_s": 44.8,
+ "held_for_load_s": 0.0,
+ "load1_start": 36.8,
+ "load1_end": 34.2,
+ "first_frame_sha256": "65f30ca9611216f1dcad9b6f11aa56c1277e8463ee25dd4c02ca708e814ad35d"
+ },
+ {
+ "trial": 32,
+ "condition": "bpp16",
+ "drift": "none",
+ "bpp": 16,
+ "desktop": [
+ 1280,
+ 800
+ ],
+ "success": true,
+ "error": null,
+ "stop": null,
+ "model_calls": 0,
+ "rung_counts": {
+ "template": 5
+ },
+ "db_outcome": "correct",
+ "note_holders": [
+ 1
+ ],
+ "class": "verified_save",
+ "must_save": true,
+ "elapsed_s": 43.27,
+ "held_for_load_s": 0.0,
+ "load1_start": 31.7,
+ "load1_end": 38.2,
+ "first_frame_sha256": "35d55d936cfbc867a3968526eb11f340fa7ddf7eae2fe46543a73aab32054a64"
+ },
+ {
+ "trial": 33,
+ "condition": "bpp16",
+ "drift": "none",
+ "bpp": 16,
+ "desktop": [
+ 1280,
+ 800
+ ],
+ "success": true,
+ "error": null,
+ "stop": null,
+ "model_calls": 0,
+ "rung_counts": {
+ "template": 5
+ },
+ "db_outcome": "correct",
+ "note_holders": [
+ 1
+ ],
+ "class": "verified_save",
+ "must_save": true,
+ "elapsed_s": 40.49,
+ "held_for_load_s": 0.0,
+ "load1_start": 41.2,
+ "load1_end": 58.2,
+ "first_frame_sha256": "0bfa533e6e08bc2342458e9e18d4df6d63d9d69380921dd1d7b17d0cc161a893"
+ },
+ {
+ "trial": 34,
+ "condition": "bpp16",
+ "drift": "none",
+ "bpp": 16,
+ "desktop": [
+ 1280,
+ 800
+ ],
+ "success": true,
+ "error": null,
+ "stop": null,
+ "model_calls": 0,
+ "rung_counts": {
+ "template": 5
+ },
+ "db_outcome": "correct",
+ "note_holders": [
+ 1
+ ],
+ "class": "verified_save",
+ "must_save": true,
+ "elapsed_s": 36.28,
+ "held_for_load_s": 0.0,
+ "load1_start": 64.6,
+ "load1_end": 115.1,
+ "first_frame_sha256": "ecf6e704ecb6eaac04d32a34f8c65e3d8e2d5694320bef773e7e2c944a778268"
+ },
+ {
+ "trial": 35,
+ "condition": "bpp16",
+ "drift": "none",
+ "bpp": 16,
+ "desktop": [
+ 1280,
+ 800
+ ],
+ "success": true,
+ "error": null,
+ "stop": null,
+ "model_calls": 0,
+ "rung_counts": {
+ "template": 5
+ },
+ "db_outcome": "correct",
+ "note_holders": [
+ 1
+ ],
+ "class": "verified_save",
+ "must_save": true,
+ "elapsed_s": 19.53,
+ "held_for_load_s": 0.0,
+ "load1_start": 115.3,
+ "load1_end": 117.8,
+ "first_frame_sha256": "4491025e521d05b07587817db6194bb1603fbb77066cc11e604489f6970bd32c"
+ },
+ {
+ "trial": 36,
+ "condition": "bpp16",
+ "drift": "none",
+ "bpp": 16,
+ "desktop": [
+ 1280,
+ 800
+ ],
+ "success": true,
+ "error": null,
+ "stop": null,
+ "model_calls": 0,
+ "rung_counts": {
+ "template": 5
+ },
+ "db_outcome": "correct",
+ "note_holders": [
+ 1
+ ],
+ "class": "verified_save",
+ "must_save": true,
+ "elapsed_s": 20.39,
+ "held_for_load_s": 0.0,
+ "load1_start": 102.8,
+ "load1_end": 94.0,
+ "first_frame_sha256": "4df43d060bda5003629fb1c0ee866417310189d25a35d49f58e8e635414862cb"
+ },
+ {
+ "trial": 37,
+ "condition": "bpp16",
+ "drift": "none",
+ "bpp": 16,
+ "desktop": [
+ 1280,
+ 800
+ ],
+ "success": true,
+ "error": null,
+ "stop": null,
+ "model_calls": 0,
+ "rung_counts": {
+ "template": 5
+ },
+ "db_outcome": "correct",
+ "note_holders": [
+ 1
+ ],
+ "class": "verified_save",
+ "must_save": true,
+ "elapsed_s": 6.31,
+ "held_for_load_s": 0.0,
+ "load1_start": 80.5,
+ "load1_end": 76.8,
+ "first_frame_sha256": "4df43d060bda5003629fb1c0ee866417310189d25a35d49f58e8e635414862cb"
+ },
+ {
+ "trial": 38,
+ "condition": "bpp16",
+ "drift": "none",
+ "bpp": 16,
+ "desktop": [
+ 1280,
+ 800
+ ],
+ "success": true,
+ "error": null,
+ "stop": null,
+ "model_calls": 0,
+ "rung_counts": {
+ "template": 5
+ },
+ "db_outcome": "correct",
+ "note_holders": [
+ 1
+ ],
+ "class": "verified_save",
+ "must_save": true,
+ "elapsed_s": 19.93,
+ "held_for_load_s": 0.0,
+ "load1_start": 70.0,
+ "load1_end": 77.5,
+ "first_frame_sha256": "da05a396bcc93fb7f51cd570a58f281e25dc7bdb57d41174d6a89a76d2a1c495"
+ },
+ {
+ "trial": 39,
+ "condition": "bpp16",
+ "drift": "none",
+ "bpp": 16,
+ "desktop": [
+ 1280,
+ 800
+ ],
+ "success": true,
+ "error": null,
+ "stop": null,
+ "model_calls": 0,
+ "rung_counts": {
+ "template": 5
+ },
+ "db_outcome": "correct",
+ "note_holders": [
+ 1
+ ],
+ "class": "verified_save",
+ "must_save": true,
+ "elapsed_s": 25.35,
+ "held_for_load_s": 0.0,
+ "load1_start": 67.5,
+ "load1_end": 59.0,
+ "first_frame_sha256": "089fde06a623b61d48980b7ac53b46507d6717330b10adc25743a0783097e7ba"
+ },
+ {
+ "trial": 40,
+ "condition": "bpp16",
+ "drift": "none",
+ "bpp": 16,
+ "desktop": [
+ 1280,
+ 800
+ ],
+ "success": true,
+ "error": null,
+ "stop": null,
+ "model_calls": 0,
+ "rung_counts": {
+ "template": 5
+ },
+ "db_outcome": "correct",
+ "note_holders": [
+ 1
+ ],
+ "class": "verified_save",
+ "must_save": true,
+ "elapsed_s": 11.32,
+ "held_for_load_s": 0.0,
+ "load1_start": 54.8,
+ "load1_end": 54.1,
+ "first_frame_sha256": "032df09ebcbcf500df76f40c2356a37187aab5ddfef8722ff30fd4b017528ec7"
+ },
+ {
+ "trial": 41,
+ "condition": "decoy",
+ "drift": "decoy",
+ "bpp": 32,
+ "desktop": [
+ 1280,
+ 800
+ ],
+ "success": false,
+ "error": null,
+ "stop": {
+ "step_id": "step_002",
+ "intent": "click 'Search'",
+ "error": "Postconditions failed for step 'step_002' (click 'Search'): expected screen state not reached (semantic drift) \u2014 failed: text_present 'Patient: Neil Sorenson (1984-03-12)' \u2014 run aborted",
+ "safety_halt": true
+ },
+ "model_calls": 0,
+ "rung_counts": {
+ "template": 1
+ },
+ "db_outcome": "no_write",
+ "note_holders": [],
+ "class": "false_stop",
+ "must_save": true,
+ "elapsed_s": 13.66,
+ "held_for_load_s": 0.0,
+ "load1_start": 44.5,
+ "load1_end": 47.0,
+ "first_frame_sha256": "8b4d3df6b37238b25205d7a557bab7acd6df3c0f0dc5e963bae22e9200a997e6"
+ },
+ {
+ "trial": 42,
+ "condition": "decoy",
+ "drift": "decoy",
+ "bpp": 32,
+ "desktop": [
+ 1280,
+ 800
+ ],
+ "success": false,
+ "error": null,
+ "stop": {
+ "step_id": "step_002",
+ "intent": "click 'Search'",
+ "error": "Postconditions failed for step 'step_002' (click 'Search'): expected screen state not reached (semantic drift) \u2014 failed: text_present 'Patient: Neil Sorenson (1984-03-12)' \u2014 run aborted",
+ "safety_halt": true
+ },
+ "model_calls": 0,
+ "rung_counts": {
+ "template": 1
+ },
+ "db_outcome": "no_write",
+ "note_holders": [],
+ "class": "false_stop",
+ "must_save": true,
+ "elapsed_s": 10.4,
+ "held_for_load_s": 0.0,
+ "load1_start": 47.9,
+ "load1_end": 47.9,
+ "first_frame_sha256": "cfcc1cdfa630a97edd2a6d0c0417f4ba791a1ddd8332e519275379a63e42c7c3"
+ },
+ {
+ "trial": 43,
+ "condition": "decoy",
+ "drift": "decoy",
+ "bpp": 32,
+ "desktop": [
+ 1280,
+ 800
+ ],
+ "success": false,
+ "error": null,
+ "stop": {
+ "step_id": "step_002",
+ "intent": "click 'Search'",
+ "error": "Postconditions failed for step 'step_002' (click 'Search'): expected screen state not reached (semantic drift) \u2014 failed: text_present 'Patient: Neil Sorenson (1984-03-12)' \u2014 run aborted",
+ "safety_halt": true
+ },
+ "model_calls": 0,
+ "rung_counts": {
+ "template": 1
+ },
+ "db_outcome": "no_write",
+ "note_holders": [],
+ "class": "false_stop",
+ "must_save": true,
+ "elapsed_s": 31.89,
+ "held_for_load_s": 0.0,
+ "load1_start": 39.5,
+ "load1_end": 40.0,
+ "first_frame_sha256": "4b539b419e8011cce3fe9b5c22cb8edbb862f87230ad39c86f912f667c3f78fd"
+ },
+ {
+ "trial": 44,
+ "condition": "decoy",
+ "drift": "decoy",
+ "bpp": 32,
+ "desktop": [
+ 1280,
+ 800
+ ],
+ "success": false,
+ "error": null,
+ "stop": {
+ "step_id": "step_002",
+ "intent": "click 'Search'",
+ "error": "Postconditions failed for step 'step_002' (click 'Search'): expected screen state not reached (semantic drift) \u2014 failed: text_present 'Patient: Neil Sorenson (1984-03-12)' \u2014 run aborted",
+ "safety_halt": true
+ },
+ "model_calls": 0,
+ "rung_counts": {
+ "template": 1
+ },
+ "db_outcome": "no_write",
+ "note_holders": [],
+ "class": "false_stop",
+ "must_save": true,
+ "elapsed_s": 49.58,
+ "held_for_load_s": 0.0,
+ "load1_start": 37.0,
+ "load1_end": 47.7,
+ "first_frame_sha256": "34ed2f4c0f694b98766ec15bf394e9f0829597f0401a3e9c2c6fdf70b5d39831"
+ },
+ {
+ "trial": 45,
+ "condition": "decoy",
+ "drift": "decoy",
+ "bpp": 32,
+ "desktop": [
+ 1280,
+ 800
+ ],
+ "success": false,
+ "error": null,
+ "stop": {
+ "step_id": "step_002",
+ "intent": "click 'Search'",
+ "error": "Postconditions failed for step 'step_002' (click 'Search'): expected screen state not reached (semantic drift) \u2014 failed: text_present 'Patient: Neil Sorenson (1984-03-12)' \u2014 run aborted",
+ "safety_halt": true
+ },
+ "model_calls": 0,
+ "rung_counts": {
+ "template": 1
+ },
+ "db_outcome": "no_write",
+ "note_holders": [],
+ "class": "false_stop",
+ "must_save": true,
+ "elapsed_s": 72.95,
+ "held_for_load_s": 0.0,
+ "load1_start": 46.8,
+ "load1_end": 51.7,
+ "first_frame_sha256": "48517babd806bc8daa929efae64b209f2e39923c438be00c00665865e73faa34"
+ },
+ {
+ "trial": 46,
+ "condition": "decoy",
+ "drift": "decoy",
+ "bpp": 32,
+ "desktop": [
+ 1280,
+ 800
+ ],
+ "success": false,
+ "error": null,
+ "stop": {
+ "step_id": "step_002",
+ "intent": "click 'Search'",
+ "error": "Postconditions failed for step 'step_002' (click 'Search'): expected screen state not reached (semantic drift) \u2014 failed: text_present 'Patient: Neil Sorenson (1984-03-12)' \u2014 run aborted",
+ "safety_halt": true
+ },
+ "model_calls": 0,
+ "rung_counts": {
+ "template": 1
+ },
+ "db_outcome": "no_write",
+ "note_holders": [],
+ "class": "false_stop",
+ "must_save": true,
+ "elapsed_s": 59.14,
+ "held_for_load_s": 0.0,
+ "load1_start": 41.6,
+ "load1_end": 46.7,
+ "first_frame_sha256": "b66a0afe44b37cbb9c4beed47e2e23ce58c8d1c04265928a015c2ec5be17ad86"
+ },
+ {
+ "trial": 47,
+ "condition": "decoy",
+ "drift": "decoy",
+ "bpp": 32,
+ "desktop": [
+ 1280,
+ 800
+ ],
+ "success": false,
+ "error": null,
+ "stop": {
+ "step_id": "step_002",
+ "intent": "click 'Search'",
+ "error": "Postconditions failed for step 'step_002' (click 'Search'): expected screen state not reached (semantic drift) \u2014 failed: text_present 'Patient: Neil Sorenson (1984-03-12)' \u2014 run aborted",
+ "safety_halt": true
+ },
+ "model_calls": 0,
+ "rung_counts": {
+ "template": 1
+ },
+ "db_outcome": "no_write",
+ "note_holders": [],
+ "class": "false_stop",
+ "must_save": true,
+ "elapsed_s": 29.4,
+ "held_for_load_s": 0.0,
+ "load1_start": 44.1,
+ "load1_end": 48.3,
+ "first_frame_sha256": "b61ddff8df44a7cb8a283867e393474bd5c0648aa93c0beffd469c91d614a23f"
+ },
+ {
+ "trial": 48,
+ "condition": "decoy",
+ "drift": "decoy",
+ "bpp": 32,
+ "desktop": [
+ 1280,
+ 800
+ ],
+ "success": false,
+ "error": null,
+ "stop": {
+ "step_id": "step_002",
+ "intent": "click 'Search'",
+ "error": "Postconditions failed for step 'step_002' (click 'Search'): expected screen state not reached (semantic drift) \u2014 failed: text_present 'Patient: Neil Sorenson (1984-03-12)' \u2014 run aborted",
+ "safety_halt": true
+ },
+ "model_calls": 0,
+ "rung_counts": {
+ "template": 1
+ },
+ "db_outcome": "no_write",
+ "note_holders": [],
+ "class": "false_stop",
+ "must_save": true,
+ "elapsed_s": 34.07,
+ "held_for_load_s": 0.0,
+ "load1_start": 40.1,
+ "load1_end": 46.5,
+ "first_frame_sha256": "b2fe8fc2afca39a714c2d0c28b4fb991a924e42ff0e91ab3ce92d13dc5882fe9"
+ },
+ {
+ "trial": 49,
+ "condition": "decoy",
+ "drift": "decoy",
+ "bpp": 32,
+ "desktop": [
+ 1280,
+ 800
+ ],
+ "success": false,
+ "error": null,
+ "stop": {
+ "step_id": "step_002",
+ "intent": "click 'Search'",
+ "error": "Postconditions failed for step 'step_002' (click 'Search'): expected screen state not reached (semantic drift) \u2014 failed: text_present 'Patient: Neil Sorenson (1984-03-12)' \u2014 run aborted",
+ "safety_halt": true
+ },
+ "model_calls": 0,
+ "rung_counts": {
+ "template": 1
+ },
+ "db_outcome": "no_write",
+ "note_holders": [],
+ "class": "false_stop",
+ "must_save": true,
+ "elapsed_s": 54.01,
+ "held_for_load_s": 0.0,
+ "load1_start": 44.2,
+ "load1_end": 55.8,
+ "first_frame_sha256": "8a8d03ed9c8afffac2efdfef896e7f3d3823b2ba66192d1e39b08bf78b1ba579"
+ },
+ {
+ "trial": 50,
+ "condition": "decoy",
+ "drift": "decoy",
+ "bpp": 32,
+ "desktop": [
+ 1280,
+ 800
+ ],
+ "success": false,
+ "error": null,
+ "stop": {
+ "step_id": "step_002",
+ "intent": "click 'Search'",
+ "error": "Postconditions failed for step 'step_002' (click 'Search'): expected screen state not reached (semantic drift) \u2014 failed: text_present 'Patient: Neil Sorenson (1984-03-12)' \u2014 run aborted",
+ "safety_halt": true
+ },
+ "model_calls": 0,
+ "rung_counts": {
+ "template": 1
+ },
+ "db_outcome": "no_write",
+ "note_holders": [],
+ "class": "false_stop",
+ "must_save": true,
+ "elapsed_s": 103.84,
+ "held_for_load_s": 0.0,
+ "load1_start": 53.4,
+ "load1_end": 104.3,
+ "first_frame_sha256": "9b6232677e4d10d932a7eb3e27c9c5b4b375d9d38c1872ae7d7b0c86992dcca2"
+ },
+ {
+ "trial": 51,
+ "condition": "siblings",
+ "drift": "siblings",
+ "bpp": 32,
+ "desktop": [
+ 1280,
+ 800
+ ],
+ "success": false,
+ "error": null,
+ "stop": {
+ "step_id": "step_003",
+ "intent": "click 'Neil'",
+ "error": "Identity check failed for step 'step_003' (click 'Neil'): a target was found positionally (rung 'ocr', confidence 1.00) but its surrounding text does not match the recorded target's \u2014 expected 'recorded identifier crop', observed 'identifier pixels differ locally (spike 0.076, floor 0.000) \u2014 a different identifier' (coverage 0.00) \u2014 refusing to act; run aborted",
+ "safety_halt": true
+ },
+ "model_calls": 0,
+ "rung_counts": {
+ "template": 2
+ },
+ "db_outcome": "no_write",
+ "note_holders": [],
+ "class": "stop_on_lookalike",
+ "must_save": false,
+ "elapsed_s": 35.36,
+ "held_for_load_s": 0.0,
+ "load1_start": 100.0,
+ "load1_end": 82.1,
+ "first_frame_sha256": "d5f177b80569ce95216eda15faf1253b217552881e61adffd2b9e9b9188fe716"
+ },
+ {
+ "trial": 52,
+ "condition": "siblings",
+ "drift": "siblings",
+ "bpp": 32,
+ "desktop": [
+ 1280,
+ 800
+ ],
+ "success": false,
+ "error": null,
+ "stop": {
+ "step_id": "step_003",
+ "intent": "click 'Neil'",
+ "error": "Identity check failed for step 'step_003' (click 'Neil'): a target was found positionally (rung 'ocr', confidence 1.00) but its surrounding text does not match the recorded target's \u2014 expected 'recorded identifier crop', observed 'identifier pixels differ locally (spike 0.076, floor 0.000) \u2014 a different identifier' (coverage 0.00) \u2014 refusing to act; run aborted",
+ "safety_halt": true
+ },
+ "model_calls": 0,
+ "rung_counts": {
+ "template": 2
+ },
+ "db_outcome": "no_write",
+ "note_holders": [],
+ "class": "stop_on_lookalike",
+ "must_save": false,
+ "elapsed_s": 34.72,
+ "held_for_load_s": 0.0,
+ "load1_start": 71.0,
+ "load1_end": 68.4,
+ "first_frame_sha256": "bb050c45f6ffa1901539e3cc03d2772bbfbefcc9906191c3884a4053a03c1740"
+ },
+ {
+ "trial": 53,
+ "condition": "siblings",
+ "drift": "siblings",
+ "bpp": 32,
+ "desktop": [
+ 1280,
+ 800
+ ],
+ "success": false,
+ "error": null,
+ "stop": {
+ "step_id": "step_003",
+ "intent": "click 'Neil'",
+ "error": "Identity check failed for step 'step_003' (click 'Neil'): a target was found positionally (rung 'ocr', confidence 1.00) but its surrounding text does not match the recorded target's \u2014 expected 'recorded identifier crop', observed 'identifier pixels differ locally (spike 0.076, floor 0.000) \u2014 a different identifier' (coverage 0.00) \u2014 refusing to act; run aborted",
+ "safety_halt": true
+ },
+ "model_calls": 0,
+ "rung_counts": {
+ "template": 2
+ },
+ "db_outcome": "no_write",
+ "note_holders": [],
+ "class": "stop_on_lookalike",
+ "must_save": false,
+ "elapsed_s": 34.62,
+ "held_for_load_s": 0.0,
+ "load1_start": 60.4,
+ "load1_end": 56.3,
+ "first_frame_sha256": "896aada9121ff1900078e147ebeb0814db322369adede962fec89bbfed2b959b"
+ },
+ {
+ "trial": 54,
+ "condition": "siblings",
+ "drift": "siblings",
+ "bpp": 32,
+ "desktop": [
+ 1280,
+ 800
+ ],
+ "success": false,
+ "error": null,
+ "stop": {
+ "step_id": "step_003",
+ "intent": "click 'Neil'",
+ "error": "Identity check failed for step 'step_003' (click 'Neil'): a target was found positionally (rung 'ocr', confidence 1.00) but its surrounding text does not match the recorded target's \u2014 expected 'recorded identifier crop', observed 'identifier pixels differ locally (spike 0.076, floor 0.000) \u2014 a different identifier' (coverage 0.00) \u2014 refusing to act; run aborted",
+ "safety_halt": true
+ },
+ "model_calls": 0,
+ "rung_counts": {
+ "template": 2
+ },
+ "db_outcome": "no_write",
+ "note_holders": [],
+ "class": "stop_on_lookalike",
+ "must_save": false,
+ "elapsed_s": 26.09,
+ "held_for_load_s": 0.0,
+ "load1_start": 53.5,
+ "load1_end": 50.6,
+ "first_frame_sha256": "960a1a775b9af91d072221302f27f198c3d824b56818c1b848ccdffa78fa711a"
+ },
+ {
+ "trial": 55,
+ "condition": "siblings",
+ "drift": "siblings",
+ "bpp": 32,
+ "desktop": [
+ 1280,
+ 800
+ ],
+ "success": false,
+ "error": null,
+ "stop": {
+ "step_id": "step_003",
+ "intent": "click 'Neil'",
+ "error": "Identity check failed for step 'step_003' (click 'Neil'): a target was found positionally (rung 'ocr', confidence 1.00) but its surrounding text does not match the recorded target's \u2014 expected 'recorded identifier crop', observed 'identifier pixels differ locally (spike 0.076, floor 0.000) \u2014 a different identifier' (coverage 0.00) \u2014 refusing to act; run aborted",
+ "safety_halt": true
+ },
+ "model_calls": 0,
+ "rung_counts": {
+ "template": 2
+ },
+ "db_outcome": "no_write",
+ "note_holders": [],
+ "class": "stop_on_lookalike",
+ "must_save": false,
+ "elapsed_s": 2.76,
+ "held_for_load_s": 0.0,
+ "load1_start": 49.2,
+ "load1_end": 49.2,
+ "first_frame_sha256": "76f0b575f2ca462805996976af59e87e97bf97f3fc136767b53e5239e717b89f"
+ },
+ {
+ "trial": 56,
+ "condition": "siblings",
+ "drift": "siblings",
+ "bpp": 32,
+ "desktop": [
+ 1280,
+ 800
+ ],
+ "success": false,
+ "error": null,
+ "stop": {
+ "step_id": "step_003",
+ "intent": "click 'Neil'",
+ "error": "Identity check failed for step 'step_003' (click 'Neil'): a target was found positionally (rung 'ocr', confidence 1.00) but its surrounding text does not match the recorded target's \u2014 expected 'recorded identifier crop', observed 'identifier pixels differ locally (spike 0.076, floor 0.000) \u2014 a different identifier' (coverage 0.00) \u2014 refusing to act; run aborted",
+ "safety_halt": true
+ },
+ "model_calls": 0,
+ "rung_counts": {
+ "template": 2
+ },
+ "db_outcome": "no_write",
+ "note_holders": [],
+ "class": "stop_on_lookalike",
+ "must_save": false,
+ "elapsed_s": 26.4,
+ "held_for_load_s": 0.0,
+ "load1_start": 52.4,
+ "load1_end": 46.7,
+ "first_frame_sha256": "3c04a62fd634c5534469d3b63e77ff22139c66d7fc87f91550c94a2c4f2fd022"
+ },
+ {
+ "trial": 57,
+ "condition": "siblings",
+ "drift": "siblings",
+ "bpp": 32,
+ "desktop": [
+ 1280,
+ 800
+ ],
+ "success": false,
+ "error": null,
+ "stop": {
+ "step_id": "step_003",
+ "intent": "click 'Neil'",
+ "error": "Identity check failed for step 'step_003' (click 'Neil'): a target was found positionally (rung 'ocr', confidence 1.00) but its surrounding text does not match the recorded target's \u2014 expected 'recorded identifier crop', observed 'identifier pixels differ locally (spike 0.076, floor 0.000) \u2014 a different identifier' (coverage 0.00) \u2014 refusing to act; run aborted",
+ "safety_halt": true
+ },
+ "model_calls": 0,
+ "rung_counts": {
+ "template": 2
+ },
+ "db_outcome": "no_write",
+ "note_holders": [],
+ "class": "stop_on_lookalike",
+ "must_save": false,
+ "elapsed_s": 19.9,
+ "held_for_load_s": 0.0,
+ "load1_start": 40.4,
+ "load1_end": 52.5,
+ "first_frame_sha256": "216a108387ea17c14e4fe272422f8f1d7b385665d2685660974f5142ca6d0e0a"
+ },
+ {
+ "trial": 58,
+ "condition": "siblings",
+ "drift": "siblings",
+ "bpp": 32,
+ "desktop": [
+ 1280,
+ 800
+ ],
+ "success": false,
+ "error": null,
+ "stop": {
+ "step_id": "step_003",
+ "intent": "click 'Neil'",
+ "error": "Identity check failed for step 'step_003' (click 'Neil'): a target was found positionally (rung 'ocr', confidence 1.00) but its surrounding text does not match the recorded target's \u2014 expected 'recorded identifier crop', observed 'identifier pixels differ locally (spike 0.076, floor 0.000) \u2014 a different identifier' (coverage 0.00) \u2014 refusing to act; run aborted",
+ "safety_halt": true
+ },
+ "model_calls": 0,
+ "rung_counts": {
+ "template": 2
+ },
+ "db_outcome": "no_write",
+ "note_holders": [],
+ "class": "stop_on_lookalike",
+ "must_save": false,
+ "elapsed_s": 7.56,
+ "held_for_load_s": 0.0,
+ "load1_start": 44.9,
+ "load1_end": 43.9,
+ "first_frame_sha256": "7faae0167bcea41f9d1552c86fef402254781e1377be269b03bdb0e638b86e84"
+ },
+ {
+ "trial": 59,
+ "condition": "siblings",
+ "drift": "siblings",
+ "bpp": 32,
+ "desktop": [
+ 1280,
+ 800
+ ],
+ "success": false,
+ "error": null,
+ "stop": {
+ "step_id": "step_003",
+ "intent": "click 'Neil'",
+ "error": "Identity check failed for step 'step_003' (click 'Neil'): a target was found positionally (rung 'ocr', confidence 1.00) but its surrounding text does not match the recorded target's \u2014 expected 'recorded identifier crop', observed 'identifier pixels differ locally (spike 0.076, floor 0.000) \u2014 a different identifier' (coverage 0.00) \u2014 refusing to act; run aborted",
+ "safety_halt": true
+ },
+ "model_calls": 0,
+ "rung_counts": {
+ "template": 2
+ },
+ "db_outcome": "no_write",
+ "note_holders": [],
+ "class": "stop_on_lookalike",
+ "must_save": false,
+ "elapsed_s": 16.64,
+ "held_for_load_s": 0.0,
+ "load1_start": 37.1,
+ "load1_end": 42.0,
+ "first_frame_sha256": "15f65a3bcce5aaf1026f2123ea39cb216cd3b25342c09a1f624f186ab38e0446"
+ },
+ {
+ "trial": 60,
+ "condition": "siblings",
+ "drift": "siblings",
+ "bpp": 32,
+ "desktop": [
+ 1280,
+ 800
+ ],
+ "success": false,
+ "error": null,
+ "stop": {
+ "step_id": "step_003",
+ "intent": "click 'Neil'",
+ "error": "Identity check failed for step 'step_003' (click 'Neil'): a target was found positionally (rung 'ocr', confidence 1.00) but its surrounding text does not match the recorded target's \u2014 expected 'recorded identifier crop', observed 'identifier pixels differ locally (spike 0.076, floor 0.000) \u2014 a different identifier' (coverage 0.00) \u2014 refusing to act; run aborted",
+ "safety_halt": true
+ },
+ "model_calls": 0,
+ "rung_counts": {
+ "template": 2
+ },
+ "db_outcome": "no_write",
+ "note_holders": [],
+ "class": "stop_on_lookalike",
+ "must_save": false,
+ "elapsed_s": 5.63,
+ "held_for_load_s": 0.0,
+ "load1_start": 34.0,
+ "load1_end": 35.0,
+ "first_frame_sha256": "d0adaccf3f9e1eace2e1b7f1539f1f8824d5dc2472ffede0d5bfac9cb21ba702"
+ },
+ {
+ "trial": 61,
+ "condition": "desktop1440",
+ "drift": "none",
+ "bpp": 32,
+ "desktop": [
+ 1440,
+ 900
+ ],
+ "success": false,
+ "error": null,
+ "stop": {
+ "step_id": "step_000",
+ "intent": "click recorded visual target",
+ "error": "Layout drift before step 'step_000' (click recorded visual target): resolution_changed: frame is 1440x900, recorded 1280x800 \u2014 the screen no longer matches the recording; refusing to act.",
+ "safety_halt": true
+ },
+ "model_calls": 0,
+ "rung_counts": {},
+ "db_outcome": "no_write",
+ "note_holders": [],
+ "class": "false_stop",
+ "must_save": true,
+ "elapsed_s": 5.77,
+ "held_for_load_s": 0.0,
+ "load1_start": 27.2,
+ "load1_end": 28.1,
+ "first_frame_sha256": "d8bcca2545d8573e1babd5c9f51660d324e7f858fb6ac2280d92b98d3c6519f1"
+ },
+ {
+ "trial": 62,
+ "condition": "desktop1440",
+ "drift": "none",
+ "bpp": 32,
+ "desktop": [
+ 1440,
+ 900
+ ],
+ "success": false,
+ "error": null,
+ "stop": {
+ "step_id": "step_000",
+ "intent": "click recorded visual target",
+ "error": "Layout drift before step 'step_000' (click recorded visual target): resolution_changed: frame is 1440x900, recorded 1280x800 \u2014 the screen no longer matches the recording; refusing to act.",
+ "safety_halt": true
+ },
+ "model_calls": 0,
+ "rung_counts": {},
+ "db_outcome": "no_write",
+ "note_holders": [],
+ "class": "false_stop",
+ "must_save": true,
+ "elapsed_s": 0.42,
+ "held_for_load_s": 0.0,
+ "load1_start": 24.5,
+ "load1_end": 24.5,
+ "first_frame_sha256": "d8bcca2545d8573e1babd5c9f51660d324e7f858fb6ac2280d92b98d3c6519f1"
+ },
+ {
+ "trial": 63,
+ "condition": "desktop1440",
+ "drift": "none",
+ "bpp": 32,
+ "desktop": [
+ 1440,
+ 900
+ ],
+ "success": false,
+ "error": null,
+ "stop": {
+ "step_id": "step_000",
+ "intent": "click recorded visual target",
+ "error": "Layout drift before step 'step_000' (click recorded visual target): resolution_changed: frame is 1440x900, recorded 1280x800 \u2014 the screen no longer matches the recording; refusing to act.",
+ "safety_halt": true
+ },
+ "model_calls": 0,
+ "rung_counts": {},
+ "db_outcome": "no_write",
+ "note_holders": [],
+ "class": "false_stop",
+ "must_save": true,
+ "elapsed_s": 0.19,
+ "held_for_load_s": 0.0,
+ "load1_start": 21.7,
+ "load1_end": 21.7,
+ "first_frame_sha256": "d8bcca2545d8573e1babd5c9f51660d324e7f858fb6ac2280d92b98d3c6519f1"
+ },
+ {
+ "trial": 64,
+ "condition": "desktop1440",
+ "drift": "none",
+ "bpp": 32,
+ "desktop": [
+ 1440,
+ 900
+ ],
+ "success": false,
+ "error": null,
+ "stop": {
+ "step_id": "step_000",
+ "intent": "click recorded visual target",
+ "error": "Layout drift before step 'step_000' (click recorded visual target): resolution_changed: frame is 1440x900, recorded 1280x800 \u2014 the screen no longer matches the recording; refusing to act.",
+ "safety_halt": true
+ },
+ "model_calls": 0,
+ "rung_counts": {},
+ "db_outcome": "no_write",
+ "note_holders": [],
+ "class": "false_stop",
+ "must_save": true,
+ "elapsed_s": 1.08,
+ "held_for_load_s": 0.0,
+ "load1_start": 18.7,
+ "load1_end": 17.9,
+ "first_frame_sha256": "c4753729ea750db669d60e3c371995eddee61296afcd8391108d556f100f0acd"
+ },
+ {
+ "trial": 65,
+ "condition": "desktop1440",
+ "drift": "none",
+ "bpp": 32,
+ "desktop": [
+ 1440,
+ 900
+ ],
+ "success": false,
+ "error": null,
+ "stop": {
+ "step_id": "step_000",
+ "intent": "click recorded visual target",
+ "error": "Layout drift before step 'step_000' (click recorded visual target): resolution_changed: frame is 1440x900, recorded 1280x800 \u2014 the screen no longer matches the recording; refusing to act.",
+ "safety_halt": true
+ },
+ "model_calls": 0,
+ "rung_counts": {},
+ "db_outcome": "no_write",
+ "note_holders": [],
+ "class": "false_stop",
+ "must_save": true,
+ "elapsed_s": 0.27,
+ "held_for_load_s": 0.0,
+ "load1_start": 16.7,
+ "load1_end": 16.7,
+ "first_frame_sha256": "c4753729ea750db669d60e3c371995eddee61296afcd8391108d556f100f0acd"
+ },
+ {
+ "trial": 66,
+ "condition": "desktop1440",
+ "drift": "none",
+ "bpp": 32,
+ "desktop": [
+ 1440,
+ 900
+ ],
+ "success": false,
+ "error": null,
+ "stop": {
+ "step_id": "step_000",
+ "intent": "click recorded visual target",
+ "error": "Layout drift before step 'step_000' (click recorded visual target): resolution_changed: frame is 1440x900, recorded 1280x800 \u2014 the screen no longer matches the recording; refusing to act.",
+ "safety_halt": true
+ },
+ "model_calls": 0,
+ "rung_counts": {},
+ "db_outcome": "no_write",
+ "note_holders": [],
+ "class": "false_stop",
+ "must_save": true,
+ "elapsed_s": 0.22,
+ "held_for_load_s": 0.0,
+ "load1_start": 15.8,
+ "load1_end": 15.8,
+ "first_frame_sha256": "c4753729ea750db669d60e3c371995eddee61296afcd8391108d556f100f0acd"
+ },
+ {
+ "trial": 67,
+ "condition": "desktop1440",
+ "drift": "none",
+ "bpp": 32,
+ "desktop": [
+ 1440,
+ 900
+ ],
+ "success": false,
+ "error": null,
+ "stop": {
+ "step_id": "step_000",
+ "intent": "click recorded visual target",
+ "error": "Layout drift before step 'step_000' (click recorded visual target): resolution_changed: frame is 1440x900, recorded 1280x800 \u2014 the screen no longer matches the recording; refusing to act.",
+ "safety_halt": true
+ },
+ "model_calls": 0,
+ "rung_counts": {},
+ "db_outcome": "no_write",
+ "note_holders": [],
+ "class": "false_stop",
+ "must_save": true,
+ "elapsed_s": 0.35,
+ "held_for_load_s": 0.0,
+ "load1_start": 16.5,
+ "load1_end": 16.5,
+ "first_frame_sha256": "c4753729ea750db669d60e3c371995eddee61296afcd8391108d556f100f0acd"
+ },
+ {
+ "trial": 68,
+ "condition": "desktop1440",
+ "drift": "none",
+ "bpp": 32,
+ "desktop": [
+ 1440,
+ 900
+ ],
+ "success": false,
+ "error": null,
+ "stop": {
+ "step_id": "step_000",
+ "intent": "click recorded visual target",
+ "error": "Layout drift before step 'step_000' (click recorded visual target): resolution_changed: frame is 1440x900, recorded 1280x800 \u2014 the screen no longer matches the recording; refusing to act.",
+ "safety_halt": true
+ },
+ "model_calls": 0,
+ "rung_counts": {},
+ "db_outcome": "no_write",
+ "note_holders": [],
+ "class": "false_stop",
+ "must_save": true,
+ "elapsed_s": 4.28,
+ "held_for_load_s": 0.0,
+ "load1_start": 19.3,
+ "load1_end": 19.6,
+ "first_frame_sha256": "c061fcea1ba4469b9441855b68e6dfb4b1dcccf5304f8a6379504963d3ba1ac4"
+ },
+ {
+ "trial": 69,
+ "condition": "desktop1440",
+ "drift": "none",
+ "bpp": 32,
+ "desktop": [
+ 1440,
+ 900
+ ],
+ "success": false,
+ "error": null,
+ "stop": {
+ "step_id": "step_000",
+ "intent": "click recorded visual target",
+ "error": "Layout drift before step 'step_000' (click recorded visual target): resolution_changed: frame is 1440x900, recorded 1280x800 \u2014 the screen no longer matches the recording; refusing to act.",
+ "safety_halt": true
+ },
+ "model_calls": 0,
+ "rung_counts": {},
+ "db_outcome": "no_write",
+ "note_holders": [],
+ "class": "false_stop",
+ "must_save": true,
+ "elapsed_s": 0.65,
+ "held_for_load_s": 0.0,
+ "load1_start": 20.7,
+ "load1_end": 20.7,
+ "first_frame_sha256": "c061fcea1ba4469b9441855b68e6dfb4b1dcccf5304f8a6379504963d3ba1ac4"
+ },
+ {
+ "trial": 70,
+ "condition": "desktop1440",
+ "drift": "none",
+ "bpp": 32,
+ "desktop": [
+ 1440,
+ 900
+ ],
+ "success": false,
+ "error": null,
+ "stop": {
+ "step_id": "step_000",
+ "intent": "click recorded visual target",
+ "error": "Layout drift before step 'step_000' (click recorded visual target): resolution_changed: frame is 1440x900, recorded 1280x800 \u2014 the screen no longer matches the recording; refusing to act.",
+ "safety_halt": true
+ },
+ "model_calls": 0,
+ "rung_counts": {},
+ "db_outcome": "no_write",
+ "note_holders": [],
+ "class": "false_stop",
+ "must_save": true,
+ "elapsed_s": 0.22,
+ "held_for_load_s": 0.0,
+ "load1_start": 18.6,
+ "load1_end": 18.6,
+ "first_frame_sha256": "c061fcea1ba4469b9441855b68e6dfb4b1dcccf5304f8a6379504963d3ba1ac4"
+ }
+]
\ No newline at end of file
diff --git a/packages/flow/environments/openenv/_windows/results/windows11-x64-2026-11-04/win-claims-desk-rdp.json b/packages/flow/environments/openenv/_windows/results/windows11-x64-2026-11-04/win-claims-desk-rdp.json
new file mode 100644
index 0000000000..e2805216da
--- /dev/null
+++ b/packages/flow/environments/openenv/_windows/results/windows11-x64-2026-11-04/win-claims-desk-rdp.json
@@ -0,0 +1,1473 @@
+{
+ "episodes": [
+ {
+ "action_errors": 0,
+ "agent": "scripted",
+ "claim": "failure",
+ "fault": "wrong_row",
+ "feasible": false,
+ "judge_error": null,
+ "reset_s": 27.14,
+ "reward": 1.0,
+ "seconds": 57.41,
+ "seed": 0,
+ "silent_wrong_effect": false,
+ "steps": 14,
+ "task_id": "winclaims-47bc79d5c4",
+ "verdict": "REFUTED"
+ },
+ {
+ "action_errors": 0,
+ "agent": "screen_trusting",
+ "claim": "success",
+ "derived_from": "scripted",
+ "fault": "wrong_row",
+ "feasible": false,
+ "judge_error": null,
+ "reset_s": null,
+ "reward": 0.0,
+ "seconds": 57.41,
+ "seed": 0,
+ "silent_wrong_effect": true,
+ "steps": 14,
+ "task_id": "winclaims-47bc79d5c4",
+ "verdict": "REFUTED"
+ },
+ {
+ "action_errors": 0,
+ "agent": "random",
+ "claim": "failure",
+ "fault": "wrong_row",
+ "feasible": false,
+ "judge_error": null,
+ "reset_s": 3.23,
+ "reward": 0.0,
+ "seconds": 19.48,
+ "seed": 0,
+ "silent_wrong_effect": false,
+ "steps": 11,
+ "task_id": "winclaims-47bc79d5c4",
+ "verdict": "REFUTED"
+ },
+ {
+ "action_errors": 0,
+ "agent": "scripted",
+ "claim": "success",
+ "fault": "ok",
+ "feasible": true,
+ "judge_error": null,
+ "reset_s": 3.13,
+ "reward": 1.0,
+ "seconds": 28.9,
+ "seed": 0,
+ "silent_wrong_effect": false,
+ "steps": 14,
+ "task_id": "winclaims-0b6da80ac6",
+ "verdict": "CONFIRMED"
+ },
+ {
+ "action_errors": 0,
+ "agent": "screen_trusting",
+ "claim": "success",
+ "derived_from": "scripted",
+ "fault": "ok",
+ "feasible": true,
+ "judge_error": null,
+ "reset_s": null,
+ "reward": 1.0,
+ "seconds": 28.9,
+ "seed": 0,
+ "silent_wrong_effect": false,
+ "steps": 14,
+ "task_id": "winclaims-0b6da80ac6",
+ "verdict": "CONFIRMED"
+ },
+ {
+ "action_errors": 0,
+ "agent": "planted_fault",
+ "claim": "success",
+ "fault": "wrong_row",
+ "feasible": false,
+ "judge_error": null,
+ "reset_s": 3.18,
+ "reward": 0.0,
+ "seconds": 33.81,
+ "seed": 0,
+ "silent_wrong_effect": true,
+ "steps": 14,
+ "task_id": "winclaims-0b6da80ac6",
+ "verdict": "REFUTED"
+ },
+ {
+ "action_errors": 0,
+ "agent": "random",
+ "claim": "failure",
+ "fault": "ok",
+ "feasible": true,
+ "judge_error": null,
+ "reset_s": 3.29,
+ "reward": 0.0,
+ "seconds": 19.55,
+ "seed": 0,
+ "silent_wrong_effect": false,
+ "steps": 11,
+ "task_id": "winclaims-0b6da80ac6",
+ "verdict": "REFUTED"
+ },
+ {
+ "action_errors": 0,
+ "agent": "scripted",
+ "claim": "success",
+ "fault": "ok",
+ "feasible": true,
+ "judge_error": null,
+ "reset_s": 3.13,
+ "reward": 1.0,
+ "seconds": 29.54,
+ "seed": 0,
+ "silent_wrong_effect": false,
+ "steps": 14,
+ "task_id": "winclaims-1628cd5fe1",
+ "verdict": "CONFIRMED"
+ },
+ {
+ "action_errors": 0,
+ "agent": "screen_trusting",
+ "claim": "success",
+ "derived_from": "scripted",
+ "fault": "ok",
+ "feasible": true,
+ "judge_error": null,
+ "reset_s": null,
+ "reward": 1.0,
+ "seconds": 29.54,
+ "seed": 0,
+ "silent_wrong_effect": false,
+ "steps": 14,
+ "task_id": "winclaims-1628cd5fe1",
+ "verdict": "CONFIRMED"
+ },
+ {
+ "action_errors": 0,
+ "agent": "planted_fault",
+ "claim": "success",
+ "fault": "duplicate",
+ "feasible": false,
+ "judge_error": null,
+ "reset_s": 3.1,
+ "reward": 0.0,
+ "seconds": 33.84,
+ "seed": 0,
+ "silent_wrong_effect": true,
+ "steps": 14,
+ "task_id": "winclaims-1628cd5fe1",
+ "verdict": "REFUTED"
+ },
+ {
+ "action_errors": 0,
+ "agent": "random",
+ "claim": "failure",
+ "fault": "ok",
+ "feasible": true,
+ "judge_error": null,
+ "reset_s": 3.32,
+ "reward": 0.0,
+ "seconds": 20.54,
+ "seed": 0,
+ "silent_wrong_effect": false,
+ "steps": 11,
+ "task_id": "winclaims-1628cd5fe1",
+ "verdict": "REFUTED"
+ },
+ {
+ "action_errors": 0,
+ "agent": "scripted",
+ "claim": "success",
+ "fault": "drop_first",
+ "feasible": true,
+ "judge_error": null,
+ "reset_s": 3.12,
+ "reward": 1.0,
+ "seconds": 45.7,
+ "seed": 0,
+ "silent_wrong_effect": false,
+ "steps": 23,
+ "task_id": "winclaims-43e35c19cb",
+ "verdict": "CONFIRMED"
+ },
+ {
+ "action_errors": 0,
+ "agent": "screen_trusting",
+ "claim": "success",
+ "derived_from": "scripted",
+ "fault": "drop_first",
+ "feasible": true,
+ "judge_error": null,
+ "reset_s": null,
+ "reward": 1.0,
+ "seconds": 45.7,
+ "seed": 0,
+ "silent_wrong_effect": false,
+ "steps": 23,
+ "task_id": "winclaims-43e35c19cb",
+ "verdict": "CONFIRMED"
+ },
+ {
+ "action_errors": 0,
+ "agent": "planted_fault",
+ "claim": "success",
+ "fault": "truncate",
+ "feasible": false,
+ "judge_error": null,
+ "reset_s": 3.16,
+ "reward": 0.0,
+ "seconds": 50.08,
+ "seed": 0,
+ "silent_wrong_effect": true,
+ "steps": 23,
+ "task_id": "winclaims-43e35c19cb",
+ "verdict": "REFUTED"
+ },
+ {
+ "action_errors": 0,
+ "agent": "random",
+ "claim": "failure",
+ "fault": "drop_first",
+ "feasible": true,
+ "judge_error": null,
+ "reset_s": 3.33,
+ "reward": 0.0,
+ "seconds": 19.92,
+ "seed": 0,
+ "silent_wrong_effect": false,
+ "steps": 11,
+ "task_id": "winclaims-43e35c19cb",
+ "verdict": "REFUTED"
+ },
+ {
+ "action_errors": 0,
+ "agent": "scripted",
+ "claim": "success",
+ "fault": "ok",
+ "feasible": true,
+ "judge_error": null,
+ "reset_s": 3.05,
+ "reward": 1.0,
+ "seconds": 28.21,
+ "seed": 0,
+ "silent_wrong_effect": false,
+ "steps": 14,
+ "task_id": "winclaims-f7883acff6",
+ "verdict": "CONFIRMED"
+ },
+ {
+ "action_errors": 0,
+ "agent": "screen_trusting",
+ "claim": "success",
+ "derived_from": "scripted",
+ "fault": "ok",
+ "feasible": true,
+ "judge_error": null,
+ "reset_s": null,
+ "reward": 1.0,
+ "seconds": 28.21,
+ "seed": 0,
+ "silent_wrong_effect": false,
+ "steps": 14,
+ "task_id": "winclaims-f7883acff6",
+ "verdict": "CONFIRMED"
+ },
+ {
+ "action_errors": 0,
+ "agent": "planted_fault",
+ "claim": "success",
+ "fault": "stale",
+ "feasible": false,
+ "judge_error": null,
+ "reset_s": 3.17,
+ "reward": 0.0,
+ "seconds": 33.39,
+ "seed": 0,
+ "silent_wrong_effect": true,
+ "steps": 14,
+ "task_id": "winclaims-f7883acff6",
+ "verdict": "REFUTED"
+ },
+ {
+ "action_errors": 0,
+ "agent": "random",
+ "claim": "failure",
+ "fault": "ok",
+ "feasible": true,
+ "judge_error": null,
+ "reset_s": 3.18,
+ "reward": 0.0,
+ "seconds": 18.6,
+ "seed": 0,
+ "silent_wrong_effect": false,
+ "steps": 11,
+ "task_id": "winclaims-f7883acff6",
+ "verdict": "REFUTED"
+ },
+ {
+ "action_errors": 0,
+ "agent": "scripted",
+ "claim": "success",
+ "fault": "ok",
+ "feasible": true,
+ "judge_error": null,
+ "reset_s": 3.07,
+ "reward": 1.0,
+ "seconds": 28.23,
+ "seed": 0,
+ "silent_wrong_effect": false,
+ "steps": 14,
+ "task_id": "winclaims-86281e6614",
+ "verdict": "CONFIRMED"
+ },
+ {
+ "action_errors": 0,
+ "agent": "screen_trusting",
+ "claim": "success",
+ "derived_from": "scripted",
+ "fault": "ok",
+ "feasible": true,
+ "judge_error": null,
+ "reset_s": null,
+ "reward": 1.0,
+ "seconds": 28.23,
+ "seed": 0,
+ "silent_wrong_effect": false,
+ "steps": 14,
+ "task_id": "winclaims-86281e6614",
+ "verdict": "CONFIRMED"
+ },
+ {
+ "action_errors": 0,
+ "agent": "planted_fault",
+ "claim": "success",
+ "fault": "drop",
+ "feasible": false,
+ "judge_error": null,
+ "reset_s": 3.32,
+ "reward": 0.0,
+ "seconds": 33.37,
+ "seed": 0,
+ "silent_wrong_effect": true,
+ "steps": 14,
+ "task_id": "winclaims-86281e6614",
+ "verdict": "REFUTED"
+ },
+ {
+ "action_errors": 0,
+ "agent": "random",
+ "claim": "failure",
+ "fault": "ok",
+ "feasible": true,
+ "judge_error": null,
+ "reset_s": 3.24,
+ "reward": 0.0,
+ "seconds": 18.82,
+ "seed": 0,
+ "silent_wrong_effect": false,
+ "steps": 11,
+ "task_id": "winclaims-86281e6614",
+ "verdict": "REFUTED"
+ },
+ {
+ "action_errors": 0,
+ "agent": "scripted",
+ "claim": "failure",
+ "fault": "drop",
+ "feasible": false,
+ "judge_error": null,
+ "reset_s": 3.03,
+ "reward": 1.0,
+ "seconds": 33.04,
+ "seed": 0,
+ "silent_wrong_effect": false,
+ "steps": 14,
+ "task_id": "winclaims-a70198c8ef",
+ "verdict": "REFUTED"
+ },
+ {
+ "action_errors": 0,
+ "agent": "screen_trusting",
+ "claim": "success",
+ "derived_from": "scripted",
+ "fault": "drop",
+ "feasible": false,
+ "judge_error": null,
+ "reset_s": null,
+ "reward": 0.0,
+ "seconds": 33.04,
+ "seed": 0,
+ "silent_wrong_effect": true,
+ "steps": 14,
+ "task_id": "winclaims-a70198c8ef",
+ "verdict": "REFUTED"
+ },
+ {
+ "action_errors": 0,
+ "agent": "random",
+ "claim": "failure",
+ "fault": "drop",
+ "feasible": false,
+ "judge_error": null,
+ "reset_s": 3.21,
+ "reward": 0.0,
+ "seconds": 19.02,
+ "seed": 0,
+ "silent_wrong_effect": false,
+ "steps": 11,
+ "task_id": "winclaims-a70198c8ef",
+ "verdict": "REFUTED"
+ },
+ {
+ "action_errors": 0,
+ "agent": "scripted",
+ "claim": "failure",
+ "fault": "truncate",
+ "feasible": false,
+ "judge_error": null,
+ "reset_s": 3.09,
+ "reward": 1.0,
+ "seconds": 32.82,
+ "seed": 0,
+ "silent_wrong_effect": false,
+ "steps": 14,
+ "task_id": "winclaims-5b0c5a32ac",
+ "verdict": "REFUTED"
+ },
+ {
+ "action_errors": 0,
+ "agent": "screen_trusting",
+ "claim": "success",
+ "derived_from": "scripted",
+ "fault": "truncate",
+ "feasible": false,
+ "judge_error": null,
+ "reset_s": null,
+ "reward": 0.0,
+ "seconds": 32.82,
+ "seed": 0,
+ "silent_wrong_effect": true,
+ "steps": 14,
+ "task_id": "winclaims-5b0c5a32ac",
+ "verdict": "REFUTED"
+ },
+ {
+ "action_errors": 0,
+ "agent": "random",
+ "claim": "failure",
+ "fault": "truncate",
+ "feasible": false,
+ "judge_error": null,
+ "reset_s": 3.23,
+ "reward": 0.0,
+ "seconds": 18.78,
+ "seed": 0,
+ "silent_wrong_effect": false,
+ "steps": 11,
+ "task_id": "winclaims-5b0c5a32ac",
+ "verdict": "REFUTED"
+ },
+ {
+ "action_errors": 0,
+ "agent": "scripted",
+ "claim": "success",
+ "fault": "ok",
+ "feasible": true,
+ "judge_error": null,
+ "reset_s": 3.09,
+ "reward": 1.0,
+ "seconds": 28.47,
+ "seed": 0,
+ "silent_wrong_effect": false,
+ "steps": 14,
+ "task_id": "winclaims-ef30c53031",
+ "verdict": "CONFIRMED"
+ },
+ {
+ "action_errors": 0,
+ "agent": "screen_trusting",
+ "claim": "success",
+ "derived_from": "scripted",
+ "fault": "ok",
+ "feasible": true,
+ "judge_error": null,
+ "reset_s": null,
+ "reward": 1.0,
+ "seconds": 28.47,
+ "seed": 0,
+ "silent_wrong_effect": false,
+ "steps": 14,
+ "task_id": "winclaims-ef30c53031",
+ "verdict": "CONFIRMED"
+ },
+ {
+ "action_errors": 0,
+ "agent": "planted_fault",
+ "claim": "success",
+ "fault": "truncate",
+ "feasible": false,
+ "judge_error": null,
+ "reset_s": 3.14,
+ "reward": 0.0,
+ "seconds": 33.12,
+ "seed": 0,
+ "silent_wrong_effect": true,
+ "steps": 14,
+ "task_id": "winclaims-ef30c53031",
+ "verdict": "REFUTED"
+ },
+ {
+ "action_errors": 0,
+ "agent": "random",
+ "claim": "failure",
+ "fault": "ok",
+ "feasible": true,
+ "judge_error": null,
+ "reset_s": 3.22,
+ "reward": 0.0,
+ "seconds": 18.75,
+ "seed": 0,
+ "silent_wrong_effect": false,
+ "steps": 11,
+ "task_id": "winclaims-ef30c53031",
+ "verdict": "REFUTED"
+ },
+ {
+ "action_errors": 0,
+ "agent": "scripted",
+ "claim": "success",
+ "fault": "ok",
+ "feasible": true,
+ "judge_error": null,
+ "reset_s": 3.08,
+ "reward": 1.0,
+ "seconds": 28.26,
+ "seed": 0,
+ "silent_wrong_effect": false,
+ "steps": 14,
+ "task_id": "winclaims-a64ea5d937",
+ "verdict": "CONFIRMED"
+ },
+ {
+ "action_errors": 0,
+ "agent": "screen_trusting",
+ "claim": "success",
+ "derived_from": "scripted",
+ "fault": "ok",
+ "feasible": true,
+ "judge_error": null,
+ "reset_s": null,
+ "reward": 1.0,
+ "seconds": 28.26,
+ "seed": 0,
+ "silent_wrong_effect": false,
+ "steps": 14,
+ "task_id": "winclaims-a64ea5d937",
+ "verdict": "CONFIRMED"
+ },
+ {
+ "action_errors": 0,
+ "agent": "planted_fault",
+ "claim": "success",
+ "fault": "stale",
+ "feasible": false,
+ "judge_error": null,
+ "reset_s": 4.03,
+ "reward": 0.0,
+ "seconds": 34.13,
+ "seed": 0,
+ "silent_wrong_effect": true,
+ "steps": 14,
+ "task_id": "winclaims-a64ea5d937",
+ "verdict": "REFUTED"
+ },
+ {
+ "action_errors": 0,
+ "agent": "random",
+ "claim": "failure",
+ "fault": "ok",
+ "feasible": true,
+ "judge_error": null,
+ "reset_s": 3.07,
+ "reward": 0.0,
+ "seconds": 18.89,
+ "seed": 0,
+ "silent_wrong_effect": false,
+ "steps": 11,
+ "task_id": "winclaims-a64ea5d937",
+ "verdict": "REFUTED"
+ },
+ {
+ "action_errors": 0,
+ "agent": "scripted",
+ "claim": "failure",
+ "fault": "wrong_row",
+ "feasible": false,
+ "judge_error": null,
+ "reset_s": 3.09,
+ "reward": 1.0,
+ "seconds": 33.13,
+ "seed": 0,
+ "silent_wrong_effect": false,
+ "steps": 14,
+ "task_id": "winclaims-a2a3b6542e",
+ "verdict": "REFUTED"
+ },
+ {
+ "action_errors": 0,
+ "agent": "screen_trusting",
+ "claim": "success",
+ "derived_from": "scripted",
+ "fault": "wrong_row",
+ "feasible": false,
+ "judge_error": null,
+ "reset_s": null,
+ "reward": 0.0,
+ "seconds": 33.13,
+ "seed": 0,
+ "silent_wrong_effect": true,
+ "steps": 14,
+ "task_id": "winclaims-a2a3b6542e",
+ "verdict": "REFUTED"
+ },
+ {
+ "action_errors": 0,
+ "agent": "random",
+ "claim": "failure",
+ "fault": "wrong_row",
+ "feasible": false,
+ "judge_error": null,
+ "reset_s": 3.24,
+ "reward": 0.0,
+ "seconds": 19.04,
+ "seed": 0,
+ "silent_wrong_effect": false,
+ "steps": 11,
+ "task_id": "winclaims-a2a3b6542e",
+ "verdict": "REFUTED"
+ },
+ {
+ "action_errors": 0,
+ "agent": "scripted",
+ "claim": "success",
+ "fault": "ok",
+ "feasible": true,
+ "judge_error": null,
+ "reset_s": 3.14,
+ "reward": 1.0,
+ "seconds": 28.57,
+ "seed": 0,
+ "silent_wrong_effect": false,
+ "steps": 14,
+ "task_id": "winclaims-58a5a7888a",
+ "verdict": "CONFIRMED"
+ },
+ {
+ "action_errors": 0,
+ "agent": "screen_trusting",
+ "claim": "success",
+ "derived_from": "scripted",
+ "fault": "ok",
+ "feasible": true,
+ "judge_error": null,
+ "reset_s": null,
+ "reward": 1.0,
+ "seconds": 28.57,
+ "seed": 0,
+ "silent_wrong_effect": false,
+ "steps": 14,
+ "task_id": "winclaims-58a5a7888a",
+ "verdict": "CONFIRMED"
+ },
+ {
+ "action_errors": 0,
+ "agent": "planted_fault",
+ "claim": "success",
+ "fault": "wrong_row",
+ "feasible": false,
+ "judge_error": null,
+ "reset_s": 3.2,
+ "reward": 0.0,
+ "seconds": 33.58,
+ "seed": 0,
+ "silent_wrong_effect": true,
+ "steps": 14,
+ "task_id": "winclaims-58a5a7888a",
+ "verdict": "REFUTED"
+ },
+ {
+ "action_errors": 0,
+ "agent": "random",
+ "claim": "failure",
+ "fault": "ok",
+ "feasible": true,
+ "judge_error": null,
+ "reset_s": 3.32,
+ "reward": 0.0,
+ "seconds": 19.05,
+ "seed": 0,
+ "silent_wrong_effect": false,
+ "steps": 11,
+ "task_id": "winclaims-58a5a7888a",
+ "verdict": "REFUTED"
+ },
+ {
+ "action_errors": 0,
+ "agent": "scripted",
+ "claim": "failure",
+ "fault": "stale",
+ "feasible": false,
+ "judge_error": null,
+ "reset_s": 3.22,
+ "reward": 1.0,
+ "seconds": 33.41,
+ "seed": 0,
+ "silent_wrong_effect": false,
+ "steps": 14,
+ "task_id": "winclaims-f64c53f6b4",
+ "verdict": "REFUTED"
+ },
+ {
+ "action_errors": 0,
+ "agent": "screen_trusting",
+ "claim": "success",
+ "derived_from": "scripted",
+ "fault": "stale",
+ "feasible": false,
+ "judge_error": null,
+ "reset_s": null,
+ "reward": 0.0,
+ "seconds": 33.41,
+ "seed": 0,
+ "silent_wrong_effect": true,
+ "steps": 14,
+ "task_id": "winclaims-f64c53f6b4",
+ "verdict": "REFUTED"
+ },
+ {
+ "action_errors": 0,
+ "agent": "random",
+ "claim": "failure",
+ "fault": "stale",
+ "feasible": false,
+ "judge_error": null,
+ "reset_s": 3.58,
+ "reward": 0.0,
+ "seconds": 19.35,
+ "seed": 0,
+ "silent_wrong_effect": false,
+ "steps": 11,
+ "task_id": "winclaims-f64c53f6b4",
+ "verdict": "REFUTED"
+ },
+ {
+ "action_errors": 0,
+ "agent": "scripted",
+ "claim": "failure",
+ "fault": "drop",
+ "feasible": false,
+ "judge_error": null,
+ "reset_s": 3.13,
+ "reward": 1.0,
+ "seconds": 33.07,
+ "seed": 0,
+ "silent_wrong_effect": false,
+ "steps": 14,
+ "task_id": "winclaims-7e1ed7aa45",
+ "verdict": "REFUTED"
+ },
+ {
+ "action_errors": 0,
+ "agent": "screen_trusting",
+ "claim": "success",
+ "derived_from": "scripted",
+ "fault": "drop",
+ "feasible": false,
+ "judge_error": null,
+ "reset_s": null,
+ "reward": 0.0,
+ "seconds": 33.07,
+ "seed": 0,
+ "silent_wrong_effect": true,
+ "steps": 14,
+ "task_id": "winclaims-7e1ed7aa45",
+ "verdict": "REFUTED"
+ },
+ {
+ "action_errors": 0,
+ "agent": "random",
+ "claim": "failure",
+ "fault": "drop",
+ "feasible": false,
+ "judge_error": null,
+ "reset_s": 3.17,
+ "reward": 0.0,
+ "seconds": 18.84,
+ "seed": 0,
+ "silent_wrong_effect": false,
+ "steps": 11,
+ "task_id": "winclaims-7e1ed7aa45",
+ "verdict": "REFUTED"
+ },
+ {
+ "action_errors": 0,
+ "agent": "scripted",
+ "claim": "failure",
+ "fault": "wrong_row",
+ "feasible": false,
+ "judge_error": null,
+ "reset_s": 3.14,
+ "reward": 1.0,
+ "seconds": 33.11,
+ "seed": 0,
+ "silent_wrong_effect": false,
+ "steps": 14,
+ "task_id": "winclaims-4b213973e5",
+ "verdict": "REFUTED"
+ },
+ {
+ "action_errors": 0,
+ "agent": "screen_trusting",
+ "claim": "success",
+ "derived_from": "scripted",
+ "fault": "wrong_row",
+ "feasible": false,
+ "judge_error": null,
+ "reset_s": null,
+ "reward": 0.0,
+ "seconds": 33.11,
+ "seed": 0,
+ "silent_wrong_effect": true,
+ "steps": 14,
+ "task_id": "winclaims-4b213973e5",
+ "verdict": "REFUTED"
+ },
+ {
+ "action_errors": 0,
+ "agent": "random",
+ "claim": "failure",
+ "fault": "wrong_row",
+ "feasible": false,
+ "judge_error": null,
+ "reset_s": 3.39,
+ "reward": 0.0,
+ "seconds": 18.79,
+ "seed": 0,
+ "silent_wrong_effect": false,
+ "steps": 11,
+ "task_id": "winclaims-4b213973e5",
+ "verdict": "REFUTED"
+ },
+ {
+ "action_errors": 0,
+ "agent": "scripted",
+ "claim": "success",
+ "fault": "drop_first",
+ "feasible": true,
+ "judge_error": null,
+ "reset_s": 3.29,
+ "reward": 1.0,
+ "seconds": 44.38,
+ "seed": 0,
+ "silent_wrong_effect": false,
+ "steps": 23,
+ "task_id": "winclaims-8821889da6",
+ "verdict": "CONFIRMED"
+ },
+ {
+ "action_errors": 0,
+ "agent": "screen_trusting",
+ "claim": "success",
+ "derived_from": "scripted",
+ "fault": "drop_first",
+ "feasible": true,
+ "judge_error": null,
+ "reset_s": null,
+ "reward": 1.0,
+ "seconds": 44.38,
+ "seed": 0,
+ "silent_wrong_effect": false,
+ "steps": 23,
+ "task_id": "winclaims-8821889da6",
+ "verdict": "CONFIRMED"
+ },
+ {
+ "action_errors": 0,
+ "agent": "planted_fault",
+ "claim": "success",
+ "fault": "drop",
+ "feasible": false,
+ "judge_error": null,
+ "reset_s": 3.16,
+ "reward": 0.0,
+ "seconds": 49.41,
+ "seed": 0,
+ "silent_wrong_effect": true,
+ "steps": 23,
+ "task_id": "winclaims-8821889da6",
+ "verdict": "REFUTED"
+ },
+ {
+ "action_errors": 0,
+ "agent": "random",
+ "claim": "failure",
+ "fault": "drop_first",
+ "feasible": true,
+ "judge_error": null,
+ "reset_s": 3.25,
+ "reward": 0.0,
+ "seconds": 19.13,
+ "seed": 0,
+ "silent_wrong_effect": false,
+ "steps": 11,
+ "task_id": "winclaims-8821889da6",
+ "verdict": "REFUTED"
+ },
+ {
+ "action_errors": 0,
+ "agent": "scripted",
+ "claim": "success",
+ "fault": "drop_first",
+ "feasible": true,
+ "judge_error": null,
+ "reset_s": 3.58,
+ "reward": 1.0,
+ "seconds": 44.71,
+ "seed": 0,
+ "silent_wrong_effect": false,
+ "steps": 23,
+ "task_id": "winclaims-232feac081",
+ "verdict": "CONFIRMED"
+ },
+ {
+ "action_errors": 0,
+ "agent": "screen_trusting",
+ "claim": "success",
+ "derived_from": "scripted",
+ "fault": "drop_first",
+ "feasible": true,
+ "judge_error": null,
+ "reset_s": null,
+ "reward": 1.0,
+ "seconds": 44.71,
+ "seed": 0,
+ "silent_wrong_effect": false,
+ "steps": 23,
+ "task_id": "winclaims-232feac081",
+ "verdict": "CONFIRMED"
+ },
+ {
+ "action_errors": 0,
+ "agent": "planted_fault",
+ "claim": "success",
+ "fault": "wrong_row",
+ "feasible": false,
+ "judge_error": null,
+ "reset_s": 3.18,
+ "reward": 0.0,
+ "seconds": 48.7,
+ "seed": 0,
+ "silent_wrong_effect": true,
+ "steps": 23,
+ "task_id": "winclaims-232feac081",
+ "verdict": "REFUTED"
+ },
+ {
+ "action_errors": 0,
+ "agent": "random",
+ "claim": "failure",
+ "fault": "drop_first",
+ "feasible": true,
+ "judge_error": null,
+ "reset_s": 3.26,
+ "reward": 0.0,
+ "seconds": 18.98,
+ "seed": 0,
+ "silent_wrong_effect": false,
+ "steps": 11,
+ "task_id": "winclaims-232feac081",
+ "verdict": "REFUTED"
+ },
+ {
+ "action_errors": 0,
+ "agent": "scripted",
+ "claim": "success",
+ "fault": "ok",
+ "feasible": true,
+ "judge_error": null,
+ "reset_s": 3.21,
+ "reward": 1.0,
+ "seconds": 28.38,
+ "seed": 0,
+ "silent_wrong_effect": false,
+ "steps": 14,
+ "task_id": "winclaims-2c8d585a77",
+ "verdict": "CONFIRMED"
+ },
+ {
+ "action_errors": 0,
+ "agent": "screen_trusting",
+ "claim": "success",
+ "derived_from": "scripted",
+ "fault": "ok",
+ "feasible": true,
+ "judge_error": null,
+ "reset_s": null,
+ "reward": 1.0,
+ "seconds": 28.38,
+ "seed": 0,
+ "silent_wrong_effect": false,
+ "steps": 14,
+ "task_id": "winclaims-2c8d585a77",
+ "verdict": "CONFIRMED"
+ },
+ {
+ "action_errors": 0,
+ "agent": "planted_fault",
+ "claim": "success",
+ "fault": "duplicate",
+ "feasible": false,
+ "judge_error": null,
+ "reset_s": 3.25,
+ "reward": 0.0,
+ "seconds": 34.51,
+ "seed": 0,
+ "silent_wrong_effect": true,
+ "steps": 14,
+ "task_id": "winclaims-2c8d585a77",
+ "verdict": "REFUTED"
+ },
+ {
+ "action_errors": 0,
+ "agent": "random",
+ "claim": "failure",
+ "fault": "ok",
+ "feasible": true,
+ "judge_error": null,
+ "reset_s": 3.41,
+ "reward": 0.0,
+ "seconds": 19.3,
+ "seed": 0,
+ "silent_wrong_effect": false,
+ "steps": 11,
+ "task_id": "winclaims-2c8d585a77",
+ "verdict": "REFUTED"
+ },
+ {
+ "action_errors": 0,
+ "agent": "scripted",
+ "claim": "success",
+ "fault": "ok",
+ "feasible": true,
+ "judge_error": null,
+ "reset_s": 3.53,
+ "reward": 1.0,
+ "seconds": 28.71,
+ "seed": 0,
+ "silent_wrong_effect": false,
+ "steps": 14,
+ "task_id": "winclaims-d95991d94a",
+ "verdict": "CONFIRMED"
+ },
+ {
+ "action_errors": 0,
+ "agent": "screen_trusting",
+ "claim": "success",
+ "derived_from": "scripted",
+ "fault": "ok",
+ "feasible": true,
+ "judge_error": null,
+ "reset_s": null,
+ "reward": 1.0,
+ "seconds": 28.71,
+ "seed": 0,
+ "silent_wrong_effect": false,
+ "steps": 14,
+ "task_id": "winclaims-d95991d94a",
+ "verdict": "CONFIRMED"
+ },
+ {
+ "action_errors": 0,
+ "agent": "planted_fault",
+ "claim": "success",
+ "fault": "truncate",
+ "feasible": false,
+ "judge_error": null,
+ "reset_s": 3.2,
+ "reward": 0.0,
+ "seconds": 33.95,
+ "seed": 0,
+ "silent_wrong_effect": true,
+ "steps": 14,
+ "task_id": "winclaims-d95991d94a",
+ "verdict": "REFUTED"
+ },
+ {
+ "action_errors": 0,
+ "agent": "random",
+ "claim": "failure",
+ "fault": "ok",
+ "feasible": true,
+ "judge_error": null,
+ "reset_s": 3.19,
+ "reward": 0.0,
+ "seconds": 19.86,
+ "seed": 0,
+ "silent_wrong_effect": false,
+ "steps": 11,
+ "task_id": "winclaims-d95991d94a",
+ "verdict": "REFUTED"
+ },
+ {
+ "action_errors": 0,
+ "agent": "scripted",
+ "claim": "failure",
+ "fault": "stale",
+ "feasible": false,
+ "judge_error": null,
+ "reset_s": 3.11,
+ "reward": 1.0,
+ "seconds": 34.0,
+ "seed": 0,
+ "silent_wrong_effect": false,
+ "steps": 14,
+ "task_id": "winclaims-6ad69b812c",
+ "verdict": "REFUTED"
+ },
+ {
+ "action_errors": 0,
+ "agent": "screen_trusting",
+ "claim": "success",
+ "derived_from": "scripted",
+ "fault": "stale",
+ "feasible": false,
+ "judge_error": null,
+ "reset_s": null,
+ "reward": 0.0,
+ "seconds": 34.0,
+ "seed": 0,
+ "silent_wrong_effect": true,
+ "steps": 14,
+ "task_id": "winclaims-6ad69b812c",
+ "verdict": "REFUTED"
+ },
+ {
+ "action_errors": 0,
+ "agent": "random",
+ "claim": "failure",
+ "fault": "stale",
+ "feasible": false,
+ "judge_error": null,
+ "reset_s": 3.3,
+ "reward": 0.0,
+ "seconds": 19.85,
+ "seed": 0,
+ "silent_wrong_effect": false,
+ "steps": 11,
+ "task_id": "winclaims-6ad69b812c",
+ "verdict": "REFUTED"
+ },
+ {
+ "action_errors": 0,
+ "agent": "scripted",
+ "claim": "failure",
+ "fault": "truncate",
+ "feasible": false,
+ "judge_error": null,
+ "reset_s": 3.34,
+ "reward": 1.0,
+ "seconds": 34.13,
+ "seed": 0,
+ "silent_wrong_effect": false,
+ "steps": 14,
+ "task_id": "winclaims-6d743438e4",
+ "verdict": "REFUTED"
+ },
+ {
+ "action_errors": 0,
+ "agent": "screen_trusting",
+ "claim": "success",
+ "derived_from": "scripted",
+ "fault": "truncate",
+ "feasible": false,
+ "judge_error": null,
+ "reset_s": null,
+ "reward": 0.0,
+ "seconds": 34.13,
+ "seed": 0,
+ "silent_wrong_effect": true,
+ "steps": 14,
+ "task_id": "winclaims-6d743438e4",
+ "verdict": "REFUTED"
+ },
+ {
+ "action_errors": 0,
+ "agent": "random",
+ "claim": "failure",
+ "fault": "truncate",
+ "feasible": false,
+ "judge_error": null,
+ "reset_s": 3.26,
+ "reward": 0.0,
+ "seconds": 19.2,
+ "seed": 0,
+ "silent_wrong_effect": false,
+ "steps": 11,
+ "task_id": "winclaims-6d743438e4",
+ "verdict": "REFUTED"
+ },
+ {
+ "action_errors": 0,
+ "agent": "scripted",
+ "claim": "failure",
+ "fault": "duplicate",
+ "feasible": false,
+ "judge_error": null,
+ "reset_s": 3.04,
+ "reward": 1.0,
+ "seconds": 34.38,
+ "seed": 0,
+ "silent_wrong_effect": false,
+ "steps": 14,
+ "task_id": "winclaims-5095144dcd",
+ "verdict": "REFUTED"
+ },
+ {
+ "action_errors": 0,
+ "agent": "screen_trusting",
+ "claim": "success",
+ "derived_from": "scripted",
+ "fault": "duplicate",
+ "feasible": false,
+ "judge_error": null,
+ "reset_s": null,
+ "reward": 0.0,
+ "seconds": 34.38,
+ "seed": 0,
+ "silent_wrong_effect": true,
+ "steps": 14,
+ "task_id": "winclaims-5095144dcd",
+ "verdict": "REFUTED"
+ },
+ {
+ "action_errors": 0,
+ "agent": "random",
+ "claim": "failure",
+ "fault": "duplicate",
+ "feasible": false,
+ "judge_error": null,
+ "reset_s": 3.61,
+ "reward": 0.0,
+ "seconds": 20.07,
+ "seed": 0,
+ "silent_wrong_effect": false,
+ "steps": 11,
+ "task_id": "winclaims-5095144dcd",
+ "verdict": "REFUTED"
+ },
+ {
+ "action_errors": 0,
+ "agent": "scripted",
+ "claim": "failure",
+ "fault": "duplicate",
+ "feasible": false,
+ "judge_error": null,
+ "reset_s": 3.19,
+ "reward": 1.0,
+ "seconds": 33.95,
+ "seed": 0,
+ "silent_wrong_effect": false,
+ "steps": 14,
+ "task_id": "winclaims-05a2a4983b",
+ "verdict": "REFUTED"
+ },
+ {
+ "action_errors": 0,
+ "agent": "screen_trusting",
+ "claim": "success",
+ "derived_from": "scripted",
+ "fault": "duplicate",
+ "feasible": false,
+ "judge_error": null,
+ "reset_s": null,
+ "reward": 0.0,
+ "seconds": 33.95,
+ "seed": 0,
+ "silent_wrong_effect": true,
+ "steps": 14,
+ "task_id": "winclaims-05a2a4983b",
+ "verdict": "REFUTED"
+ },
+ {
+ "action_errors": 0,
+ "agent": "random",
+ "claim": "failure",
+ "fault": "duplicate",
+ "feasible": false,
+ "judge_error": null,
+ "reset_s": 3.27,
+ "reward": 0.0,
+ "seconds": 19.52,
+ "seed": 0,
+ "silent_wrong_effect": false,
+ "steps": 11,
+ "task_id": "winclaims-05a2a4983b",
+ "verdict": "REFUTED"
+ },
+ {
+ "action_errors": 0,
+ "agent": "scripted",
+ "claim": "failure",
+ "fault": "drop",
+ "feasible": false,
+ "judge_error": null,
+ "reset_s": 3.16,
+ "reward": 1.0,
+ "seconds": 33.37,
+ "seed": 0,
+ "silent_wrong_effect": false,
+ "steps": 14,
+ "task_id": "winclaims-3e05fded8d",
+ "verdict": "REFUTED"
+ },
+ {
+ "action_errors": 0,
+ "agent": "screen_trusting",
+ "claim": "success",
+ "derived_from": "scripted",
+ "fault": "drop",
+ "feasible": false,
+ "judge_error": null,
+ "reset_s": null,
+ "reward": 0.0,
+ "seconds": 33.37,
+ "seed": 0,
+ "silent_wrong_effect": true,
+ "steps": 14,
+ "task_id": "winclaims-3e05fded8d",
+ "verdict": "REFUTED"
+ },
+ {
+ "action_errors": 0,
+ "agent": "random",
+ "claim": "failure",
+ "fault": "drop",
+ "feasible": false,
+ "judge_error": null,
+ "reset_s": 3.23,
+ "reward": 0.0,
+ "seconds": 19.46,
+ "seed": 0,
+ "silent_wrong_effect": false,
+ "steps": 11,
+ "task_id": "winclaims-3e05fded8d",
+ "verdict": "REFUTED"
+ }
+ ],
+ "summary": {
+ "agents": {
+ "planted_fault": {
+ "action_errors": 0,
+ "episodes": 12,
+ "judge_errors": 0,
+ "mean_reward": 0.0,
+ "silent_wrong_effects": 12,
+ "verdicts": {
+ "CONFIRMED": 0,
+ "INDETERMINATE": 0,
+ "REFUTED": 12
+ }
+ },
+ "random": {
+ "action_errors": 0,
+ "episodes": 24,
+ "judge_errors": 0,
+ "mean_reward": 0.0,
+ "silent_wrong_effects": 0,
+ "verdicts": {
+ "CONFIRMED": 0,
+ "INDETERMINATE": 0,
+ "REFUTED": 24
+ }
+ },
+ "screen_trusting": {
+ "action_errors": 0,
+ "episodes": 24,
+ "judge_errors": 0,
+ "mean_reward": 0.5,
+ "silent_wrong_effects": 12,
+ "verdicts": {
+ "CONFIRMED": 12,
+ "INDETERMINATE": 0,
+ "REFUTED": 12
+ }
+ },
+ "scripted": {
+ "action_errors": 0,
+ "episodes": 24,
+ "judge_errors": 0,
+ "mean_reward": 1.0,
+ "silent_wrong_effects": 0,
+ "verdicts": {
+ "CONFIRMED": 12,
+ "INDETERMINATE": 0,
+ "REFUTED": 12
+ }
+ }
+ },
+ "checks": {
+ "every_feasible_task_fails_with_a_planted_fault": true,
+ "every_task_passes_with_its_solution": true,
+ "no_judge_errors": true,
+ "no_state_leaks": true,
+ "random_floor_margin": true,
+ "screen_trusting_paid_only_on_feasible": true
+ },
+ "env": "openadapt-win-claims-desk-rdp",
+ "feasible_tasks": 12,
+ "leak_checks": [
+ {
+ "app_processes": 1,
+ "digest_after_write_differs": true,
+ "note_field_after_reset": "",
+ "passed": true,
+ "reader": "winclaims-1628cd5fe1",
+ "records_after_reset": 1,
+ "records_in_pristine_seed": 1,
+ "restored_digest_is_pristine": true,
+ "writer": "winclaims-0b6da80ac6"
+ },
+ {
+ "app_processes": 1,
+ "digest_after_write_differs": true,
+ "note_field_after_reset": "",
+ "passed": true,
+ "reader": "winclaims-43e35c19cb",
+ "records_after_reset": 1,
+ "records_in_pristine_seed": 1,
+ "restored_digest_is_pristine": true,
+ "writer": "winclaims-1628cd5fe1"
+ }
+ ],
+ "passed": true,
+ "reset_s": {
+ "episodes": 60,
+ "max": 27.14,
+ "median": 3.21,
+ "p95": 3.58
+ },
+ "run": {
+ "model_calls": 0,
+ "server_platform": "Linux aarch64 py3.12.16",
+ "started": "2026-11-04T04:51:06Z",
+ "wall_s": 1815.2
+ },
+ "surface": "rdp_pixels",
+ "tasks": 24
+ }
+}
diff --git a/packages/flow/environments/openenv/_windows/results/windows11-x64-2026-11-04/win-claims-desk.json b/packages/flow/environments/openenv/_windows/results/windows11-x64-2026-11-04/win-claims-desk.json
new file mode 100644
index 0000000000..213bbb7faf
--- /dev/null
+++ b/packages/flow/environments/openenv/_windows/results/windows11-x64-2026-11-04/win-claims-desk.json
@@ -0,0 +1,1473 @@
+{
+ "episodes": [
+ {
+ "action_errors": 0,
+ "agent": "scripted",
+ "claim": "failure",
+ "fault": "wrong_row",
+ "feasible": false,
+ "judge_error": null,
+ "reset_s": 26.34,
+ "reward": 1.0,
+ "seconds": 67.31,
+ "seed": 0,
+ "silent_wrong_effect": false,
+ "steps": 14,
+ "task_id": "winclaims-47bc79d5c4",
+ "verdict": "REFUTED"
+ },
+ {
+ "action_errors": 0,
+ "agent": "screen_trusting",
+ "claim": "success",
+ "derived_from": "scripted",
+ "fault": "wrong_row",
+ "feasible": false,
+ "judge_error": null,
+ "reset_s": null,
+ "reward": 0.0,
+ "seconds": 67.31,
+ "seed": 0,
+ "silent_wrong_effect": true,
+ "steps": 14,
+ "task_id": "winclaims-47bc79d5c4",
+ "verdict": "REFUTED"
+ },
+ {
+ "action_errors": 0,
+ "agent": "random",
+ "claim": "success",
+ "fault": "wrong_row",
+ "feasible": false,
+ "judge_error": null,
+ "reset_s": 6.93,
+ "reward": 0.0,
+ "seconds": 29.65,
+ "seed": 0,
+ "silent_wrong_effect": true,
+ "steps": 11,
+ "task_id": "winclaims-47bc79d5c4",
+ "verdict": "REFUTED"
+ },
+ {
+ "action_errors": 0,
+ "agent": "scripted",
+ "claim": "success",
+ "fault": "ok",
+ "feasible": true,
+ "judge_error": null,
+ "reset_s": 6.63,
+ "reward": 1.0,
+ "seconds": 41.88,
+ "seed": 0,
+ "silent_wrong_effect": false,
+ "steps": 14,
+ "task_id": "winclaims-0b6da80ac6",
+ "verdict": "CONFIRMED"
+ },
+ {
+ "action_errors": 0,
+ "agent": "screen_trusting",
+ "claim": "success",
+ "derived_from": "scripted",
+ "fault": "ok",
+ "feasible": true,
+ "judge_error": null,
+ "reset_s": null,
+ "reward": 1.0,
+ "seconds": 41.88,
+ "seed": 0,
+ "silent_wrong_effect": false,
+ "steps": 14,
+ "task_id": "winclaims-0b6da80ac6",
+ "verdict": "CONFIRMED"
+ },
+ {
+ "action_errors": 0,
+ "agent": "planted_fault",
+ "claim": "success",
+ "fault": "wrong_row",
+ "feasible": false,
+ "judge_error": null,
+ "reset_s": 6.54,
+ "reward": 0.0,
+ "seconds": 47.62,
+ "seed": 0,
+ "silent_wrong_effect": true,
+ "steps": 14,
+ "task_id": "winclaims-0b6da80ac6",
+ "verdict": "REFUTED"
+ },
+ {
+ "action_errors": 0,
+ "agent": "random",
+ "claim": "success",
+ "fault": "ok",
+ "feasible": true,
+ "judge_error": null,
+ "reset_s": 6.5,
+ "reward": 0.0,
+ "seconds": 29.11,
+ "seed": 0,
+ "silent_wrong_effect": true,
+ "steps": 11,
+ "task_id": "winclaims-0b6da80ac6",
+ "verdict": "REFUTED"
+ },
+ {
+ "action_errors": 0,
+ "agent": "scripted",
+ "claim": "success",
+ "fault": "ok",
+ "feasible": true,
+ "judge_error": null,
+ "reset_s": 6.49,
+ "reward": 1.0,
+ "seconds": 42.05,
+ "seed": 0,
+ "silent_wrong_effect": false,
+ "steps": 14,
+ "task_id": "winclaims-1628cd5fe1",
+ "verdict": "CONFIRMED"
+ },
+ {
+ "action_errors": 0,
+ "agent": "screen_trusting",
+ "claim": "success",
+ "derived_from": "scripted",
+ "fault": "ok",
+ "feasible": true,
+ "judge_error": null,
+ "reset_s": null,
+ "reward": 1.0,
+ "seconds": 42.05,
+ "seed": 0,
+ "silent_wrong_effect": false,
+ "steps": 14,
+ "task_id": "winclaims-1628cd5fe1",
+ "verdict": "CONFIRMED"
+ },
+ {
+ "action_errors": 0,
+ "agent": "planted_fault",
+ "claim": "success",
+ "fault": "duplicate",
+ "feasible": false,
+ "judge_error": null,
+ "reset_s": 6.52,
+ "reward": 0.0,
+ "seconds": 46.39,
+ "seed": 0,
+ "silent_wrong_effect": true,
+ "steps": 14,
+ "task_id": "winclaims-1628cd5fe1",
+ "verdict": "REFUTED"
+ },
+ {
+ "action_errors": 0,
+ "agent": "random",
+ "claim": "success",
+ "fault": "ok",
+ "feasible": true,
+ "judge_error": null,
+ "reset_s": 6.48,
+ "reward": 0.0,
+ "seconds": 30.42,
+ "seed": 0,
+ "silent_wrong_effect": true,
+ "steps": 11,
+ "task_id": "winclaims-1628cd5fe1",
+ "verdict": "REFUTED"
+ },
+ {
+ "action_errors": 0,
+ "agent": "scripted",
+ "claim": "success",
+ "fault": "drop_first",
+ "feasible": true,
+ "judge_error": null,
+ "reset_s": 6.56,
+ "reward": 1.0,
+ "seconds": 67.13,
+ "seed": 0,
+ "silent_wrong_effect": false,
+ "steps": 23,
+ "task_id": "winclaims-43e35c19cb",
+ "verdict": "CONFIRMED"
+ },
+ {
+ "action_errors": 0,
+ "agent": "screen_trusting",
+ "claim": "success",
+ "derived_from": "scripted",
+ "fault": "drop_first",
+ "feasible": true,
+ "judge_error": null,
+ "reset_s": null,
+ "reward": 1.0,
+ "seconds": 67.13,
+ "seed": 0,
+ "silent_wrong_effect": false,
+ "steps": 23,
+ "task_id": "winclaims-43e35c19cb",
+ "verdict": "CONFIRMED"
+ },
+ {
+ "action_errors": 0,
+ "agent": "planted_fault",
+ "claim": "success",
+ "fault": "truncate",
+ "feasible": false,
+ "judge_error": null,
+ "reset_s": 6.95,
+ "reward": 0.0,
+ "seconds": 72.18,
+ "seed": 0,
+ "silent_wrong_effect": true,
+ "steps": 23,
+ "task_id": "winclaims-43e35c19cb",
+ "verdict": "REFUTED"
+ },
+ {
+ "action_errors": 0,
+ "agent": "random",
+ "claim": "success",
+ "fault": "drop_first",
+ "feasible": true,
+ "judge_error": null,
+ "reset_s": 6.68,
+ "reward": 0.0,
+ "seconds": 29.36,
+ "seed": 0,
+ "silent_wrong_effect": true,
+ "steps": 11,
+ "task_id": "winclaims-43e35c19cb",
+ "verdict": "REFUTED"
+ },
+ {
+ "action_errors": 0,
+ "agent": "scripted",
+ "claim": "success",
+ "fault": "ok",
+ "feasible": true,
+ "judge_error": null,
+ "reset_s": 6.67,
+ "reward": 1.0,
+ "seconds": 42.18,
+ "seed": 0,
+ "silent_wrong_effect": false,
+ "steps": 14,
+ "task_id": "winclaims-f7883acff6",
+ "verdict": "CONFIRMED"
+ },
+ {
+ "action_errors": 0,
+ "agent": "screen_trusting",
+ "claim": "success",
+ "derived_from": "scripted",
+ "fault": "ok",
+ "feasible": true,
+ "judge_error": null,
+ "reset_s": null,
+ "reward": 1.0,
+ "seconds": 42.18,
+ "seed": 0,
+ "silent_wrong_effect": false,
+ "steps": 14,
+ "task_id": "winclaims-f7883acff6",
+ "verdict": "CONFIRMED"
+ },
+ {
+ "action_errors": 0,
+ "agent": "planted_fault",
+ "claim": "success",
+ "fault": "stale",
+ "feasible": false,
+ "judge_error": null,
+ "reset_s": 6.57,
+ "reward": 0.0,
+ "seconds": 46.4,
+ "seed": 0,
+ "silent_wrong_effect": true,
+ "steps": 14,
+ "task_id": "winclaims-f7883acff6",
+ "verdict": "REFUTED"
+ },
+ {
+ "action_errors": 0,
+ "agent": "random",
+ "claim": "success",
+ "fault": "ok",
+ "feasible": true,
+ "judge_error": null,
+ "reset_s": 6.55,
+ "reward": 0.0,
+ "seconds": 29.48,
+ "seed": 0,
+ "silent_wrong_effect": true,
+ "steps": 11,
+ "task_id": "winclaims-f7883acff6",
+ "verdict": "REFUTED"
+ },
+ {
+ "action_errors": 0,
+ "agent": "scripted",
+ "claim": "success",
+ "fault": "ok",
+ "feasible": true,
+ "judge_error": null,
+ "reset_s": 6.57,
+ "reward": 1.0,
+ "seconds": 42.61,
+ "seed": 0,
+ "silent_wrong_effect": false,
+ "steps": 14,
+ "task_id": "winclaims-86281e6614",
+ "verdict": "CONFIRMED"
+ },
+ {
+ "action_errors": 0,
+ "agent": "screen_trusting",
+ "claim": "success",
+ "derived_from": "scripted",
+ "fault": "ok",
+ "feasible": true,
+ "judge_error": null,
+ "reset_s": null,
+ "reward": 1.0,
+ "seconds": 42.61,
+ "seed": 0,
+ "silent_wrong_effect": false,
+ "steps": 14,
+ "task_id": "winclaims-86281e6614",
+ "verdict": "CONFIRMED"
+ },
+ {
+ "action_errors": 0,
+ "agent": "planted_fault",
+ "claim": "success",
+ "fault": "drop",
+ "feasible": false,
+ "judge_error": null,
+ "reset_s": 6.9,
+ "reward": 0.0,
+ "seconds": 48.82,
+ "seed": 0,
+ "silent_wrong_effect": true,
+ "steps": 14,
+ "task_id": "winclaims-86281e6614",
+ "verdict": "REFUTED"
+ },
+ {
+ "action_errors": 0,
+ "agent": "random",
+ "claim": "success",
+ "fault": "ok",
+ "feasible": true,
+ "judge_error": null,
+ "reset_s": 6.81,
+ "reward": 0.0,
+ "seconds": 30.55,
+ "seed": 0,
+ "silent_wrong_effect": true,
+ "steps": 11,
+ "task_id": "winclaims-86281e6614",
+ "verdict": "REFUTED"
+ },
+ {
+ "action_errors": 0,
+ "agent": "scripted",
+ "claim": "failure",
+ "fault": "drop",
+ "feasible": false,
+ "judge_error": null,
+ "reset_s": 6.52,
+ "reward": 1.0,
+ "seconds": 47.07,
+ "seed": 0,
+ "silent_wrong_effect": false,
+ "steps": 14,
+ "task_id": "winclaims-a70198c8ef",
+ "verdict": "REFUTED"
+ },
+ {
+ "action_errors": 0,
+ "agent": "screen_trusting",
+ "claim": "success",
+ "derived_from": "scripted",
+ "fault": "drop",
+ "feasible": false,
+ "judge_error": null,
+ "reset_s": null,
+ "reward": 0.0,
+ "seconds": 47.07,
+ "seed": 0,
+ "silent_wrong_effect": true,
+ "steps": 14,
+ "task_id": "winclaims-a70198c8ef",
+ "verdict": "REFUTED"
+ },
+ {
+ "action_errors": 0,
+ "agent": "random",
+ "claim": "success",
+ "fault": "drop",
+ "feasible": false,
+ "judge_error": null,
+ "reset_s": 6.48,
+ "reward": 0.0,
+ "seconds": 28.84,
+ "seed": 0,
+ "silent_wrong_effect": true,
+ "steps": 11,
+ "task_id": "winclaims-a70198c8ef",
+ "verdict": "REFUTED"
+ },
+ {
+ "action_errors": 0,
+ "agent": "scripted",
+ "claim": "failure",
+ "fault": "truncate",
+ "feasible": false,
+ "judge_error": null,
+ "reset_s": 6.41,
+ "reward": 1.0,
+ "seconds": 46.97,
+ "seed": 0,
+ "silent_wrong_effect": false,
+ "steps": 14,
+ "task_id": "winclaims-5b0c5a32ac",
+ "verdict": "REFUTED"
+ },
+ {
+ "action_errors": 0,
+ "agent": "screen_trusting",
+ "claim": "success",
+ "derived_from": "scripted",
+ "fault": "truncate",
+ "feasible": false,
+ "judge_error": null,
+ "reset_s": null,
+ "reward": 0.0,
+ "seconds": 46.97,
+ "seed": 0,
+ "silent_wrong_effect": true,
+ "steps": 14,
+ "task_id": "winclaims-5b0c5a32ac",
+ "verdict": "REFUTED"
+ },
+ {
+ "action_errors": 0,
+ "agent": "random",
+ "claim": "success",
+ "fault": "truncate",
+ "feasible": false,
+ "judge_error": null,
+ "reset_s": 6.5,
+ "reward": 0.0,
+ "seconds": 29.79,
+ "seed": 0,
+ "silent_wrong_effect": true,
+ "steps": 11,
+ "task_id": "winclaims-5b0c5a32ac",
+ "verdict": "REFUTED"
+ },
+ {
+ "action_errors": 0,
+ "agent": "scripted",
+ "claim": "success",
+ "fault": "ok",
+ "feasible": true,
+ "judge_error": null,
+ "reset_s": 6.55,
+ "reward": 1.0,
+ "seconds": 42.3,
+ "seed": 0,
+ "silent_wrong_effect": false,
+ "steps": 14,
+ "task_id": "winclaims-ef30c53031",
+ "verdict": "CONFIRMED"
+ },
+ {
+ "action_errors": 0,
+ "agent": "screen_trusting",
+ "claim": "success",
+ "derived_from": "scripted",
+ "fault": "ok",
+ "feasible": true,
+ "judge_error": null,
+ "reset_s": null,
+ "reward": 1.0,
+ "seconds": 42.3,
+ "seed": 0,
+ "silent_wrong_effect": false,
+ "steps": 14,
+ "task_id": "winclaims-ef30c53031",
+ "verdict": "CONFIRMED"
+ },
+ {
+ "action_errors": 0,
+ "agent": "planted_fault",
+ "claim": "success",
+ "fault": "truncate",
+ "feasible": false,
+ "judge_error": null,
+ "reset_s": 6.63,
+ "reward": 0.0,
+ "seconds": 46.34,
+ "seed": 0,
+ "silent_wrong_effect": true,
+ "steps": 14,
+ "task_id": "winclaims-ef30c53031",
+ "verdict": "REFUTED"
+ },
+ {
+ "action_errors": 0,
+ "agent": "random",
+ "claim": "success",
+ "fault": "ok",
+ "feasible": true,
+ "judge_error": null,
+ "reset_s": 6.38,
+ "reward": 0.0,
+ "seconds": 28.2,
+ "seed": 0,
+ "silent_wrong_effect": true,
+ "steps": 11,
+ "task_id": "winclaims-ef30c53031",
+ "verdict": "REFUTED"
+ },
+ {
+ "action_errors": 0,
+ "agent": "scripted",
+ "claim": "success",
+ "fault": "ok",
+ "feasible": true,
+ "judge_error": null,
+ "reset_s": 6.54,
+ "reward": 1.0,
+ "seconds": 43.12,
+ "seed": 0,
+ "silent_wrong_effect": false,
+ "steps": 14,
+ "task_id": "winclaims-a64ea5d937",
+ "verdict": "CONFIRMED"
+ },
+ {
+ "action_errors": 0,
+ "agent": "screen_trusting",
+ "claim": "success",
+ "derived_from": "scripted",
+ "fault": "ok",
+ "feasible": true,
+ "judge_error": null,
+ "reset_s": null,
+ "reward": 1.0,
+ "seconds": 43.12,
+ "seed": 0,
+ "silent_wrong_effect": false,
+ "steps": 14,
+ "task_id": "winclaims-a64ea5d937",
+ "verdict": "CONFIRMED"
+ },
+ {
+ "action_errors": 0,
+ "agent": "planted_fault",
+ "claim": "success",
+ "fault": "stale",
+ "feasible": false,
+ "judge_error": null,
+ "reset_s": 6.7,
+ "reward": 0.0,
+ "seconds": 48.86,
+ "seed": 0,
+ "silent_wrong_effect": true,
+ "steps": 14,
+ "task_id": "winclaims-a64ea5d937",
+ "verdict": "REFUTED"
+ },
+ {
+ "action_errors": 0,
+ "agent": "random",
+ "claim": "success",
+ "fault": "ok",
+ "feasible": true,
+ "judge_error": null,
+ "reset_s": 6.61,
+ "reward": 0.0,
+ "seconds": 30.03,
+ "seed": 0,
+ "silent_wrong_effect": true,
+ "steps": 11,
+ "task_id": "winclaims-a64ea5d937",
+ "verdict": "REFUTED"
+ },
+ {
+ "action_errors": 0,
+ "agent": "scripted",
+ "claim": "failure",
+ "fault": "wrong_row",
+ "feasible": false,
+ "judge_error": null,
+ "reset_s": 6.75,
+ "reward": 1.0,
+ "seconds": 48.12,
+ "seed": 0,
+ "silent_wrong_effect": false,
+ "steps": 14,
+ "task_id": "winclaims-a2a3b6542e",
+ "verdict": "REFUTED"
+ },
+ {
+ "action_errors": 0,
+ "agent": "screen_trusting",
+ "claim": "success",
+ "derived_from": "scripted",
+ "fault": "wrong_row",
+ "feasible": false,
+ "judge_error": null,
+ "reset_s": null,
+ "reward": 0.0,
+ "seconds": 48.12,
+ "seed": 0,
+ "silent_wrong_effect": true,
+ "steps": 14,
+ "task_id": "winclaims-a2a3b6542e",
+ "verdict": "REFUTED"
+ },
+ {
+ "action_errors": 0,
+ "agent": "random",
+ "claim": "success",
+ "fault": "wrong_row",
+ "feasible": false,
+ "judge_error": null,
+ "reset_s": 6.43,
+ "reward": 0.0,
+ "seconds": 28.66,
+ "seed": 0,
+ "silent_wrong_effect": true,
+ "steps": 11,
+ "task_id": "winclaims-a2a3b6542e",
+ "verdict": "REFUTED"
+ },
+ {
+ "action_errors": 0,
+ "agent": "scripted",
+ "claim": "success",
+ "fault": "ok",
+ "feasible": true,
+ "judge_error": null,
+ "reset_s": 6.66,
+ "reward": 1.0,
+ "seconds": 44.84,
+ "seed": 0,
+ "silent_wrong_effect": false,
+ "steps": 14,
+ "task_id": "winclaims-58a5a7888a",
+ "verdict": "CONFIRMED"
+ },
+ {
+ "action_errors": 0,
+ "agent": "screen_trusting",
+ "claim": "success",
+ "derived_from": "scripted",
+ "fault": "ok",
+ "feasible": true,
+ "judge_error": null,
+ "reset_s": null,
+ "reward": 1.0,
+ "seconds": 44.84,
+ "seed": 0,
+ "silent_wrong_effect": false,
+ "steps": 14,
+ "task_id": "winclaims-58a5a7888a",
+ "verdict": "CONFIRMED"
+ },
+ {
+ "action_errors": 0,
+ "agent": "planted_fault",
+ "claim": "success",
+ "fault": "wrong_row",
+ "feasible": false,
+ "judge_error": null,
+ "reset_s": 6.9,
+ "reward": 0.0,
+ "seconds": 49.24,
+ "seed": 0,
+ "silent_wrong_effect": true,
+ "steps": 14,
+ "task_id": "winclaims-58a5a7888a",
+ "verdict": "REFUTED"
+ },
+ {
+ "action_errors": 0,
+ "agent": "random",
+ "claim": "success",
+ "fault": "ok",
+ "feasible": true,
+ "judge_error": null,
+ "reset_s": 6.52,
+ "reward": 0.0,
+ "seconds": 29.46,
+ "seed": 0,
+ "silent_wrong_effect": true,
+ "steps": 11,
+ "task_id": "winclaims-58a5a7888a",
+ "verdict": "REFUTED"
+ },
+ {
+ "action_errors": 0,
+ "agent": "scripted",
+ "claim": "failure",
+ "fault": "stale",
+ "feasible": false,
+ "judge_error": null,
+ "reset_s": 6.57,
+ "reward": 1.0,
+ "seconds": 46.0,
+ "seed": 0,
+ "silent_wrong_effect": false,
+ "steps": 14,
+ "task_id": "winclaims-f64c53f6b4",
+ "verdict": "REFUTED"
+ },
+ {
+ "action_errors": 0,
+ "agent": "screen_trusting",
+ "claim": "success",
+ "derived_from": "scripted",
+ "fault": "stale",
+ "feasible": false,
+ "judge_error": null,
+ "reset_s": null,
+ "reward": 0.0,
+ "seconds": 46.0,
+ "seed": 0,
+ "silent_wrong_effect": true,
+ "steps": 14,
+ "task_id": "winclaims-f64c53f6b4",
+ "verdict": "REFUTED"
+ },
+ {
+ "action_errors": 0,
+ "agent": "random",
+ "claim": "success",
+ "fault": "stale",
+ "feasible": false,
+ "judge_error": null,
+ "reset_s": 6.79,
+ "reward": 0.0,
+ "seconds": 30.33,
+ "seed": 0,
+ "silent_wrong_effect": true,
+ "steps": 11,
+ "task_id": "winclaims-f64c53f6b4",
+ "verdict": "REFUTED"
+ },
+ {
+ "action_errors": 0,
+ "agent": "scripted",
+ "claim": "failure",
+ "fault": "drop",
+ "feasible": false,
+ "judge_error": null,
+ "reset_s": 6.73,
+ "reward": 1.0,
+ "seconds": 47.54,
+ "seed": 0,
+ "silent_wrong_effect": false,
+ "steps": 14,
+ "task_id": "winclaims-7e1ed7aa45",
+ "verdict": "REFUTED"
+ },
+ {
+ "action_errors": 0,
+ "agent": "screen_trusting",
+ "claim": "success",
+ "derived_from": "scripted",
+ "fault": "drop",
+ "feasible": false,
+ "judge_error": null,
+ "reset_s": null,
+ "reward": 0.0,
+ "seconds": 47.54,
+ "seed": 0,
+ "silent_wrong_effect": true,
+ "steps": 14,
+ "task_id": "winclaims-7e1ed7aa45",
+ "verdict": "REFUTED"
+ },
+ {
+ "action_errors": 0,
+ "agent": "random",
+ "claim": "success",
+ "fault": "drop",
+ "feasible": false,
+ "judge_error": null,
+ "reset_s": 6.58,
+ "reward": 0.0,
+ "seconds": 29.74,
+ "seed": 0,
+ "silent_wrong_effect": true,
+ "steps": 11,
+ "task_id": "winclaims-7e1ed7aa45",
+ "verdict": "REFUTED"
+ },
+ {
+ "action_errors": 0,
+ "agent": "scripted",
+ "claim": "failure",
+ "fault": "wrong_row",
+ "feasible": false,
+ "judge_error": null,
+ "reset_s": 6.61,
+ "reward": 1.0,
+ "seconds": 48.55,
+ "seed": 0,
+ "silent_wrong_effect": false,
+ "steps": 14,
+ "task_id": "winclaims-4b213973e5",
+ "verdict": "REFUTED"
+ },
+ {
+ "action_errors": 0,
+ "agent": "screen_trusting",
+ "claim": "success",
+ "derived_from": "scripted",
+ "fault": "wrong_row",
+ "feasible": false,
+ "judge_error": null,
+ "reset_s": null,
+ "reward": 0.0,
+ "seconds": 48.55,
+ "seed": 0,
+ "silent_wrong_effect": true,
+ "steps": 14,
+ "task_id": "winclaims-4b213973e5",
+ "verdict": "REFUTED"
+ },
+ {
+ "action_errors": 0,
+ "agent": "random",
+ "claim": "success",
+ "fault": "wrong_row",
+ "feasible": false,
+ "judge_error": null,
+ "reset_s": 6.71,
+ "reward": 0.0,
+ "seconds": 30.39,
+ "seed": 0,
+ "silent_wrong_effect": true,
+ "steps": 11,
+ "task_id": "winclaims-4b213973e5",
+ "verdict": "REFUTED"
+ },
+ {
+ "action_errors": 0,
+ "agent": "scripted",
+ "claim": "success",
+ "fault": "drop_first",
+ "feasible": true,
+ "judge_error": null,
+ "reset_s": 6.91,
+ "reward": 1.0,
+ "seconds": 66.4,
+ "seed": 0,
+ "silent_wrong_effect": false,
+ "steps": 23,
+ "task_id": "winclaims-8821889da6",
+ "verdict": "CONFIRMED"
+ },
+ {
+ "action_errors": 0,
+ "agent": "screen_trusting",
+ "claim": "success",
+ "derived_from": "scripted",
+ "fault": "drop_first",
+ "feasible": true,
+ "judge_error": null,
+ "reset_s": null,
+ "reward": 1.0,
+ "seconds": 66.4,
+ "seed": 0,
+ "silent_wrong_effect": false,
+ "steps": 23,
+ "task_id": "winclaims-8821889da6",
+ "verdict": "CONFIRMED"
+ },
+ {
+ "action_errors": 0,
+ "agent": "planted_fault",
+ "claim": "success",
+ "fault": "drop",
+ "feasible": false,
+ "judge_error": null,
+ "reset_s": 6.57,
+ "reward": 0.0,
+ "seconds": 68.84,
+ "seed": 0,
+ "silent_wrong_effect": true,
+ "steps": 23,
+ "task_id": "winclaims-8821889da6",
+ "verdict": "REFUTED"
+ },
+ {
+ "action_errors": 0,
+ "agent": "random",
+ "claim": "success",
+ "fault": "drop_first",
+ "feasible": true,
+ "judge_error": null,
+ "reset_s": 6.68,
+ "reward": 0.0,
+ "seconds": 29.95,
+ "seed": 0,
+ "silent_wrong_effect": true,
+ "steps": 11,
+ "task_id": "winclaims-8821889da6",
+ "verdict": "REFUTED"
+ },
+ {
+ "action_errors": 0,
+ "agent": "scripted",
+ "claim": "success",
+ "fault": "drop_first",
+ "feasible": true,
+ "judge_error": null,
+ "reset_s": 6.58,
+ "reward": 1.0,
+ "seconds": 65.9,
+ "seed": 0,
+ "silent_wrong_effect": false,
+ "steps": 23,
+ "task_id": "winclaims-232feac081",
+ "verdict": "CONFIRMED"
+ },
+ {
+ "action_errors": 0,
+ "agent": "screen_trusting",
+ "claim": "success",
+ "derived_from": "scripted",
+ "fault": "drop_first",
+ "feasible": true,
+ "judge_error": null,
+ "reset_s": null,
+ "reward": 1.0,
+ "seconds": 65.9,
+ "seed": 0,
+ "silent_wrong_effect": false,
+ "steps": 23,
+ "task_id": "winclaims-232feac081",
+ "verdict": "CONFIRMED"
+ },
+ {
+ "action_errors": 0,
+ "agent": "planted_fault",
+ "claim": "success",
+ "fault": "wrong_row",
+ "feasible": false,
+ "judge_error": null,
+ "reset_s": 6.83,
+ "reward": 0.0,
+ "seconds": 68.78,
+ "seed": 0,
+ "silent_wrong_effect": true,
+ "steps": 23,
+ "task_id": "winclaims-232feac081",
+ "verdict": "REFUTED"
+ },
+ {
+ "action_errors": 0,
+ "agent": "random",
+ "claim": "success",
+ "fault": "drop_first",
+ "feasible": true,
+ "judge_error": null,
+ "reset_s": 6.63,
+ "reward": 0.0,
+ "seconds": 30.25,
+ "seed": 0,
+ "silent_wrong_effect": true,
+ "steps": 11,
+ "task_id": "winclaims-232feac081",
+ "verdict": "REFUTED"
+ },
+ {
+ "action_errors": 0,
+ "agent": "scripted",
+ "claim": "success",
+ "fault": "ok",
+ "feasible": true,
+ "judge_error": null,
+ "reset_s": 6.76,
+ "reward": 1.0,
+ "seconds": 42.44,
+ "seed": 0,
+ "silent_wrong_effect": false,
+ "steps": 14,
+ "task_id": "winclaims-2c8d585a77",
+ "verdict": "CONFIRMED"
+ },
+ {
+ "action_errors": 0,
+ "agent": "screen_trusting",
+ "claim": "success",
+ "derived_from": "scripted",
+ "fault": "ok",
+ "feasible": true,
+ "judge_error": null,
+ "reset_s": null,
+ "reward": 1.0,
+ "seconds": 42.44,
+ "seed": 0,
+ "silent_wrong_effect": false,
+ "steps": 14,
+ "task_id": "winclaims-2c8d585a77",
+ "verdict": "CONFIRMED"
+ },
+ {
+ "action_errors": 0,
+ "agent": "planted_fault",
+ "claim": "success",
+ "fault": "duplicate",
+ "feasible": false,
+ "judge_error": null,
+ "reset_s": 6.69,
+ "reward": 0.0,
+ "seconds": 49.11,
+ "seed": 0,
+ "silent_wrong_effect": true,
+ "steps": 14,
+ "task_id": "winclaims-2c8d585a77",
+ "verdict": "REFUTED"
+ },
+ {
+ "action_errors": 0,
+ "agent": "random",
+ "claim": "success",
+ "fault": "ok",
+ "feasible": true,
+ "judge_error": null,
+ "reset_s": 6.71,
+ "reward": 0.0,
+ "seconds": 29.53,
+ "seed": 0,
+ "silent_wrong_effect": true,
+ "steps": 11,
+ "task_id": "winclaims-2c8d585a77",
+ "verdict": "REFUTED"
+ },
+ {
+ "action_errors": 0,
+ "agent": "scripted",
+ "claim": "success",
+ "fault": "ok",
+ "feasible": true,
+ "judge_error": null,
+ "reset_s": 6.35,
+ "reward": 1.0,
+ "seconds": 43.26,
+ "seed": 0,
+ "silent_wrong_effect": false,
+ "steps": 14,
+ "task_id": "winclaims-d95991d94a",
+ "verdict": "CONFIRMED"
+ },
+ {
+ "action_errors": 0,
+ "agent": "screen_trusting",
+ "claim": "success",
+ "derived_from": "scripted",
+ "fault": "ok",
+ "feasible": true,
+ "judge_error": null,
+ "reset_s": null,
+ "reward": 1.0,
+ "seconds": 43.26,
+ "seed": 0,
+ "silent_wrong_effect": false,
+ "steps": 14,
+ "task_id": "winclaims-d95991d94a",
+ "verdict": "CONFIRMED"
+ },
+ {
+ "action_errors": 0,
+ "agent": "planted_fault",
+ "claim": "success",
+ "fault": "truncate",
+ "feasible": false,
+ "judge_error": null,
+ "reset_s": 6.65,
+ "reward": 0.0,
+ "seconds": 50.05,
+ "seed": 0,
+ "silent_wrong_effect": true,
+ "steps": 14,
+ "task_id": "winclaims-d95991d94a",
+ "verdict": "REFUTED"
+ },
+ {
+ "action_errors": 0,
+ "agent": "random",
+ "claim": "success",
+ "fault": "ok",
+ "feasible": true,
+ "judge_error": null,
+ "reset_s": 6.52,
+ "reward": 0.0,
+ "seconds": 30.45,
+ "seed": 0,
+ "silent_wrong_effect": true,
+ "steps": 11,
+ "task_id": "winclaims-d95991d94a",
+ "verdict": "REFUTED"
+ },
+ {
+ "action_errors": 0,
+ "agent": "scripted",
+ "claim": "failure",
+ "fault": "stale",
+ "feasible": false,
+ "judge_error": null,
+ "reset_s": 6.78,
+ "reward": 1.0,
+ "seconds": 48.79,
+ "seed": 0,
+ "silent_wrong_effect": false,
+ "steps": 14,
+ "task_id": "winclaims-6ad69b812c",
+ "verdict": "REFUTED"
+ },
+ {
+ "action_errors": 0,
+ "agent": "screen_trusting",
+ "claim": "success",
+ "derived_from": "scripted",
+ "fault": "stale",
+ "feasible": false,
+ "judge_error": null,
+ "reset_s": null,
+ "reward": 0.0,
+ "seconds": 48.79,
+ "seed": 0,
+ "silent_wrong_effect": true,
+ "steps": 14,
+ "task_id": "winclaims-6ad69b812c",
+ "verdict": "REFUTED"
+ },
+ {
+ "action_errors": 0,
+ "agent": "random",
+ "claim": "success",
+ "fault": "stale",
+ "feasible": false,
+ "judge_error": null,
+ "reset_s": 6.74,
+ "reward": 0.0,
+ "seconds": 32.34,
+ "seed": 0,
+ "silent_wrong_effect": true,
+ "steps": 11,
+ "task_id": "winclaims-6ad69b812c",
+ "verdict": "REFUTED"
+ },
+ {
+ "action_errors": 0,
+ "agent": "scripted",
+ "claim": "failure",
+ "fault": "truncate",
+ "feasible": false,
+ "judge_error": null,
+ "reset_s": 6.61,
+ "reward": 1.0,
+ "seconds": 48.31,
+ "seed": 0,
+ "silent_wrong_effect": false,
+ "steps": 14,
+ "task_id": "winclaims-6d743438e4",
+ "verdict": "REFUTED"
+ },
+ {
+ "action_errors": 0,
+ "agent": "screen_trusting",
+ "claim": "success",
+ "derived_from": "scripted",
+ "fault": "truncate",
+ "feasible": false,
+ "judge_error": null,
+ "reset_s": null,
+ "reward": 0.0,
+ "seconds": 48.31,
+ "seed": 0,
+ "silent_wrong_effect": true,
+ "steps": 14,
+ "task_id": "winclaims-6d743438e4",
+ "verdict": "REFUTED"
+ },
+ {
+ "action_errors": 0,
+ "agent": "random",
+ "claim": "success",
+ "fault": "truncate",
+ "feasible": false,
+ "judge_error": null,
+ "reset_s": 6.63,
+ "reward": 0.0,
+ "seconds": 30.18,
+ "seed": 0,
+ "silent_wrong_effect": true,
+ "steps": 11,
+ "task_id": "winclaims-6d743438e4",
+ "verdict": "REFUTED"
+ },
+ {
+ "action_errors": 0,
+ "agent": "scripted",
+ "claim": "failure",
+ "fault": "duplicate",
+ "feasible": false,
+ "judge_error": null,
+ "reset_s": 6.63,
+ "reward": 1.0,
+ "seconds": 46.77,
+ "seed": 0,
+ "silent_wrong_effect": false,
+ "steps": 14,
+ "task_id": "winclaims-5095144dcd",
+ "verdict": "REFUTED"
+ },
+ {
+ "action_errors": 0,
+ "agent": "screen_trusting",
+ "claim": "success",
+ "derived_from": "scripted",
+ "fault": "duplicate",
+ "feasible": false,
+ "judge_error": null,
+ "reset_s": null,
+ "reward": 0.0,
+ "seconds": 46.77,
+ "seed": 0,
+ "silent_wrong_effect": true,
+ "steps": 14,
+ "task_id": "winclaims-5095144dcd",
+ "verdict": "REFUTED"
+ },
+ {
+ "action_errors": 0,
+ "agent": "random",
+ "claim": "success",
+ "fault": "duplicate",
+ "feasible": false,
+ "judge_error": null,
+ "reset_s": 6.41,
+ "reward": 0.0,
+ "seconds": 29.5,
+ "seed": 0,
+ "silent_wrong_effect": true,
+ "steps": 11,
+ "task_id": "winclaims-5095144dcd",
+ "verdict": "REFUTED"
+ },
+ {
+ "action_errors": 0,
+ "agent": "scripted",
+ "claim": "failure",
+ "fault": "duplicate",
+ "feasible": false,
+ "judge_error": null,
+ "reset_s": 6.62,
+ "reward": 1.0,
+ "seconds": 45.71,
+ "seed": 0,
+ "silent_wrong_effect": false,
+ "steps": 14,
+ "task_id": "winclaims-05a2a4983b",
+ "verdict": "REFUTED"
+ },
+ {
+ "action_errors": 0,
+ "agent": "screen_trusting",
+ "claim": "success",
+ "derived_from": "scripted",
+ "fault": "duplicate",
+ "feasible": false,
+ "judge_error": null,
+ "reset_s": null,
+ "reward": 0.0,
+ "seconds": 45.71,
+ "seed": 0,
+ "silent_wrong_effect": true,
+ "steps": 14,
+ "task_id": "winclaims-05a2a4983b",
+ "verdict": "REFUTED"
+ },
+ {
+ "action_errors": 0,
+ "agent": "random",
+ "claim": "success",
+ "fault": "duplicate",
+ "feasible": false,
+ "judge_error": null,
+ "reset_s": 6.52,
+ "reward": 0.0,
+ "seconds": 28.1,
+ "seed": 0,
+ "silent_wrong_effect": true,
+ "steps": 11,
+ "task_id": "winclaims-05a2a4983b",
+ "verdict": "REFUTED"
+ },
+ {
+ "action_errors": 0,
+ "agent": "scripted",
+ "claim": "failure",
+ "fault": "drop",
+ "feasible": false,
+ "judge_error": null,
+ "reset_s": 6.36,
+ "reward": 1.0,
+ "seconds": 50.12,
+ "seed": 0,
+ "silent_wrong_effect": false,
+ "steps": 14,
+ "task_id": "winclaims-3e05fded8d",
+ "verdict": "REFUTED"
+ },
+ {
+ "action_errors": 0,
+ "agent": "screen_trusting",
+ "claim": "success",
+ "derived_from": "scripted",
+ "fault": "drop",
+ "feasible": false,
+ "judge_error": null,
+ "reset_s": null,
+ "reward": 0.0,
+ "seconds": 50.12,
+ "seed": 0,
+ "silent_wrong_effect": true,
+ "steps": 14,
+ "task_id": "winclaims-3e05fded8d",
+ "verdict": "REFUTED"
+ },
+ {
+ "action_errors": 0,
+ "agent": "random",
+ "claim": "success",
+ "fault": "drop",
+ "feasible": false,
+ "judge_error": null,
+ "reset_s": 6.64,
+ "reward": 0.0,
+ "seconds": 31.5,
+ "seed": 0,
+ "silent_wrong_effect": true,
+ "steps": 11,
+ "task_id": "winclaims-3e05fded8d",
+ "verdict": "REFUTED"
+ }
+ ],
+ "summary": {
+ "agents": {
+ "planted_fault": {
+ "action_errors": 0,
+ "episodes": 12,
+ "judge_errors": 0,
+ "mean_reward": 0.0,
+ "silent_wrong_effects": 12,
+ "verdicts": {
+ "CONFIRMED": 0,
+ "INDETERMINATE": 0,
+ "REFUTED": 12
+ }
+ },
+ "random": {
+ "action_errors": 0,
+ "episodes": 24,
+ "judge_errors": 0,
+ "mean_reward": 0.0,
+ "silent_wrong_effects": 24,
+ "verdicts": {
+ "CONFIRMED": 0,
+ "INDETERMINATE": 0,
+ "REFUTED": 24
+ }
+ },
+ "screen_trusting": {
+ "action_errors": 0,
+ "episodes": 24,
+ "judge_errors": 0,
+ "mean_reward": 0.5,
+ "silent_wrong_effects": 12,
+ "verdicts": {
+ "CONFIRMED": 12,
+ "INDETERMINATE": 0,
+ "REFUTED": 12
+ }
+ },
+ "scripted": {
+ "action_errors": 0,
+ "episodes": 24,
+ "judge_errors": 0,
+ "mean_reward": 1.0,
+ "silent_wrong_effects": 0,
+ "verdicts": {
+ "CONFIRMED": 12,
+ "INDETERMINATE": 0,
+ "REFUTED": 12
+ }
+ }
+ },
+ "checks": {
+ "every_feasible_task_fails_with_a_planted_fault": true,
+ "every_task_passes_with_its_solution": true,
+ "no_judge_errors": true,
+ "no_state_leaks": true,
+ "random_floor_margin": true,
+ "screen_trusting_paid_only_on_feasible": true
+ },
+ "env": "openadapt-win-claims-desk",
+ "feasible_tasks": 12,
+ "leak_checks": [
+ {
+ "app_processes": 1,
+ "digest_after_write_differs": true,
+ "note_field_after_reset": "",
+ "passed": true,
+ "reader": "winclaims-1628cd5fe1",
+ "records_after_reset": 1,
+ "records_in_pristine_seed": 1,
+ "restored_digest_is_pristine": true,
+ "writer": "winclaims-0b6da80ac6"
+ },
+ {
+ "app_processes": 1,
+ "digest_after_write_differs": true,
+ "note_field_after_reset": "",
+ "passed": true,
+ "reader": "winclaims-43e35c19cb",
+ "records_after_reset": 1,
+ "records_in_pristine_seed": 1,
+ "restored_digest_is_pristine": true,
+ "writer": "winclaims-1628cd5fe1"
+ }
+ ],
+ "passed": true,
+ "reset_s": {
+ "episodes": 60,
+ "max": 26.34,
+ "median": 6.62,
+ "p95": 6.91
+ },
+ "run": {
+ "model_calls": 0,
+ "server_platform": "Darwin arm64 py3.12.13",
+ "started": "2026-11-04T05:21:49Z",
+ "wall_s": 2655.5
+ },
+ "surface": "windows_uia",
+ "tasks": 24
+ }
+}
diff --git a/packages/flow/environments/openenv/_windows/results/windows11-x64-2026-11-04/win-patient-chart-rdp.json b/packages/flow/environments/openenv/_windows/results/windows11-x64-2026-11-04/win-patient-chart-rdp.json
new file mode 100644
index 0000000000..2aa94cf445
--- /dev/null
+++ b/packages/flow/environments/openenv/_windows/results/windows11-x64-2026-11-04/win-patient-chart-rdp.json
@@ -0,0 +1,1473 @@
+{
+ "episodes": [
+ {
+ "action_errors": 0,
+ "agent": "scripted",
+ "claim": "success",
+ "fault": "ok",
+ "feasible": true,
+ "judge_error": null,
+ "reset_s": 29.69,
+ "reward": 1.0,
+ "seconds": 52.19,
+ "seed": 0,
+ "silent_wrong_effect": false,
+ "steps": 11,
+ "task_id": "winchart-05152397d0",
+ "verdict": "CONFIRMED"
+ },
+ {
+ "action_errors": 0,
+ "agent": "screen_trusting",
+ "claim": "success",
+ "derived_from": "scripted",
+ "fault": "ok",
+ "feasible": true,
+ "judge_error": null,
+ "reset_s": null,
+ "reward": 1.0,
+ "seconds": 52.19,
+ "seed": 0,
+ "silent_wrong_effect": false,
+ "steps": 11,
+ "task_id": "winchart-05152397d0",
+ "verdict": "CONFIRMED"
+ },
+ {
+ "action_errors": 0,
+ "agent": "planted_fault",
+ "claim": "success",
+ "fault": "drop",
+ "feasible": false,
+ "judge_error": null,
+ "reset_s": 3.7,
+ "reward": 0.0,
+ "seconds": 30.92,
+ "seed": 0,
+ "silent_wrong_effect": true,
+ "steps": 11,
+ "task_id": "winchart-05152397d0",
+ "verdict": "REFUTED"
+ },
+ {
+ "action_errors": 0,
+ "agent": "random",
+ "claim": "failure",
+ "fault": "ok",
+ "feasible": true,
+ "judge_error": null,
+ "reset_s": 3.35,
+ "reward": 0.0,
+ "seconds": 20.23,
+ "seed": 0,
+ "silent_wrong_effect": false,
+ "steps": 11,
+ "task_id": "winchart-05152397d0",
+ "verdict": "REFUTED"
+ },
+ {
+ "action_errors": 0,
+ "agent": "scripted",
+ "claim": "success",
+ "fault": "ok",
+ "feasible": true,
+ "judge_error": null,
+ "reset_s": 3.36,
+ "reward": 1.0,
+ "seconds": 25.21,
+ "seed": 0,
+ "silent_wrong_effect": false,
+ "steps": 11,
+ "task_id": "winchart-0508cc32b5",
+ "verdict": "CONFIRMED"
+ },
+ {
+ "action_errors": 0,
+ "agent": "screen_trusting",
+ "claim": "success",
+ "derived_from": "scripted",
+ "fault": "ok",
+ "feasible": true,
+ "judge_error": null,
+ "reset_s": null,
+ "reward": 1.0,
+ "seconds": 25.21,
+ "seed": 0,
+ "silent_wrong_effect": false,
+ "steps": 11,
+ "task_id": "winchart-0508cc32b5",
+ "verdict": "CONFIRMED"
+ },
+ {
+ "action_errors": 0,
+ "agent": "planted_fault",
+ "claim": "success",
+ "fault": "wrong_row",
+ "feasible": false,
+ "judge_error": null,
+ "reset_s": 3.25,
+ "reward": 0.0,
+ "seconds": 29.63,
+ "seed": 0,
+ "silent_wrong_effect": true,
+ "steps": 11,
+ "task_id": "winchart-0508cc32b5",
+ "verdict": "REFUTED"
+ },
+ {
+ "action_errors": 0,
+ "agent": "random",
+ "claim": "failure",
+ "fault": "ok",
+ "feasible": true,
+ "judge_error": null,
+ "reset_s": 3.51,
+ "reward": 0.0,
+ "seconds": 19.95,
+ "seed": 0,
+ "silent_wrong_effect": false,
+ "steps": 11,
+ "task_id": "winchart-0508cc32b5",
+ "verdict": "REFUTED"
+ },
+ {
+ "action_errors": 0,
+ "agent": "scripted",
+ "claim": "failure",
+ "fault": "truncate",
+ "feasible": false,
+ "judge_error": null,
+ "reset_s": 3.32,
+ "reward": 1.0,
+ "seconds": 30.27,
+ "seed": 0,
+ "silent_wrong_effect": false,
+ "steps": 11,
+ "task_id": "winchart-d60d31ca58",
+ "verdict": "REFUTED"
+ },
+ {
+ "action_errors": 0,
+ "agent": "screen_trusting",
+ "claim": "success",
+ "derived_from": "scripted",
+ "fault": "truncate",
+ "feasible": false,
+ "judge_error": null,
+ "reset_s": null,
+ "reward": 0.0,
+ "seconds": 30.27,
+ "seed": 0,
+ "silent_wrong_effect": true,
+ "steps": 11,
+ "task_id": "winchart-d60d31ca58",
+ "verdict": "REFUTED"
+ },
+ {
+ "action_errors": 0,
+ "agent": "random",
+ "claim": "failure",
+ "fault": "truncate",
+ "feasible": false,
+ "judge_error": null,
+ "reset_s": 3.29,
+ "reward": 0.0,
+ "seconds": 19.81,
+ "seed": 0,
+ "silent_wrong_effect": false,
+ "steps": 11,
+ "task_id": "winchart-d60d31ca58",
+ "verdict": "REFUTED"
+ },
+ {
+ "action_errors": 0,
+ "agent": "scripted",
+ "claim": "failure",
+ "fault": "wrong_row",
+ "feasible": false,
+ "judge_error": null,
+ "reset_s": 3.39,
+ "reward": 1.0,
+ "seconds": 29.89,
+ "seed": 0,
+ "silent_wrong_effect": false,
+ "steps": 11,
+ "task_id": "winchart-6c39916c8c",
+ "verdict": "REFUTED"
+ },
+ {
+ "action_errors": 0,
+ "agent": "screen_trusting",
+ "claim": "success",
+ "derived_from": "scripted",
+ "fault": "wrong_row",
+ "feasible": false,
+ "judge_error": null,
+ "reset_s": null,
+ "reward": 0.0,
+ "seconds": 29.89,
+ "seed": 0,
+ "silent_wrong_effect": true,
+ "steps": 11,
+ "task_id": "winchart-6c39916c8c",
+ "verdict": "REFUTED"
+ },
+ {
+ "action_errors": 0,
+ "agent": "random",
+ "claim": "failure",
+ "fault": "wrong_row",
+ "feasible": false,
+ "judge_error": null,
+ "reset_s": 3.19,
+ "reward": 0.0,
+ "seconds": 19.71,
+ "seed": 0,
+ "silent_wrong_effect": false,
+ "steps": 11,
+ "task_id": "winchart-6c39916c8c",
+ "verdict": "REFUTED"
+ },
+ {
+ "action_errors": 0,
+ "agent": "scripted",
+ "claim": "failure",
+ "fault": "wrong_row",
+ "feasible": false,
+ "judge_error": null,
+ "reset_s": 3.21,
+ "reward": 1.0,
+ "seconds": 29.85,
+ "seed": 0,
+ "silent_wrong_effect": false,
+ "steps": 11,
+ "task_id": "winchart-6ed0cfb738",
+ "verdict": "REFUTED"
+ },
+ {
+ "action_errors": 0,
+ "agent": "screen_trusting",
+ "claim": "success",
+ "derived_from": "scripted",
+ "fault": "wrong_row",
+ "feasible": false,
+ "judge_error": null,
+ "reset_s": null,
+ "reward": 0.0,
+ "seconds": 29.85,
+ "seed": 0,
+ "silent_wrong_effect": true,
+ "steps": 11,
+ "task_id": "winchart-6ed0cfb738",
+ "verdict": "REFUTED"
+ },
+ {
+ "action_errors": 0,
+ "agent": "random",
+ "claim": "failure",
+ "fault": "wrong_row",
+ "feasible": false,
+ "judge_error": null,
+ "reset_s": 3.54,
+ "reward": 0.0,
+ "seconds": 20.05,
+ "seed": 0,
+ "silent_wrong_effect": false,
+ "steps": 11,
+ "task_id": "winchart-6ed0cfb738",
+ "verdict": "REFUTED"
+ },
+ {
+ "action_errors": 0,
+ "agent": "scripted",
+ "claim": "success",
+ "fault": "ok",
+ "feasible": true,
+ "judge_error": null,
+ "reset_s": 3.49,
+ "reward": 1.0,
+ "seconds": 24.8,
+ "seed": 0,
+ "silent_wrong_effect": false,
+ "steps": 11,
+ "task_id": "winchart-23feef3efc",
+ "verdict": "CONFIRMED"
+ },
+ {
+ "action_errors": 0,
+ "agent": "screen_trusting",
+ "claim": "success",
+ "derived_from": "scripted",
+ "fault": "ok",
+ "feasible": true,
+ "judge_error": null,
+ "reset_s": null,
+ "reward": 1.0,
+ "seconds": 24.8,
+ "seed": 0,
+ "silent_wrong_effect": false,
+ "steps": 11,
+ "task_id": "winchart-23feef3efc",
+ "verdict": "CONFIRMED"
+ },
+ {
+ "action_errors": 0,
+ "agent": "planted_fault",
+ "claim": "success",
+ "fault": "drop",
+ "feasible": false,
+ "judge_error": null,
+ "reset_s": 3.24,
+ "reward": 0.0,
+ "seconds": 29.51,
+ "seed": 0,
+ "silent_wrong_effect": true,
+ "steps": 11,
+ "task_id": "winchart-23feef3efc",
+ "verdict": "REFUTED"
+ },
+ {
+ "action_errors": 0,
+ "agent": "random",
+ "claim": "failure",
+ "fault": "ok",
+ "feasible": true,
+ "judge_error": null,
+ "reset_s": 3.18,
+ "reward": 0.0,
+ "seconds": 19.29,
+ "seed": 0,
+ "silent_wrong_effect": false,
+ "steps": 11,
+ "task_id": "winchart-23feef3efc",
+ "verdict": "REFUTED"
+ },
+ {
+ "action_errors": 0,
+ "agent": "scripted",
+ "claim": "success",
+ "fault": "ok",
+ "feasible": true,
+ "judge_error": null,
+ "reset_s": 3.21,
+ "reward": 1.0,
+ "seconds": 24.5,
+ "seed": 0,
+ "silent_wrong_effect": false,
+ "steps": 11,
+ "task_id": "winchart-082349533f",
+ "verdict": "CONFIRMED"
+ },
+ {
+ "action_errors": 0,
+ "agent": "screen_trusting",
+ "claim": "success",
+ "derived_from": "scripted",
+ "fault": "ok",
+ "feasible": true,
+ "judge_error": null,
+ "reset_s": null,
+ "reward": 1.0,
+ "seconds": 24.5,
+ "seed": 0,
+ "silent_wrong_effect": false,
+ "steps": 11,
+ "task_id": "winchart-082349533f",
+ "verdict": "CONFIRMED"
+ },
+ {
+ "action_errors": 0,
+ "agent": "planted_fault",
+ "claim": "success",
+ "fault": "wrong_row",
+ "feasible": false,
+ "judge_error": null,
+ "reset_s": 3.2,
+ "reward": 0.0,
+ "seconds": 29.46,
+ "seed": 0,
+ "silent_wrong_effect": true,
+ "steps": 11,
+ "task_id": "winchart-082349533f",
+ "verdict": "REFUTED"
+ },
+ {
+ "action_errors": 0,
+ "agent": "random",
+ "claim": "failure",
+ "fault": "ok",
+ "feasible": true,
+ "judge_error": null,
+ "reset_s": 3.46,
+ "reward": 0.0,
+ "seconds": 20.02,
+ "seed": 0,
+ "silent_wrong_effect": false,
+ "steps": 11,
+ "task_id": "winchart-082349533f",
+ "verdict": "REFUTED"
+ },
+ {
+ "action_errors": 0,
+ "agent": "scripted",
+ "claim": "success",
+ "fault": "ok",
+ "feasible": true,
+ "judge_error": null,
+ "reset_s": 3.49,
+ "reward": 1.0,
+ "seconds": 25.31,
+ "seed": 0,
+ "silent_wrong_effect": false,
+ "steps": 11,
+ "task_id": "winchart-5e28ead589",
+ "verdict": "CONFIRMED"
+ },
+ {
+ "action_errors": 0,
+ "agent": "screen_trusting",
+ "claim": "success",
+ "derived_from": "scripted",
+ "fault": "ok",
+ "feasible": true,
+ "judge_error": null,
+ "reset_s": null,
+ "reward": 1.0,
+ "seconds": 25.31,
+ "seed": 0,
+ "silent_wrong_effect": false,
+ "steps": 11,
+ "task_id": "winchart-5e28ead589",
+ "verdict": "CONFIRMED"
+ },
+ {
+ "action_errors": 0,
+ "agent": "planted_fault",
+ "claim": "success",
+ "fault": "duplicate",
+ "feasible": false,
+ "judge_error": null,
+ "reset_s": 3.31,
+ "reward": 0.0,
+ "seconds": 30.03,
+ "seed": 0,
+ "silent_wrong_effect": true,
+ "steps": 11,
+ "task_id": "winchart-5e28ead589",
+ "verdict": "REFUTED"
+ },
+ {
+ "action_errors": 0,
+ "agent": "random",
+ "claim": "failure",
+ "fault": "ok",
+ "feasible": true,
+ "judge_error": null,
+ "reset_s": 3.13,
+ "reward": 0.0,
+ "seconds": 19.27,
+ "seed": 0,
+ "silent_wrong_effect": false,
+ "steps": 11,
+ "task_id": "winchart-5e28ead589",
+ "verdict": "REFUTED"
+ },
+ {
+ "action_errors": 0,
+ "agent": "scripted",
+ "claim": "success",
+ "fault": "drop_first",
+ "feasible": true,
+ "judge_error": null,
+ "reset_s": 3.22,
+ "reward": 1.0,
+ "seconds": 36.84,
+ "seed": 0,
+ "silent_wrong_effect": false,
+ "steps": 17,
+ "task_id": "winchart-9f775ce2bc",
+ "verdict": "CONFIRMED"
+ },
+ {
+ "action_errors": 0,
+ "agent": "screen_trusting",
+ "claim": "success",
+ "derived_from": "scripted",
+ "fault": "drop_first",
+ "feasible": true,
+ "judge_error": null,
+ "reset_s": null,
+ "reward": 1.0,
+ "seconds": 36.84,
+ "seed": 0,
+ "silent_wrong_effect": false,
+ "steps": 17,
+ "task_id": "winchart-9f775ce2bc",
+ "verdict": "CONFIRMED"
+ },
+ {
+ "action_errors": 0,
+ "agent": "planted_fault",
+ "claim": "success",
+ "fault": "truncate",
+ "feasible": false,
+ "judge_error": null,
+ "reset_s": 3.32,
+ "reward": 0.0,
+ "seconds": 41.63,
+ "seed": 0,
+ "silent_wrong_effect": true,
+ "steps": 17,
+ "task_id": "winchart-9f775ce2bc",
+ "verdict": "REFUTED"
+ },
+ {
+ "action_errors": 0,
+ "agent": "random",
+ "claim": "failure",
+ "fault": "drop_first",
+ "feasible": true,
+ "judge_error": null,
+ "reset_s": 3.08,
+ "reward": 0.0,
+ "seconds": 19.44,
+ "seed": 0,
+ "silent_wrong_effect": false,
+ "steps": 11,
+ "task_id": "winchart-9f775ce2bc",
+ "verdict": "REFUTED"
+ },
+ {
+ "action_errors": 0,
+ "agent": "scripted",
+ "claim": "failure",
+ "fault": "truncate",
+ "feasible": false,
+ "judge_error": null,
+ "reset_s": 3.14,
+ "reward": 1.0,
+ "seconds": 30.34,
+ "seed": 0,
+ "silent_wrong_effect": false,
+ "steps": 11,
+ "task_id": "winchart-dc2c6a0c72",
+ "verdict": "REFUTED"
+ },
+ {
+ "action_errors": 0,
+ "agent": "screen_trusting",
+ "claim": "success",
+ "derived_from": "scripted",
+ "fault": "truncate",
+ "feasible": false,
+ "judge_error": null,
+ "reset_s": null,
+ "reward": 0.0,
+ "seconds": 30.34,
+ "seed": 0,
+ "silent_wrong_effect": true,
+ "steps": 11,
+ "task_id": "winchart-dc2c6a0c72",
+ "verdict": "REFUTED"
+ },
+ {
+ "action_errors": 0,
+ "agent": "random",
+ "claim": "failure",
+ "fault": "truncate",
+ "feasible": false,
+ "judge_error": null,
+ "reset_s": 3.57,
+ "reward": 0.0,
+ "seconds": 19.88,
+ "seed": 0,
+ "silent_wrong_effect": false,
+ "steps": 11,
+ "task_id": "winchart-dc2c6a0c72",
+ "verdict": "REFUTED"
+ },
+ {
+ "action_errors": 0,
+ "agent": "scripted",
+ "claim": "failure",
+ "fault": "drop",
+ "feasible": false,
+ "judge_error": null,
+ "reset_s": 3.35,
+ "reward": 1.0,
+ "seconds": 30.33,
+ "seed": 0,
+ "silent_wrong_effect": false,
+ "steps": 11,
+ "task_id": "winchart-b3c1a3e373",
+ "verdict": "REFUTED"
+ },
+ {
+ "action_errors": 0,
+ "agent": "screen_trusting",
+ "claim": "success",
+ "derived_from": "scripted",
+ "fault": "drop",
+ "feasible": false,
+ "judge_error": null,
+ "reset_s": null,
+ "reward": 0.0,
+ "seconds": 30.33,
+ "seed": 0,
+ "silent_wrong_effect": true,
+ "steps": 11,
+ "task_id": "winchart-b3c1a3e373",
+ "verdict": "REFUTED"
+ },
+ {
+ "action_errors": 0,
+ "agent": "random",
+ "claim": "failure",
+ "fault": "drop",
+ "feasible": false,
+ "judge_error": null,
+ "reset_s": 3.39,
+ "reward": 0.0,
+ "seconds": 20.1,
+ "seed": 0,
+ "silent_wrong_effect": false,
+ "steps": 11,
+ "task_id": "winchart-b3c1a3e373",
+ "verdict": "REFUTED"
+ },
+ {
+ "action_errors": 0,
+ "agent": "scripted",
+ "claim": "failure",
+ "fault": "drop",
+ "feasible": false,
+ "judge_error": null,
+ "reset_s": 3.37,
+ "reward": 1.0,
+ "seconds": 30.1,
+ "seed": 0,
+ "silent_wrong_effect": false,
+ "steps": 11,
+ "task_id": "winchart-bc96492095",
+ "verdict": "REFUTED"
+ },
+ {
+ "action_errors": 0,
+ "agent": "screen_trusting",
+ "claim": "success",
+ "derived_from": "scripted",
+ "fault": "drop",
+ "feasible": false,
+ "judge_error": null,
+ "reset_s": null,
+ "reward": 0.0,
+ "seconds": 30.1,
+ "seed": 0,
+ "silent_wrong_effect": true,
+ "steps": 11,
+ "task_id": "winchart-bc96492095",
+ "verdict": "REFUTED"
+ },
+ {
+ "action_errors": 0,
+ "agent": "random",
+ "claim": "failure",
+ "fault": "drop",
+ "feasible": false,
+ "judge_error": null,
+ "reset_s": 3.32,
+ "reward": 0.0,
+ "seconds": 19.54,
+ "seed": 0,
+ "silent_wrong_effect": false,
+ "steps": 11,
+ "task_id": "winchart-bc96492095",
+ "verdict": "REFUTED"
+ },
+ {
+ "action_errors": 0,
+ "agent": "scripted",
+ "claim": "failure",
+ "fault": "stale",
+ "feasible": false,
+ "judge_error": null,
+ "reset_s": 3.29,
+ "reward": 1.0,
+ "seconds": 29.81,
+ "seed": 0,
+ "silent_wrong_effect": false,
+ "steps": 11,
+ "task_id": "winchart-730817ef79",
+ "verdict": "REFUTED"
+ },
+ {
+ "action_errors": 0,
+ "agent": "screen_trusting",
+ "claim": "success",
+ "derived_from": "scripted",
+ "fault": "stale",
+ "feasible": false,
+ "judge_error": null,
+ "reset_s": null,
+ "reward": 0.0,
+ "seconds": 29.81,
+ "seed": 0,
+ "silent_wrong_effect": true,
+ "steps": 11,
+ "task_id": "winchart-730817ef79",
+ "verdict": "REFUTED"
+ },
+ {
+ "action_errors": 0,
+ "agent": "random",
+ "claim": "failure",
+ "fault": "stale",
+ "feasible": false,
+ "judge_error": null,
+ "reset_s": 3.41,
+ "reward": 0.0,
+ "seconds": 19.89,
+ "seed": 0,
+ "silent_wrong_effect": false,
+ "steps": 11,
+ "task_id": "winchart-730817ef79",
+ "verdict": "REFUTED"
+ },
+ {
+ "action_errors": 0,
+ "agent": "scripted",
+ "claim": "success",
+ "fault": "ok",
+ "feasible": true,
+ "judge_error": null,
+ "reset_s": 3.41,
+ "reward": 1.0,
+ "seconds": 26.05,
+ "seed": 0,
+ "silent_wrong_effect": false,
+ "steps": 11,
+ "task_id": "winchart-584c51f82f",
+ "verdict": "CONFIRMED"
+ },
+ {
+ "action_errors": 0,
+ "agent": "screen_trusting",
+ "claim": "success",
+ "derived_from": "scripted",
+ "fault": "ok",
+ "feasible": true,
+ "judge_error": null,
+ "reset_s": null,
+ "reward": 1.0,
+ "seconds": 26.05,
+ "seed": 0,
+ "silent_wrong_effect": false,
+ "steps": 11,
+ "task_id": "winchart-584c51f82f",
+ "verdict": "CONFIRMED"
+ },
+ {
+ "action_errors": 0,
+ "agent": "planted_fault",
+ "claim": "success",
+ "fault": "truncate",
+ "feasible": false,
+ "judge_error": null,
+ "reset_s": 3.54,
+ "reward": 0.0,
+ "seconds": 29.96,
+ "seed": 0,
+ "silent_wrong_effect": true,
+ "steps": 11,
+ "task_id": "winchart-584c51f82f",
+ "verdict": "REFUTED"
+ },
+ {
+ "action_errors": 0,
+ "agent": "random",
+ "claim": "failure",
+ "fault": "ok",
+ "feasible": true,
+ "judge_error": null,
+ "reset_s": 3.21,
+ "reward": 0.0,
+ "seconds": 21.42,
+ "seed": 0,
+ "silent_wrong_effect": false,
+ "steps": 11,
+ "task_id": "winchart-584c51f82f",
+ "verdict": "REFUTED"
+ },
+ {
+ "action_errors": 0,
+ "agent": "scripted",
+ "claim": "failure",
+ "fault": "drop",
+ "feasible": false,
+ "judge_error": null,
+ "reset_s": 3.23,
+ "reward": 1.0,
+ "seconds": 30.5,
+ "seed": 0,
+ "silent_wrong_effect": false,
+ "steps": 11,
+ "task_id": "winchart-e63f24def2",
+ "verdict": "REFUTED"
+ },
+ {
+ "action_errors": 0,
+ "agent": "screen_trusting",
+ "claim": "success",
+ "derived_from": "scripted",
+ "fault": "drop",
+ "feasible": false,
+ "judge_error": null,
+ "reset_s": null,
+ "reward": 0.0,
+ "seconds": 30.5,
+ "seed": 0,
+ "silent_wrong_effect": true,
+ "steps": 11,
+ "task_id": "winchart-e63f24def2",
+ "verdict": "REFUTED"
+ },
+ {
+ "action_errors": 0,
+ "agent": "random",
+ "claim": "failure",
+ "fault": "drop",
+ "feasible": false,
+ "judge_error": null,
+ "reset_s": 3.61,
+ "reward": 0.0,
+ "seconds": 20.05,
+ "seed": 0,
+ "silent_wrong_effect": false,
+ "steps": 11,
+ "task_id": "winchart-e63f24def2",
+ "verdict": "REFUTED"
+ },
+ {
+ "action_errors": 0,
+ "agent": "scripted",
+ "claim": "success",
+ "fault": "drop_first",
+ "feasible": true,
+ "judge_error": null,
+ "reset_s": 3.52,
+ "reward": 1.0,
+ "seconds": 38.35,
+ "seed": 0,
+ "silent_wrong_effect": false,
+ "steps": 17,
+ "task_id": "winchart-6e3ceeeee5",
+ "verdict": "CONFIRMED"
+ },
+ {
+ "action_errors": 0,
+ "agent": "screen_trusting",
+ "claim": "success",
+ "derived_from": "scripted",
+ "fault": "drop_first",
+ "feasible": true,
+ "judge_error": null,
+ "reset_s": null,
+ "reward": 1.0,
+ "seconds": 38.35,
+ "seed": 0,
+ "silent_wrong_effect": false,
+ "steps": 17,
+ "task_id": "winchart-6e3ceeeee5",
+ "verdict": "CONFIRMED"
+ },
+ {
+ "action_errors": 0,
+ "agent": "planted_fault",
+ "claim": "success",
+ "fault": "drop",
+ "feasible": false,
+ "judge_error": null,
+ "reset_s": 3.0,
+ "reward": 0.0,
+ "seconds": 43.9,
+ "seed": 0,
+ "silent_wrong_effect": true,
+ "steps": 17,
+ "task_id": "winchart-6e3ceeeee5",
+ "verdict": "REFUTED"
+ },
+ {
+ "action_errors": 0,
+ "agent": "random",
+ "claim": "failure",
+ "fault": "drop_first",
+ "feasible": true,
+ "judge_error": null,
+ "reset_s": 3.23,
+ "reward": 0.0,
+ "seconds": 20.68,
+ "seed": 0,
+ "silent_wrong_effect": false,
+ "steps": 11,
+ "task_id": "winchart-6e3ceeeee5",
+ "verdict": "REFUTED"
+ },
+ {
+ "action_errors": 0,
+ "agent": "scripted",
+ "claim": "failure",
+ "fault": "stale",
+ "feasible": false,
+ "judge_error": null,
+ "reset_s": 3.5,
+ "reward": 1.0,
+ "seconds": 31.4,
+ "seed": 0,
+ "silent_wrong_effect": false,
+ "steps": 11,
+ "task_id": "winchart-4c12138125",
+ "verdict": "REFUTED"
+ },
+ {
+ "action_errors": 0,
+ "agent": "screen_trusting",
+ "claim": "success",
+ "derived_from": "scripted",
+ "fault": "stale",
+ "feasible": false,
+ "judge_error": null,
+ "reset_s": null,
+ "reward": 0.0,
+ "seconds": 31.4,
+ "seed": 0,
+ "silent_wrong_effect": true,
+ "steps": 11,
+ "task_id": "winchart-4c12138125",
+ "verdict": "REFUTED"
+ },
+ {
+ "action_errors": 0,
+ "agent": "random",
+ "claim": "failure",
+ "fault": "stale",
+ "feasible": false,
+ "judge_error": null,
+ "reset_s": 3.57,
+ "reward": 0.0,
+ "seconds": 22.05,
+ "seed": 0,
+ "silent_wrong_effect": false,
+ "steps": 11,
+ "task_id": "winchart-4c12138125",
+ "verdict": "REFUTED"
+ },
+ {
+ "action_errors": 0,
+ "agent": "scripted",
+ "claim": "success",
+ "fault": "ok",
+ "feasible": true,
+ "judge_error": null,
+ "reset_s": 3.5,
+ "reward": 1.0,
+ "seconds": 26.9,
+ "seed": 0,
+ "silent_wrong_effect": false,
+ "steps": 11,
+ "task_id": "winchart-e095f22847",
+ "verdict": "CONFIRMED"
+ },
+ {
+ "action_errors": 0,
+ "agent": "screen_trusting",
+ "claim": "success",
+ "derived_from": "scripted",
+ "fault": "ok",
+ "feasible": true,
+ "judge_error": null,
+ "reset_s": null,
+ "reward": 1.0,
+ "seconds": 26.9,
+ "seed": 0,
+ "silent_wrong_effect": false,
+ "steps": 11,
+ "task_id": "winchart-e095f22847",
+ "verdict": "CONFIRMED"
+ },
+ {
+ "action_errors": 0,
+ "agent": "planted_fault",
+ "claim": "success",
+ "fault": "duplicate",
+ "feasible": false,
+ "judge_error": null,
+ "reset_s": 3.98,
+ "reward": 0.0,
+ "seconds": 31.56,
+ "seed": 0,
+ "silent_wrong_effect": true,
+ "steps": 11,
+ "task_id": "winchart-e095f22847",
+ "verdict": "REFUTED"
+ },
+ {
+ "action_errors": 0,
+ "agent": "random",
+ "claim": "failure",
+ "fault": "ok",
+ "feasible": true,
+ "judge_error": null,
+ "reset_s": 3.15,
+ "reward": 0.0,
+ "seconds": 20.7,
+ "seed": 0,
+ "silent_wrong_effect": false,
+ "steps": 11,
+ "task_id": "winchart-e095f22847",
+ "verdict": "REFUTED"
+ },
+ {
+ "action_errors": 0,
+ "agent": "scripted",
+ "claim": "success",
+ "fault": "ok",
+ "feasible": true,
+ "judge_error": null,
+ "reset_s": 3.15,
+ "reward": 1.0,
+ "seconds": 24.68,
+ "seed": 0,
+ "silent_wrong_effect": false,
+ "steps": 11,
+ "task_id": "winchart-1307b4784e",
+ "verdict": "CONFIRMED"
+ },
+ {
+ "action_errors": 0,
+ "agent": "screen_trusting",
+ "claim": "success",
+ "derived_from": "scripted",
+ "fault": "ok",
+ "feasible": true,
+ "judge_error": null,
+ "reset_s": null,
+ "reward": 1.0,
+ "seconds": 24.68,
+ "seed": 0,
+ "silent_wrong_effect": false,
+ "steps": 11,
+ "task_id": "winchart-1307b4784e",
+ "verdict": "CONFIRMED"
+ },
+ {
+ "action_errors": 0,
+ "agent": "planted_fault",
+ "claim": "success",
+ "fault": "truncate",
+ "feasible": false,
+ "judge_error": null,
+ "reset_s": 2.93,
+ "reward": 0.0,
+ "seconds": 29.7,
+ "seed": 0,
+ "silent_wrong_effect": true,
+ "steps": 11,
+ "task_id": "winchart-1307b4784e",
+ "verdict": "REFUTED"
+ },
+ {
+ "action_errors": 0,
+ "agent": "random",
+ "claim": "failure",
+ "fault": "ok",
+ "feasible": true,
+ "judge_error": null,
+ "reset_s": 3.11,
+ "reward": 0.0,
+ "seconds": 19.89,
+ "seed": 0,
+ "silent_wrong_effect": false,
+ "steps": 11,
+ "task_id": "winchart-1307b4784e",
+ "verdict": "REFUTED"
+ },
+ {
+ "action_errors": 0,
+ "agent": "scripted",
+ "claim": "failure",
+ "fault": "wrong_row",
+ "feasible": false,
+ "judge_error": null,
+ "reset_s": 3.04,
+ "reward": 1.0,
+ "seconds": 29.83,
+ "seed": 0,
+ "silent_wrong_effect": false,
+ "steps": 11,
+ "task_id": "winchart-29cf0e8200",
+ "verdict": "REFUTED"
+ },
+ {
+ "action_errors": 0,
+ "agent": "screen_trusting",
+ "claim": "success",
+ "derived_from": "scripted",
+ "fault": "wrong_row",
+ "feasible": false,
+ "judge_error": null,
+ "reset_s": null,
+ "reward": 0.0,
+ "seconds": 29.83,
+ "seed": 0,
+ "silent_wrong_effect": true,
+ "steps": 11,
+ "task_id": "winchart-29cf0e8200",
+ "verdict": "REFUTED"
+ },
+ {
+ "action_errors": 0,
+ "agent": "random",
+ "claim": "failure",
+ "fault": "wrong_row",
+ "feasible": false,
+ "judge_error": null,
+ "reset_s": 3.61,
+ "reward": 0.0,
+ "seconds": 21.28,
+ "seed": 0,
+ "silent_wrong_effect": false,
+ "steps": 11,
+ "task_id": "winchart-29cf0e8200",
+ "verdict": "REFUTED"
+ },
+ {
+ "action_errors": 0,
+ "agent": "scripted",
+ "claim": "success",
+ "fault": "ok",
+ "feasible": true,
+ "judge_error": null,
+ "reset_s": 3.44,
+ "reward": 1.0,
+ "seconds": 25.15,
+ "seed": 0,
+ "silent_wrong_effect": false,
+ "steps": 11,
+ "task_id": "winchart-5fb21b5401",
+ "verdict": "CONFIRMED"
+ },
+ {
+ "action_errors": 0,
+ "agent": "screen_trusting",
+ "claim": "success",
+ "derived_from": "scripted",
+ "fault": "ok",
+ "feasible": true,
+ "judge_error": null,
+ "reset_s": null,
+ "reward": 1.0,
+ "seconds": 25.15,
+ "seed": 0,
+ "silent_wrong_effect": false,
+ "steps": 11,
+ "task_id": "winchart-5fb21b5401",
+ "verdict": "CONFIRMED"
+ },
+ {
+ "action_errors": 0,
+ "agent": "planted_fault",
+ "claim": "success",
+ "fault": "drop",
+ "feasible": false,
+ "judge_error": null,
+ "reset_s": 3.03,
+ "reward": 0.0,
+ "seconds": 29.47,
+ "seed": 0,
+ "silent_wrong_effect": true,
+ "steps": 11,
+ "task_id": "winchart-5fb21b5401",
+ "verdict": "REFUTED"
+ },
+ {
+ "action_errors": 0,
+ "agent": "random",
+ "claim": "failure",
+ "fault": "ok",
+ "feasible": true,
+ "judge_error": null,
+ "reset_s": 3.13,
+ "reward": 0.0,
+ "seconds": 19.04,
+ "seed": 0,
+ "silent_wrong_effect": false,
+ "steps": 11,
+ "task_id": "winchart-5fb21b5401",
+ "verdict": "REFUTED"
+ },
+ {
+ "action_errors": 0,
+ "agent": "scripted",
+ "claim": "failure",
+ "fault": "duplicate",
+ "feasible": false,
+ "judge_error": null,
+ "reset_s": 3.11,
+ "reward": 1.0,
+ "seconds": 29.18,
+ "seed": 0,
+ "silent_wrong_effect": false,
+ "steps": 11,
+ "task_id": "winchart-0f49a8fcfb",
+ "verdict": "REFUTED"
+ },
+ {
+ "action_errors": 0,
+ "agent": "screen_trusting",
+ "claim": "success",
+ "derived_from": "scripted",
+ "fault": "duplicate",
+ "feasible": false,
+ "judge_error": null,
+ "reset_s": null,
+ "reward": 0.0,
+ "seconds": 29.18,
+ "seed": 0,
+ "silent_wrong_effect": true,
+ "steps": 11,
+ "task_id": "winchart-0f49a8fcfb",
+ "verdict": "REFUTED"
+ },
+ {
+ "action_errors": 0,
+ "agent": "random",
+ "claim": "failure",
+ "fault": "duplicate",
+ "feasible": false,
+ "judge_error": null,
+ "reset_s": 3.05,
+ "reward": 0.0,
+ "seconds": 19.34,
+ "seed": 0,
+ "silent_wrong_effect": false,
+ "steps": 11,
+ "task_id": "winchart-0f49a8fcfb",
+ "verdict": "REFUTED"
+ },
+ {
+ "action_errors": 0,
+ "agent": "scripted",
+ "claim": "failure",
+ "fault": "duplicate",
+ "feasible": false,
+ "judge_error": null,
+ "reset_s": 3.16,
+ "reward": 1.0,
+ "seconds": 29.56,
+ "seed": 0,
+ "silent_wrong_effect": false,
+ "steps": 11,
+ "task_id": "winchart-508b9a5076",
+ "verdict": "REFUTED"
+ },
+ {
+ "action_errors": 0,
+ "agent": "screen_trusting",
+ "claim": "success",
+ "derived_from": "scripted",
+ "fault": "duplicate",
+ "feasible": false,
+ "judge_error": null,
+ "reset_s": null,
+ "reward": 0.0,
+ "seconds": 29.56,
+ "seed": 0,
+ "silent_wrong_effect": true,
+ "steps": 11,
+ "task_id": "winchart-508b9a5076",
+ "verdict": "REFUTED"
+ },
+ {
+ "action_errors": 0,
+ "agent": "random",
+ "claim": "failure",
+ "fault": "duplicate",
+ "feasible": false,
+ "judge_error": null,
+ "reset_s": 3.11,
+ "reward": 0.0,
+ "seconds": 19.15,
+ "seed": 0,
+ "silent_wrong_effect": false,
+ "steps": 11,
+ "task_id": "winchart-508b9a5076",
+ "verdict": "REFUTED"
+ },
+ {
+ "action_errors": 0,
+ "agent": "scripted",
+ "claim": "success",
+ "fault": "drop_first",
+ "feasible": true,
+ "judge_error": null,
+ "reset_s": 3.12,
+ "reward": 1.0,
+ "seconds": 36.18,
+ "seed": 0,
+ "silent_wrong_effect": false,
+ "steps": 17,
+ "task_id": "winchart-e9853ade43",
+ "verdict": "CONFIRMED"
+ },
+ {
+ "action_errors": 0,
+ "agent": "screen_trusting",
+ "claim": "success",
+ "derived_from": "scripted",
+ "fault": "drop_first",
+ "feasible": true,
+ "judge_error": null,
+ "reset_s": null,
+ "reward": 1.0,
+ "seconds": 36.18,
+ "seed": 0,
+ "silent_wrong_effect": false,
+ "steps": 17,
+ "task_id": "winchart-e9853ade43",
+ "verdict": "CONFIRMED"
+ },
+ {
+ "action_errors": 0,
+ "agent": "planted_fault",
+ "claim": "success",
+ "fault": "truncate",
+ "feasible": false,
+ "judge_error": null,
+ "reset_s": 2.98,
+ "reward": 0.0,
+ "seconds": 40.74,
+ "seed": 0,
+ "silent_wrong_effect": true,
+ "steps": 17,
+ "task_id": "winchart-e9853ade43",
+ "verdict": "REFUTED"
+ },
+ {
+ "action_errors": 0,
+ "agent": "random",
+ "claim": "failure",
+ "fault": "drop_first",
+ "feasible": true,
+ "judge_error": null,
+ "reset_s": 3.1,
+ "reward": 0.0,
+ "seconds": 19.38,
+ "seed": 0,
+ "silent_wrong_effect": false,
+ "steps": 11,
+ "task_id": "winchart-e9853ade43",
+ "verdict": "REFUTED"
+ }
+ ],
+ "summary": {
+ "agents": {
+ "planted_fault": {
+ "action_errors": 0,
+ "episodes": 12,
+ "judge_errors": 0,
+ "mean_reward": 0.0,
+ "silent_wrong_effects": 12,
+ "verdicts": {
+ "CONFIRMED": 0,
+ "INDETERMINATE": 0,
+ "REFUTED": 12
+ }
+ },
+ "random": {
+ "action_errors": 0,
+ "episodes": 24,
+ "judge_errors": 0,
+ "mean_reward": 0.0,
+ "silent_wrong_effects": 0,
+ "verdicts": {
+ "CONFIRMED": 0,
+ "INDETERMINATE": 0,
+ "REFUTED": 24
+ }
+ },
+ "screen_trusting": {
+ "action_errors": 0,
+ "episodes": 24,
+ "judge_errors": 0,
+ "mean_reward": 0.5,
+ "silent_wrong_effects": 12,
+ "verdicts": {
+ "CONFIRMED": 12,
+ "INDETERMINATE": 0,
+ "REFUTED": 12
+ }
+ },
+ "scripted": {
+ "action_errors": 0,
+ "episodes": 24,
+ "judge_errors": 0,
+ "mean_reward": 1.0,
+ "silent_wrong_effects": 0,
+ "verdicts": {
+ "CONFIRMED": 12,
+ "INDETERMINATE": 0,
+ "REFUTED": 12
+ }
+ }
+ },
+ "checks": {
+ "every_feasible_task_fails_with_a_planted_fault": true,
+ "every_task_passes_with_its_solution": true,
+ "no_judge_errors": true,
+ "no_state_leaks": true,
+ "random_floor_margin": true,
+ "screen_trusting_paid_only_on_feasible": true
+ },
+ "env": "openadapt-win-patient-chart-rdp",
+ "feasible_tasks": 12,
+ "leak_checks": [
+ {
+ "app_processes": 1,
+ "digest_after_write_differs": true,
+ "note_field_after_reset": "",
+ "passed": true,
+ "reader": "winchart-0508cc32b5",
+ "records_after_reset": 3,
+ "records_in_pristine_seed": 3,
+ "restored_digest_is_pristine": true,
+ "writer": "winchart-05152397d0"
+ },
+ {
+ "app_processes": 1,
+ "digest_after_write_differs": true,
+ "note_field_after_reset": "",
+ "passed": true,
+ "reader": "winchart-23feef3efc",
+ "records_after_reset": 3,
+ "records_in_pristine_seed": 3,
+ "restored_digest_is_pristine": true,
+ "writer": "winchart-0508cc32b5"
+ }
+ ],
+ "passed": true,
+ "reset_s": {
+ "episodes": 60,
+ "max": 29.69,
+ "median": 3.29,
+ "p95": 3.61
+ },
+ "run": {
+ "model_calls": 0,
+ "server_platform": "Linux aarch64 py3.12.16",
+ "started": "2026-11-04T04:22:26Z",
+ "wall_s": 1675.6
+ },
+ "surface": "rdp_pixels",
+ "tasks": 24
+ }
+}
diff --git a/packages/flow/environments/openenv/_windows/results/windows11-x64-2026-11-04/win-patient-chart.json b/packages/flow/environments/openenv/_windows/results/windows11-x64-2026-11-04/win-patient-chart.json
new file mode 100644
index 0000000000..260bac81bc
--- /dev/null
+++ b/packages/flow/environments/openenv/_windows/results/windows11-x64-2026-11-04/win-patient-chart.json
@@ -0,0 +1,1473 @@
+{
+ "episodes": [
+ {
+ "action_errors": 0,
+ "agent": "scripted",
+ "claim": "success",
+ "fault": "ok",
+ "feasible": true,
+ "judge_error": null,
+ "reset_s": 51.76,
+ "reward": 1.0,
+ "seconds": 95.27,
+ "seed": 0,
+ "silent_wrong_effect": false,
+ "steps": 11,
+ "task_id": "winchart-05152397d0",
+ "verdict": "CONFIRMED"
+ },
+ {
+ "action_errors": 0,
+ "agent": "screen_trusting",
+ "claim": "success",
+ "derived_from": "scripted",
+ "fault": "ok",
+ "feasible": true,
+ "judge_error": null,
+ "reset_s": null,
+ "reward": 1.0,
+ "seconds": 95.27,
+ "seed": 0,
+ "silent_wrong_effect": false,
+ "steps": 11,
+ "task_id": "winchart-05152397d0",
+ "verdict": "CONFIRMED"
+ },
+ {
+ "action_errors": 0,
+ "agent": "planted_fault",
+ "claim": "success",
+ "fault": "drop",
+ "feasible": false,
+ "judge_error": null,
+ "reset_s": 6.88,
+ "reward": 0.0,
+ "seconds": 53.85,
+ "seed": 0,
+ "silent_wrong_effect": true,
+ "steps": 11,
+ "task_id": "winchart-05152397d0",
+ "verdict": "REFUTED"
+ },
+ {
+ "action_errors": 0,
+ "agent": "random",
+ "claim": "success",
+ "fault": "ok",
+ "feasible": true,
+ "judge_error": null,
+ "reset_s": 8.65,
+ "reward": 0.0,
+ "seconds": 40.07,
+ "seed": 0,
+ "silent_wrong_effect": true,
+ "steps": 11,
+ "task_id": "winchart-05152397d0",
+ "verdict": "REFUTED"
+ },
+ {
+ "action_errors": 0,
+ "agent": "scripted",
+ "claim": "success",
+ "fault": "ok",
+ "feasible": true,
+ "judge_error": null,
+ "reset_s": 8.78,
+ "reward": 1.0,
+ "seconds": 47.69,
+ "seed": 0,
+ "silent_wrong_effect": false,
+ "steps": 11,
+ "task_id": "winchart-0508cc32b5",
+ "verdict": "CONFIRMED"
+ },
+ {
+ "action_errors": 0,
+ "agent": "screen_trusting",
+ "claim": "success",
+ "derived_from": "scripted",
+ "fault": "ok",
+ "feasible": true,
+ "judge_error": null,
+ "reset_s": null,
+ "reward": 1.0,
+ "seconds": 47.69,
+ "seed": 0,
+ "silent_wrong_effect": false,
+ "steps": 11,
+ "task_id": "winchart-0508cc32b5",
+ "verdict": "CONFIRMED"
+ },
+ {
+ "action_errors": 0,
+ "agent": "planted_fault",
+ "claim": "success",
+ "fault": "wrong_row",
+ "feasible": false,
+ "judge_error": null,
+ "reset_s": 8.81,
+ "reward": 0.0,
+ "seconds": 46.13,
+ "seed": 0,
+ "silent_wrong_effect": true,
+ "steps": 11,
+ "task_id": "winchart-0508cc32b5",
+ "verdict": "REFUTED"
+ },
+ {
+ "action_errors": 0,
+ "agent": "random",
+ "claim": "success",
+ "fault": "ok",
+ "feasible": true,
+ "judge_error": null,
+ "reset_s": 10.06,
+ "reward": 0.0,
+ "seconds": 34.14,
+ "seed": 0,
+ "silent_wrong_effect": true,
+ "steps": 11,
+ "task_id": "winchart-0508cc32b5",
+ "verdict": "REFUTED"
+ },
+ {
+ "action_errors": 0,
+ "agent": "scripted",
+ "claim": "failure",
+ "fault": "truncate",
+ "feasible": false,
+ "judge_error": null,
+ "reset_s": 7.34,
+ "reward": 1.0,
+ "seconds": 43.21,
+ "seed": 0,
+ "silent_wrong_effect": false,
+ "steps": 11,
+ "task_id": "winchart-d60d31ca58",
+ "verdict": "REFUTED"
+ },
+ {
+ "action_errors": 0,
+ "agent": "screen_trusting",
+ "claim": "success",
+ "derived_from": "scripted",
+ "fault": "truncate",
+ "feasible": false,
+ "judge_error": null,
+ "reset_s": null,
+ "reward": 0.0,
+ "seconds": 43.21,
+ "seed": 0,
+ "silent_wrong_effect": true,
+ "steps": 11,
+ "task_id": "winchart-d60d31ca58",
+ "verdict": "REFUTED"
+ },
+ {
+ "action_errors": 0,
+ "agent": "random",
+ "claim": "success",
+ "fault": "truncate",
+ "feasible": false,
+ "judge_error": null,
+ "reset_s": 6.46,
+ "reward": 0.0,
+ "seconds": 31.39,
+ "seed": 0,
+ "silent_wrong_effect": true,
+ "steps": 11,
+ "task_id": "winchart-d60d31ca58",
+ "verdict": "REFUTED"
+ },
+ {
+ "action_errors": 0,
+ "agent": "scripted",
+ "claim": "failure",
+ "fault": "wrong_row",
+ "feasible": false,
+ "judge_error": null,
+ "reset_s": 7.95,
+ "reward": 1.0,
+ "seconds": 44.74,
+ "seed": 0,
+ "silent_wrong_effect": false,
+ "steps": 11,
+ "task_id": "winchart-6c39916c8c",
+ "verdict": "REFUTED"
+ },
+ {
+ "action_errors": 0,
+ "agent": "screen_trusting",
+ "claim": "success",
+ "derived_from": "scripted",
+ "fault": "wrong_row",
+ "feasible": false,
+ "judge_error": null,
+ "reset_s": null,
+ "reward": 0.0,
+ "seconds": 44.74,
+ "seed": 0,
+ "silent_wrong_effect": true,
+ "steps": 11,
+ "task_id": "winchart-6c39916c8c",
+ "verdict": "REFUTED"
+ },
+ {
+ "action_errors": 0,
+ "agent": "random",
+ "claim": "success",
+ "fault": "wrong_row",
+ "feasible": false,
+ "judge_error": null,
+ "reset_s": 6.74,
+ "reward": 0.0,
+ "seconds": 30.2,
+ "seed": 0,
+ "silent_wrong_effect": true,
+ "steps": 11,
+ "task_id": "winchart-6c39916c8c",
+ "verdict": "REFUTED"
+ },
+ {
+ "action_errors": 0,
+ "agent": "scripted",
+ "claim": "failure",
+ "fault": "wrong_row",
+ "feasible": false,
+ "judge_error": null,
+ "reset_s": 7.48,
+ "reward": 1.0,
+ "seconds": 42.58,
+ "seed": 0,
+ "silent_wrong_effect": false,
+ "steps": 11,
+ "task_id": "winchart-6ed0cfb738",
+ "verdict": "REFUTED"
+ },
+ {
+ "action_errors": 0,
+ "agent": "screen_trusting",
+ "claim": "success",
+ "derived_from": "scripted",
+ "fault": "wrong_row",
+ "feasible": false,
+ "judge_error": null,
+ "reset_s": null,
+ "reward": 0.0,
+ "seconds": 42.58,
+ "seed": 0,
+ "silent_wrong_effect": true,
+ "steps": 11,
+ "task_id": "winchart-6ed0cfb738",
+ "verdict": "REFUTED"
+ },
+ {
+ "action_errors": 0,
+ "agent": "random",
+ "claim": "success",
+ "fault": "wrong_row",
+ "feasible": false,
+ "judge_error": null,
+ "reset_s": 6.2,
+ "reward": 0.0,
+ "seconds": 28.39,
+ "seed": 0,
+ "silent_wrong_effect": true,
+ "steps": 11,
+ "task_id": "winchart-6ed0cfb738",
+ "verdict": "REFUTED"
+ },
+ {
+ "action_errors": 0,
+ "agent": "scripted",
+ "claim": "success",
+ "fault": "ok",
+ "feasible": true,
+ "judge_error": null,
+ "reset_s": 6.56,
+ "reward": 1.0,
+ "seconds": 36.31,
+ "seed": 0,
+ "silent_wrong_effect": false,
+ "steps": 11,
+ "task_id": "winchart-23feef3efc",
+ "verdict": "CONFIRMED"
+ },
+ {
+ "action_errors": 0,
+ "agent": "screen_trusting",
+ "claim": "success",
+ "derived_from": "scripted",
+ "fault": "ok",
+ "feasible": true,
+ "judge_error": null,
+ "reset_s": null,
+ "reward": 1.0,
+ "seconds": 36.31,
+ "seed": 0,
+ "silent_wrong_effect": false,
+ "steps": 11,
+ "task_id": "winchart-23feef3efc",
+ "verdict": "CONFIRMED"
+ },
+ {
+ "action_errors": 0,
+ "agent": "planted_fault",
+ "claim": "success",
+ "fault": "drop",
+ "feasible": false,
+ "judge_error": null,
+ "reset_s": 6.19,
+ "reward": 0.0,
+ "seconds": 41.02,
+ "seed": 0,
+ "silent_wrong_effect": true,
+ "steps": 11,
+ "task_id": "winchart-23feef3efc",
+ "verdict": "REFUTED"
+ },
+ {
+ "action_errors": 0,
+ "agent": "random",
+ "claim": "success",
+ "fault": "ok",
+ "feasible": true,
+ "judge_error": null,
+ "reset_s": 6.13,
+ "reward": 0.0,
+ "seconds": 29.22,
+ "seed": 0,
+ "silent_wrong_effect": true,
+ "steps": 11,
+ "task_id": "winchart-23feef3efc",
+ "verdict": "REFUTED"
+ },
+ {
+ "action_errors": 0,
+ "agent": "scripted",
+ "claim": "success",
+ "fault": "ok",
+ "feasible": true,
+ "judge_error": null,
+ "reset_s": 6.15,
+ "reward": 1.0,
+ "seconds": 36.56,
+ "seed": 0,
+ "silent_wrong_effect": false,
+ "steps": 11,
+ "task_id": "winchart-082349533f",
+ "verdict": "CONFIRMED"
+ },
+ {
+ "action_errors": 0,
+ "agent": "screen_trusting",
+ "claim": "success",
+ "derived_from": "scripted",
+ "fault": "ok",
+ "feasible": true,
+ "judge_error": null,
+ "reset_s": null,
+ "reward": 1.0,
+ "seconds": 36.56,
+ "seed": 0,
+ "silent_wrong_effect": false,
+ "steps": 11,
+ "task_id": "winchart-082349533f",
+ "verdict": "CONFIRMED"
+ },
+ {
+ "action_errors": 0,
+ "agent": "planted_fault",
+ "claim": "success",
+ "fault": "wrong_row",
+ "feasible": false,
+ "judge_error": null,
+ "reset_s": 6.19,
+ "reward": 0.0,
+ "seconds": 40.16,
+ "seed": 0,
+ "silent_wrong_effect": true,
+ "steps": 11,
+ "task_id": "winchart-082349533f",
+ "verdict": "REFUTED"
+ },
+ {
+ "action_errors": 0,
+ "agent": "random",
+ "claim": "success",
+ "fault": "ok",
+ "feasible": true,
+ "judge_error": null,
+ "reset_s": 6.23,
+ "reward": 0.0,
+ "seconds": 28.61,
+ "seed": 0,
+ "silent_wrong_effect": true,
+ "steps": 11,
+ "task_id": "winchart-082349533f",
+ "verdict": "REFUTED"
+ },
+ {
+ "action_errors": 0,
+ "agent": "scripted",
+ "claim": "success",
+ "fault": "ok",
+ "feasible": true,
+ "judge_error": null,
+ "reset_s": 6.32,
+ "reward": 1.0,
+ "seconds": 35.89,
+ "seed": 0,
+ "silent_wrong_effect": false,
+ "steps": 11,
+ "task_id": "winchart-5e28ead589",
+ "verdict": "CONFIRMED"
+ },
+ {
+ "action_errors": 0,
+ "agent": "screen_trusting",
+ "claim": "success",
+ "derived_from": "scripted",
+ "fault": "ok",
+ "feasible": true,
+ "judge_error": null,
+ "reset_s": null,
+ "reward": 1.0,
+ "seconds": 35.89,
+ "seed": 0,
+ "silent_wrong_effect": false,
+ "steps": 11,
+ "task_id": "winchart-5e28ead589",
+ "verdict": "CONFIRMED"
+ },
+ {
+ "action_errors": 0,
+ "agent": "planted_fault",
+ "claim": "success",
+ "fault": "duplicate",
+ "feasible": false,
+ "judge_error": null,
+ "reset_s": 6.48,
+ "reward": 0.0,
+ "seconds": 43.64,
+ "seed": 0,
+ "silent_wrong_effect": true,
+ "steps": 11,
+ "task_id": "winchart-5e28ead589",
+ "verdict": "REFUTED"
+ },
+ {
+ "action_errors": 0,
+ "agent": "random",
+ "claim": "success",
+ "fault": "ok",
+ "feasible": true,
+ "judge_error": null,
+ "reset_s": 6.17,
+ "reward": 0.0,
+ "seconds": 32.11,
+ "seed": 0,
+ "silent_wrong_effect": true,
+ "steps": 11,
+ "task_id": "winchart-5e28ead589",
+ "verdict": "REFUTED"
+ },
+ {
+ "action_errors": 0,
+ "agent": "scripted",
+ "claim": "success",
+ "fault": "drop_first",
+ "feasible": true,
+ "judge_error": null,
+ "reset_s": 9.32,
+ "reward": 1.0,
+ "seconds": 75.23,
+ "seed": 0,
+ "silent_wrong_effect": false,
+ "steps": 17,
+ "task_id": "winchart-9f775ce2bc",
+ "verdict": "CONFIRMED"
+ },
+ {
+ "action_errors": 0,
+ "agent": "screen_trusting",
+ "claim": "success",
+ "derived_from": "scripted",
+ "fault": "drop_first",
+ "feasible": true,
+ "judge_error": null,
+ "reset_s": null,
+ "reward": 1.0,
+ "seconds": 75.23,
+ "seed": 0,
+ "silent_wrong_effect": false,
+ "steps": 17,
+ "task_id": "winchart-9f775ce2bc",
+ "verdict": "CONFIRMED"
+ },
+ {
+ "action_errors": 0,
+ "agent": "planted_fault",
+ "claim": "success",
+ "fault": "truncate",
+ "feasible": false,
+ "judge_error": null,
+ "reset_s": 9.26,
+ "reward": 0.0,
+ "seconds": 77.42,
+ "seed": 0,
+ "silent_wrong_effect": true,
+ "steps": 17,
+ "task_id": "winchart-9f775ce2bc",
+ "verdict": "REFUTED"
+ },
+ {
+ "action_errors": 0,
+ "agent": "random",
+ "claim": "success",
+ "fault": "drop_first",
+ "feasible": true,
+ "judge_error": null,
+ "reset_s": 9.14,
+ "reward": 0.0,
+ "seconds": 38.93,
+ "seed": 0,
+ "silent_wrong_effect": true,
+ "steps": 11,
+ "task_id": "winchart-9f775ce2bc",
+ "verdict": "REFUTED"
+ },
+ {
+ "action_errors": 0,
+ "agent": "scripted",
+ "claim": "failure",
+ "fault": "truncate",
+ "feasible": false,
+ "judge_error": null,
+ "reset_s": 9.76,
+ "reward": 1.0,
+ "seconds": 51.1,
+ "seed": 0,
+ "silent_wrong_effect": false,
+ "steps": 11,
+ "task_id": "winchart-dc2c6a0c72",
+ "verdict": "REFUTED"
+ },
+ {
+ "action_errors": 0,
+ "agent": "screen_trusting",
+ "claim": "success",
+ "derived_from": "scripted",
+ "fault": "truncate",
+ "feasible": false,
+ "judge_error": null,
+ "reset_s": null,
+ "reward": 0.0,
+ "seconds": 51.1,
+ "seed": 0,
+ "silent_wrong_effect": true,
+ "steps": 11,
+ "task_id": "winchart-dc2c6a0c72",
+ "verdict": "REFUTED"
+ },
+ {
+ "action_errors": 0,
+ "agent": "random",
+ "claim": "success",
+ "fault": "truncate",
+ "feasible": false,
+ "judge_error": null,
+ "reset_s": 8.85,
+ "reward": 0.0,
+ "seconds": 36.46,
+ "seed": 0,
+ "silent_wrong_effect": true,
+ "steps": 11,
+ "task_id": "winchart-dc2c6a0c72",
+ "verdict": "REFUTED"
+ },
+ {
+ "action_errors": 0,
+ "agent": "scripted",
+ "claim": "failure",
+ "fault": "drop",
+ "feasible": false,
+ "judge_error": null,
+ "reset_s": 8.4,
+ "reward": 1.0,
+ "seconds": 49.88,
+ "seed": 0,
+ "silent_wrong_effect": false,
+ "steps": 11,
+ "task_id": "winchart-b3c1a3e373",
+ "verdict": "REFUTED"
+ },
+ {
+ "action_errors": 0,
+ "agent": "screen_trusting",
+ "claim": "success",
+ "derived_from": "scripted",
+ "fault": "drop",
+ "feasible": false,
+ "judge_error": null,
+ "reset_s": null,
+ "reward": 0.0,
+ "seconds": 49.88,
+ "seed": 0,
+ "silent_wrong_effect": true,
+ "steps": 11,
+ "task_id": "winchart-b3c1a3e373",
+ "verdict": "REFUTED"
+ },
+ {
+ "action_errors": 0,
+ "agent": "random",
+ "claim": "success",
+ "fault": "drop",
+ "feasible": false,
+ "judge_error": null,
+ "reset_s": 6.45,
+ "reward": 0.0,
+ "seconds": 30.75,
+ "seed": 0,
+ "silent_wrong_effect": true,
+ "steps": 11,
+ "task_id": "winchart-b3c1a3e373",
+ "verdict": "REFUTED"
+ },
+ {
+ "action_errors": 0,
+ "agent": "scripted",
+ "claim": "failure",
+ "fault": "drop",
+ "feasible": false,
+ "judge_error": null,
+ "reset_s": 6.48,
+ "reward": 1.0,
+ "seconds": 44.42,
+ "seed": 0,
+ "silent_wrong_effect": false,
+ "steps": 11,
+ "task_id": "winchart-bc96492095",
+ "verdict": "REFUTED"
+ },
+ {
+ "action_errors": 0,
+ "agent": "screen_trusting",
+ "claim": "success",
+ "derived_from": "scripted",
+ "fault": "drop",
+ "feasible": false,
+ "judge_error": null,
+ "reset_s": null,
+ "reward": 0.0,
+ "seconds": 44.42,
+ "seed": 0,
+ "silent_wrong_effect": true,
+ "steps": 11,
+ "task_id": "winchart-bc96492095",
+ "verdict": "REFUTED"
+ },
+ {
+ "action_errors": 0,
+ "agent": "random",
+ "claim": "success",
+ "fault": "drop",
+ "feasible": false,
+ "judge_error": null,
+ "reset_s": 7.65,
+ "reward": 0.0,
+ "seconds": 32.15,
+ "seed": 0,
+ "silent_wrong_effect": true,
+ "steps": 11,
+ "task_id": "winchart-bc96492095",
+ "verdict": "REFUTED"
+ },
+ {
+ "action_errors": 0,
+ "agent": "scripted",
+ "claim": "failure",
+ "fault": "stale",
+ "feasible": false,
+ "judge_error": null,
+ "reset_s": 7.33,
+ "reward": 1.0,
+ "seconds": 46.5,
+ "seed": 0,
+ "silent_wrong_effect": false,
+ "steps": 11,
+ "task_id": "winchart-730817ef79",
+ "verdict": "REFUTED"
+ },
+ {
+ "action_errors": 0,
+ "agent": "screen_trusting",
+ "claim": "success",
+ "derived_from": "scripted",
+ "fault": "stale",
+ "feasible": false,
+ "judge_error": null,
+ "reset_s": null,
+ "reward": 0.0,
+ "seconds": 46.5,
+ "seed": 0,
+ "silent_wrong_effect": true,
+ "steps": 11,
+ "task_id": "winchart-730817ef79",
+ "verdict": "REFUTED"
+ },
+ {
+ "action_errors": 0,
+ "agent": "random",
+ "claim": "success",
+ "fault": "stale",
+ "feasible": false,
+ "judge_error": null,
+ "reset_s": 6.79,
+ "reward": 0.0,
+ "seconds": 34.04,
+ "seed": 0,
+ "silent_wrong_effect": true,
+ "steps": 11,
+ "task_id": "winchart-730817ef79",
+ "verdict": "REFUTED"
+ },
+ {
+ "action_errors": 0,
+ "agent": "scripted",
+ "claim": "success",
+ "fault": "ok",
+ "feasible": true,
+ "judge_error": null,
+ "reset_s": 9.09,
+ "reward": 1.0,
+ "seconds": 46.36,
+ "seed": 0,
+ "silent_wrong_effect": false,
+ "steps": 11,
+ "task_id": "winchart-584c51f82f",
+ "verdict": "CONFIRMED"
+ },
+ {
+ "action_errors": 0,
+ "agent": "screen_trusting",
+ "claim": "success",
+ "derived_from": "scripted",
+ "fault": "ok",
+ "feasible": true,
+ "judge_error": null,
+ "reset_s": null,
+ "reward": 1.0,
+ "seconds": 46.36,
+ "seed": 0,
+ "silent_wrong_effect": false,
+ "steps": 11,
+ "task_id": "winchart-584c51f82f",
+ "verdict": "CONFIRMED"
+ },
+ {
+ "action_errors": 0,
+ "agent": "planted_fault",
+ "claim": "success",
+ "fault": "truncate",
+ "feasible": false,
+ "judge_error": null,
+ "reset_s": 7.52,
+ "reward": 0.0,
+ "seconds": 50.01,
+ "seed": 0,
+ "silent_wrong_effect": true,
+ "steps": 11,
+ "task_id": "winchart-584c51f82f",
+ "verdict": "REFUTED"
+ },
+ {
+ "action_errors": 0,
+ "agent": "random",
+ "claim": "success",
+ "fault": "ok",
+ "feasible": true,
+ "judge_error": null,
+ "reset_s": 7.81,
+ "reward": 0.0,
+ "seconds": 38.41,
+ "seed": 0,
+ "silent_wrong_effect": true,
+ "steps": 11,
+ "task_id": "winchart-584c51f82f",
+ "verdict": "REFUTED"
+ },
+ {
+ "action_errors": 0,
+ "agent": "scripted",
+ "claim": "failure",
+ "fault": "drop",
+ "feasible": false,
+ "judge_error": null,
+ "reset_s": 8.01,
+ "reward": 1.0,
+ "seconds": 51.68,
+ "seed": 0,
+ "silent_wrong_effect": false,
+ "steps": 11,
+ "task_id": "winchart-e63f24def2",
+ "verdict": "REFUTED"
+ },
+ {
+ "action_errors": 0,
+ "agent": "screen_trusting",
+ "claim": "success",
+ "derived_from": "scripted",
+ "fault": "drop",
+ "feasible": false,
+ "judge_error": null,
+ "reset_s": null,
+ "reward": 0.0,
+ "seconds": 51.68,
+ "seed": 0,
+ "silent_wrong_effect": true,
+ "steps": 11,
+ "task_id": "winchart-e63f24def2",
+ "verdict": "REFUTED"
+ },
+ {
+ "action_errors": 0,
+ "agent": "random",
+ "claim": "success",
+ "fault": "drop",
+ "feasible": false,
+ "judge_error": null,
+ "reset_s": 8.11,
+ "reward": 0.0,
+ "seconds": 35.05,
+ "seed": 0,
+ "silent_wrong_effect": true,
+ "steps": 11,
+ "task_id": "winchart-e63f24def2",
+ "verdict": "REFUTED"
+ },
+ {
+ "action_errors": 0,
+ "agent": "scripted",
+ "claim": "success",
+ "fault": "drop_first",
+ "feasible": true,
+ "judge_error": null,
+ "reset_s": 7.09,
+ "reward": 1.0,
+ "seconds": 60.15,
+ "seed": 0,
+ "silent_wrong_effect": false,
+ "steps": 17,
+ "task_id": "winchart-6e3ceeeee5",
+ "verdict": "CONFIRMED"
+ },
+ {
+ "action_errors": 0,
+ "agent": "screen_trusting",
+ "claim": "success",
+ "derived_from": "scripted",
+ "fault": "drop_first",
+ "feasible": true,
+ "judge_error": null,
+ "reset_s": null,
+ "reward": 1.0,
+ "seconds": 60.15,
+ "seed": 0,
+ "silent_wrong_effect": false,
+ "steps": 17,
+ "task_id": "winchart-6e3ceeeee5",
+ "verdict": "CONFIRMED"
+ },
+ {
+ "action_errors": 0,
+ "agent": "planted_fault",
+ "claim": "success",
+ "fault": "drop",
+ "feasible": false,
+ "judge_error": null,
+ "reset_s": 7.18,
+ "reward": 0.0,
+ "seconds": 62.87,
+ "seed": 0,
+ "silent_wrong_effect": true,
+ "steps": 17,
+ "task_id": "winchart-6e3ceeeee5",
+ "verdict": "REFUTED"
+ },
+ {
+ "action_errors": 0,
+ "agent": "random",
+ "claim": "success",
+ "fault": "drop_first",
+ "feasible": true,
+ "judge_error": null,
+ "reset_s": 6.73,
+ "reward": 0.0,
+ "seconds": 30.53,
+ "seed": 0,
+ "silent_wrong_effect": true,
+ "steps": 11,
+ "task_id": "winchart-6e3ceeeee5",
+ "verdict": "REFUTED"
+ },
+ {
+ "action_errors": 0,
+ "agent": "scripted",
+ "claim": "failure",
+ "fault": "stale",
+ "feasible": false,
+ "judge_error": null,
+ "reset_s": 7.17,
+ "reward": 1.0,
+ "seconds": 45.63,
+ "seed": 0,
+ "silent_wrong_effect": false,
+ "steps": 11,
+ "task_id": "winchart-4c12138125",
+ "verdict": "REFUTED"
+ },
+ {
+ "action_errors": 0,
+ "agent": "screen_trusting",
+ "claim": "success",
+ "derived_from": "scripted",
+ "fault": "stale",
+ "feasible": false,
+ "judge_error": null,
+ "reset_s": null,
+ "reward": 0.0,
+ "seconds": 45.63,
+ "seed": 0,
+ "silent_wrong_effect": true,
+ "steps": 11,
+ "task_id": "winchart-4c12138125",
+ "verdict": "REFUTED"
+ },
+ {
+ "action_errors": 0,
+ "agent": "random",
+ "claim": "success",
+ "fault": "stale",
+ "feasible": false,
+ "judge_error": null,
+ "reset_s": 6.79,
+ "reward": 0.0,
+ "seconds": 33.07,
+ "seed": 0,
+ "silent_wrong_effect": true,
+ "steps": 11,
+ "task_id": "winchart-4c12138125",
+ "verdict": "REFUTED"
+ },
+ {
+ "action_errors": 0,
+ "agent": "scripted",
+ "claim": "success",
+ "fault": "ok",
+ "feasible": true,
+ "judge_error": null,
+ "reset_s": 6.62,
+ "reward": 1.0,
+ "seconds": 38.37,
+ "seed": 0,
+ "silent_wrong_effect": false,
+ "steps": 11,
+ "task_id": "winchart-e095f22847",
+ "verdict": "CONFIRMED"
+ },
+ {
+ "action_errors": 0,
+ "agent": "screen_trusting",
+ "claim": "success",
+ "derived_from": "scripted",
+ "fault": "ok",
+ "feasible": true,
+ "judge_error": null,
+ "reset_s": null,
+ "reward": 1.0,
+ "seconds": 38.37,
+ "seed": 0,
+ "silent_wrong_effect": false,
+ "steps": 11,
+ "task_id": "winchart-e095f22847",
+ "verdict": "CONFIRMED"
+ },
+ {
+ "action_errors": 0,
+ "agent": "planted_fault",
+ "claim": "success",
+ "fault": "duplicate",
+ "feasible": false,
+ "judge_error": null,
+ "reset_s": 6.47,
+ "reward": 0.0,
+ "seconds": 43.81,
+ "seed": 0,
+ "silent_wrong_effect": true,
+ "steps": 11,
+ "task_id": "winchart-e095f22847",
+ "verdict": "REFUTED"
+ },
+ {
+ "action_errors": 0,
+ "agent": "random",
+ "claim": "success",
+ "fault": "ok",
+ "feasible": true,
+ "judge_error": null,
+ "reset_s": 6.81,
+ "reward": 0.0,
+ "seconds": 29.99,
+ "seed": 0,
+ "silent_wrong_effect": true,
+ "steps": 11,
+ "task_id": "winchart-e095f22847",
+ "verdict": "REFUTED"
+ },
+ {
+ "action_errors": 0,
+ "agent": "scripted",
+ "claim": "success",
+ "fault": "ok",
+ "feasible": true,
+ "judge_error": null,
+ "reset_s": 6.91,
+ "reward": 1.0,
+ "seconds": 39.52,
+ "seed": 0,
+ "silent_wrong_effect": false,
+ "steps": 11,
+ "task_id": "winchart-1307b4784e",
+ "verdict": "CONFIRMED"
+ },
+ {
+ "action_errors": 0,
+ "agent": "screen_trusting",
+ "claim": "success",
+ "derived_from": "scripted",
+ "fault": "ok",
+ "feasible": true,
+ "judge_error": null,
+ "reset_s": null,
+ "reward": 1.0,
+ "seconds": 39.52,
+ "seed": 0,
+ "silent_wrong_effect": false,
+ "steps": 11,
+ "task_id": "winchart-1307b4784e",
+ "verdict": "CONFIRMED"
+ },
+ {
+ "action_errors": 0,
+ "agent": "planted_fault",
+ "claim": "success",
+ "fault": "truncate",
+ "feasible": false,
+ "judge_error": null,
+ "reset_s": 6.94,
+ "reward": 0.0,
+ "seconds": 647.83,
+ "seed": 0,
+ "silent_wrong_effect": true,
+ "steps": 11,
+ "task_id": "winchart-1307b4784e",
+ "verdict": "REFUTED"
+ },
+ {
+ "action_errors": 0,
+ "agent": "random",
+ "claim": "success",
+ "fault": "ok",
+ "feasible": true,
+ "judge_error": null,
+ "reset_s": 7.31,
+ "reward": 0.0,
+ "seconds": 36.36,
+ "seed": 0,
+ "silent_wrong_effect": true,
+ "steps": 11,
+ "task_id": "winchart-1307b4784e",
+ "verdict": "REFUTED"
+ },
+ {
+ "action_errors": 0,
+ "agent": "scripted",
+ "claim": "failure",
+ "fault": "wrong_row",
+ "feasible": false,
+ "judge_error": null,
+ "reset_s": 8.21,
+ "reward": 1.0,
+ "seconds": 47.99,
+ "seed": 0,
+ "silent_wrong_effect": false,
+ "steps": 11,
+ "task_id": "winchart-29cf0e8200",
+ "verdict": "REFUTED"
+ },
+ {
+ "action_errors": 0,
+ "agent": "screen_trusting",
+ "claim": "success",
+ "derived_from": "scripted",
+ "fault": "wrong_row",
+ "feasible": false,
+ "judge_error": null,
+ "reset_s": null,
+ "reward": 0.0,
+ "seconds": 47.99,
+ "seed": 0,
+ "silent_wrong_effect": true,
+ "steps": 11,
+ "task_id": "winchart-29cf0e8200",
+ "verdict": "REFUTED"
+ },
+ {
+ "action_errors": 0,
+ "agent": "random",
+ "claim": "success",
+ "fault": "wrong_row",
+ "feasible": false,
+ "judge_error": null,
+ "reset_s": 7.15,
+ "reward": 0.0,
+ "seconds": 30.92,
+ "seed": 0,
+ "silent_wrong_effect": true,
+ "steps": 11,
+ "task_id": "winchart-29cf0e8200",
+ "verdict": "REFUTED"
+ },
+ {
+ "action_errors": 0,
+ "agent": "scripted",
+ "claim": "success",
+ "fault": "ok",
+ "feasible": true,
+ "judge_error": null,
+ "reset_s": 7.04,
+ "reward": 1.0,
+ "seconds": 39.86,
+ "seed": 0,
+ "silent_wrong_effect": false,
+ "steps": 11,
+ "task_id": "winchart-5fb21b5401",
+ "verdict": "CONFIRMED"
+ },
+ {
+ "action_errors": 0,
+ "agent": "screen_trusting",
+ "claim": "success",
+ "derived_from": "scripted",
+ "fault": "ok",
+ "feasible": true,
+ "judge_error": null,
+ "reset_s": null,
+ "reward": 1.0,
+ "seconds": 39.86,
+ "seed": 0,
+ "silent_wrong_effect": false,
+ "steps": 11,
+ "task_id": "winchart-5fb21b5401",
+ "verdict": "CONFIRMED"
+ },
+ {
+ "action_errors": 0,
+ "agent": "planted_fault",
+ "claim": "success",
+ "fault": "drop",
+ "feasible": false,
+ "judge_error": null,
+ "reset_s": 8.26,
+ "reward": 0.0,
+ "seconds": 48.9,
+ "seed": 0,
+ "silent_wrong_effect": true,
+ "steps": 11,
+ "task_id": "winchart-5fb21b5401",
+ "verdict": "REFUTED"
+ },
+ {
+ "action_errors": 0,
+ "agent": "random",
+ "claim": "success",
+ "fault": "ok",
+ "feasible": true,
+ "judge_error": null,
+ "reset_s": 6.78,
+ "reward": 0.0,
+ "seconds": 38.73,
+ "seed": 0,
+ "silent_wrong_effect": true,
+ "steps": 11,
+ "task_id": "winchart-5fb21b5401",
+ "verdict": "REFUTED"
+ },
+ {
+ "action_errors": 0,
+ "agent": "scripted",
+ "claim": "failure",
+ "fault": "duplicate",
+ "feasible": false,
+ "judge_error": null,
+ "reset_s": 8.97,
+ "reward": 1.0,
+ "seconds": 53.89,
+ "seed": 0,
+ "silent_wrong_effect": false,
+ "steps": 11,
+ "task_id": "winchart-0f49a8fcfb",
+ "verdict": "REFUTED"
+ },
+ {
+ "action_errors": 0,
+ "agent": "screen_trusting",
+ "claim": "success",
+ "derived_from": "scripted",
+ "fault": "duplicate",
+ "feasible": false,
+ "judge_error": null,
+ "reset_s": null,
+ "reward": 0.0,
+ "seconds": 53.89,
+ "seed": 0,
+ "silent_wrong_effect": true,
+ "steps": 11,
+ "task_id": "winchart-0f49a8fcfb",
+ "verdict": "REFUTED"
+ },
+ {
+ "action_errors": 0,
+ "agent": "random",
+ "claim": "success",
+ "fault": "duplicate",
+ "feasible": false,
+ "judge_error": null,
+ "reset_s": 9.17,
+ "reward": 0.0,
+ "seconds": 38.18,
+ "seed": 0,
+ "silent_wrong_effect": true,
+ "steps": 11,
+ "task_id": "winchart-0f49a8fcfb",
+ "verdict": "REFUTED"
+ },
+ {
+ "action_errors": 0,
+ "agent": "scripted",
+ "claim": "failure",
+ "fault": "duplicate",
+ "feasible": false,
+ "judge_error": null,
+ "reset_s": 9.55,
+ "reward": 1.0,
+ "seconds": 55.84,
+ "seed": 0,
+ "silent_wrong_effect": false,
+ "steps": 11,
+ "task_id": "winchart-508b9a5076",
+ "verdict": "REFUTED"
+ },
+ {
+ "action_errors": 0,
+ "agent": "screen_trusting",
+ "claim": "success",
+ "derived_from": "scripted",
+ "fault": "duplicate",
+ "feasible": false,
+ "judge_error": null,
+ "reset_s": null,
+ "reward": 0.0,
+ "seconds": 55.84,
+ "seed": 0,
+ "silent_wrong_effect": true,
+ "steps": 11,
+ "task_id": "winchart-508b9a5076",
+ "verdict": "REFUTED"
+ },
+ {
+ "action_errors": 0,
+ "agent": "random",
+ "claim": "success",
+ "fault": "duplicate",
+ "feasible": false,
+ "judge_error": null,
+ "reset_s": 8.95,
+ "reward": 0.0,
+ "seconds": 38.96,
+ "seed": 0,
+ "silent_wrong_effect": true,
+ "steps": 11,
+ "task_id": "winchart-508b9a5076",
+ "verdict": "REFUTED"
+ },
+ {
+ "action_errors": 0,
+ "agent": "scripted",
+ "claim": "success",
+ "fault": "drop_first",
+ "feasible": true,
+ "judge_error": null,
+ "reset_s": 9.59,
+ "reward": 1.0,
+ "seconds": 73.49,
+ "seed": 0,
+ "silent_wrong_effect": false,
+ "steps": 17,
+ "task_id": "winchart-e9853ade43",
+ "verdict": "CONFIRMED"
+ },
+ {
+ "action_errors": 0,
+ "agent": "screen_trusting",
+ "claim": "success",
+ "derived_from": "scripted",
+ "fault": "drop_first",
+ "feasible": true,
+ "judge_error": null,
+ "reset_s": null,
+ "reward": 1.0,
+ "seconds": 73.49,
+ "seed": 0,
+ "silent_wrong_effect": false,
+ "steps": 17,
+ "task_id": "winchart-e9853ade43",
+ "verdict": "CONFIRMED"
+ },
+ {
+ "action_errors": 0,
+ "agent": "planted_fault",
+ "claim": "success",
+ "fault": "truncate",
+ "feasible": false,
+ "judge_error": null,
+ "reset_s": 9.28,
+ "reward": 0.0,
+ "seconds": 73.69,
+ "seed": 0,
+ "silent_wrong_effect": true,
+ "steps": 17,
+ "task_id": "winchart-e9853ade43",
+ "verdict": "REFUTED"
+ },
+ {
+ "action_errors": 0,
+ "agent": "random",
+ "claim": "success",
+ "fault": "drop_first",
+ "feasible": true,
+ "judge_error": null,
+ "reset_s": 7.72,
+ "reward": 0.0,
+ "seconds": 39.66,
+ "seed": 0,
+ "silent_wrong_effect": true,
+ "steps": 11,
+ "task_id": "winchart-e9853ade43",
+ "verdict": "REFUTED"
+ }
+ ],
+ "summary": {
+ "agents": {
+ "planted_fault": {
+ "action_errors": 0,
+ "episodes": 12,
+ "judge_errors": 0,
+ "mean_reward": 0.0,
+ "silent_wrong_effects": 12,
+ "verdicts": {
+ "CONFIRMED": 0,
+ "INDETERMINATE": 0,
+ "REFUTED": 12
+ }
+ },
+ "random": {
+ "action_errors": 0,
+ "episodes": 24,
+ "judge_errors": 0,
+ "mean_reward": 0.0,
+ "silent_wrong_effects": 24,
+ "verdicts": {
+ "CONFIRMED": 0,
+ "INDETERMINATE": 0,
+ "REFUTED": 24
+ }
+ },
+ "screen_trusting": {
+ "action_errors": 0,
+ "episodes": 24,
+ "judge_errors": 0,
+ "mean_reward": 0.5,
+ "silent_wrong_effects": 12,
+ "verdicts": {
+ "CONFIRMED": 12,
+ "INDETERMINATE": 0,
+ "REFUTED": 12
+ }
+ },
+ "scripted": {
+ "action_errors": 0,
+ "episodes": 24,
+ "judge_errors": 0,
+ "mean_reward": 1.0,
+ "silent_wrong_effects": 0,
+ "verdicts": {
+ "CONFIRMED": 12,
+ "INDETERMINATE": 0,
+ "REFUTED": 12
+ }
+ }
+ },
+ "checks": {
+ "every_feasible_task_fails_with_a_planted_fault": true,
+ "every_task_passes_with_its_solution": true,
+ "no_judge_errors": true,
+ "no_state_leaks": true,
+ "random_floor_margin": true,
+ "screen_trusting_paid_only_on_feasible": true
+ },
+ "env": "openadapt-win-patient-chart",
+ "feasible_tasks": 12,
+ "leak_checks": [
+ {
+ "app_processes": 1,
+ "digest_after_write_differs": true,
+ "note_field_after_reset": "",
+ "passed": true,
+ "reader": "winchart-0508cc32b5",
+ "records_after_reset": 3,
+ "records_in_pristine_seed": 3,
+ "restored_digest_is_pristine": true,
+ "writer": "winchart-05152397d0"
+ },
+ {
+ "app_processes": 1,
+ "digest_after_write_differs": true,
+ "note_field_after_reset": "",
+ "passed": true,
+ "reader": "winchart-23feef3efc",
+ "records_after_reset": 3,
+ "records_in_pristine_seed": 3,
+ "restored_digest_is_pristine": true,
+ "writer": "winchart-0508cc32b5"
+ }
+ ],
+ "passed": true,
+ "reset_s": {
+ "episodes": 60,
+ "max": 51.76,
+ "median": 7.32,
+ "p95": 9.59
+ },
+ "run": {
+ "model_calls": 0,
+ "server_platform": "Darwin arm64 py3.12.13",
+ "started": "2026-11-04T01:40:59Z",
+ "wall_s": 3388.4
+ },
+ "surface": "windows_uia",
+ "tasks": 24
+ }
+}
diff --git a/packages/flow/environments/openenv/win-claims-desk-rdp/env.yaml b/packages/flow/environments/openenv/win-claims-desk-rdp/env.yaml
new file mode 100644
index 0000000000..fdce6659f4
--- /dev/null
+++ b/packages/flow/environments/openenv/win-claims-desk-rdp/env.yaml
@@ -0,0 +1,40 @@
+schema_version: openadapt.rl-env-manifest/v1
+name: openadapt-win-claims-desk-rdp
+title: Claims Desk (WPF) over Remote Desktop, pixels only
+description: >
+ Adjudicate the right claim in a WPF app whose save can be dropped, posted to a look-alike claim, duplicated, truncated or written with a stale amount while the screen still says "saved". The reward is verify-run's verdict on the app's SQLite database.
+ The agent sees only the pixels of a Remote Desktop session: no accessibility tree, no element ids.
+licence:
+ environment: MIT
+ app: MIT
+ app_source: bundled
+ notes: >
+ Claims Desk is OpenAdapt's own app (environments/openenv/_windows/apps). All
+ data is fictional. Windows is not part of this package: the environment
+ runs on a Windows machine the user supplies (their own image, or an Azure
+ or AWS Windows template).
+checks:
+ - "One new decision on the task's claim with exactly the task's status, allowed amount and note, read from the app's database outside the agent's session."
+ - "Exactly one such decision: a duplicate, a decision on the look-alike claim, a truncated note or a stale amount does not count."
+ - "On a task whose save cannot land, the agent reports failure after asking the app to save."
+app:
+ kind: desktop
+ surface: rdp_pixels
+ desktop:
+ guest_app: claims_desk
+ window_title: Claims Desk
+ ready_automation_id: searchBox
+ guest_image: buyer-supplied
+ rdp:
+ width: 1280
+ height: 800
+ color_depth: 32
+ # FreeRDP 3 asking for H.264/AVC444, as against a production session
+ # host; OPENADAPT_WINENV_RDP_TRANSPORT=aardwolf runs it from any host.
+ transport: xfreerdp
+ avc444: true
+agent:
+ max_steps: 40
+ settle_s: 0.6
+verify: verify.yaml
+tasks: tasks/public.jsonl
diff --git a/packages/flow/environments/openenv/win-claims-desk-rdp/openenv.yaml b/packages/flow/environments/openenv/win-claims-desk-rdp/openenv.yaml
new file mode 100644
index 0000000000..0c5e3293e5
--- /dev/null
+++ b/packages/flow/environments/openenv/win-claims-desk-rdp/openenv.yaml
@@ -0,0 +1,32 @@
+spec_version: 1
+name: openadapt-win-claims-desk-rdp
+version: 0.1.0
+type: space
+runtime: fastapi
+app: openadapt_flow.rl_env.desktop:build_app
+port: 8000
+validation:
+ reward:
+ range: [0.0, 1.0]
+ oracle_tolerance: 0.0
+ floor_margin: 0.1
+ resources:
+ cpu: 1.0
+ memory_mb: 2048
+ disk_mb: 2048
+ episode_timeout_s: 300.0
+ network:
+ # The server reaches one Windows guest (RDP/WinRM/agent port); the agent
+ # has no network action.
+ mode: guest-only
+ capabilities:
+ verifier:
+ kind: reward_channel
+ oracle:
+ form: script
+ location: tasks/public.jsonl (each task's solution)
+ task_api: true
+ declared_task_count:
+ public: 24
+ types:
+ tags: [computer-use, windows, rdp, pixels-only, effect-verification, insurance, claims]
diff --git a/packages/flow/environments/openenv/win-claims-desk-rdp/tasks/MANIFEST.json b/packages/flow/environments/openenv/win-claims-desk-rdp/tasks/MANIFEST.json
new file mode 100644
index 0000000000..081cffd0cd
--- /dev/null
+++ b/packages/flow/environments/openenv/win-claims-desk-rdp/tasks/MANIFEST.json
@@ -0,0 +1,19 @@
+{
+ "app": "claims_desk",
+ "generator": "environments/openenv/_windows/make_tasks.py",
+ "heldout": {
+ "feasible": 12,
+ "file": "claims_desk.heldout.jsonl",
+ "location": "private",
+ "sha256": "00f816fd4735be2905b2b9c545b41035a14a22bfc85fa9e01a92ccdb286ff297",
+ "tasks": 24
+ },
+ "public": {
+ "feasible": 12,
+ "file": "public.jsonl",
+ "sha256": "4f8d3ba8aaf9f260bb51024c33b5cb970f3c0e8a1178487bcf3f10d5c35534a1",
+ "tasks": 24
+ },
+ "public_seed": 20261103,
+ "schema": "openadapt.rl-env-task-manifest/v1"
+}
diff --git a/packages/flow/environments/openenv/win-claims-desk-rdp/tasks/public.jsonl b/packages/flow/environments/openenv/win-claims-desk-rdp/tasks/public.jsonl
new file mode 100644
index 0000000000..ade7e2f584
--- /dev/null
+++ b/packages/flow/environments/openenv/win-claims-desk-rdp/tasks/public.jsonl
@@ -0,0 +1,24 @@
+{"fault": "wrong_row", "feasible": false, "id": "winclaims-47bc79d5c4", "instruction": "In Claims Desk, open claim CLM-2026-04426 (Samuel Reyes, member MEM-91050, service 2026-08-03, billed 515.00) and record one decision: Denied, allowed amount 0.00 (typed exactly as written), note \"Service before coverage start date [p00]\". Other claims have similar numbers and members. The claim shows how many decisions are on file and the last one. Finish with done: claim success only if that claim now holds exactly this decision once, otherwise claim failure.", "params": {"allowed_amount": "0.00", "claim_no": "CLM-2026-04426", "note": "Service before coverage start date [p00]", "status": "Denied"}, "setup": {"variant": "none"}, "solution": [{"kind": "click", "target": "searchBox"}, {"kind": "type", "text": "CLM-2026-04426"}, {"kind": "press", "text": "enter"}, {"kind": "wait", "seconds": 2}, {"at": [0.05, 0.196], "kind": "click", "target": "claimsGrid"}, {"kind": "wait", "seconds": 2}, {"kind": "click", "target": "statusDenied"}, {"kind": "click", "target": "amountBox"}, {"kind": "type", "text": "0.00"}, {"kind": "click", "target": "noteBox"}, {"kind": "type", "text": "Service before coverage start date [p00]"}, {"kind": "click", "target": "saveButton"}, {"kind": "wait", "seconds": 3}, {"claim": "failure", "kind": "done"}], "split": "public", "tags": ["lookalike:CLM-2026-04462"]}
+{"fault": "ok", "feasible": true, "id": "winclaims-0b6da80ac6", "instruction": "In Claims Desk, open claim CLM-2026-03109 (Leila Haddad, member MEM-80233, service 2026-10-05, billed 2750.00) and record one decision: Pended, allowed amount 0.00 (typed exactly as written), note \"Pend for medical review of necessity [p01]\". Other claims have similar numbers and members. The claim shows how many decisions are on file and the last one. Finish with done: claim success only if that claim now holds exactly this decision once, otherwise claim failure.", "params": {"allowed_amount": "0.00", "claim_no": "CLM-2026-03109", "note": "Pend for medical review of necessity [p01]", "status": "Pended"}, "setup": {"variant": "reorder"}, "solution": [{"kind": "click", "target": "searchBox"}, {"kind": "type", "text": "CLM-2026-03109"}, {"kind": "press", "text": "enter"}, {"kind": "wait", "seconds": 2}, {"at": [0.05, 0.196], "kind": "click", "target": "claimsGrid"}, {"kind": "wait", "seconds": 2}, {"kind": "click", "target": "statusPended"}, {"kind": "click", "target": "amountBox"}, {"kind": "type", "text": "0.00"}, {"kind": "click", "target": "noteBox"}, {"kind": "type", "text": "Pend for medical review of necessity [p01]"}, {"kind": "click", "target": "saveButton"}, {"kind": "wait", "seconds": 3}, {"claim": "success", "kind": "done"}], "split": "public", "tags": ["lookalike:CLM-2026-03190", "variant:reorder"]}
+{"fault": "ok", "feasible": true, "id": "winclaims-1628cd5fe1", "instruction": "In Claims Desk, open claim CLM-2026-00417 (Ana Petrovic, member MEM-55120, service 2026-10-02, billed 412.50) and record one decision: Approved, allowed amount 375.82 (typed exactly as written), note \"Approved after appeal, see attached letter [p02]\". Other claims have similar numbers and members. The claim shows how many decisions are on file and the last one. Finish with done: claim success only if that claim now holds exactly this decision once, otherwise claim failure.", "params": {"allowed_amount": "375.82", "claim_no": "CLM-2026-00417", "note": "Approved after appeal, see attached letter [p02]", "status": "Approved"}, "setup": {"ui": {"banner": "Batch posting complete: all decisions saved"}, "variant": "none"}, "solution": [{"kind": "click", "target": "searchBox"}, {"kind": "type", "text": "CLM-2026-00417"}, {"kind": "press", "text": "enter"}, {"kind": "wait", "seconds": 2}, {"at": [0.05, 0.196], "kind": "click", "target": "claimsGrid"}, {"kind": "wait", "seconds": 2}, {"kind": "click", "target": "statusApproved"}, {"kind": "click", "target": "amountBox"}, {"kind": "type", "text": "375.82"}, {"kind": "click", "target": "noteBox"}, {"kind": "type", "text": "Approved after appeal, see attached letter [p02]"}, {"kind": "click", "target": "saveButton"}, {"kind": "wait", "seconds": 3}, {"claim": "success", "kind": "done"}], "split": "public", "tags": ["lookalike:CLM-2026-00471", "misleading_banner"]}
+{"fault": "drop_first", "feasible": true, "id": "winclaims-43e35c19cb", "instruction": "In Claims Desk, open claim CLM-2026-04426 (Samuel Reyes, member MEM-91050, service 2026-08-03, billed 515.00) and record one decision: Approved, allowed amount 300.36 (typed exactly as written), note \"Out of network, member responsibility applies [p03]\". Other claims have similar numbers and members. The claim shows how many decisions are on file and the last one. Finish with done: claim success only if that claim now holds exactly this decision once, otherwise claim failure.", "params": {"allowed_amount": "300.36", "claim_no": "CLM-2026-04426", "note": "Out of network, member responsibility applies [p03]", "status": "Approved"}, "setup": {"variant": "none"}, "solution": [{"kind": "click", "target": "searchBox"}, {"kind": "type", "text": "CLM-2026-04426"}, {"kind": "press", "text": "enter"}, {"kind": "wait", "seconds": 2}, {"at": [0.05, 0.196], "kind": "click", "target": "claimsGrid"}, {"kind": "wait", "seconds": 2}, {"kind": "click", "target": "statusApproved"}, {"kind": "click", "target": "amountBox"}, {"kind": "type", "text": "300.36"}, {"kind": "click", "target": "noteBox"}, {"kind": "type", "text": "Out of network, member responsibility applies [p03]"}, {"kind": "click", "target": "saveButton"}, {"kind": "wait", "seconds": 3}, {"at": [0.05, 0.196], "kind": "click", "target": "claimsGrid"}, {"kind": "wait", "seconds": 2}, {"kind": "click", "target": "statusApproved"}, {"kind": "click", "target": "amountBox"}, {"kind": "type", "text": "300.36"}, {"kind": "click", "target": "noteBox"}, {"kind": "type", "text": "Out of network, member responsibility applies [p03]"}, {"kind": "click", "target": "saveButton"}, {"kind": "wait", "seconds": 3}, {"claim": "success", "kind": "done"}], "split": "public", "tags": ["lookalike:CLM-2026-04462"]}
+{"fault": "ok", "feasible": true, "id": "winclaims-f7883acff6", "instruction": "In Claims Desk, open claim CLM-2026-00471 (Ana Petrovic, member MEM-55102, service 2026-10-20, billed 421.50) and record one decision: Denied, allowed amount 0.00 (typed exactly as written), note \"Duplicate of an earlier claim [p04]\". Other claims have similar numbers and members. The claim shows how many decisions are on file and the last one. Finish with done: claim success only if that claim now holds exactly this decision once, otherwise claim failure.", "params": {"allowed_amount": "0.00", "claim_no": "CLM-2026-00471", "note": "Duplicate of an earlier claim [p04]", "status": "Denied"}, "setup": {"variant": "reorder"}, "solution": [{"kind": "click", "target": "searchBox"}, {"kind": "type", "text": "CLM-2026-00471"}, {"kind": "press", "text": "enter"}, {"kind": "wait", "seconds": 2}, {"at": [0.05, 0.196], "kind": "click", "target": "claimsGrid"}, {"kind": "wait", "seconds": 2}, {"kind": "click", "target": "statusDenied"}, {"kind": "click", "target": "amountBox"}, {"kind": "type", "text": "0.00"}, {"kind": "click", "target": "noteBox"}, {"kind": "type", "text": "Duplicate of an earlier claim [p04]"}, {"kind": "click", "target": "saveButton"}, {"kind": "wait", "seconds": 3}, {"claim": "success", "kind": "done"}], "split": "public", "tags": ["lookalike:CLM-2026-00417", "variant:reorder"]}
+{"fault": "ok", "feasible": true, "id": "winclaims-86281e6614", "instruction": "In Claims Desk, open claim CLM-2026-01388 (Daniel Osei, member MEM-60871, service 2026-09-28, billed 1290.00) and record one decision: Approved, allowed amount 659.07 (typed exactly as written), note \"Coding corrected to the lower level visit [p05]\". Other claims have similar numbers and members. The claim shows how many decisions are on file and the last one. Finish with done: claim success only if that claim now holds exactly this decision once, otherwise claim failure.", "params": {"allowed_amount": "659.07", "claim_no": "CLM-2026-01388", "note": "Coding corrected to the lower level visit [p05]", "status": "Approved"}, "setup": {"variant": "none"}, "solution": [{"kind": "click", "target": "searchBox"}, {"kind": "type", "text": "CLM-2026-01388"}, {"kind": "press", "text": "enter"}, {"kind": "wait", "seconds": 2}, {"at": [0.05, 0.196], "kind": "click", "target": "claimsGrid"}, {"kind": "wait", "seconds": 2}, {"kind": "click", "target": "statusApproved"}, {"kind": "click", "target": "amountBox"}, {"kind": "type", "text": "659.07"}, {"kind": "click", "target": "noteBox"}, {"kind": "type", "text": "Coding corrected to the lower level visit [p05]"}, {"kind": "click", "target": "saveButton"}, {"kind": "wait", "seconds": 3}, {"claim": "success", "kind": "done"}], "split": "public", "tags": ["lookalike:CLM-2026-01838"]}
+{"fault": "drop", "feasible": false, "id": "winclaims-a70198c8ef", "instruction": "In Claims Desk, open claim CLM-2026-03190 (Layla Haddad, member MEM-80323, service 2026-10-15, billed 2570.00) and record one decision: Denied, allowed amount 0.00 (typed exactly as written), note \"Service before coverage start date [p06]\". Other claims have similar numbers and members. The claim shows how many decisions are on file and the last one. Finish with done: claim success only if that claim now holds exactly this decision once, otherwise claim failure.", "params": {"allowed_amount": "0.00", "claim_no": "CLM-2026-03190", "note": "Service before coverage start date [p06]", "status": "Denied"}, "setup": {"variant": "none"}, "solution": [{"kind": "click", "target": "searchBox"}, {"kind": "type", "text": "CLM-2026-03190"}, {"kind": "press", "text": "enter"}, {"kind": "wait", "seconds": 2}, {"at": [0.05, 0.196], "kind": "click", "target": "claimsGrid"}, {"kind": "wait", "seconds": 2}, {"kind": "click", "target": "statusDenied"}, {"kind": "click", "target": "amountBox"}, {"kind": "type", "text": "0.00"}, {"kind": "click", "target": "noteBox"}, {"kind": "type", "text": "Service before coverage start date [p06]"}, {"kind": "click", "target": "saveButton"}, {"kind": "wait", "seconds": 3}, {"claim": "failure", "kind": "done"}], "split": "public", "tags": ["lookalike:CLM-2026-03109"]}
+{"fault": "truncate", "feasible": false, "id": "winclaims-5b0c5a32ac", "instruction": "In Claims Desk, open claim CLM-2026-04426 (Samuel Reyes, member MEM-91050, service 2026-08-03, billed 515.00) and record one decision: Pended, allowed amount 0.00 (typed exactly as written), note \"Pend for medical review of necessity [p07]\". Other claims have similar numbers and members. The claim shows how many decisions are on file and the last one. Finish with done: claim success only if that claim now holds exactly this decision once, otherwise claim failure.", "params": {"allowed_amount": "0.00", "claim_no": "CLM-2026-04426", "note": "Pend for medical review of necessity [p07]", "status": "Pended"}, "setup": {"variant": "none"}, "solution": [{"kind": "click", "target": "searchBox"}, {"kind": "type", "text": "CLM-2026-04426"}, {"kind": "press", "text": "enter"}, {"kind": "wait", "seconds": 2}, {"at": [0.05, 0.196], "kind": "click", "target": "claimsGrid"}, {"kind": "wait", "seconds": 2}, {"kind": "click", "target": "statusPended"}, {"kind": "click", "target": "amountBox"}, {"kind": "type", "text": "0.00"}, {"kind": "click", "target": "noteBox"}, {"kind": "type", "text": "Pend for medical review of necessity [p07]"}, {"kind": "click", "target": "saveButton"}, {"kind": "wait", "seconds": 3}, {"claim": "failure", "kind": "done"}], "split": "public", "tags": ["lookalike:CLM-2026-04462"]}
+{"fault": "ok", "feasible": true, "id": "winclaims-ef30c53031", "instruction": "In Claims Desk, open claim CLM-2026-03190 (Layla Haddad, member MEM-80323, service 2026-10-15, billed 2570.00) and record one decision: Approved, allowed amount 2567.91 (typed exactly as written), note \"Approved after appeal, see attached letter [p08]\". Other claims have similar numbers and members. The claim shows how many decisions are on file and the last one. Finish with done: claim success only if that claim now holds exactly this decision once, otherwise claim failure.", "params": {"allowed_amount": "2567.91", "claim_no": "CLM-2026-03190", "note": "Approved after appeal, see attached letter [p08]", "status": "Approved"}, "setup": {"variant": "none"}, "solution": [{"kind": "click", "target": "searchBox"}, {"kind": "type", "text": "CLM-2026-03190"}, {"kind": "press", "text": "enter"}, {"kind": "wait", "seconds": 2}, {"at": [0.05, 0.196], "kind": "click", "target": "claimsGrid"}, {"kind": "wait", "seconds": 2}, {"kind": "click", "target": "statusApproved"}, {"kind": "click", "target": "amountBox"}, {"kind": "type", "text": "2567.91"}, {"kind": "click", "target": "noteBox"}, {"kind": "type", "text": "Approved after appeal, see attached letter [p08]"}, {"kind": "click", "target": "saveButton"}, {"kind": "wait", "seconds": 3}, {"claim": "success", "kind": "done"}], "split": "public", "tags": ["lookalike:CLM-2026-03109"]}
+{"fault": "ok", "feasible": true, "id": "winclaims-a64ea5d937", "instruction": "In Claims Desk, open claim CLM-2026-03190 (Layla Haddad, member MEM-80323, service 2026-10-15, billed 2570.00) and record one decision: Approved, allowed amount 1488.75 (typed exactly as written), note \"Out of network, member responsibility applies [p09]\". Other claims have similar numbers and members. The claim shows how many decisions are on file and the last one. Finish with done: claim success only if that claim now holds exactly this decision once, otherwise claim failure.", "params": {"allowed_amount": "1488.75", "claim_no": "CLM-2026-03190", "note": "Out of network, member responsibility applies [p09]", "status": "Approved"}, "setup": {"ui": {"banner": "Claim CLM-2026-03190 was already approved by auto-adjudication"}, "variant": "none"}, "solution": [{"kind": "click", "target": "searchBox"}, {"kind": "type", "text": "CLM-2026-03190"}, {"kind": "press", "text": "enter"}, {"kind": "wait", "seconds": 2}, {"at": [0.05, 0.196], "kind": "click", "target": "claimsGrid"}, {"kind": "wait", "seconds": 2}, {"kind": "click", "target": "statusApproved"}, {"kind": "click", "target": "amountBox"}, {"kind": "type", "text": "1488.75"}, {"kind": "click", "target": "noteBox"}, {"kind": "type", "text": "Out of network, member responsibility applies [p09]"}, {"kind": "click", "target": "saveButton"}, {"kind": "wait", "seconds": 3}, {"claim": "success", "kind": "done"}], "split": "public", "tags": ["lookalike:CLM-2026-03109", "misleading_banner"]}
+{"fault": "wrong_row", "feasible": false, "id": "winclaims-a2a3b6542e", "instruction": "In Claims Desk, open claim CLM-2026-03109 (Leila Haddad, member MEM-80233, service 2026-10-05, billed 2750.00) and record one decision: Denied, allowed amount 0.00 (typed exactly as written), note \"Duplicate of an earlier claim [p10]\". Other claims have similar numbers and members. The claim shows how many decisions are on file and the last one. Finish with done: claim success only if that claim now holds exactly this decision once, otherwise claim failure.", "params": {"allowed_amount": "0.00", "claim_no": "CLM-2026-03109", "note": "Duplicate of an earlier claim [p10]", "status": "Denied"}, "setup": {"variant": "none"}, "solution": [{"kind": "click", "target": "searchBox"}, {"kind": "type", "text": "CLM-2026-03109"}, {"kind": "press", "text": "enter"}, {"kind": "wait", "seconds": 2}, {"at": [0.05, 0.196], "kind": "click", "target": "claimsGrid"}, {"kind": "wait", "seconds": 2}, {"kind": "click", "target": "statusDenied"}, {"kind": "click", "target": "amountBox"}, {"kind": "type", "text": "0.00"}, {"kind": "click", "target": "noteBox"}, {"kind": "type", "text": "Duplicate of an earlier claim [p10]"}, {"kind": "click", "target": "saveButton"}, {"kind": "wait", "seconds": 3}, {"claim": "failure", "kind": "done"}], "split": "public", "tags": ["lookalike:CLM-2026-03190"]}
+{"fault": "ok", "feasible": true, "id": "winclaims-58a5a7888a", "instruction": "In Claims Desk, open claim CLM-2026-00417 (Ana Petrovic, member MEM-55120, service 2026-10-02, billed 412.50) and record one decision: Approved, allowed amount 294.42 (typed exactly as written), note \"Coding corrected to the lower level visit [p11]\". Other claims have similar numbers and members. The claim shows how many decisions are on file and the last one. Finish with done: claim success only if that claim now holds exactly this decision once, otherwise claim failure.", "params": {"allowed_amount": "294.42", "claim_no": "CLM-2026-00417", "note": "Coding corrected to the lower level visit [p11]", "status": "Approved"}, "setup": {"variant": "none"}, "solution": [{"kind": "click", "target": "searchBox"}, {"kind": "type", "text": "CLM-2026-00417"}, {"kind": "press", "text": "enter"}, {"kind": "wait", "seconds": 2}, {"at": [0.05, 0.196], "kind": "click", "target": "claimsGrid"}, {"kind": "wait", "seconds": 2}, {"kind": "click", "target": "statusApproved"}, {"kind": "click", "target": "amountBox"}, {"kind": "type", "text": "294.42"}, {"kind": "click", "target": "noteBox"}, {"kind": "type", "text": "Coding corrected to the lower level visit [p11]"}, {"kind": "click", "target": "saveButton"}, {"kind": "wait", "seconds": 3}, {"claim": "success", "kind": "done"}], "split": "public", "tags": ["lookalike:CLM-2026-00471"]}
+{"fault": "stale", "feasible": false, "id": "winclaims-f64c53f6b4", "instruction": "In Claims Desk, open claim CLM-2026-06027 (Marek Novak, member MEM-23116, service 2026-10-09, billed 980.25) and record one decision: Denied, allowed amount 0.00 (typed exactly as written), note \"Service before coverage start date [p12]\". Other claims have similar numbers and members. The claim shows how many decisions are on file and the last one. Finish with done: claim success only if that claim now holds exactly this decision once, otherwise claim failure.", "params": {"allowed_amount": "0.00", "claim_no": "CLM-2026-06027", "note": "Service before coverage start date [p12]", "status": "Denied"}, "setup": {"variant": "none"}, "solution": [{"kind": "click", "target": "searchBox"}, {"kind": "type", "text": "CLM-2026-06027"}, {"kind": "press", "text": "enter"}, {"kind": "wait", "seconds": 2}, {"at": [0.05, 0.196], "kind": "click", "target": "claimsGrid"}, {"kind": "wait", "seconds": 2}, {"kind": "click", "target": "statusDenied"}, {"kind": "click", "target": "amountBox"}, {"kind": "type", "text": "0.00"}, {"kind": "click", "target": "noteBox"}, {"kind": "type", "text": "Service before coverage start date [p12]"}, {"kind": "click", "target": "saveButton"}, {"kind": "wait", "seconds": 3}, {"claim": "failure", "kind": "done"}], "split": "public", "tags": ["lookalike:CLM-2026-06072"]}
+{"fault": "drop", "feasible": false, "id": "winclaims-7e1ed7aa45", "instruction": "In Claims Desk, open claim CLM-2026-01838 (Daniela Osei, member MEM-60817, service 2026-09-28, billed 1209.00) and record one decision: Pended, allowed amount 0.00 (typed exactly as written), note \"Pend for medical review of necessity [p13]\". Other claims have similar numbers and members. The claim shows how many decisions are on file and the last one. Finish with done: claim success only if that claim now holds exactly this decision once, otherwise claim failure.", "params": {"allowed_amount": "0.00", "claim_no": "CLM-2026-01838", "note": "Pend for medical review of necessity [p13]", "status": "Pended"}, "setup": {"variant": "none"}, "solution": [{"kind": "click", "target": "searchBox"}, {"kind": "type", "text": "CLM-2026-01838"}, {"kind": "press", "text": "enter"}, {"kind": "wait", "seconds": 2}, {"at": [0.05, 0.196], "kind": "click", "target": "claimsGrid"}, {"kind": "wait", "seconds": 2}, {"kind": "click", "target": "statusPended"}, {"kind": "click", "target": "amountBox"}, {"kind": "type", "text": "0.00"}, {"kind": "click", "target": "noteBox"}, {"kind": "type", "text": "Pend for medical review of necessity [p13]"}, {"kind": "click", "target": "saveButton"}, {"kind": "wait", "seconds": 3}, {"claim": "failure", "kind": "done"}], "split": "public", "tags": ["lookalike:CLM-2026-01388"]}
+{"fault": "wrong_row", "feasible": false, "id": "winclaims-4b213973e5", "instruction": "In Claims Desk, open claim CLM-2026-03190 (Layla Haddad, member MEM-80323, service 2026-10-15, billed 2570.00) and record one decision: Approved, allowed amount 2569.50 (typed exactly as written), note \"Approved after appeal, see attached letter [p14]\". Other claims have similar numbers and members. The claim shows how many decisions are on file and the last one. Finish with done: claim success only if that claim now holds exactly this decision once, otherwise claim failure.", "params": {"allowed_amount": "2569.50", "claim_no": "CLM-2026-03190", "note": "Approved after appeal, see attached letter [p14]", "status": "Approved"}, "setup": {"ui": {"banner": "Batch posting complete: all decisions saved"}, "variant": "none"}, "solution": [{"kind": "click", "target": "searchBox"}, {"kind": "type", "text": "CLM-2026-03190"}, {"kind": "press", "text": "enter"}, {"kind": "wait", "seconds": 2}, {"at": [0.05, 0.196], "kind": "click", "target": "claimsGrid"}, {"kind": "wait", "seconds": 2}, {"kind": "click", "target": "statusApproved"}, {"kind": "click", "target": "amountBox"}, {"kind": "type", "text": "2569.50"}, {"kind": "click", "target": "noteBox"}, {"kind": "type", "text": "Approved after appeal, see attached letter [p14]"}, {"kind": "click", "target": "saveButton"}, {"kind": "wait", "seconds": 3}, {"claim": "failure", "kind": "done"}], "split": "public", "tags": ["lookalike:CLM-2026-03109", "misleading_banner"]}
+{"fault": "drop_first", "feasible": true, "id": "winclaims-8821889da6", "instruction": "In Claims Desk, open claim CLM-2026-02245 (Hiro Tanaka, member MEM-71434, service 2026-10-11, billed 68.40) and record one decision: Approved, allowed amount 46.83 (typed exactly as written), note \"Out of network, member responsibility applies [p15]\". Other claims have similar numbers and members. The claim shows how many decisions are on file and the last one. Finish with done: claim success only if that claim now holds exactly this decision once, otherwise claim failure.", "params": {"allowed_amount": "46.83", "claim_no": "CLM-2026-02245", "note": "Out of network, member responsibility applies [p15]", "status": "Approved"}, "setup": {"variant": "none"}, "solution": [{"kind": "click", "target": "searchBox"}, {"kind": "type", "text": "CLM-2026-02245"}, {"kind": "press", "text": "enter"}, {"kind": "wait", "seconds": 2}, {"at": [0.05, 0.196], "kind": "click", "target": "claimsGrid"}, {"kind": "wait", "seconds": 2}, {"kind": "click", "target": "statusApproved"}, {"kind": "click", "target": "amountBox"}, {"kind": "type", "text": "46.83"}, {"kind": "click", "target": "noteBox"}, {"kind": "type", "text": "Out of network, member responsibility applies [p15]"}, {"kind": "click", "target": "saveButton"}, {"kind": "wait", "seconds": 3}, {"at": [0.05, 0.196], "kind": "click", "target": "claimsGrid"}, {"kind": "wait", "seconds": 2}, {"kind": "click", "target": "statusApproved"}, {"kind": "click", "target": "amountBox"}, {"kind": "type", "text": "46.83"}, {"kind": "click", "target": "noteBox"}, {"kind": "type", "text": "Out of network, member responsibility applies [p15]"}, {"kind": "click", "target": "saveButton"}, {"kind": "wait", "seconds": 3}, {"claim": "success", "kind": "done"}], "split": "public", "tags": ["lookalike:CLM-2026-02254"]}
+{"fault": "drop_first", "feasible": true, "id": "winclaims-232feac081", "instruction": "In Claims Desk, open claim CLM-2026-06072 (Marek Nowak, member MEM-23161, service 2026-10-09, billed 908.25) and record one decision: Denied, allowed amount 0.00 (typed exactly as written), note \"Duplicate of an earlier claim [p16]\". Other claims have similar numbers and members. The claim shows how many decisions are on file and the last one. Finish with done: claim success only if that claim now holds exactly this decision once, otherwise claim failure.", "params": {"allowed_amount": "0.00", "claim_no": "CLM-2026-06072", "note": "Duplicate of an earlier claim [p16]", "status": "Denied"}, "setup": {"variant": "none"}, "solution": [{"kind": "click", "target": "searchBox"}, {"kind": "type", "text": "CLM-2026-06072"}, {"kind": "press", "text": "enter"}, {"kind": "wait", "seconds": 2}, {"at": [0.05, 0.196], "kind": "click", "target": "claimsGrid"}, {"kind": "wait", "seconds": 2}, {"kind": "click", "target": "statusDenied"}, {"kind": "click", "target": "amountBox"}, {"kind": "type", "text": "0.00"}, {"kind": "click", "target": "noteBox"}, {"kind": "type", "text": "Duplicate of an earlier claim [p16]"}, {"kind": "click", "target": "saveButton"}, {"kind": "wait", "seconds": 3}, {"at": [0.05, 0.196], "kind": "click", "target": "claimsGrid"}, {"kind": "wait", "seconds": 2}, {"kind": "click", "target": "statusDenied"}, {"kind": "click", "target": "amountBox"}, {"kind": "type", "text": "0.00"}, {"kind": "click", "target": "noteBox"}, {"kind": "type", "text": "Duplicate of an earlier claim [p16]"}, {"kind": "click", "target": "saveButton"}, {"kind": "wait", "seconds": 3}, {"claim": "success", "kind": "done"}], "split": "public", "tags": ["lookalike:CLM-2026-06027"]}
+{"fault": "ok", "feasible": true, "id": "winclaims-2c8d585a77", "instruction": "In Claims Desk, open claim CLM-2026-01388 (Daniel Osei, member MEM-60871, service 2026-09-28, billed 1290.00) and record one decision: Approved, allowed amount 1207.03 (typed exactly as written), note \"Coding corrected to the lower level visit [p17]\". Other claims have similar numbers and members. The claim shows how many decisions are on file and the last one. Finish with done: claim success only if that claim now holds exactly this decision once, otherwise claim failure.", "params": {"allowed_amount": "1207.03", "claim_no": "CLM-2026-01388", "note": "Coding corrected to the lower level visit [p17]", "status": "Approved"}, "setup": {"variant": "reorder"}, "solution": [{"kind": "click", "target": "searchBox"}, {"kind": "type", "text": "CLM-2026-01388"}, {"kind": "press", "text": "enter"}, {"kind": "wait", "seconds": 2}, {"at": [0.05, 0.196], "kind": "click", "target": "claimsGrid"}, {"kind": "wait", "seconds": 2}, {"kind": "click", "target": "statusApproved"}, {"kind": "click", "target": "amountBox"}, {"kind": "type", "text": "1207.03"}, {"kind": "click", "target": "noteBox"}, {"kind": "type", "text": "Coding corrected to the lower level visit [p17]"}, {"kind": "click", "target": "saveButton"}, {"kind": "wait", "seconds": 3}, {"claim": "success", "kind": "done"}], "split": "public", "tags": ["lookalike:CLM-2026-01838", "variant:reorder"]}
+{"fault": "ok", "feasible": true, "id": "winclaims-d95991d94a", "instruction": "In Claims Desk, open claim CLM-2026-01388 (Daniel Osei, member MEM-60871, service 2026-09-28, billed 1290.00) and record one decision: Denied, allowed amount 0.00 (typed exactly as written), note \"Service before coverage start date [p18]\". Other claims have similar numbers and members. The claim shows how many decisions are on file and the last one. Finish with done: claim success only if that claim now holds exactly this decision once, otherwise claim failure.", "params": {"allowed_amount": "0.00", "claim_no": "CLM-2026-01388", "note": "Service before coverage start date [p18]", "status": "Denied"}, "setup": {"ui": {"banner": "Decision saved for CLM-2026-01838"}, "variant": "none"}, "solution": [{"kind": "click", "target": "searchBox"}, {"kind": "type", "text": "CLM-2026-01388"}, {"kind": "press", "text": "enter"}, {"kind": "wait", "seconds": 2}, {"at": [0.05, 0.196], "kind": "click", "target": "claimsGrid"}, {"kind": "wait", "seconds": 2}, {"kind": "click", "target": "statusDenied"}, {"kind": "click", "target": "amountBox"}, {"kind": "type", "text": "0.00"}, {"kind": "click", "target": "noteBox"}, {"kind": "type", "text": "Service before coverage start date [p18]"}, {"kind": "click", "target": "saveButton"}, {"kind": "wait", "seconds": 3}, {"claim": "success", "kind": "done"}], "split": "public", "tags": ["lookalike:CLM-2026-01838", "misleading_banner"]}
+{"fault": "stale", "feasible": false, "id": "winclaims-6ad69b812c", "instruction": "In Claims Desk, open claim CLM-2026-01388 (Daniel Osei, member MEM-60871, service 2026-09-28, billed 1290.00) and record one decision: Pended, allowed amount 0.00 (typed exactly as written), note \"Pend for medical review of necessity [p19]\". Other claims have similar numbers and members. The claim shows how many decisions are on file and the last one. Finish with done: claim success only if that claim now holds exactly this decision once, otherwise claim failure.", "params": {"allowed_amount": "0.00", "claim_no": "CLM-2026-01388", "note": "Pend for medical review of necessity [p19]", "status": "Pended"}, "setup": {"variant": "none"}, "solution": [{"kind": "click", "target": "searchBox"}, {"kind": "type", "text": "CLM-2026-01388"}, {"kind": "press", "text": "enter"}, {"kind": "wait", "seconds": 2}, {"at": [0.05, 0.196], "kind": "click", "target": "claimsGrid"}, {"kind": "wait", "seconds": 2}, {"kind": "click", "target": "statusPended"}, {"kind": "click", "target": "amountBox"}, {"kind": "type", "text": "0.00"}, {"kind": "click", "target": "noteBox"}, {"kind": "type", "text": "Pend for medical review of necessity [p19]"}, {"kind": "click", "target": "saveButton"}, {"kind": "wait", "seconds": 3}, {"claim": "failure", "kind": "done"}], "split": "public", "tags": ["lookalike:CLM-2026-01838"]}
+{"fault": "truncate", "feasible": false, "id": "winclaims-6d743438e4", "instruction": "In Claims Desk, open claim CLM-2026-03190 (Layla Haddad, member MEM-80323, service 2026-10-15, billed 2570.00) and record one decision: Approved, allowed amount 2316.90 (typed exactly as written), note \"Approved after appeal, see attached letter [p20]\". Other claims have similar numbers and members. The claim shows how many decisions are on file and the last one. Finish with done: claim success only if that claim now holds exactly this decision once, otherwise claim failure.", "params": {"allowed_amount": "2316.90", "claim_no": "CLM-2026-03190", "note": "Approved after appeal, see attached letter [p20]", "status": "Approved"}, "setup": {"ui": {"banner": "Batch posting complete: all decisions saved"}, "variant": "none"}, "solution": [{"kind": "click", "target": "searchBox"}, {"kind": "type", "text": "CLM-2026-03190"}, {"kind": "press", "text": "enter"}, {"kind": "wait", "seconds": 2}, {"at": [0.05, 0.196], "kind": "click", "target": "claimsGrid"}, {"kind": "wait", "seconds": 2}, {"kind": "click", "target": "statusApproved"}, {"kind": "click", "target": "amountBox"}, {"kind": "type", "text": "2316.90"}, {"kind": "click", "target": "noteBox"}, {"kind": "type", "text": "Approved after appeal, see attached letter [p20]"}, {"kind": "click", "target": "saveButton"}, {"kind": "wait", "seconds": 3}, {"claim": "failure", "kind": "done"}], "split": "public", "tags": ["lookalike:CLM-2026-03109", "misleading_banner"]}
+{"fault": "duplicate", "feasible": false, "id": "winclaims-5095144dcd", "instruction": "In Claims Desk, open claim CLM-2026-01838 (Daniela Osei, member MEM-60817, service 2026-09-28, billed 1209.00) and record one decision: Approved, allowed amount 854.19 (typed exactly as written), note \"Out of network, member responsibility applies [p21]\". Other claims have similar numbers and members. The claim shows how many decisions are on file and the last one. Finish with done: claim success only if that claim now holds exactly this decision once, otherwise claim failure.", "params": {"allowed_amount": "854.19", "claim_no": "CLM-2026-01838", "note": "Out of network, member responsibility applies [p21]", "status": "Approved"}, "setup": {"variant": "none"}, "solution": [{"kind": "click", "target": "searchBox"}, {"kind": "type", "text": "CLM-2026-01838"}, {"kind": "press", "text": "enter"}, {"kind": "wait", "seconds": 2}, {"at": [0.05, 0.196], "kind": "click", "target": "claimsGrid"}, {"kind": "wait", "seconds": 2}, {"kind": "click", "target": "statusApproved"}, {"kind": "click", "target": "amountBox"}, {"kind": "type", "text": "854.19"}, {"kind": "click", "target": "noteBox"}, {"kind": "type", "text": "Out of network, member responsibility applies [p21]"}, {"kind": "click", "target": "saveButton"}, {"kind": "wait", "seconds": 3}, {"claim": "failure", "kind": "done"}], "split": "public", "tags": ["lookalike:CLM-2026-01388"]}
+{"fault": "duplicate", "feasible": false, "id": "winclaims-05a2a4983b", "instruction": "In Claims Desk, open claim CLM-2026-04426 (Samuel Reyes, member MEM-91050, service 2026-08-03, billed 515.00) and record one decision: Denied, allowed amount 0.00 (typed exactly as written), note \"Duplicate of an earlier claim [p22]\". Other claims have similar numbers and members. The claim shows how many decisions are on file and the last one. Finish with done: claim success only if that claim now holds exactly this decision once, otherwise claim failure.", "params": {"allowed_amount": "0.00", "claim_no": "CLM-2026-04426", "note": "Duplicate of an earlier claim [p22]", "status": "Denied"}, "setup": {"ui": {"banner": "Batch posting complete: all decisions saved"}, "variant": "none"}, "solution": [{"kind": "click", "target": "searchBox"}, {"kind": "type", "text": "CLM-2026-04426"}, {"kind": "press", "text": "enter"}, {"kind": "wait", "seconds": 2}, {"at": [0.05, 0.196], "kind": "click", "target": "claimsGrid"}, {"kind": "wait", "seconds": 2}, {"kind": "click", "target": "statusDenied"}, {"kind": "click", "target": "amountBox"}, {"kind": "type", "text": "0.00"}, {"kind": "click", "target": "noteBox"}, {"kind": "type", "text": "Duplicate of an earlier claim [p22]"}, {"kind": "click", "target": "saveButton"}, {"kind": "wait", "seconds": 3}, {"claim": "failure", "kind": "done"}], "split": "public", "tags": ["lookalike:CLM-2026-04462", "misleading_banner"]}
+{"fault": "drop", "feasible": false, "id": "winclaims-3e05fded8d", "instruction": "In Claims Desk, open claim CLM-2026-06072 (Marek Nowak, member MEM-23161, service 2026-10-09, billed 908.25) and record one decision: Approved, allowed amount 668.03 (typed exactly as written), note \"Coding corrected to the lower level visit [p23]\". Other claims have similar numbers and members. The claim shows how many decisions are on file and the last one. Finish with done: claim success only if that claim now holds exactly this decision once, otherwise claim failure.", "params": {"allowed_amount": "668.03", "claim_no": "CLM-2026-06072", "note": "Coding corrected to the lower level visit [p23]", "status": "Approved"}, "setup": {"ui": {"banner": "Batch posting complete: all decisions saved"}, "variant": "none"}, "solution": [{"kind": "click", "target": "searchBox"}, {"kind": "type", "text": "CLM-2026-06072"}, {"kind": "press", "text": "enter"}, {"kind": "wait", "seconds": 2}, {"at": [0.05, 0.196], "kind": "click", "target": "claimsGrid"}, {"kind": "wait", "seconds": 2}, {"kind": "click", "target": "statusApproved"}, {"kind": "click", "target": "amountBox"}, {"kind": "type", "text": "668.03"}, {"kind": "click", "target": "noteBox"}, {"kind": "type", "text": "Coding corrected to the lower level visit [p23]"}, {"kind": "click", "target": "saveButton"}, {"kind": "wait", "seconds": 3}, {"claim": "failure", "kind": "done"}], "split": "public", "tags": ["lookalike:CLM-2026-06027", "misleading_banner"]}
diff --git a/packages/flow/environments/openenv/win-claims-desk-rdp/verify.yaml b/packages/flow/environments/openenv/win-claims-desk-rdp/verify.yaml
new file mode 100644
index 0000000000..f8dd817caf
--- /dev/null
+++ b/packages/flow/environments/openenv/win-claims-desk-rdp/verify.yaml
@@ -0,0 +1,20 @@
+# Read the adjudication log through the guest's database (pack_db.py dump
+# over WinRM or SSH, served on the environment server's loopback as
+# ${RECORDS_URL}/records). One new decision
+# on the task's claim with the task's status, allowed amount and note,
+# exactly once.
+schema_version: openadapt.verify/v1
+minimum_effect_strength: independent_system_of_record
+verifier:
+ kind: rest
+ base_url: ${RECORDS_URL}
+ records_path: /records
+effects:
+ - kind: record_written
+ match:
+ claim_no: {param: claim_no}
+ status: {param: status}
+ allowed_amount: {param: allowed_amount}
+ note: {param: note}
+ expected_count: 1
+ count_new_only: true
diff --git a/packages/flow/environments/openenv/win-claims-desk/env.yaml b/packages/flow/environments/openenv/win-claims-desk/env.yaml
new file mode 100644
index 0000000000..fd054ea0b5
--- /dev/null
+++ b/packages/flow/environments/openenv/win-claims-desk/env.yaml
@@ -0,0 +1,37 @@
+schema_version: openadapt.rl-env-manifest/v1
+name: openadapt-win-claims-desk
+title: Claims Desk (WPF) on Windows, UI Automation surface
+description: >
+ Adjudicate the right claim in a WPF app whose save can be dropped, posted to a look-alike claim, duplicated, truncated or written with a stale amount while the screen still says "saved". The reward is verify-run's verdict on the app's SQLite database.
+ The agent sees the screen and the window's UI Automation elements.
+licence:
+ environment: MIT
+ app: MIT
+ app_source: bundled
+ notes: >
+ Claims Desk is OpenAdapt's own app (environments/openenv/_windows/apps). All
+ data is fictional. Windows is not part of this package: the environment
+ runs on a Windows machine the user supplies (their own image, or an Azure
+ or AWS Windows template).
+checks:
+ - "One new decision on the task's claim with exactly the task's status, allowed amount and note, read from the app's database outside the agent's session."
+ - "Exactly one such decision: a duplicate, a decision on the look-alike claim, a truncated note or a stale amount does not count."
+ - "On a task whose save cannot land, the agent reports failure after asking the app to save."
+app:
+ kind: desktop
+ surface: windows_uia
+ desktop:
+ guest_app: claims_desk
+ window_title: Claims Desk
+ ready_automation_id: searchBox
+ guest_image: buyer-supplied
+ rdp:
+ width: 1280
+ height: 800
+ color_depth: 32
+ transport: xfreerdp
+agent:
+ max_steps: 40
+ settle_s: 0.6
+verify: verify.yaml
+tasks: tasks/public.jsonl
diff --git a/packages/flow/environments/openenv/win-claims-desk/openenv.yaml b/packages/flow/environments/openenv/win-claims-desk/openenv.yaml
new file mode 100644
index 0000000000..12262ea033
--- /dev/null
+++ b/packages/flow/environments/openenv/win-claims-desk/openenv.yaml
@@ -0,0 +1,32 @@
+spec_version: 1
+name: openadapt-win-claims-desk
+version: 0.1.0
+type: space
+runtime: fastapi
+app: openadapt_flow.rl_env.desktop:build_app
+port: 8000
+validation:
+ reward:
+ range: [0.0, 1.0]
+ oracle_tolerance: 0.0
+ floor_margin: 0.1
+ resources:
+ cpu: 1.0
+ memory_mb: 2048
+ disk_mb: 2048
+ episode_timeout_s: 300.0
+ network:
+ # The server reaches one Windows guest (RDP/WinRM/agent port); the agent
+ # has no network action.
+ mode: guest-only
+ capabilities:
+ verifier:
+ kind: reward_channel
+ oracle:
+ form: script
+ location: tasks/public.jsonl (each task's solution)
+ task_api: true
+ declared_task_count:
+ public: 24
+ types:
+ tags: [computer-use, windows, ui-automation, effect-verification, insurance, claims]
diff --git a/packages/flow/environments/openenv/win-claims-desk/tasks/MANIFEST.json b/packages/flow/environments/openenv/win-claims-desk/tasks/MANIFEST.json
new file mode 100644
index 0000000000..081cffd0cd
--- /dev/null
+++ b/packages/flow/environments/openenv/win-claims-desk/tasks/MANIFEST.json
@@ -0,0 +1,19 @@
+{
+ "app": "claims_desk",
+ "generator": "environments/openenv/_windows/make_tasks.py",
+ "heldout": {
+ "feasible": 12,
+ "file": "claims_desk.heldout.jsonl",
+ "location": "private",
+ "sha256": "00f816fd4735be2905b2b9c545b41035a14a22bfc85fa9e01a92ccdb286ff297",
+ "tasks": 24
+ },
+ "public": {
+ "feasible": 12,
+ "file": "public.jsonl",
+ "sha256": "4f8d3ba8aaf9f260bb51024c33b5cb970f3c0e8a1178487bcf3f10d5c35534a1",
+ "tasks": 24
+ },
+ "public_seed": 20261103,
+ "schema": "openadapt.rl-env-task-manifest/v1"
+}
diff --git a/packages/flow/environments/openenv/win-claims-desk/tasks/public.jsonl b/packages/flow/environments/openenv/win-claims-desk/tasks/public.jsonl
new file mode 100644
index 0000000000..ade7e2f584
--- /dev/null
+++ b/packages/flow/environments/openenv/win-claims-desk/tasks/public.jsonl
@@ -0,0 +1,24 @@
+{"fault": "wrong_row", "feasible": false, "id": "winclaims-47bc79d5c4", "instruction": "In Claims Desk, open claim CLM-2026-04426 (Samuel Reyes, member MEM-91050, service 2026-08-03, billed 515.00) and record one decision: Denied, allowed amount 0.00 (typed exactly as written), note \"Service before coverage start date [p00]\". Other claims have similar numbers and members. The claim shows how many decisions are on file and the last one. Finish with done: claim success only if that claim now holds exactly this decision once, otherwise claim failure.", "params": {"allowed_amount": "0.00", "claim_no": "CLM-2026-04426", "note": "Service before coverage start date [p00]", "status": "Denied"}, "setup": {"variant": "none"}, "solution": [{"kind": "click", "target": "searchBox"}, {"kind": "type", "text": "CLM-2026-04426"}, {"kind": "press", "text": "enter"}, {"kind": "wait", "seconds": 2}, {"at": [0.05, 0.196], "kind": "click", "target": "claimsGrid"}, {"kind": "wait", "seconds": 2}, {"kind": "click", "target": "statusDenied"}, {"kind": "click", "target": "amountBox"}, {"kind": "type", "text": "0.00"}, {"kind": "click", "target": "noteBox"}, {"kind": "type", "text": "Service before coverage start date [p00]"}, {"kind": "click", "target": "saveButton"}, {"kind": "wait", "seconds": 3}, {"claim": "failure", "kind": "done"}], "split": "public", "tags": ["lookalike:CLM-2026-04462"]}
+{"fault": "ok", "feasible": true, "id": "winclaims-0b6da80ac6", "instruction": "In Claims Desk, open claim CLM-2026-03109 (Leila Haddad, member MEM-80233, service 2026-10-05, billed 2750.00) and record one decision: Pended, allowed amount 0.00 (typed exactly as written), note \"Pend for medical review of necessity [p01]\". Other claims have similar numbers and members. The claim shows how many decisions are on file and the last one. Finish with done: claim success only if that claim now holds exactly this decision once, otherwise claim failure.", "params": {"allowed_amount": "0.00", "claim_no": "CLM-2026-03109", "note": "Pend for medical review of necessity [p01]", "status": "Pended"}, "setup": {"variant": "reorder"}, "solution": [{"kind": "click", "target": "searchBox"}, {"kind": "type", "text": "CLM-2026-03109"}, {"kind": "press", "text": "enter"}, {"kind": "wait", "seconds": 2}, {"at": [0.05, 0.196], "kind": "click", "target": "claimsGrid"}, {"kind": "wait", "seconds": 2}, {"kind": "click", "target": "statusPended"}, {"kind": "click", "target": "amountBox"}, {"kind": "type", "text": "0.00"}, {"kind": "click", "target": "noteBox"}, {"kind": "type", "text": "Pend for medical review of necessity [p01]"}, {"kind": "click", "target": "saveButton"}, {"kind": "wait", "seconds": 3}, {"claim": "success", "kind": "done"}], "split": "public", "tags": ["lookalike:CLM-2026-03190", "variant:reorder"]}
+{"fault": "ok", "feasible": true, "id": "winclaims-1628cd5fe1", "instruction": "In Claims Desk, open claim CLM-2026-00417 (Ana Petrovic, member MEM-55120, service 2026-10-02, billed 412.50) and record one decision: Approved, allowed amount 375.82 (typed exactly as written), note \"Approved after appeal, see attached letter [p02]\". Other claims have similar numbers and members. The claim shows how many decisions are on file and the last one. Finish with done: claim success only if that claim now holds exactly this decision once, otherwise claim failure.", "params": {"allowed_amount": "375.82", "claim_no": "CLM-2026-00417", "note": "Approved after appeal, see attached letter [p02]", "status": "Approved"}, "setup": {"ui": {"banner": "Batch posting complete: all decisions saved"}, "variant": "none"}, "solution": [{"kind": "click", "target": "searchBox"}, {"kind": "type", "text": "CLM-2026-00417"}, {"kind": "press", "text": "enter"}, {"kind": "wait", "seconds": 2}, {"at": [0.05, 0.196], "kind": "click", "target": "claimsGrid"}, {"kind": "wait", "seconds": 2}, {"kind": "click", "target": "statusApproved"}, {"kind": "click", "target": "amountBox"}, {"kind": "type", "text": "375.82"}, {"kind": "click", "target": "noteBox"}, {"kind": "type", "text": "Approved after appeal, see attached letter [p02]"}, {"kind": "click", "target": "saveButton"}, {"kind": "wait", "seconds": 3}, {"claim": "success", "kind": "done"}], "split": "public", "tags": ["lookalike:CLM-2026-00471", "misleading_banner"]}
+{"fault": "drop_first", "feasible": true, "id": "winclaims-43e35c19cb", "instruction": "In Claims Desk, open claim CLM-2026-04426 (Samuel Reyes, member MEM-91050, service 2026-08-03, billed 515.00) and record one decision: Approved, allowed amount 300.36 (typed exactly as written), note \"Out of network, member responsibility applies [p03]\". Other claims have similar numbers and members. The claim shows how many decisions are on file and the last one. Finish with done: claim success only if that claim now holds exactly this decision once, otherwise claim failure.", "params": {"allowed_amount": "300.36", "claim_no": "CLM-2026-04426", "note": "Out of network, member responsibility applies [p03]", "status": "Approved"}, "setup": {"variant": "none"}, "solution": [{"kind": "click", "target": "searchBox"}, {"kind": "type", "text": "CLM-2026-04426"}, {"kind": "press", "text": "enter"}, {"kind": "wait", "seconds": 2}, {"at": [0.05, 0.196], "kind": "click", "target": "claimsGrid"}, {"kind": "wait", "seconds": 2}, {"kind": "click", "target": "statusApproved"}, {"kind": "click", "target": "amountBox"}, {"kind": "type", "text": "300.36"}, {"kind": "click", "target": "noteBox"}, {"kind": "type", "text": "Out of network, member responsibility applies [p03]"}, {"kind": "click", "target": "saveButton"}, {"kind": "wait", "seconds": 3}, {"at": [0.05, 0.196], "kind": "click", "target": "claimsGrid"}, {"kind": "wait", "seconds": 2}, {"kind": "click", "target": "statusApproved"}, {"kind": "click", "target": "amountBox"}, {"kind": "type", "text": "300.36"}, {"kind": "click", "target": "noteBox"}, {"kind": "type", "text": "Out of network, member responsibility applies [p03]"}, {"kind": "click", "target": "saveButton"}, {"kind": "wait", "seconds": 3}, {"claim": "success", "kind": "done"}], "split": "public", "tags": ["lookalike:CLM-2026-04462"]}
+{"fault": "ok", "feasible": true, "id": "winclaims-f7883acff6", "instruction": "In Claims Desk, open claim CLM-2026-00471 (Ana Petrovic, member MEM-55102, service 2026-10-20, billed 421.50) and record one decision: Denied, allowed amount 0.00 (typed exactly as written), note \"Duplicate of an earlier claim [p04]\". Other claims have similar numbers and members. The claim shows how many decisions are on file and the last one. Finish with done: claim success only if that claim now holds exactly this decision once, otherwise claim failure.", "params": {"allowed_amount": "0.00", "claim_no": "CLM-2026-00471", "note": "Duplicate of an earlier claim [p04]", "status": "Denied"}, "setup": {"variant": "reorder"}, "solution": [{"kind": "click", "target": "searchBox"}, {"kind": "type", "text": "CLM-2026-00471"}, {"kind": "press", "text": "enter"}, {"kind": "wait", "seconds": 2}, {"at": [0.05, 0.196], "kind": "click", "target": "claimsGrid"}, {"kind": "wait", "seconds": 2}, {"kind": "click", "target": "statusDenied"}, {"kind": "click", "target": "amountBox"}, {"kind": "type", "text": "0.00"}, {"kind": "click", "target": "noteBox"}, {"kind": "type", "text": "Duplicate of an earlier claim [p04]"}, {"kind": "click", "target": "saveButton"}, {"kind": "wait", "seconds": 3}, {"claim": "success", "kind": "done"}], "split": "public", "tags": ["lookalike:CLM-2026-00417", "variant:reorder"]}
+{"fault": "ok", "feasible": true, "id": "winclaims-86281e6614", "instruction": "In Claims Desk, open claim CLM-2026-01388 (Daniel Osei, member MEM-60871, service 2026-09-28, billed 1290.00) and record one decision: Approved, allowed amount 659.07 (typed exactly as written), note \"Coding corrected to the lower level visit [p05]\". Other claims have similar numbers and members. The claim shows how many decisions are on file and the last one. Finish with done: claim success only if that claim now holds exactly this decision once, otherwise claim failure.", "params": {"allowed_amount": "659.07", "claim_no": "CLM-2026-01388", "note": "Coding corrected to the lower level visit [p05]", "status": "Approved"}, "setup": {"variant": "none"}, "solution": [{"kind": "click", "target": "searchBox"}, {"kind": "type", "text": "CLM-2026-01388"}, {"kind": "press", "text": "enter"}, {"kind": "wait", "seconds": 2}, {"at": [0.05, 0.196], "kind": "click", "target": "claimsGrid"}, {"kind": "wait", "seconds": 2}, {"kind": "click", "target": "statusApproved"}, {"kind": "click", "target": "amountBox"}, {"kind": "type", "text": "659.07"}, {"kind": "click", "target": "noteBox"}, {"kind": "type", "text": "Coding corrected to the lower level visit [p05]"}, {"kind": "click", "target": "saveButton"}, {"kind": "wait", "seconds": 3}, {"claim": "success", "kind": "done"}], "split": "public", "tags": ["lookalike:CLM-2026-01838"]}
+{"fault": "drop", "feasible": false, "id": "winclaims-a70198c8ef", "instruction": "In Claims Desk, open claim CLM-2026-03190 (Layla Haddad, member MEM-80323, service 2026-10-15, billed 2570.00) and record one decision: Denied, allowed amount 0.00 (typed exactly as written), note \"Service before coverage start date [p06]\". Other claims have similar numbers and members. The claim shows how many decisions are on file and the last one. Finish with done: claim success only if that claim now holds exactly this decision once, otherwise claim failure.", "params": {"allowed_amount": "0.00", "claim_no": "CLM-2026-03190", "note": "Service before coverage start date [p06]", "status": "Denied"}, "setup": {"variant": "none"}, "solution": [{"kind": "click", "target": "searchBox"}, {"kind": "type", "text": "CLM-2026-03190"}, {"kind": "press", "text": "enter"}, {"kind": "wait", "seconds": 2}, {"at": [0.05, 0.196], "kind": "click", "target": "claimsGrid"}, {"kind": "wait", "seconds": 2}, {"kind": "click", "target": "statusDenied"}, {"kind": "click", "target": "amountBox"}, {"kind": "type", "text": "0.00"}, {"kind": "click", "target": "noteBox"}, {"kind": "type", "text": "Service before coverage start date [p06]"}, {"kind": "click", "target": "saveButton"}, {"kind": "wait", "seconds": 3}, {"claim": "failure", "kind": "done"}], "split": "public", "tags": ["lookalike:CLM-2026-03109"]}
+{"fault": "truncate", "feasible": false, "id": "winclaims-5b0c5a32ac", "instruction": "In Claims Desk, open claim CLM-2026-04426 (Samuel Reyes, member MEM-91050, service 2026-08-03, billed 515.00) and record one decision: Pended, allowed amount 0.00 (typed exactly as written), note \"Pend for medical review of necessity [p07]\". Other claims have similar numbers and members. The claim shows how many decisions are on file and the last one. Finish with done: claim success only if that claim now holds exactly this decision once, otherwise claim failure.", "params": {"allowed_amount": "0.00", "claim_no": "CLM-2026-04426", "note": "Pend for medical review of necessity [p07]", "status": "Pended"}, "setup": {"variant": "none"}, "solution": [{"kind": "click", "target": "searchBox"}, {"kind": "type", "text": "CLM-2026-04426"}, {"kind": "press", "text": "enter"}, {"kind": "wait", "seconds": 2}, {"at": [0.05, 0.196], "kind": "click", "target": "claimsGrid"}, {"kind": "wait", "seconds": 2}, {"kind": "click", "target": "statusPended"}, {"kind": "click", "target": "amountBox"}, {"kind": "type", "text": "0.00"}, {"kind": "click", "target": "noteBox"}, {"kind": "type", "text": "Pend for medical review of necessity [p07]"}, {"kind": "click", "target": "saveButton"}, {"kind": "wait", "seconds": 3}, {"claim": "failure", "kind": "done"}], "split": "public", "tags": ["lookalike:CLM-2026-04462"]}
+{"fault": "ok", "feasible": true, "id": "winclaims-ef30c53031", "instruction": "In Claims Desk, open claim CLM-2026-03190 (Layla Haddad, member MEM-80323, service 2026-10-15, billed 2570.00) and record one decision: Approved, allowed amount 2567.91 (typed exactly as written), note \"Approved after appeal, see attached letter [p08]\". Other claims have similar numbers and members. The claim shows how many decisions are on file and the last one. Finish with done: claim success only if that claim now holds exactly this decision once, otherwise claim failure.", "params": {"allowed_amount": "2567.91", "claim_no": "CLM-2026-03190", "note": "Approved after appeal, see attached letter [p08]", "status": "Approved"}, "setup": {"variant": "none"}, "solution": [{"kind": "click", "target": "searchBox"}, {"kind": "type", "text": "CLM-2026-03190"}, {"kind": "press", "text": "enter"}, {"kind": "wait", "seconds": 2}, {"at": [0.05, 0.196], "kind": "click", "target": "claimsGrid"}, {"kind": "wait", "seconds": 2}, {"kind": "click", "target": "statusApproved"}, {"kind": "click", "target": "amountBox"}, {"kind": "type", "text": "2567.91"}, {"kind": "click", "target": "noteBox"}, {"kind": "type", "text": "Approved after appeal, see attached letter [p08]"}, {"kind": "click", "target": "saveButton"}, {"kind": "wait", "seconds": 3}, {"claim": "success", "kind": "done"}], "split": "public", "tags": ["lookalike:CLM-2026-03109"]}
+{"fault": "ok", "feasible": true, "id": "winclaims-a64ea5d937", "instruction": "In Claims Desk, open claim CLM-2026-03190 (Layla Haddad, member MEM-80323, service 2026-10-15, billed 2570.00) and record one decision: Approved, allowed amount 1488.75 (typed exactly as written), note \"Out of network, member responsibility applies [p09]\". Other claims have similar numbers and members. The claim shows how many decisions are on file and the last one. Finish with done: claim success only if that claim now holds exactly this decision once, otherwise claim failure.", "params": {"allowed_amount": "1488.75", "claim_no": "CLM-2026-03190", "note": "Out of network, member responsibility applies [p09]", "status": "Approved"}, "setup": {"ui": {"banner": "Claim CLM-2026-03190 was already approved by auto-adjudication"}, "variant": "none"}, "solution": [{"kind": "click", "target": "searchBox"}, {"kind": "type", "text": "CLM-2026-03190"}, {"kind": "press", "text": "enter"}, {"kind": "wait", "seconds": 2}, {"at": [0.05, 0.196], "kind": "click", "target": "claimsGrid"}, {"kind": "wait", "seconds": 2}, {"kind": "click", "target": "statusApproved"}, {"kind": "click", "target": "amountBox"}, {"kind": "type", "text": "1488.75"}, {"kind": "click", "target": "noteBox"}, {"kind": "type", "text": "Out of network, member responsibility applies [p09]"}, {"kind": "click", "target": "saveButton"}, {"kind": "wait", "seconds": 3}, {"claim": "success", "kind": "done"}], "split": "public", "tags": ["lookalike:CLM-2026-03109", "misleading_banner"]}
+{"fault": "wrong_row", "feasible": false, "id": "winclaims-a2a3b6542e", "instruction": "In Claims Desk, open claim CLM-2026-03109 (Leila Haddad, member MEM-80233, service 2026-10-05, billed 2750.00) and record one decision: Denied, allowed amount 0.00 (typed exactly as written), note \"Duplicate of an earlier claim [p10]\". Other claims have similar numbers and members. The claim shows how many decisions are on file and the last one. Finish with done: claim success only if that claim now holds exactly this decision once, otherwise claim failure.", "params": {"allowed_amount": "0.00", "claim_no": "CLM-2026-03109", "note": "Duplicate of an earlier claim [p10]", "status": "Denied"}, "setup": {"variant": "none"}, "solution": [{"kind": "click", "target": "searchBox"}, {"kind": "type", "text": "CLM-2026-03109"}, {"kind": "press", "text": "enter"}, {"kind": "wait", "seconds": 2}, {"at": [0.05, 0.196], "kind": "click", "target": "claimsGrid"}, {"kind": "wait", "seconds": 2}, {"kind": "click", "target": "statusDenied"}, {"kind": "click", "target": "amountBox"}, {"kind": "type", "text": "0.00"}, {"kind": "click", "target": "noteBox"}, {"kind": "type", "text": "Duplicate of an earlier claim [p10]"}, {"kind": "click", "target": "saveButton"}, {"kind": "wait", "seconds": 3}, {"claim": "failure", "kind": "done"}], "split": "public", "tags": ["lookalike:CLM-2026-03190"]}
+{"fault": "ok", "feasible": true, "id": "winclaims-58a5a7888a", "instruction": "In Claims Desk, open claim CLM-2026-00417 (Ana Petrovic, member MEM-55120, service 2026-10-02, billed 412.50) and record one decision: Approved, allowed amount 294.42 (typed exactly as written), note \"Coding corrected to the lower level visit [p11]\". Other claims have similar numbers and members. The claim shows how many decisions are on file and the last one. Finish with done: claim success only if that claim now holds exactly this decision once, otherwise claim failure.", "params": {"allowed_amount": "294.42", "claim_no": "CLM-2026-00417", "note": "Coding corrected to the lower level visit [p11]", "status": "Approved"}, "setup": {"variant": "none"}, "solution": [{"kind": "click", "target": "searchBox"}, {"kind": "type", "text": "CLM-2026-00417"}, {"kind": "press", "text": "enter"}, {"kind": "wait", "seconds": 2}, {"at": [0.05, 0.196], "kind": "click", "target": "claimsGrid"}, {"kind": "wait", "seconds": 2}, {"kind": "click", "target": "statusApproved"}, {"kind": "click", "target": "amountBox"}, {"kind": "type", "text": "294.42"}, {"kind": "click", "target": "noteBox"}, {"kind": "type", "text": "Coding corrected to the lower level visit [p11]"}, {"kind": "click", "target": "saveButton"}, {"kind": "wait", "seconds": 3}, {"claim": "success", "kind": "done"}], "split": "public", "tags": ["lookalike:CLM-2026-00471"]}
+{"fault": "stale", "feasible": false, "id": "winclaims-f64c53f6b4", "instruction": "In Claims Desk, open claim CLM-2026-06027 (Marek Novak, member MEM-23116, service 2026-10-09, billed 980.25) and record one decision: Denied, allowed amount 0.00 (typed exactly as written), note \"Service before coverage start date [p12]\". Other claims have similar numbers and members. The claim shows how many decisions are on file and the last one. Finish with done: claim success only if that claim now holds exactly this decision once, otherwise claim failure.", "params": {"allowed_amount": "0.00", "claim_no": "CLM-2026-06027", "note": "Service before coverage start date [p12]", "status": "Denied"}, "setup": {"variant": "none"}, "solution": [{"kind": "click", "target": "searchBox"}, {"kind": "type", "text": "CLM-2026-06027"}, {"kind": "press", "text": "enter"}, {"kind": "wait", "seconds": 2}, {"at": [0.05, 0.196], "kind": "click", "target": "claimsGrid"}, {"kind": "wait", "seconds": 2}, {"kind": "click", "target": "statusDenied"}, {"kind": "click", "target": "amountBox"}, {"kind": "type", "text": "0.00"}, {"kind": "click", "target": "noteBox"}, {"kind": "type", "text": "Service before coverage start date [p12]"}, {"kind": "click", "target": "saveButton"}, {"kind": "wait", "seconds": 3}, {"claim": "failure", "kind": "done"}], "split": "public", "tags": ["lookalike:CLM-2026-06072"]}
+{"fault": "drop", "feasible": false, "id": "winclaims-7e1ed7aa45", "instruction": "In Claims Desk, open claim CLM-2026-01838 (Daniela Osei, member MEM-60817, service 2026-09-28, billed 1209.00) and record one decision: Pended, allowed amount 0.00 (typed exactly as written), note \"Pend for medical review of necessity [p13]\". Other claims have similar numbers and members. The claim shows how many decisions are on file and the last one. Finish with done: claim success only if that claim now holds exactly this decision once, otherwise claim failure.", "params": {"allowed_amount": "0.00", "claim_no": "CLM-2026-01838", "note": "Pend for medical review of necessity [p13]", "status": "Pended"}, "setup": {"variant": "none"}, "solution": [{"kind": "click", "target": "searchBox"}, {"kind": "type", "text": "CLM-2026-01838"}, {"kind": "press", "text": "enter"}, {"kind": "wait", "seconds": 2}, {"at": [0.05, 0.196], "kind": "click", "target": "claimsGrid"}, {"kind": "wait", "seconds": 2}, {"kind": "click", "target": "statusPended"}, {"kind": "click", "target": "amountBox"}, {"kind": "type", "text": "0.00"}, {"kind": "click", "target": "noteBox"}, {"kind": "type", "text": "Pend for medical review of necessity [p13]"}, {"kind": "click", "target": "saveButton"}, {"kind": "wait", "seconds": 3}, {"claim": "failure", "kind": "done"}], "split": "public", "tags": ["lookalike:CLM-2026-01388"]}
+{"fault": "wrong_row", "feasible": false, "id": "winclaims-4b213973e5", "instruction": "In Claims Desk, open claim CLM-2026-03190 (Layla Haddad, member MEM-80323, service 2026-10-15, billed 2570.00) and record one decision: Approved, allowed amount 2569.50 (typed exactly as written), note \"Approved after appeal, see attached letter [p14]\". Other claims have similar numbers and members. The claim shows how many decisions are on file and the last one. Finish with done: claim success only if that claim now holds exactly this decision once, otherwise claim failure.", "params": {"allowed_amount": "2569.50", "claim_no": "CLM-2026-03190", "note": "Approved after appeal, see attached letter [p14]", "status": "Approved"}, "setup": {"ui": {"banner": "Batch posting complete: all decisions saved"}, "variant": "none"}, "solution": [{"kind": "click", "target": "searchBox"}, {"kind": "type", "text": "CLM-2026-03190"}, {"kind": "press", "text": "enter"}, {"kind": "wait", "seconds": 2}, {"at": [0.05, 0.196], "kind": "click", "target": "claimsGrid"}, {"kind": "wait", "seconds": 2}, {"kind": "click", "target": "statusApproved"}, {"kind": "click", "target": "amountBox"}, {"kind": "type", "text": "2569.50"}, {"kind": "click", "target": "noteBox"}, {"kind": "type", "text": "Approved after appeal, see attached letter [p14]"}, {"kind": "click", "target": "saveButton"}, {"kind": "wait", "seconds": 3}, {"claim": "failure", "kind": "done"}], "split": "public", "tags": ["lookalike:CLM-2026-03109", "misleading_banner"]}
+{"fault": "drop_first", "feasible": true, "id": "winclaims-8821889da6", "instruction": "In Claims Desk, open claim CLM-2026-02245 (Hiro Tanaka, member MEM-71434, service 2026-10-11, billed 68.40) and record one decision: Approved, allowed amount 46.83 (typed exactly as written), note \"Out of network, member responsibility applies [p15]\". Other claims have similar numbers and members. The claim shows how many decisions are on file and the last one. Finish with done: claim success only if that claim now holds exactly this decision once, otherwise claim failure.", "params": {"allowed_amount": "46.83", "claim_no": "CLM-2026-02245", "note": "Out of network, member responsibility applies [p15]", "status": "Approved"}, "setup": {"variant": "none"}, "solution": [{"kind": "click", "target": "searchBox"}, {"kind": "type", "text": "CLM-2026-02245"}, {"kind": "press", "text": "enter"}, {"kind": "wait", "seconds": 2}, {"at": [0.05, 0.196], "kind": "click", "target": "claimsGrid"}, {"kind": "wait", "seconds": 2}, {"kind": "click", "target": "statusApproved"}, {"kind": "click", "target": "amountBox"}, {"kind": "type", "text": "46.83"}, {"kind": "click", "target": "noteBox"}, {"kind": "type", "text": "Out of network, member responsibility applies [p15]"}, {"kind": "click", "target": "saveButton"}, {"kind": "wait", "seconds": 3}, {"at": [0.05, 0.196], "kind": "click", "target": "claimsGrid"}, {"kind": "wait", "seconds": 2}, {"kind": "click", "target": "statusApproved"}, {"kind": "click", "target": "amountBox"}, {"kind": "type", "text": "46.83"}, {"kind": "click", "target": "noteBox"}, {"kind": "type", "text": "Out of network, member responsibility applies [p15]"}, {"kind": "click", "target": "saveButton"}, {"kind": "wait", "seconds": 3}, {"claim": "success", "kind": "done"}], "split": "public", "tags": ["lookalike:CLM-2026-02254"]}
+{"fault": "drop_first", "feasible": true, "id": "winclaims-232feac081", "instruction": "In Claims Desk, open claim CLM-2026-06072 (Marek Nowak, member MEM-23161, service 2026-10-09, billed 908.25) and record one decision: Denied, allowed amount 0.00 (typed exactly as written), note \"Duplicate of an earlier claim [p16]\". Other claims have similar numbers and members. The claim shows how many decisions are on file and the last one. Finish with done: claim success only if that claim now holds exactly this decision once, otherwise claim failure.", "params": {"allowed_amount": "0.00", "claim_no": "CLM-2026-06072", "note": "Duplicate of an earlier claim [p16]", "status": "Denied"}, "setup": {"variant": "none"}, "solution": [{"kind": "click", "target": "searchBox"}, {"kind": "type", "text": "CLM-2026-06072"}, {"kind": "press", "text": "enter"}, {"kind": "wait", "seconds": 2}, {"at": [0.05, 0.196], "kind": "click", "target": "claimsGrid"}, {"kind": "wait", "seconds": 2}, {"kind": "click", "target": "statusDenied"}, {"kind": "click", "target": "amountBox"}, {"kind": "type", "text": "0.00"}, {"kind": "click", "target": "noteBox"}, {"kind": "type", "text": "Duplicate of an earlier claim [p16]"}, {"kind": "click", "target": "saveButton"}, {"kind": "wait", "seconds": 3}, {"at": [0.05, 0.196], "kind": "click", "target": "claimsGrid"}, {"kind": "wait", "seconds": 2}, {"kind": "click", "target": "statusDenied"}, {"kind": "click", "target": "amountBox"}, {"kind": "type", "text": "0.00"}, {"kind": "click", "target": "noteBox"}, {"kind": "type", "text": "Duplicate of an earlier claim [p16]"}, {"kind": "click", "target": "saveButton"}, {"kind": "wait", "seconds": 3}, {"claim": "success", "kind": "done"}], "split": "public", "tags": ["lookalike:CLM-2026-06027"]}
+{"fault": "ok", "feasible": true, "id": "winclaims-2c8d585a77", "instruction": "In Claims Desk, open claim CLM-2026-01388 (Daniel Osei, member MEM-60871, service 2026-09-28, billed 1290.00) and record one decision: Approved, allowed amount 1207.03 (typed exactly as written), note \"Coding corrected to the lower level visit [p17]\". Other claims have similar numbers and members. The claim shows how many decisions are on file and the last one. Finish with done: claim success only if that claim now holds exactly this decision once, otherwise claim failure.", "params": {"allowed_amount": "1207.03", "claim_no": "CLM-2026-01388", "note": "Coding corrected to the lower level visit [p17]", "status": "Approved"}, "setup": {"variant": "reorder"}, "solution": [{"kind": "click", "target": "searchBox"}, {"kind": "type", "text": "CLM-2026-01388"}, {"kind": "press", "text": "enter"}, {"kind": "wait", "seconds": 2}, {"at": [0.05, 0.196], "kind": "click", "target": "claimsGrid"}, {"kind": "wait", "seconds": 2}, {"kind": "click", "target": "statusApproved"}, {"kind": "click", "target": "amountBox"}, {"kind": "type", "text": "1207.03"}, {"kind": "click", "target": "noteBox"}, {"kind": "type", "text": "Coding corrected to the lower level visit [p17]"}, {"kind": "click", "target": "saveButton"}, {"kind": "wait", "seconds": 3}, {"claim": "success", "kind": "done"}], "split": "public", "tags": ["lookalike:CLM-2026-01838", "variant:reorder"]}
+{"fault": "ok", "feasible": true, "id": "winclaims-d95991d94a", "instruction": "In Claims Desk, open claim CLM-2026-01388 (Daniel Osei, member MEM-60871, service 2026-09-28, billed 1290.00) and record one decision: Denied, allowed amount 0.00 (typed exactly as written), note \"Service before coverage start date [p18]\". Other claims have similar numbers and members. The claim shows how many decisions are on file and the last one. Finish with done: claim success only if that claim now holds exactly this decision once, otherwise claim failure.", "params": {"allowed_amount": "0.00", "claim_no": "CLM-2026-01388", "note": "Service before coverage start date [p18]", "status": "Denied"}, "setup": {"ui": {"banner": "Decision saved for CLM-2026-01838"}, "variant": "none"}, "solution": [{"kind": "click", "target": "searchBox"}, {"kind": "type", "text": "CLM-2026-01388"}, {"kind": "press", "text": "enter"}, {"kind": "wait", "seconds": 2}, {"at": [0.05, 0.196], "kind": "click", "target": "claimsGrid"}, {"kind": "wait", "seconds": 2}, {"kind": "click", "target": "statusDenied"}, {"kind": "click", "target": "amountBox"}, {"kind": "type", "text": "0.00"}, {"kind": "click", "target": "noteBox"}, {"kind": "type", "text": "Service before coverage start date [p18]"}, {"kind": "click", "target": "saveButton"}, {"kind": "wait", "seconds": 3}, {"claim": "success", "kind": "done"}], "split": "public", "tags": ["lookalike:CLM-2026-01838", "misleading_banner"]}
+{"fault": "stale", "feasible": false, "id": "winclaims-6ad69b812c", "instruction": "In Claims Desk, open claim CLM-2026-01388 (Daniel Osei, member MEM-60871, service 2026-09-28, billed 1290.00) and record one decision: Pended, allowed amount 0.00 (typed exactly as written), note \"Pend for medical review of necessity [p19]\". Other claims have similar numbers and members. The claim shows how many decisions are on file and the last one. Finish with done: claim success only if that claim now holds exactly this decision once, otherwise claim failure.", "params": {"allowed_amount": "0.00", "claim_no": "CLM-2026-01388", "note": "Pend for medical review of necessity [p19]", "status": "Pended"}, "setup": {"variant": "none"}, "solution": [{"kind": "click", "target": "searchBox"}, {"kind": "type", "text": "CLM-2026-01388"}, {"kind": "press", "text": "enter"}, {"kind": "wait", "seconds": 2}, {"at": [0.05, 0.196], "kind": "click", "target": "claimsGrid"}, {"kind": "wait", "seconds": 2}, {"kind": "click", "target": "statusPended"}, {"kind": "click", "target": "amountBox"}, {"kind": "type", "text": "0.00"}, {"kind": "click", "target": "noteBox"}, {"kind": "type", "text": "Pend for medical review of necessity [p19]"}, {"kind": "click", "target": "saveButton"}, {"kind": "wait", "seconds": 3}, {"claim": "failure", "kind": "done"}], "split": "public", "tags": ["lookalike:CLM-2026-01838"]}
+{"fault": "truncate", "feasible": false, "id": "winclaims-6d743438e4", "instruction": "In Claims Desk, open claim CLM-2026-03190 (Layla Haddad, member MEM-80323, service 2026-10-15, billed 2570.00) and record one decision: Approved, allowed amount 2316.90 (typed exactly as written), note \"Approved after appeal, see attached letter [p20]\". Other claims have similar numbers and members. The claim shows how many decisions are on file and the last one. Finish with done: claim success only if that claim now holds exactly this decision once, otherwise claim failure.", "params": {"allowed_amount": "2316.90", "claim_no": "CLM-2026-03190", "note": "Approved after appeal, see attached letter [p20]", "status": "Approved"}, "setup": {"ui": {"banner": "Batch posting complete: all decisions saved"}, "variant": "none"}, "solution": [{"kind": "click", "target": "searchBox"}, {"kind": "type", "text": "CLM-2026-03190"}, {"kind": "press", "text": "enter"}, {"kind": "wait", "seconds": 2}, {"at": [0.05, 0.196], "kind": "click", "target": "claimsGrid"}, {"kind": "wait", "seconds": 2}, {"kind": "click", "target": "statusApproved"}, {"kind": "click", "target": "amountBox"}, {"kind": "type", "text": "2316.90"}, {"kind": "click", "target": "noteBox"}, {"kind": "type", "text": "Approved after appeal, see attached letter [p20]"}, {"kind": "click", "target": "saveButton"}, {"kind": "wait", "seconds": 3}, {"claim": "failure", "kind": "done"}], "split": "public", "tags": ["lookalike:CLM-2026-03109", "misleading_banner"]}
+{"fault": "duplicate", "feasible": false, "id": "winclaims-5095144dcd", "instruction": "In Claims Desk, open claim CLM-2026-01838 (Daniela Osei, member MEM-60817, service 2026-09-28, billed 1209.00) and record one decision: Approved, allowed amount 854.19 (typed exactly as written), note \"Out of network, member responsibility applies [p21]\". Other claims have similar numbers and members. The claim shows how many decisions are on file and the last one. Finish with done: claim success only if that claim now holds exactly this decision once, otherwise claim failure.", "params": {"allowed_amount": "854.19", "claim_no": "CLM-2026-01838", "note": "Out of network, member responsibility applies [p21]", "status": "Approved"}, "setup": {"variant": "none"}, "solution": [{"kind": "click", "target": "searchBox"}, {"kind": "type", "text": "CLM-2026-01838"}, {"kind": "press", "text": "enter"}, {"kind": "wait", "seconds": 2}, {"at": [0.05, 0.196], "kind": "click", "target": "claimsGrid"}, {"kind": "wait", "seconds": 2}, {"kind": "click", "target": "statusApproved"}, {"kind": "click", "target": "amountBox"}, {"kind": "type", "text": "854.19"}, {"kind": "click", "target": "noteBox"}, {"kind": "type", "text": "Out of network, member responsibility applies [p21]"}, {"kind": "click", "target": "saveButton"}, {"kind": "wait", "seconds": 3}, {"claim": "failure", "kind": "done"}], "split": "public", "tags": ["lookalike:CLM-2026-01388"]}
+{"fault": "duplicate", "feasible": false, "id": "winclaims-05a2a4983b", "instruction": "In Claims Desk, open claim CLM-2026-04426 (Samuel Reyes, member MEM-91050, service 2026-08-03, billed 515.00) and record one decision: Denied, allowed amount 0.00 (typed exactly as written), note \"Duplicate of an earlier claim [p22]\". Other claims have similar numbers and members. The claim shows how many decisions are on file and the last one. Finish with done: claim success only if that claim now holds exactly this decision once, otherwise claim failure.", "params": {"allowed_amount": "0.00", "claim_no": "CLM-2026-04426", "note": "Duplicate of an earlier claim [p22]", "status": "Denied"}, "setup": {"ui": {"banner": "Batch posting complete: all decisions saved"}, "variant": "none"}, "solution": [{"kind": "click", "target": "searchBox"}, {"kind": "type", "text": "CLM-2026-04426"}, {"kind": "press", "text": "enter"}, {"kind": "wait", "seconds": 2}, {"at": [0.05, 0.196], "kind": "click", "target": "claimsGrid"}, {"kind": "wait", "seconds": 2}, {"kind": "click", "target": "statusDenied"}, {"kind": "click", "target": "amountBox"}, {"kind": "type", "text": "0.00"}, {"kind": "click", "target": "noteBox"}, {"kind": "type", "text": "Duplicate of an earlier claim [p22]"}, {"kind": "click", "target": "saveButton"}, {"kind": "wait", "seconds": 3}, {"claim": "failure", "kind": "done"}], "split": "public", "tags": ["lookalike:CLM-2026-04462", "misleading_banner"]}
+{"fault": "drop", "feasible": false, "id": "winclaims-3e05fded8d", "instruction": "In Claims Desk, open claim CLM-2026-06072 (Marek Nowak, member MEM-23161, service 2026-10-09, billed 908.25) and record one decision: Approved, allowed amount 668.03 (typed exactly as written), note \"Coding corrected to the lower level visit [p23]\". Other claims have similar numbers and members. The claim shows how many decisions are on file and the last one. Finish with done: claim success only if that claim now holds exactly this decision once, otherwise claim failure.", "params": {"allowed_amount": "668.03", "claim_no": "CLM-2026-06072", "note": "Coding corrected to the lower level visit [p23]", "status": "Approved"}, "setup": {"ui": {"banner": "Batch posting complete: all decisions saved"}, "variant": "none"}, "solution": [{"kind": "click", "target": "searchBox"}, {"kind": "type", "text": "CLM-2026-06072"}, {"kind": "press", "text": "enter"}, {"kind": "wait", "seconds": 2}, {"at": [0.05, 0.196], "kind": "click", "target": "claimsGrid"}, {"kind": "wait", "seconds": 2}, {"kind": "click", "target": "statusApproved"}, {"kind": "click", "target": "amountBox"}, {"kind": "type", "text": "668.03"}, {"kind": "click", "target": "noteBox"}, {"kind": "type", "text": "Coding corrected to the lower level visit [p23]"}, {"kind": "click", "target": "saveButton"}, {"kind": "wait", "seconds": 3}, {"claim": "failure", "kind": "done"}], "split": "public", "tags": ["lookalike:CLM-2026-06027", "misleading_banner"]}
diff --git a/packages/flow/environments/openenv/win-claims-desk/verify.yaml b/packages/flow/environments/openenv/win-claims-desk/verify.yaml
new file mode 100644
index 0000000000..f8dd817caf
--- /dev/null
+++ b/packages/flow/environments/openenv/win-claims-desk/verify.yaml
@@ -0,0 +1,20 @@
+# Read the adjudication log through the guest's database (pack_db.py dump
+# over WinRM or SSH, served on the environment server's loopback as
+# ${RECORDS_URL}/records). One new decision
+# on the task's claim with the task's status, allowed amount and note,
+# exactly once.
+schema_version: openadapt.verify/v1
+minimum_effect_strength: independent_system_of_record
+verifier:
+ kind: rest
+ base_url: ${RECORDS_URL}
+ records_path: /records
+effects:
+ - kind: record_written
+ match:
+ claim_no: {param: claim_no}
+ status: {param: status}
+ allowed_amount: {param: allowed_amount}
+ note: {param: note}
+ expected_count: 1
+ count_new_only: true
diff --git a/packages/flow/environments/openenv/win-patient-chart-rdp/env.yaml b/packages/flow/environments/openenv/win-patient-chart-rdp/env.yaml
new file mode 100644
index 0000000000..f94b142f50
--- /dev/null
+++ b/packages/flow/environments/openenv/win-patient-chart-rdp/env.yaml
@@ -0,0 +1,40 @@
+schema_version: openadapt.rl-env-manifest/v1
+name: openadapt-win-patient-chart-rdp
+title: Patient Chart (WinForms) over Remote Desktop, pixels only
+description: >
+ Write a chart note on the right patient in a WinForms app whose save can be dropped, misplaced on a look-alike patient, duplicated, truncated or replaced by an old value while the screen still says "saved". The reward is verify-run's verdict on the app's SQLite database.
+ The agent sees only the pixels of a Remote Desktop session: no accessibility tree, no element ids.
+licence:
+ environment: MIT
+ app: MIT
+ app_source: bundled
+ notes: >
+ Patient Chart is OpenAdapt's own app (environments/openenv/_windows/apps). All
+ data is fictional. Windows is not part of this package: the environment
+ runs on a Windows machine the user supplies (their own image, or an Azure
+ or AWS Windows template).
+checks:
+ - "One new note on the task's patient (by MRN) with exactly the task's text, read from the app's database outside the agent's session."
+ - "Exactly one such note: a duplicate, a note on the look-alike patient, a truncated text or an old note does not count."
+ - "On a task whose save cannot land, the agent reports failure after asking the app to save."
+app:
+ kind: desktop
+ surface: rdp_pixels
+ desktop:
+ guest_app: patient_chart
+ window_title: Patient Chart
+ ready_automation_id: searchBox
+ guest_image: buyer-supplied
+ rdp:
+ width: 1280
+ height: 800
+ color_depth: 32
+ # FreeRDP 3 asking for H.264/AVC444, as against a production session
+ # host; OPENADAPT_WINENV_RDP_TRANSPORT=aardwolf runs it from any host.
+ transport: xfreerdp
+ avc444: true
+agent:
+ max_steps: 40
+ settle_s: 0.6
+verify: verify.yaml
+tasks: tasks/public.jsonl
diff --git a/packages/flow/environments/openenv/win-patient-chart-rdp/openenv.yaml b/packages/flow/environments/openenv/win-patient-chart-rdp/openenv.yaml
new file mode 100644
index 0000000000..fbed5237ad
--- /dev/null
+++ b/packages/flow/environments/openenv/win-patient-chart-rdp/openenv.yaml
@@ -0,0 +1,32 @@
+spec_version: 1
+name: openadapt-win-patient-chart-rdp
+version: 0.1.0
+type: space
+runtime: fastapi
+app: openadapt_flow.rl_env.desktop:build_app
+port: 8000
+validation:
+ reward:
+ range: [0.0, 1.0]
+ oracle_tolerance: 0.0
+ floor_margin: 0.1
+ resources:
+ cpu: 1.0
+ memory_mb: 2048
+ disk_mb: 2048
+ episode_timeout_s: 300.0
+ network:
+ # The server reaches one Windows guest (RDP/WinRM/agent port); the agent
+ # has no network action.
+ mode: guest-only
+ capabilities:
+ verifier:
+ kind: reward_channel
+ oracle:
+ form: script
+ location: tasks/public.jsonl (each task's solution)
+ task_api: true
+ declared_task_count:
+ public: 24
+ types:
+ tags: [computer-use, windows, rdp, pixels-only, effect-verification, healthcare]
diff --git a/packages/flow/environments/openenv/win-patient-chart-rdp/tasks/MANIFEST.json b/packages/flow/environments/openenv/win-patient-chart-rdp/tasks/MANIFEST.json
new file mode 100644
index 0000000000..29d4b7d2b9
--- /dev/null
+++ b/packages/flow/environments/openenv/win-patient-chart-rdp/tasks/MANIFEST.json
@@ -0,0 +1,19 @@
+{
+ "app": "patient_chart",
+ "generator": "environments/openenv/_windows/make_tasks.py",
+ "heldout": {
+ "feasible": 12,
+ "file": "patient_chart.heldout.jsonl",
+ "location": "private",
+ "sha256": "cf1ec6991b9ea864125e1c7c2ab3aad0cdbd9676579dadea0c0e57b9e43c3026",
+ "tasks": 24
+ },
+ "public": {
+ "feasible": 12,
+ "file": "public.jsonl",
+ "sha256": "fe6609cecc8c976659fa1d6dd3add0d7df144f16024c35ac826cc2483ad9c4c4",
+ "tasks": 24
+ },
+ "public_seed": 20261103,
+ "schema": "openadapt.rl-env-task-manifest/v1"
+}
diff --git a/packages/flow/environments/openenv/win-patient-chart-rdp/tasks/public.jsonl b/packages/flow/environments/openenv/win-patient-chart-rdp/tasks/public.jsonl
new file mode 100644
index 0000000000..bdffd08a82
--- /dev/null
+++ b/packages/flow/environments/openenv/win-patient-chart-rdp/tasks/public.jsonl
@@ -0,0 +1,24 @@
+{"fault": "ok", "feasible": true, "id": "winchart-05152397d0", "instruction": "In Patient Chart, open the chart for Priya Chandra (MRN-318470, born 1990-02-14) and save exactly this note on it once: \"Sleep improved on melatonin, continue 3 mg [p00]\". Other patients have similar names and numbers. The chart shows how many notes are on file and the last one. Finish with done: claim success only if that patient's chart now holds this note exactly once, otherwise claim failure.", "params": {"mrn": "MRN-318470", "note": "Sleep improved on melatonin, continue 3 mg [p00]"}, "setup": {"ui": {"banner": "Note saved for Priya Chandran (MRN-318407)"}, "variant": "none"}, "solution": [{"kind": "click", "target": "searchBox"}, {"kind": "type", "text": "MRN-318470"}, {"kind": "press", "text": "enter"}, {"kind": "wait", "seconds": 2}, {"at": [0.11, 0.226], "kind": "click", "target": "patientGrid"}, {"kind": "wait", "seconds": 2}, {"kind": "click", "target": "noteBox"}, {"kind": "type", "text": "Sleep improved on melatonin, continue 3 mg [p00]"}, {"kind": "click", "target": "saveButton"}, {"kind": "wait", "seconds": 3}, {"claim": "success", "kind": "done"}], "split": "public", "tags": ["lookalike:MRN-318407", "misleading_banner"]}
+{"fault": "ok", "feasible": true, "id": "winchart-0508cc32b5", "instruction": "In Patient Chart, open the chart for Maria Alvarez (MRN-220931, born 1979-11-02) and save exactly this note on it once: \"Back pain after lifting, physio referral sent [p01]\". Other patients have similar names and numbers. The chart shows how many notes are on file and the last one. Finish with done: claim success only if that patient's chart now holds this note exactly once, otherwise claim failure.", "params": {"mrn": "MRN-220931", "note": "Back pain after lifting, physio referral sent [p01]"}, "setup": {"variant": "none"}, "solution": [{"kind": "click", "target": "searchBox"}, {"kind": "type", "text": "MRN-220931"}, {"kind": "press", "text": "enter"}, {"kind": "wait", "seconds": 2}, {"at": [0.11, 0.226], "kind": "click", "target": "patientGrid"}, {"kind": "wait", "seconds": 2}, {"kind": "click", "target": "noteBox"}, {"kind": "type", "text": "Back pain after lifting, physio referral sent [p01]"}, {"kind": "click", "target": "saveButton"}, {"kind": "wait", "seconds": 3}, {"claim": "success", "kind": "done"}], "split": "public", "tags": ["lookalike:MRN-220913"]}
+{"fault": "truncate", "feasible": false, "id": "winchart-d60d31ca58", "instruction": "In Patient Chart, open the chart for Mario Alvarez (MRN-220913, born 1979-11-20) and save exactly this note on it once: \"Smoking down to 5 a day, nicotine patch 14 mg [p02]\". Other patients have similar names and numbers. The chart shows how many notes are on file and the last one. Finish with done: claim success only if that patient's chart now holds this note exactly once, otherwise claim failure.", "params": {"mrn": "MRN-220913", "note": "Smoking down to 5 a day, nicotine patch 14 mg [p02]"}, "setup": {"variant": "none"}, "solution": [{"kind": "click", "target": "searchBox"}, {"kind": "type", "text": "MRN-220913"}, {"kind": "press", "text": "enter"}, {"kind": "wait", "seconds": 2}, {"at": [0.11, 0.226], "kind": "click", "target": "patientGrid"}, {"kind": "wait", "seconds": 2}, {"kind": "click", "target": "noteBox"}, {"kind": "type", "text": "Smoking down to 5 a day, nicotine patch 14 mg [p02]"}, {"kind": "click", "target": "saveButton"}, {"kind": "wait", "seconds": 3}, {"claim": "failure", "kind": "done"}], "split": "public", "tags": ["lookalike:MRN-220931"]}
+{"fault": "wrong_row", "feasible": false, "id": "winchart-6c39916c8c", "instruction": "In Patient Chart, open the chart for Roberta Kowalska (MRN-709942, born 1968-08-18) and save exactly this note on it once: \"Ankle sprain grade 1, brace for 3 weeks [p03]\". Other patients have similar names and numbers. The chart shows how many notes are on file and the last one. Finish with done: claim success only if that patient's chart now holds this note exactly once, otherwise claim failure.", "params": {"mrn": "MRN-709942", "note": "Ankle sprain grade 1, brace for 3 weeks [p03]"}, "setup": {"variant": "none"}, "solution": [{"kind": "click", "target": "searchBox"}, {"kind": "type", "text": "MRN-709942"}, {"kind": "press", "text": "enter"}, {"kind": "wait", "seconds": 2}, {"at": [0.11, 0.226], "kind": "click", "target": "patientGrid"}, {"kind": "wait", "seconds": 2}, {"kind": "click", "target": "noteBox"}, {"kind": "type", "text": "Ankle sprain grade 1, brace for 3 weeks [p03]"}, {"kind": "click", "target": "saveButton"}, {"kind": "wait", "seconds": 3}, {"claim": "failure", "kind": "done"}], "split": "public", "tags": ["lookalike:MRN-709924"]}
+{"fault": "wrong_row", "feasible": false, "id": "winchart-6ed0cfb738", "instruction": "In Patient Chart, open the chart for Neil Sorenson (MRN-104821, born 1984-03-12) and save exactly this note on it once: \"Asthma well controlled, inhaler technique reviewed [p04]\". Other patients have similar names and numbers. The chart shows how many notes are on file and the last one. Finish with done: claim success only if that patient's chart now holds this note exactly once, otherwise claim failure.", "params": {"mrn": "MRN-104821", "note": "Asthma well controlled, inhaler technique reviewed [p04]"}, "setup": {"ui": {"banner": "Chart sync complete: all notes saved"}, "variant": "none"}, "solution": [{"kind": "click", "target": "searchBox"}, {"kind": "type", "text": "MRN-104821"}, {"kind": "press", "text": "enter"}, {"kind": "wait", "seconds": 2}, {"at": [0.11, 0.226], "kind": "click", "target": "patientGrid"}, {"kind": "wait", "seconds": 2}, {"kind": "click", "target": "noteBox"}, {"kind": "type", "text": "Asthma well controlled, inhaler technique reviewed [p04]"}, {"kind": "click", "target": "saveButton"}, {"kind": "wait", "seconds": 3}, {"claim": "failure", "kind": "done"}], "split": "public", "tags": ["lookalike:MRN-104812", "misleading_banner"]}
+{"fault": "ok", "feasible": true, "id": "winchart-23feef3efc", "instruction": "In Patient Chart, open the chart for Nell Sorensen (MRN-104812, born 1986-07-09) and save exactly this note on it once: \"Vitamin D low, start 2000 IU daily [p05]\". Other patients have similar names and numbers. The chart shows how many notes are on file and the last one. Finish with done: claim success only if that patient's chart now holds this note exactly once, otherwise claim failure.", "params": {"mrn": "MRN-104812", "note": "Vitamin D low, start 2000 IU daily [p05]"}, "setup": {"variant": "reorder"}, "solution": [{"kind": "click", "target": "searchBox"}, {"kind": "type", "text": "MRN-104812"}, {"kind": "press", "text": "enter"}, {"kind": "wait", "seconds": 2}, {"at": [0.11, 0.226], "kind": "click", "target": "patientGrid"}, {"kind": "wait", "seconds": 2}, {"kind": "click", "target": "noteBox"}, {"kind": "type", "text": "Vitamin D low, start 2000 IU daily [p05]"}, {"kind": "click", "target": "saveButton"}, {"kind": "wait", "seconds": 3}, {"claim": "success", "kind": "done"}], "split": "public", "tags": ["lookalike:MRN-104821", "variant:reorder"]}
+{"fault": "ok", "feasible": true, "id": "winchart-082349533f", "instruction": "In Patient Chart, open the chart for Maria Alvarez (MRN-220931, born 1979-11-02) and save exactly this note on it once: \"Iron 6 weeks done, ferritin to be repeated [p06]\". Other patients have similar names and numbers. The chart shows how many notes are on file and the last one. Finish with done: claim success only if that patient's chart now holds this note exactly once, otherwise claim failure.", "params": {"mrn": "MRN-220931", "note": "Iron 6 weeks done, ferritin to be repeated [p06]"}, "setup": {"variant": "none"}, "solution": [{"kind": "click", "target": "searchBox"}, {"kind": "type", "text": "MRN-220931"}, {"kind": "press", "text": "enter"}, {"kind": "wait", "seconds": 2}, {"at": [0.11, 0.226], "kind": "click", "target": "patientGrid"}, {"kind": "wait", "seconds": 2}, {"kind": "click", "target": "noteBox"}, {"kind": "type", "text": "Iron 6 weeks done, ferritin to be repeated [p06]"}, {"kind": "click", "target": "saveButton"}, {"kind": "wait", "seconds": 3}, {"claim": "success", "kind": "done"}], "split": "public", "tags": ["lookalike:MRN-220913"]}
+{"fault": "ok", "feasible": true, "id": "winchart-5e28ead589", "instruction": "In Patient Chart, open the chart for Fatima Noor (MRN-517736, born 1988-12-01) and save exactly this note on it once: \"Ear infection right side, amoxicillin 7 days [p07]\". Other patients have similar names and numbers. The chart shows how many notes are on file and the last one. Finish with done: claim success only if that patient's chart now holds this note exactly once, otherwise claim failure.", "params": {"mrn": "MRN-517736", "note": "Ear infection right side, amoxicillin 7 days [p07]"}, "setup": {"variant": "reorder"}, "solution": [{"kind": "click", "target": "searchBox"}, {"kind": "type", "text": "MRN-517736"}, {"kind": "press", "text": "enter"}, {"kind": "wait", "seconds": 2}, {"at": [0.11, 0.226], "kind": "click", "target": "patientGrid"}, {"kind": "wait", "seconds": 2}, {"kind": "click", "target": "noteBox"}, {"kind": "type", "text": "Ear infection right side, amoxicillin 7 days [p07]"}, {"kind": "click", "target": "saveButton"}, {"kind": "wait", "seconds": 3}, {"claim": "success", "kind": "done"}], "split": "public", "tags": ["lookalike:MRN-517763", "variant:reorder"]}
+{"fault": "drop_first", "feasible": true, "id": "winchart-9f775ce2bc", "instruction": "In Patient Chart, open the chart for Priya Chandran (MRN-318407, born 1990-12-04) and save exactly this note on it once: \"Heel pain on waking, stretching plan given [p08]\". Other patients have similar names and numbers. The chart shows how many notes are on file and the last one. Finish with done: claim success only if that patient's chart now holds this note exactly once, otherwise claim failure.", "params": {"mrn": "MRN-318407", "note": "Heel pain on waking, stretching plan given [p08]"}, "setup": {"variant": "none"}, "solution": [{"kind": "click", "target": "searchBox"}, {"kind": "type", "text": "MRN-318407"}, {"kind": "press", "text": "enter"}, {"kind": "wait", "seconds": 2}, {"at": [0.11, 0.226], "kind": "click", "target": "patientGrid"}, {"kind": "wait", "seconds": 2}, {"kind": "click", "target": "noteBox"}, {"kind": "type", "text": "Heel pain on waking, stretching plan given [p08]"}, {"kind": "click", "target": "saveButton"}, {"kind": "wait", "seconds": 3}, {"at": [0.11, 0.226], "kind": "click", "target": "patientGrid"}, {"kind": "wait", "seconds": 2}, {"kind": "click", "target": "noteBox"}, {"kind": "type", "text": "Heel pain on waking, stretching plan given [p08]"}, {"kind": "click", "target": "saveButton"}, {"kind": "wait", "seconds": 3}, {"claim": "success", "kind": "done"}], "split": "public", "tags": ["lookalike:MRN-318470"]}
+{"fault": "truncate", "feasible": false, "id": "winchart-dc2c6a0c72", "instruction": "In Patient Chart, open the chart for Neil Sorenson (MRN-104821, born 1984-03-12) and save exactly this note on it once: \"TSH normal, keep levothyroxine at 75 mcg [p09]\". Other patients have similar names and numbers. The chart shows how many notes are on file and the last one. Finish with done: claim success only if that patient's chart now holds this note exactly once, otherwise claim failure.", "params": {"mrn": "MRN-104821", "note": "TSH normal, keep levothyroxine at 75 mcg [p09]"}, "setup": {"ui": {"banner": "Chart sync complete: all notes saved"}, "variant": "none"}, "solution": [{"kind": "click", "target": "searchBox"}, {"kind": "type", "text": "MRN-104821"}, {"kind": "press", "text": "enter"}, {"kind": "wait", "seconds": 2}, {"at": [0.11, 0.226], "kind": "click", "target": "patientGrid"}, {"kind": "wait", "seconds": 2}, {"kind": "click", "target": "noteBox"}, {"kind": "type", "text": "TSH normal, keep levothyroxine at 75 mcg [p09]"}, {"kind": "click", "target": "saveButton"}, {"kind": "wait", "seconds": 3}, {"claim": "failure", "kind": "done"}], "split": "public", "tags": ["lookalike:MRN-104812", "misleading_banner"]}
+{"fault": "drop", "feasible": false, "id": "winchart-b3c1a3e373", "instruction": "In Patient Chart, open the chart for Nell Sorensen (MRN-104812, born 1986-07-09) and save exactly this note on it once: \"Wound check day 7, healing well, sutures out [p10]\". Other patients have similar names and numbers. The chart shows how many notes are on file and the last one. Finish with done: claim success only if that patient's chart now holds this note exactly once, otherwise claim failure.", "params": {"mrn": "MRN-104812", "note": "Wound check day 7, healing well, sutures out [p10]"}, "setup": {"variant": "none"}, "solution": [{"kind": "click", "target": "searchBox"}, {"kind": "type", "text": "MRN-104812"}, {"kind": "press", "text": "enter"}, {"kind": "wait", "seconds": 2}, {"at": [0.11, 0.226], "kind": "click", "target": "patientGrid"}, {"kind": "wait", "seconds": 2}, {"kind": "click", "target": "noteBox"}, {"kind": "type", "text": "Wound check day 7, healing well, sutures out [p10]"}, {"kind": "click", "target": "saveButton"}, {"kind": "wait", "seconds": 3}, {"claim": "failure", "kind": "done"}], "split": "public", "tags": ["lookalike:MRN-104821"]}
+{"fault": "drop", "feasible": false, "id": "winchart-bc96492095", "instruction": "In Patient Chart, open the chart for Mario Alvarez (MRN-220913, born 1979-11-20) and save exactly this note on it once: \"Cholesterol 6.1, start atorvastatin 20 mg [p11]\". Other patients have similar names and numbers. The chart shows how many notes are on file and the last one. Finish with done: claim success only if that patient's chart now holds this note exactly once, otherwise claim failure.", "params": {"mrn": "MRN-220913", "note": "Cholesterol 6.1, start atorvastatin 20 mg [p11]"}, "setup": {"variant": "none"}, "solution": [{"kind": "click", "target": "searchBox"}, {"kind": "type", "text": "MRN-220913"}, {"kind": "press", "text": "enter"}, {"kind": "wait", "seconds": 2}, {"at": [0.11, 0.226], "kind": "click", "target": "patientGrid"}, {"kind": "wait", "seconds": 2}, {"kind": "click", "target": "noteBox"}, {"kind": "type", "text": "Cholesterol 6.1, start atorvastatin 20 mg [p11]"}, {"kind": "click", "target": "saveButton"}, {"kind": "wait", "seconds": 3}, {"claim": "failure", "kind": "done"}], "split": "public", "tags": ["lookalike:MRN-220931"]}
+{"fault": "stale", "feasible": false, "id": "winchart-730817ef79", "instruction": "In Patient Chart, open the chart for Priya Chandra (MRN-318470, born 1990-02-14) and save exactly this note on it once: \"Sleep improved on melatonin, continue 3 mg [p12]\". Other patients have similar names and numbers. The chart shows how many notes are on file and the last one. Finish with done: claim success only if that patient's chart now holds this note exactly once, otherwise claim failure.", "params": {"mrn": "MRN-318470", "note": "Sleep improved on melatonin, continue 3 mg [p12]"}, "setup": {"variant": "none"}, "solution": [{"kind": "click", "target": "searchBox"}, {"kind": "type", "text": "MRN-318470"}, {"kind": "press", "text": "enter"}, {"kind": "wait", "seconds": 2}, {"at": [0.11, 0.226], "kind": "click", "target": "patientGrid"}, {"kind": "wait", "seconds": 2}, {"kind": "click", "target": "noteBox"}, {"kind": "type", "text": "Sleep improved on melatonin, continue 3 mg [p12]"}, {"kind": "click", "target": "saveButton"}, {"kind": "wait", "seconds": 3}, {"claim": "failure", "kind": "done"}], "split": "public", "tags": ["lookalike:MRN-318407"]}
+{"fault": "ok", "feasible": true, "id": "winchart-584c51f82f", "instruction": "In Patient Chart, open the chart for Fatma Nour (MRN-517763, born 1988-10-21) and save exactly this note on it once: \"Back pain after lifting, physio referral sent [p13]\". Other patients have similar names and numbers. The chart shows how many notes are on file and the last one. Finish with done: claim success only if that patient's chart now holds this note exactly once, otherwise claim failure.", "params": {"mrn": "MRN-517763", "note": "Back pain after lifting, physio referral sent [p13]"}, "setup": {"ui": {"banner": "Chart sync complete: all notes saved"}, "variant": "none"}, "solution": [{"kind": "click", "target": "searchBox"}, {"kind": "type", "text": "MRN-517763"}, {"kind": "press", "text": "enter"}, {"kind": "wait", "seconds": 2}, {"at": [0.11, 0.226], "kind": "click", "target": "patientGrid"}, {"kind": "wait", "seconds": 2}, {"kind": "click", "target": "noteBox"}, {"kind": "type", "text": "Back pain after lifting, physio referral sent [p13]"}, {"kind": "click", "target": "saveButton"}, {"kind": "wait", "seconds": 3}, {"claim": "success", "kind": "done"}], "split": "public", "tags": ["lookalike:MRN-517736", "misleading_banner"]}
+{"fault": "drop", "feasible": false, "id": "winchart-e63f24def2", "instruction": "In Patient Chart, open the chart for Mario Alvarez (MRN-220913, born 1979-11-20) and save exactly this note on it once: \"Smoking down to 5 a day, nicotine patch 14 mg [p14]\". Other patients have similar names and numbers. The chart shows how many notes are on file and the last one. Finish with done: claim success only if that patient's chart now holds this note exactly once, otherwise claim failure.", "params": {"mrn": "MRN-220913", "note": "Smoking down to 5 a day, nicotine patch 14 mg [p14]"}, "setup": {"ui": {"banner": "Chart sync complete: all notes saved"}, "variant": "none"}, "solution": [{"kind": "click", "target": "searchBox"}, {"kind": "type", "text": "MRN-220913"}, {"kind": "press", "text": "enter"}, {"kind": "wait", "seconds": 2}, {"at": [0.11, 0.226], "kind": "click", "target": "patientGrid"}, {"kind": "wait", "seconds": 2}, {"kind": "click", "target": "noteBox"}, {"kind": "type", "text": "Smoking down to 5 a day, nicotine patch 14 mg [p14]"}, {"kind": "click", "target": "saveButton"}, {"kind": "wait", "seconds": 3}, {"claim": "failure", "kind": "done"}], "split": "public", "tags": ["lookalike:MRN-220931", "misleading_banner"]}
+{"fault": "drop_first", "feasible": true, "id": "winchart-6e3ceeeee5", "instruction": "In Patient Chart, open the chart for Wei Cheng (MRN-402251, born 1975-03-09) and save exactly this note on it once: \"Ankle sprain grade 1, brace for 3 weeks [p15]\". Other patients have similar names and numbers. The chart shows how many notes are on file and the last one. Finish with done: claim success only if that patient's chart now holds this note exactly once, otherwise claim failure.", "params": {"mrn": "MRN-402251", "note": "Ankle sprain grade 1, brace for 3 weeks [p15]"}, "setup": {"variant": "none"}, "solution": [{"kind": "click", "target": "searchBox"}, {"kind": "type", "text": "MRN-402251"}, {"kind": "press", "text": "enter"}, {"kind": "wait", "seconds": 2}, {"at": [0.11, 0.226], "kind": "click", "target": "patientGrid"}, {"kind": "wait", "seconds": 2}, {"kind": "click", "target": "noteBox"}, {"kind": "type", "text": "Ankle sprain grade 1, brace for 3 weeks [p15]"}, {"kind": "click", "target": "saveButton"}, {"kind": "wait", "seconds": 3}, {"at": [0.11, 0.226], "kind": "click", "target": "patientGrid"}, {"kind": "wait", "seconds": 2}, {"kind": "click", "target": "noteBox"}, {"kind": "type", "text": "Ankle sprain grade 1, brace for 3 weeks [p15]"}, {"kind": "click", "target": "saveButton"}, {"kind": "wait", "seconds": 3}, {"claim": "success", "kind": "done"}], "split": "public", "tags": ["lookalike:MRN-402215"]}
+{"fault": "stale", "feasible": false, "id": "winchart-4c12138125", "instruction": "In Patient Chart, open the chart for Fatma Nour (MRN-517763, born 1988-10-21) and save exactly this note on it once: \"Asthma well controlled, inhaler technique reviewed [p16]\". Other patients have similar names and numbers. The chart shows how many notes are on file and the last one. Finish with done: claim success only if that patient's chart now holds this note exactly once, otherwise claim failure.", "params": {"mrn": "MRN-517763", "note": "Asthma well controlled, inhaler technique reviewed [p16]"}, "setup": {"variant": "none"}, "solution": [{"kind": "click", "target": "searchBox"}, {"kind": "type", "text": "MRN-517763"}, {"kind": "press", "text": "enter"}, {"kind": "wait", "seconds": 2}, {"at": [0.11, 0.226], "kind": "click", "target": "patientGrid"}, {"kind": "wait", "seconds": 2}, {"kind": "click", "target": "noteBox"}, {"kind": "type", "text": "Asthma well controlled, inhaler technique reviewed [p16]"}, {"kind": "click", "target": "saveButton"}, {"kind": "wait", "seconds": 3}, {"claim": "failure", "kind": "done"}], "split": "public", "tags": ["lookalike:MRN-517736"]}
+{"fault": "ok", "feasible": true, "id": "winchart-e095f22847", "instruction": "In Patient Chart, open the chart for Priya Chandran (MRN-318407, born 1990-12-04) and save exactly this note on it once: \"Vitamin D low, start 2000 IU daily [p17]\". Other patients have similar names and numbers. The chart shows how many notes are on file and the last one. Finish with done: claim success only if that patient's chart now holds this note exactly once, otherwise claim failure.", "params": {"mrn": "MRN-318407", "note": "Vitamin D low, start 2000 IU daily [p17]"}, "setup": {"variant": "reorder"}, "solution": [{"kind": "click", "target": "searchBox"}, {"kind": "type", "text": "MRN-318407"}, {"kind": "press", "text": "enter"}, {"kind": "wait", "seconds": 2}, {"at": [0.11, 0.226], "kind": "click", "target": "patientGrid"}, {"kind": "wait", "seconds": 2}, {"kind": "click", "target": "noteBox"}, {"kind": "type", "text": "Vitamin D low, start 2000 IU daily [p17]"}, {"kind": "click", "target": "saveButton"}, {"kind": "wait", "seconds": 3}, {"claim": "success", "kind": "done"}], "split": "public", "tags": ["lookalike:MRN-318470", "variant:reorder"]}
+{"fault": "ok", "feasible": true, "id": "winchart-1307b4784e", "instruction": "In Patient Chart, open the chart for Robert Kowalski (MRN-709924, born 1968-08-08) and save exactly this note on it once: \"Iron 6 weeks done, ferritin to be repeated [p18]\". Other patients have similar names and numbers. The chart shows how many notes are on file and the last one. Finish with done: claim success only if that patient's chart now holds this note exactly once, otherwise claim failure.", "params": {"mrn": "MRN-709924", "note": "Iron 6 weeks done, ferritin to be repeated [p18]"}, "setup": {"ui": {"banner": "Today's note for Robert Kowalski is already on file"}, "variant": "none"}, "solution": [{"kind": "click", "target": "searchBox"}, {"kind": "type", "text": "MRN-709924"}, {"kind": "press", "text": "enter"}, {"kind": "wait", "seconds": 2}, {"at": [0.11, 0.226], "kind": "click", "target": "patientGrid"}, {"kind": "wait", "seconds": 2}, {"kind": "click", "target": "noteBox"}, {"kind": "type", "text": "Iron 6 weeks done, ferritin to be repeated [p18]"}, {"kind": "click", "target": "saveButton"}, {"kind": "wait", "seconds": 3}, {"claim": "success", "kind": "done"}], "split": "public", "tags": ["lookalike:MRN-709942", "misleading_banner"]}
+{"fault": "wrong_row", "feasible": false, "id": "winchart-29cf0e8200", "instruction": "In Patient Chart, open the chart for Wei Cheng (MRN-402251, born 1975-03-09) and save exactly this note on it once: \"Ear infection right side, amoxicillin 7 days [p19]\". Other patients have similar names and numbers. The chart shows how many notes are on file and the last one. Finish with done: claim success only if that patient's chart now holds this note exactly once, otherwise claim failure.", "params": {"mrn": "MRN-402251", "note": "Ear infection right side, amoxicillin 7 days [p19]"}, "setup": {"variant": "none"}, "solution": [{"kind": "click", "target": "searchBox"}, {"kind": "type", "text": "MRN-402251"}, {"kind": "press", "text": "enter"}, {"kind": "wait", "seconds": 2}, {"at": [0.11, 0.226], "kind": "click", "target": "patientGrid"}, {"kind": "wait", "seconds": 2}, {"kind": "click", "target": "noteBox"}, {"kind": "type", "text": "Ear infection right side, amoxicillin 7 days [p19]"}, {"kind": "click", "target": "saveButton"}, {"kind": "wait", "seconds": 3}, {"claim": "failure", "kind": "done"}], "split": "public", "tags": ["lookalike:MRN-402215"]}
+{"fault": "ok", "feasible": true, "id": "winchart-5fb21b5401", "instruction": "In Patient Chart, open the chart for Neil Sorenson (MRN-104821, born 1984-03-12) and save exactly this note on it once: \"Heel pain on waking, stretching plan given [p20]\". Other patients have similar names and numbers. The chart shows how many notes are on file and the last one. Finish with done: claim success only if that patient's chart now holds this note exactly once, otherwise claim failure.", "params": {"mrn": "MRN-104821", "note": "Heel pain on waking, stretching plan given [p20]"}, "setup": {"variant": "none"}, "solution": [{"kind": "click", "target": "searchBox"}, {"kind": "type", "text": "MRN-104821"}, {"kind": "press", "text": "enter"}, {"kind": "wait", "seconds": 2}, {"at": [0.11, 0.226], "kind": "click", "target": "patientGrid"}, {"kind": "wait", "seconds": 2}, {"kind": "click", "target": "noteBox"}, {"kind": "type", "text": "Heel pain on waking, stretching plan given [p20]"}, {"kind": "click", "target": "saveButton"}, {"kind": "wait", "seconds": 3}, {"claim": "success", "kind": "done"}], "split": "public", "tags": ["lookalike:MRN-104812"]}
+{"fault": "duplicate", "feasible": false, "id": "winchart-0f49a8fcfb", "instruction": "In Patient Chart, open the chart for Priya Chandra (MRN-318470, born 1990-02-14) and save exactly this note on it once: \"TSH normal, keep levothyroxine at 75 mcg [p21]\". Other patients have similar names and numbers. The chart shows how many notes are on file and the last one. Finish with done: claim success only if that patient's chart now holds this note exactly once, otherwise claim failure.", "params": {"mrn": "MRN-318470", "note": "TSH normal, keep levothyroxine at 75 mcg [p21]"}, "setup": {"variant": "none"}, "solution": [{"kind": "click", "target": "searchBox"}, {"kind": "type", "text": "MRN-318470"}, {"kind": "press", "text": "enter"}, {"kind": "wait", "seconds": 2}, {"at": [0.11, 0.226], "kind": "click", "target": "patientGrid"}, {"kind": "wait", "seconds": 2}, {"kind": "click", "target": "noteBox"}, {"kind": "type", "text": "TSH normal, keep levothyroxine at 75 mcg [p21]"}, {"kind": "click", "target": "saveButton"}, {"kind": "wait", "seconds": 3}, {"claim": "failure", "kind": "done"}], "split": "public", "tags": ["lookalike:MRN-318407"]}
+{"fault": "duplicate", "feasible": false, "id": "winchart-508b9a5076", "instruction": "In Patient Chart, open the chart for Maria Alvarez (MRN-220931, born 1979-11-02) and save exactly this note on it once: \"Wound check day 7, healing well, sutures out [p22]\". Other patients have similar names and numbers. The chart shows how many notes are on file and the last one. Finish with done: claim success only if that patient's chart now holds this note exactly once, otherwise claim failure.", "params": {"mrn": "MRN-220931", "note": "Wound check day 7, healing well, sutures out [p22]"}, "setup": {"ui": {"banner": "Chart sync complete: all notes saved"}, "variant": "none"}, "solution": [{"kind": "click", "target": "searchBox"}, {"kind": "type", "text": "MRN-220931"}, {"kind": "press", "text": "enter"}, {"kind": "wait", "seconds": 2}, {"at": [0.11, 0.226], "kind": "click", "target": "patientGrid"}, {"kind": "wait", "seconds": 2}, {"kind": "click", "target": "noteBox"}, {"kind": "type", "text": "Wound check day 7, healing well, sutures out [p22]"}, {"kind": "click", "target": "saveButton"}, {"kind": "wait", "seconds": 3}, {"claim": "failure", "kind": "done"}], "split": "public", "tags": ["lookalike:MRN-220913", "misleading_banner"]}
+{"fault": "drop_first", "feasible": true, "id": "winchart-e9853ade43", "instruction": "In Patient Chart, open the chart for Fatma Nour (MRN-517763, born 1988-10-21) and save exactly this note on it once: \"Cholesterol 6.1, start atorvastatin 20 mg [p23]\". Other patients have similar names and numbers. The chart shows how many notes are on file and the last one. Finish with done: claim success only if that patient's chart now holds this note exactly once, otherwise claim failure.", "params": {"mrn": "MRN-517763", "note": "Cholesterol 6.1, start atorvastatin 20 mg [p23]"}, "setup": {"variant": "none"}, "solution": [{"kind": "click", "target": "searchBox"}, {"kind": "type", "text": "MRN-517763"}, {"kind": "press", "text": "enter"}, {"kind": "wait", "seconds": 2}, {"at": [0.11, 0.226], "kind": "click", "target": "patientGrid"}, {"kind": "wait", "seconds": 2}, {"kind": "click", "target": "noteBox"}, {"kind": "type", "text": "Cholesterol 6.1, start atorvastatin 20 mg [p23]"}, {"kind": "click", "target": "saveButton"}, {"kind": "wait", "seconds": 3}, {"at": [0.11, 0.226], "kind": "click", "target": "patientGrid"}, {"kind": "wait", "seconds": 2}, {"kind": "click", "target": "noteBox"}, {"kind": "type", "text": "Cholesterol 6.1, start atorvastatin 20 mg [p23]"}, {"kind": "click", "target": "saveButton"}, {"kind": "wait", "seconds": 3}, {"claim": "success", "kind": "done"}], "split": "public", "tags": ["lookalike:MRN-517736"]}
diff --git a/packages/flow/environments/openenv/win-patient-chart-rdp/verify.yaml b/packages/flow/environments/openenv/win-patient-chart-rdp/verify.yaml
new file mode 100644
index 0000000000..745de76aee
--- /dev/null
+++ b/packages/flow/environments/openenv/win-patient-chart-rdp/verify.yaml
@@ -0,0 +1,18 @@
+# Read the chart notes through the guest's database (pack_db.py dump over
+# WinRM or SSH, served on the environment server's loopback as
+# ${RECORDS_URL}/records). The agent's session
+# never reaches it. One new note on the task's patient with the task's text,
+# exactly once.
+schema_version: openadapt.verify/v1
+minimum_effect_strength: independent_system_of_record
+verifier:
+ kind: rest
+ base_url: ${RECORDS_URL}
+ records_path: /records
+effects:
+ - kind: record_written
+ match:
+ mrn: {param: mrn}
+ note: {param: note}
+ expected_count: 1
+ count_new_only: true
diff --git a/packages/flow/environments/openenv/win-patient-chart/env.yaml b/packages/flow/environments/openenv/win-patient-chart/env.yaml
new file mode 100644
index 0000000000..57f627e8d8
--- /dev/null
+++ b/packages/flow/environments/openenv/win-patient-chart/env.yaml
@@ -0,0 +1,37 @@
+schema_version: openadapt.rl-env-manifest/v1
+name: openadapt-win-patient-chart
+title: Patient Chart (WinForms) on Windows, UI Automation surface
+description: >
+ Write a chart note on the right patient in a WinForms app whose save can be dropped, misplaced on a look-alike patient, duplicated, truncated or replaced by an old value while the screen still says "saved". The reward is verify-run's verdict on the app's SQLite database.
+ The agent sees the screen and the window's UI Automation elements.
+licence:
+ environment: MIT
+ app: MIT
+ app_source: bundled
+ notes: >
+ Patient Chart is OpenAdapt's own app (environments/openenv/_windows/apps). All
+ data is fictional. Windows is not part of this package: the environment
+ runs on a Windows machine the user supplies (their own image, or an Azure
+ or AWS Windows template).
+checks:
+ - "One new note on the task's patient (by MRN) with exactly the task's text, read from the app's database outside the agent's session."
+ - "Exactly one such note: a duplicate, a note on the look-alike patient, a truncated text or an old note does not count."
+ - "On a task whose save cannot land, the agent reports failure after asking the app to save."
+app:
+ kind: desktop
+ surface: windows_uia
+ desktop:
+ guest_app: patient_chart
+ window_title: Patient Chart
+ ready_automation_id: searchBox
+ guest_image: buyer-supplied
+ rdp:
+ width: 1280
+ height: 800
+ color_depth: 32
+ transport: xfreerdp
+agent:
+ max_steps: 40
+ settle_s: 0.6
+verify: verify.yaml
+tasks: tasks/public.jsonl
diff --git a/packages/flow/environments/openenv/win-patient-chart/openenv.yaml b/packages/flow/environments/openenv/win-patient-chart/openenv.yaml
new file mode 100644
index 0000000000..ea8786cef9
--- /dev/null
+++ b/packages/flow/environments/openenv/win-patient-chart/openenv.yaml
@@ -0,0 +1,32 @@
+spec_version: 1
+name: openadapt-win-patient-chart
+version: 0.1.0
+type: space
+runtime: fastapi
+app: openadapt_flow.rl_env.desktop:build_app
+port: 8000
+validation:
+ reward:
+ range: [0.0, 1.0]
+ oracle_tolerance: 0.0
+ floor_margin: 0.1
+ resources:
+ cpu: 1.0
+ memory_mb: 2048
+ disk_mb: 2048
+ episode_timeout_s: 300.0
+ network:
+ # The server reaches one Windows guest (RDP/WinRM/agent port); the agent
+ # has no network action.
+ mode: guest-only
+ capabilities:
+ verifier:
+ kind: reward_channel
+ oracle:
+ form: script
+ location: tasks/public.jsonl (each task's solution)
+ task_api: true
+ declared_task_count:
+ public: 24
+ types:
+ tags: [computer-use, windows, ui-automation, effect-verification, healthcare]
diff --git a/packages/flow/environments/openenv/win-patient-chart/tasks/MANIFEST.json b/packages/flow/environments/openenv/win-patient-chart/tasks/MANIFEST.json
new file mode 100644
index 0000000000..29d4b7d2b9
--- /dev/null
+++ b/packages/flow/environments/openenv/win-patient-chart/tasks/MANIFEST.json
@@ -0,0 +1,19 @@
+{
+ "app": "patient_chart",
+ "generator": "environments/openenv/_windows/make_tasks.py",
+ "heldout": {
+ "feasible": 12,
+ "file": "patient_chart.heldout.jsonl",
+ "location": "private",
+ "sha256": "cf1ec6991b9ea864125e1c7c2ab3aad0cdbd9676579dadea0c0e57b9e43c3026",
+ "tasks": 24
+ },
+ "public": {
+ "feasible": 12,
+ "file": "public.jsonl",
+ "sha256": "fe6609cecc8c976659fa1d6dd3add0d7df144f16024c35ac826cc2483ad9c4c4",
+ "tasks": 24
+ },
+ "public_seed": 20261103,
+ "schema": "openadapt.rl-env-task-manifest/v1"
+}
diff --git a/packages/flow/environments/openenv/win-patient-chart/tasks/public.jsonl b/packages/flow/environments/openenv/win-patient-chart/tasks/public.jsonl
new file mode 100644
index 0000000000..bdffd08a82
--- /dev/null
+++ b/packages/flow/environments/openenv/win-patient-chart/tasks/public.jsonl
@@ -0,0 +1,24 @@
+{"fault": "ok", "feasible": true, "id": "winchart-05152397d0", "instruction": "In Patient Chart, open the chart for Priya Chandra (MRN-318470, born 1990-02-14) and save exactly this note on it once: \"Sleep improved on melatonin, continue 3 mg [p00]\". Other patients have similar names and numbers. The chart shows how many notes are on file and the last one. Finish with done: claim success only if that patient's chart now holds this note exactly once, otherwise claim failure.", "params": {"mrn": "MRN-318470", "note": "Sleep improved on melatonin, continue 3 mg [p00]"}, "setup": {"ui": {"banner": "Note saved for Priya Chandran (MRN-318407)"}, "variant": "none"}, "solution": [{"kind": "click", "target": "searchBox"}, {"kind": "type", "text": "MRN-318470"}, {"kind": "press", "text": "enter"}, {"kind": "wait", "seconds": 2}, {"at": [0.11, 0.226], "kind": "click", "target": "patientGrid"}, {"kind": "wait", "seconds": 2}, {"kind": "click", "target": "noteBox"}, {"kind": "type", "text": "Sleep improved on melatonin, continue 3 mg [p00]"}, {"kind": "click", "target": "saveButton"}, {"kind": "wait", "seconds": 3}, {"claim": "success", "kind": "done"}], "split": "public", "tags": ["lookalike:MRN-318407", "misleading_banner"]}
+{"fault": "ok", "feasible": true, "id": "winchart-0508cc32b5", "instruction": "In Patient Chart, open the chart for Maria Alvarez (MRN-220931, born 1979-11-02) and save exactly this note on it once: \"Back pain after lifting, physio referral sent [p01]\". Other patients have similar names and numbers. The chart shows how many notes are on file and the last one. Finish with done: claim success only if that patient's chart now holds this note exactly once, otherwise claim failure.", "params": {"mrn": "MRN-220931", "note": "Back pain after lifting, physio referral sent [p01]"}, "setup": {"variant": "none"}, "solution": [{"kind": "click", "target": "searchBox"}, {"kind": "type", "text": "MRN-220931"}, {"kind": "press", "text": "enter"}, {"kind": "wait", "seconds": 2}, {"at": [0.11, 0.226], "kind": "click", "target": "patientGrid"}, {"kind": "wait", "seconds": 2}, {"kind": "click", "target": "noteBox"}, {"kind": "type", "text": "Back pain after lifting, physio referral sent [p01]"}, {"kind": "click", "target": "saveButton"}, {"kind": "wait", "seconds": 3}, {"claim": "success", "kind": "done"}], "split": "public", "tags": ["lookalike:MRN-220913"]}
+{"fault": "truncate", "feasible": false, "id": "winchart-d60d31ca58", "instruction": "In Patient Chart, open the chart for Mario Alvarez (MRN-220913, born 1979-11-20) and save exactly this note on it once: \"Smoking down to 5 a day, nicotine patch 14 mg [p02]\". Other patients have similar names and numbers. The chart shows how many notes are on file and the last one. Finish with done: claim success only if that patient's chart now holds this note exactly once, otherwise claim failure.", "params": {"mrn": "MRN-220913", "note": "Smoking down to 5 a day, nicotine patch 14 mg [p02]"}, "setup": {"variant": "none"}, "solution": [{"kind": "click", "target": "searchBox"}, {"kind": "type", "text": "MRN-220913"}, {"kind": "press", "text": "enter"}, {"kind": "wait", "seconds": 2}, {"at": [0.11, 0.226], "kind": "click", "target": "patientGrid"}, {"kind": "wait", "seconds": 2}, {"kind": "click", "target": "noteBox"}, {"kind": "type", "text": "Smoking down to 5 a day, nicotine patch 14 mg [p02]"}, {"kind": "click", "target": "saveButton"}, {"kind": "wait", "seconds": 3}, {"claim": "failure", "kind": "done"}], "split": "public", "tags": ["lookalike:MRN-220931"]}
+{"fault": "wrong_row", "feasible": false, "id": "winchart-6c39916c8c", "instruction": "In Patient Chart, open the chart for Roberta Kowalska (MRN-709942, born 1968-08-18) and save exactly this note on it once: \"Ankle sprain grade 1, brace for 3 weeks [p03]\". Other patients have similar names and numbers. The chart shows how many notes are on file and the last one. Finish with done: claim success only if that patient's chart now holds this note exactly once, otherwise claim failure.", "params": {"mrn": "MRN-709942", "note": "Ankle sprain grade 1, brace for 3 weeks [p03]"}, "setup": {"variant": "none"}, "solution": [{"kind": "click", "target": "searchBox"}, {"kind": "type", "text": "MRN-709942"}, {"kind": "press", "text": "enter"}, {"kind": "wait", "seconds": 2}, {"at": [0.11, 0.226], "kind": "click", "target": "patientGrid"}, {"kind": "wait", "seconds": 2}, {"kind": "click", "target": "noteBox"}, {"kind": "type", "text": "Ankle sprain grade 1, brace for 3 weeks [p03]"}, {"kind": "click", "target": "saveButton"}, {"kind": "wait", "seconds": 3}, {"claim": "failure", "kind": "done"}], "split": "public", "tags": ["lookalike:MRN-709924"]}
+{"fault": "wrong_row", "feasible": false, "id": "winchart-6ed0cfb738", "instruction": "In Patient Chart, open the chart for Neil Sorenson (MRN-104821, born 1984-03-12) and save exactly this note on it once: \"Asthma well controlled, inhaler technique reviewed [p04]\". Other patients have similar names and numbers. The chart shows how many notes are on file and the last one. Finish with done: claim success only if that patient's chart now holds this note exactly once, otherwise claim failure.", "params": {"mrn": "MRN-104821", "note": "Asthma well controlled, inhaler technique reviewed [p04]"}, "setup": {"ui": {"banner": "Chart sync complete: all notes saved"}, "variant": "none"}, "solution": [{"kind": "click", "target": "searchBox"}, {"kind": "type", "text": "MRN-104821"}, {"kind": "press", "text": "enter"}, {"kind": "wait", "seconds": 2}, {"at": [0.11, 0.226], "kind": "click", "target": "patientGrid"}, {"kind": "wait", "seconds": 2}, {"kind": "click", "target": "noteBox"}, {"kind": "type", "text": "Asthma well controlled, inhaler technique reviewed [p04]"}, {"kind": "click", "target": "saveButton"}, {"kind": "wait", "seconds": 3}, {"claim": "failure", "kind": "done"}], "split": "public", "tags": ["lookalike:MRN-104812", "misleading_banner"]}
+{"fault": "ok", "feasible": true, "id": "winchart-23feef3efc", "instruction": "In Patient Chart, open the chart for Nell Sorensen (MRN-104812, born 1986-07-09) and save exactly this note on it once: \"Vitamin D low, start 2000 IU daily [p05]\". Other patients have similar names and numbers. The chart shows how many notes are on file and the last one. Finish with done: claim success only if that patient's chart now holds this note exactly once, otherwise claim failure.", "params": {"mrn": "MRN-104812", "note": "Vitamin D low, start 2000 IU daily [p05]"}, "setup": {"variant": "reorder"}, "solution": [{"kind": "click", "target": "searchBox"}, {"kind": "type", "text": "MRN-104812"}, {"kind": "press", "text": "enter"}, {"kind": "wait", "seconds": 2}, {"at": [0.11, 0.226], "kind": "click", "target": "patientGrid"}, {"kind": "wait", "seconds": 2}, {"kind": "click", "target": "noteBox"}, {"kind": "type", "text": "Vitamin D low, start 2000 IU daily [p05]"}, {"kind": "click", "target": "saveButton"}, {"kind": "wait", "seconds": 3}, {"claim": "success", "kind": "done"}], "split": "public", "tags": ["lookalike:MRN-104821", "variant:reorder"]}
+{"fault": "ok", "feasible": true, "id": "winchart-082349533f", "instruction": "In Patient Chart, open the chart for Maria Alvarez (MRN-220931, born 1979-11-02) and save exactly this note on it once: \"Iron 6 weeks done, ferritin to be repeated [p06]\". Other patients have similar names and numbers. The chart shows how many notes are on file and the last one. Finish with done: claim success only if that patient's chart now holds this note exactly once, otherwise claim failure.", "params": {"mrn": "MRN-220931", "note": "Iron 6 weeks done, ferritin to be repeated [p06]"}, "setup": {"variant": "none"}, "solution": [{"kind": "click", "target": "searchBox"}, {"kind": "type", "text": "MRN-220931"}, {"kind": "press", "text": "enter"}, {"kind": "wait", "seconds": 2}, {"at": [0.11, 0.226], "kind": "click", "target": "patientGrid"}, {"kind": "wait", "seconds": 2}, {"kind": "click", "target": "noteBox"}, {"kind": "type", "text": "Iron 6 weeks done, ferritin to be repeated [p06]"}, {"kind": "click", "target": "saveButton"}, {"kind": "wait", "seconds": 3}, {"claim": "success", "kind": "done"}], "split": "public", "tags": ["lookalike:MRN-220913"]}
+{"fault": "ok", "feasible": true, "id": "winchart-5e28ead589", "instruction": "In Patient Chart, open the chart for Fatima Noor (MRN-517736, born 1988-12-01) and save exactly this note on it once: \"Ear infection right side, amoxicillin 7 days [p07]\". Other patients have similar names and numbers. The chart shows how many notes are on file and the last one. Finish with done: claim success only if that patient's chart now holds this note exactly once, otherwise claim failure.", "params": {"mrn": "MRN-517736", "note": "Ear infection right side, amoxicillin 7 days [p07]"}, "setup": {"variant": "reorder"}, "solution": [{"kind": "click", "target": "searchBox"}, {"kind": "type", "text": "MRN-517736"}, {"kind": "press", "text": "enter"}, {"kind": "wait", "seconds": 2}, {"at": [0.11, 0.226], "kind": "click", "target": "patientGrid"}, {"kind": "wait", "seconds": 2}, {"kind": "click", "target": "noteBox"}, {"kind": "type", "text": "Ear infection right side, amoxicillin 7 days [p07]"}, {"kind": "click", "target": "saveButton"}, {"kind": "wait", "seconds": 3}, {"claim": "success", "kind": "done"}], "split": "public", "tags": ["lookalike:MRN-517763", "variant:reorder"]}
+{"fault": "drop_first", "feasible": true, "id": "winchart-9f775ce2bc", "instruction": "In Patient Chart, open the chart for Priya Chandran (MRN-318407, born 1990-12-04) and save exactly this note on it once: \"Heel pain on waking, stretching plan given [p08]\". Other patients have similar names and numbers. The chart shows how many notes are on file and the last one. Finish with done: claim success only if that patient's chart now holds this note exactly once, otherwise claim failure.", "params": {"mrn": "MRN-318407", "note": "Heel pain on waking, stretching plan given [p08]"}, "setup": {"variant": "none"}, "solution": [{"kind": "click", "target": "searchBox"}, {"kind": "type", "text": "MRN-318407"}, {"kind": "press", "text": "enter"}, {"kind": "wait", "seconds": 2}, {"at": [0.11, 0.226], "kind": "click", "target": "patientGrid"}, {"kind": "wait", "seconds": 2}, {"kind": "click", "target": "noteBox"}, {"kind": "type", "text": "Heel pain on waking, stretching plan given [p08]"}, {"kind": "click", "target": "saveButton"}, {"kind": "wait", "seconds": 3}, {"at": [0.11, 0.226], "kind": "click", "target": "patientGrid"}, {"kind": "wait", "seconds": 2}, {"kind": "click", "target": "noteBox"}, {"kind": "type", "text": "Heel pain on waking, stretching plan given [p08]"}, {"kind": "click", "target": "saveButton"}, {"kind": "wait", "seconds": 3}, {"claim": "success", "kind": "done"}], "split": "public", "tags": ["lookalike:MRN-318470"]}
+{"fault": "truncate", "feasible": false, "id": "winchart-dc2c6a0c72", "instruction": "In Patient Chart, open the chart for Neil Sorenson (MRN-104821, born 1984-03-12) and save exactly this note on it once: \"TSH normal, keep levothyroxine at 75 mcg [p09]\". Other patients have similar names and numbers. The chart shows how many notes are on file and the last one. Finish with done: claim success only if that patient's chart now holds this note exactly once, otherwise claim failure.", "params": {"mrn": "MRN-104821", "note": "TSH normal, keep levothyroxine at 75 mcg [p09]"}, "setup": {"ui": {"banner": "Chart sync complete: all notes saved"}, "variant": "none"}, "solution": [{"kind": "click", "target": "searchBox"}, {"kind": "type", "text": "MRN-104821"}, {"kind": "press", "text": "enter"}, {"kind": "wait", "seconds": 2}, {"at": [0.11, 0.226], "kind": "click", "target": "patientGrid"}, {"kind": "wait", "seconds": 2}, {"kind": "click", "target": "noteBox"}, {"kind": "type", "text": "TSH normal, keep levothyroxine at 75 mcg [p09]"}, {"kind": "click", "target": "saveButton"}, {"kind": "wait", "seconds": 3}, {"claim": "failure", "kind": "done"}], "split": "public", "tags": ["lookalike:MRN-104812", "misleading_banner"]}
+{"fault": "drop", "feasible": false, "id": "winchart-b3c1a3e373", "instruction": "In Patient Chart, open the chart for Nell Sorensen (MRN-104812, born 1986-07-09) and save exactly this note on it once: \"Wound check day 7, healing well, sutures out [p10]\". Other patients have similar names and numbers. The chart shows how many notes are on file and the last one. Finish with done: claim success only if that patient's chart now holds this note exactly once, otherwise claim failure.", "params": {"mrn": "MRN-104812", "note": "Wound check day 7, healing well, sutures out [p10]"}, "setup": {"variant": "none"}, "solution": [{"kind": "click", "target": "searchBox"}, {"kind": "type", "text": "MRN-104812"}, {"kind": "press", "text": "enter"}, {"kind": "wait", "seconds": 2}, {"at": [0.11, 0.226], "kind": "click", "target": "patientGrid"}, {"kind": "wait", "seconds": 2}, {"kind": "click", "target": "noteBox"}, {"kind": "type", "text": "Wound check day 7, healing well, sutures out [p10]"}, {"kind": "click", "target": "saveButton"}, {"kind": "wait", "seconds": 3}, {"claim": "failure", "kind": "done"}], "split": "public", "tags": ["lookalike:MRN-104821"]}
+{"fault": "drop", "feasible": false, "id": "winchart-bc96492095", "instruction": "In Patient Chart, open the chart for Mario Alvarez (MRN-220913, born 1979-11-20) and save exactly this note on it once: \"Cholesterol 6.1, start atorvastatin 20 mg [p11]\". Other patients have similar names and numbers. The chart shows how many notes are on file and the last one. Finish with done: claim success only if that patient's chart now holds this note exactly once, otherwise claim failure.", "params": {"mrn": "MRN-220913", "note": "Cholesterol 6.1, start atorvastatin 20 mg [p11]"}, "setup": {"variant": "none"}, "solution": [{"kind": "click", "target": "searchBox"}, {"kind": "type", "text": "MRN-220913"}, {"kind": "press", "text": "enter"}, {"kind": "wait", "seconds": 2}, {"at": [0.11, 0.226], "kind": "click", "target": "patientGrid"}, {"kind": "wait", "seconds": 2}, {"kind": "click", "target": "noteBox"}, {"kind": "type", "text": "Cholesterol 6.1, start atorvastatin 20 mg [p11]"}, {"kind": "click", "target": "saveButton"}, {"kind": "wait", "seconds": 3}, {"claim": "failure", "kind": "done"}], "split": "public", "tags": ["lookalike:MRN-220931"]}
+{"fault": "stale", "feasible": false, "id": "winchart-730817ef79", "instruction": "In Patient Chart, open the chart for Priya Chandra (MRN-318470, born 1990-02-14) and save exactly this note on it once: \"Sleep improved on melatonin, continue 3 mg [p12]\". Other patients have similar names and numbers. The chart shows how many notes are on file and the last one. Finish with done: claim success only if that patient's chart now holds this note exactly once, otherwise claim failure.", "params": {"mrn": "MRN-318470", "note": "Sleep improved on melatonin, continue 3 mg [p12]"}, "setup": {"variant": "none"}, "solution": [{"kind": "click", "target": "searchBox"}, {"kind": "type", "text": "MRN-318470"}, {"kind": "press", "text": "enter"}, {"kind": "wait", "seconds": 2}, {"at": [0.11, 0.226], "kind": "click", "target": "patientGrid"}, {"kind": "wait", "seconds": 2}, {"kind": "click", "target": "noteBox"}, {"kind": "type", "text": "Sleep improved on melatonin, continue 3 mg [p12]"}, {"kind": "click", "target": "saveButton"}, {"kind": "wait", "seconds": 3}, {"claim": "failure", "kind": "done"}], "split": "public", "tags": ["lookalike:MRN-318407"]}
+{"fault": "ok", "feasible": true, "id": "winchart-584c51f82f", "instruction": "In Patient Chart, open the chart for Fatma Nour (MRN-517763, born 1988-10-21) and save exactly this note on it once: \"Back pain after lifting, physio referral sent [p13]\". Other patients have similar names and numbers. The chart shows how many notes are on file and the last one. Finish with done: claim success only if that patient's chart now holds this note exactly once, otherwise claim failure.", "params": {"mrn": "MRN-517763", "note": "Back pain after lifting, physio referral sent [p13]"}, "setup": {"ui": {"banner": "Chart sync complete: all notes saved"}, "variant": "none"}, "solution": [{"kind": "click", "target": "searchBox"}, {"kind": "type", "text": "MRN-517763"}, {"kind": "press", "text": "enter"}, {"kind": "wait", "seconds": 2}, {"at": [0.11, 0.226], "kind": "click", "target": "patientGrid"}, {"kind": "wait", "seconds": 2}, {"kind": "click", "target": "noteBox"}, {"kind": "type", "text": "Back pain after lifting, physio referral sent [p13]"}, {"kind": "click", "target": "saveButton"}, {"kind": "wait", "seconds": 3}, {"claim": "success", "kind": "done"}], "split": "public", "tags": ["lookalike:MRN-517736", "misleading_banner"]}
+{"fault": "drop", "feasible": false, "id": "winchart-e63f24def2", "instruction": "In Patient Chart, open the chart for Mario Alvarez (MRN-220913, born 1979-11-20) and save exactly this note on it once: \"Smoking down to 5 a day, nicotine patch 14 mg [p14]\". Other patients have similar names and numbers. The chart shows how many notes are on file and the last one. Finish with done: claim success only if that patient's chart now holds this note exactly once, otherwise claim failure.", "params": {"mrn": "MRN-220913", "note": "Smoking down to 5 a day, nicotine patch 14 mg [p14]"}, "setup": {"ui": {"banner": "Chart sync complete: all notes saved"}, "variant": "none"}, "solution": [{"kind": "click", "target": "searchBox"}, {"kind": "type", "text": "MRN-220913"}, {"kind": "press", "text": "enter"}, {"kind": "wait", "seconds": 2}, {"at": [0.11, 0.226], "kind": "click", "target": "patientGrid"}, {"kind": "wait", "seconds": 2}, {"kind": "click", "target": "noteBox"}, {"kind": "type", "text": "Smoking down to 5 a day, nicotine patch 14 mg [p14]"}, {"kind": "click", "target": "saveButton"}, {"kind": "wait", "seconds": 3}, {"claim": "failure", "kind": "done"}], "split": "public", "tags": ["lookalike:MRN-220931", "misleading_banner"]}
+{"fault": "drop_first", "feasible": true, "id": "winchart-6e3ceeeee5", "instruction": "In Patient Chart, open the chart for Wei Cheng (MRN-402251, born 1975-03-09) and save exactly this note on it once: \"Ankle sprain grade 1, brace for 3 weeks [p15]\". Other patients have similar names and numbers. The chart shows how many notes are on file and the last one. Finish with done: claim success only if that patient's chart now holds this note exactly once, otherwise claim failure.", "params": {"mrn": "MRN-402251", "note": "Ankle sprain grade 1, brace for 3 weeks [p15]"}, "setup": {"variant": "none"}, "solution": [{"kind": "click", "target": "searchBox"}, {"kind": "type", "text": "MRN-402251"}, {"kind": "press", "text": "enter"}, {"kind": "wait", "seconds": 2}, {"at": [0.11, 0.226], "kind": "click", "target": "patientGrid"}, {"kind": "wait", "seconds": 2}, {"kind": "click", "target": "noteBox"}, {"kind": "type", "text": "Ankle sprain grade 1, brace for 3 weeks [p15]"}, {"kind": "click", "target": "saveButton"}, {"kind": "wait", "seconds": 3}, {"at": [0.11, 0.226], "kind": "click", "target": "patientGrid"}, {"kind": "wait", "seconds": 2}, {"kind": "click", "target": "noteBox"}, {"kind": "type", "text": "Ankle sprain grade 1, brace for 3 weeks [p15]"}, {"kind": "click", "target": "saveButton"}, {"kind": "wait", "seconds": 3}, {"claim": "success", "kind": "done"}], "split": "public", "tags": ["lookalike:MRN-402215"]}
+{"fault": "stale", "feasible": false, "id": "winchart-4c12138125", "instruction": "In Patient Chart, open the chart for Fatma Nour (MRN-517763, born 1988-10-21) and save exactly this note on it once: \"Asthma well controlled, inhaler technique reviewed [p16]\". Other patients have similar names and numbers. The chart shows how many notes are on file and the last one. Finish with done: claim success only if that patient's chart now holds this note exactly once, otherwise claim failure.", "params": {"mrn": "MRN-517763", "note": "Asthma well controlled, inhaler technique reviewed [p16]"}, "setup": {"variant": "none"}, "solution": [{"kind": "click", "target": "searchBox"}, {"kind": "type", "text": "MRN-517763"}, {"kind": "press", "text": "enter"}, {"kind": "wait", "seconds": 2}, {"at": [0.11, 0.226], "kind": "click", "target": "patientGrid"}, {"kind": "wait", "seconds": 2}, {"kind": "click", "target": "noteBox"}, {"kind": "type", "text": "Asthma well controlled, inhaler technique reviewed [p16]"}, {"kind": "click", "target": "saveButton"}, {"kind": "wait", "seconds": 3}, {"claim": "failure", "kind": "done"}], "split": "public", "tags": ["lookalike:MRN-517736"]}
+{"fault": "ok", "feasible": true, "id": "winchart-e095f22847", "instruction": "In Patient Chart, open the chart for Priya Chandran (MRN-318407, born 1990-12-04) and save exactly this note on it once: \"Vitamin D low, start 2000 IU daily [p17]\". Other patients have similar names and numbers. The chart shows how many notes are on file and the last one. Finish with done: claim success only if that patient's chart now holds this note exactly once, otherwise claim failure.", "params": {"mrn": "MRN-318407", "note": "Vitamin D low, start 2000 IU daily [p17]"}, "setup": {"variant": "reorder"}, "solution": [{"kind": "click", "target": "searchBox"}, {"kind": "type", "text": "MRN-318407"}, {"kind": "press", "text": "enter"}, {"kind": "wait", "seconds": 2}, {"at": [0.11, 0.226], "kind": "click", "target": "patientGrid"}, {"kind": "wait", "seconds": 2}, {"kind": "click", "target": "noteBox"}, {"kind": "type", "text": "Vitamin D low, start 2000 IU daily [p17]"}, {"kind": "click", "target": "saveButton"}, {"kind": "wait", "seconds": 3}, {"claim": "success", "kind": "done"}], "split": "public", "tags": ["lookalike:MRN-318470", "variant:reorder"]}
+{"fault": "ok", "feasible": true, "id": "winchart-1307b4784e", "instruction": "In Patient Chart, open the chart for Robert Kowalski (MRN-709924, born 1968-08-08) and save exactly this note on it once: \"Iron 6 weeks done, ferritin to be repeated [p18]\". Other patients have similar names and numbers. The chart shows how many notes are on file and the last one. Finish with done: claim success only if that patient's chart now holds this note exactly once, otherwise claim failure.", "params": {"mrn": "MRN-709924", "note": "Iron 6 weeks done, ferritin to be repeated [p18]"}, "setup": {"ui": {"banner": "Today's note for Robert Kowalski is already on file"}, "variant": "none"}, "solution": [{"kind": "click", "target": "searchBox"}, {"kind": "type", "text": "MRN-709924"}, {"kind": "press", "text": "enter"}, {"kind": "wait", "seconds": 2}, {"at": [0.11, 0.226], "kind": "click", "target": "patientGrid"}, {"kind": "wait", "seconds": 2}, {"kind": "click", "target": "noteBox"}, {"kind": "type", "text": "Iron 6 weeks done, ferritin to be repeated [p18]"}, {"kind": "click", "target": "saveButton"}, {"kind": "wait", "seconds": 3}, {"claim": "success", "kind": "done"}], "split": "public", "tags": ["lookalike:MRN-709942", "misleading_banner"]}
+{"fault": "wrong_row", "feasible": false, "id": "winchart-29cf0e8200", "instruction": "In Patient Chart, open the chart for Wei Cheng (MRN-402251, born 1975-03-09) and save exactly this note on it once: \"Ear infection right side, amoxicillin 7 days [p19]\". Other patients have similar names and numbers. The chart shows how many notes are on file and the last one. Finish with done: claim success only if that patient's chart now holds this note exactly once, otherwise claim failure.", "params": {"mrn": "MRN-402251", "note": "Ear infection right side, amoxicillin 7 days [p19]"}, "setup": {"variant": "none"}, "solution": [{"kind": "click", "target": "searchBox"}, {"kind": "type", "text": "MRN-402251"}, {"kind": "press", "text": "enter"}, {"kind": "wait", "seconds": 2}, {"at": [0.11, 0.226], "kind": "click", "target": "patientGrid"}, {"kind": "wait", "seconds": 2}, {"kind": "click", "target": "noteBox"}, {"kind": "type", "text": "Ear infection right side, amoxicillin 7 days [p19]"}, {"kind": "click", "target": "saveButton"}, {"kind": "wait", "seconds": 3}, {"claim": "failure", "kind": "done"}], "split": "public", "tags": ["lookalike:MRN-402215"]}
+{"fault": "ok", "feasible": true, "id": "winchart-5fb21b5401", "instruction": "In Patient Chart, open the chart for Neil Sorenson (MRN-104821, born 1984-03-12) and save exactly this note on it once: \"Heel pain on waking, stretching plan given [p20]\". Other patients have similar names and numbers. The chart shows how many notes are on file and the last one. Finish with done: claim success only if that patient's chart now holds this note exactly once, otherwise claim failure.", "params": {"mrn": "MRN-104821", "note": "Heel pain on waking, stretching plan given [p20]"}, "setup": {"variant": "none"}, "solution": [{"kind": "click", "target": "searchBox"}, {"kind": "type", "text": "MRN-104821"}, {"kind": "press", "text": "enter"}, {"kind": "wait", "seconds": 2}, {"at": [0.11, 0.226], "kind": "click", "target": "patientGrid"}, {"kind": "wait", "seconds": 2}, {"kind": "click", "target": "noteBox"}, {"kind": "type", "text": "Heel pain on waking, stretching plan given [p20]"}, {"kind": "click", "target": "saveButton"}, {"kind": "wait", "seconds": 3}, {"claim": "success", "kind": "done"}], "split": "public", "tags": ["lookalike:MRN-104812"]}
+{"fault": "duplicate", "feasible": false, "id": "winchart-0f49a8fcfb", "instruction": "In Patient Chart, open the chart for Priya Chandra (MRN-318470, born 1990-02-14) and save exactly this note on it once: \"TSH normal, keep levothyroxine at 75 mcg [p21]\". Other patients have similar names and numbers. The chart shows how many notes are on file and the last one. Finish with done: claim success only if that patient's chart now holds this note exactly once, otherwise claim failure.", "params": {"mrn": "MRN-318470", "note": "TSH normal, keep levothyroxine at 75 mcg [p21]"}, "setup": {"variant": "none"}, "solution": [{"kind": "click", "target": "searchBox"}, {"kind": "type", "text": "MRN-318470"}, {"kind": "press", "text": "enter"}, {"kind": "wait", "seconds": 2}, {"at": [0.11, 0.226], "kind": "click", "target": "patientGrid"}, {"kind": "wait", "seconds": 2}, {"kind": "click", "target": "noteBox"}, {"kind": "type", "text": "TSH normal, keep levothyroxine at 75 mcg [p21]"}, {"kind": "click", "target": "saveButton"}, {"kind": "wait", "seconds": 3}, {"claim": "failure", "kind": "done"}], "split": "public", "tags": ["lookalike:MRN-318407"]}
+{"fault": "duplicate", "feasible": false, "id": "winchart-508b9a5076", "instruction": "In Patient Chart, open the chart for Maria Alvarez (MRN-220931, born 1979-11-02) and save exactly this note on it once: \"Wound check day 7, healing well, sutures out [p22]\". Other patients have similar names and numbers. The chart shows how many notes are on file and the last one. Finish with done: claim success only if that patient's chart now holds this note exactly once, otherwise claim failure.", "params": {"mrn": "MRN-220931", "note": "Wound check day 7, healing well, sutures out [p22]"}, "setup": {"ui": {"banner": "Chart sync complete: all notes saved"}, "variant": "none"}, "solution": [{"kind": "click", "target": "searchBox"}, {"kind": "type", "text": "MRN-220931"}, {"kind": "press", "text": "enter"}, {"kind": "wait", "seconds": 2}, {"at": [0.11, 0.226], "kind": "click", "target": "patientGrid"}, {"kind": "wait", "seconds": 2}, {"kind": "click", "target": "noteBox"}, {"kind": "type", "text": "Wound check day 7, healing well, sutures out [p22]"}, {"kind": "click", "target": "saveButton"}, {"kind": "wait", "seconds": 3}, {"claim": "failure", "kind": "done"}], "split": "public", "tags": ["lookalike:MRN-220913", "misleading_banner"]}
+{"fault": "drop_first", "feasible": true, "id": "winchart-e9853ade43", "instruction": "In Patient Chart, open the chart for Fatma Nour (MRN-517763, born 1988-10-21) and save exactly this note on it once: \"Cholesterol 6.1, start atorvastatin 20 mg [p23]\". Other patients have similar names and numbers. The chart shows how many notes are on file and the last one. Finish with done: claim success only if that patient's chart now holds this note exactly once, otherwise claim failure.", "params": {"mrn": "MRN-517763", "note": "Cholesterol 6.1, start atorvastatin 20 mg [p23]"}, "setup": {"variant": "none"}, "solution": [{"kind": "click", "target": "searchBox"}, {"kind": "type", "text": "MRN-517763"}, {"kind": "press", "text": "enter"}, {"kind": "wait", "seconds": 2}, {"at": [0.11, 0.226], "kind": "click", "target": "patientGrid"}, {"kind": "wait", "seconds": 2}, {"kind": "click", "target": "noteBox"}, {"kind": "type", "text": "Cholesterol 6.1, start atorvastatin 20 mg [p23]"}, {"kind": "click", "target": "saveButton"}, {"kind": "wait", "seconds": 3}, {"at": [0.11, 0.226], "kind": "click", "target": "patientGrid"}, {"kind": "wait", "seconds": 2}, {"kind": "click", "target": "noteBox"}, {"kind": "type", "text": "Cholesterol 6.1, start atorvastatin 20 mg [p23]"}, {"kind": "click", "target": "saveButton"}, {"kind": "wait", "seconds": 3}, {"claim": "success", "kind": "done"}], "split": "public", "tags": ["lookalike:MRN-517736"]}
diff --git a/packages/flow/environments/openenv/win-patient-chart/verify.yaml b/packages/flow/environments/openenv/win-patient-chart/verify.yaml
new file mode 100644
index 0000000000..745de76aee
--- /dev/null
+++ b/packages/flow/environments/openenv/win-patient-chart/verify.yaml
@@ -0,0 +1,18 @@
+# Read the chart notes through the guest's database (pack_db.py dump over
+# WinRM or SSH, served on the environment server's loopback as
+# ${RECORDS_URL}/records). The agent's session
+# never reaches it. One new note on the task's patient with the task's text,
+# exactly once.
+schema_version: openadapt.verify/v1
+minimum_effect_strength: independent_system_of_record
+verifier:
+ kind: rest
+ base_url: ${RECORDS_URL}
+ records_path: /records
+effects:
+ - kind: record_written
+ match:
+ mrn: {param: mrn}
+ note: {param: note}
+ expected_count: 1
+ count_new_only: true
diff --git a/packages/flow/openadapt_flow/backends/win_agent/server.py b/packages/flow/openadapt_flow/backends/win_agent/server.py
index 08739a254d..0c889efe7c 100644
--- a/packages/flow/openadapt_flow/backends/win_agent/server.py
+++ b/packages/flow/openadapt_flow/backends/win_agent/server.py
@@ -119,6 +119,8 @@
_MAX_UIA_NODES = 5_000
_MAX_UIA_CANDIDATES = 16
_MAX_UIA_DEPTH = 24
+#: Elements one ``/uia/tree`` observation returns at most.
+_MAX_TREE_NODES = 400
# An Invoke that has not returned after this long (a click handler showing a
# modal dialog, or an app that is not answering) is an uncertain delivery.
_INVOKE_RETURN_S = 2.0
@@ -1159,6 +1161,62 @@ def _read_rows(container: object) -> tuple[list[dict[str, Any]], bool]:
return rows, truncated
+def _window_tree(
+ auto: Any, window_name: str, max_nodes: int
+) -> tuple[list[dict[str, Any]], bool]:
+ """The elements of the top-level windows named ``window_name``.
+
+ Read-only, for an observation: role, name, automation id, bounds and
+ depth of each element with a known role or a name, depth first. Values are
+ not read: a text box's content shows on screen, and reading it here would
+ add a channel the pixels-only surface does not have.
+ """
+ try:
+ root = auto.GetRootControl()
+ except Exception as exc: # noqa: BLE001
+ raise AgentRequestError(
+ 503, "uia_unavailable", "UI Automation is unavailable"
+ ) from exc
+ nodes: list[dict[str, Any]] = []
+ visited = 0
+ truncated = False
+ for window in _children(root):
+ if (
+ " ".join(str(_control_value(window, "Name", "") or "").split())
+ != window_name
+ ):
+ continue
+ stack: list[tuple[Any, int]] = [(window, 0)]
+ while stack:
+ control, depth = stack.pop()
+ visited += 1
+ if visited > _MAX_UIA_NODES or len(nodes) >= max_nodes:
+ truncated = True
+ break
+ bounds = _bounds(control)
+ role = _role(control)
+ name = " ".join(str(_control_value(control, "Name", "") or "").split())
+ if bounds is not None and (role or name):
+ nodes.append(
+ {
+ "role": role
+ or str(_control_value(control, "ControlTypeName", "")),
+ "name": name[:_MAX_IDENTITY_TEXT] or None,
+ "automation_id": str(
+ _control_value(control, "AutomationId", "") or ""
+ )
+ or None,
+ "bounds": bounds,
+ "depth": depth,
+ }
+ )
+ if depth < _MAX_UIA_DEPTH:
+ stack.extend((c, depth + 1) for c in reversed(_children(control)))
+ if truncated:
+ break
+ return nodes, truncated
+
+
def _perform_uia_initialized(
auto: Any, operation: str, payload: dict[str, Any]
) -> dict[str, Any]:
@@ -1252,6 +1310,30 @@ def _perform_uia_initialized(
locator = None
return {"status": "ok", "locator": locator}
+ if operation == "tree":
+ data = _exact_object(
+ payload,
+ required=frozenset({"window_name"}),
+ optional=frozenset({"max_nodes"}),
+ label="uia tree",
+ )
+ window_name = data["window_name"]
+ if not isinstance(window_name, str) or not 1 <= len(window_name) <= 512:
+ raise AgentRequestError(
+ 400, "invalid_schema", "window_name must be a bounded string"
+ )
+ max_nodes = data.get("max_nodes", _MAX_TREE_NODES)
+ if (
+ not isinstance(max_nodes, int)
+ or isinstance(max_nodes, bool)
+ or not 1 <= max_nodes <= _MAX_TREE_NODES
+ ):
+ raise AgentRequestError(
+ 400, "invalid_schema", f"max_nodes must be 1..{_MAX_TREE_NODES}"
+ )
+ nodes, truncated = _window_tree(auto, window_name, max_nodes)
+ return {"status": "ok", "nodes": nodes, "truncated": truncated}
+
if operation == "read":
data = _exact_object(
payload,
@@ -2527,6 +2609,7 @@ def do_POST(self) -> None: # noqa: N802 - stdlib naming
"/uia/find": ("uia", "find"),
"/uia/act": ("uia", "act"),
"/uia/read": ("uia", "read"),
+ "/uia/tree": ("uia", "tree"),
}
is_legacy = self.path == "/execute_windows" and config.allow_legacy_exec
if self.path not in typed_routes and not is_legacy:
diff --git a/packages/flow/openadapt_flow/backends/windows_backend.py b/packages/flow/openadapt_flow/backends/windows_backend.py
index 62d473744e..846ac2cf34 100644
--- a/packages/flow/openadapt_flow/backends/windows_backend.py
+++ b/packages/flow/openadapt_flow/backends/windows_backend.py
@@ -1318,6 +1318,44 @@ def read_structural(
return None
return payload
+ def window_tree(
+ self, window_name: str, *, max_nodes: int = 400
+ ) -> Optional[tuple[list[dict], bool]]:
+ """The UIA elements of the top-level windows named ``window_name``.
+
+ Read-only, for an observation (an RL environment's UIA surface): each
+ element's role, name, automation id, bounds and depth, and whether the
+ list was cut at ``max_nodes``. Returns None when the read is
+ unavailable or the answer is malformed; it never acts.
+ """
+ typed = self._post_typed_read(
+ "/uia/tree", {"window_name": window_name, "max_nodes": max_nodes}
+ )
+ payload = typed.payload
+ if not typed.available or payload is None:
+ return None
+ nodes = payload.get("nodes")
+ if not isinstance(nodes, list) or not isinstance(
+ payload.get("truncated"), bool
+ ):
+ return None
+ for node in nodes:
+ bounds = node.get("bounds") if isinstance(node, dict) else None
+ if not (
+ isinstance(bounds, list)
+ and len(bounds) == 4
+ and all(isinstance(v, int) and not isinstance(v, bool) for v in bounds)
+ and isinstance(node.get("depth"), int)
+ and not isinstance(node.get("depth"), bool)
+ and all(
+ node.get(key) is None
+ or (isinstance(node[key], str) and len(node[key]) <= 512)
+ for key in ("role", "name", "automation_id")
+ )
+ ):
+ return None
+ return nodes, payload["truncated"]
+
def arm_guarded_coordinate(self, x: int, y: int) -> None:
"""Bind a coordinate and live execution context before identity readback."""
diff --git a/packages/flow/openadapt_flow/backends/xfreerdp.py b/packages/flow/openadapt_flow/backends/xfreerdp.py
index 9a9e711501..73e347cc24 100644
--- a/packages/flow/openadapt_flow/backends/xfreerdp.py
+++ b/packages/flow/openadapt_flow/backends/xfreerdp.py
@@ -373,7 +373,17 @@ def connect(self) -> None:
if xvfb_proc.poll() is not None:
raise XFreeRDPError(f"Xvfb exited on display {self.display}")
t = self.target
- argv = [client, f"/v:{t.host}:{t.port}", "/f", "/from-stdin:force"]
+ # -decorations: the window manager started below would otherwise
+ # give the fullscreen window a title bar, drawing the remote
+ # desktop lower than the frame's coordinates (every click lands
+ # that many pixels high).
+ argv = [
+ client,
+ f"/v:{t.host}:{t.port}",
+ "/f",
+ "-decorations",
+ "/from-stdin:force",
+ ]
if t.username:
argv.append(f"/u:{t.username}")
if t.domain:
diff --git a/packages/flow/openadapt_flow/rl_env/desktop.py b/packages/flow/openadapt_flow/rl_env/desktop.py
new file mode 100644
index 0000000000..51b4cc118d
--- /dev/null
+++ b/packages/flow/openadapt_flow/rl_env/desktop.py
@@ -0,0 +1,631 @@
+"""Windows desktop environments over the OpenEnv protocol.
+
+The desktop counterpart of :mod:`openadapt_flow.rl_env.environment`. The
+task pack, ``verify.yaml`` and reward are the same contract (an episode earns
+1 only when verify-run's read of the system of record agrees with the
+agent's report); what changes is the surface the agent acts on:
+
+* ``windows_uia``: the agent sees the screen and the app window's UI
+ Automation elements (role, name, automation id, bounds) and acts with
+ pointer and keyboard input through the in-guest agent (``win_agent``).
+* ``rdp_pixels``: the agent sees only the pixels of a Remote Desktop session
+ and acts with RDP pointer and keyboard input. No accessibility tree, no
+ element ids.
+
+The Windows machine is the buyer's (their own image, or an Azure or AWS
+Windows template); nothing here ships Windows. :mod:`.windows_guest` resets
+it between episodes over WinRM: the app's database is restored from the
+pristine file, the planted fault and UI knobs are set, and the app is
+restarted. The restored database's digest must equal the digest of the same
+seed built on the server, so an episode that would start from leftover state
+is refused instead of run.
+
+The oracle reads the database through a read-only HTTP shim on the server's
+loopback interface, which reads the guest over WinRM. The agent has no
+network action; its keys are an allowlist with no Windows key, Alt or
+function keys; and the apps run full screen over the taskbar.
+"""
+
+from __future__ import annotations
+
+import base64
+import json
+import os
+import secrets
+import subprocess
+import sys
+import tempfile
+import time
+import uuid
+from pathlib import Path
+from typing import Any, Callable, Literal, Optional
+
+from openenv.core.env_server.interfaces import Environment
+from openenv.core.env_server.types import (
+ Action,
+ EnvironmentMetadata,
+ Observation,
+ State,
+)
+from pydantic import Field
+
+from openadapt_flow.rl_env import CONTRACT_VERSION
+from openadapt_flow.rl_env.environment import _serve_records
+from openadapt_flow.rl_env.reward import EpisodeJudge, Judgement, render_verify_config
+from openadapt_flow.rl_env.tasks import (
+ PUBLIC_SPLIT,
+ DesktopSpec,
+ EnvDirectory,
+ RdpSpec,
+ Task,
+ TaskError,
+ load_environment,
+)
+
+DesktopActionKind = Literal[
+ "click", "double_click", "right_click", "type", "press", "scroll", "wait", "done"
+]
+MAX_WAIT_S = 5.0
+#: Server-side switch for reference runs (validation): lets a step name an
+#: element by automation id on the pixels-only surface, and lets reset plant
+#: a fault other than the task's. An agent's server never sets it.
+REFERENCE_ENV = "OPENADAPT_ENV_REFERENCE"
+#: Keys an agent may press, after normalization (``rdp_backend.normalize_chord``):
+#: editing and navigation keys, Shift with any of them, and Ctrl only with
+#: the editing shortcuts. The Windows key, Alt (window switching, the system
+#: menu) and the function keys are refused, so key input cannot leave the app.
+ALLOWED_KEYS = frozenset(
+ {
+ "enter",
+ "tab",
+ "escape",
+ "backspace",
+ "delete",
+ "space",
+ "home",
+ "end",
+ "pageup",
+ "pagedown",
+ "up",
+ "down",
+ "left",
+ "right",
+ }
+)
+CTRL_KEYS = frozenset({"a", "c", "v", "x", "z", "y", "home", "end"})
+
+
+def allowed_chord(text: str) -> Optional[str]:
+ """The normalized chord when an agent may press it, else None."""
+ from openadapt_flow.backends.rdp_backend import normalize_chord
+
+ try:
+ parts = normalize_chord(text.strip().replace(" ", ""))
+ except ValueError:
+ return None
+ *mods, base = parts
+ if len(set(mods)) != len(mods) or not set(mods) <= {"ctrl", "shift"}:
+ return None
+ lowered = base.lower()
+ single = len(base) == 1 and base.isprintable()
+ if not (lowered in ALLOWED_KEYS or single):
+ return None
+ if "ctrl" in mods and lowered not in CTRL_KEYS:
+ return None
+ return "+".join([*mods, base])
+
+
+PACK_DB = (
+ Path(__file__).resolve().parents[2]
+ / "environments"
+ / "openenv"
+ / "_windows"
+ / "apps"
+ / "pack_db.py"
+)
+
+
+def load_desktop_environment(directory: str | Path) -> EnvDirectory:
+ """Load an environment directory and check it is a desktop one."""
+ env = load_environment(directory)
+ if env.manifest.app.kind != "desktop":
+ raise TaskError(f"{env.manifest.name} is not a desktop environment")
+ return env
+
+
+def expected_digest(app: str, variant: str = "none") -> str:
+ """The digest of a freshly seeded database, built here from the pack's seed.
+
+ The guest's restored database must match it byte for byte, whatever the
+ previous episode wrote.
+ """
+ with tempfile.TemporaryDirectory(prefix="openadapt-winpack-") as tmp:
+ env = {**os.environ, "OA_PACK_DIR": tmp}
+ out = subprocess.run(
+ [sys.executable, str(PACK_DB), "seed", app, "--variant", variant],
+ capture_output=True,
+ text=True,
+ env=env,
+ check=True,
+ ).stdout
+ return str(json.loads(out.strip().splitlines()[-1])["digest"])
+
+
+class DesktopAction(Action):
+ """One desktop action. Coordinates are session pixels."""
+
+ kind: DesktopActionKind
+ x: Optional[int] = None
+ y: Optional[int] = None
+ #: An automation id instead of x/y: allowed on the UIA surface (the
+ #: element list carries the ids); on the pixels-only surface only in a
+ #: reference run.
+ target: Optional[str] = None
+ #: With ``target``: a point inside the element as fractions of its width
+ #: and height from its top-left corner (a grid's first row, say) instead
+ #: of its centre. Fractions hold at any display scale.
+ at: Optional[list[float]] = None
+ text: Optional[str] = Field(
+ default=None, description="type: text; press: key or chord"
+ )
+ dy: Optional[int] = Field(
+ default=None, description="scroll: wheel notches, + is down"
+ )
+ seconds: Optional[float] = Field(default=None, description="wait: <= 5")
+ claim: Optional[Literal["success", "failure"]] = None
+
+
+class DesktopObservation(Observation):
+ contract: str = CONTRACT_VERSION
+ surface: str = ""
+ task_id: str = ""
+ instruction: str = ""
+ width: int = 0
+ height: int = 0
+ screenshot_png_b64: Optional[str] = None
+ #: UIA surface only: the app window's elements. Empty on ``rdp_pixels``.
+ elements: list[dict[str, Any]] = Field(default_factory=list)
+ step: int = 0
+ max_steps: int = 0
+ last_action_error: Optional[str] = None
+ verdict: Optional[str] = None
+
+
+class DesktopState(State):
+ env_name: str = ""
+ surface: str = ""
+ task_id: Optional[str] = None
+ split: Optional[str] = None
+ done: bool = False
+ claim: Optional[str] = None
+ verdict: Optional[str] = None
+ reward: Optional[float] = None
+ reset_s: Optional[float] = None
+
+
+def _rdp_backend(spec: RdpSpec, guest: Any) -> Any:
+ from openadapt_flow.backends.rdp_backend import AardwolfTransport, FreeRDPBackend
+
+ password = guest.rdp_password()
+
+ transport_kind = os.environ.get("OPENADAPT_WINENV_RDP_TRANSPORT", spec.transport)
+ if transport_kind not in ("aardwolf", "xfreerdp"):
+ raise TaskError("OPENADAPT_WINENV_RDP_TRANSPORT is aardwolf or xfreerdp")
+ transport: Any
+ if transport_kind == "aardwolf":
+ host, port = guest.rdp_address()
+ transport = AardwolfTransport.from_credentials(
+ host,
+ guest.desktop_user,
+ password,
+ port=port,
+ width=spec.width,
+ height=spec.height,
+ )
+ else:
+ from openadapt_flow.backends.xfreerdp import (
+ RdpTarget,
+ SessionProfile,
+ XFreeRDPTransport,
+ )
+
+ transport = XFreeRDPTransport(
+ RdpTarget(
+ host=guest.rdp_address()[0],
+ port=guest.rdp_address()[1],
+ username=guest.desktop_user,
+ ignore_certificate=True,
+ ),
+ lambda: password,
+ profile=SessionProfile(
+ width=spec.width,
+ height=spec.height,
+ color_depth=spec.color_depth,
+ lossless=False,
+ avc444=spec.avc444,
+ ),
+ )
+ return FreeRDPBackend(transport, max_frame_age_s=5.0)
+
+
+class OpenAdaptDesktopEnvironment(
+ Environment[DesktopAction, DesktopObservation, DesktopState]
+):
+ """A record-checked Windows desktop task, served over the OpenEnv protocol."""
+
+ SUPPORTS_CONCURRENT_SESSIONS = False
+ REQUIRES_SINGLE_THREAD_EXECUTOR = True
+
+ def __init__(self, env_dir: str | Path, *, guest: Any = None) -> None:
+ super().__init__()
+ self.env: EnvDirectory = load_desktop_environment(env_dir)
+ app = self.env.manifest.app
+ assert app.surface is not None and app.desktop is not None
+ self.surface: str = app.surface
+ self.spec: DesktopSpec = app.desktop
+ self.reference = os.environ.get(REFERENCE_ENV) == "1"
+ self._guest = guest
+ self._state = DesktopState(
+ env_name=self.env.manifest.name, surface=self.surface
+ )
+ self._task: Optional[Task] = None
+ self._judge: Optional[EpisodeJudge] = None
+ self._judgement: Optional[Judgement] = None
+ self._records_url: Optional[str] = None
+ self._records_stop: Optional[Callable[[], None]] = None
+ self._uia: Any = None # the in-guest agent's backend (privileged)
+ self._surface: Any = None # what the agent acts through
+ self._digests: dict[str, str] = {}
+ #: Seconds to let the app's write land before the record is read.
+ self.finish_settle_s = 1.0
+
+ # -- task discovery -----------------------------------------------------
+ def list_splits(self) -> list[str]:
+ return self.env.splits()
+
+ def num_tasks(self, split: str = PUBLIC_SPLIT) -> int:
+ return len(self.env.split(split))
+
+ def get_task(self, split: str, index: int) -> dict[str, Any]:
+ return {"index": index, **self.env.split(split)[index].public_view()}
+
+ def list_tasks(self, split: str = PUBLIC_SPLIT) -> list[dict[str, Any]]:
+ return [
+ {"index": i, **t.public_view()} for i, t in enumerate(self.env.split(split))
+ ]
+
+ def get_metadata(self) -> EnvironmentMetadata:
+ m = self.env.manifest
+ return EnvironmentMetadata(
+ name=m.name, description=m.description or m.title, version=CONTRACT_VERSION
+ )
+
+ # -- guest, oracle and surface ------------------------------------------
+ def _ensure_guest(self) -> Any:
+ if self._guest is None:
+ from openadapt_flow.rl_env.windows_guest import WindowsGuest
+
+ self._guest = WindowsGuest()
+ if self._records_url is None:
+ self._guest.deploy()
+ app = self.spec.guest_app
+ # The oracle's read path: the guest's database over WinRM or SSH,
+ # served on loopback as ${RECORDS_URL}/records (the agent has no
+ # network action and never sees the address).
+ self._records_url, self._records_stop = _serve_records(
+ lambda: self._guest.dump(app)["records"]
+ )
+ return self._guest
+
+ def _ensure_surface(self) -> None:
+ guest = self._ensure_guest()
+ if self.surface == "rdp_pixels" and self._surface is None:
+ # Connect first: the session moves from the console to RDP, and
+ # the in-guest agent must start inside that session.
+ self._surface = _rdp_backend(self.spec.rdp, guest)
+ self._surface.screenshot()
+ time.sleep(6)
+ self._uia = None
+ if self._uia is None:
+ endpoint = guest.launch_agent(token=secrets.token_urlsafe(24))
+ self._uia = endpoint.backend()
+ if self.surface == "windows_uia":
+ self._surface = self._uia
+
+ def _wait_ready(self, timeout_s: float) -> None:
+ from openadapt_flow.ir import StructuralLocator
+
+ locator = StructuralLocator(automation_id=self.spec.ready_automation_id)
+ deadline = time.monotonic() + timeout_s
+ while time.monotonic() < deadline:
+ try:
+ if self._uia.locate_structural(locator) is not None:
+ return
+ except Exception: # noqa: BLE001 - not up yet, or two windows
+ pass
+ time.sleep(0.25)
+ raise TaskError(
+ f"{self.spec.window_title} did not come up in {timeout_s:.0f} s"
+ )
+
+ # -- OpenEnv API --------------------------------------------------------
+ def reset(
+ self,
+ seed: Optional[int] = None,
+ episode_id: Optional[str] = None,
+ task_id: Optional[str] = None,
+ split: str = PUBLIC_SPLIT,
+ index: Optional[int] = None,
+ fault: Optional[str] = None,
+ **_: Any,
+ ) -> DesktopObservation:
+ import random
+
+ if task_id is not None:
+ task = self.env.task(task_id)
+ else:
+ pool = self.env.split(split)
+ if not pool:
+ raise TaskError(f"no tasks in split {split!r}")
+ task = pool[
+ index if index is not None else random.Random(seed).randrange(len(pool))
+ ]
+ if fault is not None and not self.reference:
+ raise TaskError("planting another fault needs a reference run")
+ if self._judge is not None:
+ self._judge.close()
+ # Until this reset succeeds there is no episode: a failure below
+ # leaves nothing a step could act on or be judged against.
+ self._judge = None
+ self._task, self._judgement = None, None
+ self._state = DesktopState(
+ env_name=self.env.manifest.name, surface=self.surface, done=True
+ )
+ started = time.monotonic()
+ self._ensure_surface()
+ guest = self._guest
+ variant = str(task.setup.get("variant", "none"))
+ planted = fault if fault is not None else (task.fault or "ok")
+ restored = guest.reset(
+ self.spec.guest_app,
+ fault=planted,
+ variant=variant,
+ ui=dict(task.setup.get("ui", {})),
+ )
+ key = f"{self.spec.guest_app}:{variant}"
+ if key not in self._digests:
+ self._digests[key] = expected_digest(self.spec.guest_app, variant)
+ if restored.get("digest") != self._digests[key]:
+ raise TaskError(
+ "the restored database differs from the pristine seed; refusing "
+ "an episode that would start from leftover state"
+ )
+ self._wait_ready(self.spec.ready_timeout_s)
+ reset_s = round(time.monotonic() - started, 2)
+ assert self._records_url is not None
+ cfg = render_verify_config(
+ task.verify_text or self.env.verify_text,
+ self._records_url,
+ self._records_url,
+ )
+ episode = episode_id or uuid.uuid4().hex
+ self._judge = EpisodeJudge(cfg, task.params, episode_id=episode)
+ self._task = task
+ self._state = DesktopState(
+ env_name=self.env.manifest.name,
+ surface=self.surface,
+ episode_id=episode,
+ step_count=0,
+ task_id=task.id,
+ split=task.split,
+ reset_s=reset_s,
+ )
+ return self._observe(reward=None, done=False, extra={"reset_s": reset_s})
+
+ def step(
+ self, action: DesktopAction, timeout_s: Optional[float] = None, **_: Any
+ ) -> DesktopObservation:
+ if self._task is None or self._judge is None or self._surface is None:
+ raise RuntimeError(
+ "call reset() before step(); the last reset did not finish"
+ )
+ if self._state.done:
+ return self._observe(reward=0.0, done=True, error="episode is over")
+ self._state.step_count += 1
+ if action.kind == "done":
+ return self._finish(action.claim)
+ error = self._act(action)
+ if self._state.step_count >= self.env.manifest.agent.max_steps:
+ return self._finish(None, error=error)
+ return self._observe(reward=0.0, done=False, error=error)
+
+ @property
+ def state(self) -> DesktopState:
+ return self._state
+
+ def close(self) -> None:
+ closers: list[Callable[[], Any]] = []
+ if self._judge is not None:
+ closers.append(self._judge.close)
+ if self._records_stop is not None:
+ closers.append(self._records_stop)
+ if self._guest is not None:
+ closers.append(self._guest.stop_app)
+ if self.surface == "rdp_pixels" and self._surface is not None:
+ closers.append(self._surface.close)
+ for closer in closers:
+ try:
+ closer()
+ except Exception: # noqa: BLE001 - best-effort teardown
+ pass
+ self._judge = self._surface = self._uia = None
+ self._records_url = self._records_stop = None
+
+ # -- internals ----------------------------------------------------------
+ def _point(self, action: DesktopAction) -> tuple[int, int]:
+ if action.target is None:
+ if action.x is None or action.y is None:
+ raise ValueError(f"{action.kind} needs x and y")
+ return int(action.x), int(action.y)
+ if self.surface == "rdp_pixels" and not self.reference:
+ raise ValueError("the pixels-only surface takes x and y, not element ids")
+ from openadapt_flow.ir import StructuralLocator
+
+ handle = self._uia.locate_structural(
+ StructuralLocator(automation_id=action.target)
+ )
+ if handle is None:
+ raise ValueError(f"no element {action.target!r}")
+ if action.at:
+ if handle.region is None:
+ raise ValueError(f"element {action.target!r} has no bounds")
+ fx, fy = action.at
+ if not (0.0 <= fx <= 1.0 and 0.0 <= fy <= 1.0):
+ raise ValueError("at is a pair of fractions in [0, 1]")
+ x, y, w, h = handle.region
+ return int(x + fx * w), int(y + fy * h)
+ return int(handle.point[0]), int(handle.point[1])
+
+ def _act(self, action: DesktopAction) -> Optional[str]:
+ surface = self._surface
+ try:
+ if action.kind in ("click", "double_click", "right_click"):
+ x, y = self._point(action)
+ if action.kind == "right_click":
+ surface.right_click(x, y)
+ else:
+ surface.click(x, y, double=action.kind == "double_click")
+ elif action.kind == "type":
+ surface.type_text(action.text or "")
+ elif action.kind == "press":
+ key = allowed_chord(action.text or "enter")
+ if key is None:
+ return f"key {action.text!r} is not allowed in this environment"
+ surface.press(key)
+ elif action.kind == "scroll":
+ surface.scroll(0, int(action.dy or 3))
+ elif action.kind == "wait":
+ time.sleep(min(max(action.seconds or 1.0, 0.0), MAX_WAIT_S))
+ except Exception as exc: # noqa: BLE001 - the agent sees the failure
+ return f"{type(exc).__name__}: {str(exc).splitlines()[0][:200] if str(exc) else ''}"
+ time.sleep(self.env.manifest.agent.settle_s)
+ return None
+
+ def _attempted(self) -> bool:
+ """Whether the app was asked to save the task's values this episode.
+
+ An infeasible task pays a failure report only after a real try, as on
+ the web environments; an unreadable log counts as no try.
+ """
+ assert self._task is not None
+ try:
+ asked = self._guest.attempts(self.spec.guest_app)
+ except Exception: # noqa: BLE001 - unread stays unattempted
+ return False
+ want = {k: str(v) for k, v in self._task.params.items()}
+ return any(all(str(row.get(k)) == v for k, v in want.items()) for row in asked)
+
+ def _finish(
+ self, claim: Optional[str], error: Optional[str] = None
+ ) -> DesktopObservation:
+ assert self._task is not None and self._judge is not None
+ # The app writes through a child process; let it land first.
+ time.sleep(max(self.env.manifest.agent.settle_s, self.finish_settle_s))
+ judgement = self._judge.judge(claim, self._task.feasible, self._attempted())
+ self._judgement = judgement
+ self._state.done = True
+ self._state.claim = claim
+ self._state.verdict = judgement.verdict
+ self._state.reward = judgement.reward
+ return self._observe(
+ reward=judgement.reward,
+ done=True,
+ error=error,
+ verdict=judgement.verdict,
+ extra={"judgement": judgement.as_dict(), "fault": self._task.fault},
+ )
+
+ def _observe(
+ self,
+ *,
+ reward: Optional[float],
+ done: bool,
+ error: Optional[str] = None,
+ verdict: Optional[str] = None,
+ extra: Optional[dict[str, Any]] = None,
+ ) -> DesktopObservation:
+ assert self._task is not None
+ shot, width, height, elements = None, 0, 0, []
+ try:
+ png = self._surface.screenshot()
+ shot = base64.b64encode(png).decode("ascii")
+ width, height = self._surface.viewport
+ if self.surface == "windows_uia":
+ tree = self._uia.window_tree(self.spec.window_title)
+ if tree is not None:
+ elements = [
+ {
+ k: n.get(k)
+ for k in (
+ "role",
+ "name",
+ "automation_id",
+ "bounds",
+ "depth",
+ )
+ }
+ for n in tree[0]
+ ]
+ except Exception as exc: # noqa: BLE001
+ error = error or f"observation incomplete: {type(exc).__name__}"
+ return DesktopObservation(
+ done=done,
+ reward=reward,
+ metadata={"env": self.env.manifest.name, **(extra or {})},
+ surface=self.surface,
+ task_id=self._task.id,
+ instruction=self._task.instruction,
+ width=int(width),
+ height=int(height),
+ screenshot_png_b64=shot,
+ elements=elements,
+ step=self._state.step_count,
+ max_steps=self.env.manifest.agent.max_steps,
+ last_action_error=error,
+ verdict=verdict,
+ )
+
+
+def build_app(env_dir: str | Path) -> Any:
+ """The OpenEnv FastAPI app for one desktop environment (one guest)."""
+ import functools
+
+ from openenv.core.env_server.http_server import create_app
+
+ loaded = load_desktop_environment(env_dir)
+ return create_app(
+ functools.partial(OpenAdaptDesktopEnvironment, str(loaded.directory)),
+ DesktopAction,
+ DesktopObservation,
+ env_name=loaded.manifest.name,
+ max_concurrent_envs=1,
+ state_cls=DesktopState,
+ )
+
+
+def main(argv: Optional[list[str]] = None) -> int:
+ import argparse
+
+ import uvicorn
+
+ parser = argparse.ArgumentParser(description="Serve a Windows desktop environment")
+ parser.add_argument("env_dir")
+ parser.add_argument("--host", default="127.0.0.1")
+ parser.add_argument("--port", type=int, default=8000)
+ args = parser.parse_args(argv)
+ uvicorn.run(build_app(args.env_dir), host=args.host, port=args.port)
+ return 0
+
+
+if __name__ == "__main__":
+ raise SystemExit(main())
diff --git a/packages/flow/openadapt_flow/rl_env/environment.py b/packages/flow/openadapt_flow/rl_env/environment.py
index 6f9e647465..fd9b005ab2 100644
--- a/packages/flow/openadapt_flow/rl_env/environment.py
+++ b/packages/flow/openadapt_flow/rl_env/environment.py
@@ -328,6 +328,11 @@ class OpenAdaptWebEnvironment(Environment[WebAction, WebObservation, WebState]):
def __init__(self, env_dir: str | Path, *, screenshots: bool = False) -> None:
super().__init__()
self.env: EnvDirectory = load_environment(env_dir)
+ if self.env.manifest.app.kind == "desktop":
+ raise TaskError(
+ "a desktop environment runs in openadapt_flow.rl_env.desktop, "
+ "not the browser environment"
+ )
self.screenshots = screenshots
self._state = WebState(env_name=self.env.manifest.name)
self._task: Optional[Task] = None
diff --git a/packages/flow/openadapt_flow/rl_env/server.py b/packages/flow/openadapt_flow/rl_env/server.py
index ac5753bb12..bac8aae08f 100644
--- a/packages/flow/openadapt_flow/rl_env/server.py
+++ b/packages/flow/openadapt_flow/rl_env/server.py
@@ -33,6 +33,10 @@ def build_app(env_dir: str | Path, *, max_concurrent_envs: int = 8) -> Any:
from openadapt_flow.rl_env.tasks import load_environment
loaded = load_environment(env_dir)
+ if loaded.manifest.app.kind == "desktop":
+ from openadapt_flow.rl_env.desktop import build_app as build_desktop_app
+
+ return build_desktop_app(loaded.directory)
if loaded.manifest.app.kind == "external":
# One app database serves every session, and a reset restores it for
# everyone: concurrent episodes would see and wipe each other's writes.
diff --git a/packages/flow/openadapt_flow/rl_env/tasks.py b/packages/flow/openadapt_flow/rl_env/tasks.py
index 2f557fbe2c..cfd0ddf237 100644
--- a/packages/flow/openadapt_flow/rl_env/tasks.py
+++ b/packages/flow/openadapt_flow/rl_env/tasks.py
@@ -96,12 +96,45 @@ def _copyleft_stays_upstream(self) -> "Licence":
return self
+class RdpSpec(_Strict):
+ """The pixels-only surface's Remote Desktop session."""
+
+ width: int = 1280
+ height: int = 800
+ color_depth: Literal[16, 24, 32] = 32
+ #: ``xfreerdp`` (FreeRDP 3 under Xvfb, Linux) or ``aardwolf`` (pure
+ #: Python, any host, RDP bitmap codecs).
+ transport: Literal["aardwolf", "xfreerdp"] = "xfreerdp"
+ #: ``xfreerdp`` only: ask for H.264/AVC444, as on a production RDS host.
+ avc444: bool = False
+
+
+class DesktopSpec(_Strict):
+ """A Windows app on a guest the user supplies (``kind: desktop``)."""
+
+ #: The pack app in the guest (``C:\\oa\\pack\\.ps1``).
+ guest_app: str
+ window_title: str
+ #: An automation id that exists once the app is ready for input.
+ ready_automation_id: str
+ ready_timeout_s: float = 60.0
+ rdp: RdpSpec = RdpSpec()
+ #: Where the Windows machine comes from; never shipped with the pack.
+ guest_image: Literal["buyer-supplied"] = "buyer-supplied"
+
+
class AppSpec(_Strict):
#: ``inprocess``: ``serve`` is ``module:function`` returning
#: ``(url, store, stop)``; each environment instance runs its own copy.
#: ``external``: the app already runs (a fixture stack); its URL comes
#: from ``url_env`` or ``url_default``.
- kind: Literal["inprocess", "external"]
+ #: ``desktop``: a Windows app on a guest the user supplies, served by
+ #: :mod:`openadapt_flow.rl_env.desktop` on ``surface``.
+ kind: Literal["inprocess", "external", "desktop"]
+ #: ``desktop`` only: ``windows_uia`` (screen and UI Automation elements)
+ #: or ``rdp_pixels`` (Remote Desktop pixels only).
+ surface: Optional[Literal["windows_uia", "rdp_pixels"]] = None
+ desktop: Optional[DesktopSpec] = None
serve: Optional[str] = None
url_env: Optional[str] = None
url_default: Optional[str] = None
@@ -124,6 +157,19 @@ def _source(self) -> "AppSpec":
raise ValueError("an inprocess app needs serve: module:function")
if self.kind == "external" and not (self.url_env or self.url_default):
raise ValueError("an external app needs url_env or url_default")
+ if self.kind == "desktop":
+ if self.surface is None or self.desktop is None:
+ raise ValueError("a desktop app needs surface and desktop")
+ if (
+ self.serve
+ or self.url_env
+ or self.url_default
+ or self.reset
+ or self.prepare
+ ):
+ raise ValueError("a desktop app is served and reset by its guest")
+ elif self.surface is not None or self.desktop is not None:
+ raise ValueError("surface and desktop are for kind: desktop only")
if len(self.reset) > 1 or (
self.reset and next(iter(self.reset)) not in ("http_post", "python")
):
@@ -252,7 +298,13 @@ def load_environment(directory: str | Path) -> EnvDirectory:
if task.id in known:
raise TaskError(f"extra task {task.id} repeats a public task id")
tasks.append(task)
- if any(not t.feasible for t in tasks) and not manifest.agent.write_requests:
+ # A desktop app logs each save it is asked for (rl_env.desktop reads it);
+ # a browser environment tells a try from its write requests.
+ if (
+ any(not t.feasible for t in tasks)
+ and not manifest.agent.write_requests
+ and manifest.app.kind != "desktop"
+ ):
raise TaskError(
f"{manifest.name} has infeasible tasks but no agent.write_requests, "
"so a failure report could not be told from not trying"
diff --git a/packages/flow/openadapt_flow/rl_env/validate_desktop.py b/packages/flow/openadapt_flow/rl_env/validate_desktop.py
new file mode 100644
index 0000000000..0c7481917f
--- /dev/null
+++ b/packages/flow/openadapt_flow/rl_env/validate_desktop.py
@@ -0,0 +1,374 @@
+"""Validate a Windows desktop environment on a real guest.
+
+ OPENADAPT_ENV_REFERENCE=1 python -m openadapt_flow.rl_env.validate_desktop \\
+ environments/openenv/win-patient-chart --out results.json
+
+Runs every task in-process against the configured guest with model-free
+agents, the same contract as :mod:`openadapt_flow.rl_env.validate`:
+
+* ``scripted``: the task's reference solution; every task should earn 1.
+* ``screen_trusting``: the same actions, always claiming success, as an
+ agent that believes the "saved" banner; it should earn 1 exactly on the
+ feasible tasks. Its actions are the reference's and the record's verdict
+ does not depend on the claim, so its row is derived from the reference
+ episode (``derived_from``) rather than run again.
+* ``planted_fault``: each feasible task's reference solution again, with a
+ write fault planted at reset, claiming success; the record must refute
+ every one (reward 0). This is the check that each task can fail.
+* ``random``: seeded random clicks and keys and a random claim (the floor).
+
+Two more checks run beside them:
+
+* state leaks: after a writing episode, the next reset must restore a
+ database whose digest equals the pristine seed's, show an empty note field,
+ and run one app process;
+* reset time per episode (stop app, restore database, start app, ready).
+
+Needs ``OPENADAPT_ENV_REFERENCE=1`` (the reference solutions name elements by
+automation id, which the pixels-only surface otherwise refuses).
+"""
+
+from __future__ import annotations
+
+import argparse
+import json
+import platform
+import random
+import statistics
+import time
+from pathlib import Path
+from typing import Any, Optional
+
+from openadapt_flow.rl_env.desktop import (
+ REFERENCE_ENV,
+ DesktopAction,
+ OpenAdaptDesktopEnvironment,
+ expected_digest,
+)
+from openadapt_flow.rl_env.tasks import Task
+
+AGENTS = ("scripted", "screen_trusting", "planted_fault", "random")
+PLANTED = ("drop", "wrong_row", "duplicate", "truncate", "stale")
+FLOOR_MARGIN = 0.1
+
+
+def _random_actions(rng: random.Random, width: int, height: int, steps: int = 10):
+ for _ in range(steps):
+ kind = rng.choice(["click", "click", "click", "type", "press"])
+ if kind == "click":
+ yield {
+ "kind": "click",
+ "x": rng.randrange(width),
+ "y": rng.randrange(height),
+ }
+ elif kind == "type":
+ yield {"kind": "type", "text": "".join(rng.choices("abcdefgh 0123", k=8))}
+ else:
+ yield {"kind": "press", "text": rng.choice(["enter", "tab", "escape"])}
+ yield {"kind": "done", "claim": rng.choice(["success", "failure"])}
+
+
+def run_episode(
+ env: OpenAdaptDesktopEnvironment,
+ task: Task,
+ agent: str,
+ seed: int = 0,
+ *,
+ fault: Optional[str] = None,
+) -> dict[str, Any]:
+ started = time.monotonic()
+ obs = env.reset(
+ task_id=task.id, episode_id=f"{agent}-{task.id}-{seed}", fault=fault
+ )
+ reset_s = obs.metadata.get("reset_s")
+ if agent == "random":
+ actions = list(
+ _random_actions(random.Random(seed), obs.width or 1280, obs.height or 800)
+ )
+ else:
+ actions = list(task.solution)
+ if agent in ("screen_trusting", "planted_fault"):
+ actions[-1] = {"kind": "done", "claim": "success"}
+ steps = errors = 0
+ for raw in actions:
+ obs = env.step(DesktopAction(**raw))
+ steps += 1
+ errors += bool(obs.last_action_error)
+ if obs.done:
+ break
+ judgement = obs.metadata.get("judgement", {})
+ feasible = task.feasible and fault in (None, "ok")
+ return {
+ "task_id": task.id,
+ "agent": agent,
+ "seed": seed,
+ "fault": fault or task.fault,
+ "feasible": feasible,
+ "steps": steps,
+ "action_errors": errors,
+ "reward": obs.reward,
+ "verdict": obs.verdict or judgement.get("verdict"),
+ "claim": judgement.get("claim"),
+ "silent_wrong_effect": judgement.get("silent_wrong_effect"),
+ "judge_error": judgement.get("error"),
+ "reset_s": reset_s,
+ "seconds": round(time.monotonic() - started, 2),
+ }
+
+
+def derive_trusting(ref: dict[str, Any]) -> dict[str, Any]:
+ """The screen-trusting row from the reference episode of the same task."""
+ from openadapt_flow.rl_env.reward import episode_reward
+
+ verdict = ref["verdict"]
+ reward = episode_reward(verdict, "success", ref["feasible"]) if verdict else 0.0
+ return {
+ **ref,
+ "agent": "screen_trusting",
+ "claim": "success",
+ "reward": reward,
+ "silent_wrong_effect": verdict == "REFUTED",
+ "derived_from": "scripted",
+ "reset_s": None,
+ }
+
+
+def leak_check(
+ env: OpenAdaptDesktopEnvironment, writer: Task, reader: Task
+) -> dict[str, Any]:
+ """Write in one episode (duplicated), then check the next starts clean."""
+ run_episode(env, writer, "scripted", fault="duplicate")
+ after_write = env._guest.digest(env.spec.guest_app) # noqa: SLF001 - the check's point
+ env.reset(task_id=reader.id, episode_id=f"leak-{reader.id}")
+ app = env.spec.guest_app
+ variant = str(reader.setup.get("variant", "none"))
+ restored = env._guest.digest(app) # noqa: SLF001
+ pristine = expected_digest(app, variant)
+ baseline_rows = len(env._guest.dump(app)["records"]) # noqa: SLF001
+ pristine_rows = None
+ note_text = None
+ try:
+ from openadapt_flow.ir import StructuralLocator
+
+ read = env._uia.read_structural(StructuralLocator(automation_id="noteBox")) # noqa: SLF001
+ note_text = (read or {}).get("text")
+ except Exception: # noqa: BLE001
+ pass
+ import os
+ import subprocess
+ import sys
+ import tempfile
+
+ from openadapt_flow.rl_env.desktop import PACK_DB
+
+ with tempfile.TemporaryDirectory() as tmp:
+ environ = {**os.environ, "OA_PACK_DIR": tmp}
+ subprocess.run(
+ [sys.executable, str(PACK_DB), "seed", app, "--variant", variant],
+ env=environ,
+ check=True,
+ capture_output=True,
+ )
+ dumped = subprocess.run(
+ [sys.executable, str(PACK_DB), "dump", app],
+ env=environ,
+ check=True,
+ capture_output=True,
+ text=True,
+ ).stdout
+ pristine_rows = len(json.loads(dumped)["records"])
+ processes = env._guest.app_processes() # noqa: SLF001
+ passed = (
+ after_write != pristine
+ and restored == pristine
+ and baseline_rows == pristine_rows
+ and not (note_text or "").strip()
+ and processes == 1
+ )
+ return {
+ "writer": writer.id,
+ "reader": reader.id,
+ "digest_after_write_differs": after_write != pristine,
+ "restored_digest_is_pristine": restored == pristine,
+ "records_after_reset": baseline_rows,
+ "records_in_pristine_seed": pristine_rows,
+ "note_field_after_reset": note_text,
+ "app_processes": processes,
+ "passed": passed,
+ }
+
+
+def _mean(rows: list[dict[str, Any]]) -> float:
+ return round(sum(r["reward"] or 0.0 for r in rows) / len(rows), 4) if rows else 0.0
+
+
+def summarize(
+ tasks: list[Task], rows: list[dict[str, Any]], leaks: list[dict]
+) -> dict[str, Any]:
+ by_agent: dict[str, Any] = {}
+ for agent in AGENTS:
+ mine = [r for r in rows if r["agent"] == agent]
+ if not mine:
+ continue
+ by_agent[agent] = {
+ "episodes": len(mine),
+ "mean_reward": _mean(mine),
+ "verdicts": {
+ v: sum(r["verdict"] == v for r in mine)
+ for v in ("CONFIRMED", "REFUTED", "INDETERMINATE")
+ },
+ "silent_wrong_effects": sum(bool(r["silent_wrong_effect"]) for r in mine),
+ "judge_errors": sum(bool(r["judge_error"]) for r in mine),
+ "action_errors": sum(r["action_errors"] for r in mine),
+ }
+ feasible = sum(t.feasible for t in tasks)
+ resets = [r["reset_s"] for r in rows if r["reset_s"] is not None]
+ checks: dict[str, bool] = {
+ "no_judge_errors": all(a["judge_errors"] == 0 for a in by_agent.values()),
+ }
+ if "scripted" in by_agent:
+ checks["every_task_passes_with_its_solution"] = (
+ by_agent["scripted"]["mean_reward"] == 1.0
+ )
+ if "screen_trusting" in by_agent:
+ checks["screen_trusting_paid_only_on_feasible"] = by_agent["screen_trusting"][
+ "mean_reward"
+ ] == round(feasible / len(tasks), 4)
+ if "planted_fault" in by_agent:
+ planted = [r for r in rows if r["agent"] == "planted_fault"]
+ checks["every_feasible_task_fails_with_a_planted_fault"] = all(
+ r["verdict"] == "REFUTED" and r["reward"] == 0.0 for r in planted
+ )
+ if "random" in by_agent:
+ checks["random_floor_margin"] = (
+ round(1.0 - by_agent["random"]["mean_reward"], 4) >= FLOOR_MARGIN
+ )
+ if leaks:
+ checks["no_state_leaks"] = all(leak["passed"] for leak in leaks)
+ return {
+ "tasks": len(tasks),
+ "feasible_tasks": feasible,
+ "agents": by_agent,
+ "reset_s": {
+ "episodes": len(resets),
+ "median": round(statistics.median(resets), 2) if resets else None,
+ "p95": round(sorted(resets)[int(0.95 * (len(resets) - 1))], 2)
+ if resets
+ else None,
+ "max": max(resets) if resets else None,
+ },
+ "leak_checks": leaks,
+ "checks": checks,
+ "passed": all(checks.values()),
+ }
+
+
+def validate(
+ env_dir: Path,
+ *,
+ agents: tuple[str, ...] = AGENTS,
+ only: Optional[list[str]] = None,
+ random_seeds: int = 1,
+ leak_checks: int = 2,
+ out: Optional[Path] = None,
+) -> dict[str, Any]:
+ import os
+
+ if os.environ.get(REFERENCE_ENV) != "1":
+ raise SystemExit(f"set {REFERENCE_ENV}=1 for a reference run")
+ env = OpenAdaptDesktopEnvironment(env_dir)
+ tasks = [t for t in env.env.tasks if not only or t.id in only]
+ rows: list[dict[str, Any]] = []
+ leaks: list[dict] = []
+ started = time.time()
+
+ def save() -> None:
+ if out is not None:
+ out.parent.mkdir(parents=True, exist_ok=True)
+ out.write_text(
+ json.dumps({"partial": True, "episodes": rows}, indent=1) + "\n"
+ )
+
+ try:
+ for i, task in enumerate(tasks):
+ for agent in agents:
+ if agent == "planted_fault":
+ if not task.feasible:
+ continue
+ rows.append(
+ run_episode(env, task, agent, fault=PLANTED[i % len(PLANTED)])
+ )
+ elif agent == "screen_trusting" and "scripted" in agents:
+ # Same actions as the reference; the record's verdict does
+ # not depend on the claim, so only the claim changes.
+ ref = next(
+ r
+ for r in rows
+ if r["task_id"] == task.id and r["agent"] == "scripted"
+ )
+ rows.append(derive_trusting(ref))
+ elif agent == "random":
+ for seed in range(random_seeds):
+ rows.append(run_episode(env, task, agent, seed))
+ else:
+ rows.append(run_episode(env, task, agent))
+ print(
+ f" {task.id}: "
+ + " ".join(
+ f"{r['agent']}={r['reward']}({r['verdict']},{r['reset_s']}s)"
+ for r in rows
+ if r["task_id"] == task.id
+ ),
+ flush=True,
+ )
+ save()
+ feasible = [t for t in tasks if t.feasible]
+ for k in range(min(leak_checks, max(len(feasible) - 1, 0))):
+ leaks.append(leak_check(env, feasible[k], feasible[k + 1]))
+ finally:
+ env.close()
+ summary = summarize(tasks, rows, leaks)
+ summary["env"] = env.env.manifest.name
+ summary["surface"] = env.surface
+ summary["run"] = {
+ "started": time.strftime("%Y-%m-%dT%H:%M:%SZ", time.gmtime(started)),
+ "wall_s": round(time.time() - started, 1),
+ "server_platform": f"{platform.system()} {platform.machine()} py{platform.python_version()}",
+ "model_calls": 0,
+ # "pack" keeps whatever else the desktop runs between episodes (a
+ # shared desktop); "account" stops every process of the account.
+ "reset_scope": getattr(env._guest, "reset_scope", None), # noqa: SLF001
+ }
+ result = {"summary": summary, "episodes": rows}
+ if out is not None:
+ out.write_text(json.dumps(result, indent=1, sort_keys=True) + "\n")
+ return result
+
+
+def main(argv: Optional[list[str]] = None) -> int:
+ parser = argparse.ArgumentParser(description=__doc__.splitlines()[0])
+ parser.add_argument("env_dir", type=Path)
+ parser.add_argument("--agents", default=",".join(AGENTS))
+ parser.add_argument("--only", action="append")
+ parser.add_argument("--random-seeds", type=int, default=1)
+ parser.add_argument("--leak-checks", type=int, default=2)
+ parser.add_argument("--out", type=Path)
+ args = parser.parse_args(argv)
+ result = validate(
+ args.env_dir,
+ agents=tuple(a for a in args.agents.split(",") if a),
+ only=args.only,
+ random_seeds=args.random_seeds,
+ leak_checks=args.leak_checks,
+ out=args.out,
+ )
+ print(
+ json.dumps(
+ {k: v for k, v in result["summary"].items() if k != "leak_checks"}, indent=2
+ )
+ )
+ return 0 if result["summary"]["passed"] else 1
+
+
+if __name__ == "__main__":
+ raise SystemExit(main())
diff --git a/packages/flow/openadapt_flow/rl_env/windows_guest.py b/packages/flow/openadapt_flow/rl_env/windows_guest.py
new file mode 100644
index 0000000000..033862e1b5
--- /dev/null
+++ b/packages/flow/openadapt_flow/rl_env/windows_guest.py
@@ -0,0 +1,715 @@
+"""The Windows guest behind a desktop environment, reached over WinRM.
+
+The environment server drives one Windows machine (a buyer's VM built from
+their own Windows image, an Azure or AWS Windows template, or a lab VM). This
+module is its control plane, separate from the agent's surface:
+
+* deploy the pack's apps and its database CLI into ``C:\\oa\\pack``, which
+ the desktop session can read but not change (its data, in ``data``, it
+ can); deploy checks that with a write probe from the desktop and refuses
+ a guest where the desktop session could rewrite the oracle's code;
+* reset an episode: stop the app, restore the pristine database, set the
+ planted fault and the UI knobs, start the app on the signed-in desktop, all
+ in one WinRM round trip;
+* read the system of record (``pack_db.py dump``) for the oracle, and its
+ digest for the state-leak check;
+* start the in-guest UIA agent (``win_agent``) with a pinned TLS certificate.
+
+WinRM runs in a network logon (session 0): it can see files and processes
+but not the desktop, so it is never part of what the agent observes or acts
+through. Credentials come from ``OPENADAPT_WINENV_HOST``, ``..._USER`` and
+``..._PASSWORD`` (or the lab's ``OAFLOW_WINLAB_*``) and are never printed.
+``pywinrm`` is imported lazily: ``pip install pywinrm``.
+"""
+
+from __future__ import annotations
+
+import base64
+import hashlib
+import json
+import os
+import re
+import shutil
+import subprocess
+import time
+from dataclasses import dataclass
+from pathlib import Path
+from typing import Any, Optional
+
+#: Where the pack lives in the guest. Fixed so the apps can name it. The
+#: code is read-only to the desktop session; ``DATA_DIR`` holds what the
+#: apps write (the databases, the fault and the UI knobs).
+GUEST_DIR = r"C:\oa\pack"
+DATA_DIR = r"C:\oa\pack\data"
+#: Values that reach a PowerShell script from a task file.
+_SAFE = re.compile(r"[a-z][a-z0-9_]{0,31}")
+APPS_DIR = (
+ Path(__file__).resolve().parents[2]
+ / "environments"
+ / "openenv"
+ / "_windows"
+ / "apps"
+)
+APP_FILES = ("pack_db.py", "patient_chart.ps1", "claims_desk.ps1")
+PACK_DB_SHA256 = hashlib.sha256((APPS_DIR / "pack_db.py").read_bytes()).hexdigest()
+APP_TASK = "OAEnvApp"
+# Processes of the desktop account that stay across a reset: its shell. The
+# in-guest agent stays too (matched by its command line). Everything else the
+# account runs in its desktop session (the app, a save still writing, any
+# window the last episode opened) is stopped. System processes in that
+# session (winlogon, csrss, dwm, fontdrvhost) are owned by other accounts and
+# never touched.
+_KEEP = (
+ "explorer",
+ "sihost",
+ "ctfmon",
+ "svchost",
+ "taskhostw",
+ "runtimebroker",
+ "searchhost",
+ "startmenuexperiencehost",
+ "shellexperiencehost",
+ "textinputhost",
+ "rdpclip",
+ "securityhealthsystray",
+ "widgets",
+ "widgetservice",
+ "lockapp",
+ "applicationframehost",
+ "dllhost",
+ "backgroundtaskhost",
+ "crossdeviceresume",
+ "phoneexperiencehost",
+ "msedgewebview2",
+ "onedrive",
+ "useroobebroker",
+ "smartscreen",
+)
+
+
+def _stop_desktop_processes(user: str) -> str:
+ """PowerShell that stops the desktop account's own processes but its shell.
+
+ Fails (the reset is refused) when the account has no desktop session or
+ its processes' owners cannot be read, rather than leaving the last
+ episode's windows open.
+ """
+ short = _ps_quote(user.split("\\")[-1])
+ # With a domain, match the whole DOMAIN\\name; without, the name alone.
+ owner = (
+ f"$_.UserName -eq '{_ps_quote(user)}'"
+ if "\\" in user
+ else f"$_.UserName.Split('\\')[-1] -eq '{short}'"
+ )
+ return (
+ "$keep = @(" + ",".join(f"'{n}'" for n in _KEEP) + ")\n"
+ f"$line = (query session '{short}' 2>$null | Select-Object -Skip 1 | Select-Object -First 1)\n"
+ "if (-not ($line -and $line -match '\\s(\\d+)\\s+(Active|Disc)')) {\n"
+ f" throw 'no desktop session for {short}: refusing a reset that could leave windows open'\n"
+ "}\n"
+ "$sid = [int]$Matches[1]\n"
+ "$agent = @(Get-CimInstance Win32_Process | Where-Object { $_.CommandLine -like "
+ "'*win_agent_server.py*' } | ForEach-Object { $_.ProcessId })\n"
+ "$mine = @(Get-Process -IncludeUserName -ErrorAction Stop | Where-Object { "
+ f"$_.SessionId -eq $sid -and $_.UserName -and {owner} }})\n"
+ # At least its shell runs: an account name that matches nothing
+ # (another spelling of it) would otherwise stop nothing and pass.
+ f"if ($mine.Count -eq 0) {{ throw 'no processes of {short} in its session: check the desktop account name' }}\n"
+ "$mine | Where-Object { $keep -notcontains $_.ProcessName.ToLower() -and $agent -notcontains $_.Id } | "
+ "ForEach-Object { Stop-Process -Id $_.Id -Force -ErrorAction SilentlyContinue }\n"
+ # A save launched from another session, or still exiting.
+ "Get-CimInstance Win32_Process -Filter \"Name='python.exe'\" | "
+ "Where-Object { $_.CommandLine -like '*pack_db.py*' } | "
+ "ForEach-Object { Stop-Process -Id $_.ProcessId -Force -ErrorAction SilentlyContinue }\n"
+ "Start-Sleep -Milliseconds 300\n"
+ )
+
+
+# The pack's own processes only: its apps, and any save still writing.
+_STOP_PACK_PROCESSES = (
+ "Get-CimInstance Win32_Process | Where-Object { ($_.Name -eq 'powershell.exe' -and "
+ "$_.CommandLine -like '*\\pack\\*.ps1*') -or ($_.Name -eq 'python.exe' -and "
+ "$_.CommandLine -like '*pack_db.py*') } | "
+ "ForEach-Object { Stop-Process -Id $_.ProcessId -Force -ErrorAction SilentlyContinue }\n"
+ "Start-Sleep -Milliseconds 300\n"
+)
+# Over SSH: UTF-8 output, no progress records, and exit 1 when the script's
+# last statement failed (as ``powershell -Command`` does).
+_SSH_PRELUDE = (
+ "$ProgressPreference='SilentlyContinue'\n"
+ "[Console]::OutputEncoding=[Text.Encoding]::UTF8\n"
+)
+_SSH_EPILOGUE = "\nif (-not $?) { exit 1 }\n"
+# Room left on a cmd.exe command line for an encoded script.
+_CMD_LINE_ROOM = 7800
+# Reads "\n