Skip to content

feat(mobile): instrumentable iPad simulator for reproducing and profiling iPad-only defects #4

Description

@nohat

Problem

Most of my time in T3 Code is on the iPad app, and I cannot debug it from the Mac. When the iPad hangs (#3: a thread open freezes the whole UI until force-quit), the only evidence is a screenshot and my description. Server traces cannot show a blocked JS thread, and I cannot read the iPad's local cache or see what its JS thread is doing. #3 was investigated for an hour without finding the cause for that reason.

Goal

An iPad simulator setup that an agent or I can launch with one command and inspect, so a defect seen on the iPad can be reproduced and profiled on the Mac.

  • Boots an iPad simulator with the dev client (see scripts/mobile-native-client.ts ensure and the test-t3-mobile workflow) paired to an isolated dev server.
  • Seeds that server from a copy of my real data (VACUUM INTO, per AGENTS.md "Test data"), so large real threads like the one in bug(mobile): iPad thread open hangs on 'Syncing messages...' until force-quit #3 are available.
  • Exposes instrumentation: JS thread stall detection (long-task or event-loop lag logging), the React Native JS profiler or a Hermes sampling profile, and a way to read the app's local SQLite cache for a given thread.
  • Reproduces an open of a named thread, with a scripted tap, and reports whether the JS thread stayed responsive.
  • Never touches ~/.t3/userdata read-write and never shares state with the live app.

First use

Reproduce #3 with the failing thread's data and find what blocks the JS thread. Fix or file the cause.

Priority

High. It unblocks every iPad-only defect, and iPad is my main surface. It also feeds the papercut capture work (docs/fork/papercuts.md): a stall detector built here is the same signal the automatic offer needs.

Related: #3, #2.

Activity

  1. nohat commented on Oct 4, 2026

    @nohat
    OwnerAuthor

    Status 2026-10-04, branch feat/ios-repro-harness (c5ebb44394). Works end to end on the iPad simulator, paired to an isolated server seeded from a VACUUM INTO copy:

    • scripts/ios-repro/export-thread.ts + the dev-only DevReplay service (T3CODE_DEV_REPLAY_FILE, trigger file <file>.go) replay a recorded thread into a new thread at original cadence.
    • scripts/ios-repro/probe.ts pings the Hermes JS thread over Metro's inspector, records feed scroll offsets, and captures a symbolicated stack of each stall via Debugger.pause.

    Bugs found and fixed while using it: replay lines carried no commandId, so every line failed to decode and a replay dispatched nothing (the test fixture hid it); the probe's socket was rejected by Metro for a missing Origin.

    Limits found: a debug dev client plus an attached debugger inflates JS time (React DevTools and React dev frames dominate stall stacks), and any XCTest input walks the accessibility tree on the main thread, which blocks taps on long text views. Measure by deep link and simctl, not agent-device press. Still missing: a Release-build measurement path, since the defects were seen on a Release archive. Results so far are on #16.

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

    enhancementNew feature or request

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions