Research: native screen capture and hardware encoding for remote desktops (D200) #139

Closed
opened 2026-10-09 09:27:32 +00:00 by kayg · 33 comments
Owner

Owner 2026-10-09 (D200 in main 61309f22). Research only: measured candidates and a recommendation; the owner decides foundational choices.

Owner 2026-10-09 (D200 in main 61309f22). Research only: measured candidates and a recommendation; the owner decides foundational choices.
Author
Owner

Starting native screen capture research on branch research-capture; base SHA 63b1f10e21.

Starting native screen capture research on branch research-capture; base SHA 63b1f10e2112b4d06f7059d4faf196251a58d6a8.
Author
Owner

Finding (2026-10-09): on the shared macOS 27.0 VM (arm64, 4 vCPU, 8 GiB; load averages 0.97/0.94/0.90), /usr/sbin/screencapture -v -V4 -x completed without a new permission prompt. The 4 s recording took 8.42 s wall, 0.21 s process CPU, peak RSS 34,373,632 bytes, and wrote 715,687 bytes. mdls returned null for duration/codec/dimensions, so this run does not yield frame count or per-frame encode latency. No ScreenCaptureKit or CGEvent helper was run; its Screen Recording and Post Event/Accessibility grants were not requested. The CLI result is only a capture+recording-path reference, not a VideoToolbox benchmark.

Finding (2026-10-09): on the shared macOS 27.0 VM (arm64, 4 vCPU, 8 GiB; load averages 0.97/0.94/0.90), `/usr/sbin/screencapture -v -V4 -x` completed without a new permission prompt. The 4 s recording took 8.42 s wall, 0.21 s process CPU, peak RSS 34,373,632 bytes, and wrote 715,687 bytes. `mdls` returned null for duration/codec/dimensions, so this run does not yield frame count or per-frame encode latency. No ScreenCaptureKit or CGEvent helper was run; its Screen Recording and Post Event/Accessibility grants were not requested. The CLI result is only a capture+recording-path reference, not a VideoToolbox benchmark.
Author
Owner

Linux finding (2026-10-09): the host has Xvfb and /dev/dri/card0, but no DRM render node, current user cannot read card0, and the host has no PipeWire/portal tools, X11 headers, or FFmpeg x11grab input. VA-API initialization against card0 fails (No VA display found; exit 234), so the advertised FFmpeg VAAPI/NVENC wrappers are not evidence of usable hardware here. A scoped software-only encoder run (systemd-run --user --scope -p CPUWeight=10000) encoded 120 synthetic 1280×800 frames at 30 fps with libx264 ultrafast/zerolatency, no B frames, GOP 30: 0.947 s wall, 0.730 s user CPU, 0.073 s system CPU, 71,596 KiB child max RSS, 4.61× realtime. Load average was 20.87/19.85/19.98 before and after. This is an encoder-only baseline, not a screen-capture measurement.

Linux finding (2026-10-09): the host has Xvfb and `/dev/dri/card0`, but no DRM render node, current user cannot read card0, and the host has no PipeWire/portal tools, X11 headers, or FFmpeg `x11grab` input. VA-API initialization against card0 fails (`No VA display found`; exit 234), so the advertised FFmpeg VAAPI/NVENC wrappers are not evidence of usable hardware here. A scoped software-only encoder run (`systemd-run --user --scope -p CPUWeight=10000`) encoded 120 synthetic 1280×800 frames at 30 fps with libx264 ultrafast/zerolatency, no B frames, GOP 30: 0.947 s wall, 0.730 s user CPU, 0.073 s system CPU, 71,596 KiB child max RSS, 4.61× realtime. Load average was 20.87/19.85/19.98 before and after. This is an encoder-only baseline, not a screen-capture measurement.
Author
Owner

Finding (2026-10-09): Apple’s macOS 27 support guide lists a distinct Privacy & Security > Remote Desktop control for app access to screen/audio through Remote Desktop, alongside Screen & System Audio Recording. Apple DTS states there is no public API to query the Remote Desktop grant status. The system screencapture CLI spike did not exercise a signed infraternal agent, this privacy category, or CGEvent posting. Treat Remote Desktop, Screen Recording, and Post Event/Accessibility behavior as separate VM checks; do not inspect private TCC databases. Sources: https://support.apple.com/en-au/guide/mac-help/mchl211c911f/mac ; https://support.apple.com/en-au/guide/mac-help/mchle046574e/mac ; https://developer.apple.com/forums/thread/841530

Finding (2026-10-09): Apple’s macOS 27 support guide lists a distinct Privacy & Security > Remote Desktop control for app access to screen/audio through Remote Desktop, alongside Screen & System Audio Recording. Apple DTS states there is no public API to query the Remote Desktop grant status. The system `screencapture` CLI spike did not exercise a signed infraternal agent, this privacy category, or `CGEvent` posting. Treat Remote Desktop, Screen Recording, and Post Event/Accessibility behavior as separate VM checks; do not inspect private TCC databases. Sources: https://support.apple.com/en-au/guide/mac-help/mchl211c911f/mac ; https://support.apple.com/en-au/guide/mac-help/mchle046574e/mac ; https://developer.apple.com/forums/thread/841530
Author
Owner

Finding (2026-10-09): Apple’s published PPPC table lists Post Event and a deny-only Screen Recording control, but no Remote Desktop service. The guide is dated 2024, so the managed grant path for macOS 27 remains unverified rather than disproven. Report now records this gap and requires a signed-app VM check. Source: https://support.apple.com/en-gb/guide/deployment/dep38df53c2a/web

Finding (2026-10-09): Apple’s published PPPC table lists Post Event and a deny-only Screen Recording control, but no Remote Desktop service. The guide is dated 2024, so the managed grant path for macOS 27 remains unverified rather than disproven. Report now records this gap and requires a signed-app VM check. Source: https://support.apple.com/en-gb/guide/deployment/dep38df53c2a/web
Author
Owner

Step complete: recorded bounded Mac CLI and Linux encoder/capability spikes in commit 73c90418. Mac screencapture: 4 s request, 8.42 s wall, 32.8 MiB max RSS; no verified frame count/codec/dimensions. Linux libx264 synthetic 1280×800@30: 4.61× realtime, 0.201 core and 69.9 MiB per process (linear estimates only). scripts/verify fast rerun is still in progress after correcting scratch Zig staging and the fixture parent.

Step complete: recorded bounded Mac CLI and Linux encoder/capability spikes in commit 73c90418. Mac `screencapture`: 4 s request, 8.42 s wall, 32.8 MiB max RSS; no verified frame count/codec/dimensions. Linux libx264 synthetic 1280×800@30: 4.61× realtime, 0.201 core and 69.9 MiB per process (linear estimates only). `scripts/verify fast` rerun is still in progress after correcting scratch Zig staging and the fixture parent.
Author
Owner

Step complete: synthesized macOS, Linux, permissions, browser pipeline, license, and scale trade-offs in research/native-capture/REPORT.md, commit 35d72f21. Estimates remain explicitly unmeasured: three 32-bit capture buffers are 23.7 MiB at 1080p and 94.9 MiB at 4K; ×50 gives 1.16/4.63 GiB. Candidate engine selection remains with the owner under the foundational-choice rule. scripts/verify fast is still running.

Step complete: synthesized macOS, Linux, permissions, browser pipeline, license, and scale trade-offs in `research/native-capture/REPORT.md`, commit 35d72f21. Estimates remain explicitly unmeasured: three 32-bit capture buffers are 23.7 MiB at 1080p and 94.9 MiB at 4K; ×50 gives 1.16/4.63 GiB. Candidate engine selection remains with the owner under the foundational-choice rule. `scripts/verify fast` is still running.
Author
Owner

Gate finding (2026-10-09): scoped scripts/verify fast Rust tests failed in agent_daemon at abrupt restart 22/24. The real binary returned “terminal command queue full” with 4,193,649 input bytes sent, 4,193,632 ACKed, 468,224 bytes pending, and no output observed for that iteration. This is outside the gate’s named baseline exceptions; branch changes are documentation only. Reproducing the exact test in isolation before classifying it.

Gate finding (2026-10-09): scoped `scripts/verify fast` Rust tests failed in `agent_daemon` at abrupt restart 22/24. The real binary returned “terminal command queue full” with 4,193,649 input bytes sent, 4,193,632 ACKed, 468,224 bytes pending, and no output observed for that iteration. This is outside the gate’s named baseline exceptions; branch changes are documentation only. Reproducing the exact test in isolation before classifying it.
Author
Owner

Gate follow-up (2026-10-09): the exact agent_daemon restart test passed in isolation under systemd-run --user --scope -p CPUWeight=10000 with the repository Nix toolchain: all 24 stop positions replayed 4,710,396 payload bytes, including iteration 22. The earlier full-suite queue-full result did not reproduce; no product code changed. Running the full gate again for a final result.

Gate follow-up (2026-10-09): the exact `agent_daemon` restart test passed in isolation under `systemd-run --user --scope -p CPUWeight=10000` with the repository Nix toolchain: all 24 stop positions replayed 4,710,396 payload bytes, including iteration 22. The earlier full-suite queue-full result did not reproduce; no product code changed. Running the full gate again for a final result.
Author
Owner

Finished on research-capture at head 35d72f2185cb2ec88c6cc7d97e9a6d6b3f272932 (spikes: 73c90418d4eba866aabd98cfbdd2ba8bb3d133f7). Added research/native-capture/REPORT.md and the macOS/Linux spike records. No product code or engine choice was added.

The final weighted scripts/verify fast run passed. Gate output excerpts, verbatim:

+---------------------------+--------------+
| Rust gate                 | Result       |
+---------------------------+--------------+
| fmt                       | PASS         |
| VT native fmt             | PASS         |
| clippy                    | PASS         |
| test                      | PASS         |
| cargo-deny                | PASS         |
| static builds             | PASS         |
+---------------------------+--------------+
PT_INTERP: absent; size: 15965392 bytes (baseline 16142672 + allowance 262144 = max 16404816)
PT_INTERP: absent; size: 13426064 bytes (baseline 13555672 + allowance 262144 = max 13817816)
(pass) 1,000 nodes lay out in a few milliseconds [17.10ms]
 54 pass
 0 fail
Ran 54 tests across 12 files. [370.00ms]
stream differential: 134 streams, 11439 schedules, zero divergences
 7 pass
 0 fail
Ran 7 tests across 2 files. [2.56s]

The earlier performance variance was load-sensitive: the 1,000-node layout test once measured 30.49 ms against 25 ms, then passed isolated at 15.93 ms and in the final full run at 17.10 ms. The daemon restart test’s one queue-full result at iteration 22 also passed in isolation and in the final full run.

Finished on `research-capture` at head `35d72f2185cb2ec88c6cc7d97e9a6d6b3f272932` (spikes: `73c90418d4eba866aabd98cfbdd2ba8bb3d133f7`). Added `research/native-capture/REPORT.md` and the macOS/Linux spike records. No product code or engine choice was added. The final weighted `scripts/verify fast` run passed. Gate output excerpts, verbatim: ``` +---------------------------+--------------+ | Rust gate | Result | +---------------------------+--------------+ | fmt | PASS | | VT native fmt | PASS | | clippy | PASS | | test | PASS | | cargo-deny | PASS | | static builds | PASS | +---------------------------+--------------+ PT_INTERP: absent; size: 15965392 bytes (baseline 16142672 + allowance 262144 = max 16404816) PT_INTERP: absent; size: 13426064 bytes (baseline 13555672 + allowance 262144 = max 13817816) (pass) 1,000 nodes lay out in a few milliseconds [17.10ms] 54 pass 0 fail Ran 54 tests across 12 files. [370.00ms] stream differential: 134 streams, 11439 schedules, zero divergences 7 pass 0 fail Ran 7 tests across 2 files. [2.56s] ``` The earlier performance variance was load-sensitive: the 1,000-node layout test once measured 30.49 ms against 25 ms, then passed isolated at 15.93 ms and in the final full run at 17.10 ms. The daemon restart test’s one queue-full result at iteration 22 also passed in isolation and in the final full run.
Author
Owner

Starting the Mac native capture and hardware encoding measurements on branch capture-measure; base SHA 35d72f2185cb2ec88c6cc7d97e9a6d6b3f272932.

Starting the Mac native capture and hardware encoding measurements on branch `capture-measure`; base SHA `35d72f2185cb2ec88c6cc7d97e9a6d6b3f272932`.
Author
Owner

Environment finding: the first locked SSH run stopped before compilation because the Mac VM has no rustup (remote-run.sh line 35: rustup: command not found, exit 127). The EXIT trap released /tmp/mac-bench.lock; no capture probe or privacy change occurred. I will install Rust in the VM user’s home as allowed by the brief.

Environment finding: the first locked SSH run stopped before compilation because the Mac VM has no `rustup` (`remote-run.sh` line 35: `rustup: command not found`, exit 127). The EXIT trap released `/tmp/mac-bench.lock`; no capture probe or privacy change occurred. I will install Rust in the VM user’s home as allowed by the brief.
Author
Owner

VM finding: the locked host reports macOS 27.0, arm64, 4 vCPU, 8 GiB RAM, with load averages 0.74/0.81/0.85 before the first capture attempt. system_profiler SPDisplaysDataType returned no resolution; the harness will record the active display dimensions from CoreGraphics and the captured pixel buffer.

VM finding: the locked host reports macOS 27.0, arm64, 4 vCPU, 8 GiB RAM, with load averages 0.74/0.81/0.85 before the first capture attempt. `system_profiler SPDisplaysDataType` returned no resolution; the harness will record the active display dimensions from CoreGraphics and the captured pixel buffer.
Author
Owner

Finding (2026-10-09): the first no-grant ScreenCaptureKit wrapper display probe ran on macOS 27.0 arm64, 4 vCPU / 8 GiB, load 0.95/1.05/1.05. At 2502×1326 over 12 s it reported 47 complete and 245 idle frames (257 deliveries), p50/p95 display-time-to-callback 677/1883 ms, 0.17 s process CPU, and 18,300,928 bytes max RSS. The Rust runner starts after adding the selected macOS Swift runtime rpath; no privacy list was changed. ObjC2 and window probes are still running.

Finding (2026-10-09): the first no-grant ScreenCaptureKit wrapper display probe ran on macOS 27.0 arm64, 4 vCPU / 8 GiB, load 0.95/1.05/1.05. At 2502×1326 over 12 s it reported 47 complete and 245 idle frames (257 deliveries), p50/p95 display-time-to-callback 677/1883 ms, 0.17 s process CPU, and 18,300,928 bytes max RSS. The Rust runner starts after adding the selected macOS Swift runtime rpath; no privacy list was changed. ObjC2 and window probes are still running.
Author
Owner

Finding (2026-10-09): ScreenCaptureKit works from the ungranted SSH-launched executable; no TCC entries were added. On the same VM run (load 0.95/1.05/1.05 before, 1.40/1.18/1.10 after), the generated-binding display request was 5004×2652 and delivered 48 complete / 242 idle frames with 0.13 s CPU and 17,793,024 B max RSS; the 960×600 region delivered 1 complete / 300 idle with p50/p95 over all statuses 506/1662 ms, 0.16 s CPU, 17,760,256 B max RSS. Wrapper window at 480×300 reported p50/p95 0.91/5.62 ms, 0.14 s CPU, 18,251,776 B max RSS, but its Retina scale metadata is 2 and the configured output was only 480×300. I’m correcting window dimensions and separating complete-frame delay from idle-frame age before treating capture latency as comparable.

Finding (2026-10-09): ScreenCaptureKit works from the ungranted SSH-launched executable; no TCC entries were added. On the same VM run (load 0.95/1.05/1.05 before, 1.40/1.18/1.10 after), the generated-binding display request was 5004×2652 and delivered 48 complete / 242 idle frames with 0.13 s CPU and 17,793,024 B max RSS; the 960×600 region delivered 1 complete / 300 idle with p50/p95 over all statuses 506/1662 ms, 0.16 s CPU, 17,760,256 B max RSS. Wrapper window at 480×300 reported p50/p95 0.91/5.62 ms, 0.14 s CPU, 18,251,776 B max RSS, but its Retina scale metadata is 2 and the configured output was only 480×300. I’m correcting window dimensions and separating complete-frame delay from idle-frame age before treating capture latency as comparable.
Author
Owner

Finding (2026-10-09): with complete frames separated from idle callbacks, both ScreenCaptureKit paths produced a 5004×2652 full-display sample at point scale 2 on macOS 27 arm64 (4 vCPU / 8 GiB; load 0.89/1.08/1.07 before and 1.09/1.12/1.08 after). Wrapper: 46 complete, 235 idle, 11 timestamped completes, 4.06 ms p50 / 2019.9 ms p95, 0.16 s CPU, 18,268,160 B max RSS. Generated objc2: 49 complete, 232 idle, 13 timestamped completes, 4.14 ms p50 / 1963.3 ms p95, 0.13 s CPU, 17,793,024 B max RSS. The long tail has one or two outliers in small timestamped samples; p95 needs this sample-count caveat. At 960×600 window/region: wrapper had 55 complete, no idle, 0.535/2.231 ms p50/p95, 0.09 s CPU, 18,251,776 B max RSS; generated objc2 had 1 complete + 299 idle, 1 timestamped complete at 4.46 ms, 0.14 s CPU, 17,711,104 B max RSS. Idle callbacks continued around 25/s on an unchanged display/region, with ~0.5–0.8 s median callback age; this is an observed idle-wakeup cost, not a claim that idle capture suspends. The marker’s reported backing scale was 2.0. The harness now requests/records the 960×600 Retina window output and records actual sample dimensions.

Finding (2026-10-09): with complete frames separated from idle callbacks, both ScreenCaptureKit paths produced a 5004×2652 full-display sample at point scale 2 on macOS 27 arm64 (4 vCPU / 8 GiB; load 0.89/1.08/1.07 before and 1.09/1.12/1.08 after). Wrapper: 46 complete, 235 idle, 11 timestamped completes, 4.06 ms p50 / 2019.9 ms p95, 0.16 s CPU, 18,268,160 B max RSS. Generated objc2: 49 complete, 232 idle, 13 timestamped completes, 4.14 ms p50 / 1963.3 ms p95, 0.13 s CPU, 17,793,024 B max RSS. The long tail has one or two outliers in small timestamped samples; p95 needs this sample-count caveat. At 960×600 window/region: wrapper had 55 complete, no idle, 0.535/2.231 ms p50/p95, 0.09 s CPU, 18,251,776 B max RSS; generated objc2 had 1 complete + 299 idle, 1 timestamped complete at 4.46 ms, 0.14 s CPU, 17,711,104 B max RSS. Idle callbacks continued around 25/s on an unchanged display/region, with ~0.5–0.8 s median callback age; this is an observed idle-wakeup cost, not a claim that idle capture suspends. The marker’s reported backing scale was 2.0. The harness now requests/records the 960×600 Retina window output and records actual sample dimensions.
Author
Owner

Finding (2026-10-09): the first CGEventPost probe ran without requesting access and returned from both posts, but the visible marker logged no mouseDown and no phase change. post-input measured 6.10 ms from entering the down-post call to return and 180.3 ms between down/up posts; this is not injection-to-visible latency because no visible change occurred. ScreenCaptureKit continues to work without a grant. I will follow the approved VNC procedure to add only Post Event access to ~/infraternal-bench/capture-measure/capture-measure; I will not add Screen Recording access unless a later capture path actually requires it.

Finding (2026-10-09): the first CGEventPost probe ran without requesting access and returned from both posts, but the visible marker logged no mouseDown and no phase change. `post-input` measured 6.10 ms from entering the down-post call to return and 180.3 ms between down/up posts; this is not injection-to-visible latency because no visible change occurred. ScreenCaptureKit continues to work without a grant. I will follow the approved VNC procedure to add only Post Event access to `~/infraternal-bench/capture-measure/capture-measure`; I will not add Screen Recording access unless a later capture path actually requires it.
Author
Owner

Correction/result: the earlier no-click probe used y=663, which missed the marker; it did not demonstrate denial. With the marker frontmost at (1251,415), 21/21 CGEvent clicks produced mouse-down and draw callbacks. Inject-to-draw: p50 10.013 ms, p95 12.420 ms, range 8.809–13.064 ms (mach timebase 125/3), on macOS 27.0 arm64/4 vCPU; run load averages 1.39/1.96/1.83 before and 1.36/1.87/1.81 after. CGPreflightPostEventAccess was true; its request returned true without a dialog. No Screen Recording or Post Event entry was added or changed.

Correction/result: the earlier no-click probe used y=663, which missed the marker; it did not demonstrate denial. With the marker frontmost at (1251,415), 21/21 CGEvent clicks produced mouse-down and draw callbacks. Inject-to-draw: p50 10.013 ms, p95 12.420 ms, range 8.809–13.064 ms (mach timebase 125/3), on macOS 27.0 arm64/4 vCPU; run load averages 1.39/1.96/1.83 before and 1.36/1.87/1.81 after. CGPreflightPostEventAccess was true; its request returned true without a dialog. No Screen Recording or Post Event entry was added or changed.
Author
Owner

Window comparison: the maintained wrapper captured the marker window at 960x600 (2x scale), 66 complete/1 idle callbacks, complete-delivery p50 0.773 ms/p95 1.929 ms, 0.05 s CPU and 18,399,232 B max RSS. Host load was 0.98/1.85/1.83 before and 0.83/1.77/1.80 after. The generated objc2 display probe captured 5004x2652; its new desktop-independent window filter aborts with CGS_REQUIRE_INIT before delivering frames, so that window candidate remains unmeasured. Investigating the direct binding path.

Window comparison: the maintained wrapper captured the marker window at 960x600 (2x scale), 66 complete/1 idle callbacks, complete-delivery p50 0.773 ms/p95 1.929 ms, 0.05 s CPU and 18,399,232 B max RSS. Host load was 0.98/1.85/1.83 before and 0.83/1.77/1.80 after. The generated objc2 display probe captured 5004x2652; its new desktop-independent window filter aborts with `CGS_REQUIRE_INIT` before delivering frames, so that window candidate remains unmeasured. Investigating the direct binding path.
Author
Owner

Window-path update: initWithDesktopIndependentWindow aborted with CGS_REQUIRE_INIT. The generated objc2 path now uses initWithDisplay_includingWindows plus the selected window frame as sourceRect and succeeds. With a 10 Hz marker at 960x600, wrapper: 99 complete, 0 idle, p50 0.921 ms/p95 3.586 ms, 0.07 s CPU, 18,333,696 B max RSS. objc2: 81 complete/258 idle, 32 timed completes, p50 29.575 ms/p95 158.582 ms, 0.07 s CPU, 17,858,560 B max RSS. Host load 1.64/1.67/1.74 before and 1.70/1.67/1.73 after. The VM-reported source display had changed to 1748x1000 (from 2502x1326 earlier); the measured output region remained 960x600 at 2x.

Window-path update: `initWithDesktopIndependentWindow` aborted with CGS_REQUIRE_INIT. The generated objc2 path now uses `initWithDisplay_includingWindows` plus the selected window frame as sourceRect and succeeds. With a 10 Hz marker at 960x600, wrapper: 99 complete, 0 idle, p50 0.921 ms/p95 3.586 ms, 0.07 s CPU, 18,333,696 B max RSS. objc2: 81 complete/258 idle, 32 timed completes, p50 29.575 ms/p95 158.582 ms, 0.07 s CPU, 17,858,560 B max RSS. Host load 1.64/1.67/1.74 before and 1.70/1.67/1.73 after. The VM-reported source display had changed to 1748x1000 (from 2502x1326 earlier); the measured output region remained 960x600 at 2x.
Author
Owner

Completed VideoToolbox hardware measurements; commit f24604a899. One 1920x1080, 300-frame, 60 fps session per run, with a four-buffer input pool, no frame reordering and a 30-frame GOP. Hardware selection reported true for H.264 and HEVC. The VM logged IOServiceMatchingfailed for: AppleM2ScalerParavirtDriver; this did not prevent hardware selection.

H.264 at 2/5/10 Mbps targets: callback latency p50 27.231/25.122/26.014 ms, p95 41.417/39.653/39.706 ms; measured bitrate 1.181/0.201/0.285 Mbps. HEVC at the same targets: p50 28.673/29.656/27.991 ms, p95 43.634/42.850/42.196 ms; bitrate 1.554/1.568/0.319 Mbps. All six runs encoded 300 frames with 10 keyframes and no errors. The moving checker pattern is low motion and content-dependent; these rates do not establish screen-content quality or target-bitrate tracking.

Peak RSS was 86.0–86.3 MB per session; process CPU was 0.73–0.80 core-seconds over about 5.2 seconds, including pattern generation. Linear planning arithmetic gives about 0.86 GB RSS and 1.4–1.5 CPU cores for 10 sessions, and 4.3 GB and 7–7.5 cores for 50. This is not a concurrent capacity result; the VM has 4 vCPUs. Load averages were 1.25/1.11/1.41 before and 1.37/1.15/1.41 after.

Completed VideoToolbox hardware measurements; commit f24604a899affcf7b315c601e64abf3c1d0dcefd. One 1920x1080, 300-frame, 60 fps session per run, with a four-buffer input pool, no frame reordering and a 30-frame GOP. Hardware selection reported true for H.264 and HEVC. The VM logged `IOServiceMatchingfailed for: AppleM2ScalerParavirtDriver`; this did not prevent hardware selection. H.264 at 2/5/10 Mbps targets: callback latency p50 27.231/25.122/26.014 ms, p95 41.417/39.653/39.706 ms; measured bitrate 1.181/0.201/0.285 Mbps. HEVC at the same targets: p50 28.673/29.656/27.991 ms, p95 43.634/42.850/42.196 ms; bitrate 1.554/1.568/0.319 Mbps. All six runs encoded 300 frames with 10 keyframes and no errors. The moving checker pattern is low motion and content-dependent; these rates do not establish screen-content quality or target-bitrate tracking. Peak RSS was 86.0–86.3 MB per session; process CPU was 0.73–0.80 core-seconds over about 5.2 seconds, including pattern generation. Linear planning arithmetic gives about 0.86 GB RSS and 1.4–1.5 CPU cores for 10 sessions, and 4.3 GB and 7–7.5 cores for 50. This is not a concurrent capacity result; the VM has 4 vCPUs. Load averages were 1.25/1.11/1.41 before and 1.37/1.15/1.41 after.
Author
Owner

Completed the capture-to-WebCodecs proxy; harness commit 032e95ab5a. ScreenCaptureKit callback timestamps followed hardware H.264 and Chromium WebCodecs decode to canvas. Two runs decoded 36 and 35 frames; callback-to-canvas p50/p95 were 242.447/527.164 ms and 267.742/515.419 ms. The repeat was 4.79 s, peak RSS 33,718,272 bytes, with 0.12 CPU seconds reported by /usr/bin/time -lp; VM load averages were 1.24/1.26/1.31 before and 1.22/1.25/1.31 after. Hardware encoder property was true; the VM also logged IOServiceMatchingfailed for: AppleM2ScalerParavirtDriver.

The relay used TCP from the Mac VM to Chromium on infraternal-dev. Its repeat handshake round trip was 148.6 ms, so this result includes the private network path and is not a loopback or product-transport measurement. Timestamps mark ScreenCaptureKit delivery callbacks. The browser harness ran under systemd-run --user --scope -p CPUWeight=10000 with TRACER_TEST_PORT=4390; dev load averages were 7.19/8.05/6.83 before and 8.88/8.33/6.98 after. No TCC entries were added or changed.

Completed the capture-to-WebCodecs proxy; harness commit 032e95ab5a3dab4b4fac97c177e1dc1179407313. ScreenCaptureKit callback timestamps followed hardware H.264 and Chromium WebCodecs decode to canvas. Two runs decoded 36 and 35 frames; callback-to-canvas p50/p95 were 242.447/527.164 ms and 267.742/515.419 ms. The repeat was 4.79 s, peak RSS 33,718,272 bytes, with 0.12 CPU seconds reported by `/usr/bin/time -lp`; VM load averages were 1.24/1.26/1.31 before and 1.22/1.25/1.31 after. Hardware encoder property was true; the VM also logged `IOServiceMatchingfailed for: AppleM2ScalerParavirtDriver`. The relay used TCP from the Mac VM to Chromium on infraternal-dev. Its repeat handshake round trip was 148.6 ms, so this result includes the private network path and is not a loopback or product-transport measurement. Timestamps mark ScreenCaptureKit delivery callbacks. The browser harness ran under `systemd-run --user --scope -p CPUWeight=10000` with `TRACER_TEST_PORT=4390`; dev load averages were 7.19/8.05/6.83 before and 8.88/8.33/6.98 after. No TCC entries were added or changed.
Author
Owner

Added the isolated AGPL measurement crate and declared wrapper, generated objc2, and CoreGraphics dependencies in commit 27b89b09a7. The crate is outside the product workspace; candidate modules are landing independently. D200 and D203 C4 remain owner decisions.

Added the isolated AGPL measurement crate and declared wrapper, generated objc2, and CoreGraphics dependencies in commit 27b89b09a7e8ef43e052209094dc89b17c95792d. The crate is outside the product workspace; candidate modules are landing independently. D200 and D203 C4 remain owner decisions.
Author
Owner

Added the maintained Rust ScreenCaptureKit measurement path and shared host-time conversion in commit 55d5c73230. Full-display capture reported 44 complete/293 idle callbacks; 16 timed completes had p50 4.431 ms and p95 1961.787 ms. The animated 960x600 window run reported 99 complete/0 idle, p50 0.921 ms and p95 3.586 ms; process peak RSS was 18,333,696 bytes. The full-display p95 has only 16 timed samples and is dominated by long stalls.

Added the maintained Rust ScreenCaptureKit measurement path and shared host-time conversion in commit 55d5c73230374c30cddb5521238fe94cbd7731d8. Full-display capture reported 44 complete/293 idle callbacks; 16 timed completes had p50 4.431 ms and p95 1961.787 ms. The animated 960x600 window run reported 99 complete/0 idle, p50 0.921 ms and p95 3.586 ms; process peak RSS was 18,333,696 bytes. The full-display p95 has only 16 timed samples and is dominated by long stalls.
Author
Owner

Added the generated objc2 ScreenCaptureKit candidate in commit ba6e257482. Full-display capture produced 36 complete/258 idle callbacks; 13 timed completes had p50 5.707 ms and p95 1967.556 ms. The animated 960x600 window path produced 81 complete/258 idle, with 32 timed completes at p50 29.575 ms and p95 158.582 ms. The desktop-independent window initializer aborted with CGS_REQUIRE_INIT; the display-including-windows filter with the window frame as source rectangle passed.

Added the generated objc2 ScreenCaptureKit candidate in commit ba6e2574820667e389421d3ce1e7062c6fae00b9. Full-display capture produced 36 complete/258 idle callbacks; 13 timed completes had p50 5.707 ms and p95 1967.556 ms. The animated 960x600 window path produced 81 complete/258 idle, with 32 timed completes at p50 29.575 ms and p95 158.582 ms. The desktop-independent window initializer aborted with `CGS_REQUIRE_INIT`; the display-including-windows filter with the window frame as source rectangle passed.
Author
Owner

Added the CGEvent marker input probe in commit 708f7bfe7f. With the marker frontmost at (1251, 415) points, 21/21 clicks produced mouse-down and draw callbacks; inject-to-visible-draw p50 was 10.013 ms, p95 12.420 ms, range 8.809–13.064 ms. Post Event preflight and request returned true. No TCC entries were added or changed.

Added the CGEvent marker input probe in commit 708f7bfe7f75d7e5ff1d41cd898e3b636261e0fa. With the marker frontmost at (1251, 415) points, 21/21 clicks produced mouse-down and draw callbacks; inject-to-visible-draw p50 was 10.013 ms, p95 12.420 ms, range 8.809–13.064 ms. Post Event preflight and request returned true. No TCC entries were added or changed.
Author
Owner

Added the locked-VM measurement runner and usage guide in commit daa23c79c7. It builds and runs the candidate modules under ~/infraternal-bench/capture-measure, records machine/load context, and terminates its marker process on exit. The per-job directory has been removed and the mac-bench lock was released by its EXIT trap.

Added the locked-VM measurement runner and usage guide in commit daa23c79c7c23f1f4be3ee88f5cf17e78806d48b. It builds and runs the candidate modules under `~/infraternal-bench/capture-measure`, records machine/load context, and terminates its marker process on exit. The per-job directory has been removed and the mac-bench lock was released by its EXIT trap.
Author
Owner

Added the owner-first measurement report in commit 57346fc31d. It records both SCK candidates, Retina window results, encoder rows/settings and ×10/×50 arithmetic, event-to-draw timing, and the two WebCodecs proxy runs, with machine/load context and limits. The E2E repeat remains 35 decoded frames at p50 267.742 ms / p95 515.419 ms over the VM-to-dev TCP path. No TCC entries were added, removed, or changed.

Added the owner-first measurement report in commit 57346fc31d13208950202854fc49db899da8f6b5. It records both SCK candidates, Retina window results, encoder rows/settings and ×10/×50 arithmetic, event-to-draw timing, and the two WebCodecs proxy runs, with machine/load context and limits. The E2E repeat remains 35 decoded frames at p50 267.742 ms / p95 515.419 ms over the VM-to-dev TCP path. No TCC entries were added, removed, or changed.
Author
Owner

The first fast-gate attempt passed fmt, Zig fmt, Clippy, and cargo-deny. One test and the static builds failed because repository scripts assume target/ exists: an agent test creates target/<state> directly, while the musl wrapper resolves target/auth-tools/zig/zig. The required CARGO_TARGET_DIR was under job scratch, so those repository-relative paths were absent. I will rerun with a worktree target symlink to the scratch target; build data remains in scratch.

The first fast-gate attempt passed fmt, Zig fmt, Clippy, and cargo-deny. One test and the static builds failed because repository scripts assume `target/` exists: an agent test creates `target/<state>` directly, while the musl wrapper resolves `target/auth-tools/zig/zig`. The required CARGO_TARGET_DIR was under job scratch, so those repository-relative paths were absent. I will rerun with a worktree `target` symlink to the scratch target; build data remains in scratch.
Author
Owner

The required detached dev baseline test was run at SHA 7d6df4470c. auth::tests::socket_tests::expired_handshake_releases_user_permits passed 1/1 in 0.57 s; load averages were 19.98/15.16/12.60 before and 14.70/15.40/13.07 after. The baseline result did not reproduce the candidate gate's failure, so I will rerun that exact candidate test and the gate before classifying it.

The required detached `dev` baseline test was run at SHA 7d6df4470cfce59661225c0f3dbcbf2a36827ab1. `auth::tests::socket_tests::expired_handshake_releases_user_permits` passed 1/1 in 0.57 s; load averages were 19.98/15.16/12.60 before and 14.70/15.40/13.07 after. The baseline result did not reproduce the candidate gate's failure, so I will rerun that exact candidate test and the gate before classifying it.
Author
Owner

The exact candidate test rerun passed 1/1 in 0.53 s: auth::tests::socket_tests::expired_handshake_releases_user_permits. Load averages were 15.55/17.19/15.01 before and 12.59/15.93/14.87 after. The first candidate-gate failure was not reproduced on retry; the full fast gate is being rerun with the corrected scratch target link.

The exact candidate test rerun passed 1/1 in 0.53 s: `auth::tests::socket_tests::expired_handshake_releases_user_permits`. Load averages were 15.55/17.19/15.01 before and 12.59/15.93/14.87 after. The first candidate-gate failure was not reproduced on retry; the full fast gate is being rerun with the corrected scratch target link.
Author
Owner

Finished at head 57346fc31d.

Report: research/native-capture/MEASURE.md. Spike code is in research/native-capture/spikes/measure. No product code changed. No TCC grants were added and no pre-existing Privacy & Security entries were changed; the Mac lock and temporary benchmark directory were cleaned.

scripts/verify fast exited 0. Verbatim gate summaries:

+---------------------------+--------------+
| Rust gate | Result |
+---------------------------+--------------+
| fmt | PASS |
| VT native fmt | PASS |
| clippy | PASS |
| test | PASS |
| cargo-deny | PASS |
| static builds | PASS |
+---------------------------+--------------+

54 pass
0 fail
9930 expect() calls
Ran 54 tests across 12 files. [6.16s]

stream differential: 134 streams, 11439 schedules, zero divergences
7 pass
0 fail
34390 expect() calls
Ran 7 tests across 2 files. [17.93s]

Finished at head 57346fc31d13208950202854fc49db899da8f6b5. Report: research/native-capture/MEASURE.md. Spike code is in research/native-capture/spikes/measure. No product code changed. No TCC grants were added and no pre-existing Privacy & Security entries were changed; the Mac lock and temporary benchmark directory were cleaned. scripts/verify fast exited 0. Verbatim gate summaries: +---------------------------+--------------+ | Rust gate | Result | +---------------------------+--------------+ | fmt | PASS | | VT native fmt | PASS | | clippy | PASS | | test | PASS | | cargo-deny | PASS | | static builds | PASS | +---------------------------+--------------+ 54 pass 0 fail 9930 expect() calls Ran 54 tests across 12 files. [6.16s] stream differential: 134 streams, 11439 schedules, zero divergences 7 pass 0 fail 34390 expect() calls Ran 7 tests across 2 files. [17.93s]
Author
Owner

Closed by the orchestrator during the 2026-10-28 handover (#254), on the owner's request to close finished issues. Evidence: Research delivered (research/native-capture/MEASURE.md, 57346fc3) and owner decision recorded as D204 (macOS capture bindings and encoder). Reopen if anything is still missing.

Closed by the orchestrator during the 2026-10-28 handover (#254), on the owner's request to close finished issues. Evidence: Research delivered (research/native-capture/MEASURE.md, 57346fc3) and owner decision recorded as D204 (macOS capture bindings and encoder). Reopen if anything is still missing.
kayg closed this issue 2026-10-28 17:52:49 +00:00
Sign in to join this conversation.
No labels
launch-qa
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
kayg/infraternal#139
No description provided.