From 056d117ddc83a567d403174d8dfa43e938faa568 Mon Sep 17 00:00:00 2001 From: Lihua <1017343802@qq.com> Date: Wed, 4 Nov 2026 20:51:08 -0800 Subject: [PATCH] fix(antigravity): request inline Core admission output Keep model context transport enabled for the parent while the native Stop hook reads the existing inline machine decision. Preserve PYTHONPATH isolation, UTF-8 decoding, user gates and quota refusals. Qualify both inherited context modes against real Core and record the reusable caller repair pattern. Signed-off-by: Lihua <1017343802@qq.com> --- loopx/agy_goal_mode/host_runtime.py | 6 +++++- skills/loopx-self-repair/references/repair-patterns.md | 1 + tests/test_antigravity_host_runtime.py | 7 ++++++- 3 files changed, 12 insertions(+), 2 deletions(-) diff --git a/loopx/agy_goal_mode/host_runtime.py b/loopx/agy_goal_mode/host_runtime.py index cd49631876..e0be7b1078 100644 --- a/loopx/agy_goal_mode/host_runtime.py +++ b/loopx/agy_goal_mode/host_runtime.py @@ -70,7 +70,11 @@ def _admitted(args: argparse.Namespace) -> bool: encoding="utf-8", timeout=10, check=True, - env={key: value for key, value in os.environ.items() if key != "PYTHONPATH"}, + env={ + **{key: value for key, value in os.environ.items() if key != "PYTHONPATH"}, + # This machine read needs Core's decision, not model context navigation. + "LOOPX_CONTEXT_DELIVERY": "off", + }, ) return json.loads(read.stdout).get("should_run") is True diff --git a/skills/loopx-self-repair/references/repair-patterns.md b/skills/loopx-self-repair/references/repair-patterns.md index 0117da7243..30b23b6604 100644 --- a/skills/loopx-self-repair/references/repair-patterns.md +++ b/skills/loopx-self-repair/references/repair-patterns.md @@ -150,6 +150,7 @@ teaches a reusable control-plane lesson. | `repeat_vision_wait_ack_gap` | Two exact blocked-successor stalls correctly trigger replan, but a maintenance-only continuation appears to close the obligation while a `repeat_until_closed` vision still has no evidence-linked path outcome; later heartbeats repeat the same wait cycle. | active agent vision advancement policy, blocked-successor frontier identity, current obligation id, host-projected coverage ledger, typed progress observation, current runnable successor ids, and semantic receipt. | Replan validity considered a caller-supplied delta label instead of the obligation's typed outcomes and current state. | Require an accepted semantic delta bound to the exact current obligation. A vision-derived duty accepts a fresh evidence-linked vision path, new evidence-backed blocker, or coverage-backed terminal; a successor id is accepted only when current state proves it runnable, and maintenance-only continuation never closes the vision duty. Cover repeat/as-needed routing and stale-obligation identities. | | `future_monitor_heartbeat_liveness_overreach` | A valid future-scheduled monitor repeatedly enters `frontier_exhausted_monitor_lane` or `dead_monitor_repeat` even though it is not due and no real monitor execution occurred. | generated heartbeat guard command, trigger `current_time_iso`, quota `heartbeat_receipt`, monitor Todo `next_due_at`, run-history `quota_monitor_poll` rows, concrete Todo/target identity, and monitor mode. | Future wait state was collapsed into empty-frontier exhaustion, while distinct heartbeat turn ids were treated as monitor executions and lowered the dead-monitor threshold. | Add typed `future_monitor_wait` and `due_monitor_execution` frontier rules. Keep future monitors quiet/no-spend until due; count `dead_monitor_repeat` only from unchanged due/external executions carrying a concrete Todo or target identity. Heartbeat turn ids remain idempotency/liveness evidence and never reduce the real execution threshold. | | `replan_context_delivery_gap` | A replan obligation is visible, but a weak protocol-following model ignores or mis-executes a manual evidence-log read ritual, then spends turns debugging ACK/read order instead of choosing a new direction. | current obligation id, host-projected `replan_context_v0`, compact coverage ledger, delivery receipt, typed action packet, selected model tool action, semantic writeback receipt, and successor turn boundary. | Evidence access was modeled as an agent CLI obligation even though the control plane already owned the ledger; read execution and semantic use were conflated. A separate Todo-add then refresh ACK also let the model execute the successor in the replan turn. | Have the host prefetch and project bounded evidence coverage into quota. Treat the delivery receipt as context delivery only; require the model's real next action to produce an accepted typed semantic delta bound to the current obligation. When the delta is a runnable successor, bind the exact obligation on the Todo write itself and return `end_current_heartbeat`; do not require a second ACK or run the successor in that turn. Remove the standalone evidence command and generated read rituals. Reuse the typed replan context for the core Goal, dense scoped decision evidence, repetition reduction and exact history-reference reads. Keep replan selection independent of the routine display window, and validate novelty against complete available history even when the readable context is truncated; reject malformed schemas and unavailable references instead of treating them as empty evidence. Preserve the durable history and historical receipt decoder, not a compatibility command. Cover real quota→model action→Todo/refresh CLI behavior plus missing/wrong obligation identity. | +| `machine_cli_capture_projection_gap` | A native hook or non-model JSON consumer treats context navigation as the effective decision and denies ready work because a top-level admission field is absent. | Original child argv/runtime profile; outer schema versus the same immutable captured Core decision; parent/child context settings; real Core ready, user-gate and zero-quota cases. | Model-facing context transport wrapped the formerly inline machine payload. A locator is not a policy decision; a locale/codec repair alone cannot restore this path. | Use the existing machine-output contract only for the non-model child process, retaining Core gates, identity, UTF-8 and environment isolation. Reuse the established per-child `LOOPX_CONTEXT_DELIVERY=off`; do not disable model context globally or interpret navigation `ok` as admission. Actual model consumers must follow the original readers and retain current bytes/digests. Validate ready, user-gate and zero-quota behavior with parent context on/off unchanged; distinguish source, installed-host and live-model qualification. | | `replan_settlement_binding_projection_gap` | A replan packet and selected Todo are both visible, so an agent combines `--todo-id` with `--replan-obligation-id`, alternates between them after rejection, or performs the Todo-bound refresh but omits the matching spend. | Original quota receipt identity, selected Todo, semantic obligation id, interaction settlement plan, projected refresh/spend commands, and accepted semantic ACK. | The semantic obligation target and causal settlement identity were adjacent but unlabeled, while one boolean conflated direct obligation binding with whether a full settlement chain was required. | Keep exactly one causal settlement binding. For a turn-scoped executable plan, project a domain-local typed replan settlement contract that labels the selected Todo or Todo-less obligation as the binding and keeps the replan id as a separate semantic target when necessary. Todo-bound and directly bound replan writes both project material refresh followed by spend; never combine their CLI flags. Keep unscoped diagnostic reads compact and non-executable. Cover TS projection, hot-path envelope, real Todo-bound/Todo-less CLI chains, output budget, and in-flight delivery continuity. | | `native_goal_todoless_replan_reentry_gap` | A native visible Goal completes all advancement Todos, semantic closeout derives a Todo-less autonomous replan obligation, and the next unbound quota read projects a bare refresh with no Turn identity or spend chain. | Native Goal runtime profile, selected Todo absence, replan obligation id, interaction CLI actions before and after Turn creation, and settlement identity. | Native-Goal Turn re-entry recognized only selected Todos as actionable settlement bindings and ignored a valid Todo-less replan obligation. | Treat either a selected Todo or a valid replan obligation as a native-Goal settlement binding. When no Turn or settlement plan exists, project only the exact `quota should-run ... --begin-turn` re-entry. After execution, require the obligation-bound refresh and spend chain; keep generic unscoped diagnostic behavior unchanged. | | `replan_meta_successor_churn` | An autonomous replan repeatedly adds and completes obligation-bound advancement Todos whose only action is to replan, re-arm, wait for the host, or report no new direction; Todo count grows while executable targets and evidence do not. | current obligation and acceptance gaps, generated replan action packet, bound Todo `action_kind`/`target_key`/Explore refs, semantic ACK, Todo lifecycle, and compact progress fingerprints. | A planning instruction was compiled into a runnable successor command, while Todo authoring and ACK validation treated obligation identity alone as proof of executable semantic change. | Generate a successor command only from a concrete bounded frontier with a typed action and stable target. Require the same semantic binding at Todo write and ACK time; generic vision/frontier replans must resolve through a typed progress or coverage-backed terminal outcome instead of creating a meta Todo. Cover packet generation, write rejection, ACK rejection, and a real quota→model→CLI successor re-entry. | diff --git a/tests/test_antigravity_host_runtime.py b/tests/test_antigravity_host_runtime.py index 04d362fce8..1bfaacf07b 100644 --- a/tests/test_antigravity_host_runtime.py +++ b/tests/test_antigravity_host_runtime.py @@ -276,12 +276,16 @@ def test_admission_decodes_utf8_core_output_under_a_locale_codec(tmp_path): assert result.stdout == b"" -def test_native_hook_admission_uses_real_core_ready_user_gate_and_zero_quota(tmp_path): +@pytest.mark.parametrize("context_delivery", ["on", "off"]) +def test_native_hook_admission_uses_real_core_ready_user_gate_and_zero_quota( + tmp_path, monkeypatch, context_delivery, +): from examples.control_plane.quota_plan_fixtures import ( SCOPED_AGENT_ID, write_cli_fixture, ) + monkeypatch.setenv("LOOPX_CONTEXT_DELIVERY", context_delivery) registry, runtime_root, _ = write_cli_fixture(tmp_path / "core", scoped_agents=True) data = json.loads(registry.read_text()) for goal in data["goals"]: @@ -302,6 +306,7 @@ def test_native_hook_admission_uses_real_core_ready_user_gate_and_zero_quota(tmp ): args.goal_id = goal assert runtime._admitted(args) is expected + assert os.environ["LOOPX_CONTEXT_DELIVERY"] == context_delivery def test_hooks_migrate_only_an_unchanged_owned_legacy_entry(tmp_path):