Repository navigation
A shared clipboard between the development host and ToyOS under QEMU, through QEMU's vdagent - #894
Conversation
|
Design review, round 1, head Net lines ( Evidence: The brief's questions
BLOCKER
NOTE
DESIGN NEEDS CHANGES: let the opening REQUEST's answer land (owner |
|
The orchestrator's rulings on round 1 (#894 (comment)), following spice-vdagent and QEMU per #885's rule:
|
|
Design round 2, head New measurements, all on ToyOSOrg/evidence The owner's later direction (ToyOS does not follow Linux). The design now rests on three definitions only: virtio 1.2, spice-protocol's BLOCKER
NOTE
|
|
Design review, round 2, head Net lines ( Evidence: ToyOSOrg/evidence Round 1's BLOCKERs
BLOCKER
NOTE
SEND BACK |
|
Rulings on round 2 (#894 (comment)).
|
|
Design round 3, head New evidence, ToyOSOrg/evidence
The probe runs QEMU under BLOCKER
NOTE
Still open, as the body says
|
|
Design review, round 3, head Net lines ( Evidence: ToyOSOrg/evidence
Round 2's BLOCKERs
Round 2's NOTEsAll taken:
The fence matches the ruling: BLOCKER
NOTE
SEND BACK |
|
Rulings on round 3 (#894 (comment)).
|
|
Design round 4, head BLOCKERA guest copy withdraws an owed
NOTE
NOTEs 3 and 4 are ruled as the orchestrator's and the build round's, and the body is unchanged for them. |
|
Design review, round 4, head Net lines ( Evidence: ToyOSOrg/evidence Round 3's BLOCKER
Round 3's NOTEs 1, 2, 5
BLOCKER
NOTE
Is it ready for a builder who has read neither source? Not yet. Every QEMU fact the bridge encodes now stands on a cited log line or is marked unmeasured, and the serial and withdrawal rules can be built from this body alone. What remains is the BLOCKER above: the answer's text must be pinned and the size claim must be tested. Once that closes, the body is ready for such a builder. SEND BACK |
|
Design round 5, head BLOCKERThe answer's text is pinned, and the size bound is tested at its exact counts.
NOTE
|
|
Design review, round 5, head Net lines ( How I checked it:
Round 4's BLOCKER: CLOSEDThe answer's text is pinned at the host
Round 4's NOTE: CLOSEDThe capabilities row and "Transmit" both state The two additions beyond the review
BLOCKER
NOTENone. Is it ready for a builder who has read neither source? Not yet. Every size is right, and the serial, withdrawal and deferral rules can be built from this body alone. Two SEND BACK |
|
Round 6: the round-5 review's findings, mapped to the body. Head BLOCKER 1 (a second host
Rule (the
BLOCKER 2 (an answer crossed by QEMU's own grab). Measured as Q19. The sequence is a kept guest grab, a host paste (the guest gets
Rule: a kept host grab withdraws an owed answer, as it withdraws the push. This is in the host
What moved with it:
|
|
Design review, round 6, head Net lines ( How I checked it:
Round 5 BLOCKER 1, a second host
|
|
Round 7: the round-6 review's findings, mapped to the body. Head BLOCKER 1, the
NOTE 1, §4 "Transmit" names an answer and NOTE 2, Q19 cites the bus-mastering run. That sentence and its citation are deleted. Q19 now cites only requests log |
|
Design review, round 7, head Net lines ( How I checked it:
Round 6 BLOCKER 1, the bridge answers a
|
|
Design accepted at |
… through QEMU's vdagent Every virtio machine gets QEMU's qemu-vdagent chardev on a virtio-serial function of its own, created just before the console's, with the agent's port `com.redhat.spice.0` at id 1 of 2 (build/vdagent.rs, read by cargo run's launch and by the harness). `cargo run` takes the display whose clipboard the host shares: cocoa on macOS, GTK with its clipboard on elsewhere. A QEMU without the chardev, or a non-macOS host without GTK, is refused by name before anything launches. The kernel: two 1af4:1043 functions now carry two devices. The console drives the first virtio console function that offers no MULTIPORT (toyos_pci::console), read by the first half of VirtioDevice::init, split out as VirtioDevice::offer, before any function masters the bus; a declined function is reset and left to a claim. A claim's vendor:device resolves among the functions the kernel does not drive (toyos_pci::claimed). /system/bin/vdagent claims the function, drives it over toyos-virtio and toyos-pci-claim, decodes the stream with toyos-vdagent (lib/vdagent, an input boundary of its own, after vd_agent.h at 499cc832 and virtio 1.2 §5.3), and makes every decision in toyos-vdagent-bridge, pure and host-tested. It pushes each guest copy with its text, answers no host REQUEST, and keeps QEMU 11.1.1's grab serials as measured black-box. The compositor serves a third port, `clipboard`, whose one connection is sent every client copy, one outstanding at a time, and whose sets land only while its ask is outstanding (toyos_desktop::clipboard); the build lets `vdagent` alone receive it. Two issues filed: every pcidev slot claimed on a cargo run boot, and the clipboard unmeasured on Linux and Windows hosts. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015xhaydXCVRNscoccHYFUWy
8fa3b83 to
519b432
Compare
|
T14 at A first judge with the wrong words ( |
|
Review of the build at Net lines ( What checks out.
BLOCKER
NOTE
SEND BACK |
|
Rulings on the build review (#894 (comment)).
The fix round stays clean-room: no QEMU or spice-vdagent source, and not this PR's earlier comment thread. |
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015xhaydXCVRNscoccHYFUWy
…fore a watcher are kept, and sets are one in flight The build review of 519b432 found a race: a host text past 4096 bytes whose MSG_COPY_BEGIN crossed a delivery committed after the watcher's re-ask, and landed over the guest's copy while the host was given that copy. A commit now lands only if the ask was outstanding at its BEGIN and no delivery happened since, and the agent drops the set queued behind the one in flight when it reads a delivery. The compositor's Watch lives in its Session for its whole life, so a copy made before the agent watches is delivered at its first ask; a watcher that leaves takes its ask and region with it. Every watcher set, inline included, is answered by MSG_CLIPBOARD_SET_ANSWERED, and the agent keeps one in flight (toyos_vdagent_bridge::sets), so a host copying at any rate cannot fill the compositor's pipe and end the agent. The stream refuses another protocol, an unknown type and a size its type's layout does not have at the header, counting the data off unread, and grows a kept message's buffer by doubling capped at the declared size. Two tests the review cut go: one re-typed the launch's format! output, one checked a first-party assert. ClaimError's docs say what rule (b) made true; the slot issue is held by the orchestrator, and the declined console function's mapping is filed. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015xhaydXCVRNscoccHYFUWy
…t's exit names no absent function The aarch64 `cargo run` boot the build review asked for refused before launching: `qemu-system-aarch64 -chardev help` exits 1, "No machine specified, and there is no default". `-machine none` lists the chardevs and displays on both architectures' QEMU 11.1.1, measured. That boot then showed the agent saying "no virtio-serial function on this machine" while the supervisor said the function was there and not handed over: the agent's line now says what it knows, that none was handed to it. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015xhaydXCVRNscoccHYFUWy
|
Round 2: the build at
Net lines (
Earlier BLOCKERs
BLOCKER
NOTE
SEND BACK |
|
Rulings on build round 2 (#894 (comment)).
|
…ver holds past its declared size The reserve compared a total length with the chunk's length: once a chunk outgrew the bytes already kept, the reserve fell short and `Vec`'s own doubling decided the capacity. At QEMU 11.1.1's 1,024-byte chunks a `CLIPBOARD` of 2,048 bytes of text, declaring 2,052, kept 4,016. The test now feeds that message as well as the largest the bound admits; it is red with the old line (4,016 held for 2,052 declared) and green with this one. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015xhaydXCVRNscoccHYFUWy
Under HVF `cargo run`'s `virt` has no ITS, so every claim is refused on its interrupts. The same launch by hand with only the machine changed to `virt,gic-version=3,its=on,iommu=smmuv3,kernel-irqchip=off` arms the ITS and maps each claim's DeviceID, and still hands over none: every claimed function's BAR, moved inside firmware's windows, answers at none of the eight addresses tried. So the clipboard agent's aarch64 claim and handshake are unbooted; the arm64 track owns the fix. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015xhaydXCVRNscoccHYFUWy
|
Round 3: the build at
Net lines ( Earlier BLOCKERs
BLOCKERNone. NOTE
LAND |
Each function answers at its firmware BAR with its own value, and the moved BAR reads 0xffffffff except at the ECAM base, where the NVMe reads 0x00081b36 and the other three 0x00000000; cited by line in the log. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015xhaydXCVRNscoccHYFUWy
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015xhaydXCVRNscoccHYFUWy
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015xhaydXCVRNscoccHYFUWy
#894 adds the clipboard port beside the input port: both are held alone, both are served by the compositor, and its poll budget counts both. #904 rewrote step 7.2 of the track; its text is kept, marked done. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015xhaydXCVRNscoccHYFUWy
#894's `clipboardcase` landed with a compositor row from before this branch, and the compositor takes the `input` acceptor as it takes `prompt`'s, so it panicked at its start on that boot. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015xhaydXCVRNscoccHYFUWy
A shared clipboard between the development host and ToyOS under QEMU: copy on the host and paste in ToyOS, and the other way. The guest end is
/system/bin/vdagent, the agent of QEMU'sqemu-vdagentchardev. It talks to that chardev over a virtio-serial function of its own, and it talks to a newclipboardport of the compositor. The owner gave his go. The design was accepted on this pull request before the build. Every statement about what QEMU 11.1.1 does is behaviour measured black-box, and the logs are onToyOSOrg/evidencepr-894. Nothing in the tree cites an implementation's source.What changed, and why
The launch (
build/vdagent.rs,build/qemu.rs,tests/common/qemu.rs). Every virtio machine gets-chardev qemu-vdagent,id=vdagent0,clipboard=on,mouse=off. It also gets avirtio-serial-pci-non-transitionalwithmax_ports=2, withvirtserialport nr=1 name=com.redhat.spice.0on it.toyos_buildlibrary. That function reads the codec crate's declaration (PORT_NAME,MAX_PORTS,PORT_ID), and both launchers call it.00:06.0before the console's00:07.0on q35), and every virtio guest boot runs the kernel's console rule.cargo runnow passes-display cocoaon macOS and-display gtk,clipboard=onon other hosts, one choice per host. The harness keeps-display none.qemu-vdagent(-machine none -chardev help) before anything launches. A non-macOScargo runalso asks forgtk(-machine none -display help). The machine is named becauseqemu-system-aarch64has no default one and lists nothing without it. A missing one is refused by name ("built without spice-protocol", "no GTK display; Debian ships it asqemu-system-gui"). Nothing falls back.The kernel: two
1af4:1043functions are two devices. Both rules are pure decisions intoyos_pci(kernel/pci/src/choose.rs), with host tests.VIRTIO_CONSOLE_F_MULTIPORT(toyos_pci::console). The single-port driver can drive nothing else: a multiport device names its console ports on control queues (virtio 1.2 §5.3.6.2).VirtioDevice::init, split out asVirtioDevice::offer. That half is §3.1.1's reset,ACKNOWLEDGE,DRIVERand the read.initis nowofferfollowed byOffered::accept.enable_bus_masteris what records a function as the kernel's.offers MULTIPORT … reset and left to a claim) and left to a claim.vendor:deviceresolves among the functions the kernel does not drive (toyos_pci::claimed). One such match is the claim's, two areAmbiguous, and driven matches alone areKernelDriven.usbd_drives_the_spare'sKernelDrivencontrol keeps its line and stays green.The codec,
toyos-vdagent(lib/vdagent). This is an input boundary of its own: pure,no_std, and tested on the host. Every word it decodes comes from the host.spice/vd_agent.hat499cc832). The stream is decoded as a stream, so a header may straddle two receive buffers.VD_AGENT_MAX_DATA_SIZEends the decode. Everything else is refused by name and the next message still decodes: another port is skipped; another protocol, a message declared past4 + MAX_TEXT, an unknown type or a size its type's layout does not have is refused at its header, and its data counted off unread. An admitted message carries its type as an enum, so the decode of a whole one cannot refuse.Vec's own doubling never decides the capacity.LARGEST_TRANSMITis computed by the encoder: capabilities plus a 2 MiB push, which comes to 2,105,448 bytes.The agent,
/system/bin/vdagent(system/vdagent). It drives the function overtoyos-pci-claimandtoyos-virtio, in netstack's pattern.MULTIPORTand refuses amax_nr_portsthat is not 2. It builds the six queues beforeDRIVER_OK, all on the one MSI-X entry.PORT_OPEN(0/1)with its own.toyos-vdagent-bridge:GRAB [serial]with itsCLIPBOARD, or with aRELEASEfor a copy of nothing, in one transmit. Once QEMU holds the text, no host paste waits on the guest.REQUEST.s ≥ last, and each session starts at 0.REQUESTon a guest copy, and an unsent push on a kept host grab.toyos_vdagent_bridge::sets) until the compositor answers it, with only the newest host text behind it, and drops that one when a guest copy is delivered: its text was taken before the copy.cargo run, below) it says so in one line and exits 0.The compositor and
sdk/window. A third port,clipboard, with one connection, the watcher:MSG_CLIPBOARD_WATCH) in a slot of its own (toyos_desktop::Port,pending_admits). A second watcher is refused by name.Sessionfor its whole life (Watch), so a copy made before the agent watches is sent at its first ask. A watcher that leaves takes its ask and its open region with it, and leaves the unsent copy to the next one (Watch::leave).MSG_COPY_BEGINand no copy was delivered since, judged atMSG_COPY_COMMIT. So a host text that crossed a guest copy never lands over it, whether the delivery came before or after the region opened.MSG_CLIPBOARD_SET_ANSWERED(compositor → watcher, bare, 14), whether or not it landed.window::watcher::Watcherholds one set in flight until that answer and panics on a second (the caller's bound), so a host copying at any rate cannot fill the compositor's pipe and end the agent.toyos_desktop::clipboard::Watch.MAX_WINDOW_SLOTSfrom 218 to 216.Authority.
[programs.vdagent]holdsdevices = ["pci:1af4:1043"]andreceives = ["clipboard"], and runs in[boot] start. The compositor's row servesclipboard, inimages/system.tomland in the two test configs whose compositor rows serveprompt(metalcase,panelcase).HELD_ALONEgains (clipboard,vdagent), and the port's name and holder are declared intoyos_manifest::clipboard.exempt.ownssits insystem/vdagent/Cargo.toml's metadata, where the tree keeps it.kernel/src/device.rs(the fence widened by this one file):ClaimError::AmbiguousandKernelDrivensay what rule (b) made true, more than one function the kernel does not drive and every matching function driven.Issues. Four. The first three are held by the orchestrator:
issues/a-cargo-run-boot-claims-every-pcidev-slot.md: sound, net, disk and now the agent take all four ofpcidev::MAX_FUNCTIONS. Exit: acargo runboot leaves a slot free.issues/the-shared-clipboard-is-unmeasured-on-linux-and-windows-hosts.md. Exit: a copy and a paste each way, measured on a Linux host under GTK and on a Windows host.issues/a-declined-console-function-keeps-a-kernel-mapping-of-its-firmware-bar.md:VirtioDevice::offermaps the declined function's capability windows throughmap_mmio, which has no unmap, andpcidevlater moves that BAR. Virtio 1.2 §4.1.4.9's configuration access capability is named as the way to read with nothing mapped. Exit: a declined function leaves no kernel mapping and no driven window.issues/an-aarch64-cargo-run-boot-hands-over-no-pci-claim.md, owned by the arm64 track:cargo run'svirtunder HVF has no ITS, and with one by hand every claim's BAR placement still fails (below). It records the agent's aarch64 claim and handshake as unbooted. Exit: acargo run -- --arch aarch64boot shows diskserver serving andvdagent: port 1 open.Fix round 3, finding by finding
Against the round-3 review (#894 (comment)).
issues/an-aarch64-cargo-run-boot-hands-over-no-pci-claim.md:18-21is false of the log0x0f0107ff,0x79000000,0x30bf8024,0x00000103, :327, :386, :433, :470); every moved BAR reads0xffffffffexcept at0x4010000000, the ECAM base (:212) inside a window firmware declared (:225), where the NVMe reads0x00081b36and the other three0x00000000Fix round 2, finding by finding
Against the round-2 review (#894 (comment)) and its rulings (the newest comment).
stream.rs: the reserve's floor isdata.len() + take, a total, where it wastake, an incrementa_kept_message_buffers_no_more_than_it_declaresnow feeds a 2,048-byte text throughhost()as well asMAX_TEXT, asserting the capacity is at most the declared size. With3a60123b6's line it is 101, "4016 bytes held for 2052 declared"; with the fix 0; the log names that red arm m24, the same patch as m25 below (capacity-arms.log:11, :25, :35). At the head, m25 (that line restored) reds it, 101MSG_CLIPBOARD_SET_ANSWEREDport 1 open, so the agent's aarch64 claim and handshake are recorded unbooted in the new issue, and the two lines shown in round 1 standissues/an-aarch64-cargo-run-boot-hands-over-no-pci-claim.mdvirtwith one isits=on,kernel-irqchip=off; it does not record thatcargo run's boot hands over no claimThe aarch64 boot with an ITS (aarch64-its-boot.log, the argv aarch64-its-boot.argv.log). The image is
cargo run -- --arch aarch64 --build-onlyat24880cdc5(build 24880cdc5… clean, :350);60f08b937adds only the issue.cargo run -- --arch aarch64was run with aqemu-system-aarch64first onPATH(aarch64-its-boot.shim.sh) that logscargo run's own argv and execs QEMU 11.1.1 with only-machinechanged tovirt,gic-version=3,its=on,iommu=smmuv3,kernel-irqchip=off. The tree was not changed. Exit 0, QEMU ended by me over QMP once the agent had exited (:492); QEMU's stderr is empty.00:08.0(:282-287).port 1 opendoes not appear. Every claim fails a step later than without the ITS:pcidev: PCI 00:07.0 NOT HANDED OVER — its BAR was moved onto 8 64-bit address(es) inside the windows firmware declared and the function answered at none of them(:487), and the same for00:02.0,00:06.0and00:05.0(:343, :418, :450). The agent exits on "no virtio-serial function was handed to this program" (:491).cargo run's machine is in this branch's fence. Both are the new issue's, owned by the arm64 track.Fix round 1, finding by finding
Against the build review (#894 (comment)) and the rulings (#894 (comment)).
519b43215Watchrecords atbeginwhether the ask was outstanding, and a delivery marks an open region stale; the agent drops the set queued behind the one in flight when it reads a delivery (Sets::delivered)a_region_opened_after_a_delivery_refuses_the_commit_after_the_next_ask, the review's sequence: 101 on519b43215'sclipboard.rs(base-red/run.log:2).a_delivered_guest_copy_drops_the_set_behindis new API; m23 reds itWatchis aSessionfield;client_copyrecords every copy;Watch::leaveat reapa_copy_made_while_nobody_watched_is_sent_at_the_next_askis new API (leave), so it cannot exist at519b43215; m18 (a leave that forgets the unsent copy) and m19 (one that keeps the ask) red it. The session glue itself has no host test: the pure claim it rests on, a copy before any ask is sent at the first ask, isa_client_set_is_sent_once_asked, unchangedthe_launch_spells_the_codecs_declarationanda_message_past_the_buffer_is_the_callers_bugdeletedcargo runboot95d5161f:qemu-system-aarch64 -chardev helpexits 1, "No machine specified" (log:286). The listings now name-machine none, measured to list both on QEMU 11.1.1 for both architectures. At the head the boot shows the first two lines and not the third; see belowunsent = falsesetreads the ask alone and takes&selfBody::Keepcarries a typedKindand no protocola_refusal_is_named_at_its_header_before_its_data_arrives: 101 on519b43215'sstream.rs(base-red/run.log:3)a_kept_message_buffers_no_more_than_it_declares: 101 on519b43215'sstream.rs(base-red/run.log:4)MSG_CLIPBOARD_SET_ANSWEREDa_set_waits_for_the_answer_to_the_one_in_flight,only_the_newest_set_waits: new API; m21, m22 red themmap_mmiowindowstatus: assigned, held by the orchestratorClaimErrordocskernel/src/device.rspr-894EXIT=lines added laterEXIT=line in this round's logs is appended by the command that ran itAlso found by B5's boot: the agent said "no virtio-serial function on this machine" while the supervisor said it was there and not handed over. It now says none was handed to it.
Checks
Round 2's logs are at evidence
e626cced, from head60f08b937, exceptcapacity-arms.log, which ran with the fix uncommitted at no recorded head; both arms are held at the head bymutations/run.log(m25, 101) andhost-ci.log. Round 1's are atb1283478, from head3a60123b6, which mergesorigin/mainat1b080a3f1; its mutations and base-red runs are from95d5161f, and the one commit after it touchesbuild/vdagent.rsand the agent's exit line, which none of them reaches.cargo run -- --ci hostat7cf25b31fcargo run -- --ci hostat60f08b937cargo test --test toyos-build -- the_opening_exchange_with_qemus_agent_completes, the guest row the fix reaches3a60123b6's line 10160f08b937, m01, m24 (rebased onto the fixed line) and m25port 1 openabsentcargo run -- --ci hostcargo test, the whole guest suitecargo run -- --arch aarch64at95d5161fcargo run -- --arch aarch64at the head519b43215's file858da4d42, agent absentSTALLED519b43215The aarch64 boot without an ITS, round 1 (aarch64-cargo-run.log). Of the three lines the review named:
virtio-console: PCI 00:07.0 offers MULTIPORT … reset and left to a claim(:279);virtio-console: found at PCI 00:08.0andinitialized(:280-285);port 1 opendoes not appear.pcidev: PCI 00:07.0 NOT HANDED OVER — its interrupts would not be remapped on this machine(:397):cargo run'svirtunder HVF has no ITS (ITS: the MADT names none), so no claim is handed over, soundserver's, netstack's and diskserver's among them, none of which this branch changes. The arm64 track (issues/toyos-runs-on-arm64.md) records only that HVF's own GIC refuses an ITS, "so avirtwith one isits=on,kernel-irqchip=off"; it does not record thatcargo run's machine has none, which is nowissues/an-aarch64-cargo-run-boot-hands-over-no-pci-claim.md. The same boot shows the compositor ending on "the manifest gives this program the keyboard": no USB function is handed over either. Round 2's boot with an ITS is above.Mutations of this round, each a checked patch, built, its named test run, and restored, the tree clean after: the size bound lifted (m01); a set sent back (m11); a delivery without an ask (m12); a stale inline set landing (m13); a region judged at its
beginalone (m14) and at itscommitalone,519b43215's rule (m17); a leave that forgets the unsent copy (m18), keeps the ask (m19) or keeps the region (m20); a set sent while one is in flight (m21); the oldest set kept behind it (m22); a delivery that keeps the set behind (m23); growth past the declared size (m24). Round 2 rebases m24 onto the fixed line and adds m25, the reserve short of the chunk (3a60123b6's line). Their patches are beside the log, with the script that wrote them.Independent oracles.
vd_agent.hat499cc832. The encoders are tested byte for byte against the header's packed layouts and §5.3.6.2.pr-894(qemu-vdagent-blackbox.log,-requests.log,-interleave.log). They back every QEMU fact the bridge's tests encode.Why the new guest test needs QEMU.
the_opening_exchange_with_qemus_agent_completesbootstests/images/clipboardcase.tomlonHeadlessVirtioGpu, the one virtio machine with a framebuffer for the compositor.What it costs. The smoke boot is 7 s (guest-suite.log:778). Round 1 measured the suite at 89.7 s on the base and 96.6 s with the row, one sample each; this round's run took 44.5 s for 53 tests, on a warm cache. These are measurements, not bounds. In the image,
bin/vdagentand one process start in everyimages/system.tomlboot, the T14's included.The T14, the orchestrator's run of
519b43215(judge-rows.log, kernel.log, masked):519b43215clean (kernel.log:322).spawn_costandpci_inventoryPASS, 2 of 2 (judge-rows.log:14-22).1af4:1059,1af4:1041,1b36:0010or1af4:1043, and novendor:deviceis on two functions, so rule (b) changes no claim on that machine and rule (a) finds no console function.spawn_cost:toyboxmedian 1111 µs, min 927 µs, over 50 (kernel.log:531).device.rs's doc comments), and neither row reaches the compositor's clipboard, the window SDK's watcher or the agent.Net lines.
git diff --shortstat origin/main...HEAD: 45 files, +3,474 −154. Round 1 put production at 2,456 (with the test lines inside modified files), tests at 867, issues andCargo.lockat 102. Round 1 alone: 14 files, +359 −143. Round 2 alone (git diff --shortstat 3a60123b6..HEAD): 2 files, +51 −8, one production line changed, the rest the test and the issue. Round 3 alone: 1 file, +8 −2, the issue's prose.Dependencies. No external crate is added. The new crates are
toyos-vdagent(a boundary),toyos-vdagent-bridge(the program's pure decisions) and thevdagentprogram.toyos-buildtakestoyos-vdagentso the launch reads the agent's declaration.Staged evidence: the owner's copy and paste on the Mac
Nothing waits on this. It is the cocoa peer, which no probe could reach.
cargo runon the Mac. QEMU must listqemu-vdagent(qemu-system-x86_64 -chardev help), and this development host's 11.1.1 does. The console printsvdagent: port 1 open, the host announces capabilities …and thenvdagent: the host's clipboard, N bytes, where N is the length of whatever the Mac's clipboard held at boot.vdagent: the host grabs the clipboard, serial S, 1 type(s)andvdagent: the host's clipboard, N bytes. Open the Editor in ToyOS and paste with GUI+V. If cocoa takes ⌘V for QEMU's own menu, use whatever key reaches the guest as GUI. The line appears.vdagent: a guest copy of N bytes. Paste with ⌘V in a macOS app, and the text appears.Record each console line and what appeared, and attach them here.
What I am unsure of
Outside the kernel fence, accepted by name in the rulings:
tests/common/iommu.rs:iommu_virtio_platformcounts the agent's function among those the kernel does not drive (- 2became- 3).tests/images/metalcase.tomlandpanelcase.toml: their compositor rows serveclipboard, as they serveprompt.The agent on aarch64 is not booted past its claim. No claim is handed over on
cargo run'svirtunder HVF, nor with an ITS by hand, so the agent's handshake on aarch64 rests on the same code that passes on q35;issues/an-aarch64-cargo-run-boot-hands-over-no-pci-claim.mdrecords it unbooted.B2's glue has no test that reaches it.
Sessionnow ownsWatchand records every copy; no host test drivesSession, and the one guest row does not copy before the agent watches.A new frame type, accepted by name in round 2's rulings.
MSG_CLIPBOARD_SET_ANSWEREDis how the ruling's "one in flight" is bounded for inline sets, which had no answer: the alternative, every set through a region, cannot carry an empty set (copy_fitsrefuses 0 bytes).Two spellings of the clipboard's bound.
toyos_vdagent::MAX_TEXTis a second spelling ofwindow::MAX_CLIPBOARD_BYTES, asserted equal at compile time in the agent, as the compositor assertsMAX_SNAPSHOT_BYTES == MAX_FRAME_LEN.sdk/windowis guest-built and the codec is host-tested, so the codec cannot read it.offerturns on memory decode before the reset.enable_bus_masterused to do both at once."A session that would pass
u32::MAXends by name." This is my reading, because a host serial reaches the bound: the session stops flowing (SerialsExhausted) until the next announcement, and the program does not end.Unmeasured: the cocoa and GTK peers. The steps above cover the Mac, and the issue covers the rest.
🤖 Generated with Claude Code
https://claude.ai/code/session_015xhaydXCVRNscoccHYFUWy