Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
6 changes: 5 additions & 1 deletion loopx/agy_goal_mode/host_runtime.py
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
1 change: 1 addition & 0 deletions skills/loopx-self-repair/references/repair-patterns.md
Original file line number Diff line number Diff line change
Expand Up @@ -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. |
Expand Down
7 changes: 6 additions & 1 deletion tests/test_antigravity_host_runtime.py
Original file line number Diff line number Diff line change
Expand Up @@ -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"]:
Expand All @@ -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):
Expand Down
Loading