# Sync 1080p60: browser sender versus paced producer 10 September 2026 · Research report · Measured on an Apple M4 / 32 GiB host (macOS 26.5, Chrome 152.0.7977.83) **Recommendation:** instrument the camera extension's consume cycle, the stage between the daemon's CMIO sink enqueue (the pts stamp) and the extension's relay stamp, before changing it. That stage is the next boundary to change for the arrival jitter that persists with a paced producer; the plan's precondition for changing it (evidence of missed arrival deadlines plus idle CPU and power measurements) is not met by this leg. Hand the browser sender's one-period late send to plan section 4B. Do not shorten the extension's 4 ms empty-queue wait on this evidence. This report describes arrival timing at a reader: VideoFrames handed to a MediaStreamTrackProcessor reader in a Chrome receiver page, or CMSampleBuffers handed to an AVCaptureVideoDataOutput delegate in a native AVFoundation client. No arm measured final rendered pixels, unique delivered FPS, or marker age as plan section 3 defines them, and no count here is a delivered-pixel count. The measurements are web only; no desktop build ran. They cover eight 20 s windows (four arms in each of two runs) recorded inside six minutes of wall time on one host. ## 1. Question and design Plan section 4A asks: does the browser sender create the arrival jitter, or does jitter persist with a paced native producer? Its decision rule: if paced production reduces arrival jitter and repeated selection, investigate sender export, pacing and socket pressure next (plan section 4B); if jitter persists, instrument native submission, extension consumption and browser arrival; if the difference is inconclusive, preserve the result and proceed to one targeted stage trace; do not sweep timing constants. The deliverable is one stage-timing diagram, source receipts and a decision naming the next boundary to change. The design is a 2 x 2 of producer by receiver. Each cell ran once per run. Run 1 ran browser-chrome, native-chrome, browser-avf, native-avf; run 2 ran native-chrome, browser-chrome, native-avf, browser-avf, so the producer order is reversed within each receiver pair while the receiver-pair order (Chrome pair first) is the same in both runs. The two producers: - Browser sender: Noisedeck A (export b7c0cb0a, SDK 0.1.5) rendering its startup scene at 1920x1080 and sending through the SDK frame sink (maxBufferedFrames = 1) over a loopback WebSocket. A send hook on the page records every `socket.send` (sequence, SDK presentation stamp, time, bufferedAmount before the send, bytes) and every sink refusal, and a 1 Hz loop reads the SDK sender counters. - Paced producer: a Node process (`bin/paced-producer.mjs`) writing a 14-byte WebSocket header and an 8294464-byte 1920x1080 payload per frame (pixel format field 1; alphaMode field 3, against the 1 the SDK writes per its source, since the hook did not record header values) at absolute monotonic deadlines, 60 frames per second, over a loopback WebSocket. Each picture carries a 24-bit sequence marker. The producer records its deadline, submit time, write-completion time and schedule error per frame and samples the daemon's accepted and dropped counters once per second. The two receivers: - Chrome reader (chrome): Noisedeck B's page in Chrome 152.0.7977.83, loaded only to host a recorder. The recorder attaches the Sync Camera stream to a muted, never-inserted video element (so the element's own totalVideoFrames can be read at start and end) and runs one MediaStreamTrackProcessor reader; per frame it copies the NV12 picture out (copyTo), decodes the marker where one exists and hashes the luma plane. It does not upload into Noisedeck's media effect. - AVFoundation delegate (avf): a standalone AVCaptureSession client on the same Sync Camera device, requesting BGRA 1920x1080. Per sample it records the presentation stamp (pts), the CMIO host-time attachment the extension sets at relay, the CMIO sequence number and discontinuity flag, the sample duration and its own delegate entry time on the mach clock. No Chrome process runs during these arms. Both receivers see the same daemon and the same installed camera extension. Both producers feed the same daemon socket, frame fitter (into a 1920x1080 BGRA pixel buffer), CMIO sink enqueue with a fresh host-time pts, and extension consume and relay; the format contract differs in the alphaMode field, and the daemon's handling of value 3 beyond the fitter's alpha branch was not verified. The marker identity exists only in the paced producer's picture, so identity joins (producer sequence to receiver marker) exist only in the native arms; the browser arms are compared by intervals and by consecutive luma-hash change. Fixtures. | Fixture | Revision or value | |---|---| | Daemon | Sync 0.2.65, built from sync `d167ee4fefb12ad714f8b20023f4d2ddaed0e840`; syncd sha256 `d157fe7447522ac63cbfd499ddf6b2c28e500760dc11615a4dbad62174f3a3cd`; restarted per arm in test mode with a fresh instance id per arm | | Camera extension | Installed 0.2.38, executable sha256 `67bbc9fa19f5ed14a9525281f7750198eb78b5d1314e0646026227df40a69eba`; asserted to be built from sync 865cc2e. The extension source (camera_extension/main.mm) is byte-identical from 7fdfdc9 through d167ee4, so the same extension source stands at 865cc2e and at d167ee4; the mapping of the installed bundle to that commit is asserted, not shown. One extension process served all eight arms. | | Noisedeck | Export b7c0cb0a (Noisedeck `b7c0cb0ac3e89ea5aa5552e35dde642f6dbbad09` in the plan), SDK 0.1.5; browser arms only | | Chrome | Chrome/152.0.7977.83 in the six arms that launched Chrome; the two native-avf arms ran no Chrome | | Node | v26.0.0 | | Host | Apple M4, 10 logical CPUs, 32 GiB (totalMemBytes 34359738368), macOS 26.5 build 25F71, kernel 25.5.0 | | Windows | Warmup 5 s, measurement 20 s, interior window 7.5 s to 12.5 s into the measurement window (5.000 s). The receiver started before the producer in every arm and saw the extension's idle picture first; those pre-window frames are excluded from both windows by epoch time. | | Frames | 1920x1080 at every receiver in every window; 8294464 bytes per frame on the socket; NV12 at the Chrome reader, BGRA at the AVF delegate | Arm order. | Run | Arm | Producer | Receiver | Started (UTC) | |---|---|---|---|---| | 1 | browser-chrome | browser sender | Chrome reader | 2026-09-10T21:55:08.065Z | | 1 | native-chrome | paced producer | Chrome reader | 2026-09-10T21:55:59.357Z | | 1 | browser-avf | browser sender | AVF delegate | 2026-09-10T21:56:49.665Z | | 1 | native-avf | paced producer | AVF delegate | 2026-09-10T21:57:30.860Z | | 2 | native-chrome | paced producer | Chrome reader | 2026-09-10T21:58:35.807Z | | 2 | browser-chrome | browser sender | Chrome reader | 2026-09-10T21:59:17.607Z | | 2 | native-avf | paced producer | AVF delegate | 2026-09-10T22:00:08.782Z | | 2 | browser-avf | browser sender | AVF delegate | 2026-09-10T22:00:39.896Z | ## 2. Measurement contract as applied Windows. warmupS = 5 and measureS = 20 in every manifest. Window membership is by epoch millisecond mapped from each process's own clock. Interval arithmetic uses the receiver's own monotonic clock: `performance.now()` at `reader.read()` (0.1 ms resolution) for Chrome and `mach_absolute_time` at delegate entry for AVF. The interior window is 7.5 s to 12.5 s into the measurement window. The warmup clock starts at different events per producer: after Noisedeck A reported "sending" and the canvas resize returned in browser arms, at producer spawn in native arms. Conventions. Percentiles are nearest-rank (rank = ceil(p x n)); sd is the sample standard deviation (n - 1); "raw" arrival intervals are between every arrival the reader received, including re-delivered repeats; "distinct-picture" intervals exclude arrivals whose luma hash equals the previous arrival's. Every number below is quoted as its source file prints it; the statistics tables print three decimals and the per-frame analysis records print more. Where a longer value from a record is shortened it keeps at least three decimals and is marked here once as rounded: the cross-process join bounds 1.010498046875, 1.010009765625, 1.7998046875 and 1.900146484375 ms appear below as 1.01, 1.01, 1.80 and 1.90 ms (rounded). Observer cost. Each reader does work per frame that a product page does not, and no arm ran without it, so the readers' effect on their own arrival timing is bounded, not measured. Observer cost per frame. | Observer | Arm | mean | p50 | p95 | p99 | max | Note | |---|---|---|---|---|---|---|---| | Chrome reader readCostMs (copyTo + marker decode + luma hash), ms | run1 browser-chrome | 0.6049742584163084 | 0.5999994277954102 | 0.9000005722045898 | 1.1999998092651367 | 1.8000001907348633 | p95 over interval p50 0.05357146202301454 | | Chrome reader readCostMs, ms | run1 native-chrome | 0.839749984741211 | 0.8000001907348633 | 1.1000003814697266 | 1.5 | 1.9000005722045898 | p95 over interval p50 0.06547621243935299 | | Chrome reader readCostMs, ms | run2 browser-chrome | 0.6021079212979965 | 0.5999994277954102 | 0.9000005722045898 | 1.1999998092651367 | 2.0 | p95 over interval p50 0.05357146202301454 | | Chrome reader readCostMs, ms | run2 native-chrome | 0.8063492141570663 | 0.8000001907348633 | 1.1000003814697266 | 1.3000001907348633 | 1.8000001907348633 | p95 over interval p50 0.06358383637815446 | | AVF delegate busyUs (whole delegate callback), us | run1 browser-avf | 1486.0 | 1543.6 | 2131.3 | 2623.0 | 2963.9 | alwaysDiscardsLateVideoFrames = false; consumer drops 0 | | AVF delegate busyUs, us | run1 native-avf | 1177.6 | 1206.4 | 1624.5 | 2116.7 | 2477.4 | consumer drops 0 | | AVF delegate busyUs, us | run2 browser-avf | 1373.5 | 1433.2 | 2033.5 | 2356.8 | 2720.9 | consumer drops 0 | | AVF delegate busyUs, us | run2 native-avf | 1172.4 | 1196.8 | 1493.3 | 2100.0 | 2221.7 | consumer drops 0 | | Sender page 1 Hz senderStats evaluate, ms (browser arms) | run1 browser-chrome, run1 browser-avf, run2 browser-chrome, run2 browser-avf | n/a | n/a | n/a | n/a | 6 / 5 / 5 / 5 | 20 in-window samples per arm; the loop was never disabled | | Send hook on the sender page | all four browser arms | n/a | n/a | n/a | n/a | n/a | cost per call not recorded; no hook-free arm | Clock join bounds. Where an identity join crosses processes (native arms), the level of a latency carries a measured bound: the producer anchor (one Date.now() sample, 1.0 ms) plus the receiver's anchor offset: 1.01 ms for both native-avf arms, 1.80 ms (run 1) and 1.90 ms (run 2) for native-chrome. Interval and spread statistics do not carry this bound because each interval chain is on one clock. The pts to relay and relay to delegate stages are on one mach clock. Browser arms have no cross-process identity join. Host state. AC power throughout (battery 80 %, not charging); no thermal warning recorded (the absence of a recorded warning, not a temperature measurement); harness, daemon, producer and consumer at nice 0; Chrome's nice value was not recorded. One-minute load average before each arm 1.61 to 3.56 and after 2.38 to 3.66. CPU was sampled only at arm endpoints, GPU activity was not sampled, and no idle baseline exists for this host. Two AI coding-agent sessions and system indexers were active on the host (fseventsd at 50.7 % before run1 browser-chrome; corespotlightd at 38.4 % before run1 native-chrome). Nothing was stopped. Integrity. Every manifest is ok and valid with no warnings. Every analysis has accountingValid = true with 0 rejected receiver records. Chrome arms have elementFramesDeltaMinusDelivered = 0 (the video element's totalVideoFrames delta equals the reader's delivered count), overflow 0 and reader errors 0; Chrome exposes no drop callback. AVF arms have 0 didDropSampleBuffer records. Native arms have producer framesSkipped 0 and daemon dropped = 0 at every one of the 26 stats samples per arm, with accepted equal to frames submitted; the daemon counter was not sampled in the browser arms. secondsBelow50 = 0 and secondsBelow55 = 0 in all eight windows, and both native-avf arms recorded 60 arrivals in every complete second. Those are reader counts, not delivery. ## 3. Results: arrival timing at both receivers Table 1 gives the 20 s windows; Table 2 the interior 5 s windows. Raw intervals include re-delivered repeats, which is why the browser-chrome rows have a minimum below 1 ms. Missing markers apply to native arms only (the browser picture carries no marker). Table 1. Arrival timing, 20 s windows. | Arm | Receiver | Run | Arrivals | Arrivals/s | Interval mean ms | sd | p50 | p95 | p99 | max | Consecutive repeats | Same-timestamp pairs | Gaps > 25 ms | Missing markers | |---|---|---|---|---|---|---|---|---|---|---|---|---|---|---| | browser-chrome | chrome | 1 | 1166 | 58.297 | 17.152 | 5.876 | 16.800 | 29.600 | 39.600 | 49.300 | 44 | 30 | 73 | n/a | | native-chrome | chrome | 1 | 1200 | 59.994 | 16.667 | 2.829 | 16.800 | 21.400 | 23.200 | 25.900 | 0 | 0 | 1 | 0 | | browser-avf | avf | 1 | 1167 | 58.344 | 17.139 | 4.288 | 16.944 | 22.064 | 38.638 | 41.219 | 0 | 0 (pts) | 34 | n/a | | native-avf | avf | 1 | 1200 | 59.991 | 16.660 | 2.859 | 17.066 | 20.839 | 22.740 | 25.905 | 0 | 0 (pts) | 1 | 0 | | native-chrome | chrome | 2 | 1197 | 59.844 | 16.706 | 3.264 | 17.300 | 21.000 | 24.400 | 31.100 | 0 | 0 | 6 | 3 | | browser-chrome | chrome | 2 | 1186 | 59.297 | 16.863 | 6.084 | 16.800 | 29.200 | 39.100 | 43.100 | 51 | 32 | 65 | n/a | | native-avf | avf | 2 | 1200 | 59.994 | 16.667 | 2.476 | 16.707 | 21.585 | 22.985 | 24.369 | 0 | 0 (pts) | 0 | 0 | | browser-avf | avf | 2 | 1156 | 57.797 | 17.311 | 5.106 | 16.886 | 23.822 | 39.555 | 46.050 | 0 | 0 (pts) | 45 | n/a | Table 2. Arrival timing, interior 5 s windows (7.5 s to 12.5 s). | Arm | Receiver | Run | Arrivals | Arrivals/s | Intervals n | mean ms | sd | min | p50 | p95 | p99 | max | Consecutive repeats | Same-stamp pairs | |---|---|---|---|---|---|---|---|---|---|---|---|---|---|---| | browser-chrome | chrome | 1 | 293 | 58.600 | 292 | 17.069 | 5.758 | 0.500 | 16.800 | 29.500 | 39.700 | 40.300 | 11 | 7 | | native-chrome | chrome | 1 | 300 | 60.000 | 299 | 16.666 | 2.645 | 10.400 | 16.800 | 20.800 | 21.900 | 24.600 | 0 | 0 | | browser-avf | avf | 1 | 293 | 58.600 | 292 | 17.053 | 4.081 | 10.414 | 16.929 | 20.453 | 38.701 | 40.951 | 0 | 0 | | native-avf | avf | 1 | 300 | 60.000 | 299 | 16.649 | 2.959 | 10.543 | 17.006 | 21.399 | 23.442 | 25.905 | 0 | 0 | | native-chrome | chrome | 2 | 299 | 59.800 | 298 | 16.723 | 3.121 | 9.200 | 17.300 | 20.500 | 24.500 | 29.900 | 0 | 0 | | browser-chrome | chrome | 2 | 298 | 59.600 | 297 | 16.775 | 5.591 | 0.500 | 16.800 | 22.900 | 39.300 | 40.200 | 11 | 5 | | native-avf | avf | 2 | 300 | 60.000 | 299 | 16.666 | 2.468 | 10.724 | 16.720 | 21.508 | 22.441 | 22.946 | 0 | 0 | | browser-avf | avf | 2 | 289 | 57.800 | 288 | 17.247 | 4.985 | 10.645 | 16.892 | 23.456 | 39.238 | 44.775 | 0 | 0 | Browser sender versus paced producer at the Chrome reader (browser minus native, 20 s windows, 95 % bootstrap CI in brackets). Raw arrival-interval sd +3.047 [2.521, 3.547] ms (run 1) and +2.820 [2.292, 3.294] ms (run 2); p95 +8.200 [2.800, 11.900] and +8.200 [1.000, 12.500] ms; p99 +16.400 [14.800, 17.200] and +14.700 [13.600, 15.900] ms; max 49.300 / 43.100 against 25.900 / 31.100 ms; consecutive repeats 44 / 51 against 0 / 0; same-VideoFrame.timestamp pairs 30 / 32 against 0 / 0. With the re-delivered frames removed (distinct-picture intervals: browser sd 5.029 / 5.121, p95 30.300 / 32.400, p99 39.600 / 39.200, max 49.800 / 43.100 ms) the sd difference is still +2.200 [1.679, 2.713] and +1.856 [1.347, 2.374] ms. At the AVF delegate: sd +1.429 [0.904, 1.937] and +2.629 [2.091, 3.133] ms; p95 +1.224 [-0.921, 2.359] and +2.237 [1.014, 12.252] ms; p99 +15.898 [14.978, 17.020] and +16.570 [15.585, 17.763] ms; max 41.219 / 46.050 against 25.905 / 24.369 ms; repeats 0 against 0 in all four; arrival gaps above 25 ms 34 / 45 against 1 / 0. The browser effect at AVF is in the tail (the about 33 ms send gaps of section 5), not the body of the distribution. Every sd and p99 difference CI excludes zero in both orders at both receivers. Jitter persists with the paced producer. With submit-interval sd 0.012 / 0.005 / 0.605 / 0.005 ms (run1 native-chrome, run1 native-avf, run2 native-chrome, run2 native-avf; full precision 0.012403814374117982 / 0.005250702892427489 / 0.6048722740396212 / 0.005142754946299068 ms; the 0.605 reflects one submit at sequence 970 that was 15331.676 us late, submit interval 31.993 ms, followed by a 2.618 ms interval), the paced producer's arrival-interval sd at the reader was 2.829 / 2.859 / 3.264 / 2.476 ms, p95 21.400 / 20.839 / 21.000 / 21.585 ms, p99 23.200 / 22.740 / 24.400 / 22.985 ms and max 25.900 / 25.905 / 31.100 / 24.369 ms, same order. All six gaps above 25 ms in run2 native-chrome, including the 31.100 ms maximum (markers 323 to 324), fall between frames the producer submitted 16.644 to 16.682 ms apart, so that maximum is not the sequence 970 event (which sits beside the 29.900 ms interval at markers 968 to 969). Chrome reader versus AVF delegate as receivers of the paced producer (separate sessions): Chrome minus AVF raw arrival-interval sd was -0.0298 ms in run 1 (paired bootstrap 95 % CI [-0.1899, 0.1183]) and +0.7881 ms in run 2 ([0.6121, 0.9693]); the two receivers agreed in one order and not the other, and because they never ran at the same time this leg cannot attribute the run 2 difference to Chrome rather than to the session. Whether the Chrome reader adds spread is undecided. ## 4. Where the paced producer's jitter enters In the two native-avf arms every frame carries four stamps that join by marker identity: the producer's submit (its socket write call), the daemon's pts (stamped with the host clock after the frame is fitted into the pixel buffer and immediately before `CMSimpleQueueEnqueue`), the extension's relay stamp (the CMIO host-time attachment set with a fresh host time when the sample is relayed to the source stream), and the AVF delegate entry. The daemon drains each 8294464-byte frame on one libuv thread in 127 or more 64 KiB reads, decodes it, fits it, stamps it and enqueues it; the extension consumes the sink queue on a serial client queue and, when a consume call returns nothing, waits 4 ms before consuming again; the relay forwards the sample's pts and duration untouched. Figure 1 (stage-timing.svg) draws the interval series and the per-stage latencies over the interior 5 s window; Figure 2 (intervals.svg) draws the arrival-interval distributions. ![Stage-timing diagram, interior 5 s window. Top row: interval between consecutive arrivals in milliseconds versus seconds into the window, one panel per arm, with hairlines at 16.7 ms and 33.3 ms. Bottom row: per-stage latency where an identity join exists, submit to arrival for the native arms plus submit to pts and pts to arrival for the native-avf arms, and a no-identity-join note for the four browser arms.](stage-timing.svg) Figure 1. Arrival timing at the reader, interior 5 s window. Top row: interval between consecutive arrivals (ms) versus seconds into the window, one panel per arm; the hairlines at 16.7 ms and 33.3 ms are one and two 60 Hz periods. Bottom row: per-stage latency where an identity join exists (marker sequence to producer sequence). Counts are samples handed to a reader, not delivered pixels; cross-process stages carry the measured clock bound stated in section 2. The four browser panels carry no identity join: the sender hook sequence and the receiver hash share no identity because the Noisedeck picture has no marker. The published file is the retained diagram (digest in section 10) with the legend of the two native-avf stage panels moved below the x-axis label; no data, axis or caption changed; both digests are in the evidence manifest. The top panels' interval axis extends above the last 40 ms gridline, to 1.25 times the largest interior p99 (39.700 ms, run1 browser-chrome); no interval in any panel exceeds it (the largest is 44.775 ms, run2 browser-avf), so the off-scale marker the diagram's subtitle describes does not occur. [Full-size SVG](stage-timing.svg). Table 3. Per-frame stage latencies, native producer to AVF delegate, 20 s windows, 1200 joined frames per arm (four-decimal rows from the mechanism analysis; the last row from the statistics document at three decimals). | Stage | Run 1 p5 / p50 / p95 / p99 / max (ms) | Run 1 sd | Run 2 p5 / p50 / p95 / p99 / max (ms) | Run 2 sd | Clock | |---|---|---|---|---|---| | submit → pts (producer write, loopback kernel, daemon drain, decode, fit, enqueue) | 3.7089 / 4.9040 / 7.4530 / 8.1133 / 8.4281 | 1.0227 | 3.9396 / 5.1277 / 7.3357 / 8.2356 / 8.6920 | 0.9337 | cross-process, bound 1.01 ms | | of which producer write duration (submit → writeDone) | 1.4771 / 2.6200 / 7.1192 / 7.5463 / 7.7492 | 1.4507 | 1.6112 / 2.6062 / 6.4501 / 7.5513 / 8.2070 | 1.3373 | producer hrtime | | of which writeDone → pts residual | 0.6186 / 2.1074 / 2.5693 / 2.8386 / 3.5396 | 0.6061 | 0.8182 / 2.3182 / 2.7736 / 2.9450 / 3.8662 | 0.6078 | derived, bound 1.01 ms | | pts → relay (sink enqueue to extension relay stamp) | 0.4028 / 2.2717 / 5.6041 / 6.6140 / 6.9452 | 1.7623 | 0.5981 / 1.4561 / 5.1934 / 6.7916 / 7.0733 | 1.5786 | same mach clock | | relay → AVF delegate | 0.4863 / 0.7081 / 0.8978 / 1.0094 / 1.1898 | 0.1158 | 0.5327 / 0.7221 / 0.9160 / 1.1522 / 1.3219 | 0.1200 | same mach clock | | pts → AVF delegate | 1.1380 / 2.9564 / 6.3120 / 7.3536 / 7.9644 | 1.7736 | 1.3278 / 2.1756 / 5.9073 / 7.5794 / 8.1423 | 1.5877 | same mach clock | | submit → AVF delegate (every hop) | 5.743 / 7.943 / 11.859 / 13.067 / 14.478 | 2.136 | 6.348 / 6.819 / 12.138 / 13.496 / 15.767 | 2.034 | cross-process, bound 1.01 ms | Table 4. Interval series at each stamp, consecutive sequences only, 1199 pairs per arm. | Interval series | Run 1 sd | Run 1 p1 | Run 1 p99 | Run 1 max | Run 2 sd | Run 2 p1 | Run 2 p99 | Run 2 max | |---|---|---|---|---|---|---|---|---| | producer submit | 0.005250702892427489 | 16.652583 | 16.681 | 16.7085 | 0.005142754946299068 | 16.652292 | 16.681542 | 16.700667 | | daemon sink pts | 1.2413 | 13.2700 | 19.9200 | 20.5700 | 1.1566 | 13.4100 | 20.0100 | 20.7500 | | extension relay stamp | 2.8502 | 11.1389 | 22.5826 | 25.5853 | 2.4731 | 10.7988 | 22.9408 | 24.4645 | | AVF delegate arrival | 2.8589 | 11.0422 | 22.7397 | 25.9055 | 2.4763 | 10.7414 | 22.9855 | 24.3694 | | Chrome reader arrival (native-chrome arms, separate sessions; statistics document, three decimals) | 2.829 | 10.800 | 23.200 | 25.900 | 3.264 | 10.500 | 24.400 | 31.100 | Table 5. Variance added at each step of the AVF chain, 20 s windows. | Step | Run 1 interval sd before (ms) | Run 1 sd after | Run 1 variance added (ms^2) | Run 2 interval sd before (ms) | Run 2 sd after | Run 2 variance added (ms^2) | |---|---|---|---|---|---|---| | submit → pts | 0.005 | 1.241 | 1.541 | 0.005 | 1.157 | 1.338 | | pts → relay | 1.241 | 2.850 | 6.583 | 1.157 | 2.473 | 4.779 | | relay → arrival | 2.850 | 2.859 | 0.050 | 2.473 | 2.476 | 0.016 | Variance budget for the AVF path: arrival-interval variance 8.173 / 6.132 ms^2 = 0.000 (producer) + 1.541 / 1.338 entering before the sink stamp + 6.632 / 4.794 entering after it, of which 6.583 / 4.779 between the sink stamp and the relay stamp and 0.050 / 0.016 from relay to delegate. The share entering after the sink stamp is 81.1 % / 78.2 %. The pts-to-delegate latency variance is 3.008 / 2.891 times the submit-to-pts latency variance. The two stages do not carry comparable variance. The daemon already spreads the producer's cadence: sink pts intervals run from 13.270 to 19.920 ms (run 1) and 13.410 to 20.010 ms (run 2) at the 1st and 99th percentiles, about plus or minus 3.3 ms around 16.66 ms. ![Interval diagram, 20 s windows. Left, per run: histograms of the interval between consecutive arrivals in 0.5 ms bins from 0 to 55 ms, one outline per cell (browser-chrome, native-chrome, browser-avf, native-avf), on a log count axis with hairlines at 16.7 ms and 33.3 ms. Right, per run: histograms of the per-frame stage latencies by identity join in the native-avf arm, submit to pts, pts to relay and relay to delegate.](intervals.svg) Figure 2 (intervals.svg). Left: raw arrival intervals at the reader, 20 s window, 0.5 ms bins, one outline per cell on a log count axis, one panel per run. Right: per-frame stage latency by identity join in the two native-avf arms (submit → pts, pts → relay, relay → delegate), 0.5 ms bins. Counts are samples handed to a reader, never delivered pixels. [Full-size SVG](intervals.svg). The stage before the sink stamp is not attributable to daemon processing alone. Submit → pts tracks the producer's own write completion at correlation 0.938 / 0.917, and the residual after the write completed (writeDone → pts) is p50 2.1074 / 2.3182 ms with sd 0.6061 / 0.6078 ms. It is a coupled producer-write, loopback-kernel and daemon-drain stage, and the report labels it as such rather than as "the daemon path". Slow drains cluster in time (lag-1 autocorrelation 0.267 / 0.237). The stage between the sink stamp and the relay stamp has a shape a pure 4 ms poll would not give. A uniform 0 to 4 ms wait would have sd 1.155 ms and a flat histogram; the measured pts → relay latency has sd 1.7623 / 1.5786 ms, spans 0.2576 to 6.9452 / 0.2667 to 7.0733 ms, and is bimodal: run 1 has 575 of 1200 frames below 2.0 ms and a plateau from 2.5 to 6.5 ms holding 582 frames; run 2 has 760 below 2.0 ms and a plateau from 2.5 to 7.0 ms holding 383. The plateau is about 4 ms wide in both runs. The daemon's own lateness does not choose the population (correlation of submit → pts with pts → relay 0.085 / 0.240). The shape is producer-independent: the browser-avf arms show the same bimodal pts → relay shape (p50 3.031 / 2.982, p95 5.825 / 6.246, max 7.429 / 7.042 ms). A two-population reading (frames returned by a consume call already in flight, and frames that arrived during the timed wait and paid the remaining wait plus a consume round trip) fits the shape but is an inference, not a finding; the population split (48 % / 63 % short) is not a stable number. Leg A narrows the boundary to this span but does not identify one operation within it. The pts stamp's provenance is recorded as UNVERIFIED in every AVF start record; reading it as the daemon sink stamp rests on the d167ee4 source and on the CMIO host-time attachment being later than pts on every joined frame (minimum 0.258 / 0.267 ms), and the discriminating run (daemon dropped > 0) did not occur. Every in-window sample carried the sink's duration 16666667 ns, every CMIO sequence step was 1 and every discontinuity flag was 0 in both native-avf arms. If that reading were wrong, the "after the sink stamp" share would be mis-assigned; extension-side instrumentation settles it directly. The Chrome reader, in separate sessions of the same producer, daemon and extension (native-chrome arms, run 1 / run 2): submit → arrival p50 27.859 / 30.323 ms, sd 2.304 / 2.593, p95 32.643 / 34.637, p99 34.159 / 35.531, max 36.292 / 49.121 ms, minimum 23.784423828125 / 21.068359375 ms (join bound 1.80 / 1.90 ms). The reader saw the same producer's frames 19.917 / 23.503 ms later at the median than the AVF delegate, most of it fixed cost; the submit-to-arrival latency sd was larger by 0.168 / 0.559 ms in the Chrome sessions, which these separate sessions cannot attribute to Chrome rather than to the session. The run 2 maximum of 49.121 ms is sequence 324 (producer schedule error 22.3 us), beside missing marker 325, not the sequence 970 producer event. Chrome's VideoFrame.timestamp is not the CMIO pts: its interval sd (2.939 / 3.237 ms) equals the arrival-interval sd, while the read time minus the stamp, after subtracting its minimum, has sd 0.274 / 0.254 ms, so the stamps carry the delivery-to-page jitter. The format at the reader is NV12 while the extension delivers BGRA, so the Chrome path includes a conversion the AVF path does not. This is a cross-session, cross-observer description, not a within-receiver comparison. The browser sender's chain has no identity join, so only intervals can be followed (run 1 / run 2 browser-avf). SDK frame stamp to `socket.send` p50 20.300 ms, p99 37.100 / 37.200 ms, an export stage the paced producer does not have. Send-interval sd 2.759 / 3.297 ms with 33 / 45 gaps above 25 ms; sink-stamp interval sd 3.970 / 4.755 ms (variance added between the page's send and the sink stamp 8.150 / 11.739 ms^2, against 1.541 / 1.338 ms^2 for the paced producer's submit → pts step); relay-stamp interval sd 4.316 / 5.143 ms; delegate arrival-interval sd 4.288 / 5.106 ms. Every send gap above 25 ms reappears as a sink-stamp gap and an arrival gap above 25 ms (33 / 33 / 34 and 45 / 45 / 45). ## 5. The browser sender's own tail In the four browser-sender windows the SDK sender's send intervals, recorded at `socket.send`, carry a tail that the paced producer's submit intervals do not. Table 6 lists the send side; Table 7 what reached each receiver. Arm order in every four-value list is run1 browser-chrome, run1 browser-avf, run2 browser-chrome, run2 browser-avf. Table 6. Browser sender send intervals and refusals, 20 s windows. | Arm | Sends | Send-interval sd (ms) | p99 | max | Send gaps > 25 ms | Refusal records | In-window droppedBackpressure delta | Whole-session refusals | Stamp → send p50 (ms) | Stamp → send p99 | |---|---|---|---|---|---|---|---|---|---|---| | run1 browser-chrome | 1151 | 3.489 | 33.700 | 50.700 | 48 | 49 | 47 | 66 | 20.300 | 37.400 | | run1 browser-avf | 1167 | 2.759 | 33.400 | 33.600 | 33 | 33 | 31 | 40 | 20.300 | 37.100 | | run2 browser-chrome | 1153 | 3.362 | 33.700 | 34.100 | 47 | 47 | 45 | 56 | 20.300 | 37.500 | | run2 browser-avf | 1155 | 3.297 | 33.400 | 33.900 | 45 | 45 | 43 | 56 | 20.300 | 37.200 | Against this, the paced producer's submit-interval p99 was 16.707 / 16.681 / 16.710 / 16.682 ms and max 16.779 / 16.709 / 31.993 / 16.701 ms (run1 native-chrome, run1 native-avf, run2 native-chrome, run2 native-avf). The send gaps are 30.9 to 34.1 ms, one skipped frame period, plus one of two periods (50.7 ms). Event order. Of the 173 send gaps above 25 ms in the four windows, 168 have no backpressure refusal between the two sends: the gap-ending frame is the next frame in sequence (sequence step 1 in 45 / 33 / 45 / 45), its SDK presentation stamp is 16.7 ms after the previous sent frame's at the median, and it reached `socket.send` about one frame period late (stamp-to-send p50 37.3 / 37.0 / 37.3 / 37.0 ms against 20.3 ms for all sends) with socket.bufferedAmount 0 at that send (bufferedAmount non-zero before a send in 0 of 1151 / 1167 / 1153 / 1155 sends). The SDK's byte-budget refusal of the following frame came p50 4.2 / 4.2 / 4.2 / 4.3 ms after that late send (range 3.1 to 5.3 ms), while the just-sent 8294464-byte frame was still buffered (172 of 174 refusals); in 5 gaps a refusal preceded the late send. The next send followed 16.5 / 16.5 / 16.5 / 16.6 ms after the late one with a sequence step of 2 and a presentation-stamp step of 33.3 / 33.3 / 33.3 / 33.2 ms. Net per event: one send slot empty and one picture never sent. The skipped picture is the consequence of the late send, not its cause; the 33 ms gaps are not themselves "skipped frames". The one 50.700 ms gap (run1 browser-chrome, sequences 860 to 863) is a different shape: two refusals with 691624 bytes still buffered at +13.1 and +16.4 ms after a normally timed send, then a frame two periods late. The delay lies between the SDK's frame timestamp and its `socket.send` call on the sender side. This leg does not separate GPU fence readiness, CPU buffer copy, frame encoding, socket submission, page scheduling or Chrome's socket accounting inside that interval, and the export-queue implementation is the engine loaded at runtime from the shaders CDN, whose version the manifests do not record. The 1 Hz senderStats evaluate fell inside a send gap in 1 of 48, 1 of 33, 0 of 47 and 1 of 45 gaps, so the probe does not explain the stalls; the send hook's own cost is unmeasured. Per the plan, the producer comparison changes export, transport ingress, admission rule and pacing together and does not identify one operation as the cause. Table 7. What each send gap became at the receiver, 20 s windows. | Arm | Send gaps > 25 ms | Followed within 60 ms by an arrival gap > 25 ms | Receiver arrival gaps > 25 ms | AVF sink-stamp gaps > 25 ms | Matched send gap p50 (ms) | Matched arrival gap p50 (ms) | Consecutive repeats at the receiver | Repeats within 60 ms after a send gap | Base rate for any arrival | |---|---|---|---|---|---|---|---|---|---| | run1 browser-chrome | 48 | 48 of 48 | 73 | n/a | 33.5 | 37.7 | 44 | 43 of 44 | 0.130 | | run1 browser-avf | 33 | 33 of 33 | 34 | 33 | 33.3 | 38.4 | 0 | 0 of 0 | 0.096 | | run2 browser-chrome | 47 | 47 of 47 | 65 | n/a | 33.6 | 37.9 | 51 | 42 of 51 | 0.149 | | run2 browser-avf | 45 | 45 of 45 | 45 | 45 | 33.3 | 38.1 | 0 | 0 of 0 | 0.135 | Pass-through to the AVF delegate. Every send gap above 25 ms reached the AVF delegate as one arrival gap above 25 ms within 60 ms (33 of 33 and 45 of 45), with no repeat and an immediate catch-up (next interval p50 12.477 / 12.471 ms). The matched arrival gaps are about 5 ms wider than the send gaps at the median (AVF sink-stamp gaps p50 38.56 / 38.89 ms; index-aligned, no identity); because the browser arms carry no marker, the records do not establish which frames bound each arrival gap or where the extra width enters. The arrival-interval p99 in the browser arms is 39.600 / 38.638 / 39.100 / 39.555 ms against 23.200 / 22.740 / 24.400 / 22.985 ms in the native arms. Arrival rate. The browser arms delivered 1166 / 1167 / 1186 / 1156 arrivals per 20 s against 1151 / 1167 / 1153 / 1155 sends; the native arms 1200 / 1200 / 1197 / 1200 against 1200 submits. The browser arms' lower arrival rate is at least partly the sender omitting 3.3 to 4.4 percent of its own frames before the socket (whole-session refusals 66 / 40 / 56 / 56 with maxBufferedFrames = 1), so arrivals must be compared with sends, not with 60. Chrome-reader re-deliveries. In the two browser-chrome windows the reader received 44 and 51 consecutive same-hash VideoFrames, 37 / 46 of them under 1 ms after the previous frame (read delta min 0.4 / 0.1, p50 0.6 / 0.6, max 1.9 / 2.0 ms), 30 and 32 with an identical VideoFrame.timestamp and the rest +0.1 or +0.2 ms; 44 of 44 and 47 of 51 immediately after an arrival gap above 25 ms; 43 of 44 and 42 of 51 within 60 ms after a send gap (base rate for an arbitrary arrival 0.130 / 0.149). The video element's totalVideoFrames delta equals the reader's delivered count in every Chrome arm, so the re-deliveries exist at the track source, upstream of the reader. In run 1 the interval after the re-delivered frame was p50 27.900 ms (27 of 44 above 25 ms); in run 2 p50 12.300 ms (3 of 51). In the browser-chrome sessions 29 and 18 sent frames per 20 s never reached the reader as a new picture (sends 1151 / 1153, distinct arrivals 1122 / 1135; hash-only distinctness), while the AVF sessions delivered every sent frame to the delegate (1167 sends / 1167 arrivals; 1155 / 1156). With the paced producer at the same reader there were 0 / 0 in-window repeats, but run2 native-chrome's warmup contains 3 sub-millisecond same-hash re-deliveries (markers 73, 95, 150; read deltas 0.900 / 0.900 / 1.000 ms), so the signature is not exclusive to the browser sender. The AVF delegate recorded 0 consecutive repeats and 0 same-pts pairs in every window, with every CMIO sequence step 1 and every sample duration 16666667 ns. Not decided by these records: whether the re-deliveries arise in Chrome's capture service, its track, or the CMIO client path (the two receivers never ran at the same time and consume different formats, NV12 at Chrome and BGRA at AVF, with the AVF device reporting minFrameDuration 0.033333333 s); and whether the trigger is the browser sender's late frame specifically or any arrival gap of 33 ms or more. The arrival that ended a gap of 33 ms or more was followed by a re-delivery 33 of 47 / 35 of 52 times, but the paced producer never produced an arrival gap of 33 ms or more at the Chrome reader (native-chrome max 25.900 / 31.100 ms); in the 25 to 33 ms bin the browser arms show 11 re-deliveries in 39 against 0 in 9 for the native arms (hypergeometric probability of 0 of 9 given 11 of 48: 0.07417752516918065). The report does not say that Chrome "inserts" duplicates, and does not say the AVF client saw the same sender "in the same conditions". The plan's "repeated selection" (uploads and selected frame timestamps) was not measured in this leg. Where this feeds. Plan section 4B (reduce measured sender stalls) has the entry condition "A implicates the sender, or a controlled trace identifies sender stalls that precede downstream gaps"; leg A meets the second clause by the 48 of 48 / 33 of 33 / 47 of 47 / 45 of 45 matches and the first clause for the tail (not for the body of the spread). What 4B requires next, in the plan's words: separate GPU fence readiness, CPU buffer copy, frame encoding, socket submission and socket pressure; compare a quiet host with a recorded, controlled GPU load; preserve source content within each pair; measure any tracing overhead separately. The measurement leg A lacks and 4B needs is a per-frame trace inside the SDK export path from completion of the readback to `socket.send`, with the engine version recorded, on a quiet host and under controlled GPU load, plus a hook-free control arm. The plan's rejected read-ahead change must not be repeated without a new causal result. Plan section 4C (receiver freshness) has the entry condition "repeated frame selection remains after A, and a public signal can guide a bounded scheduling change". Leg A did not measure frame selection, so that condition is not evaluated here. As a diagnostic input only: at the track source a re-delivered frame carries an equal VideoFrame.timestamp in 30 of 44 and 32 of 51 cases and a 0.1 to 0.2 ms step in the rest, so a timestamp-equality signal alone would miss 14 of 44 and 19 of 51 of these re-deliveries. That is consistent with the plan's statement that E8 and E9 support an arrival hint with a race, not an exact identity signal, and with its rule that a public counter or timestamp repeat must not by itself skip an upload. E1's 229 distinct timestamps in 300 uploads is not explained by leg A and must not be attributed to either finding here. ## 6. Reproducibility The sign of the browser-minus-native difference repeated in both orders at both receivers (section 3). The cells themselves did not agree between run 1 and run 2. Table 8 compares each cell across runs (raw arrival intervals, 20 s windows; bootstrap 2000 draws, seed 20260910, nearest-rank 2.5th and 97.5th percentiles; KS p is asymptotic and shown for scale only). Table 8. Run 1 versus run 2 per cell, raw arrival intervals, 20 s windows. | Cell | Run 1 sd [CI] | Run 2 sd [CI] | sd diff (r2 - r1) [CI] | sd CIs overlap | Run 1 p99 [CI] | Run 2 p99 [CI] | p99 diff [CI] | Run 1 / run 2 p95 | p95 diff [CI] | Run 1 / run 2 max | Repeats | KS D | |---|---|---|---|---|---|---|---|---|---|---|---|---| | browser → chrome | 5.876 [5.361, 6.351] | 6.084 [5.565, 6.540] | 0.208 [-0.462, 0.900] | yes | 39.600 [38.400, 39.900] | 39.100 [38.300, 39.800] | -0.500 [-1.100, 1.000] | 29.600 / 29.200 | -0.400 [-9.100, 5.800] | 49.300 / 43.100 | 44 / 51 | 0.060 | | browser → avf | 4.288 [3.767, 4.791] | 5.106 [4.577, 5.613] | 0.817 [0.069, 1.529] | yes | 38.638 [37.965, 39.563] | 39.555 [38.701, 40.482] | 0.918 [-0.446, 2.008] | 22.064 / 23.822 | 1.759 [0.437, 11.438] | 41.219 / 46.050 | 0 / 0 | 0.058 | | native → chrome | 2.829 [2.711, 2.944] | 3.264 [3.135, 3.393] | 0.435 [0.258, 0.604] | no | 23.200 [22.500, 24.000] | 24.400 [23.800, 25.000] | 1.200 [-0.000, 2.200] | 21.400 / 21.000 | -0.400 [-0.900, 1.000] | 25.900 / 31.100 | 0 / 0 | 0.137 | | native → avf | 2.859 [2.753, 2.965] | 2.476 [2.354, 2.594] | -0.383 [-0.543, -0.235] | no | 22.740 [22.256, 23.442] | 22.985 [22.220, 23.391] | 0.246 [-0.705, 0.925] | 20.839 / 21.585 | 0.746 [-0.603, 1.632] | 25.905 / 24.369 | 0 / 0 | 0.183 | What repeated. Browser minus native raw arrival-interval sd was +3.047 and +2.820 ms at the Chrome reader and +1.429 and +2.629 ms at the AVF delegate; p99 +16.400 / +14.700 ms at Chrome and +15.898 / +16.570 ms at AVF; consecutive repeats 44 and 51 against 0 and 0 at Chrome; arrival gaps above 25 ms 73 and 65 against 1 and 6 at Chrome and 34 and 45 against 1 and 0 at AVF. An independent recompute of the same records with a different bootstrap seed gave sd-difference CIs [2.566, 3.528], [2.312, 3.314], [0.915, 1.935] and [2.072, 3.149], all excluding zero. The between-run differences within a cell are an order smaller than the browser-minus-native differences. What differed. Raw arrival-interval sd differed by +0.435 ms in native-chrome (2.829 vs 3.264 ms), by -0.383 ms in native-avf (2.859 vs 2.476 ms) and by +0.817 ms in browser-avf (4.288 vs 5.106 ms); these three difference CIs exclude zero, and also exclude zero under moving-block bootstraps of 30 and 60 intervals. Only browser-chrome had overlapping spread statistics (sd 5.876 vs 6.084 ms; p99 39.600 vs 39.100 ms), and there the interval after a re-delivered frame exceeded 25 ms in 27 of 44 cases in run 1 and 3 of 51 in run 2 (p50 27.900 vs 12.300 ms; Fisher exact two-sided p = 4.62e-09). p99 differences include zero in all four cells under the i.i.d. bootstrap (native-chrome +1.200 ms, [-0.000, 2.200]). The two native cells differ in distribution shape between runs (two-sample KS D 0.137 and 0.183, permutation p 0.001 for both). run2 native-chrome has more intervals near 13 ms (114 vs 36 in the 13 ms bin) and fewer near 16 ms (142 vs 400); its p25 is 13.500 ms against 16.100 ms in run 1. That difference is not the run 2 producer stall: with the 18 intervals around sequences 325, 731 and 971 removed the sd difference is still +0.381 ms ([0.218, 0.544]), and every 5 s segment of run 2 (sd 3.079 to 3.459) is wider than every segment of run 1 (2.713 to 2.961). Chrome's own VideoFrame.timestamp intervals carry the same shape (p25 13.400 vs 16.200 ms), and the higher-sd run started on the quieter host (1 min load 2.19 vs 3.56), so neither the reader nor endpoint host load explains it. The native-avf difference sits after the daemon's sink stamp: the sink pts interval sd agreed between runs (1.241 vs 1.157 ms, CI of the difference [-0.185, 0.017]) while the extension relay-stamp interval sd did not (2.850 vs 2.473 ms, [-0.540, -0.221]), and run2 native-avf was not stationary inside its own 20 s window (share of frames with pts → relay under 2 ms 0.543 in the first 5 s, 0.663 in the last 15 s; run 1 0.507 and 0.470). The between-run change coincides with a within-session change in the extension's pts-to-relay population (fraction below 2 ms per 2 s bin 0.43 to 0.54 in run1 native-avf, 0.51 to 0.77 in run 2; correlation with per-bin interval sd -0.424 / -0.747). One extension process served all eight arms while the daemon was restarted per arm, so run 2 is not an independent replication of extension state; in-window host activity was not sampled, so neither cause is established. The two native-chrome runs were not identical on the producer side: run 2 carried one submit 15331.676 us late at sequence 970 (event loop blocked 17666.667 us) that no other native arm had. Integrity: daemon dropped = 0 at every stats sample in each native arm; reordered markers 0 and invalid markers 0 in all four native arms; run2 native-chrome lost 3 markers inside its window (325, 731, 971) and 4 before it (1, 75, 97, 152), and re-delivered 3 frames (sequences 73, 95, 150) 0.900 to 1.000 ms after their first arrival with identical hash during its warmup; run1 native-chrome lost only sequence 1 (pre-window); both native-avf arms lost none. Marker 971 is the second frame of the back-to-back pair at the producer stall; markers 325 and 731 had ordinary producer timing (schedule errors 21.3 / 96.1 us) and each sits beside a long receiver interval (31.100 ms before marker 324, then 12.700 ms into 326; 27.000 ms before 730, then 19.600 ms into 732). The daemon accepted them all (dropped 0) and no AVF arm lost any marker, so the loss occurred after daemon acceptance; these records cannot place it. This is one host, one 20 s window per arm, two arms per cell, with the receiver-pair order not reversed; it supports the statement that the sign of the producer effect repeated and does not support the statement that the cells agree. ## 7. Comparison with E1 E1 (the plan's camera arrival trace) recorded 300 arrivals in 5.003 s with arrival-interval mean 16.674, min 9.042, p95 21.933 and max 24.200 ms, on an Apple M2 with the browser sender, observed by a compositor trace of Noisedeck B's media path in Chromium revision 79460ebecaa5625e57a5fb679a735659e73dc687, with the extension revision uncertified. Leg A's Chrome numbers come from a MediaStreamTrackProcessor reader on an Apple M4 in Chrome 152.0.7977.83, and its AVF numbers from a native delegate. Table 9 places every arm beside E1's published numbers; it is a comparison of arrival-interval envelopes across observers, not a replication, and not a paired measurement with any leg A arm. E1 published no sd or p99. Table 9. Every arm against E1 (ms). | Arm | Window | n | mean | mean - E1 | min | min - E1 | p95 | p95 - E1 | max | max - E1 | Intervals < 9.042 | Intervals > 24.200 | |---|---|---|---|---|---|---|---|---|---|---|---|---| | E1 (browser sender, Apple M2, compositor trace) | 5.003 s | 300 arrivals | 16.674 | | 9.042 | | 21.933 | | 24.200 | | | | | run1 browser-chrome | 20 s | 1165 | 17.152 | 0.478 | 0.400 | -8.642 | 29.600 | 7.667 | 49.300 | 25.100 | 44 | 74 | | run1 browser-chrome | interior 5 s | 292 | 17.069 | 0.395 | 0.500 | -8.542 | 29.500 | 7.567 | 40.300 | 16.100 | 11 | 16 | | run1 native-chrome | 20 s | 1199 | 16.667 | -0.007 | 6.200 | -2.842 | 21.400 | -0.533 | 25.900 | 1.700 | 1 | 6 | | run1 native-chrome | interior 5 s | 299 | 16.666 | -0.008 | 10.400 | 1.358 | 20.800 | -1.133 | 24.600 | 0.400 | 0 | 2 | | run1 browser-avf | 20 s | 1166 | 17.139 | 0.465 | 6.489 | -2.553 | 22.064 | 0.131 | 41.219 | 17.019 | 1 | 34 | | run1 browser-avf | interior 5 s | 292 | 17.053 | 0.379 | 10.414 | 1.372 | 20.453 | -1.480 | 40.951 | 16.751 | 0 | 7 | | run1 native-avf | 20 s | 1199 | 16.660 | -0.014 | 10.543 | 1.501 | 20.839 | -1.094 | 25.905 | 1.705 | 0 | 2 | | run1 native-avf | interior 5 s | 299 | 16.649 | -0.025 | 10.543 | 1.501 | 21.399 | -0.534 | 25.905 | 1.705 | 0 | 2 | | run2 native-chrome | 20 s | 1196 | 16.706 | 0.032 | 6.400 | -2.642 | 21.000 | -0.933 | 31.100 | 6.900 | 3 | 12 | | run2 native-chrome | interior 5 s | 298 | 16.723 | 0.049 | 9.200 | 0.158 | 20.500 | -1.433 | 29.900 | 5.700 | 0 | 3 | | run2 browser-chrome | 20 s | 1185 | 16.863 | 0.189 | 0.100 | -8.942 | 29.200 | 7.267 | 43.100 | 18.900 | 53 | 66 | | run2 browser-chrome | interior 5 s | 297 | 16.775 | 0.101 | 0.500 | -8.542 | 22.900 | 0.967 | 40.200 | 16.000 | 11 | 13 | | run2 native-avf | 20 s | 1199 | 16.667 | -0.007 | 9.673 | 0.631 | 21.585 | -0.348 | 24.369 | 0.169 | 0 | 1 | | run2 native-avf | interior 5 s | 299 | 16.666 | -0.008 | 10.724 | 1.682 | 21.508 | -0.425 | 22.946 | -1.254 | 0 | 0 | | run2 browser-avf | 20 s | 1155 | 17.311 | 0.637 | 6.485 | -2.557 | 23.822 | 1.889 | 46.050 | 21.850 | 2 | 54 | | run2 browser-avf | interior 5 s | 288 | 17.247 | 0.573 | 10.645 | 1.603 | 23.456 | 1.523 | 44.775 | 20.575 | 0 | 12 | Reading. Over the 20 s windows the four native arms' means sit within -0.014 to 0.032 ms of E1's 16.674; their p95 values (21.400, 20.839, 21.000, 21.585) are all below E1's 21.933; their maxima (25.900, 25.905, 31.100, 24.369) are at or above E1's 24.200 in all four, with 6, 2, 12, 1 intervals per arm above 24.200 out of about 1199 (E1 had none above its own maximum by definition, in 300 intervals). At equal sample size, over 300-interval sliding blocks of the native-chrome arms, the statistics range min 6.200 to 11.000 / 6.400 to 10.800 ms, p95 20.700 to 21.500 / 20.300 to 23.000 ms, max 24.200 to 25.900 / 24.600 to 31.100 ms, and 0 of 15 blocks in either native-chrome arm have a maximum at or below E1's 24.200 ms. Leg A's own browser arms, E1's condition on a different host and observer, do not reproduce E1's envelope at all: 300-interval block maxima 39.100 to 49.300 ms at Chrome and 38.701 to 44.775 ms at AVF, 0 of 15 blocks within 24.200 ms in any browser arm, and 44 and 53 intervals below 9.042 ms (the re-delivery pairs) in the browser-chrome windows. E1's 5.003 s trace carries no gap above 25 ms, so the browser sender's tail of section 5 is a property of these sessions and is not established for E1's host. What this supports: a resemblance of arrival envelopes across observers. What it does not support: equality with E1, replication of E1, a before/after pairing with any leg A arm, or the claim that E1's jitter had the same cause. "Comparable envelope" is the most the data support. ## 8. Decision ### 8.1 How the plan's decision rule resolves - Branch "paced production reduces arrival jitter and repeated selection": fires on arrival timing and reader re-deliveries. Arrival jitter is reduced at both receivers in both orders (every browser-minus-native sd and p99 CI excludes zero) and the Chrome-reader re-deliveries went from 44 / 51 to 0 / 0. The plan's "repeated selection" (uploads and selected frame timestamps) was not measured. Consequence: investigate sender export, pacing and socket pressure next, which is plan section 4B, whose entry condition leg A meets (section 5). - Branch "jitter persists": fires (sections 3 and 4). "Instrument native submission, extension consumption and browser arrival" is now done for native submission (deadline, submit, write completion per frame), for the daemon's sink stamp (pts, provenance UNVERIFIED by record), for the extension's relay stamp, for AVF delegate entry and for Chrome reader arrival. It is not done inside the extension's consume cycle: no record exists of each consume call's issue time, completion time, nil or non-nil result, hasMore flag or relay time, and no extension CPU or power sample exists. - Branch "inconclusive": does not apply to the producer contrast. It does apply to one side question, whether the Chrome reader adds spread (run 1 -0.030 ms [-0.190, 0.122], run 2 +0.788 ms [0.614, 0.958], i.i.d. bootstrap; the paired bootstrap quoted in section 3 gives -0.0298 [-0.1899, 0.1183] and +0.7881 [0.6121, 0.9693]; confounded by session and host state); that question stays open and is not the next boundary. ### 8.2 The next boundary to change, and why Named boundary: the stage between the daemon's CMIO sink enqueue (the pts stamp) and the extension's relay of the sample, the extension's consume cycle, for the jitter that persists with a paced producer. 1. The variance budget places the largest share there: of the AVF arrival-interval variance 8.173 / 6.132 ms^2, 6.583 / 4.779 ms^2 enters between the sink stamp and the relay stamp, 1.541 / 1.338 ms^2 before the sink stamp, and 0.050 / 0.016 ms^2 from relay to delegate. The pts-to-delegate latency variance is 3.008 / 2.891 times the submit-to-pts latency variance. 2. The stage's latency distribution has a shape a pure 4 ms poll would not give: bimodal, 0.258 to 6.945 / 0.267 to 7.073 ms, sd 1.762 / 1.579 ms against 1.155 ms for a uniform 0 to 4 ms wait, with a plateau about 4 ms wide; and the shape is producer-independent (the browser-avf arms show it too). 3. The between-run change in the native-avf cell sits in this stage: the sink pts interval sd agreed between runs (1.241 vs 1.157 ms, CI [-0.185, 0.017]) while the relay-stamp interval sd did not (2.850 vs 2.473 ms, CI [-0.540, -0.221]), coinciding with a shift in the share of frames whose pts-to-relay latency is below 2 ms (0.479 vs 0.633). 4. The stage before it is bounded: submit → pts tracks the producer's own write completion at correlation 0.938 / 0.917 and holds about 19 to 22 percent of the interval variance, so a daemon-side change is capped at that share on paper. The stage after it is negligible (relay → delegate sd 0.116 / 0.120 ms). The Chrome reader adds latency (19.917 / 23.503 ms at p50) but whether it adds spread is undecided, so no Chrome-side boundary is identified by this leg. ### 8.3 What the plan requires before that boundary is changed, and why leg A does not yet satisfy it - Plan section 4A: "The extension's empty-queue wait is a possible source of jitter. Do not shorten it without evidence of missed arrival deadlines and measurements of idle CPU and power." Leg A has no missed arrival deadline in the plan's sense (secondsBelow50 = 0 and secondsBelow55 = 0 in all eight windows; 60 arrivals in every complete second of both native-avf arms) and no extension CPU or power sample. So the change is not a shorter constant, and "Do not sweep timing constants" applies. - Plan section 4A: "Check the running extension's provenance before attributing behavior to local source." The installed 0.2.38 extension's build commit is asserted, not shown; the extension source is unchanged from 7fdfdc9 through d167ee4, and daemon-side native code including cmio_camera_sink.mm changed between 865cc2e and d167ee4. - The pts stamp's provenance is UNVERIFIED by record. The boundary is named on the reading in section 4 (duration 16666667 ns on every frame; relay attachment later than pts on every frame); if that reading were wrong, the "after the sink stamp" share would be mis-assigned. Extension-side instrumentation settles this directly. - The candidate change, if the instrumentation supports it, is event-driven consumption of the sink queue (re-arm consume without the timed gap, or another framework-side wake-up), which removes the plateau population if the two-population reading holds; it requires rebuilding and re-approving the system extension and carries a CPU-spin risk if the framework returns nil immediately. A one-frame jitter buffer is not the candidate: it adds 16.7 ms of marker age, re-creates the two-clock beat class already seen on this host at 81.74 s, and the plan's E2 and E3 already rejected a fixed delay for delivery reasons. ### 8.4 The measurement that must accompany any change at this boundary 1. First, without changing anything: an extension-side consume-cycle trace at the present 0.2.38 build or a byte-identical rebuild whose commit is recorded, logging per consume call the issue time, the completion time, nil or non-nil, hasMore and the relay time, on the host clock, with bounded storage, joined by CMIO sequence or by the marker to the daemon's pts and to the receiver's arrival, with measured clock anchors. This establishes which population each frame falls in, whether the framework parks an empty consume, and settles the pts provenance. Record extension CPU and power at 60 fps and at idle with the present 4 ms wait. 2. Then, baseline-then-candidate with one reverse-order confirmation, on the leg A harness, same receiver, same daemon, same recorded extension build, same host: the pts → relay histogram (the candidate must collapse it from two populations to one), AVF delegate and Chrome reader arrival-interval sd / p95 / p99 / max, framesPerCompleteSecond, marker loss and duplicates, daemon dropped, extension CPU and power at 60 fps and idle. Reject on any increase in marker loss, any CPU spin at idle, or no change in the histogram. 3. Only after that, the plan's section 3 contract for a delivery claim: unique delivered FPS decoded from final rendered pixels through Noisedeck B's media effect, in web and desktop, with marker age p50 / p95 / p99 / max, complete-second records, and the probe-free timing trace kept separate from the pixel-observer run. 4. In every run: in-window CPU and GPU sampling, an idle baseline for the host, AC power and thermal state, other sessions recorded; no builds or unrelated profiling during a comparison. Ordering recommendation (a recommendation, not a finding): run the extension consume-cycle trace before the 4B sender separation, because it completes the unfinished part of the 4A rule, it is reader-independent, and it settles the pts provenance on which the stage picture in section 4 rests. Both are one-hour screens and must run serially on the host (plan section 5). ### 8.5 What must not be concluded from leg A - No delivery claim. No arm rendered camera frames into Noisedeck's media effect; nothing here is unique delivered FPS, final pixels, or marker age as the plan defines it. "60 arrivals in every complete second" is a reader count. - No desktop claim. No Electron arm ran; the plan's step 5 (repeat in desktop) and the "both builds" rule are unmet; the desktop fixture's Chromium differs from the web fixture. - No long-session claim. Eight 20 s windows inside six minutes of wall time cannot resolve the 81.74 s beat (0.012234 Hz, four times below the 0.050 Hz resolution of one window) or multi-hour decline, the reset-boundary question, or plan section 6. - No E1 equality, replication, before/after pairing, or cause claim: different observer, host, browser build and sample size; the native arms' envelope resembles E1's and is not a measurement of it. - No "the browser sender creates the jitter": it does not create the body of the spread; it adds a tail; the producer comparison bundles export, ingress, admission rule and pacing. - No "Chrome adds no spread" and no "Chrome adds spread": undecided. No "both stages carry comparable variance". No "daemon-only" label on the pre-stamp stage. No "AVF delivery" for delegate entry. - No "Chrome inserts duplicates", no "skipped frames" as the description of the 33 ms send gaps, no "same conditions" across receivers. - No "the cells agree", no "no missing markers", no "no consumer drops" at Chrome, no "no arm recorded daemon drops". - No cross-host claim (M4 here, M2 in the plan's evidence), no claim that the running extension was built from a named commit, no claim about host load magnitude (no idle baseline, no in-window sample), no claim that any single operation inside the named boundary is the cause. ## 9. Limits 1. Every count and interval is arrival timing at a reader (Chrome MediaStreamTrackProcessor or an AVFoundation delegate); no final pixels and no unique delivered FPS were measured; E1 remains the only camera-path final-pixel-adjacent trace and it used a different observer, host and browser. 2. Daemon is Sync 0.2.65 (syncd sha256 `d157fe7447522ac63cbfd499ddf6b2c28e500760dc11615a4dbad62174f3a3cd`); the running camera extension is the installed 0.2.38 (sha256 `67bbc9fa19f5ed14a9525281f7750198eb78b5d1314e0646026227df40a69eba`); the extension source is unchanged from 7fdfdc9 through d167ee4; the mapping of 0.2.38 to a specific commit is asserted, not shown (the sync tree carries no changelog entry or embedded commit hash for it, and the product version is supplied at package time); daemon-side native code including cmio_camera_sink.mm, camera_publisher.cpp, camera_frame_fitter.mm and websocket.cpp changed between 865cc2e and d167ee4; no arm ran a 0.2.65 extension and no arm ran the 0.2.38 daemon, so this leg cannot separate daemon-version from extension-version effects; one extension process served all eight arms while the daemon was restarted per arm, so extension-side state carried across the arms. 3. Host is Apple M4 / 32 GiB / macOS 26.5 / Chrome 152.0.7977.83, not the plan's Apple M2 / 24 GiB evidence host; nothing was re-measured across hosts and cross-host comparisons are not supported. 4. Other interactive sessions (two AI coding-agent sessions) and system indexers (corespotlightd 38.4 % before run1 native-chrome; fseventsd 50.7 % before run1 browser-chrome) were active; CPU was sampled only at arm endpoints (1 min load 1.61 to 3.56 before, 2.38 to 3.66 after); GPU activity was not sampled; no idle baseline exists for this host, so only the persistence of the spread, not its magnitude on this host, is established. 5. AC power throughout (battery 80 %, not charging); no thermal warning recorded (the absence of a recorded warning, not a temperature measurement); harness, daemon, producer and consumer at nice 0; Chrome's nice value not recorded. 6. Observer costs: Chrome reader readCostMs p95 0.9000005722045898 to 1.1000003814697266 ms per frame (5.4 to 6.5 percent of the median interval), a 1 Hz senderStats evaluate of at most 6 ms in-window on the sender page, an unmeasured send hook, and AVF busyUs p99 of at most 2623.0 us; none was controlled by a probe-free arm. 7. Cross-process stage latencies carry a measured join bound of 1.010009765625 to 1.900146484375 ms on the levels, not on interval spreads; the AVF pts stage provenance is UNVERIFIED by record and the discriminating run (daemon dropped > 0) did not occur. 8. Identity exists only in native arms (24-bit marker per frame); browser arms are hash-only (FNV-1a luma at stride 61), with unexplained non-consecutive hash recurrence (unique hashes 792 / 856 / 806 / 953 against 1122 / 1167 / 1135 / 1156 distinct arrivals, at lags of about 577 to 597 frames) and an unrecorded source scene; the plan's `testPattern()` was not used, so the browser arms' picture is not reproducible from the record. 9. The browser sender and the Chrome receiver ran on the harness's test-token path: the daemon in test mode with a test origin and test token, Noisedeck A's Sync controller token replaced and its client creation wrapped, a permissions.query stub answering loopback-network and local-network-access as granted, and Chrome launched with a fresh profile per arm and the flags --no-first-run, --no-default-browser-check, --autoplay-policy=no-user-gesture-required, --disable-features=LocalNetworkAccessChecks (Noisedeck A) and --use-fake-ui-for-media-stream (Noisedeck B, which auto-accepts the getUserMedia prompt while keeping the real device list). No pairing and no permission prompt was exercised; a passing run is not evidence that a real user's permission prompts work correctly. The browser sender refused 40 to 66 of its own frames per session, while the native producer skipped none; the producers also differ in the alphaMode header field (3 vs 1) and in source picture. Arrival-rate differences are not attributable to the camera path alone. 10. Chrome-receiver interval statistics for browser arms include the re-delivered repeats unless stated otherwise (that is why their min is 0.400 / 0.100 ms); distinct-only values are in section 3 (p95 moves from 29.200 to 32.400 ms in run2 browser-chrome under the distinct-only convention). 11. The two receivers share the daemon and extension and ran in separate, never simultaneous sessions with different capture formats (NV12 at Chrome, BGRA at AVF), so their agreement is expected rather than independent, and comparisons hold within a receiver, never across receivers. 12. The receiver swap also changed host state, so anything attributed to Chrome includes effects upstream of Chrome's capture: the producer's own socket write duration (submit to write completion, in-window, n = 1200 per arm) was p50 3.543 / 3.214 ms with Chrome B running (run1 / run2 native-chrome) against 2.620 / 2.607 ms without (run1 / run2 native-avf), with frames above 6 ms 156 / 226 against 88 / 67 and p95 7.319 / 7.119 / 7.884 / 6.451 ms; these values are the decision memo's recompute from the four producer records (n = 1200 per arm, frames selected by submit time inside the measurement window) and are not in the retained C2 review output; the mechanism-analysis row of Table 3 selects frames by identity join, which gives 2.6062 ms for the run 2 native-avf median. 13. run2 native-chrome lost 3 markers inside its window (325, 731, 971) and 4 before it (1, 75, 97, 152), with daemon dropped 0 and no AVF arm losing any; its warmup carried 3 sub-millisecond same-hash re-deliveries (markers 73, 95, 150); its producer carried one 15331.676 us late submit (sequence 970) that no other native arm had. The two native-chrome runs were therefore not identical on the producer side. 14. No desktop repeat exists. The harness holds no Electron support. A desktop repeat would require at minimum the retained desktop fixture the plan describes for E3 (Electron 42.3.0 / Chromium 148.0.7778.180, source entry not packaged), launched for both A and B with a remote-debugging port; the same test-token and permission handling inside Electron (its session permission handler or the same Chromium switches, including the fake media UI and the LocalNetworkAccessChecks feature); MediaStreamTrackProcessor available in that Chromium; the same staged daemon and installed extension; the Electron and Chromium versions recorded in the manifest; and both browser-sender and chrome-receiver cells re-run (the AVF receiver cells are Chromium-independent, but the sender cells change). The plan's own caveat applies: the desktop fixture's Chromium version differs from the web fixture, so cross-build differences do not isolate the desktop shell. 15. No delivery and no long session: 20 s windows cannot resolve an 81.74 s beat (0.012234 Hz against a 0.050 Hz resolution) or multi-hour decline; consecutive arms within a run started 31.114 to 51.292 s apart and run 2 began 64.947 s after run 1's last arm; the eight windows total 160 s of measurement inside six minutes. One host, two runs per cell, receiver-pair order not reversed; n = 2 per cell supports no interval estimate. 16. Bootstrap CIs assume independent intervals; lag-1 autocorrelation is -0.251 to -0.536 across arms (gap-then-catch-up pairs are negatively correlated), so the CIs are approximate and if anything too narrow; KS p-values are asymptotic and shown for scale only. AVF pts values arrive quantized (the consumer sees ptsScale 100000 and values ending in 0000); the statistics document bounds the effect of that quantization on pts-interval sd at no more than 0.029 ms; Chrome read times have 0.1 ms granularity. 17. The canvas.changed invariant difference between browser arms (true) and native arms (null) is by design (no Noisedeck A canvas exists in native arms); the four analyzer warnings about it are not defects; every receiver frame in every window was 1920x1080. 18. Retention gaps: no complete-second plot (the per-second arrays are in each arm's analysis under framesPerCompleteSecond); the AVF consumer binaries exist only in the experiment workspace (source and build flags are retained per arm); the harness sources, untracked when the limits audit and the decision memo were written, are committed at 0f73f5c (section 10). The 24 raw input files hash to the values recorded in each analysis (verified 2026-09-10); they are mode 0644 and not write-protected. 19. Two statements in earlier leg A working documents are superseded by the reviews and by this report: the statistics and limits documents attribute run2 native-chrome's 31.100 ms maximum to the producer stall (it is markers 323 to 324 with ordinary producer timing; the stall sits beside the 29.900 ms interval at 968 to 969), and the statistics document attributes the run 2 Chrome maximum submit-to-arrival of 49.121 ms to the sequence 970/971 event (it is sequence 324). The originals are left untouched, as the retention rule requires; the decision memo and this report are the superseding record. ## 10. Retained evidence Plan section 7 asks each cycle to retain six items. Where each stands for leg A: 1. The hypothesis and the single changed variable: the specification. The producer is the changed variable; the change bundles export, transport ingress, admission rule and pacing (section 1). 2. Source and runtime hashes, environment, workload and test order: the per-arm manifests, and the fixtures and arm-order tables of section 1. 3. Raw measurements, clock bounds, missing data and observer overhead: the per-arm records and analyses, and section 2. 4. Delivery and latency distributions for both builds: absent. Arrival distributions exist for the web build only; no delivery was measured and no desktop build ran. 5. A stage-timing diagram and a complete-second delivery plot: Figure 1 is the diagram; the complete-second plot is absent, and the per-second arrival counts are retained in each arm's analysis under framesPerCompleteSecond. 6. The decision, cleanup result and next action: section 8, the decision memo, and the cleanup line at the end of this section. Retained locally, by kind (raw data and generated diagrams stay outside source control per plan section 7): - Raw per-frame records for every arm: the Chrome reader's arrivals record or the AVF delegate's record, the paced producer's record or the browser sender's send-hook record, host snapshots before and after, daemon, static-server, Chrome and orchestrator logs, and in AVF arms the consumer log and the consumer source sidecar (avf-consumer.mm, avf-decode-test.mm, avf-marker.h, avf-record.h, build-avf.sh). - Manifests with hashes: one manifest per arm recording the daemon and extension digests, the six harness tool digests, the AVF consumer digest, the Noisedeck reference and SDK version, host, OS, Node and Chrome versions, ports, windows, load averages, power, thermal state, nice values, top processes, cleanup results and the per-arm validity verdict. - Analysis outputs: one analysis per arm (with prior versions kept), the eight-arm comparison and its JSON, the per-run comparisons, the retained stage-timing diagram, the statistics document and JSON, the mechanism analysis and its four-stage decomposition output, the limits audit, the evidence ledger, the specification, the AVF self-test and decode-test logs, and the decision memo. - Review scripts and outputs: the refutation-review recomputations for each of the four draft conclusions (raw-data recompute, rival explanations, measurement contract), scripts beside outputs, except the C3 measurement-contract lens's own scripts, which were not retained; the retained C3 recompute, timeline and rival-explanation outputs independently reproduce its send p99 and max, refusal offsets, sequence-step counts and matched-gap counts. Tool sources committed to the scaffold repository at commit 0f73f5c (after the limits audit and the decision memo were written): the six files in the table below, each of whose committed blob hashes to the digest every arm manifest recorded, plus `lib/owned-children.mjs`, whose digest the evidence manifest carries. The AVFoundation consumer (executable sha256 `50bfe5f1d919656d3fde7cee99a19d54a8bb7c1b2059ac5bc87df646cfdc4e49`, built with clang 21.0.0 against SDK 26.5) and the analyzer (sha256 `178b69b8f964221482d00beeb42ad9ff856a4325ddab32bdbfeb201d31a11bdb`, Python 3.14.5) are retained in the experiment archive. Digests of the harness sources as recorded in every manifest: Harness tool source digests (manifest toolSources). | File | sha256 | |---|---| | bin/paced-producer.mjs | `0abceb94296802bc52436d3a3e1112b2c2f780aa98ed14cbd819459de6ca8bb9` | | bin/producer-probe.mjs | `2605a2de44b26810646226f65508a0326f035db045c89a36a2c3f412bc8e33c0` | | lib/arrival-recorder.mjs | `27b4e8cdab5bcc8235cfebafd09340d0a9f9c46d73ba88320d5cacb3fee2a97e` | | lib/marker.mjs | `6e5be211e621a2a35d8e98ffbda10412998b155eb3d22d85e4230dfd9926b9f9` | | lib/paced-producer.mjs | `0700b35cd5cd0567cbd4a13587c4ee91abced782f60cec81f30b31341e630c63` | | lib/probe-process.mjs | `efdf2485a8a65de3190bf3697c4519efb574eb2ed90e6d6f1a41b89832e02cce` | Digests of the 24 raw input files, as recorded in each arm's analysis and re-verified on 2026-09-10: Raw input digests. | Arm | File | sha256 | Bytes | |---|---|---|---| | run1 browser-chrome | manifest.json | `306561e239d9d7009781b490aa1757cf02bba3683a97267b0096d0407ab2166d` | 11101 | | run1 browser-chrome | sender-frames.jsonl | `8d8335a8099d3a9fd118bf333f08954063499815ed50d90ae2520d41b6098b79` | 222634 | | run1 browser-chrome | arrivals.jsonl | `3295d10653b83b0775f1512c89d877c1906d1e9be2ecbfabf84e758db6ac9d35` | 612241 | | run1 native-chrome | manifest.json | `c79e8690eee37b7f78b94be5adeabd6dc2b84b8484f9deaf89bb359ef8db56cd` | 13596 | | run1 native-chrome | producer.jsonl | `ca6a3888850b307698c3ad1e305176434dee7087901578d24aabe82906d71e9c` | 337400 | | run1 native-chrome | arrivals.jsonl | `ba38762071979f1d9165222a633bad9e68d20e143abb3fb0cd1b3a67541cfba5` | 481464 | | run1 browser-avf | manifest.json | `40db1c65adba6f716b9ff48a2e02df83254de6858e51777ce3a936497734f1e6` | 18540 | | run1 browser-avf | sender-frames.jsonl | `fa5e5faf082768d1ff382fbb433af717755eb7d6f82dffff01e38b5b096c57af` | 219558 | | run1 browser-avf | avf.jsonl | `d6858ca9d996bfd5dda9aa6fd9958ee449b30205eff235f503d05a8e39c9e7fd` | 699932 | | run1 native-avf | manifest.json | `14a702c3a4e5111aebf49be533ac2cac60389f31f794073c7eb8a84553a33702` | 20846 | | run1 native-avf | producer.jsonl | `ce420af70f6c045cc807952f93e9a638275e30c4342771ccc530d7cb52cd9128` | 337616 | | run1 native-avf | avf.jsonl | `4f913ab569410120e9e988e35129178ec0f84c2a35bd85fd82a5d226bd232c31` | 597719 | | run2 native-chrome | manifest.json | `59bcd3719950c80d74eddfaab95565ce280dc4a98b353bb2d8bb25a6019d2b86` | 13355 | | run2 native-chrome | producer.jsonl | `154080265675f49b9ff91e51febe6f801bd69abf2c7101127289b8df561870f8` | 337426 | | run2 native-chrome | arrivals.jsonl | `b53b7398f2072bcd28bbc7e4365b741c0fbeb18475c1eb215ffc446f7f0ef779` | 480561 | | run2 browser-chrome | manifest.json | `3a8d660615834d121c132aaf4f203a73f5d50a589a5f346d50ddcd8b7efe6249` | 10745 | | run2 browser-chrome | sender-frames.jsonl | `292df083efbd5d910fee9ac3160540e31b4a3320fe993e3e4c1f8c95793fffb9` | 222065 | | run2 browser-chrome | arrivals.jsonl | `387a295a2d0423b78224fa409294c566caea8f574716d624d0244f8a0c545b55` | 607475 | | run2 native-avf | manifest.json | `e33ac3dad53e489dca87d425c57dd459d10895edcf414175f3ddb7734d88efa0` | 21044 | | run2 native-avf | producer.jsonl | `0cd088fef3c75593162c86843caa2766517d51862bbad20627da4419c5a25974` | 337626 | | run2 native-avf | avf.jsonl | `7ed83c4e4c593e1d716768b6c0df893c5a8296aad8661833cee6d2235723a3c2` | 597748 | | run2 browser-avf | manifest.json | `e8009941fa8d438a798c55eb1fb8b6213733039adc2937cfd730d4d7098f186e` | 18440 | | run2 browser-avf | sender-frames.jsonl | `d36c3f250a6ea7aa03ef5f7564aebb408aae9eafeb466e277d797d3e0394d796` | 221237 | | run2 browser-avf | avf.jsonl | `7e511c5801d5ed8d0c37b7d187a7bac43099096353cf976e86ea908c63c1cdd0` | 695520 | Digests of the retained analysis documents: eight-arm comparison `f7bffad07847218abfcc8540acd572f093c045f61988c3f82ad1e9a391d58843` and its JSON `f868a4380b7b616685cb755e1e62a92750157908e78938111dc71c9788d5e0ad`; retained stage-timing diagram `97547c084d66f1c87b6401f811b134cd478e4b2243280ff43f6f996befbbc754`; statistics document `1eae89ce514d67fccadb48d8b4cc08b290729784253458d61c482720944449ef`; mechanism analysis `f490a8fa2b2fe2cd95be082d8edd3ef34b40d7636cdf26c7b3f7edf410da0714` and its stage output `e481d12fb9fc8007e03df1eeb28d752c4ecba21b10fbfe2bc02de7cc1f1c8dc1`; limits audit `fa531d71a11771632142a8370b391293c9bc8346cee785ab043d0ba148b785af`; evidence ledger `271553884b5dfea5e214f3c51c36095217c6f94322fad8696037d1e88c3bbe43`; specification `d57da40a905ce9b3ed20b206cbc0aa053b35e55bc3045f6ffaf986723a3b8e08`. Cleanup: no leftover daemon, harness Chrome, consumer or producer process after any arm; every daemon stop exited 0 without a kill; every producer and consumer exited 0 with no signal; the installed system extension keeps running by design. ## Evidence references - [E1: Camera arrival and texture-read timing (plan evidence)](../research-2026-09-10-next-research-plan/evidence-e1.txt) - [Sync 1080p60: next research plan (sections 3, 4A, 4B, 4C, 5 and 7 define this deliverable)](../research-2026-09-10-next-research-plan/) - [Measurements of 1080p camera performance (the final-pixel delivery measurements this leg does not repeat)](../research-2026-09-08-1080p60-camera/) E1 is quoted from the plan bundle's retained summary. Leg A's own evidence is retained locally as listed in section 10 and identified by the source digests above; no raw log, per-frame record or host snapshot is published here. The publication checks started no camera session. Public evidence summaries omit local paths, process identifiers, raw logs, and connection details. Source digests identify the retained inputs.