Skip to content

The T14 downloads over HTTPS through ToyOS's own stack inside its list's bound, and netstack's 64 KiB receive window is filed as the ceiling its rate sits on - #818

Draft
Japabu wants to merge 33 commits into
mainfrom
wt/toyos-speed
Draft

Japabu wants to merge 33 commits into
mainfrom
wt/toyos-speed

Conversation

@Japabu

@Japabu Japabu commented Oct 9, 2026 •

Copy link
Copy Markdown
Collaborator

Carries #801 (wt/toyos-move, ToyOS's own stack) and #810 (wt/toyos-tls, HTTPS on ring), which have not landed: this branch merges main again once they have. Its own change is 83ef5a9ae, 089c9b713 and 3b196d075, records only (git diff 9b16d2938..HEAD).

What changed and why

  • https_download (tests/toyos-rust-tests/src/bin/https_download.rs, a job) fetches Rust 1.81.0's rust-1.81.0-x86_64-unknown-linux-gnu.tar.xz from static.rust-lang.org/dist/2024-09-05/ with the client https_get builds. That client is now one module both jobs read (tests/toyos-rust-tests/src/https_client.rs, the way served_log.rs is shared): an unchanged ureq on rustls on ring that trusts one roots file, sends exactly the User-Agent toyos-build (https://github.com/ToyOSOrg/ToyOS) and nothing else identifying, and hex-encodes a digest. The shared module was the smaller choice. One job would have had to carry the lease wait, the counters, the window and the handshakes as modes of https_get.
  • The transfer is bounded by time, not by size. A metal job takes no argv: the runner refuses a job word that is not one binary name. So the bound comes from the runner. In a list, it sets TOYOS_LIST_BOUND_MS (toyos_tco::LIST_BOUND_ENV) on each job to the bound it gave the list, counted from the kernel's zero, and the harness computes that bound per boot (list_bound_ms). The job's window is that bound less 5 s for its line to reach the stick, and it covers the lease wait, the handshakes and the body. A body read to its end says whole bytes=<n> sha256=<hex> …. One the window closes on says cut bytes=<n> …, or cut before the first byte of the body. Every one of these ends 0. The job holds no pin and asserts nothing about the body: an I/O or TLS error panics, and that is all.
  • The row judges the transport (internet_download, tests/toyos.rs). The job ended 0 and some of the body came. A whole body must equal the pin, 170439044 bytes with SHA-256 1a9ee8caaa18a3e433fef93cea8a55dc1ebd478ed761b2fef69d4565f9d00e7f, the hash the project publishes beside the file (<url>.sha256), and a full download through slirp at this head hashed to it. The T14's MPERF must have been read. A cut is a reading and is green: TLS's AEAD has already authenticated every record of a cut prefix. The rate is printed as the [download] line and never judged. It is kept out of metaltimings, where every number is a ceiling.
  • The round trip, measured in ToyOS. netstack exposes no connection's SRTT. Its inspect snapshot counts sockets and nothing of any one. So before the transfer the job times five TCP handshakes to the file's host's first address, from connect called to returned, as rtt_ms=[…]. Each is one round trip plus netstack's own time for a connect, so each is an upper bound on the path's round trip. netstack is unchanged apart from the lease line below.
  • The rate is the receive window's. The T14 at 83ef5a9ae read 35.3 Mb/s with rtt_ms=[16.8 15.7 15.0 16.0 16.5] at 1.6 % busy. One window of 65,535 bytes per round trip is 524.3 / rtt_ms Mb/s, 31.2 to 35.0 across those handshakes: netstack's per-connection receive buffer (TCP_BUFFER) with a window shift of 0. toyos-net-tcp does negotiate RFC 7323 window scaling, but it takes the smallest shift that fits the buffer in 16 bits, which is 0 for this buffer. Filed as issues/netstacks-receive-buffer-caps-every-connection-at-one-64-kib-window-per-round-trip.md and owned by the network track; another branch (wt/toyos-wscale) is fixing it. Its exit is both a toyos-net-tcp host test that a stream's SYN carries a window shift above 0 and its empty-buffer window exceeds 65,535, and a T14 internet_download reading recorded after the fix, with no rate threshold. The owner, asked the line's speed, answered "No bar but its a gigabit connection and i would like close to that": the issue records that the T14 sits on a gigabit connection wired to its router, by his statement, and that the goal is close to it. The line's own rate is not measured, and neither the row, the commits nor this body calls the rate the line's or the path's.
  • netstack's lease line is declared once. toyos_tco::LEASE_SAID and NO_LEASE_SAID sit beside LEASE_BOUND_MS. netstack says them, and both boot_netcase and the job read them.
  • tests/downloadcase is its own boot, so the transfer has the machine alone. It runs on every --metal run: the tree has no nightly tier. Its netstack claims only the I219 (8086:15fc).
  • The https_download guest test is cut, along with its MACHINE_TESTS row, its arm, the job's argv mode and the config's virtio NIC. A cheaper or existing tier already holds what it held. The TLS 1.3 GET with the project's User-Agent against the harness's server is https_fetch's, and that client is now the shared module https_fetch runs through https_get. The lease wait cannot be reached in QEMU. The counters read unread there. The pin now lives in the host judge, and the cases below exercise that judge.
  • Records. The network track, the Intel-NIC, LAN and host-reach issues said that no T14 row reads the wired card and that the mDNS claim on it was unread. They now record what internet_download read at 83ef5a9ae: the lease line, then netstack: mDNS: no host answered for toyos-t14.local; this machine answers as it, and no loss line. The acpi_hold issue's exit names the bound its runner now hands each list job.

Net lines against 9b16d2938: +403 / −39. Production: +23 / −8 (test-runner 8/4, netstack 4/4, toyos-tco 11/0). Tests and config: +314 / −20. Issues: +66 / −11, of which the new issue is 51.

Gates

command exit
cargo run -- --ci host, at 3b196d075 0 (Host: 78 step(s), all green)
cargo run -- --ci host, at 089c9b713 0 (Host: 78 step(s), all green)
cargo run -- --ci host, at 83ef5a9ae 0 (Host: 78 step(s), all green)
cargo run -- --build-only, at 83ef5a9ae 0
cargo test, at 83ef5a9ae (the whole guest suite: the runner change reaches every boot, list-mode boots among them) 0 (44 passed, 44 total)
cargo test --test toyos-build -- --metal --metal-readback <scratch>/metal-r2/ internet_download, at 83ef5a9ae 2 (Staged: one image, download, list bound 60000 ms; nothing touched)
the same, judging the orchestrator's T14 boot of that image 0 (PASS internet_download)

089c9b713 and 3b196d075 change issue files and nothing else, so the build, guest and T14 gates at 83ef5a9ae stand for it.

Measured once and posted to this PR (#818 (comment)) with the patches. The cut path ran in QEMU against the live internet through slirp, under a temporary --bound-ms=12000 job list: cut bytes=9682897 secs=4.179 mbps=18.5 rtt_ms=[42.2 46.5 34.1 48.6 43.8] busy=unread, the job ending 0 and the list ending inside its bound. The whole path ran the same way at --bound-ms=150000: whole bytes=170439044 sha256=1a9ee8ca…d00e7f, the pin. The judge ran offline on an earlier T14 readback of this branch with the job's line rewritten for each case: whole 0, another hash 1, a byte short 1, cut 0, cut before the first byte 1, MPERF unread 1.

The T14 at 83ef5a9ae, run by the orchestrator (#818 (comment)): the download image, sha256 d003f3e3aeb57cff65bc7f0e1f9244fca2cffce1722a170d5357cda95fcbce02 as staged, toyos-metal --fat32-check exit 0, the judge exit 0 with PASS internet_download. The reading: [download] whole bytes=170439044 sha256=1a9ee8ca…f9d00e7f secs=38.657 mbps=35.3 rtt_ms=[16.8 15.7 15.0 16.0 16.5] busy=0.016. The window bound 524.3 / 15.0 is 34.95 Mb/s, and the rate sits at it with the CPUs 1.6 % busy. The boot's log shows the lease line, then the mDNS claim, and no loss line.

Unsure

  • rtt_ms is a handshake, not the transfer's SRTT. It includes netstack's connect path and the client's pipe setup, and it is taken idle, before the transfer. A queue that fills under load would make the loaded round trip longer than this. So a rate well under 524.3 / min(rtt_ms) does not by itself clear the window. Under slirp it is not the data path's round trip at all, because slirp answers the guest's segments itself.
  • The handshakes go to the first address the lookup returns. ureq resolves the host itself and may reach another edge.
  • The runner's bound reaches jobs through the environment. That is ambient, but argv cannot carry it: the runner's job words are binary names. The variable is set only in a list, and the job panics without it.

🤖 Generated with Claude Code

https://claude.ai/code/session_017cSFvbD35xJ2kGANVdm23C

Japabu and others added 30 commits October 9, 2026 13:09
… the requests, and smoltcp is gone

`userland/netstack` is now the card, the clock, the kernel's random source,
the kernel's pipes and the clients' connections around `toyos-net-node`:
every frame goes to the node as the card handed it over, a frame leaves only
into room the card said it has, and one request is one call of the node's.

- `main.rs` is the loop. `serve.rs` is the requests onto node calls, the id
  table and `inspect`. `pipes.rs` is the kernel's pipe ends as the node's
  `ToClient`, `FromClient` and `Wake`.
- `dhcp.rs`, `listen.rs`, `mdns.rs`, `resolve.rs` and the two smoltcp test
  harnesses are deleted; `smoltcp` and `managed` leave `Cargo.lock`.
- The node's places come from a memory figure in which a place costs what a
  listener can be made to hold.
- A listener's wake pipe and a datagram socket's receive pipe are watched for
  their owner's leaving; the 1 ms pass while a request was pending is gone.
- `netstack_socket_churn` reads the node's counts. `netstack_streams` and
  `netstack_lookup` are new, on virtio and on QEMU's e1000e.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RvnWQFcMuGqTHYhvSnTe8A
…he streams job reads its stream end

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RvnWQFcMuGqTHYhvSnTe8A
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RvnWQFcMuGqTHYhvSnTe8A
…d against the node, and the track says what stage 5 left

Closed, each by its own exit:
- a-handshake-nobody-finishes-holds-a-listeners-port-shut: the node's
  `a_handshake_nobody_finishes_leaves_the_port_open_and_is_given_up`.
- a-handshake-reset-before-it-ends-hands-its-option-to-the-next-connection:
  the one-socket listener left with smoltcp; the node's
  `a_handshake_reset_before_it_ends_leaves_the_next_connection_its_listeners_option`.
- netstack-passes-every-millisecond-while-a-request-is-pending: the loop's
  timeout is the node's next deadline and no 1 ms constant remains.
- netstack-keeps-the-datagram-socket-of-a-client-that-sent-no-close: the wake
  pipe of a listener and the receive pipe of a datagram socket are watched for
  their owner's leaving; `netstack_socket_churn` reads both counts back.
- netstack-removes-a-closed-stream-before-its-fin-leaves: a host peer of
  `netstack_streams` reads its stream's end after the guest's close.
- a-lease-kept-across-a-link-flap-is-not-verified-until-its-renewal:
  `toyos-dhcp` verifies a kept lease by INIT-REBOOT when the link returns, and
  netstack reports the change (`Node::link`).
- a-shutdown-of-the-sending-half-drops-what-the-send-pipe-still-holds: the
  node's `a_shutdown_sends_what_the_pipe_held_and_then_the_fin`, and
  `netstack_streams` shuts down at once and reads every byte back.
- netstack-cuts-a-departed-clients-unsent-tail-at-the-ceiling: the node's
  `a_departed_clients_tail_arrives_whole_while_its_peer_takes_it`.

netstack-datagram-sockets-and-listeners-have-no-bound is renamed to what is
still true of it: the places are one number for every client.

Filed: a DHCP message the client refuses is a log line each.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RvnWQFcMuGqTHYhvSnTe8A
QEMU's user network queues one connection on a forwarded port and resets a
dial that arrives while one is queued. Under load the harness's two dials,
back to back, met that: 3 of 8 runs of the whole suite red at a host load of
about 30, the second dial ending `Connection reset by peer (os error 54)` and
the frames recorded on the guest's card (`-object filter-dump`) holding one
SYN for the listener's port. The harness now reads QEMU's table of
connections after each dial and dials the next once it shows the last one
carried; 5 of 5 runs of the suite are green at the same load. A failed dial
is the test's first word, since it is why the job's wakes do not come.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RvnWQFcMuGqTHYhvSnTe8A
The shell that #793 edited is gone: its mdns.rs told the responder its link,
drew the delay of each probing and said what became of the name. On the node
the first two are `name`'s, and netstack hands `Node::answer_as` its draw and
writes the two lines for `Event::Name` as that file wrote them, which
`boot_netcase` now waits on.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RvnWQFcMuGqTHYhvSnTe8A
…dary (#796) and the NVMe install (#797), into the move

Conflicts, every hunk accounted for:
- Cargo.lock: netstack's dependencies take both sides, toyos-dhcp and the
  stack's crates from the move, toyos-device-memory and toyos-virtio from
  main; smoltcp stays gone.
- tests/common/qemu.rs: both new profiles kept, HeadlessE1000e beside
  HeadlessNoUsb, in the enum, the architecture match and the shape table.
- userland/netstack/src/virtio_net.rs: main's file, which moved the queue
  and its tests to toyos-virtio and deleted the test comment the move had
  reworded; the move's one remaining hunk, "smoltcp" to "the stack" in the
  transmit queue's comment, is applied again.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017cSFvbD35xJ2kGANVdm23C
…a rule in any 10 s, with a count of the rest

Any host on the link could send replies the client refuses, one a frame,
and each became a line of a log logkeeper keeps on the stick: the node
handed every refusal `toyos-dhcp` queued straight to netstack as
`Event::Dhcp`. The shard already bounds its crates' refusals with each
crate's `RefusalLog` (toyos-net-wire's `counters!`), and `toyos-dhcp`
declares its counters with the same macro, so it has one: the node now
holds it and admits each of the client's refusals through it where it
drains the stack's (`Node::log`), and `Event::Dhcp` carries the count of
the rule's refusals since its last line, which netstack writes as the
stack's lines are written.

`a_hundred_refused_replies_are_one_line_and_a_count` (node, lease) is the
issue's exit test: a hundred BOOTP replies give one line and a counter of
100, and one more after 10 s gives a line carrying 99.

Closes issues/a-dhcp-message-the-client-refuses-is-a-log-line-each.md.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017cSFvbD35xJ2kGANVdm23C
… is named and passed over, and a wake bridges the streams once

A client could end netstack with requests alone: every UdpRecvFrom on an
idle socket kept its connection's handle in `receiving`, which nothing
bounded, and once netstack's handle table was full the next
`acceptor.accept().expect(..)` panicked it, and every program lost the
network.

- `receiving` is a map from socket id to its one waiting receive. A
  second receive while the first waits is refused
  `ERR_RESOURCE_EXHAUSTED`; a waiter that hung up is replaced, so a client
  that left does not shut its socket's receives out. A client's requests
  now hold no more of netstack's handles than its sockets do.
- An accept the kernel refuses has already taken the connection off the
  port's queue and told its client (`sys_accept`), so netstack names the
  first refusal of a run, says how many followed when an accept succeeds
  again, and goes on.
- `netstack_socket_churn` asks a second receive on the socket whose first
  waits and reads `ResourceExhausted`.

Swept once more for anything a client or the wire reaches in `serve.rs`,
`pipes.rs`, `main.rs` and `client.rs`: every index is bounded by its
producer (`FrameRx`'s kept length, [udp]'s cut to the buffer), every cast
fits, and each `unreachable!` is the node's contract, not a client's
choice.

Two NOTEs of the review:
- A ready stream watch no longer calls `node.bridge`: it marks the wake,
  and `Sockets::bridge`, after the poller's answers, passes the streams
  once however many answers the wake carried.
- `shutdown(Read)` is answered from the id table, which already says the
  id names a stream; it no longer asks `node.nodelay` as an existence
  check.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017cSFvbD35xJ2kGANVdm23C
…eam line is a guest count, and the harness backs off between its QMP queries

- `issues/the-pipe-abi-has-no-word-for-an-unreachable-host-or-a-lookup-to-try-again.md`:
  an ICMP-ended connect, a lookup ending `Unreachable` and one ending
  `LeaseChanged`, each with the word owed, owner the pipe ABI, exit an ABI
  change after the move. `serve.rs` cites it where it answers them.
- The track's line on a pass over every stream exited on a T14
  measurement at 1,000 idle streams, which cannot exist: the places end at
  103 and the bench holds no streams. Its exit is now a guest count of
  netstack's pipe reads per frame at 1 and at 100 idle streams.
- `netstack_streams`'s dial asked QEMU's `info usernet` back to back
  until the forward carried its peer; it now waits 1 ms after each answer,
  doubling to 64 ms, under the same 30 s ceiling. QEMU raises no event for
  a carried connection.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017cSFvbD35xJ2kGANVdm23C
… move

The node now keeps a send pipe whose FIN is queued until its writer leaves and
lets a failed stream's send pipe go first, so std reads a peer's FIN after the
client's shutdown as the end. The code merges clean.

Issues: `a-shutdown-of-the-sending-half-drops-what-the-send-pipe-still-holds`
stays deleted, its exit met by `netstack_streams` (every byte of 4 MiB read
back after a shutdown at once); #803's hunk to it was its measured evidence on
smoltcp's shell, which leaves with the shell. `a-netstack-client-cannot-tell-
a-reset-from-the-peers-fin` takes #803's text; the track keeps the move's
idle-stream line and takes #803's pipe-order line.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017cSFvbD35xJ2kGANVdm23C
… IORT decode with the SMMUv3 and ITS encodings (#798) and the shipping members' rows (#799), into the move

No conflict; netstack draws from `toyos_abi::syscall::random`, whose source
#802 changes beneath the call and not the call.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017cSFvbD35xJ2kGANVdm23C
…n a guest

ring is ToyOSOrg/ring's toyos-0.17.14, pinned by the lock: the published
0.17.14 package imported byte for byte, a build script that tells a packaged
tree from a source tree by `pregenerated/` instead of `.git` (so as a git
dependency it uses the package's assembly, runs no perl, and leaves C
asserts and warnings-as-errors off, so nothing calls `__assert_fail`), and
`toyos` in its Linux-ABI and getrandom lists. The root workspace and the
guest test crate both patch it; the test crate also takes the getrandom 0.2
fork, which reaches SYS_RANDOM.

The build writes webpki-root-certs' Mozilla roots to every ROOT as
/system/etc/ssl/cert.pem (build::TRUST_ROOTS). A test image stages that file
whole, the build's roots with its harness's authority after them, and the
build refuses one that does not start with its own.

A test crate's C is compiled by the toolchain's clang against libc's
sysroot, as a program's is: TestBuild hands cargo the cc crate's variables.

https_fetch boots tests/netcase with three rustls servers on the host, each
under an authority made for the run: https_get, ureq 3 on rustls 0.23 with
the roots file and the project's User-Agent, fetches 384 KiB over TLS 1.3
and its ring SHA-256 matches the harness's sha2 one; it refuses a
certificate for another address and one from an authority the file does not
hold, by name. ring_kat runs on the shared boot: ring against RFC and NIST
known answers.

doom's build script downloads with ureq on ring and the project's
User-Agent; nothing names rustls-rustcrypto.

Filed: a refused connection's close that never reached the host's peer, and
the roots being data no licence gate reads.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017cSFvbD35xJ2kGANVdm23C
…s the pipe order

With #803's order merged, a client that shut its sending half down keeps the
send pipe's reader until it lets the pipe go, so the read after the bulk's
last byte meets the server's FIN as the end, which the job asserts.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017cSFvbD35xJ2kGANVdm23C
…reads every end in C and in std against a host peer

#803's libc half, as posted on that pull request (comment 6082081208), applied
unchanged: `recv`'s read of 0 asks the send pipe with a zero-byte write and
answers `ECONNRESET` where its reader is gone; `send` after `SHUT_WR` answers
`EPIPE` before reaching the pipe; `recv` after `SHUT_RD` answers 0; a refused
write is `ECONNRESET` or `EAGAIN`. Its rule is `streamend.rs`, host-tested by
`toyos-libc-copies` (48 tests).

`libc_sockets` gains a host peer whose first byte names how it ends a stream,
and two jobs on it: `tests/netcase/stream_ends.c` reads recv 0 at the peer's
FIN after SHUT_WR, EPIPE for a send after it, ECONNRESET on a reset
mid-stream and after SHUT_WR, and recv 0 after SHUT_RD; `stream_ends_std`
reports six ends in std, and the harness first runs the same source on its
host's TCP and requires that report. The rows are #803's measurement's, less
`half_close`, which `netstack_streams` holds on both cards. The C job closes no
socket: libc's close of one ends the program, already filed.

`a-netstack-client-cannot-tell-a-reset-from-the-peers-fin` is closed by its
exit: netstack runs on the node, the std job reads each end as the host does,
and the C case reads all five rows. Its two citing issues and the track's
line now point at the code.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017cSFvbD35xJ2kGANVdm23C
…ody reads

clippy denies the unread field.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017cSFvbD35xJ2kGANVdm23C
… stream-end order (#803), into the move

#803 is the branch merged earlier here, now on main; nothing of it conflicts.

#800 changed `userland/netstack/src/mdns.rs`, which the move deletes with the
shell on smoltcp. Its two hunks are carried where the move writes the name's
events, `userland/netstack/src/serve.rs`: the loss line now says the name is
asked for again every `toyos_mdns::RETRY_MS / 1000` s, byte for byte the text
#800 wrote. The track's mDNS line takes #800's record (the owner's ruling and
what was built) under the move's wording of where the responder runs and
where `HOSTNAME` lives.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017cSFvbD35xJ2kGANVdm23C
…etcase boot is filed

The handshake is rustls on ring at both ends, so it alone would pass a ring
wrong at both; ring's known answers are the oracle, and ring picks its code
by the CPU's features, so they run on the same guest CPU as the fetch.
ring_kat's shared run stays the T14's.

The whole suite went red once on netstack_socket_churn: the firmware cleared
the screen and said nothing more for 487 s under a load average near 90, and
the test was green alone. Filed with the load, as a red under load is.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017cSFvbD35xJ2kGANVdm23C
…y's collapsible_match asks

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017cSFvbD35xJ2kGANVdm23C
…nd's order (#803) and the .local name's probing (#800), into the HTTPS client

ring_kat's line in DRIVEN_AND_SHARED met random_draws' there; the merge keeps
main's, and the next commit decides ring_kat's place.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017cSFvbD35xJ2kGANVdm23C
… guests go

The move made the node shipped code, and three of its getters had no
caller but its own tests: `Node::nodelay` (its last production caller left
with serve.rs's `shutdown(Read)`), `Node::listener_nodelay` and
`Node::dhcp`. Each is deleted. The listener tests read the option from
the accept's answer (`Accepted::nodelay`) and the stream tests on the
wire, as `nodelay_reaches_the_stack` did already; the deadline test tells
the client's wait from the stack's by `Node::next_deadline` against
`Node::shard`'s, and the refusal test counts the client's refusals by the
`Event::Dhcp` lines the node drains, the second line's 99 suppressed.

`netstack_lookup` and `netstack_lookup_e1000e` are cut. The e1000e arm
reached nothing that `netstack_streams_e1000e` (the Intel driver in a
guest) and `netstack_lookup` did not. The virtio arm passed on any word a
server gave, so a T14 row asking the same `.invalid` name is as stable:
the outbound rows' `outbound_internet` reads `lookup=addresses` through
the same serve.rs lookup path on the I219, and the resolver's decisions
are the node's host tests'.

Issues: the pipe ABI's owed words are the network track's; the track's
linear-pass line carries `Node::pipe_gone`'s pass of its own; two false
sentences, the node's source unchanged by the move and no T14 lease on
`toyos-dhcp`, are corrected, the second with the four leases taken since.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017cSFvbD35xJ2kGANVdm23C
…s them, and ring_kat holds RSA, P-384 and SHA-384 to published answers

The owner allowed CDLA-Permissive-2.0 for the Mozilla roots. The licence gate
now judges them: by the licence of the crate the build copies them out of
(`build::TRUST_ROOTS_CRATE`), as data, the one place `licence::DATA_ONLY`
passes, and refused unless the text the image carries beside them,
/system/etc/ssl/CDLA-Permissive-2.0.txt, is that crate's own LICENSE byte for
byte. The licence asks for the text to travel with the data; it is committed
under licenses/ and NOTICE names it. The tooling issue that tracked the
gap is closed.

The `font: bool` the gate threaded through `refused`, `judge_licence` and
`Report::judge` becomes `Scope`, since a licence allowed for data alone is a
third case.

`https_fetch` stages the roots and its harness's authority under a name of its
own and passes that path, so `build_and_assemble` writes the roots
unconditionally and the test-only match and assert go.

The C environment is `GuestEnv`'s, applied by `cargo_build` to every guest
build, so `build_programs` and `TestBuild` no longer each derive it.

`trust_roots` writes PEM with `pem`, already in the lock through rcgen, and the
hand-written encoder, `base64` and the test of the encoder's round trip go.

`ring_kat` adds SHA-384 of "abc" (FIPS 180-2 D.1), ECDSA P-384 with SHA-384
(RFC 6979 A.2.6), and RSA PKCS#1 v1.5 and PSS with SHA-256 at 2048 bits (the
first passing `[mod = 2048]` SHA256 vector of NIST CAVP's FIPS 186-3
SigVer15 and SigVerPSS), each signature refused with a bit flipped. It runs in
`https_fetch` alone now: the shared boot ran it on the same QEMU CPU model as
the fetch's boot, so the second run bought nothing, and the fetch's run keeps
the oracle beside the handshake it vouches for.

The host-tools rows name the host `cc` compiling ring for doom's build script
and the toolchain's clang compiling a test crate's ring, and the lost-FIN
issue says slirp is not ruled out.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017cSFvbD35xJ2kGANVdm23C
The gate globs every section's path through git before it reads a section as
prose, and /system/etc/ssl/cert.pem is a path on ROOT, not in the tree: the
licence step of `cargo run -- --ci host` was red on it.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017cSFvbD35xJ2kGANVdm23C
…een clears

`https_fetch` alone at 216f33b, at load 89 to 99, timed out waiting for
===READY=== after 64 s with the same 58 bytes of firmware escapes on its
16550 and nothing after them.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017cSFvbD35xJ2kGANVdm23C
…ardware, and cites no deleted getter

The owner's ruling defers the T14 cable pull on the condition that
link-down and INIT-REBOOT are recorded as unread on hardware, with that
pull as the exit. Round 4's review found no such record: the deleted
late-lease issue was closed by host tests, the mDNS paragraph's attended
session names when and not what a log must show, and the Intel link
issue is about the driver's ring. The track now carries the line, with
the exit the review spelled out: one attended boot, cable pulled and
returned, whose log shows the link-down line, the held lease verified
or taken again with no no-address line, then the name's claim again.

The reset-stream line cited `Node::nodelay`, which round 3 deleted.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017cSFvbD35xJ2kGANVdm23C
… document it already holds

`judge_trust_roots_of` ran a fourth `cargo metadata --locked` over the
root workspace and built a `Graph` over it only to find one package by
name. `judge` already holds a document of that workspace: the one whose
`members` holds the root `Cargo.toml`. `webpki-root-certs` is a
non-optional dependency of the root package, so whichever feature set
that document was resolved with, it resolves the crate, and the gate
reads it from there. A shipped tree with no crate in the root workspace
is refused by name rather than guessed at.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017cSFvbD35xJ2kGANVdm23C
The conflict in tests/toyos.rs was two additions at the same sites, stream_ends_std and
netstack_streams from #801 and https_get, ring_kat and https_fetch from #810; both kept.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017cSFvbD35xJ2kGANVdm23C
@Japabu

Japabu commented Oct 9, 2026

Copy link
Copy Markdown
Collaborator Author

Mutation at b323e70ee: the job stops holding the hash. Applied with git apply, then cargo test --test toyos-build -- https_download, then git apply -R; the tree was clean after.

--- a/tests/toyos-rust-tests/src/bin/https_download.rs
+++ b/tests/toyos-rust-tests/src/bin/https_download.rs
@@ -142,7 +142,7 @@
         }
         let hex: String = digest.finish().as_ref().iter().map(|b| format!("{b:02x}")).collect();
         assert!(
-            bytes == fetch.bytes && hex == fetch.sha256,
+            bytes == fetch.bytes,
             "{} came as {bytes} bytes hashing {hex}, and is {} bytes hashing {}",
             fetch.url,
             fetch.bytes,

Run (exit 1, red as required):

19:27:01   BUILT x86_64 https_download of tests/toyos-rust-tests, for https_download  (2s)
19:27:09 FAIL https_download: held to 3b289d51f876d831646beff95e69f1f30b64afb1fde62ce2920eca295bf69ae1, the job ended Some(0) and was to end 101, saying "https_download: whole bytes=393216 secs="… only on 0:
19:27:09   FAIL  https_download  (5s)
19:27:09 test result: FAILED. 0 passed, 1 failed, 0 invalidated, 1 total (9.6s; workers: 4s building, 5s testing)
EXIT=1
RESTORED=0

@Japabu

Japabu commented Oct 9, 2026

Copy link
Copy Markdown
Collaborator Author

T14 at b323e70ee, run by the orchestrator: download boot, image sha256 5e1d59cf…fdaade5d checked against request.txt, toyos-metal --fat32-check exit 0. Judge cargo test --test toyos-build -- --metal --metal-readback <dir> internet_download: EXIT=0, PASS internet_download, [metal] 1 passed, 0 failed, 1 boot(s). The reading: [download] whole bytes=170439044 secs=38.826 mbps=35.1 busy=0.014 cpus=[0.006 0.002 0.039 0.002 0.002 0.002 0.056 0.002] (hash whole). Link I219: link up at 1000 Mb/s full duplex; lease 8259 ms after netstack came up. The job's process: cpu=1288ms, 90,484 syscalls (90,378 of number 1) over the transfer. One boot; the rate is the path's (the T14's internet line and the CDN), not a verdict on the stack.

@Japabu

Japabu commented Oct 9, 2026

Copy link
Copy Markdown
Collaborator Author

Review of #818 at b323e70ee (round 1). Own change git diff 9b16d2938 b323e70ee: 4 files, +358 / -0. Production 0. Tests 358: job 204, harness and row 107, config 46, config list 1. Against origin/main the branch carries #801 and #810: 85 files, +4263 / -4440.

BLOCKER

  • tests/toyos-rust-tests/src/bin/https_download.rs:107, tests/toyos.rs:334: the row turns red when the rate is low, which goes against the owner's ruling. A cut exits 3, and job_passed makes that red, so the row is a pass/fail on the rate with its threshold at the 60 s list. The T14 reading puts this boot at that threshold. The lease came 8.3 s after netstack started and the transfer took 38.8 s, so at least 47.1 s of the job's 55 s were used before counting boot-to-netstack and the handshake. That leaves less than 8 s of slack: a slightly slower night or a later lease (3-9 s per issues/most-t14-leases-land-one-dhcp-retry-late.md) turns the row red. Root CLAUDE.md deletes a flaky test, and this row is flaky by construction on every full --metal run, since no nightly tier exists to keep it apart. How the budget should work: bound the transfer by time, not by size. The arm passes the job its window as argv; the runner already takes --bound-ms and the harness already computes it per boot. The job reads until the body is whole or the window closes. A cut is the reading and is not red: it prints the same line and exits 0. The verdict is the transport: no I/O or TLS error, bytes > 0, and a whole body equal to the pin by length and hash. Each record of a cut prefix is already authenticated by TLS's AEAD. The cut path has never run. Once it is the common path, it must be measured once with a short window. Growing this boot's list bound instead still leaves a red at a lower rate, and costs every --metal run a longer boot.

  • tests/toyos-rust-tests/src/bin/https_download.rs:107-108: the job computes its cut as JOB_BOUND_MS - MARGIN_MS minus time since boot, not from the bound its runner was given. This repeats the defect the tree already records for acpi_hold (issues/acpi-hold-gives-up-at-a-time-counted-from-boot-whatever-its-runner-was-given.md). It holds only while this boot has no members and no earlier job. The window should come from the arm, as in the finding above.

  • tests/toyos.rs:311-316, tests/downloadcase/system.toml, the job's 4-argument mode (https_download.rs:84-91): the guest test's reason, a break "found a night later", is answered by a cheaper tier. The metal row reaches the job; it is the job's own row. Also, no nightly runs it: the row runs on every --metal run. Of what the guest test holds:

    • The TLS 1.3 GET with the project's User-Agent against the harness server is https_fetch's, which already exists.
    • The lease wait is admitted unreachable in QEMU.
    • The counters come back busy=unread and are not read.
    • What remains is the job's own assert! on the hash, which a reader sees. Moving the pin into the host judge would remove even that, as https_fetch already compares https_get's printed sha256=.

    Cut the guest test, its arm in run_machine_test, the MACHINE_TESTS row, the argv mode and the virtio NIC in the config: about 110 lines. Otherwise, name a behaviour only it reaches.

  • tests/toyos-rust-tests/src/bin/https_download.rs:106-174 against https_get.rs:15-30: the roots parse, TlsConfig, the User-Agent agent and the hashed read loop copy https_get in the same crate. The tree already has a sibling, so share it: one #[path] module the way served_log.rs is shared, or one job that prints https_get's bytes= and sha256= with the timing. The judge then holds the pin.

  • Evidence: the attribution of the rate is a guess where one cheap measurement would settle it. The commit, the row's comments and the T14 comment say the rate is "the path's (the T14's internet line and the CDN), not a verdict on the stack". netstack offers each connection a 65,535-byte receive buffer (TCP_BUFFER, userland/netstack/src/main.rs:86, which toyos-net-shard/tcp takes as the window). 35.1 Mb/s is exactly 65,535 B per 14.9 ms, a normal round trip to a CDN edge. Busy at 1.4% says the CPU is not what limits it. On this reading, the number the owner's gigabit question gets back is the stack's window ceiling, not the line. The file was also sized ("above about 35 Mb/s") on the line's speed, which nobody measured. Measure two things: the connection's round trip (netstack's SRTT, or a ping from the T14's other OS to the same host), and the same download under Ubuntu on the same machine and cable. That is the throughput oracle issues/the-lan-is-not-yet-production-grade.md stage 2 names. Then either withdraw the attribution, or file the 64 KiB window as the ceiling with the reading as evidence, owned by issues/toyos-has-its-own-network-stack.md or the LAN track.

NOTE

  • issues/the-intel-nics-room-and-wake-are-unread-on-hardware.md:13: "no image gives netstack pci:8086:15fc" is false once this lands, because tests/downloadcase/system.toml:21 gives it.
  • issues/toyos-has-its-own-network-stack.md:18, :41: these lines say no T14 row reads the wired card and no system.toml gives netstack the wired card. Both are false at this head. The T14 boot read the lease line, which :41's exit asks for, and the record does not say so.
  • tests/toyos-rust-tests/src/bin/https_download.rs:51-52 and tests/toyos.rs:3311: netstack's lease line is now spelled in a third place. No declaration is read by netstack and by both readers.
  • Prose: the commit title and the PR title say "a nightly row", and the MACHINE_TESTS reason says "the row is nightly". No nightly metal tier exists in the tree, and the row runs on every --metal.
  • Fine as built: the request carries the project's User-Agent and nothing identifying. The file is pinned by length and by the SHA-256 its publisher states, checked against an independent full download. Keeping the rate out of metaltimings is right: every number there is a ceiling at twice its record, so recording a rate there would judge it, inverted. A [download] line in the judge matches the tree's other readings ([latency], [counters]).

SEND BACK

…t's bound, and netstack's 64 KiB receive window is filed as the ceiling its rate sits on

The owner asked whether ToyOS reaches gigabit and ruled the measurement an
internet download. `https_download` fetches one public file with the client
`https_get` builds, now one module both read (`https_client.rs`): an
unchanged ureq on rustls on ring, the project's User-Agent and nothing else
identifying. The file is Rust 1.81.0's x86_64 Linux archive on
static.rust-lang.org, 170439044 bytes; the `internet_download` metal row
holds a whole body to that length and the SHA-256 the project publishes
beside it, so the job holds no pin and prints `sha256=` as `https_get` does.

The transfer is bounded by time, not by size. The runner hands each job of a
list the bound it gave the list (`toyos_tco::LIST_BOUND_ENV`), and the job's
window is that bound less 5 s for its line to reach the stick. A body read
to its end says `whole`; one the window closes on says `cut` with what came,
and both end 0. The row's verdict is the transport: the job ended 0, some of
the body came, a whole body equals the pin, and the T14's MPERF was read.
Its rate is printed and never judged.

Before the transfer the job times five TCP handshakes to the file's host,
`rtt_ms`: the round trip measured in ToyOS, since netstack exposes no
connection's SRTT. The first T14 boot read 35.1 Mb/s at 1.4 % busy, which
is 65,535 bytes every 14.9 ms: netstack's per-connection receive buffer
(`TCP_BUFFER`) with a window shift of 0, one window per round trip. That is
filed as the stack's ceiling under the network track, with an exit a T14
reading can fail. Until a boot reads `rtt_ms` beside the rate, the window is
the ceiling by arithmetic and not by measurement, and the rate is said to be
neither the line's nor the path's.

netstack's lease line is declared once in toyos-tco, which netstack says and
the harness and the job read.

The guest test of this job is cut: the HTTPS GET with the project's
User-Agent against the harness's server is `https_fetch`'s, its lease wait
cannot be reached in QEMU, and its counters read nothing there. The records
that said no T14 row reads the wired card, and the mDNS claim on it unread,
now say what the row read.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017cSFvbD35xJ2kGANVdm23C
@Japabu

Japabu commented Oct 9, 2026 •

Copy link
Copy Markdown
Collaborator Author

Round 2 evidence at 83ef5a9ae.

The cut path, measured once with a short window (QEMU, the live internet through slirp)

A temporary patch gives tests/downloadcase the virtio NIC and the runner a job list (--bound-ms=12000, so the window is 12 000 − 5 000 ms from boot less the time the job started), and adds a machine test that boots it and waits for the job's end. Applied with git apply, cargo test --test toyos-build -- https_download_measure, then git apply -R: RESTORED=0, tree clean. The test returns Err by construction so its console is printed; EXIT=1 is that, not the job.

diff --git a/tests/downloadcase/system.toml b/tests/downloadcase/system.toml
index ead213477..30443585a 100644
--- a/tests/downloadcase/system.toml
+++ b/tests/downloadcase/system.toml
@@ -15,14 +15,15 @@ serves = ["log"]
 [programs.netstack]
 service = true
 serves = ["netstack"]
-devices = ["pci:8086:15fc"]
+devices = ["pci:8086:15fc", "pci:1af4:1041"]
 
 # `netstack` for the job's lookup and connection, `log` for netstack's word on
 # its lease; `counters` and `trace` for every CPU's MPERF and stamp either
 # side of the transfer, MPERF being answered only beside `trace`; `dup`
 # because the runner hands the job a duplicate.
 [programs.test-runner]
-receives = ["netstack", "log"]
+receives = ["netstack", "log", "power"]
+args = ["--bound-ms=12000", "test_rs_https_download"]
 syscap = ["counters", "trace", "dup"]
 
 # The block service: the NVMe controller this machine's DATA is on, driven
diff --git a/tests/toyos.rs b/tests/toyos.rs
index 3d3be4d75..60dbd7e16 100644
--- a/tests/toyos.rs
+++ b/tests/toyos.rs
@@ -317,6 +317,7 @@ const MACHINE_TESTS: &[&str] = &[
     // certificate by and the sockets under it exist in a ToyOS guest alone,
     // and the T14's row is the next stage's, against a server on the bench.
     "https_fetch",
+    "https_download_measure",
     // The nested-NMI report is a raw write to the 16550, which the T14 does not
     // have.
     "nested_nmi_is_loud",
@@ -3529,6 +3530,15 @@ fn https_fetch() -> Result<(), String> {
     Ok(())
 }
 
+fn https_download_measure() -> Result<(), String> {
+    let crate_path = compile::repo_root().join("tests/toyos-rust-tests");
+    let bins = [("https_download".to_string(), qemu::build_toyos_bin(qemu::SUITE_ARCH, &crate_path, "https_download"))];
+    let mut qemu = QemuInstance::boot_with_options(&compile::repo_root().join("tests/downloadcase"), &[], &bins, BootOptions::default());
+    let mut console = qemu.boot_log().to_string();
+    let end = await_marker(&mut qemu, &mut console, "===TEST_END test_rs_https_download", "the job's end");
+    Err(format!("MEASURED {end:?}\n{console}"))
+}
+
 /// Run the machine-shape test, which owns its QEMU: the machine shape *is* the
 /// test.
 fn run_machine_test(name: &str, test_config: &Path) -> Result<(), String> {
@@ -3539,6 +3549,7 @@ fn run_machine_test(name: &str, test_config: &Path) -> Result<(), String> {
         "netstack_streams_e1000e" => netstack_streams(qemu::Profile::HeadlessE1000e),
         "libc_sockets" => libc_sockets(),
         "https_fetch" => https_fetch(),
+        "https_download_measure" => https_download_measure(),
         "nested_nmi_is_loud" => faults::nested_nmi_is_loud(test_config),
         "machine_shutdown" => power::machine_shutdown(test_config),
         "acpi_power_button" => power::acpi_power_button(test_config),

The job's lines (slirp's addresses elided):

[ 5.540 test-runner] ===TEST_START test_rs_https_download===
[10.568 test-runner tid=1 pid=9] https_download: cut bytes=9682897 secs=4.179 mbps=18.5 rtt_ms=[42.2 46.5 34.1 48.6 43.8] busy=unread
[10.572 test-runner] ===TEST_END test_rs_https_download exit=0===

The window closes 7 000 ms after the kernel's zero by construction, the zero the runner's bound counts from too (toyos_abi::clock::nanos_since_boot); a log line's time counts from the counter's own zero (stamp_ns), so the cut's line reads 10.568. The two zeros' distance was not measured apart from this. The job ended 0 and the list ended before its bound.

The same with --bound-ms=150000 and a wait that does not treat a silent transfer as a wedge (measure-whole.patch: the wait loop reads drain_serial for up to 400 s), so the whole body comes; the printed sha256 is the pin:

[24.314 test-runner pid=9] https_download: whole bytes=170439044 sha256=1a9ee8caaa18a3e433fef93cea8a55dc1ebd478ed761b2fef69d4565f9d00e7f secs=18.830 mbps=72.4 rtt_ms=[43.0 42.5 36.0 31.1 30.2] busy=unread

Under slirp the rates are not read: slirp answers the guest's segments itself, so its rtt_ms (the host's handshake with the CDN) is not the data path's round trip.

The judge, offline, on the T14's b323e70ee readback with the job's line rewritten

Each case copies that readback, replaces its one https_download: line, runs cargo test --test toyos-build -- --metal --metal-readback <case dir> internet_download (judging only: every boot has a readback), then restores tests/metal.

case the line exit verdict
whole whole bytes=170439044 sha256=<pin> secs=… rtt_ms=[…] busy=0.014 … 0 PASS
another hash whole bytes=170439044 sha256=000…0 … 1 https_download's body is not 170439044 bytes hashing 1a9e…
a byte short whole bytes=170439043 sha256=<pin> … 1 the same
cut cut bytes=9682897 secs=… busy=0.014 … 0 PASS
cut, nothing cut before the first byte of the body 1 https_download read none of the body
MPERF unread cut bytes=9682897 … busy=unread 1 https_download read no MPERF on the T14

@Japabu Japabu changed the title The T14's internet download over HTTPS through ToyOS's own stack: a nightly row reports Mb/s, judged only on whole bytes (carries #801 and #810) The T14 downloads over HTTPS through ToyOS's own stack inside its list's bound, and netstack's 64 KiB receive window is filed as the ceiling its rate sits on Oct 9, 2026
@Japabu

Japabu commented Oct 9, 2026

Copy link
Copy Markdown
Collaborator Author

T14 at 83ef5a9ae, run by the orchestrator: download boot, image sha256 d003f3e3…95fcbce02 checked against request.txt, toyos-metal --fat32-check exit 0. Judge cargo test --test toyos-build -- --metal --metal-readback <dir> internet_download: EXIT=0, PASS internet_download. The reading: [download] whole bytes=170439044 sha256=1a9ee8ca…f9d00e7f secs=38.657 mbps=35.3 rtt_ms=[16.8 15.7 15.0 16.0 16.5] busy=0.016. The window bound 524.3 / min(rtt_ms) = 524.3 / 15.0 = 34.95 Mb/s; the rate is at it (35.3, within the RTT's spread), with the CPU 1.6% busy: the 64 KiB receive window is the ceiling, as the new issue records.

@Japabu

Japabu commented Oct 9, 2026

Copy link
Copy Markdown
Collaborator Author

Review of #818 at 83ef5a9ae (round 2). Own change is git diff 9b16d2938 83ef5a9ae: 15 files, +391 / -39. Production is +23 / -8 (test-runner, netstack, toyos-tco); the rest is tests, config and issues. Against origin/main, carrying #801 and #810: 93 files, +4272 / -4455.

Round 1

  • Rate turned the row red: CLOSED. A cut now ends 0 and the judge holds the transport instead. Measured at this head (judge-all.log): whole 0, another hash 1, a byte short 1, cut 0, cut with no bytes 1, MPERF unread 1. The cut path ran once in QEMU (--bound-ms=12000, cut bytes=9682897 … exit=0).
  • Window counted from boot instead of the runner's bound: CLOSED. The runner hands its list bound to each job of a list. The job refuses by name to run without it.
  • Guest test answered by a cheaper tier: CLOSED. The MACHINE_TESTS row, its arm, the argv mode and the virtio NIC are gone. https_download is in RUST_SKIP, and the pin is in the host judge.
  • Duplicate HTTPS client: CLOSED. https_client.rs is one #[path] module, read by both jobs.
  • Rate attribution guessed: CLOSED as to the measurement. On the T14 at this head, rtt_ms=[16.8 15.7 15.0 16.0 16.5] and 35.3 Mb/s at 1.6 % busy. The claim about the line is withdrawn and the window is filed. The record that came out of it has an exit that does not work: see the BLOCKER below.

The design departure (environment variable instead of argv) is judged sound. The runner is the only holder of the bound, so it hands that value on and nothing restates it. Argv would have made src/metalimage.rs write the same number twice. The variable is set only on the list path. The job panics by name without it, so the stdin path cannot reach a silent default.

BLOCKER

  • issues/netstacks-receive-buffer-caps-every-connection-at-one-64-kib-window-per-round-trip.md:36-39: the exit is already met at this head, and the defect is unchanged. The exit asks for mbps > 524.3 / min(rtt_ms). At this head that bound is 524.3 / 15.0 = 34.95, and the T14 read 35.3. Meanwhile TCP_BUFFER is still 65,535 and the window shift is still 0.
    • Why it is met: each rtt_ms is a handshake, so it is an upper bound on the round trip (the PR body's own Unsure says so). That makes 524.3 / min(rtt_ms) a lower bound on the window's ceiling. A rate held at that ceiling will often clear it, as this reading does.
    • What it costs: the compromise is recorded with an exit its own evidence closes, which is the same as having no exit.
    • The fix: make the exit something only the fix can meet, and that a 64 KiB window cannot pass. Either a host test in toyos-net-tcp or toyos-net-shard: a stream's SYN carries a window shift above 0, and the window it advertises with an empty buffer exceeds 65,535. Or a T14 rate with a margin the RTT spread cannot cover, for example above twice 524.3 / min(rtt_ms).

NOTE

  • issues/netstacks-receive-buffer-caps-every-connection-at-one-64-kib-window-per-round-trip.md:25-31: the issue says the window is the ceiling "by arithmetic and not yet by measurement" and that rtt_ms comes "from the next boot on". That boot has run. The record should state its reading: rtt_ms 15.0 to 16.8, 35.3 Mb/s, busy 0.016, at 83ef5a9ae.
  • issues/toyos-has-its-own-network-stack.md:24,42 and the new issue, :24: they cite b323e70ee as the green internet_download. That commit is not in the branch's history; it was amended into 83ef5a9ae, and only the pull request's ref reaches it. It was also judged by the round-1 judge, which made the rate red. Cite the reading at this head.
  • Prose: the PR body's "The T14 reading is outstanding" is false. The orchestrator's comment holds the reading at this head (PASS internet_download, 35.3 Mb/s).

SEND BACK

… cite the T14 reading at 83ef5a9

The receive-window issue's exit asked for a T14 rate above 524.3 over the
smallest handshake time. Each handshake time bounds the round trip from above,
so that figure bounds the 64 KiB window's ceiling from below, and the reading at
83ef5a9 (35.3 Mb/s against 34.95) met it with the defect unchanged. The exit
now asks for both a toyos-net-tcp host test that a stream's SYN carries a window
shift above 0 and its empty-buffer window exceeds 65,535, and a T14 rate above
twice that figure, which a 64 KiB window reaches only if the fastest handshake
takes twice the round trip; the five read spread by 12 %.

The issue's Measured section records that boot: rtt_ms [16.8 15.7 15.0 16.0
16.5], 35.3 Mb/s, busy 0.016. The network track's citations of b323e70, a
commit amended into 83ef5a9 and reachable from no branch, cite that boot; its
log shows the lease line and the mDNS claim with no loss line.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017cSFvbD35xJ2kGANVdm23C
@Japabu

Japabu commented Oct 9, 2026

Copy link
Copy Markdown
Collaborator Author

Review of #818 at 089c9b713 (round 3). This round's change is git diff 83ef5a9ae 089c9b713: 2 issue files, +23 / -11, and no source, test or manifest. The branch's own change is git diff 9b16d2938 089c9b713: 15 files, +403 / -39. Production is unchanged since round 2 at +23 / -8. Against origin/main, carrying #801 and #810: 93 files, +4284 / -4455.

Round 2

  • BLOCKER, an exit the defect already met: CLOSED. The exit now needs both of two things. The first is a toyos-net-tcp host test of a shift above 0 and an empty-buffer window above 65,535; a 65,535-byte buffer fails both arms. The second is a T14 mbps above 2 x 524.3 / min(rtt_ms), which is 69.9 Mb/s at 15.0 ms. The reading at 83ef5a9ae was 35.3, so it fails that arm by about half. A 64 KiB window passes it only if the fastest handshake took twice the path's round trip, and the five handshakes spread by 12 % (16.8 / 15.0). The arithmetic checks: 65,535 x 8 / 15.0 ms = 34.95 Mb/s.
  • NOTE, the Measured section: CLOSED. It now states the reading at 83ef5a9ae with the rtt_ms, rate and busy figures, and it says the handshake bounds the round trip only from above.
  • NOTE, b323e70ee citations: CLOSED. git grep b323e70ee 089c9b713 exits 1. The track's two lines cite 83ef5a9ae, which is an ancestor of the head.
  • NOTE, the PR body's "outstanding" reading: CLOSED. The body states the T14 reading and links the orchestrator's comment.

The T14 reading stands for this head. 83ef5a9ae..089c9b713 touches only issues/, so the image built at 83ef5a9ae is this head's image. The orchestrator's comment 6088293739 holds that image's hash, the --fat32-check exit 0, the judge's EXIT=0 with PASS internet_download, and the [download] line the issue quotes.

BLOCKER

None.

NOTE

  • issues/netstacks-receive-buffer-caps-every-connection-at-one-64-kib-window-per-round-trip.md:50-54 — The T14 arm assumes the T14's uplink carries at least 70 Mb/s, and line 34 says "The line's own rate is not measured." — If the line is slower, the fix cannot meet this exit and the defect stays open after it is gone. A cheap reading on the network the T14 boots on would settle it before landing: any host fetching the same URL on the same uplink. Record that rate in Measured. If it is under 70 Mb/s, set the arm's factor below the line rate and keep it above the 12 % spread.

LAND AFTER NAMED CHANGES

…and its T14 exit is a reading after the fix with no rate bar

The review's note: the issue's T14 arm assumed a line rate nobody had
measured. The owner, asked the line's speed, answered "No bar but its a
gigabit connection and i would like close to that". Measured now records
that the T14 sits on a gigabit connection wired to its router, by the
owner's statement, and that the goal is close to it. The exit keeps the
toyos-net-tcp host-test arm; its T14 arm becomes a recorded
internet_download reading after the fix, with no rate threshold.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017cSFvbD35xJ2kGANVdm23C
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant