Skip to content

[Bug]: Host recovery I/O uses the locale codec, silently dropping non-ASCII Antigravity Stop events on cp936 #8030

Open

Description

@JasonBuildAI

Preflight

  • I searched existing issues and discussions for this behavior.
  • This report is not an unpatched security vulnerability.
  • The report and attachments contain no credentials or private/internal material.

Issue origin

Observed or reproduced in a real environment

LoopX version or commit

a0130633723210a5406dca61ee27aa33fe48b3f3 (loopx 2.2.0)

Host or runtime surface

Other: Antigravity App Stop hook and desktop managed-runtime handoff on native Windows

LoopX area

Host or runtime integration

Problem

The latest main fails both repository-wide UTF-8 guards, so the Python test lane is red before any pull request starts; on a cp936 Windows host the same omissions also turn a non-ASCII Antigravity recovery event into a silent no-op and can block managed-runtime recovery.

The repository already requires explicit UTF-8 for structured text I/O and text-mode subprocess output. Four recently shipped calls detected by the guards bypass that contract, and the Stop hook also reads its own JSON stream without pinning UTF-8:

  • loopx/agy_goal_mode/host_runtime.py reads the native Stop event from sys.stdin with the inherited locale codec, reads its recovery state through Path.read_text() without a codec, and decodes quota should-run output with the locale codec;
  • loopx/hosts/managed_service_runtime.py reads the runtime-handoff journal through Path.read_text() without a codec and decodes the doctor JSON with the locale codec.

At the commit above, the static guards fail independently of the host locale:

tests/test_loopx_text_io_utf8.py::test_shipped_runtime_pins_utf8_for_every_text_file_read_and_write FAILED
tests/test_runtime_subprocess_utf8.py::test_shipped_runtime_pins_utf8_for_every_text_mode_subprocess_call FAILED
2 failed, 4 passed

On a zh-CN Windows host, host_runtime.main() calls json.load(sys.stdin) while stdin is configured as GBK. A valid UTF-8 Stop event containing non-ASCII input raises UnicodeDecodeError; the exception path prints a generic unavailable message and returns {}. A {} response means the bound recovery is not continued. The same locale dependency is present when the hook asks Core for admission and when managed-runtime alignment restores a journal or checks its candidate runtime.

This is a regression in newly merged host/runtime work: the Antigravity Stop-hook runtime came from #7837, managed-runtime alignment came from #7980, and #7887 fixed only Antigravity discovery decoding. It is not a request for a new encoding convention; it restores the existing guarded contract.

Minimal reproduction

  1. Check out a0130633723210a5406dca61ee27aa33fe48b3f3 and install the test environment.
  2. Run the two existing repository guards:
uv run --extra test python -m pytest -q \
  tests/test_loopx_text_io_utf8.py \
  tests/test_runtime_subprocess_utf8.py

Observed: 2 failed, 4 passed, with offending sites in loopx/agy_goal_mode/host_runtime.py and loopx/hosts/managed_service_runtime.py.

  1. On a zh-CN Windows host, or in a child process with PYTHONIOENCODING=gbk and PYTHONUTF8=0, send this well-formed native event to the Stop-hook module with a bound Goal, Agent and conversation:
{"conversationId":"native-chat","terminationReason":"ERROR","fullyIdle":true,"lastUserInput":"继续授权的工作","error":"agent executor error: generating and executing: stream reading error: unexpected EOF"}

Observed before decoding is pinned: LoopX Antigravity stop-hook unavailable (UnicodeDecodeError) followed by {}. With UTF-8 pinned, the same isolated event receives {"decision": "continue", ...}.

Expected behavior

The existing package-wide UTF-8 guards pass. Native Stop JSON, recorder state, Core admission output, managed-runtime handoff journals and doctor output are decoded as UTF-8 regardless of the Windows ANSI code page, so a non-ASCII recovery event is evaluated normally and a local journal remains recoverable.

Actual behavior

The current tree fails its own static UTF-8 guards. Under the cp936 locale, the Stop hook catches the decode failure and returns no continuation; the admission reader and managed-runtime recovery paths can likewise observe an exception or a missing decoded payload.

Sanitized diagnostics

Path.read_text(): missing encoding in loopx/agy_goal_mode/host_runtime.py
Path.read_text(): missing encoding in loopx/hosts/managed_service_runtime.py
subprocess.run(text=True): missing encoding in loopx/agy_goal_mode/host_runtime.py
subprocess.run(text=True): missing encoding in loopx/hosts/managed_service_runtime.py

Stop hook under PYTHONIOENCODING=gbk / PYTHONUTF8=0:
LoopX Antigravity stop-hook unavailable (UnicodeDecodeError)
{}

Additional context

Native Windows is a supported LoopX installation and host surface. The cp936 failures match the established class handled by #4941 / #4942, #6116 / #6167, and #4155 / #4396; this report is a continuation for the recently added host/runtime sites rather than a duplicate of those closed repairs. Antigravity's public documentation lists a Windows build and its documented Stop hook consumes JSON on stdin.

Activity

  1. added
    bugSomething isn't working
    triageNeeds maintainer triage or routing.
    on Nov 4, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workingtriageNeeds maintainer triage or routing.

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions