Skip to content

fix(simdrive): MCP auto-restart wedge + host-AX boundary diagnostics (1.0.0b11) - #166

Merged
mauricecarrier7 merged 1 commit into
mainfrom
fix/mcp-autorestart-wedge-and-ax-diagnostics
Jun 23, 2026
Merged

fix(simdrive): MCP auto-restart wedge + host-AX boundary diagnostics (1.0.0b11)#166
mauricecarrier7 merged 1 commit into
mainfrom
fix/mcp-autorestart-wedge-and-ax-diagnostics

Conversation

@mauricecarrier7

@mauricecarrier7 mauricecarrier7 commented Jun 23, 2026

Copy link
Copy Markdown
Contributor

Summary

Four fixes surfaced by a live internal tickets iOS-validation campaign, which hit the MCP auto-restart wedge and the WKWebView host-AX boundary. Version bumped 1.0.0b101.0.0b11.

FIX 1 (primary — run-breaker): MCP auto-restart wedge

When simdrive ran as an MCP stdio server and detected loaded-vs-disk version drift, it auto-restarted via os.execv. That keeps the PID but tears down the client's initialized stdio session mid-stream, so every subsequent tool call failed MCP error -32602: Invalid request parameters — unrecoverable without a client /mcp reconnect. Strictly worse than the drift.

Mode-detection mechanism: a module-level _MCP_SERVER_MODE flag (helper _in_mcp_server_mode()) is flipped True only inside _serve_async — the one code path that owns the stdio transport. _maybe_handle_drift short-circuits when it's set: it surfaces the drift warning, sets no _simdrive_action, and schedules no re-exec. _check_version_drift returns an actionable message naming the -32602 hazard and the recovery (reconnect /mcp). Safe self-restart is preserved for non-MCP callers (CLI smokes, embedders, direct call_tool) where the flag stays False. SIMDRIVE_NO_AUTO_RESTART=1 remains an explicit override everywhere.

FIX 2: WKWebView host-AX diagnostic

perform_accessibility_action now appends a hint when zero custom actions are enumerated anywhere in the target window (new _window_has_any_custom_action DFS): if it's a Readium/WKWebView reader, web-content a11y isn't bridged to host-AX on the simulator — use the on-device XCTest backend (runner/). Accuracy guard: the hint fires only on a genuinely empty window, not when a specific named action is simply absent among existing custom actions.

FIX 3: set_text SwiftUI SecureField boundary (docs only)

Documented in both the set_text MCP tool description (server.py) and the ax.set_text docstring: AXValue commits UIKit fields (incl. UIAlertController) but does not reliably commit a SwiftUI SecureField/TextField bound to @State (the field may display the text while @State stays empty). Guidance: tap + type_text/HID for SwiftUI @State-bound fields. No behavior change.

FIX 4: SIMDRIVE_NO_AUTO_RESTART docs

New "Environment variables" table in simdrive/README.md documents the var (name matches what the code reads), plus the drift warning text now points to it: set it for MCP-driver sessions to suppress the version-drift auto-restart.

Tests

  • New tests/test_b11_mcp_server_mode_no_restart.py: drift in MCP-server mode does not schedule a restart and surfaces the -32602 / /mcp message (sync + async); restart is still scheduled outside MCP-server mode; helper reflects the flag.
  • Extended tests/test_ax_module.py: _window_has_any_custom_action true/false; WKWebView hint added on empty window; hint NOT added when other custom actions exist; SwiftUI-boundary docstring assertion.
  • Full suite: 1691 passed, 4 skipped, 25 errors. All 25 errors are pre-existing in tests/test_e2e_testkit.py and are environmental — they fail at setup with no_device / first_booted (require a booted simulator), unrelated to this change. hypothesis had to be installed in the test env (it was missing) to collect 4 property-test modules; also a pre-existing environmental gap.

Version + changelog

  • simdrive/pyproject.toml: 1.0.0b101.0.0b11 (single source of truth; __version__ is read from package metadata).
  • simdrive/CHANGELOG.md: added the [1.0.0b11] entry in the existing public-surface style.

⚠️ server.py / ax.py are critical paths — architect + QA forge review still required before merge.

🤖 Generated with Claude Code

…nostics (1.0.0b11)

A live PP-4527/4531/4529 + PP-4632 validation campaign hit two sharp edges:
the version-drift auto-restart desynced the MCP stdio transport, and the
host-AX backend gave unhelpful errors at the WKWebView/SwiftUI boundaries.

FIX 1 (run-breaker): never auto-restart while serving as an MCP stdio server.
os.execv keeps the PID but tears down the client's initialized stdio session,
so every later tool call failed `MCP error -32602` until a /mcp reconnect —
strictly worse than the drift. Gate auto-restart on a new `_MCP_SERVER_MODE`
flag set only in `_serve_async` (the one path that owns stdio). In that mode
we surface a clear, actionable warning (reconnect /mcp) and schedule no
re-exec. Safe self-restart is preserved for non-MCP (CLI/embedded) callers.
`SIMDRIVE_NO_AUTO_RESTART=1` remains an explicit override everywhere.

FIX 2: perform_accessibility_action now hints at the WKWebView/Readium host-AX
boundary when ZERO custom actions exist anywhere in the target window — only
then, not when a specific named action is merely absent.

FIX 3: document set_text's UIKit-vs-SwiftUI boundary — AXValue commits UIKit
(incl. UIAlertController) fields but not a SwiftUI @State-bound SecureField/
TextField; use tap + type_text/HID there. Docstring + MCP tool description.

FIX 4: document SIMDRIVE_NO_AUTO_RESTART (README env-var table + drift text):
set it for MCP-driver sessions to suppress the version-drift auto-restart.

Tests: new test_b11_mcp_server_mode_no_restart.py (suppression in MCP mode,
preserved restart outside it, actionable message) + WKWebView-hint and
SwiftUI-docstring tests in test_ax_module.py. Version 1.0.0b10 -> 1.0.0b11
+ CHANGELOG entry.

**Scope:** docs + diagnostics + the MCP-mode restart gate only. No change to
the actual AX value-setting behaviour (set_text still writes AXValue), no new
SwiftUI/WKWebView code path, and no change to the on-device XCTest backend —
this is the host-AX side plus the version-drift gating. The pre-existing
test_e2e_testkit.py simulator-dependent tests are untouched.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@mauricecarrier7
mauricecarrier7 merged commit 2b25d38 into main Jun 23, 2026
5 of 7 checks passed
mauricecarrier7 added a commit that referenced this pull request Jun 23, 2026
…nostics (1.0.0b11) (#166)

A live internal-ticket/4531/4529 + internal-ticket validation campaign hit two sharp edges:
the version-drift auto-restart desynced the MCP stdio transport, and the
host-AX backend gave unhelpful errors at the WKWebView/SwiftUI boundaries.

FIX 1 (run-breaker): never auto-restart while serving as an MCP stdio server.
os.execv keeps the PID but tears down the client's initialized stdio session,
so every later tool call failed `MCP error -32602` until a /mcp reconnect —
strictly worse than the drift. Gate auto-restart on a new `_MCP_SERVER_MODE`
flag set only in `_serve_async` (the one path that owns stdio). In that mode
we surface a clear, actionable warning (reconnect /mcp) and schedule no
re-exec. Safe self-restart is preserved for non-MCP (CLI/embedded) callers.
`SIMDRIVE_NO_AUTO_RESTART=1` remains an explicit override everywhere.

FIX 2: perform_accessibility_action now hints at the WKWebView/Readium host-AX
boundary when ZERO custom actions exist anywhere in the target window — only
then, not when a specific named action is merely absent.

FIX 3: document set_text's UIKit-vs-SwiftUI boundary — AXValue commits UIKit
(incl. UIAlertController) fields but not a SwiftUI @State-bound SecureField/
TextField; use tap + type_text/HID there. Docstring + MCP tool description.

FIX 4: document SIMDRIVE_NO_AUTO_RESTART (README env-var table + drift text):
set it for MCP-driver sessions to suppress the version-drift auto-restart.

Tests: new test_b11_mcp_server_mode_no_restart.py (suppression in MCP mode,
preserved restart outside it, actionable message) + WKWebView-hint and
SwiftUI-docstring tests in test_ax_module.py. Version 1.0.0b10 -> 1.0.0b11
+ CHANGELOG entry.

**Scope:** docs + diagnostics + the MCP-mode restart gate only. No change to
the actual AX value-setting behaviour (set_text still writes AXValue), no new
SwiftUI/WKWebView code path, and no change to the on-device XCTest backend —
this is the host-AX side plus the version-drift gating. The pre-existing
test_e2e_testkit.py simulator-dependent tests are untouched.

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@mauricecarrier7
mauricecarrier7 deleted the fix/mcp-autorestart-wedge-and-ax-diagnostics branch June 24, 2026 13:23
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant