Skip to content

Diagnose native worker crash during legacy clipboard completion #89

Description

@wieslawsoltes

AppScene coordination epic: SceneTech/AppScene#66
Related clipboard contract: #86

Problem

The macOS arm64 Release Code OSS/AppScene package can copy real Monaco text through WebScene's user-initiated Document.execCommand('copy') bridge, but a later repeat of the computer-use sequence crashed in the stripped native runtime immediately after an accepted Command-C sequence.

Qualified inputs:

  • WebScene b639b4c49985891c2521421229a2f22e976ead2c
  • AppScene e9fd26777747adfda5fadd571b0b5c73412dfe67
  • executable SHA-256 678b9106885e42ad37fe1db03d22cf32d1f2027387ab262899950138acec6e99
  • macOS 26.6 arm64

One run copied the exact scenetechmanualinputok Monaco marker to the OS clipboard, accepted all 569 bounded AppScene input records, and closed normally. A later run accepted all 368 records, delivered Command-A and Command-C with modifier flags 8, then exited with SIGSEGV before the clipboard marker appeared.

The crash report records EXC_BAD_ACCESS (SIGSEGV) with pointer-authentication failure on a WebScene worker thread. The packaged dylib is stripped, so the available image-relative offsets are:

  • 0x508cb4
  • 0x20244c
  • 0x246404
  • 0x8830c
  • 0x1ba94
  • 0x17da8
  • 0x17cc8
  • 0x17b84

The active macOS desktop was shared during the Accessibility automation and other applications intermittently became frontmost, so the trigger is not yet deterministic. The accepted input trace and worker-thread crash still require a runtime stress gate before the combined Code OSS clipboard qualification can close.

Proposed implementation

  • Retain symbols for failed native package jobs or upload a matching dSYM with bounded retention so crash offsets can be resolved.
  • Add a repeated native legacy-copy test that dispatches a trusted Command-C, creates async clipboard representations, completes the typed host request from another thread, and drains microtasks.
  • Exercise engine teardown, window focus changes, delayed completion, duplicate completion, and navigation between dispatch and completion.
  • Audit isolate locking and worker ownership around dispatch_clipboard_shortcut, complete_host_request, promise resolution, and microtask checkpoints.
  • Fix only a reproduced ownership or scheduling violation; preserve the existing browser API and typed host ABI.

Quality gates

  • A deterministic sanitizer or stress test reproduces the old failure and passes the fix for at least 10,000 copy/completion iterations.
  • The existing 10,000 clipboard round-trip, maximum-payload, queue saturation, navigation cancellation, three-RID package, and consumer gates remain green.
  • The macOS Code OSS computer-use gate copies and pastes exact text, closes normally, and passes repeatedly on an idle desktop.
  • No Electron, CEF, WebView, Chromium, or VS Code source change.

Keep the implementation in the consolidated WebScene draft branch and do not merge until the repeated native and packaged gates pass.

Activity

  1. wieslawsoltes commented on Sep 15, 2026

    @wieslawsoltes
    CollaboratorAuthor

    Diagnostic/stress implementation is now on the consolidated draft branch at 00979c54 (PR #76).

    • Adds 10,000 real native Meta-C -> prevented keydown -> Document.execCommand('copy') -> clipboard event -> typed host request -> cross-thread public completion iterations in 16-request batches.
    • Every batch verifies exact request flags/MIME/bytes and uses a worker-ordered script barrier; the engine is destroyed immediately after the final resolved promise/microtask barrier to exercise the packaged close boundary seen in the crash report.
    • Adds a 15-second performance budget with the 16-request high-water mark reported.
    • macOS Release builds now keep line tables until dsymutil creates symbols for the exact shipped UUID, then strip the packaged dylib so installed size does not grow.
    • CI uploads only the compressed macOS dSYM with three-day retention. An architecture contract locks symbol-before-strip ordering and bounded artifact policy; it passes locally 7/7.

    The complete native V8/package CI is running. No runtime behavior has been changed yet; a fix will require either deterministic reproduction or a symbolized ownership/scheduling failure.

  2. wieslawsoltes commented on Sep 15, 2026

    @wieslawsoltes
    CollaboratorAuthor

    The shutdown audit found a concrete matching defect and the fix is committed at 31e3d8ad on draft PR #76.

    host_promise_targets owns persistent V8 contexts and promise resolvers, and file_targets owns persistent contexts. The runtime destructor previously disposed the isolate before either container was cleared. If the native window closed with an unfinished clipboard or file request, later C++ member destruction reset those persistent handles against the disposed isolate. This matches the crash report: main thread waiting in webscene_engine_destroy, WebScene worker faulting during teardown, pointer-authentication failure.

    The destructor now clears both containers while holding the isolate lock and before context/isolate disposal. A direct regression creates a native Meta-C legacy copy, takes the typed clipboard request without completing it, then destroys the engine. This models closing before the OS host completion. The 10,000 completed-copy stress and exact Release dSYM pipeline remain in the same branch.

    Local static/architecture validation passes. The superseded CI runs were cancelled to avoid redundant native artifacts; the complete matrix for 31e3d8ad is running. Packaged AppScene reproduction remains required after that matrix is green.

  3. wieslawsoltes commented on Sep 15, 2026

    @wieslawsoltes
    CollaboratorAuthor

    Root cause is now independently reproduced through the public WebScene ABI against the retained pre-fix b639b4c4 macOS dylib.

    The minimal process creates an engine and textarea, handles native Meta-C with document.execCommand('copy'), takes the resulting typed clipboard request without completing it, then calls webscene_engine_destroy. It exits 139 deterministically. No AppScene, VS Code, Accessibility automation, rendering, or OS clipboard is involved.

    The new minimal crash and the packaged Code OSS crash have identical WebScene image-relative frames:

    0x508cb4, 0x20244c, 0x246404, 0x8830c, 0x1ba94, 0x17da8, 0x17cc8, 0x17b84

    Both main threads are waiting in std::thread::join() from webscene_engine_destroy; both worker faults are pointer-authentication failures. This proves the pending persistent V8 handle teardown identified in 31e3d8ad is the matching defect. The new native regression encodes the same public-ABI sequence. CI must now prove that the updated runtime exits cleanly, then the rebuilt AppScene package will repeat the computer-use copy/paste/close gate.

  4. wieslawsoltes commented on Sep 15, 2026

    @wieslawsoltes
    CollaboratorAuthor

    Validation is complete for the reproduced crash and fix at 31e3d8ad on draft PR #76.

    • The exact macOS package producer passed the direct pending-request teardown regression and the 10,000-operation native legacy-copy/completion stress gate.
    • The pre-fix public-ABI reproducer exits 139 with all eight WebScene frames matching the packaged Code OSS crash. Replacing only the dylib with the 31e3d8ad package makes the same binary print clean destroy and exit 0.
    • The shipped dylib and uploaded dSYM both have UUID A8A72CF9-8783-3C1E-A89D-02369DB0CC1E. The compressed symbol artifact is 5,352,939 bytes with three-day retention.
    • Hosted macOS/Ubuntu/Windows, NativeAOT, Linux native contracts, all three runtime packages and consumers, cross-RID evidence, and release-set verification pass.
    • A rebuilt 814,594,395-byte Code OSS/AppScene bundle passes the real-editor smoke and normal close. Real Monaco copy also reaches the OS clipboard and the prior worker SIGSEGV does not recur.

    The remaining real-Monaco paste copyback mismatch is tracked by #86 and SceneTech/AppScene#69; it is separate from this proven persistent-handle teardown defect. The implementation remains in the open draft PR and is not merged.

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

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions