Skip to content

feat(computer): lock a macOS VM bundle's installs; what macOS bench runs need (full capture, grants and relays on lume); two CUA flake fixes - #498

Merged
earakely-scale merged 11 commits into
mainfrom
edgararakelyan/fd-5225-a11-lock-a-macos-vm-bundles-installs-a-pinned-python-and
Nov 5, 2026
Merged

earakely-scale merged 11 commits into
mainfrom
edgararakelyan/fd-5225-a11-lock-a-macos-vm-bundles-installs-a-pinned-python-and

Conversation

@earakely-scale

@earakely-scale earakely-scale commented Nov 4, 2026 •

Copy link
Copy Markdown
Collaborator

What

A macOS VM bundle's installs are locked, as a Linux layer's packages are. Since #484, a macOS compose installed live in the guest: whatever Python 3.12 uv python install gave, and each venv's wheels from PyPI. The key covered neither, so two Macs could hold different wheels under one name.

  • Pinned Python: vm_bundle/macos/lib.sh installs python-build-standalone's CPython 3.12.16 (20261026) for Apple silicon, checked against its sha256, in place of uv python install.
  • Wheels resolved once: the first compose of given inputs resolves every venv's wheels in a short-lived VM of the base. That VM installs the pinned Python and builds the wheels into the folder it shares, then is deleted. The inputs are each venv's requirements, the protocol's source, the base, the arch, the resolve script, and the readying that pins the Python.
  • Stored as a lock: the wheels go into the object store with a Lock naming them, in the same store and shape as the Linux lock, with apt empty.
  • Keyed and installed offline: the lock's digest joins the VM bundle's key. Every compose of those inputs, on any Mac, stages the wheels and installs them with --no-index --no-deps.
  • Concurrency and failure: one resolve of given inputs runs on a Mac at once, under a lock of its inputs. A resolve that fails fails the pair at its resolve stage, with the resolver's output.

Two CUA flake fixes. Each failed CI's slow tier about 1 run in 25.

  • A recording's start answers once its first frame is in. Under load, the fallback recorder's first capture came late, so a 2 s recording held 1.4 s of frames, and the probe's "a recording's segments match their files" check failed. A start now answers once its recording is recording: a stream's at once, the fallback's at its first frame, waiting up to FIRST_FRAME_S.
  • cua-driver types characters off X's keymap without losing them. cua-driver maps such a character onto a spare keycode for its press and back at once, so an app that reads the press after, as a busy one does, loses it. The probe's "Unicode and mixed-case text arrives whole" check failed on it. The driver now first keeps each such character on a spare keycode, as the reference driver does, so cua-driver types it as any other key. Its own keycodes are reused oldest first, and given back when a text needs more than there are. This adds python-xlib to cua-driver's Linux requirements.

What the macOS bench rows needed, found running them on EC2 Macs (4–5 Nov).

  • cua-driver's capture is the whole display. cua-driver caps a capture's long edge by default on macOS, so at 1920×1080 @capture returned 1365×768 and the probe refused the computer. The driver now asks for max_image_dimension=0. The tools an agent calls are forwarded as before, with cua-driver's own default.
  • A local object store's grants reach a macOS VM. A lume VM could neither resolve nor reach host.docker.internal, so file loads, recording uploads and snapshots had no route to the Mac's grant server.
    • The provider declares REACHES_HOST_AT = "127.0.0.1", and prepare.sh maps host.docker.internal to the VM's loopback.
    • Each process that hands the VM grants forwards its grant server's port there over ssh -R, a reconnecting process too.
    • The local transfer CA's trust files go in the seed, with SSL_CERT_FILE, REQUESTS_CA_BUNDLE and NODE_EXTRA_CA_CERTS pointing at them.
  • An agent in this Mac's Docker reaches a macOS computer. Lume's relays listen on the Mac's loopback. get_external_url now rewrites that to host.docker.internal, as the local provider does, so an agent in colima gets a computer URL it can reach. Before, the agent ran with no desktop tools.
  • A VM's state changes under a lock of its own (_changing): a reconnect, a reset and a termination, each across agent-envs on the Mac. Concurrent processes keep each other's forwards and process ids, and a termination holds the lock until the VM is deleted.

Testing

  • Unit, on an EC2 Linux VM: 13,137 passed, 7 skipped. New tests cover:
    • one resolve for given inputs, its lock reused on another Mac with the same wheels staged and the same name;
    • changed requirements resolving again;
    • a failed resolve failing its pair at resolve;
    • the offline install line and the resolve script;
    • a recording's start waiting out a slow first frame;
    • the keymap's spare and reused keycodes, and giving them back.
  • On the EC2 Mac (mac2-m2.metal, Lume, Cua's macOS 26 base):
    • Round 1 resolved the wheels in a VM of the base (the protocol, av and cryptography among them, built for macosx…arm64), stored the lock, composed offline, and passed the full probe with only cua-driver's declared P6 waived. Deploy and reset worked. Compose, resolve and probe took 4 min 4 s.
    • Round 2: with the VM bundle deleted, it composed again from the stored lock, offline and with no resolve, under the same name. The probe passed again, and deploy and reset worked. That compose and probe took 3 min 13 s, so the resolve costs about 50 s, once per set of inputs.
  • The bench's macOS BenchLab computer on the EC2 Macs (trycua's Swift BenchLab and BenchSentinel, 1920×1080):
    • It composed and passed its probe, with P6 waived.
    • Graded agent trials with Sonnet 5.5 passed in both conditions: IR-01 foreground and background, reward 1.0. The background trial had all eight of trycua's A22 user-undisturbed criteria measured and held.
    • Friday's 70 macOS trials are running on this branch at 2d4ad6f; the run's manifest records that commit.
  • Unit tests for the macOS fixes:
    • the full-size capture call;
    • the forward, the seed's trust files and REACHES_HOST_AT;
    • a reconnect forwarding its own port;
    • two reconnects at once keeping every forward, which fails without the lock;
    • a reconnect during a termination, which fails unless the lock is held through deletion;
    • a relay's URL as a local container reaches it.
  • The flakes didn't reproduce on an EC2 Linux VM, in 12+12 probes under 24 busy loops or 8+8 with the computer capped at --cpus 0.4, with the fixes or without. The fixes regress nothing there. Worth watching CI's slow tier for a recurrence after merge.

🤖 Generated with Claude Code

RetriggerView in GreptileConfidence Score: 5/5

The PR appears safe to merge; the latest change closes the reconnect window during VM deletion.

Summary

The PR pins macOS Python and stores resolved wheels for offline installs. It also improves recording startup, Unicode typing, and local file transfers.

  • macOS VM bundle composes reuse a pinned Python and locked wheels.
  • Lume VMs can reach local grant servers and relay URLs.
  • Recording starts wait until recording has begun.
  • Linux cua-driver keeps Unicode key presses on X's keymap.
  • Screenshot capture now keeps the whole display.

Diagram

sequenceDiagram
    participant T as Terminate
    participant L as Per-VM lock
    participant R as Reconnect
    participant V as VM and saved state
    T->>L: Acquire
    T->>V: Stop processes and delete VM
    R->>L: Wait
    T->>V: Remove saved state folder
    T->>L: Release
    R->>L: Acquire
    R->>V: Read saved state
    V-->>R: SandboxNotFoundError
Loading

Reviews (7) · Last reviewed commit: "fix(lume): terminating a VM holds its lo..." · Reviewed by Greptile

earakely-scale and others added 4 commits November 4, 2026 14:44
The fallback recorder polls @capture, and a busy computer took long enough over its first frame that a recording ended
two seconds after its start held 1.4 s of frames, missing what happened first; the probe's recording check failed on
it. A start now answers once its recording is recording: a stream's at once, the fallback's at its first frame, waited
for up to FIRST_FRAME_S.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ing them

cua-driver maps a character X's keymap lacks onto a spare keycode for its press and back at once, and an app that reads
the press after, as a busy one does, loses the character: the probe's "Unicode and mixed-case text arrives whole" failed
on it. The driver first keeps each such character on a spare keycode, as the reference driver does, so cua-driver types
it as any other key; ours are reused oldest first, and given back when a text needs more than there are.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…nvs offline from a lock

A macOS compose installed live in the guest: whatever Python 3.12 uv gave and each venv's wheels from PyPI, which its
key didn't cover, so two Macs could hold different wheels under one name. Its venvs are now locked as a Linux layer's
packages are: the first compose of given inputs resolves their wheels in a VM of the base, on python-build-standalone's
CPython 3.12.16 pinned by its sha256, stores them in the object store with a lock naming them, and the lock's digest
joins the VM bundle's key; every compose of those inputs, on any Mac, stages them and installs with --no-index
--no-deps. One resolve of given inputs runs on a Mac at once.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…5-a11-lock-a-macos-vm-bundles-installs-a-pinned-python-and
@earakely-scale
earakely-scale requested a review from a team as a code owner November 4, 2026 23:12
…ymap reconnects after X restarts

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
earakely-scale and others added 2 commits November 4, 2026 15:49
…ua-driver's capture is the full display

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…to its loopback over ssh, the CA's trust in its seed

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
earakely-scale and others added 2 commits November 4, 2026 16:19
… server's port, a reconnect too

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ays at host.docker.internal

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
earakely-scale and others added 2 commits November 4, 2026 16:39
…so concurrent reconnects keep every forward

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…onnect never forwards into one going away

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@earakely-scale earakely-scale changed the title feat(computer): lock a macOS VM bundle's installs, a pinned Python and wheels installed offline; two CUA flake fixes feat(computer): lock a macOS VM bundle's installs; what macOS bench runs need (full capture, grants and relays on lume); two CUA flake fixes Nov 5, 2026
@earakely-scale
earakely-scale merged commit b2faa54 into main Nov 5, 2026
36 checks passed
@earakely-scale
earakely-scale deleted the edgararakelyan/fd-5225-a11-lock-a-macos-vm-bundles-installs-a-pinned-python-and branch November 5, 2026 01:40
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant