Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
c0eeafc
WIP: signed teach authorization bound to the teach scope
abrichr Oct 20, 2026
a0dd28a
Merge origin/main into claude/teach-authorization
abrichr Nov 3, 2026
c95563b
Teach authorization: sign with the approver roster's keys; bind or re…
abrichr Nov 3, 2026
4f7ed30
Merge origin/main into claude/teach-authorization
abrichr Nov 3, 2026
d56fd00
Teach authorization: address review round 1
abrichr Nov 3, 2026
3f0db00
Teach authorization: address review round 2
abrichr Nov 3, 2026
0acc432
Browser teach: bind taught writes to the signed teach authorization
abrichr Nov 3, 2026
c34c982
Merge origin/main into claude/teach-authorization
abrichr Nov 3, 2026
6dae6c0
Teach authorization: bind teach_run (from #1542) and test it
abrichr Nov 3, 2026
a8bb412
Browser teach writes: review round 1, keyboard activation, teach_run …
abrichr Nov 3, 2026
5c849b4
Teach authorization: fix the two CI failures
abrichr Nov 3, 2026
acfad6e
Browser teach writes and the teach scope: address review round 2
abrichr Nov 4, 2026
9538a11
Merge the #1436 head (CI fixes) into the browser-writes follow-up
abrichr Nov 4, 2026
21c18d8
Teach scope: type fixes for the key-target probe
abrichr Nov 4, 2026
c92461f
Browser teach writes and the teach scope: address review round 3
abrichr Nov 4, 2026
6eab815
feat(flow): add worker and new-window containment for guarded browser…
abrichr Nov 4, 2026
6865054
Merge main to resolve browser teach authorization conflicts
abrichr Nov 5, 2026
ac4e712
Merge worker containment dependency for browser teach writes
abrichr Nov 5, 2026
2639364
fix(flow): contain taught browser writes on every call
abrichr Nov 5, 2026
5466393
Merge origin/main into the browser teach writes branch
abrichr Nov 9, 2026
8635542
test(flow): declare complete reads in browser teach e2e fixtures
abrichr Nov 9, 2026
9401560
Merge remote-tracking branch 'origin/main' into HEAD
abrichr Nov 9, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions CAPABILITIES.md
Original file line number Diff line number Diff line change
Expand Up @@ -297,11 +297,11 @@ improvising or retrying when something is off.
| See what your own agent gets wrong, with no risk: `openadapt shadow` is a loopback pass-through proxy beside the agent. It checks each write against the system of record (FHIR through `ensure_record`; SQL through the verifier's whole-database frame), checks each `CONFIRMED` again later, and writes `report.html` and `report.json`. It never blocks, changes or resends a write; the only delay is the read before a write (at most `hold_ms`) | [#1678](https://github.com/OpenAdaptAI/OpenAdapt/pull/1678) | Real app (Medplum 5.2.8, 37 cases through a fault proxy: scripted agent 18 of 18 harms caught, 0 correct writes refuted; Claude Sonnet 5.5 9 of 9 caught, 4 correct but corrected writes refuted; 0 writes by the shadow; 15 to 25 ms median added per write; setup 76.5 s machine time, 3 decisions); real app, SQL mode (Dolibarr 21 on MariaDB 11.4, 13 cases: 8 of 8 harms caught, 5 of 5 correct writes confirmed, 292 ms median added); synthetic (SQLite) | `openadapt shadow`, [SHADOW_MODE.md](packages/flow/docs/SHADOW_MODE.md), [SHADOW_RESULTS.md](packages/flow/benchmark/fhir_medplum/public/SHADOW_RESULTS.md) |
| Skill cache for framework agents: an agent in any framework does a browser task through compile-agent's harness as plain tools (`BrowserTools`); when the system of record shows exactly the task's record and the operator confirms the checks, the run is canaried, admitted and emitted as an MCP server. A repeat of the same task (instruction, record, app, contract, environment) calls that tool instead of the agent: no model calls, the program's checks and this task's record check on every run, eviction after a failed run | Released | Synthetic (MockMed, LangGraph on `claude-sonnet-5-5`, 3 trials, repeats on the same record: run 1 6 model calls and $0.022; runs 2 to 10 27/27 VERIFIED, 0 model calls, 7.8 s median); Trac 1.6: run 1 verified, not admitted | `openadapt_flow.integrations.agents.skills`, [benchmark/skill_cache](packages/flow/benchmark/skill_cache/README.md) |
| Verified write tools for agent frameworks: `verified(tool, contract=...)` wraps a Claude Agent SDK, OpenAI Agents SDK, LangGraph or CrewAI write tool in one line. The contract and any values the operator pins come from the operator, never the agent's arguments; the store is read before and after; the agent gets a receipt or a refusal, and a refused write is held instead of retried | Released | Synthetic (each framework's own agent loop with a scripted model, writing through the example app's order form over real HTTP: verified save, a save the app drops, a save it keeps twice); one real-model run per framework, opt-in | `openadapt_flow.integrations.agents`, extras `claude-agent-sdk`, `openai-agents`, `langgraph` (CrewAI: install `crewai` beside it); [AGENT_FRAMEWORKS.md](packages/flow/docs/AGENT_FRAMEWORKS.md) |
| Browser teach refuses taught writes: a write an agent teaches needs a person's signed teach authorization, and this lane can't bind one, so `teach_start` with a contract is refused and an existing write tool doesn't run. Writes are taught through `serve --teach --teach-authorization`. The read-only lane (downloads) is unchanged | On main ([#1589](https://github.com/OpenAdaptAI/OpenAdapt/pull/1589), [#1436](https://github.com/OpenAdaptAI/OpenAdapt/pull/1436)) | Unit test of the refusal | `openadapt-agent serve --teach-browser`, [TEACH_AUTHORIZATION.md](packages/flow/docs/TEACH_AUTHORIZATION.md) |
| Teach a browser write as a verified tool: with write contracts and a person's signed teach authorization (`serve --teach-browser --contracts DIR --teach-authorization STATEMENT`), the agent teaches a save once. Run 1 starts only when the statement covers the write (origin, contract, write adapter, the record's fields and values) and runs under it; it is verified in the system of record before the `taught_<name>` tool exists. Every call checks the statement and the tool's signature again, makes the write and returns a verified receipt or a refusal. Sign-in values come from the server's environment and never reach the agent or the program. Controls in named iframes are found through their frame | On main ([#1589](https://github.com/OpenAdaptAI/OpenAdapt/pull/1589), [#1763](https://github.com/OpenAdaptAI/OpenAdapt/pull/1763)) | Synthetic (the example app's sign-in and order form in headless Chromium over MCP: verified save, a save the app drops, a save it keeps twice, a page that swaps the record during run 1; refusals for a missing, uncovering, expired, edited or wrongly signed statement) | `openadapt-agent serve --teach-browser --contracts --teach-authorization`, [VERIFY_WRITES.md](packages/flow/docs/VERIFY_WRITES.md#teach-a-write-as-a-tool) |
| Guard an agent you already run: attach to its own Chromium over CDP (one added line), hold each save until the record on screen is the one the task names, block it and tell the agent why when it isn't, read the save back; a run that reads back correctly becomes a draft program with a record check from scaffold-verifier, which a person confirms and admits, then a `taught_*` tool with no model calls. `--observe-only` never blocks | Released ([#1357](https://github.com/OpenAdaptAI/OpenAdapt/pull/1357), stacked on [#1335](https://github.com/OpenAdaptAI/OpenAdapt/pull/1335)) | Synthetic (MockMed, scripted Playwright agent, `effect_e2e` faults) | `openadapt-flow guard`, [GUARD_AN_AGENT.md](packages/flow/docs/GUARD_AN_AGENT.md) |
| Task ledger per job: rules locked when the job opens and enforced on every run, item status set only from OpenAdapt's own results, and yes-or-no questions a person answers on the phone or in Desktop, including when a run stops | Released ([#1332](https://github.com/OpenAdaptAI/OpenAdapt/pull/1332)) | Synthetic (30-item MockMed worklist, scripted agent, no model calls) | MCP tools `open_job`, `get_job`, `add_items`, `record_evidence`, `ask_user`, `get_answer`, `change_constraint`, `close_job`; [Track a long job](packages/agent/README.md#track-a-long-job) |
| Limit a teaching agent to the declared task on every teach path (`compile_agent`, `compile-agent`, teach over MCP, the airbag guard): typed text must be a declared value, links and browser requests to other origins are refused, writes are checked before they are sent, and the record is read back before a draft exists. Injected instructions in record notes, banners, tooltips, alt text and server responses are blocked or caught on MockMed through each path (scripted agent; a live-model mode is off by default). Self-repair refuses a control that leaves the app | Released ([#1359](https://github.com/OpenAdaptAI/OpenAdapt/pull/1359), [#1386](https://github.com/OpenAdaptAI/OpenAdapt/pull/1386)) | Synthetic | `openadapt_flow.teach_scope`, [THREAT_MODEL.md](packages/flow/docs/THREAT_MODEL.md) |
| Teach authorization: a person signs what a teaching agent may do (task, origins, inputs, the one write, forbidden actions and controls) with their approver key, and every teach path is bound to it or refused. Verified with the approver roster's own verifier, so an unknown, removed or wrong key, an unpinned root, a changed statement or another task refuses. Admission of every JIT draft needs one (`teach_auth_not_recorded` otherwise), as do an agent-demonstrated fix's approval and self-repair of an agent-taught program; the airbag handoff's drafts and browser-teach writes are refused | On main ([#1436](https://github.com/OpenAdaptAI/OpenAdapt/pull/1436)) | Synthetic (real approver keys, real roster, real admission) | `openadapt-flow teach-authorization`, [TEACH_AUTHORIZATION.md](packages/flow/docs/TEACH_AUTHORIZATION.md) |
| Teach authorization: a person signs what a teaching agent may do (task, origins, inputs, the one write, forbidden actions and controls) with their approver key, and every teach path is bound to it or refused. Verified with the approver roster's own verifier, so an unknown, removed or wrong key, an unpinned root, a changed statement or another task refuses. Admission of every JIT draft needs one (`teach_auth_not_recorded` otherwise), as do an agent-demonstrated fix's approval and self-repair of an agent-taught program; browser-teach writes are bound to it, and the airbag handoff's drafts are refused | On main ([#1436](https://github.com/OpenAdaptAI/OpenAdapt/pull/1436)) | Synthetic (real approver keys, real roster, real admission) | `openadapt-flow teach-authorization`, [TEACH_AUTHORIZATION.md](packages/flow/docs/TEACH_AUTHORIZATION.md) |
| Compile an agent's first verified run from a prompt (`compile-agent`), and a code-as-action authoring agent | Released ([#1277](https://github.com/OpenAdaptAI/OpenAdapt/pull/1277), [#1305](https://github.com/OpenAdaptAI/OpenAdapt/pull/1305)); the agent harness behind it runs on every backend, on main ([#1283](https://github.com/OpenAdaptAI/OpenAdapt/pull/1283)) | Synthetic | `compile-agent` |
| An agent records a native app by control: `AuthoringSession.observe()` lists the app's controls from UI Automation (Windows), Accessibility (macOS) or AT-SPI (Linux), each with its element identity (role, name, ancestry, window, process); a click by node is re-read before input and refused when that identity changed, has a twin in the window, or the tree was cut short. `compile-agent --config` and `serve-execute --config` build the app from the deployment's backend | [#1870](https://github.com/OpenAdaptAI/OpenAdapt/pull/1870) | Windows 11 Pro x64, Patient Notes (in-tree WinForms, synthetic SQLite): 11 of 11 identities re-read equal, five clicks recorded by UIA locator, the note read back from SQLite; macOS Calculator, read only: 20 of 20; Linux, the GTK3 fixture in Xvfb: recorded by control, the effect file as oracle, a click on one of two identical buttons refused ([benchmark/native_authoring](packages/flow/benchmark/native_authoring/README.md)) | `openadapt_flow/authoring.py`, `authoring_tree()` on each native backend |
| Score harness optimizers (Harness², Meta-Harness) on GUI tasks with the record read-back as the reward, with full trace export | Released ([#1299](https://github.com/OpenAdaptAI/OpenAdapt/pull/1299), [#1300](https://github.com/OpenAdaptAI/OpenAdapt/pull/1300), [#1301](https://github.com/OpenAdaptAI/OpenAdapt/pull/1301)) | Synthetic (scripted proposer) | `benchmark/harness/harness2/` (source checkout) |
Expand Down
Loading
Loading