From 18811227ac94fc56a81dc4870ea9d42efbfabcd2 Mon Sep 17 00:00:00 2001 From: LoopX Agent <337587101+loopx-agent@users.noreply.github.com> Date: Sat, 7 Nov 2026 18:33:54 +0800 Subject: [PATCH 1/2] fix(quota): retain selection transport from prepared captures Signed-off-by: LoopX Agent <337587101+loopx-agent@users.noreply.github.com> --- loopx/cli_commands/quota.py | 6 +++++- .../control_plane/test_replan_staged_read.py | 21 ++++++++++++++++++- 2 files changed, 25 insertions(+), 2 deletions(-) diff --git a/loopx/cli_commands/quota.py b/loopx/cli_commands/quota.py index 92339b96f0..8d578095f6 100644 --- a/loopx/cli_commands/quota.py +++ b/loopx/cli_commands/quota.py @@ -374,7 +374,11 @@ def _emit_quota_result( # Preserve the original validation error when activation itself failed. context_delivery_enabled = False activation = {"progressive_enabled": False} - bind_capture_selection_transport(payload, args) + # A prepared reference names one immutable capture. A later selection in + # the same Turn must create a fresh sibling instead of reusing that path. + selection_root = (capture_directory.parent if capture_directory is not None + and getattr(args, "prepared_capture_reference", False) else None) + bind_capture_selection_transport(payload, args, capture_root=selection_root) delivery_request = None decision_identity = ("", "") if capture_directory is not None and payload.get("replan_action_packet"): diff --git a/tests/control_plane/test_replan_staged_read.py b/tests/control_plane/test_replan_staged_read.py index 05df95313d..de777e507e 100644 --- a/tests/control_plane/test_replan_staged_read.py +++ b/tests/control_plane/test_replan_staged_read.py @@ -231,13 +231,23 @@ def observe(command, **kwargs): try: body = checkpoint.capture_before_replan(env, receipt, "original heartbeat instructions") assert len(commands) == 1 and "--turn-envelope" not in commands[0] - assert "--decision-output-root" in commands[0] source_path, view_path = wake / "checkpoint-start-guard.json", wake / "checkpoint-start-view.json" if context_delivery: + assert "--prepared-capture-reference" in commands[0] argv = shlex.split(body.split("```sh\n", 1)[1].split("\n```", 1)[0]) view_path = Path(argv[argv.index("--capture-file") + 1]) assert view_path.parent != wake and view_path.is_relative_to(wake) + else: + assert "--decision-output-root" in commands[0] source, view = json.loads(source_path.read_bytes()), json.loads(view_path.read_bytes()) + if context_delivery and replan: + original_dir = Path(commands[0][commands[0].index("--decision-output-dir") + 1]) + selection = source["interaction_contract"]["cli_channel"]["selection_command"] + followup = shlex.split(selection["command_args_template"]) + assert followup[followup.index("--decision-output-root") + 1] == str(original_dir.parent) + assert followup[followup.index("--context-delivery") + 1] == "on" + assert followup[followup.index("--codex-context-dir") + 1] == str(native) + assert "--decision-output-dir" not in followup and "--prepared-capture-reference" not in followup assert str(view_path) in body and str(source_path) not in body assert body.endswith("original heartbeat instructions") if context_delivery: @@ -298,6 +308,15 @@ def observe(command, **kwargs): assert {key: fixture[key].read_bytes() for key in before} == before assert capture.read_bytes() == source_path.read_bytes() assert len(commands) == 1 # Reads did not re-enter checkpoint preflight. + if context_delivery: + selected = shlex.split(selection["route_prefix"]) + followup + selected[selected.index("{todo_id}")] = TODO + result = run(selected, cwd=fixture["project"], env=env, capture_output=True, text=True, timeout=60) + assert result.returncode == 0, result.stdout + [next_capture] = set(original_dir.parent.glob("*/decision.json")) - {capture} + identity = json.loads(next_capture.read_bytes())["heartbeat_receipt"]["settlement_identity"] + assert (identity["todo_id"], identity["turn_instance_id"]) == (TODO, TURN) + assert capture.read_bytes() == source_path.read_bytes() finally: restart_effect_runtime(wait_for_exit=True) From abb6760c27a1384a1d915447611d8771d4851fbc Mon Sep 17 00:00:00 2001 From: LoopX Agent <337587101+loopx-agent@users.noreply.github.com> Date: Sat, 7 Nov 2026 18:41:34 +0800 Subject: [PATCH 2/2] refactor(quota): bind prepared selection at capture transport Signed-off-by: LoopX Agent <337587101+loopx-agent@users.noreply.github.com> --- loopx/cli_commands/quota.py | 6 +----- loopx/cli_commands/quota_capture.py | 7 ++++++- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/loopx/cli_commands/quota.py b/loopx/cli_commands/quota.py index 8d578095f6..7adf952c5b 100644 --- a/loopx/cli_commands/quota.py +++ b/loopx/cli_commands/quota.py @@ -374,11 +374,7 @@ def _emit_quota_result( # Preserve the original validation error when activation itself failed. context_delivery_enabled = False activation = {"progressive_enabled": False} - # A prepared reference names one immutable capture. A later selection in - # the same Turn must create a fresh sibling instead of reusing that path. - selection_root = (capture_directory.parent if capture_directory is not None - and getattr(args, "prepared_capture_reference", False) else None) - bind_capture_selection_transport(payload, args, capture_root=selection_root) + bind_capture_selection_transport(payload, args, capture_directory=capture_directory) delivery_request = None decision_identity = ("", "") if capture_directory is not None and payload.get("replan_action_packet"): diff --git a/loopx/cli_commands/quota_capture.py b/loopx/cli_commands/quota_capture.py index 57a075e001..47addded68 100644 --- a/loopx/cli_commands/quota_capture.py +++ b/loopx/cli_commands/quota_capture.py @@ -1034,13 +1034,18 @@ def fits(value: dict[str, object]) -> bool: def bind_capture_selection_transport(payload: dict[str, Any], args: argparse.Namespace, *, - capture_root: Path | None = None) -> None: + capture_root: Path | None = None, + capture_directory: Path | None = None) -> None: """Retain caller display/capture options in the existing selection command. Only transport argv is composed here; the typed quota owner still selects the action and owns admission. Each selection invocation allocates a new capture. """ root = getattr(args, "decision_output_root", None) + # A prepared reference binds one immutable directory. Same-Turn + # selection uses its parent to create a fresh sibling capture. + if capture_directory is not None and getattr(args, "prepared_capture_reference", False): + capture_root = capture_directory.parent if root is None and capture_root is None: return interaction = payload.get("interaction_contract")