From 58dbf8e185b1bc041cd7960c432727d8663980e1 Mon Sep 17 00:00:00 2001 From: abrichr Date: Sun, 2 Aug 2026 19:36:38 +0200 Subject: [PATCH 1/3] feat(quickstart): forward --break-it to the flow tutorial Requires openadapt-flow >= 1.29.0, which exposes tutorial --break-it. Co-Authored-By: Claude Fable 5 --- openadapt/cli.py | 25 ++++++++++++++++++++++++- pyproject.toml | 14 +++++++------- tests/test_cli_smoke.py | 24 ++++++++++++++++++++++++ 3 files changed, 55 insertions(+), 8 deletions(-) diff --git a/openadapt/cli.py b/openadapt/cli.py index 04adf4fa5..dd582068f 100644 --- a/openadapt/cli.py +++ b/openadapt/cli.py @@ -170,7 +170,17 @@ def _run_flow(argv: list[str]) -> None: @click.option( "--headed", is_flag=True, help="Show the browser while the tutorial runs." ) -def quickstart(out: Path, headed: bool) -> None: +@click.option( + "--break-it", + "break_it", + is_flag=True, + help=( + "After the verified run, rerun the same certified bundle against a " + "fault-injecting backend and watch the engine halt instead of " + "trusting the screen." + ), +) +def quickstart(out: Path, headed: bool, break_it: bool) -> None: """Run a verified local tutorial against the bundled synthetic app. This is the shortest path to a real OpenAdapt run. It uses the bundled @@ -195,6 +205,8 @@ def quickstart(out: Path, headed: bool) -> None: ] if headed: argv.append("--headed") + if break_it: + argv.append("--break-it") # The bundled tutorial contains only fixed synthetic data. Keep an # installed-but-unconfigured privacy provider from blocking this known-safe @@ -224,7 +236,18 @@ def quickstart(out: Path, headed: bool) -> None: "The synthetic write was confirmed through a read-only system-of-record API." ) click.echo("No model or Cloud call was enabled.") + if break_it: + click.echo( + "The rerun against the fault-injecting backend HALTED as designed: " + "the screen claimed success and the system of record disagreed." + ) + click.echo(f"Caught-fault evidence: {root / 'run-broken' / 'REPORT.md'}") click.echo(f"Inspect qualification gaps: openadapt flow lint {root / 'bundle'}") + if not break_it: + click.echo( + "Watch it catch a lie: openadapt quickstart --break-it --out " + f"{root}-break-it" + ) click.echo( "See a fail-safe halt: openadapt flow replay " f"{root / 'bundle'} --drift modal --run-dir {root}-halt" diff --git a/pyproject.toml b/pyproject.toml index bfcc8660d..2c9dee3c6 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -33,7 +33,7 @@ classifiers = [ # All other capabilities (capture, ml, evals, ...) remain opt-in extras. dependencies = [ "click>=8.0.0", - "openadapt-flow[hosted]>=1.25.1,<2.0.0", + "openadapt-flow[hosted]>=1.29.0,<2.0.0", ] [project.optional-dependencies] @@ -49,22 +49,22 @@ browser = [ # separately provisioned executable, not a Python-package dependency. capture = [ "openadapt-capture>=1.0.4,<2.0.0", - "openadapt-flow[capture]>=1.25.1,<2.0.0", + "openadapt-flow[capture]>=1.29.0,<2.0.0", ] # Replay substrate dependencies stay separate from capture: recording observes # the human on the local interactive desktop, while replay may target a WAA # agent, a native app, or a remote framebuffer. windows = [ - "openadapt-flow[windows]>=1.25.1,<2.0.0", + "openadapt-flow[windows]>=1.29.0,<2.0.0", ] macos = [ - "openadapt-flow[macos]>=1.25.1,<2.0.0; sys_platform == 'darwin'", + "openadapt-flow[macos]>=1.29.0,<2.0.0; sys_platform == 'darwin'", ] linux = [ - "openadapt-flow[linux]>=1.25.1,<2.0.0; sys_platform == 'linux'", + "openadapt-flow[linux]>=1.29.0,<2.0.0; sys_platform == 'linux'", ] rdp = [ - "openadapt-flow[rdp]>=1.25.1,<2.0.0", + "openadapt-flow[rdp]>=1.29.0,<2.0.0", ] ml = [ "openadapt-ml>=0.2.0", @@ -82,7 +82,7 @@ retrieval = [ "openadapt-retrieval>=0.1.0", ] privacy = [ - "openadapt-flow[privacy]>=1.25.1,<2.0.0", + "openadapt-flow[privacy]>=1.29.0,<2.0.0", ] # `flow` now ships in the base install (see `dependencies` above). This # extra is kept for backward compatibility so `pip install openadapt[flow]` diff --git a/tests/test_cli_smoke.py b/tests/test_cli_smoke.py index 8e8649240..b38bb09e9 100644 --- a/tests/test_cli_smoke.py +++ b/tests/test_cli_smoke.py @@ -114,6 +114,30 @@ def test_quickstart_forwards_the_headed_tutorial_option(monkeypatch): assert calls[0][-1] == "--headed" +def test_quickstart_forwards_the_break_it_option_and_names_the_evidence( + monkeypatch, +): + calls = [] + monkeypatch.setattr( + "openadapt.cli._invoke_flow", + lambda argv: calls.append(list(argv)) or 0, + ) + + runner = CliRunner() + with runner.isolated_filesystem(): + result = runner.invoke( + cli_main, + ["quickstart", "--break-it", "--out", "break-run"], + ) + + assert result.exit_code == 0, result.output + assert len(calls) == 1 + assert calls[0][0] == "tutorial" + assert calls[0][-1] == "--break-it" + assert "run-broken" in result.output + assert "HALTED" in result.output + + def test_quickstart_restores_the_operator_scrub_setting(monkeypatch): monkeypatch.setenv("OPENADAPT_FLOW_SCRUB", "auto") monkeypatch.setattr("openadapt.cli._invoke_flow", lambda _argv: 0) From 000e934fdc264171c13ba6d97eea94d5109dc59b Mon Sep 17 00:00:00 2001 From: abrichr Date: Sun, 2 Aug 2026 21:53:41 +0200 Subject: [PATCH 2/3] chore: raise remaining flow floor and regenerate platform manifest for flow 1.29.0 Co-Authored-By: Claude Fable 5 --- platform-manifest.json | 18 +++++++++--------- pyproject.toml | 2 +- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/platform-manifest.json b/platform-manifest.json index d0ef1f7da..9db12fe93 100644 --- a/platform-manifest.json +++ b/platform-manifest.json @@ -1,7 +1,7 @@ { "manifest_kind": "openadapt-platform-release-manifest", "schema_version": "1.0.0", - "generated_at": "2026-08-02T16:33:44+00:00", + "generated_at": "2026-08-02T19:53:33+00:00", "release_channel": "beta", "components": { "launcher": { @@ -26,21 +26,21 @@ }, "flow": { "package": "openadapt-flow", - "version": "1.28.0", + "version": "1.29.0", "source": "pypi", "requires_python": "<3.13,>=3.10", "artifacts": [ { "type": "bdist_wheel", - "filename": "openadapt_flow-1.28.0-py3-none-any.whl", - "url": "https://files.pythonhosted.org/packages/2b/ce/1a43d30411e6abd35ddfaad5fbf00321c14f0cf1082ebcaee7f993ec17b5/openadapt_flow-1.28.0-py3-none-any.whl", - "sha256": "4d156035ea411e3cbdbc40978d653d50727a7d8664646be62f7f9e95ba0c7202" + "filename": "openadapt_flow-1.29.0-py3-none-any.whl", + "url": "https://files.pythonhosted.org/packages/8f/ab/f05f65adb368a6135a32eb201e341e00e5ccc7334715d4381aad2e656c3a/openadapt_flow-1.29.0-py3-none-any.whl", + "sha256": "2c5f49199161fb2964bb43cfae2470fb79e5dbcb264e3031d6f8802ecb161a6a" }, { "type": "sdist", - "filename": "openadapt_flow-1.28.0.tar.gz", - "url": "https://files.pythonhosted.org/packages/f2/a7/9a109b155c11b5edfc2c3ed765858a976c7565f73c7f0c818a04c5ae34b8/openadapt_flow-1.28.0.tar.gz", - "sha256": "6e108f3469da20226427fee7a11378e067ca08c1fbbfcdbb4018ab9c3d142a8b" + "filename": "openadapt_flow-1.29.0.tar.gz", + "url": "https://files.pythonhosted.org/packages/a1/4f/53d31b2a8600a61e35ab9aa469e25591e327eb2301039c5e55f788044a82/openadapt_flow-1.29.0.tar.gz", + "sha256": "d4ba0fb0af915d8fbf642fdf0843524f04992e8b3080febfb618febe507311a7" } ] }, @@ -95,7 +95,7 @@ ">=0.1.0" ], "openadapt-flow": [ - ">=1.25.1,<2.0.0" + ">=1.29.0,<2.0.0" ], "openadapt-grounding": [ ">=0.1.0" diff --git a/pyproject.toml b/pyproject.toml index 2c9dee3c6..ea2a012b3 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -88,7 +88,7 @@ privacy = [ # extra is kept for backward compatibility so `pip install openadapt[flow]` # and the `all` bundle still resolve. flow = [ - "openadapt-flow>=1.25.1,<2.0.0", + "openadapt-flow>=1.29.0,<2.0.0", ] # Bundles core = [ From 9fb3aa9069d13d249bac1c238ae58aad759fab43 Mon Sep 17 00:00:00 2001 From: abrichr Date: Sun, 2 Aug 2026 22:00:40 +0200 Subject: [PATCH 3/3] test: align extras metadata floors with flow 1.29.0 Co-Authored-By: Claude Fable 5 --- tests/test_cli_smoke.py | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/tests/test_cli_smoke.py b/tests/test_cli_smoke.py index b38bb09e9..25597a5af 100644 --- a/tests/test_cli_smoke.py +++ b/tests/test_cli_smoke.py @@ -277,22 +277,22 @@ def test_launcher_flow_and_substrate_extras_metadata(): )["project"] extras = metadata["optional-dependencies"] - assert metadata["dependencies"].count("openadapt-flow[hosted]>=1.25.1,<2.0.0") == 1 - assert extras["flow"] == ["openadapt-flow>=1.25.1,<2.0.0"] + assert metadata["dependencies"].count("openadapt-flow[hosted]>=1.29.0,<2.0.0") == 1 + assert extras["flow"] == ["openadapt-flow>=1.29.0,<2.0.0"] assert extras["browser"] == ["playwright>=1.44"] - assert extras["privacy"] == ["openadapt-flow[privacy]>=1.25.1,<2.0.0"] + assert extras["privacy"] == ["openadapt-flow[privacy]>=1.29.0,<2.0.0"] assert extras["capture"] == [ "openadapt-capture>=1.0.4,<2.0.0", - "openadapt-flow[capture]>=1.25.1,<2.0.0", + "openadapt-flow[capture]>=1.29.0,<2.0.0", ] - assert extras["windows"] == ["openadapt-flow[windows]>=1.25.1,<2.0.0"] + assert extras["windows"] == ["openadapt-flow[windows]>=1.29.0,<2.0.0"] assert extras["macos"] == [ - "openadapt-flow[macos]>=1.25.1,<2.0.0; sys_platform == 'darwin'" + "openadapt-flow[macos]>=1.29.0,<2.0.0; sys_platform == 'darwin'" ] assert extras["linux"] == [ - "openadapt-flow[linux]>=1.25.1,<2.0.0; sys_platform == 'linux'" + "openadapt-flow[linux]>=1.29.0,<2.0.0; sys_platform == 'linux'" ] - assert extras["rdp"] == ["openadapt-flow[rdp]>=1.25.1,<2.0.0"] + assert extras["rdp"] == ["openadapt-flow[rdp]>=1.29.0,<2.0.0"] assert extras["all"] == [ "openadapt[browser,core,grounding,retrieval,privacy,flow,windows,rdp]", "openadapt[macos]; sys_platform == 'darwin'",