Skip to content

The self-hosting track carries what the owner decided and what is to be built; the internet clients' TLS stage targets ring, moves the tree off rustls-rustcrypto and owns the T14's HTTPS row - #679

Merged
Japabu merged 10 commits into
mainfrom
wt/toyos-selfhostplan
Oct 2, 2026

Conversation

@Japabu

@Japabu Japabu commented Oct 2, 2026 •

Copy link
Copy Markdown
Collaborator

The owner's self-hosting plan of 2026-10-01 lived only in the orchestrator's notes. issues/build/toyos-builds-itself.md now carries what was decided and what is to be built, and stage 3 of issues/design-debt/the-internet-clients-work-unchanged.md carries the TLS provider the owner chose on 2026-10-02 and owns the T14's HTTPS row. Issue files only: no code, prompt or CLAUDE.md. Net +123 −9 in five files (git diff --shortstat origin/main...16776357c).

What changed, per decision

  • A "Decided" block (owner, 2026-10-01): LLVM ships as a binary seed and C is accepted, in programs too; cargo's C dependencies are accepted; Perl and Python come to ToyOS; make it work, then optimise, then compare, with no performance study now.
  • A "To build" list, its order open: the libc crate's ToyOS module checked by ctest against our headers; select in libc; what cargo's libraries call in libc; cargo's eight C libraries cross-built for ToyOS; Perl, Python, brush, uutils, make, CMake and awk built for ToyOS; pkg past 256 MiB with links, and a loader that finds a package's libraries; the toolchain as pkg packages and an image without it.
  • Stage 3 of the internet-clients track targets ring, owns the T14's https_tls13 row, and moves the tree off rustls-rustcrypto. It named the graviola provider, which the tree does not install. The owner chose ring, graviola staying an option for later, and then chose that the HTTPS test The guest suite keeps the 21 tests only a booted machine answers; the rest are metal, host or tracked #660 cut comes back on ring and waits for it; both answers are under "The sources". The stage says ring as its target, says it owns the row and which provider its program and its judge's server come back on, and records as open and untried whether ring builds for the ToyOS target. Its exit was a handshake and two refusals "with a host-side server in the harness", which is the cut judge, filed by the guest-suite track as a metal row: one test under two tracks. The exit is now that row on the ring provider, and a tree in which no manifest names rustls-rustcrypto.
  • One line of the guest-suite track changes. Stage H's https_tls13 line had the row come back as every row there does, on what main had before the cut, which was rustls-rustcrypto. It keeps both names and the behaviour, and now says stage 3 owns the row and deletes the line. One track owns the test and the other points at it.
  • The exit's "no manifest names rustls-rustcrypto" is the tree's rule and not the owner's ruling where it reaches doom's build script: he ruled on ToyOS programs, that script runs on the host, and the clause reaches it because root CLAUDE.md takes only general and widely used crates and a second provider beside ring would be a sibling. What the script installs instead is open in the stage. ring has a build script that compiles C through cc, and rustls-rustcrypto's own manifest has none (measured below), so that is Arrivals' question for the pull request that changes it.
  • The line the cut left in tests/toyos-rust-tests is cited as main's issue. Stage 3 names issues/build/the-guest-test-crate-depends-on-three-crates-no-test-uses.md, the file main has for that manifest's dependencies no test uses.
  • One issue is filed for what The guest suite keeps the 21 tests only a booted machine answers; the rest are metal, host or tracked #660 left in three kernel issues, issues/kernel/kernel-issues-cite-the-cut-https-tests-as-cover-that-runs.md. They give https_tls13 or https_tls13_e1000e as a test that runs, and they are not this branch's files to edit. One citation is cover the cut lost and no track owes back: https_tls13_e1000e's judge asserted how many BARs the boot kept back and Refusal::BarReferenceEmpty's words, stage H's line names that test for its fetch alone, and stage 3 deletes that line.
  • The provider decision is written in stage 3 alone. The self-hosting track names the internet-clients track under "Blocked on other tracks" and does not repeat it.
  • The host's cargo and the host's OpenSSL build are not said here. The owner decided on 2026-10-02 that the development host builds cargo from the Rust fork and uses no other; issues/build/the-tooling-is-a-review-prompt-and-three-workflows.md says that on main. His answer about OpenSSL's build on the host describes a build no lockfile on main has (git grep -n '^name = "openssl' HEAD -- '*.lock', exit 1): it arrives with The toolchain is a content-addressed store built in one shared fork checkout; buildlock, keystore, worktree and identity go #629, whose rows in issues/build/the-build-runs-host-tools-outside-rust-and-qemu.md declare its host tools. The track keeps the question that is its own, how cargo's OpenSSL is built for ToyOS.
  • flock is not in the libc stage, though the notes' consequence names it: no library cargo builds for ToyOS calls it (measured below).
  • One sentence of the child-process track's stage 3 changes. It said "No select: a descriptor is a handle and passes FD_SETSIZE", which reads as libc having none. It now says the stage builds none and names this track as its owner.

Stages of this track, not files of their own

The notes' TODO was to file cargo's native libraries on ToyOS and the libc gaps. issues/README.md decides it:

  • A track "says what is to be built, what it is blocked on". Both are things to build, and both are parts of M4's cargo, which this track already stages. A second track for a stage of this one would be a sibling of it.
  • A defect is "real, reproducible", and main files the defects of its libc. The libc stage names those files instead of restating them or filing a second: issues/build/libc-refuses-what-toyos-cannot-yet-answer.md for realpath, a file mmap and record locks, issues/build/libc-stat-answers-one-serial-number-for-every-file.md for file identity, and issues/build/libc-close-of-a-socket-ends-the-process.md for socket descriptors. setvbuf, socketpair and select are in none of the three and libc defines none of them, so the stages say that themselves.
  • Every issue path the five changed files cite is a file at the head (679-r5/cited-paths.txt: 42 paths, none missing).

The sources

The orchestrator's notes of 2026-10-01, quoted:

OWNER DECISION (2026-10-01): accept C because we chose LLVM; accept cargo's C dependencies. Consequences: host keeps rustup's official cargo (#629 rework must keep it -> openssl-src/make/sh question MOOT); ToyOS programs keep rustls + ring (graviola revisit later); no cargo fork, no reqwest-upstream push needed; self-hosting (M3/M4) must cross-build cargo's 8 C libs for ToyOS + libc gains select/flock/realpath/real fcntl locks (SQLite); OpenSSL's Configure needs Perl on ToyOS (or curl's rustls backend) -> decide at M4.

OWNER: Perl comes to ToyOS; accept needed deps to self-host.

OWNER: Python AND Perl come to ToyOS (OpenSSL build + mature OS need them) -> no LLVM change to drop Python.

OWNER: NO performance study now. Order: make it work -> optimize -> compare (only after compilation succeeds). Self-hosting accepted with LLVM shipped as binary seed and C allowed for programs, even important ones.

WHEN TRACKS RESUME (self-hosting): agent writes the decided plan into issues/build/toyos-builds-itself.md stages: libc-crate ToyOS module (ctest-checked vs our headers); select in libc; libc gaps (realpath, file mmap, record locks + file identity via fsd, pollable non-blocking sockets, setvbuf/socketpair...); Perl + Python ports (spawn, no fork) + brush shell + uutils + make + CMake (libuv spawn) + awk; cargo's 8 C libs for ToyOS; pkg >256 MiB + links, loader finds package dylibs; toolchain as pkg packages, image toolchain-free; host keeps official cargo (#629 rework). Land #650 -> #659 -> #661 first.

Since those notes, on 2026-10-02 and relayed by the orchestrator, the owner:

  • overruled "host keeps rustup's official cargo" and "host keeps official cargo (The toolchain is a content-addressed store built in one shared fork checkout; buildlock, keystore, worktree and identity go #629 rework)": the host builds cargo from the Rust fork and uses no other;
  • answered the "openssl-src/make/sh question": OpenSSL's build on the host runs under the host's own make and shell, declared as dependencies; omake, brush and uutils are not used for it, and openssl-src is not forked;
  • chose the provider of stage 3, in two answers. The notes' "ToyOS programs keep rustls + ring" was never true of the tree.
    • He was first told that the tree installs neither ring nor graviola: its one provider is rustls-rustcrypto 0.0.2-alpha, in doom's build script on the host, declared and unused in tests/toyos-rust-tests, and no ToyOS program names rustls in source. Asked which provider the stage moves ToyOS programs to, ring, graviola, or rustls-rustcrypto for now, he chose ring, graviola staying an option for later.
    • That question left out four things. Until 2026-10-01 the tree had a ToyOS program using TLS, the HTTPS fetch test https_tls13, on rustls with rustls-rustcrypto. The guest suite keeps the 21 tests only a booted machine answers; the rest are metal, host or tracked #660 cut it. issues/build/the-guest-suite-runs-only-what-no-cheaper-tier-reaches.md owes it back as a T14 row. And ring has never been built for the ToyOS target.
    • He was then told those four and asked which provider that test comes back on: rustls-rustcrypto first, with ring at stage 3, or waiting for ring. He chose to wait for ring: rustls-rustcrypto does not come back into the tree, and the T14's HTTPS test stays out until ring builds for the ToyOS target. Whether ring builds for ToyOS is recorded as untried and open, with no estimate.

The notes' last sentence is a landing queue, and it is not in the issue: it turns false at a landing that need not touch the file.

The investigation those decisions rest on is posted whole as the first comment on this pull request. Its own probe logs were in a temporary directory and are gone; the rows below marked "not re-run" stand on the report.

Every number and fact, and where it comes from

Logs are under /Users/jan/.claude/jobs/2280e09e/tmp/scratchpad/orch/. One named by a bare file name is in 679-r4/; those of rounds 2, 3 and 5 are named with their directory, 679-r2/, 679-r3/ and 679-r5/. "At this head" is 16776357c, which has origin/main 7e62d3553 merged in at e7476a1c6, and every row that says it was re-run there, in 679-r5/at-head.txt unless the row names another log. Since round 4's head 03b1abe08 the tree differs in 48 paths, #664's 44 and this round's four under issues/. The root Cargo.lock and Cargo.toml and two new manifests are among them, and nothing under userland, tests, rust, kernel or src (git diff --stat 03b1abe08 HEAD -- userland tests rust kernel src prints nothing, exit 0).

in the issues origin
libc 0.2.189 has no ToyOS module and is empty for an unknown OS re-run in round 2: rg -l -i toyos over libc-0.2.189/src, exit 1; src/lib.rs:307
ToyOSOrg/libc does not exist re-run in round 2: gh api repos/ToyOSOrg/libc, HTTP 404
curl-sys, libssh2-sys, libgit2-sys import libc's C types unconditionally re-read in round 2: curl-sys-0.4.90 lib.rs:14-18, libssh2-sys-0.3.2 lib.rs:11-12, libgit2-sys-0.18.7 lib.rs:7
curl 8.21.0 #errors without select; select.c polls only under HAVE_POLL; curl-sys 0.4.90 does not define it re-read in round 2: curl/lib/curlx/wait.c:26-28; curl/lib/select.c:205,235; build.rs:393,400,435 defines HAVE_POLL_H, HAVE_SELECT and HAVE_POLL_FINE, and rg HAVE_POLL_FINE over curl's lib and include, exit 1
userland/libc at 15625e0cb is main's libc at this head: git merge-base --is-ancestor 15625e0cb HEAD, exit 0; git rev-parse of userland/libc at 15625e0cb, HEAD and origin/main answers tree 4f0065904 three times
libc defines no setvbuf, socketpair or select at this head: git grep -n -w -e flock -e realpath -e setvbuf -e socketpair -e select HEAD -- userland/libc/, exit 0, three lines: struct flock in include/fcntl.h:37, realpath's declaration in include/stdlib.h:55 and its refusal at src/refused.rs:142
the three issue files own what the stage names them for read in round 3, and none of the three differs since (git diff --stat 20df3005f HEAD over them prints nothing, at this head): libc-refuses-what-toyos-cannot-yet-answer.md lists realpath, mmap of a file, a record lock and F_SETFL; libc-stat-answers-one-serial-number-for-every-file.md is st_dev and st_ino; libc-close-of-a-socket-ends-the-process.md says a socket's descriptor is no handle, and poll hands every descriptor to the poller as one (userland/libc/src/posix_io.rs:606, at this head). Read, not run
no library cargo builds for ToyOS calls flock, so it is not in the stage run in round 2: rg -n '\bflock\s*\(' over the eight crates' sources, exit 0, 26 lines (679-r2/flock-callers.txt); outside comments and Ruby tests they are SQLite's robust_flock and mruby's file.c. SQLite's, sqlite3/sqlite3.c:42804,42808, is inside #if SQLITE_ENABLE_LOCKING_STYLE (:42796 to :42961), which :40253-40259 defines 1 only under __APPLE__ and libsqlite3-sys 0.38.1's build.rs never sets (rg LOCKING_STYLE build.rs, exit 1; 679-r2/sqlite-locking-style.txt); the crate's sqlcipher/sqlite3.c has the same call under the same guard (:41949 inside :41941 to :42106). mruby's, nghttp2/third-party/mruby/mrbgems/mruby-io/src/file.c:94,626, is in a directory libnghttp2-sys 0.1.13's build.rs does not name (rg 'mruby|third-party' build.rs, exit 1). cargo's own package-cache lock is std's File::lock, per the investigation
curl's TLS key log calls setvbuf run in round 2: rg -n '\bsetvbuf\s*\(' over curl's lib, libgit2's src, libssh2's src and sqlite3.c, exit 0, two lines, both curl/lib/vtls/keylog.c:46,48. 679-r2/setvbuf-callers.txt
what SQLite, libgit2, curl and libssh2 otherwise call the investigation, read from each library's source and not run; in round 2 only curl/lib/multi.c:315, Curl_wakeup_init, was re-read
nghttp2, zlib and blake3 build with nothing undefined; the other five do not the investigation: each library's sources compiled and linked with the toolchain's clang against the C sysroot 7cc52ed0ef46b1d5 of userland/libc at 15625e0cb. Not re-run
openssl-src 300.6.1 has no ToyOS target and refuses an unknown one re-read in round 2: rg -i toyos src/lib.rs, exit 1; src/lib.rs:426
openssl-sys is a cfg(unix) dependency of both; ToyOS is not unix re-read in round 2: curl-sys Cargo.toml:82, libssh2-sys Cargo.toml:59. At this head the rust gitlink is 3f6050fc8; run in round 4 against that commit, git -C rust grep -n -e families -e unix 3f6050fc8 -- compiler/rustc_target/src/spec/base/toyos.rs exits 1 on a file that exists (toyos-family.txt)
the ported C tools wait on stage 3 and on /dev/null the investigation, §2.7, "What every ported C tool waits on"; its tool table has CMake as C++ with a libuv spawn port, and brush and uutils as Rust, so the issue says it of the tools written in C or C++
a search of Perl 5.44.0 for posix_spawn matches nothing the investigation. Not re-run: the tarball is gone
MAX_INFLATED is 256 MiB, the whole archive is inflated in memory, links are refused re-read in round 2: userland/pkg/src/main.rs:25,68,111-122, archive.rs:10-12
librustc_driver 184.7 MB, clang 122.8 MB, lld 78.6 MB, x86_64-unknown-toyos libraries 181.1 MB the investigation: binaries of release toolchain-linux-x86_64-48dd24f826263d6c stripped with llvm-objcopy --strip-all, and file sizes. Not re-run; gh release view shows the release and its 768,410,436-byte asset. They are the Linux-host build's, a proxy, and the issue says so
rustc's launcher names librustc_driver as needed the investigation: llvm-readobj --needed-libs. Not re-run
the guest test https_tls13 ran the tree's one ToyOS program on rustls; the program and its judge's server installed rustls-rustcrypto; #660 cut both git grep -n rustls_rustcrypto 520c0d129^ -- '*.rs', exit 0, three lines: tests/toyos-rust-tests/src/bin/https_fetch.rs:156, tests/https-server-host/src/main.rs:272 and userland/doom/build.rs:165. git grep -n -e rustls -e ureq 520c0d129^ -- '*.toml', exit 0, 14 lines in four manifests: tests/toyos-rust-tests, the two host crates of that test, and doom's build-dependencies. git grep -n https_tls13 520c0d129^ -- tests/ src/ has both names registered at tests/toyos.rs:657,661. git show --stat 520c0d129 deletes https_fetch.rs, tests/common/https.rs, tests/https-server-host and tests/https-fetch-host; it is an ancestor of 06788146b, #660's merge of 2026-10-01 09:19 UTC. https-test-history.txt, cut-commit.txt
what that test held tests/common/https.rs at 520c0d129^, kept as cut-https-judge.rs: the fetched body's length and SHA-256 equal to the server's and to the same source built for the host, and six refusals, hostname-mismatch, certificate-expired, tls12-refused, downgrade-refused, plain-http and unknown-authority. Read, not run
the cut left a line naming rustls-rustcrypto in tests/toyos-rust-tests git diff 520c0d129^ 520c0d129 -- tests/toyos-rust-tests/Cargo.toml prints nothing, exit 0. git show --numstat 7c47e8930 -- tests/toyos-rust-tests/Cargo.toml: seven lines added and none removed, the dependencies ureq, rustls, rustls-rustcrypto, rustls-pki-types, webpki-roots and sha2, and a [patch.crates-io] line for the getrandom fork (679-r5/7c47e8930-manifest.txt). At this head git grep -n -e ureq -e rustls -e webpki -e sha2 -e pki_types HEAD -- tests/toyos-rust-tests ':!tests/toyos-rust-tests/Cargo.lock', exit 0, six lines, all Cargo.toml:26-31
520c0d129 deleted https_tls13 and https_tls13_e1000e, and three kernel issues give one or both as a test that runs git grep -n -w -e https_tls13 -e https_tls13_e1000e over tests/toyos.rs: eight lines at 520c0d129^, exit 1 at 520c0d129. At this head: outside issues/, exit 1; under issues/, exit 0, ten lines, in the two tracks, the new file, a-claims-own-refusals-are-read-by-nothing.md:27-28, no-boot-reaches-the-refusal-that-keeps-a-bar-read-inside-a-declared-window.md:25 and no-boot-reaches-the-retry-that-undoes-a-placement-nothing-answered.md:14,30. 679-r5/round5-facts.txt
https_tls13_e1000e's judge read the kept-BAR record and BarReferenceEmpty's words, and nothing outside the kernel names them now tests/common/https.rs:68,86,168-174 at 520c0d129^ (cut-https-judge.rs): one keeps BAR line on the e1000e bench and none on the virtio one, and the words answers all-zeroes or all-ones where firmware put it. At this head git grep -n -e BarReferenceEmpty -e 'keeps BAR' -e 'all-zeroes or all-ones' HEAD -- ':!kernel/' ':!issues/', exit 1; under kernel/, exit 0, six lines of kernel/src/pcidev/mod.rs (679-r5/round5-facts.txt). Stage H's line has https_tls13_e1000e as "the same fetch on the 82574". The judge read, not run
doom's build script installs rustls-rustcrypto, on the host at this head: git grep -n -e rustls -e ureq HEAD -- '*.rs' '*.toml', exit 0, 12 lines. The only .rs lines are userland/doom/build.rs:161-167, and :165 is rustls_rustcrypto::provider(); userland/doom/Cargo.toml:20-21 are under [build-dependencies]. cargo tree --locked --offline --target all -i rustls-rustcrypto, run in round 4 off lockfiles and manifests that have not changed since, exit 0 in both workspaces: a build-dependency of doom in userland, a dependency of toyos-rust-tests in the other (provider-trees.txt)
no build compiles ring at this head: git grep for the package names ring, rustls-rustcrypto, graviola, aws-lc-rs and openssl* over every *.lock, the root one #664 changed among them, exit 0, finds ring and rustls-rustcrypto in userland/Cargo.lock and tests/toyos-rust-tests/Cargo.lock and none of the others. cargo tree --locked --offline -e features --target all -i ring, with and without --all-features, in both workspaces, run in round 4 off those two lockfiles: exit 0 and nothing to print (provider-trees.txt). In both lockfiles ring is 0.17.14 and the only packages that list it are the two rustls-webpki versions, and rustls does not: read in round 3 (679-r3/ring-dependents.txt, 679-r3/tls-locks.txt) off lockfiles that have not changed. So ring is locked as an optional dependency of rustls-webpki that no feature turns on, and nothing compiles it for the host or for ToyOS
whether ring builds for the ToyOS target is untried not measured, and the stage records it as open. "Never built" is what the owner was told. What was run: git log -G'("ring"|^ring |aws-lc|graviola)' HEAD -- '*.toml', exit 0, four commits, whose matching lines are a comment in tests/ssh-client-host/Cargo.toml and a note in forks.toml, never a dependency or a feature (ring-in-manifest-history.txt); at this head the same four commits, and the same pattern over every manifest exits 1. A default feature of some dependency would not show in that search
ring compiles C on the host, and rustls-rustcrypto's own manifest has no build script ring-0.17.14/Cargo.toml:17 is build = "build.rs" and :252 is [build-dependencies.cc]; build.rs:507-508 is cc::Build::new(). rustls-rustcrypto-0.0.2-alpha has no build.rs, and grep -e '^build' -e cc -e ring over its Cargo.toml exits 1. leftovers-and-ring.txt. Its dependencies' build scripts were not read. This is in the body and the commit message, not in the issue
eight libraries; 256 MiB the decisions quoted above

Left out because the investigation only estimated them: the seed's total, the package sizes, the image with a toolchain in ROOT, the port sizes and durations, the DATA disk a self-build needs.

Unsure of

  • The stage's exit names the fetch and two refusals, a wrong name and an untrusted root, as main's stage 3 did, and the guest-suite line names the fetch. The cut judge held four refusals more: an expired certificate, a TLS 1.2 peer, a downgrade and a redirect to cleartext. Neither track's text says whether the row brings those back, and this round did not decide it.
  • The server the row fetches from is "a server the harness runs", the words stage 5 uses. Where it runs for a T14 row is not designed here.
  • "Owner: the orchestrator" in the new issue follows main's blockd_io file; nobody was asked.

Gates

At 16776357c, with origin/main 7e62d3553 merged in:

Not recorded here

  • The host's make, shell and Perl as rows of the host-tool table: The toolchain is a content-addressed store built in one shared fork checkout; buildlock, keystore, worktree and identity go #629's change.
  • The investigation's own recommendations: the rust and llvm package split, the self-host DATA disk, rustup later as a front end, Python out of LLVM's build (the owner decided against).
  • Its seven untracked findings: std's no-op File::lock, no #! launch, n2 without a ToyOS arm, the M2 LLVM's host triple, collect_hosted_rustc's bulk, pkg without a test, and the missing libc module, which is now a stage.
  • main's issues/build/the-guest-test-crate-depends-on-three-crates-no-test-uses.md undercounts and is not corrected here: git grep -c -w <crate> HEAD -- tests/toyos-rust-tests/src exits 1 for sixteen of the manifest's twenty-two dependencies where the file names three, the six 7c47e8930 added among the sixteen, and the file names no [patch.crates-io] line, of which getrandom's has rand_core and ring as its only locked dependents (the review's measurement, re-run at this head in 679-r5/manifest-unused.txt); the pull request that deletes those lines from the manifest corrects it.

🤖 Generated with Claude Code

https://claude.ai/code/session_013UDZQ6fSKw14e4w2TKTRfm

…stages

The plan lived only in the orchestrator's notes. The track gains what the
owner decided that day and the stages the plan lists, behind #650, #659 and
#661, which are open and land first in that order:

- Decided: LLVM ships as a binary seed and C is accepted, in programs too;
  cargo keeps its eight C libraries; Perl and Python come to ToyOS; the host
  keeps rustup's cargo, which #629's rework must keep; make it work, then
  optimise, then compare, with no performance study now.
- Stages: the libc crate's ToyOS module, checked by ctest against our headers;
  select in libc; what cargo's libraries call in libc; cargo's eight C
  libraries cross-built for ToyOS; Perl, Python, brush, uutils, make, CMake and
  awk built for ToyOS; pkg past 256 MiB with links and a loader that finds a
  package's libraries; the toolchain as pkg packages and an image without it.

What the notes leave open is written as open: whether cargo's OpenSSL goes
through its Perl Configure or cargo takes curl's rustls backend, which the
owner decides at M4; what select answers for a descriptor past FD_SETSIZE;
which Python, make and awk; how the toolchain splits into packages and how a
self-host test's guest reaches them; and any order among the stages.

cargo's native libraries and the libc gaps are stages of this track and no
files of their own. issues/README.md makes a track the place that says what
is to be built and what it is blocked on, and each is a part of M4's cargo.
Its defect is real and reproducible: the gaps were measured against #650's
libc, which main does not have, and #650 files the defects of its own libc
(realpath, a file mmap, a record lock, socket descriptors, file identity), so
a file here would be a second one for each.

Numbers are the investigation's of 2026-10-01, each with its method: the
release's stripped binaries (llvm-objcopy --strip-all), the libraries compiled
and linked with the toolchain's clang against #650's C sysroot, the search of
Perl 5.44.0 for posix_spawn, llvm-readobj --needed-libs. Re-read on this
branch: libc 0.2.189 has no ToyOS module and ToyOSOrg/libc answers 404; curl
8.21.0's wait.c and select.c and curl-sys 0.4.90's build.rs; openssl-src
300.6.1's target table; main's libc, which names none of flock, realpath,
setvbuf, socketpair or select; pkg's MAX_INFLATED and its refused links.
Estimates are left out.

Stage 3 of the child-process track said "No select"; it now says the stage
builds none and names this track as its owner, so the two do not contradict.

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

Japabu commented Oct 2, 2026

Copy link
Copy Markdown
Collaborator Author

The investigation the track's numbers come from, as its author wrote it on 2026-10-01, with two local paths shortened to <primary> and <scratch>. It is a read-only report against main at 0edf266ab, #650 at 15625e0cb and #661 at 03cb0453b; its probe logs stayed in a temporary directory and are not preserved here.

What ToyOS needs to self-host: cargo's C, Perl, the build chain, the seed, and delivery

This is a read-only investigation, done on 2026-10-01 under the owner's binding decisions of the same day: C and C++ are accepted, cargo's eight C libraries are accepted, and Perl comes to ToyOS.

  • No repository or worktree changed, no QEMU ran, and no LLVM or Rust build started.
  • Probes that did run:
    • C library compiles and links. The library sources were compiled and linked with the clang that already exists, against the C sysroots that already exist.
    • OpenSSL. Its Configure and make build_libs ran in a scratch copy, under the host's Perl.
    • Perl. Its Configure ran under the host's shells: /bin/sh and brush, each with uutils on PATH.
    • CMake. It was cross-configured for ToyOS by the host's CMake, and its cmake target compiled against the sysroot.
  • Every HTTP request carried User-Agent: toyos-build (https://github.com/ToyOSOrg/ToyOS). GitHub was queried without authentication.

Marks. [m] is measured by a command run for this report. [e] is an estimate, and says from what. [r] is read from code, not run.

Evidence and its roots:

  • TOYOS/ is <primary> at main 0edf266ab.
  • #650/ is worktree toyos-libcllvm at 15625e0cb. Its libc is in sysroot 7cc52ed0ef46b1d5, whose 397 exported names match #650/userland/libc (diff -rq of the headers is clean) [m].
  • Main's libc is sysroot 3e643c551624ebc8. #661/ is worktree toyos-m2 at 03cb0453b.
  • REG/ is the cargo registry. RUST@aca5f527/ is the fork commit main pins. LLVM/ is TOYOS/rust/src/llvm-project, 22.1.8 at 52ed14fcd.
  • External tarballs: CMake 4.4.3, CPython 3.14.8, Perl 5.44.0, perl-cross 1.6.5, GNU make 4.4.1, rustup 1.29.1, and the nightly of 2026-09-25.
  • The release is ToyOS's own toolchain-linux-x86_64-48dd24f826263d6c, published 2026-10-01T12:44Z: the x86-64 ELF build of this fork.
  • The probe logs are under <scratch>/selfhost/. probe-a1 holds zlib, nghttp2, SQLite and blake3; probe-a2 OpenSSL, libssh2, libgit2 and curl; probe-a3 Perl, sh, make and coreutils; probe-a4 Python, CMake and n2; probe-a5 rustup and the dist sizes. The release listing is release-48dd24f826263d6c.list. The prior report is cargo-rust-only.md beside this file.

Bottom line

  1. Before any C compiles, the Rust side of cargo's native stack does not build for x86_64-unknown-toyos.
    • The libc crate has no ToyOS module, and for an unknown OS it is empty: "non-supported targets: empty..." (REG/libc-0.2.186/src/lib.rs:166; 0.2.189, the newest, has no toyos either [m]).
    • curl-sys, libssh2-sys and libgit2-sys import libc::c_int and the rest unconditionally (curl-sys lib.rs:14-18, libssh2-sys lib.rs:11-12, libgit2-sys lib.rs:7) [r]. openssl-sys uses it 20 times [m].
    • openssl-sys is a cfg(unix) dependency of curl-sys (Cargo.toml:82-84) and libssh2-sys (Cargo.toml:58-59) [r], so on ToyOS, which is not unix, those crates never get OpenSSL's headers.
    • No ToyOSOrg/libc fork exists (GitHub API 404 [m]), and no issue tracks one.
    • So the first prerequisite is a libc crate fork with a ToyOS module, followed by ToyOS arms in curl-sys/curl, libssh2-sys, libgit2-sys/git2 and openssl-sys.
  2. The C side, library by library (§1):
    • nghttp2, blake3 and zlib build now.
    • SQLite builds after 1 header and 1 function on libc: the POSIX surface LLVM compiles against, and the headers held to the definitions #650.
    • libssh2 builds after 1 header and 2 type groups.
    • OpenSSL builds after a ToyOS target row in openssl-src and 5 headers and 12 functions, or 2 functions with no-ui-console no-quic -DNO_SYSLOG.
    • libgit2 compiles after 3 headers, 2 macros and 4 functions, but is blocked at run time by realpath (ENOSYS) and by file mmap (refused).
    • curl is blocked by select: curl 8.21 #errors without it, and the child-process track rules it out.
    • Perl is blocked by process creation: its system, backticks and pipe opens are fork-only.
  3. Correctness.
    • SQLite's locking is refused on libc: the POSIX surface LLVM compiles against, and the headers held to the definitions #650 (SQLITE_IOERR_LOCK at the first lock) and silently absent on main, where a crash mid-transaction corrupts even a single-user database.
    • It is correct only once the kernel or file server has POSIX byte-range record locks and stat reports real file identities.
    • Separately, std's ToyOS File::lock family answers Ok(()) and locks nothing (RUST@aca5f527/library/std/src/sys/fs/toyos.rs:566-580 [r]). That is cargo's package-cache lock, and no issue tracks it.
  4. The chain (§2).
    • Rust tools: the rustc bootstrap binary (no Python needed), cargo, toyos-build, n2, brush and uutils. Each needs a ToyOS arm.
    • C and C++ tools to port: LLVM/clang/lld (already being done), CMake (C++, about 625k compiled lines, 62 missing libc symbols, a libuv spawn port, mandatory iconv), GNU make and Perl, plus cargo's eight libraries.
    • Python can leave LLVM's build entirely, through four upstream-shaped LLVM hunks plus one configuration line (estimate under 100 lines).
    • What every ported C tool waits on:
      • the child-process track's stage 3 (posix_spawn, waitpid, environ);
      • /dev/null;
      • a POSIX sh at a known path;
      • #!/ENOEXEC script launch;
      • the select question, since curl inside both cargo and CMake requires select.
  5. Sizes (§3).
    • The M4 seed is about 873.5 MB for an x86-64 image: rustc 184.7, clang 122.8, lld 78.6, cargo 36.0, LLVM tools 34.2, clang headers 14.8, and the three targets' libraries 402.4. These are measured proxies; the rustc figure carries an estimate of ±10%.
    • The ARM64 targets add 397.5 MB. M5's C tools add about 66 MB [e], or about 114 MB if CPython stays [e].
    • What ToyOS rebuilds from that seed: M4 produces 42.8 MB of binaries in a 366 MB image [m]. M5 rebuilds the about 0.87 GB toolchain itself, from 1.71 GB of sources [m].
  6. Recommendation (§4.6): a small default image, and the toolchain as content-addressed pkg packages on DATA, published beside the host toolchain release.
    • Self-host tests vary the DATA disk, not the image.
    • rustup comes later, as a ported front end that links the pkg-installed toolchain as toyos, the way ToyOS's host does today. There is no ToyOS rustup dist server.

1. The nine libraries

1.1 Verdicts

library how its crate builds it verdict gap under #650 (all [m]) main differs
nghttp2 (libnghttp2-sys 0.1.13) cc, 26 files, no target-family branch (build.rs:51-103) buildable now none: 26 of 26 TUs; the probe references 417 functions, 0 undefined no
blake3 (1.8.5) cc, x86-64 non-Windows takes the unix .S files: sse2, sse41, avx2, avx512 (build.rs:224-279) buildable now none: 4 of 4 assemble, 0 undefined, no libc no
zlib (libz-sys 1.1.29) cc; LIBZ_SYS_STATIC=1 goes straight to build_zlib (build.rs:82-84,107-138) C buildable now; Rust side blocked by the libc crate (z_off_t = libc::off_t, src/lib.rs:46-51) none: 15 of 15 TUs, 108 functions, 0 undefined no
SQLite (libsqlite3-sys 0.38.1, bundled 3.53.2) cc via build_bundled, with THREADSAFE=1 and HAVE_LOCALTIME_R, among others (build.rs:124-143,249-251) buildable after the gaps; locking incorrect until record locks (§1.3) <sys/ioctl.h> (included, unused) and utimes main also lacks 6 declarations, struct flock and the 5 F_* lock macros; at link, fchown, readlink and utimes
libssh2 (libssh2-sys 0.3.2) cc, 26 files, HAVE_POLL and HAVE_O_NONBLOCK (build.rs:66-143) buildable after the gaps; runs only once socket descriptors are pollable and non-blocking <sys/ioctl.h>, struct iovec (POSIX puts it in <sys/socket.h>), u_char/u_int; 0 functions main also lacks <sys/un.h>
OpenSSL (openssl-sys 0.9.117 vendored, openssl-src 300.6.1+3.6.3) perl ./Configure with no-shared no-module no-tests …, then make depend, make build_libs, make install_dev (openssl-src lib.rs:197-252,654-676) buildable after a ToyOS target row and the gaps; built on ToyOS, it needs Perl, make and sh <sys/param.h> alone fails 61 of 66 failing TUs; 5 headers, 12 functions; at link, setbuf and socketpair main fails 68 TUs: dirent.h, Dl_info
libgit2 (libgit2-sys 0.18.7, 1.9.6) cc, 205 TUs including src/util/unix; GIT_THREADS, GIT_IO_POLL, OpenSSL, libssh2, bundled PCRE2; no NO_MMAP (build.rs:113-306) blocked at run time by realpath and by file mmap 3 headers, _POSIX_THREADS, SSIZE_MAX, IPv6 types; at link, pread, pwrite, utimes, getpgid main misses 9 at link
curl (curl-sys 0.4.90, 8.21.0) cc, 135 TUs, threaded resolver, ENABLE_IPV6 (build.rs:121-436) blocked by select 0 of 135 compile; with stand-ins, 135; at link, select, setvbuf, socketpair; about 14 types and macros main also lacks sa_family_t, AF_UNIX, sys/un.h
Perl 5.44.0 Configure (26,275 lines of sh), or perl-cross on a build host; miniperl runs throughout the build blocked by stage 3 and the shared blockers (§2.7); then a port of about 1k lines at link, environ, setvbuf, freopen, sigismember, truncate, utime; the other 9 of 15 undefined names go by hints —

1.2 Library notes

zlib.

nghttp2. Pure computation: curl does its socket I/O through callbacks, and its only clock is time(NULL). It references 20 libc names, none of them a stub [m].

blake3.

  • Cargo enables it with default features and uses it only under -Zchecksum-freshness (cargo-src/src/compiler/mod.rs:816-818).
  • At run time cpufeatures requires OSXSAVE and XCR0 before it reports AVX. ToyOS never sets CR4.OSXSAVE (TOYOS/kernel/src/arch/x86_64/control_regs.rs:56-66), so the SSE4.1 assembly runs [r].

OpenSSL.

  • The target table has no ToyOS row. An unknown target gets Err("don't know how to configure OpenSSL for …") and exit(1) (openssl-src lib.rs:424-429,128-136) [r, verified].
  • The fix is a row such as "x86_64-unknown-toyos" => "toyos-x86_64", with a matching Configure target: BASE_unix, x86-64 ELF perlasm, pthreads, no afalgeng and no devcryptoeng.
  • Every stand-in pulls in a foreign engine. linux-x86_64 turns on afalgeng, which fails on linux/*.h; BSD-x86_64 turns on devcryptoeng [m].
  • Three options remove the termios, syslog and socketpair needs: no-ui-console no-quic -DNO_SYSLOG, as openssl-src's WASI branch passes them (lib.rs:591-629). This was checked against the source guards only.
  • Entropy comes from libc's getentropy, which answers at most 256 bytes.
  • Without _POSIX_VERSION, async falls back to null and secure memory is compiled out [r].
  • What its build needs:
    • Perl ≥ 5.10, loading 111 module files, 14 of them XS [m].
    • Process spawning: Configure pipes $cc -dM -E -x c /dev/null, and build_libs ran Perl 131 times over 58 scripts [m].
    • A POSIX make: the generated Makefile has 0 GNU-only constructs [m]. openssl-src runs plain make, and gmake only on BSD and Solaris hosts (lib.rs:63-77).
    • /bin/sh for the recipes.

libssh2.

  • It compiles with 0 undeclared functions and 0 missing libc names once the three type gaps are filled [m].
  • It cannot run, because ToyOS's socket descriptors are not kernel handles.
    • libc numbers a socket 1024 + index (#650/…/socket.rs:81-105).
    • close, poll, read and write pass that number to the kernel, which ends a process that names a handle it does not hold (exit 139) [r]. This is tracked as #650/issues/build/libc-close-of-a-socket-ends-the-process.md.
    • F_GETFL/F_SETFL answer ENOSYS (fdreq.rs:56), so libssh2 never sets O_NONBLOCK. Its first EAGAIN would poll the socket descriptor and end the process [r].
  • No PF_UNIX means no ssh-agent authentication.

libgit2.

  • Every repository open fails, because realpath is refused (#650/…/refused.rs:141-145) and repository.c resolves its path through it [r].
  • Packs and the index are unreadable, because a file mmap answers ENODEV (memreq.rs:39-41). The NO_MMAP fallback needs pread, and the ABI has no positional I/O [r].
  • Lock files are not exclusive, because O_EXCL is ignored.
  • Connects go to port 0, because getaddrinfo ignores the service.
  • Its process spawning (fork/execve, unix/process.c) is reached only by the GIT_SSH_EXEC transport, which is off [r].

curl.

  • select is mandatory. curlx/wait.c:26-28 #errors without HAVE_SELECT, and wait.c:83 sleeps with select(0,…) [r, verified].
  • curl-sys never enables poll. It defines HAVE_POLL_FINE (build.rs:435), which curl 8.21 no longer reads (0 hits [m]). So Curl_poll runs on select on every non-Windows target.
  • It also needs:
    • socketpair(AF_UNIX) for the multi handle's wakeup, or curl_multi_init fails;
    • non-blocking sockets: curlx_nonblock failing makes every socket open CURLE_UNSUPPORTED_PROTOCOL [r];
    • fd_set in its public multi.h.
  • Two ways out, neither yet proposed upstream:
    • a libc select that serves only nfds = 0 as a sleep, together with curl-sys defining HAVE_POLL;
    • or a curl change to wait.c.

1.3 SQLite: is its locking correct on ToyOS?

On #650: refused, loudly.

  • The default VFS is unix, which uses fcntl byte-range locks; nothing sets SQLITE_DEFAULT_UNIX_VFS (sqlite3.c:48688-48727) [r].
  • libc: the POSIX surface LLVM compiles against, and the headers held to the definitions #650's fcntl answers EINVAL to F_GETLK, F_SETLK and F_SETLKW (fdreq.rs:55). SQLite maps EINVAL to SQLITE_IOERR_LOCK, so the first shared lock fails and every access to every database errors (sqlite3.c:42162-42174, 41211-41231) [r].
  • Nothing is left inconsistent.
  • Cargo turns that error into one warning per process, "failed to save last-use data", and loses its cache tracking (global_cache_tracker.rs:1600-1626). cargo clean gc fails outright (clean.rs:207) [r].

On main: silently incorrect. It compiles only once the headers gain struct flock and the F_* macros. After that:

  • Every lock "succeeds", so two writers can both hold EXCLUSIVE.
  • F_GETLK leaves the lock type at write-lock, so unixCheckReservedLock always sees a holder and the hot-journal rollback never runs (sqlite3.c:41884-41894, 64768-64769) [r].
  • A crash or kill mid-transaction therefore leaves the half-written database in use, and the next writer overwrites the journal that could have repaired it. That is corruption with a single process.
  • WAL can never open.

Wrong under both libcs:

  • One file identity for every file. fstat reports st_dev = st_ino = 0, and SQLite keys its in-process lock table and descriptor reuse on that pair. This is latent for cargo, which opens one database. It is tracked as #650/issues/build/libc-stat-answers-one-serial-number-for-every-file.md.
  • Temporary files. SQLite unlinks a temporary file right after opening it, and ToyOS refuses I/O on an unlinked file (kernel/src/tmpfs.rs:21-35) [r]. So spills fail: a large statement journal, a sorter, VACUUM. Either -DSQLITE_UNLINK_AFTER_CLOSE or SQLITE_TEMP_STORE=3 avoids it.

What cargo relies on.

  • It runs in rollback-journal mode: it sets no journal mode, and its documentation rules out WAL (global_cache_tracker.rs:69-71).
  • It runs migrations under BEGIN EXCLUSIVE.
  • It counts on its package-cache lock to keep processes apart, and calls SQLite's own lock a fallback (util/sqlite.rs:84-87).
  • That package-cache lock is std's File::lock, a no-op on ToyOS (above). ToyOS's own build already runs two cargo processes at once (TOYOS/src/build.rs:1738-1748) [r].

The alternatives.

  • unix-none takes no locks. It is correct for cargo only once cargo's own lock is real, and it would strip locking from every SQLite user. That is a workaround, not a fix.
  • unix-dotfile locks by mkdir. libc drops the errno, so contention reads as I/O errors, and a crash leaves the lock directory behind.
  • SQLITE_ENABLE_LOCKING_STYLE=1 needs 3 more headers and hits 10 errors [m].

For the stock VFS to be correct, the kernel or file server must provide POSIX advisory record locks with these properties:

  • shared and exclusive locks on arbitrary 64-bit ranges;
  • a non-blocking set answering EAGAIN or EACCES;
  • an F_GETLK that reports another owner's lock;
  • sub-range unlocking and conversion;
  • ownership by the process, released at exit;
  • keying by a real st_dev/st_ino.

It also needs a durable directory entry (#650's open refuses directories, so SQLite skips the directory fsync) and unlink-while-open. Today the ABI has no lock call [r].

1.4 Perl

How to build it.

  • Configure is 26,275 lines of sh [m]: 450 here-docs, 441 backquotes, 1,015 evals, exec 4>&1 and traps.
  • A traced host run called 39 distinct external programs, 4,764 times in all [m]. The heaviest were rm, cc, grep, sed, cat, ls, tr, expr and uniq, and awk ran 32 times.
  • Under brush on the host it hung at "Extracting config.h" [m]. brush writes a here-doc into a pipe before any reader exists, and the 174,210-byte config_h.SH exceeds macOS's 65,536-byte pipe. ToyOS's pipes are 2 MiB (kernel/src/pipe.rs:102 [r]), so it would pass there, but the deadlock is latent.
  • brush also mis-escapes \$ inside backquotes: signal 29 came out as NUM29 [m].
  • Under /bin/sh with uutils sed, grep, rm, rmdir, mktemp and uname on PATH, Configure produced the same config.sh as with the host's tools [m].

Cross-building.

  • Configure -Dusecrosscompile needs the target reachable over ssh, or a hand-written config.sh.
  • perl-cross never runs target code. For --target=x86_64-unknown-toyos against libc: the POSIX surface LLVM compiles against, and the headers held to the definitions #650 it finished in 22.54 s with uutils sed and grep [m].
    • It needs GNU make and GNU sed on the build host.
    • It omits d_nanosleep for 5.44, which leaves an invalid config.h:3102.
    • It reports 13 functions as present that libc refuses with ENOSYS: fork, link, symlink, fchmod, fchown, statvfs, fstatvfs, gethostname, uname, realpath, msync, mprotect and setsid. A ToyOS hints file must undefine them.
  • miniperl runs throughout Perl's own build (configpm, mktables, make_ext.pl's system). A rebuild on ToyOS therefore needs Perl's process creation to work there.

At run time.

  • fork sits under pp_fork, system (pp_sys.c:4698), and my_popen/my_popen_list (util.c:2476, 2628), which back backticks and piped opens.
  • No posix_spawn path exists anywhere in Perl (0 matches [m]). The non-fork paths are Win32, VMS, OS/2, Cygwin and AmigaOS only.
  • ToyOS must carry a port, estimated at 600 to 1,200 lines of C. Precedents: cygwin.c is 551 lines; AmigaOS is 1,909 lines plus 31 sites. The port covers:
    • do_aspawn, do_spawn and my_popen over posix_spawn and pipes;
    • exec as spawn, wait and exit;
    • 4-argument select over ppoll;
    • a hints file.
  • 40 of 47 core .c files compile against libc: the POSIX surface LLVM compiles against, and the headers held to the definitions #650 [m].
  • What OpenSSL makes Perl do. Its Configure loads 99 modules, 12 of them XS, and runs system(perl configdata.pm) and a piped $cc [m]. Its 99 perlasm scripts each popen a second Perl unless built no-asm.
  • No Rust Perl runs OpenSSL's Configure. strykelang (4,434 downloads) is "not a full perl replacement" and itself forks.

1.5 The libc gaps, collected (under #650)

missing needed by
select (ruled out by stage 3) curl (hard #error), CMake (curl and kwsys), Perl's 4-argument select
socketpair curl (multi wakeup), OpenSSL (QUIC), CMake
setvbuf / setbuf curl, OpenSSL, Perl, CPython, libc++'s fstream (for CMake)
utimes / utime SQLite, libgit2, Perl, CPython, CMake
pread / pwrite (deleted by #650 because no syscall reads at an offset) libgit2, CMake
environ Perl, GNU make, CPython, CMake
headers sys/param.h, sys/ioctl.h, netinet/tcp.h, sys/select.h OpenSSL, libssh2, libgit2, curl, CMake
IPv6 types (in6_addr, sockaddr_in6, AF_INET6), hostent curl, libgit2, CMake
non-blocking sockets (F_SETFL O_NONBLOCK) and socket descriptors that are kernel handles curl, libssh2, libgit2
a working realpath, file mmap, record locks, positional I/O, real st_ino, O_EXCL libgit2, SQLite, CMake/kwsys
termios, syslog OpenSSL (avoidable by configuration), CMake (ccmake, off)

2. The bootstrap chain

2.1 Milestone by milestone

M4: the guest builds ToyOS. It needs, in the guest:

  • rustc (M3), cargo, clang and lld (M2), llvm-ar;
  • the target libraries for x86_64-unknown-toyos, x86_64-unknown-none and x86_64-unknown-uefi;
  • toyos-build and n2, built by cargo in the guest;
  • the vendored crates.

ToyOS's stores are keyed by host:

  • The LLVM key hashes the host triple and the host tools' identities: cc/c++ --version, and on macOS xcrun (TOYOS/src/llvm.rs:126-128,153-173) [r]. The compiler key and the sysroot key build on it (src/compiler.rs:1-16).
  • So a guest computes keys different from the host's. It should consume the seed the way a CI runner consumes the toolchain release, as an installed toolchain (src/release.rs:1-12), and not try to find it in a store.
  • If the guest must rebuild the sysroot, libc++ comes back, and with it CMake (and Python, unless removed) already at M4.

M5: the fixed point. It adds:

  • LLVM with clang and lld: CMake, n2, a POSIX sh and coreutils, and Python unless removed;
  • libc++, libc++abi and libunwind: CMake;
  • rustc through bootstrap: cargo, the seeded rustc as stage0, CMake and n2 for LLVM, clang;
  • cargo: the eight C libraries through cc, and OpenSSL through Perl, make and sh.

2.2 LLVM, clang and lld: CMake, n2, Python

Does LLVM strictly need Python with tests off? Yes, as it stands [r, verified]:

  • find_package(Python3 … REQUIRED) runs unconditionally at LLVM/llvm/CMakeLists.txt:1016 and LLVM/runtimes/CMakeLists.txt:204-205. clang/CMakeLists.txt:104 applies only to standalone builds.
  • bundle_resources.py generates HTMLLogger.inc for clangAnalysisFlowSensitive, which the default install builds (clang/lib/Analysis/FlowSensitive/CMakeLists.txt:33-40). In M2's ToyOS build it ran as step 3371 of 4330 (m2-stubs.log:3597) [m].
  • generate_iwyu_mapping.py generates libcxx.imp under generate-cxx-headers ALL (libcxx/include/CMakeLists.txt:1703-1711). It is an include-what-you-use map that nothing in ToyOS reads.
  • llvm-lit's make_paths_relative runs at configure (AddLLVM.cmake:1857-1882), and its failure is a FATAL_ERROR. It runs because LLVM_INCLUDE_UTILS defaults ON.
  • lld runs no Python with tests off.

Every script needs only CPython's built-in core. libcxx.imp stayed byte-identical (81,212 B) with every optional C module blocked [m]. CMake's FindPython3 requires only the version probe to succeed: a stub that answered only that was "Found" [m].

Python can go entirely, by configuration plus fork hunks, each upstream-shaped, under about 100 lines in all [e]:

  • Configuration: LLVM_INCLUDE_UTILS=OFF, through [llvm] build-config.
  • Fork: the two REQUIRED finds only when tests or a Python feature are on.
  • Fork: bundle_resources.py as a cmake -P script or C23 #embed.
  • Fork: libcxx.imp only when Python exists.

If Python stays, the Arrivals rule refuses CPython while a Rust tool does the job.

  • RustPython 0.5.0 (41,266 downloads [m]) reports 3.14.0, ships every module the scripts import, and needs the libc crate fork. It is the first candidate, judged by byte-comparing libcxx.imp and HTMLLogger.inc (23,232 B) against CPython's output.
  • CPython 3.14.8 is the fallback.
    • config.sub and configure.ac refuse the ToyOS host, so they need patches and an autoconf run.
    • With a 30-line stand-in, 190 objects (361,021 lines) compiled. The link lacked 10 symbols: clock_getres daylight environ pause setbuf times timezone tzname tzset utime [m].
    • The port is 30 to 60 lines of CPython plus about 26 libc items [e]. WASI shows a fork-less CPython is supported upstream (configure.ac:1232, tier 2).

config.guess blocks LLVM on ToyOS. get_host_triple runs sh config.guess unconditionally (GetHostTriple.cmake:44-57, config-ix.cmake:527-528). config.guess has no ToyOS case and exits 1, so configure stops; passing -DLLVM_HOST_TRIPLE does not skip the call.

CMake 4.4.3 is C++. No Rust tool configures LLVM: the ledger says so, and the crate called cmake only runs the binary.

  • Size: the cmake target is 918 files, 624,844 lines and 934 ninja steps [m].
  • Mandatory vendored libraries: curl, nghttp2, libarchive with bzip2, zstd, liblzma and zlib, libuv, expat, jsoncpp and librhash. iconv is mandatory off Windows.
  • It builds itself with CMake and n2 ("Building CMake with CMake", no bootstrap script). The host's CMake cross-configured it for ToyOS through M2: CMake's ToyOS in every C sysroot, LLVM's two ToyOS arms, and LLVM, clang and LLD built for a ToyOS host by unchanged bootstrap as far as libc lets it #661's toolchain.cmake and Platform modules, exit 0 in 16.7 s [m].
  • The gap:
    • 15 headers, and 62 C symbols [m], 48 of them first referenced from libuv. They cover process and signal calls, semaphores, pread/readv, mkstemp/mkdtemp, termios, socketpair/sendmsg, getifaddrs and others.
    • libc++ built with std::filesystem, because CMake's fstream needs it. It is OFF today (src/libcxx.rs:53), and tracked in libcxx-is-built-without-std-filesystem.md.
  • Process spawning. Every child LLVM's configure starts (try_compile, execute_process, the Ninja probe) goes through libuv's uv_spawn. libuv 1.52 uses posix_spawn only #if defined(__APPLE__) and forks elsewhere, and it learns of a child's end through SIGCHLD.
    • A ToyOS port needs a posix-poll platform branch, as QNX has, a non-Apple posix_spawn path, and stage 3's SIGCHLD imitation [r]. Estimate: a few hundred lines.

n2 does not compile for ToyOS today [r].

  • run_command and the terminal functions exist only for unix, windows and wasm32.
  • Its unix path is posix_spawn of /bin/sh -c <cmd>, with /dev/null as stdin, one pipe2, and waitpid.
  • A ToyOS arm needs one of two spawn routes:
    • std's Command, which hits issues/isolation/a-childs-stdio-handle-is-not-the-one-command-named.md;
    • or the libc crate fork plus stage 3.
  • It also needs a POSIX sh at a path it names, because CMake's ninja commands are sh text.

2.3 rustc through bootstrap, without Python

Yes, it runs without Python [r]:

  • Bootstrap's own code treats Python as optional: config.python is taken from configuration, BOOTSTRAP_PYTHON or PATH, else left unset (rust/src/bootstrap/src/core/sanity.rs:165-173). Only test steps require it (build_steps/test.rs:2530-2531, 3881).
  • ./x is sh that execs Python (rust/x).
  • bootstrap.py does three things:
    • fetches stage0, unless build.rustc/build.cargo are given;
    • runs cargo build --manifest-path src/bootstrap/Cargo.toml with RUSTC_BOOTSTRAP=1, RUSTFLAGS and CARGO_TARGET_DIR (bootstrap.py:1052-1205);
    • execs the binary with BOOTSTRAP_PYTHON (:1409-1413).
  • toyos-build can do all three itself, which is the exit the ledger already names: "src/toolchain.rs runs the bootstrap binary" (issues/build/the-build-runs-host-tools-outside-rust-and-qemu.md). Today it runs ./x (TOYOS/src/toolchain.rs:686).

What bootstrap itself spawns [r]:

  • cmake (the cmake crate) and ninja, which is n2, for LLVM;
  • git, which is not needed when it builds from a source tarball;
  • curl, only for downloads;
  • strip, only on x86_64-unknown-linux-gnu (compile.rs:2875-2895);
  • make, only for the GCC backend.

2.4 cargo

The C side is §1. Building cargo's OpenSSL on ToyOS needs Perl, make and sh in the guest; everything else goes through cc, which is clang.

The Rust side is the libc crate fork and the five -sys arms (Bottom line, item 1). Cargo itself and cargo-util also need ToyOS arms:

  • 10 unix and 16 windows cfg splits in src, and 13 of each in crates/cargo-util (prior report §5.5);
  • flock.rs's error_unsupported exists only for unix and windows, and cargo would treat an Unsupported lock as acquired (flock.rs:391, 468-487) [r].

Parallelism. std's available_parallelism() answers 1 (RUST@aca5f527/library/std/src/sys/thread/toyos.rs:76-80) [r]. A guest cargo, and n2, default to one job. This is tracked as issues/design-debt/std-says-this-machine-has-one-cpu.md.

2.5 toyos-build itself

It is 32,383 lines of Rust in src/*.rs [m]. For ToyOS it needs:

  • ToyOS arms for 28 uses of std::os::unix in 13 files, and 47 uses of libc:: in 6 files [m].
  • A ToyOS answer for each external tool it runs through Command::new, at 76 sites [m]:
    • git, at sites in 12 files: worktrees, submodules, the fork checkout, and LLVM's C++ runtime sources;
    • cmake, n2, clang, llvm-ar, python3 and curl.
  • The toyos channel. The repository's rust-toolchain.toml files name channel = "toyos", which only rustup honours, so a guest build calls the toolchain directly.
  • A source-tree mode. In the guest it needs a mode that runs no git, or gitoxide for the read side, as the ledger plans for the host.

2.6 The tools

tool needed for language Rust replacement accepted? port and its ToyOS gaps effort [e]
LLVM, clang, lld M2 to M5 C++ n/a in flight (#661); libc gaps #650 lists; config.guess in progress
rustc bootstrap M5 Rust yes, itself run the binary directly, with no ./x small
n2 M5, and M4 if the sysroot rebuilds Rust yes, in use ToyOS spawn arm; /bin/sh; /dev/null days
CMake M5, and M4 if the sysroot rebuilds C++ none 62 libc symbols, 15 headers, iconv, libc++ filesystem, libuv spawn and platform port, select (curl and kwsys) weeks
Python LLVM and libc++ configure and build C RustPython if it does the job remove by LLVM hunks (under 100 lines); otherwise RustPython; otherwise CPython (10 symbols, config.sub) days
Perl cargo's OpenSSL in the guest (M5) C none stage 3; a spawn, popen and exec port of about 1k lines; hints; 6 libc functions 2 to 4 weeks after stage 3
make openssl-src, Perl's build C (GNU make 4.4.1) no: omake 0.2.0 (9,672 downloads) and makers 0.8.0 (11,782) are serial and have no jobserver upstream's posix_spawn path (in releases since 4.3, about 2020); patch its execvp re-exec; 8 libc functions (alarm ctime environ getlogin getpwnam putenv tmpnam wait) [m] about 1 week after stage 3
sh Perl's Configure, make recipes, n2, config.guess, system() Rust (brush) yes (the ledger already ran config.guess under brush 0.4.0) ToyOS fork: sys and tokio arms, 6 unix-only builtins (exec, …), an ENOEXEC "run as script" fallback, the here-doc deadlock, backquote escaping. userland/shell (1,180 lines) is not POSIX: no if, for, case, $( ) or globbing 1 to 2k lines, 2 to 3 weeks
coreutils Configure, recipes Rust (uutils 0.12.0) yes uucore uses rustix, which has no ToyOS backend; chmod is unix-only and libc refuses chmod, yet OpenSSL's install_dev runs chmod 644 under set -e 1 to 2 weeks
sed Configure Rust (uutils sed 0.2.0) yes: a measured drop-in for Perl's Configure rustix fast path days
grep Configure Rust (uu_grep 0.2.0) yes, but it links Oniguruma C through onig_sys, and has 300 downloads uucore arm days
awk Configure (32 calls) — unproven: frawk (19,206 downloads, last release 2023), zawk 29,611, none tried against Configure otherwise port onetrue-awk (C) a probe first
git toyos-build (M4), not bootstrap from a tarball C, or gitoxide gitoxide for reads (ledger) a source-tree mode for the guest —

So the C and C++ tools in the chain: LLVM/clang/lld, CMake, Perl, GNU make, cargo's eight libraries, and awk unless a Rust awk proves out. CPython is avoidable.

2.7 What every ported C tool waits on

  • Stage 3 of the child-process track: posix_spawn, waitpid and environ, system/popen through /system/bin/shell -c, and SIGCHLD imitation (Q3a).
  • /dev/null. Perl's Configure aborts without it, and OpenSSL's Configure and n2 open it. Tracked as issues/filesystem/there-is-no-dev-null.md.
  • A POSIX sh at a fixed path. There is no /bin (kernel/src/vfs.rs:85-86) [r]. Stage 3's system() names /system/bin/shell, which is not POSIX.
  • #! launch. Nothing handles #!. Perl and make fall back to sh only on ENOEXEC; brush has no fallback [r]. Untracked.
  • select. Stage 3 says "No select", while curl, in both cargo and CMake, #errors without it.

3. The seed, and what ToyOS rebuilds from it

3.1 The proxies

There is no ToyOS-hosted clang, lld or LLVM-backed rustc on this host. #661's build directories are gone, and find turned up only the macOS store's.

The release.

  • Its asset is 768,410,436 bytes compressed and 2,929,419,280 uncompressed [m]. The Linux-host half is 2,148,176,421; the ToyOS-hosted Cranelift rustc half is 781,237,840.
  • Eight binaries were extracted and stripped with llvm-objcopy --strip-all [m].

The rest:

  • This host's rust/build/x86_64-unknown-toyos/stage2, built 2026-09-27: 775,836,744 bytes, 176,708,952 stripped [m].
  • The Linux nightly of 2026-09-25 for cargo.
  • macOS arm64 installs for CMake, Python, Perl and make. These are the weakest proxies, so every figure from them is [e].

3.2 Per component (x86-64; MB = 10^6 bytes)

component as built stripped basis
librustc_driver, LLVM static (M3's shape) 594.5 184.7 [m] release Linux build. ToyOS's M3 driver is the same crates for another host [e ±10%]
librustc_driver, Cranelift, ToyOS-hosted (today) 486.1 107.4 [m] release
Cranelift backend (goes at M3) 55.2 13.2 [m] local
cargo with its eight C libraries static 36.0 36.0 [m] Linux dist 2026-09-25 bin/cargo
clang 144.0 122.8 [m] release (macOS arm64 store: 104.7)
lld (rust-lld; ld.lld is the same binary) 91.8 78.6 [m] release (macOS: 68.1)
llvm-ar, llvm-nm, llvm-objcopy 38.1 34.2 [m] release
clang resource headers 14.8 14.8 [m] release, 286 entries
x86_64-unknown-toyos libraries 181.1 181.1 [m] release: Rust 155.2; C headers 12.6; libtoyos_c.a 10.3; libc++.a 3.1
x86_64-unknown-none (kernel) 89.0 89.0 [m] release
x86_64-unknown-uefi (bootloader) 132.3 132.3 [m] release
aarch64-unknown-toyos, -none-softfloat, -uefi (ARM64 image) 397.5 397.5 [m] release: 180.9 + 86.3 + 130.3
CMake: binary and share/cmake — ~38.0 [e] Homebrew 4.4.3 arm64: 14.3 + 23.7
Perl and its core library — ~27.8 [e] macOS system 5.34
GNU make — ~0.2 [e] /usr/bin/make
CPython and its stdlib, if not removed — ~48.3 [e] miniconda 3.12: 6.9 + 41.4

For scale, upstream's Linux nightly, installed [m]:

  • rustc + cargo + rust-std: 628.5 MB (rustc 423.7, with libLLVM.so 208.2 as a separate library; cargo 36.7; rust-std 168.2).
  • Adding llvm-tools: 845.1 MB.
  • rustup-init: 21.1 MB.

3.3 Sources a self-build reads [m]

tree size
ToyOS (git ls-files) 42.7 MB, 2,220 files
crates for M4: root and userland lockfiles 489 registry packages; 529.2 MB unpacked (68.3 MB as .crate). windows* crates dominate, because cargo vendor takes every platform. 16 git packages not measured
rust fork, without tests and docs 150.1 MB (223.0 tracked in all)
llvm-project, without tests, unittests, docs and benchmarks 286.7 MB (2,023.8 tracked in all)
cargo 7c83d4cc 17.9 MB
crates for M5, adding the rust, library and cargo lockfiles 1,204 packages, 1,146 of them present: 1,209.9 MB unpacked (180.1 as .crate). 58 not measured

M4 reads 0.57 GB of sources and M5 1.71 GB.

The working space is far beyond today's DATA disks.

  • A worktree's crate targets after --build-only are 4.1 GiB, as recorded in src/worktree.rs:27-30; worktrees that also ran the host suite measure 15.2 to 21.3 GiB [m].
  • This host's accumulated bootstrap directories are stage1-rustc 26.0 GiB and stage2-rustc 21.3 GiB [m]. That is many builds, not one.
  • Today's DATA disks: cargo run's is 1 GiB (src/build.rs:1676) and the test profiles' is 128 MiB (tests/common/qemu.rs:882).

3.4 Seed versus rebuild

Ship (the seed, built on the host):

item size
M4, x86-64 873.5 MB: rustc 184.7, cargo 36.0, clang 122.8, lld 78.6, LLVM tools 34.2, clang headers 14.8, three targets' libraries 402.4. Measured proxies; rustc [e ±10%]
compressed at the release's zstd-3 ratio (26.2%) about 229 MB [e]
ARM64 targets +397.5 MB
M5 adds CMake, Perl and make about 66 MB [e]; about 114 MB [e] with CPython
needs no seed binary brush, uutils, n2 and gitoxide are Rust: the seeded cargo builds them in the guest

Rebuild (what ToyOS makes from the seed):


4. Ship in the default image, or download as packages?

4.1 pkg today

/system/bin/pkg (userland/pkg, 840 lines) installs a local .tar.gz into /apps/<name>/, which is on DATA beside /home, not on the A/B ROOT.

  • It verifies against a SHA256SUMS beside the archive first (main.rs:62-73).
  • It asks the user, or takes --yes, and writes manifest.toml last.
  • It has install <file>, remove and list (main.rs:31-43).

Against a toolchain it falls short:

  • A 256 MiB inflate ceiling, all in memory. MAX_INFLATED is 256 MiB (main.rs:25). fs::read loads the whole archive (:68), and inflate builds the whole tar in a Vec (:111-122).
    • Proposed split: rust (rustc, cargo and the target's std) would be about 375.9 MB and llvm (clang, lld, tools and C sysroot) about 276.3 MB. Both exceed the ceiling.
  • Only plain files and directories. No symlinks or hard links, no pax and no GNU long names (archive.rs:1-12,64-74). A toolchain names one LLD as ld.lld and rust-lld.
  • One program per package: <name>/<name> (lib.rs:36-48). The shell's PATH defaults to /system/bin (userland/shell/src/main.rs:20-21).
  • Gzip only. ToyOS's own release is zstd.
  • Not done yet: HTTPS (stage 2 of the package track), updates (stage 3) and signatures (stage 4). Installing by name is undesigned.
  • No test reaches pkg. pkg_install_gbae and its fixture were deleted on 2026-10-01 (520c0d129). The guest-suite track names a metal pkg_install_gbae (issues/build/the-guest-suite-runs-only-what-no-cheaper-tier-reaches.md:125) that origin/main does not have [m].
  • A package's own libraries cannot load. The loader searches DT_NEEDED libraries only in /system/lib. Tracked as issues/filesystem/a-package-cannot-ship-its-own-libraries.md.

The direction is already set.

  • The track's M2 is "clang, lld and their runtime built for ToyOS on the host and installed by /system/bin/pkg" (issues/build/toyos-builds-itself.md:16-21).
  • The package track's stage 7 removes every app from the image: "pkg install <url> brings them".

The host already consumes a content-addressed release.

  • toolchain-linux-x86_64-<16 hex of the trees> (src/release.rs:21-56) is installed by runners and linked with rustup toolchain link toyos … (issues/build/toyos-is-a-normal-target.md, stage 4).

4.2 rustup on ToyOS (rustup 1.29.1, read and not built)

It cannot run without a fork.

  • The build: build.rs:20-39 aborts unless TARGET is in the platforms crate, which has no ToyOS.
  • The parser: the partial-triple parser lacks toyos, so stable and nightly do not resolve (dist/target_tuple.rs:15-53, dist/mod.rs:209-215).
  • The proxies: run_command_for_dir has a unix arm (exec) and a windows arm (status), and nothing for a third platform (command.rs:26-53). ToyOS has no exec, so each proxy would stay resident, the Windows model.
  • The compile: 13 compile blockers in 8 files.
  • Crates with no ToyOS arm: home, wait-timeout, fs_at, remove_dir_all, console, effective-limits, rustls-platform-verifier and rustls-native-certs. aws-lc-sys (C) is hard-coded as the TLS provider (download/mod.rs:630).
  • Port size: about 100 changed lines in rustup and 300 to 500 in crate arms [e], plus the libc crate fork.
  • A run-time snag (inferred, not run): rustup opens directories as files in Toolchain::exists, and ToyOS's open never yields a directory.

A ToyOS dist server works by the protocol, but not as ToyOS needs.

  • RUSTUP_DIST_SERVER takes any URL, and target keys in the manifest are free strings.
  • But installable channels are only stable|beta|nightly|1.x.y with an optional date. ToyOS's fork would have to pose as an upstream channel name.
  • 1.29.1 verifies no signature; trust is TLS to the server.
  • No third-party dist server for a non-upstream host was found.

The precedent is "our tool delivers, rustup links": Ferrocene's criticalup, espup, and ToyOS's own host flow. toolchain link makes a symlink under $RUSTUP_HOME/toolchains. A custom toolchain cannot component add or target add.

4.3 The image

The primary's bootable.img is 365,953,024 bytes [m]. GPT, read with od [m]:

partition size
ESP 35.7 MB
slots 1.0 MB
log 35.7 MB
slot A 35.7 MB
root A 73.4 MB
slot B 35.7 MB
root B 146.8 MB

Every byte in ROOT is paid three times. Slot B's ROOT is sized at twice slot A's (src/build.rs:1661).

  • ROOT holds 65.7 MB [m].
  • The M4 seed in ROOT would make the image about 3.0 GB (366 + 3 × 873.5 MB [e from the measured rule]).
  • Every cargo run would write and sign that, and every ssh … update would resend it.

What hosted-rustc = true would ship today:

  • It is refused until its licences are read (src/build.rs:1102-1104).
  • It copies every lib/*.so of the hosted stage2 (src/build.rs:2193-2201). In the release that includes 17 proc-macro dylibs (179.6 MB) that the Linux stage2 does not carry [m], plus unstripped binaries.

4.4 The options against the principles

in the default image pkg packages on DATA rustup and a ToyOS dist server
image size about 3.0 GB [e] unchanged, 366 MB unchanged
OS and toolchain updates coupled; each OS update resends about 0.87 GB independent independent
development ergonomics (iteration speed) every image write is about 8 times larger unchanged unchanged
"existing Rust just works" cargo build works; no rustup, so rust-toolchain.toml is ignored cargo build works on PATH; channel = "toyos" works once rustup links most complete, after the port and a server
"Rust is first class" — rustup arrives later as a front end yes, but its channel model names upstream releases only
one installer (package track; the owner's "one mechanism" ruling for children) a second path pkg alone a second installer and index
M4 and M5 tests toolchain always present installed by the test, or on a prepared DATA disk needs the rustup port, TLS and a server
work before usable licences, stripping, ×3 pkg streaming and links; many programs and PATH; the loader's package-local DT_NEEDED; HTTPS for <url> all of the pkg column's loader work, plus the rustup fork, the libc crate, TLS-root arms and a server

4.5 The tests

M4 and M5 need the toolchain, and a DATA disk sized for the build. M4 needs about 6 GB [e]: 0.87 toolchain, 0.57 sources, 4.1 GiB of targets. M5 needs tens of GB [e].

The variable is the disk, not the OS. A self-host profile boots the default image with a large sparse DATA disk carrying the package archives. Its first step is pkg install <archive> --yes, which also gives pkg the end-to-end test it lost.

How the guest reaches the archives is the track's choice:

  • a host-served URL, once HTTPS lands (the package track's own harness design);
  • or a DATA volume the host lays out with the bcachefs writer that already writes ROOT. fsd mounts a volume of ours, or formats a designated one (userland/fsd/src/data.rs:213-229).

4.6 Recommendation

One design: a small default image, the toolchain as pkg packages, a self-host disk and not an image variant, and rustup later as a front end that links.

  1. The default image carries no toolchain. ROOT stays at about 66 MB. Reasons:

    • The ×3 slot rule would make the image about 3 GB.
    • Iteration speed: development ergonomics above all.
    • A/B updates would resend a gigabyte.
    • The track's M2 and the package track's stage 7 already point away from the image.
  2. The toolchain is a set of content-addressed packages, built by the same CI job and under the same tree-hash tag scheme as the host release (src/release.rs):

    • rust: rustc, cargo, std for x86_64-unknown-toyos. About 376 MB.
    • llvm: clang, lld under both names, llvm-ar/nm/objcopy, the clang headers, and the C sysroot with libc++. About 276 MB.
    • rust-std-x86_64-unknown-none (89.0 MB) and rust-std-x86_64-unknown-uefi (132.3 MB), the kernel and bootloader targets that only a ToyOS build needs.
    • The ARM64 targets later.
    • An M5 kit: cmake, make, perl, and brush and uutils built in the guest. Python only if the LLVM hunks are refused.

    Before the packages work, in order:

    • pkg streams instead of buffering, lifts the 256 MiB ceiling, and gets links, many programs per package, and PATH;
    • the loader finds a package's own DT_NEEDED libraries, without which rustc cannot start;
    • HTTPS (package stage 2) enables pkg install <url>;
    • signatures (stage 4) follow.
  3. Self-host tests use the default image plus a self-host DATA disk (§4.5). No second OS image is signed, flashed or kept in step.

  4. rustup is not shipped and not served. Once the libc crate fork, the TLS-root arms and its own arms exist, a ported rustup links the pkg-installed toolchain as toyos (rustup toolchain link toyos /apps/rust). That mirrors the host's flow, criticalup and espup, so channel = "toyos" in the repository's rust-toolchain.toml resolves the same way in the guest. A ToyOS dist server would force a fork to pose as nightly, and it would duplicate pkg's index.


Findings for the tracker

Untracked defects, each found by searching issues/:

  • The libc crate has no ToyOS module, and no ToyOSOrg/libc fork exists. It gates cargo's -sys crates, rustup, n2's spawn and RustPython.
  • std's ToyOS File::lock, lock_shared, try_lock, try_lock_shared and unlock answer Ok(()) and lock nothing (RUST@aca5f527/library/std/src/sys/fs/toyos.rs:566-580). Cargo's package-cache lock is a no-op on ToyOS.
  • ToyOS has no #! script launch and no ENOEXEC fallback.
  • n2 has no ToyOS arm, so it does not compile for the guest [r].
  • M2's ToyOS-hosted LLVM records LLVM host triple: arm64-apple-darwin27.0.0. Bootstrap passes no LLVM_HOST_TRIPLE, and config.guess has no ToyOS case.
  • collect_hosted_rustc would ship unneeded bulk. It would put 17 proc-macro dylibs (179.6 MB) and unstripped binaries into ROOT (src/build.rs:2193-2201).
  • pkg has no test. Its guest test went in 520c0d129, and the metal row the guest-suite track names does not exist.

Upstream-shaped, for the forks:

  • curl-sys: defines HAVE_POLL_FINE, which curl no longer reads, instead of HAVE_POLL; also the HAVE_STERRROR_R typo (build.rs:403,435).
  • brush: a here-doc larger than the pipe deadlocks (interp.rs:1996-2014), and \$ inside backquotes is not unescaped (word.rs:1188).
  • perl-cross: for 5.44 it omits d_nanosleep, and it reports functions present that answer ENOSYS.
  • LLVM: the stale comment "cmake has no relpath function" (AddLLVM.cmake:1860), since LLVM requires CMake 3.20.

Rules for the orchestrator to place. These are general, not about one issue:

  • A libc link test cannot tell an ENOSYS refusal from a working function, so a configure script run against ToyOS's libc must be told which functions are refused.

@Japabu

Japabu commented Oct 2, 2026

Copy link
Copy Markdown
Collaborator Author

Round 1, head c280ecef8. No earlier BLOCKER. Net +72 −2 in two files (git diff --shortstat origin/main...c280ecef8): production 0, tests 0, all of it under issues/.

The edit outside the named file, issues/kernel/a-childs-end-is-an-event-and-a-parent-takes-its-children-down.md:80-82, stays. It is the one sentence the select stage contradicts, and #650 (15625e0cb), #659 (d69b80a75) and #661 (03cb0453b) each still carry the old sentence unchanged, so none of them fights it.

BLOCKER

  • issues/build/toyos-builds-itself.md:38-39 — "cargo keeps its eight C libraries — … OpenSSL … — and nothing replaces them with Rust" stands under Decided (owner) — the record decides less: "accept cargo's C dependencies", with "OpenSSL's Configure needs Perl on ToyOS (or curl's rustls backend) -> decide at M4" (orchestrator's notes, quoted in the body). :81-82 of the same file keeps that open, and curl's rustls backend replaces one of the eight with Rust, so the bullet contradicts the open item six stages below it and says more than was decided. The bullet says what the decision says and no more.
  • issues/build/toyos-builds-itself.md:65 — flock is listed among "what cargo's libraries call" — nothing measured names a caller. The investigation has SQLite's default VFS on fcntl record locks and cargo's package-cache lock on std's File::lock (§1.3), the stage's own source sentence at :68-72 names no caller of it, the plan's stage list ("libc gaps (realpath, file mmap, record locks + file identity via fsd, pollable non-blocking sockets, setvbuf/socketpair...)") does not carry it, and the body's "Unsure" says the same. It leaves the list, or the stage says the earlier decision names it and no caller was found.

NOTE

  • issues/build/the-tooling-is-a-review-prompt-and-three-workflows.md:24-29 against issues/build/toyos-builds-itself.md:41-42 — main's tooling track says "The toolchain builds cargo from the Rust fork's submodule and ships it" and "invoke the shipped cargo and no other"; this branch files the opposite as decided and leaves that track standing — the contradiction the select sentence was edited to remove, left in for cargo. It is below BLOCKER only because the brief takes the host-cargo statement out of blocking; whichever way the owner answers, one of the two sentences changes in this merge.
  • issues/build/toyos-builds-itself.md:41-42, 46-51 — "The toolchain is a content-addressed store built in one shared fork checkout; buildlock, keystore, worktree and identity go #629, open, … is reworked to keep rustup's", "three open pull requests that land first and in this order", "which main does not have" — each turns false at a landing that need not touch this file (A parent's end takes its children down: every end walks its subtree and is published after it, a spawn past its commit lands, and a refused spawn spends no pid #659's and The toolchain is a content-addressed store built in one shared fork checkout; buildlock, keystore, worktree and identity go #629's diffs do not), and the body's "Unsure" names it and leaves it. The landing queue is the body's, where the notes are quoted; the issue keeps what stays true, the libc the gaps were measured against: pull request libc: the POSIX surface LLVM compiles against, and the headers held to the definitions #650 at 15625e0cb.
  • issues/build/toyos-builds-itself.md:46, 49, 89, 101-102 — "The plan's stages", "The plan sets no order", "the plan does not say" (twice) point at a document the tree does not hold; in the tree this section is the plan. Each is written as open.
  • issues/build/toyos-builds-itself.md:86-87 — "They wait on stage 3 of the child-process track and on issues/filesystem/there-is-no-dev-null.md" is said of all seven tools — the investigation measured it of the ported C tools (§2.7, "What every ported C tool waits on"), and brush and uutils are Rust. It is said of the C tools.
  • issues/build/toyos-builds-itself.md:36 — "C and C++ are accepted … in programs too" — both owner lines quoted in the body say C; C++ is the investigation's restatement. The owner's word.
  • PR body, "Gates" — the host run gives its command, exit code and verdict line and names no log. Read for this review: /Users/jan/.claude/jobs/2280e09e/tmp/scratchpad/orch/selfhostplan/ci-host.log, 8116 lines, last line [ci] Host: 59 step(s), all green, and ci-host.exit, EXIT=0. The body names both.
  • PR body, "Unsure" — the body becomes main's merge commit. Each doubt is answered here (the child-process sentence stays; "no order" is what the stage list says; flock and the three stale sentences are findings above) and the section goes; "Not recorded here" stays as a statement.

REMOVE

SEND BACK

Japabu and others added 2 commits October 2, 2026 10:24
…o is the tooling track's

Answers the review of c280ece and takes two answers the owner gave on
2026-10-02, after that commit was written.

The owner's answers:

- The development host builds cargo from the Rust fork and uses no other.
  The notes this branch was written from recorded the opposite as a
  consequence of accepting cargo's C dependencies, and the owner has overruled
  it. The bullet "The host builds with the cargo rustup ships. #629 ... is
  reworked to keep rustup's" goes; the tooling track's cargo sentences on main
  stand and are not repeated here.
- OpenSSL's build on the host runs under the host's own make and shell, and
  openssl-src is not forked for it. The track says so in one sentence, beside
  the question it bounds: what is open until M4 is how cargo's OpenSSL is
  built for ToyOS. The host tools themselves are declared in
  the-build-runs-host-tools-outside-rust-and-qemu.md, which is #629's change.

The review's findings:

- "cargo keeps its eight C libraries ... and nothing replaces them with Rust"
  said more than was decided and contradicted the open rustls-backend
  question. The bullet is now "cargo's C dependencies are accepted", and the
  eight are named by the stage that cross-builds them.
- flock leaves the libc stage. No library cargo builds for ToyOS calls it:
  over the eight crates' sources, `rg '\bflock\s*\('` finds a call in two
  places. SQLite's is inside `#if SQLITE_ENABLE_LOCKING_STYLE`, which
  sqlite3.c defines 1 only under __APPLE__ and libsqlite3-sys 0.38.1's
  build.rs never sets; nghttp2's is in third-party/mruby, which
  libnghttp2-sys 0.1.13's build.rs does not name.
- setvbuf gets the caller the stage did not name: curl's TLS key log
  (lib/vtls/keylog.c).
- The landing queue (#650, #659, #661 "open", "in this order") and "which
  main does not have" turn false at a landing that need not touch this file,
  and go. The stage keeps the libc its gaps were measured against, pull
  request #650's at 15625e0, and says of that libc what it said of main's:
  `git grep -w` for setvbuf, socketpair and select over userland/libc at
  15625e0 matches nothing.
- "The plan's stages", "the plan sets no order" and "the plan does not say"
  pointed at a document the tree does not hold. Each is written as open.
- Waiting on stage 3 of the child-process track and on /dev/null is said of
  the tools written in C or C++, as it was measured, and no longer of brush
  and uutils, which are Rust.
- "C and C++ are accepted" becomes the owner's word, C.
- The child-process track's sentence no longer repeats why select passes
  FD_SETSIZE; this track says it beside the open question.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013UDZQ6fSKw14e4w2TKTRfm
The owner was asked on 2026-10-02 which TLS engine ToyOS programs use and
chose ring over graviola, with graviola an option to revisit later.

- issues/build/toyos-builds-itself.md says it under "Decided", pointing at
  the stage that owns it.
- issues/design-debt/the-internet-clients-work-unchanged.md stage 3 named the
  graviola provider. It names ring, and records graviola as the later option.
  Nothing else in that track changes.

main already builds this way: userland/Cargo.lock pins ring 0.17.14 and
rustls 0.23.37, and `git grep -i graviola` over the tree matched that one
line of stage 3 and nothing else.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013UDZQ6fSKw14e4w2TKTRfm
@Japabu Japabu changed the title The self-hosting track carries the owner's plan of 2026-10-01 as its stages The self-hosting track carries what the owner decided and what is to be built; ToyOS programs' TLS is rustls with ring Oct 2, 2026
@Japabu

Japabu commented Oct 2, 2026

Copy link
Copy Markdown
Collaborator Author

Round 2, head 4a22b747c, reviewed against origin/main 46af79d5d (merge base de5f63cc2; #650 landed since, as 5924ec449).

Earlier BLOCKERs:

  • CLOSED — "cargo keeps its eight C libraries … and nothing replaces them with Rust" under Decided. issues/build/toyos-builds-itself.md:38 reads "cargo's C dependencies are accepted." and the eight are named at :71-72 by the stage that cross-builds them, above the question :78-79 keeps open (git diff c280ecef8 4a22b747c).
  • CLOSED — flock among "what cargo's libraries call". It is gone from :60-63. The implementer's 679-r2/flock-callers.txt (rg '\bflock\s*\(' over the eight crates, 26 lines) has two callers outside comments and Ruby tests: SQLite's robust_flock at sqlite3.c:42804,42808, inside #if SQLITE_ENABLE_LOCKING_STYLE (:42796 to :42961, sqlite-locking-style.txt), and mruby's file.c:94,626, which libnghttp2-sys's build.rs does not name.

Net +73 −3 in three files (git diff --shortstat origin/main...4a22b747c): production 0, tests 0, all of it under issues/. Host gate at this head: the body's command and EXIT=0, and its log read here, 679-r2/ci-host.log, last line [ci] Host: 59 step(s), all green. Merge with main as it stands now: git merge-tree --write-tree origin/main 4a22b747c, exit 0, no conflict.

BLOCKER

  • issues/design-debt/the-internet-clients-work-unchanged.md:26-29, issues/build/toyos-builds-itself.md:39-40, PR body row "main's userland/Cargo.lock pins ring and rustls" — commit 4a22b747c says "main already builds this way" and the body offers a lock grep as its origin; the tree installs no ring provider anywhere, and the measurement that says so was run and left out. git grep -n -e rustls -e ureq 4a22b747c -- '*.rs' '*.toml' (exit 0): the one place a rustls provider is installed is userland/doom/build.rs:165, rustls_rustcrypto::provider(), under [build-dependencies] (userland/doom/Cargo.toml:18-21, rustls-no-provider with rustls-rustcrypto 0.0.2-alpha), a build script that runs on the host; the one ToyOS-target manifest that names rustls, tests/toyos-rust-tests/Cargo.toml:26-28, takes rustls-no-provider and rustls-rustcrypto too, and no .rs file under tests/ names either. In userland/Cargo.lock, rustls 0.23.37's entry lists no ring; ring 0.17.14 is there as rustls-webpki's dependency, which a grep for the package name cannot tell from a provider. The implementer's own 679-r2/rustls-manifests.txt holds doom's two lines; the body cites tls-lock.txt and graviola-tree.txt and not it. So no ToyOS program uses rustls with ring, the notes' "ToyOS programs keep rustls + ring" was never true of the tree, and the owner was asked ring or graviola without being told that what the tree runs is a third provider, an alpha. It goes back for: the body row replaced by the manifests' reading; that reading put to the owner, by the orchestrator, before the line lands as decided; and stage 3 naming the rustls-rustcrypto it moves the tree off, since its exit (:30-32) passes on any provider and the divergence otherwise stands recorded nowhere.

NOTE

REMOVE

  • issues/build/toyos-builds-itself.md:79-81 — "On the host it is decided (owner, 2026-10-02): OpenSSL's build runs under the host's own make and shell, and openssl-src is not forked for it." — no lockfile on main names an openssl package (git grep -n '^name = "openssl' origin/main -- '*.lock', exit 1), so it describes a build that arrives with The toolchain is a content-addressed store built in one shared fork checkout; buildlock, keystore, worktree and identity go #629, whose rows in issues/build/the-build-runs-host-tools-outside-rust-and-qemu.md are the one place a host tool is declared; "for ToyOS" and "there" in the sentence before it already bound the open question, and the body keeps the host's cargo out of this track on the same ground.
  • issues/build/toyos-builds-itself.md:39-40 — "ToyOS programs use rustls with ring (2026-10-02): stage 3 of issues/design-debt/the-internet-clients-work-unchanged.md." — stage 3 is the declaration and this diff edits it; this track already names that track at :107, and two files carrying one decision is two to change when graviola is revisited.
  • PR body, "What is written as open" — five lines the issue's own "Open" sentences say.

SEND BACK

Japabu and others added 2 commits October 2, 2026 11:26
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013UDZQ6fSKw14e4w2TKTRfm
…es; the libc stage names main's issues

Review #679 (comment).

BLOCKER. 4a22b74 said main already builds rustls with ring. It does not.
`git grep -n -e rustls -e ureq HEAD -- '*.rs' '*.toml'` finds one source that
installs a provider, `userland/doom/build.rs:165`, a build script on the host,
and it is `rustls-rustcrypto` 0.0.2-alpha; `tests/toyos-rust-tests` declares
the same provider and no source under `tests/` names it. `ring` 0.17.14 is in
both lockfiles as an optional dependency of `rustls-webpki` that no feature
turns on: `cargo tree --locked --offline -e features --target all -i ring`
prints nothing in `userland` and in `tests/toyos-rust-tests`, with and without
`--all-features`. So no build compiles ring, for the host or for ToyOS.

The orchestrator put that reading to the owner, who chose ring as the provider
stage 3 moves ToyOS programs to, graviola staying a later option. Stage 3 of
the internet-clients track now says ring as its target, names the
`rustls-rustcrypto` it moves the tree off, records as open whether ring builds
for the ToyOS target, and its exit fails on any other provider and on a
manifest that still names `rustls-rustcrypto`.

REMOVE. The self-hosting track no longer repeats that decision under
"Decided": stage 3 is its one home. The sentence on the host's OpenSSL build
goes too: no lockfile on main names an openssl package, and the host tools of
that build are #629's rows.

NOTE. With origin/main merged, #650's libc is main's: `15625e0cb` is an
ancestor of HEAD and `userland/libc` is tree 4f00659 at both. The libc stage
says `userland/libc` at `15625e0cb` and names the three issue files main holds
for what it restated: libc-refuses-what-toyos-cannot-yet-answer.md for
`realpath`, a file `mmap` and record locks,
libc-stat-answers-one-serial-number-for-every-file.md for file identity, and
libc-close-of-a-socket-ends-the-process.md for socket descriptors.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013UDZQ6fSKw14e4w2TKTRfm
@Japabu Japabu changed the title The self-hosting track carries what the owner decided and what is to be built; ToyOS programs' TLS is rustls with ring The self-hosting track carries what the owner decided and what is to be built; the internet clients' TLS stage moves the tree from rustls-rustcrypto to ring Oct 2, 2026
@Japabu

Japabu commented Oct 2, 2026

Copy link
Copy Markdown
Collaborator Author

Round 3, head 20df3005f, reviewed against origin/main 46af79d5d, merged in at fff7c899f (git diff --stat origin/main 20df3005f names the same three files as the three-dot diff).

Earlier BLOCKERs:

  • CLOSED — round 2's: the ring line landing as decided on a lock grep. The body's row is now the manifests' reading: git grep -n -e rustls -e ureq 20df3005f -- '*.rs' '*.toml', exit 0, 12 lines, re-run here and equal to 679-r3/rustls-sources.txt. 679-r3/provider-trees.txt has cargo tree --locked --offline -e features --target all -i ring at exit 0 with "nothing to print" in both workspaces, with and without --all-features; rustls-rustcrypto 0.0.2-alpha's published manifest takes rustls-webpki with default-features = false, so nothing turns ring on. The brief records that reading put to the owner and his answer, and stage 3 names the provider it leaves (issues/design-debt/the-internet-clients-work-unchanged.md:29-32). Closed as it was posed. The reading it was posed on, round 2's own, stopped at the head; the BLOCKER below is what it left out.
  • Round 1's two stay closed: issues/build/toyos-builds-itself.md:38 and :58-71 read as round 2 found them.

Net +82 −8 in three files (git diff --shortstat origin/main...20df3005f): production 0, tests 0, all of it under issues/. Host gate at this head: the body's command, EXIT=0 in 679-r3/ci-host.exit, and the log read here, 679-r3/ci-host.log, created 11:31:05, five seconds after the head's commit, last line [ci] Host: 59 step(s), all green. git merge-tree --write-tree origin/main 20df3005f: exit 0.

BLOCKER

  • issues/design-debt/the-internet-clients-work-unchanged.md:29-36 — "tests/toyos-rust-tests declares it and names it in no source", and an exit on "no manifest names rustls-rustcrypto" — those manifest lines belong to a ToyOS TLS client that main cut the day before the owner was asked and that an open track owes back, and neither the stage, the body nor what the owner was told says so. git show --stat 520c0d129 (on main since The guest suite keeps the 21 tests only a booted machine answers; the rest are metal, host or tracked #660, 06788146b, 2026-10-01) deletes tests/toyos-rust-tests/src/bin/https_fetch.rs, tests/common/https.rs, tests/https-server-host and tests/https-fetch-host; its diff of tests/toyos-rust-tests/Cargo.toml is empty, so :26-31 there are the six lines 7c47e8930 added for that program, left behind. git grep -n rustls_rustcrypto 520c0d129^ -- '*.rs': https_fetch.rs:156 and https-server-host/src/main.rs:272 install rustls_rustcrypto::provider(), beside doom's; it was the one ToyOS program that named rustls, and it ran as https_tls13 on virtio-net and https_tls13_e1000e (tests/toyos.rs:657,661), its judge holding hostname-mismatch and unknown-authority (tests/common/https.rs:30,201). issues/build/the-guest-suite-runs-only-what-no-cheaper-tier-reaches.md:244-245 owes it back, "metal https_tls13 … ureq and rustls fetch over TLS 1.3 on the I219", and :13-14 has a row bring back "from main before the cut" what its arm needs. The round's own 679-r3/issues-tls-mentions.txt holds that line and did not follow it. Three things are wrong with landing it so. (1) "No ToyOS program uses rustls in source" is true of the head and was put to the owner without this: "keeping rustls-rustcrypto for now" was the provider of an owed T14 row, not of a dependency nothing uses, and ring has never been compiled for the target. (2) After this merge two open tracks disagree and neither names the other: the guest-suite track's stage H brings back a ToyOS program installing rustls-rustcrypto and three manifests naming it, stage 3 forbids the name and calls the declaration unused, and that track's stages "are independent and run in parallel" (:12). (3) Stage 3's exit, rewritten here, still asks for the handshake and the two refusals "with a host-side server in the harness", which is the cut judge, filed by that track as a metal row: one test under two tracks. It goes back for: stage 3 naming that row and the provider its client and judges come back on, with the one sentence of the guest-suite track that says otherwise changed in the same merge, as the select sentence was; one owner for that test; the body's record of what the owner was told saying what was not in it; and that put to the owner, by the orchestrator, before the line lands as decided: his choice makes the T14's HTTPS row wait on ring building for the ToyOS target, which stage 3 records as untried at its :32-33.

NOTE

  • issues/design-debt/the-internet-clients-work-unchanged.md:36 — "and no manifest names rustls-rustcrypto", the step past the brief — it stands, and it is the branch's, not the owner's. Round 2 asked for the provider the stage "moves the tree off" and for an exit that does not pass on any provider; a 0.0.2-alpha provider is not one of root CLAUDE.md's "general and widely used crates"; a second provider beside ring would be a sibling. For tests/toyos-rust-tests, a ToyOS program, the clause is the decision itself. For userland/doom/Cargo.toml:21, a build script on the host, he ruled on nothing, and neither the stage nor the body says what it installs instead, while the title says "moves the tree from rustls-rustcrypto to ring": ring there is its C through cc::Build under the host's cc, where rustls-rustcrypto compiles none, which is Arrivals' question for the pull request that does it. The body says in one sentence that the clause is the tree's rule and not his ruling, and the title says what the stage says: it targets ring and moves the tree off rustls-rustcrypto.

REMOVE

None.

SEND BACK

Japabu and others added 2 commits October 2, 2026 12:05
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013UDZQ6fSKw14e4w2TKTRfm
…rack points at it

Review #679 (comment).

BLOCKER. Stage 3 said `tests/toyos-rust-tests` declares `rustls-rustcrypto`
and names it in no source, and asked for a tree in which no manifest names it.
Those manifest lines are what #660 left of a ToyOS TLS client. Until
`520c0d129` the tree ran `https_tls13` and `https_tls13_e1000e`:
`tests/toyos-rust-tests/src/bin/https_fetch.rs:156` and
`tests/https-server-host/src/main.rs:272` installed
`rustls_rustcrypto::provider()`, and the judge in `tests/common/https.rs` held
the fetch's digest and the refusals. The cut's diff of
`tests/toyos-rust-tests/Cargo.toml` is empty, so the six lines `7c47e8930`
added for that program stayed. Stage H of the guest-suite track owes the test
back as a T14 row and has a row bring back what `main` had before the cut, so
after round 3 two tracks disagreed about its provider and both asked for the
same test.

The orchestrator put that to the owner: the cut test, its provider, the track
that owes it back, and that `ring` has never been built for the ToyOS target.
Asked whether the test comes back on `rustls-rustcrypto` first or waits for
`ring`, he chose to wait: `rustls-rustcrypto` does not come back into the
tree, and the T14's HTTPS row stays out until `ring` builds for ToyOS.

So stage 3 owns the row and says so, with the provider its program and judge
come back on; its exit is that row and no longer a second test beside it. The
guest-suite track's line keeps the names and the behaviour and points at
stage 3, which deletes it. Whether `ring` builds for the ToyOS target stays
open and untried.

The six leftover lines are filed, as `main` filed the three `blockd_io` left:
`git grep` for them under `tests/toyos-rust-tests` finds the manifest and its
lockfile alone.

NOTE. The exit's "no manifest names `rustls-rustcrypto`" reaches doom's build
script, on the host, where the owner ruled on nothing. `ring` 0.17.14 has a
build script and `cc` as a build-dependency (`build.rs:507`), and
`rustls-rustcrypto` 0.0.2-alpha's manifest has neither, so what that script
installs instead is the question of the pull request that changes it. The
stage records it as open.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013UDZQ6fSKw14e4w2TKTRfm
@Japabu Japabu changed the title The self-hosting track carries what the owner decided and what is to be built; the internet clients' TLS stage moves the tree from rustls-rustcrypto to ring The self-hosting track carries what the owner decided and what is to be built; the internet clients' TLS stage targets ring, moves the tree off rustls-rustcrypto and owns the T14's HTTPS row Oct 2, 2026
@Japabu

Japabu commented Oct 2, 2026

Copy link
Copy Markdown
Collaborator Author

Round 4, head 03b1abe08, reviewed against origin/main 80bc97b41, merged in at ac4f7c8f5 (git diff --stat origin/main 03b1abe08 names the same five files as the three-dot diff). This round's logs are in /Users/jan/.claude/jobs/2280e09e/tmp/scratchpad/orch/679-review-r4/.

Earlier BLOCKERs:

  • CLOSED — round 3's: stage 3 calling the cut HTTPS test's provider line unused, and forbidding a name an open track owed back, with the owner not told. Stage 3 names the row, says it owns it and which provider it comes back on (issues/design-debt/the-internet-clients-work-unchanged.md:29-36); stage H's line points there and says who deletes it (issues/build/the-guest-suite-runs-only-what-no-cheaper-tier-reaches.md:245-247); the body says what the first question left out and records the second answer; the brief records it put to the owner and his choice to wait for ring. The body's rows for it are git grep -n rustls_rustcrypto 520c0d129^ -- '*.rs' and git show --stat 520c0d129, in 679-r4/https-test-history.txt and 679-r4/cut-commit.txt. At the head, git grep -n -e https_tls13 -e rustls-rustcrypto -e rustls_rustcrypto 03b1abe08 -- ':!*.lock', run here, exit 0 (facts.txt): the two tracks, the new issue, three kernel issues, two manifests and doom's build script, and no test.
  • Round 3's NOTE is done: the body says the exit's last clause is the tree's rule where it reaches doom's build script, and the title says what the stage says.
  • Rounds 1 and 2's stay closed: git diff --stat 20df3005f 03b1abe08 over issues/build/toyos-builds-itself.md and the child-process track prints nothing (unchanged.txt).

Net +116 −9 in five files (git diff --shortstat origin/main...03b1abe08): production 0, tests 0, all of it under issues/. Host gate at this head: the body's command, EXIT=0 in 679-r4/ci-host.exit, and the log read here, 679-r4/ci-host.log, created 12:10:42, six seconds after the head's commit, 6785 lines, last line [ci] Host: 59 step(s), all green; its FAILED and error: lines are the controls' own, bar one in the build system's tests (ci-log-reds.txt). No guest test: the change reaches no code. git merge-tree --write-tree origin/main 03b1abe08: exit 0.

The round's question about the four judges (expired certificate, TLS 1.2 peer, downgrade, cleartext redirect) is no finding on this branch. The exit at issues/design-debt/the-internet-clients-work-unchanged.md:42-45 holds what both of main's lines held, stage 3's handshake with the same two refusals and stage H's fetch, so nothing is cut here; #660's line never named the four. Which arms of the cut judge the row carries, and on which tier, is the row's own pull request's to say under Guest tests, and a track does not carry it. The body's bullet stays as the record of that.

BLOCKER

  • issues/build/the-guest-test-crate-keeps-the-cut-https-tests-dependencies.md:1-21 — a second file for the issue main has as issues/build/the-guest-test-crate-depends-on-three-crates-no-test-uses.md, and neither is what the manifest holds — the two are one issue: the same manifest, the same commit (520c0d129), the same exit sentence, the same owner, and one deletion with one lockfile closes both; issues/README.md is one file per issue, and a sibling is a BLOCKER. The round measured only the six names it came for. git grep -c -w <crate> 03b1abe08 -- tests/toyos-rust-tests/src exits 1 for sixteen of the manifest's twenty-two dependencies (manifest-deps.txt, seven-more.txt): main's three, this file's six, and toyos-window, toyos-quiesce, toyos-i219, toyos-inspect, toyos-dns, winit and softbuffer (tests/toyos-rust-tests/Cargo.toml:10,12-14,20,23-24), which no issue names. And 7c47e8930 added seven lines for https_fetch.rs, not six: the round's own 679-r4/https-test-history.txt:127 is the [patch.crates-io] line for the getrandom fork, now Cargo.toml:44, whose only locked dependents are rand_core, under rustls-rustcrypto and its crates, and the ring nothing compiles (getrandom.txt). This file's exit, "the six lines are gone, the lockfile follows", is met with that fork patch left in the manifest, and with :40-42 (winit, softbuffer, raw-window-handle) beside it. It goes back for one file: main's, git mved to a slug the tree does not refute, as README's "Areas" has it; its body every [dependencies] line no source under the crate names and every [patch.crates-io] line that then patches nothing, each from a command that was run; one exit; this file deleted; issues/design-debt/the-internet-clients-work-unchanged.md:40 citing the one that stays; and the body's row "git show 7c47e8930 … adds the six" saying what the log shows. No open pull request changes main's file (open-prs.txt); The kernel declares each CPU's HWP request, and the counters round reads the power envelope back under TRACE #590 adds one line to the manifest.

NOTE

  • pull request body, "Not recorded here", last bullet — three kernel issues found citing a cut test as cover that runs, and "not filed" — root CLAUDE.md files what is found off the task. One is more than a stale name: issues/kernel/no-boot-reaches-the-retry-that-undoes-a-placement-nothing-answered.md:30-31 has https_tls13_e1000e red a deleted BarReferenceEmpty refusal, by the judge's kept-BAR count (679-r4/cut-https-judge.rs:168-174); stage H's line never named that judge, and it goes with the line when stage 3 deletes it. One file, and the bullet names it.

REMOVE

  • issues/build/the-guest-suite-runs-only-what-no-cheaper-tier-reaches.md:247-248 — "it comes back there on the ring provider, not on the rustls-rustcrypto its program and judge installed on main before the cut" — stage 3 says it at its :34-36, and the body has the provider decision written in stage 3 alone.
  • pull request body, "Gates" — "No other open pull request changes a file this round changes: …" — which open pull requests touched which files on one day is not main's record.

SEND BACK

Japabu and others added 3 commits October 2, 2026 12:30
…the pcidev issues that cite cut tests

The round-4 review (pull request #679, comment 5950322518) sent the branch
back on one BLOCKER, one NOTE and two REMOVEs.

BLOCKER. issues/build/the-guest-test-crate-keeps-the-cut-https-tests-dependencies.md
was a second file for the issue main has as
issues/build/the-guest-test-crate-depends-on-three-crates-no-test-uses.md: the
same manifest, the same cut, the same owner and exit. It is deleted, and stage
3 of the internet-clients track cites main's file. Main's file is not renamed
or widened here, by the orchestrator's ruling: that it names three of the
dependencies no source uses is main's state, and the pull request that deletes
the lines from tests/toyos-rust-tests/Cargo.toml corrects it.

NOTE. Three issues about kernel/src/pcidev still give guest tests 520c0d1
deleted as tests that run. They are not this branch's to edit, so one file,
issues/kernel/pcidev-issues-cite-cut-guest-tests-as-cover-that-runs.md, records
it. Six names, not only the two HTTPS tests the review came for: all six were
in tests/toyos.rs at 520c0d1^ and none is at 520c0d1 or outside issues/ at
this head. One citation is cover nothing owes back: https_tls13_e1000e's judge
asserted the count of BARs kept back and BarReferenceEmpty's words
(tests/common/https.rs at 520c0d1^, lines 168-174), stage H of the
guest-suite track lists that test for its fetch alone, and stage 3 deletes that
line.

REMOVE. Stage H's line no longer repeats which provider the row comes back on:
stage 3 says it.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013UDZQ6fSKw14e4w2TKTRfm
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013UDZQ6fSKw14e4w2TKTRfm
…d no others

536e804 filed the three kernel issues' stale citations under six test names:
the two HTTPS tests the review named, and bar_placement_is_proven,
pci_function_is_exclusive, virtio_net_no_msix and userdev_dma_fault, which the
same lines of the same three issues name and 520c0d1 also deleted. That was
wider than the review's finding and than the round's brief, and its population
is not closed: issues/boot-media/the-loader-does-only-what-must-precede-the-handover.md
names bar_placement_is_proven as a test that passes, and which other issues
name a test that commit deleted is nothing this round measured.

The file is renamed to
issues/kernel/kernel-issues-cite-the-cut-https-tests-as-cover-that-runs.md and
names https_tls13 and https_tls13_e1000e alone. For those two the population is
measured: under issues/ they are named by the three kernel issues, by this
file, and by the two tracks that own the row. The other four names go to the
orchestrator in the round's report.

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

Japabu commented Oct 2, 2026

Copy link
Copy Markdown
Collaborator Author

Round 5, head 16776357c, reviewed against origin/main 7e62d3553, merged in at e7476a1c6 (git diff --stat origin/main 16776357c names the same five files as the three-dot diff). Worktree /Users/jan/Dev/jan/toyos-selfhostplan, left clean (git status --porcelain --ignore-submodules=none prints nothing, exit 0). This round's logs are in /Users/jan/.claude/jobs/2280e09e/tmp/scratchpad/orch/679-review-r5/.

Earlier BLOCKERs:

  • CLOSED — round 4's: the sibling of main's issues/build/the-guest-test-crate-depends-on-three-crates-no-test-uses.md. At the head git ls-tree 16776357c issues/build/the-guest-test-crate-keeps-the-cut-https-tests-dependencies.md prints nothing and git grep -n keeps-the-cut-https 16776357c exits 1; git grep -n the-guest-test-crate 16776357c is one line, issues/design-debt/the-internet-clients-work-unchanged.md:40, citing main's file; git diff --stat origin/main 16776357c over main's file prints nothing (facts.txt, facts2.txt, since-r4.txt). The body's row for 7c47e8930 says seven lines, by git show --numstat (679-r5/7c47e8930-manifest.txt). Judged against the orchestrator's fence, which keeps main's file as it is here, and the fence leaves nothing in this diff wrong: what owns tests/toyos-rust-tests/Cargo.toml:28 is stage 3's exit, "no manifest names rustls-rustcrypto", and not the cited file; that file's exit is met with the line still there, and its close takes the citation with it and leaves stage 3's sentence true. The twelve other dependency lines no source names and the getrandom patch stay in no issue until the pull request the body names, as on main today.
  • Round 4's NOTE is done: one file, issues/kernel/kernel-issues-cite-the-cut-https-tests-as-cover-that-runs.md, and the body names it. Its claims, run here at the head: git grep -n -w -e https_tls13 -e https_tls13_e1000e 16776357c, exit 0, ten lines, all under issues/, the three kernel issues' among them; git grep -n -e BarReferenceEmpty -e 'keeps BAR' -e 'all-zeroes or all-ones' 16776357c finds kernel/src/pcidev/mod.rs and issues/ alone; at 520c0d129^ the same pattern outside kernel/ and issues/ is tests/common/https.rs and one comment, so the cut judge was the one reader (facts.txt, facts3.txt). No other issue file has its name (git ls-tree -r over issues/, no duplicate), and its frontmatter is issues/README.md's.
  • Round 4's REMOVEs are done: issues/build/the-guest-suite-runs-only-what-no-cheaper-tier-reaches.md:245-247 ends at "deletes this line.", and the body's "No other open pull request …" bullet is gone (body-r4-to-r5.diff).
  • Rounds 1 to 3's stay closed: git diff 03b1abe08 16776357c over the branch's files is the stage H line, the citation at stage 3's :40, the sibling's deletion and the new file, and nothing in issues/build/toyos-builds-itself.md or the child-process track (since-r4.txt).

Net +123 −9 in five files (git diff --shortstat origin/main...16776357c): production 0, tests 0, all of it under issues/. Host gate at this head: the body's command, EXIT=0 in 679-r5/ci-host.exit, 679-r5/ci-host.head naming 16776357c five seconds after its commit, and the log read here, 679-r5/ci-host.log: 6887 lines, 59 step lines and the last [ci] Host: 59 step(s), all green; its FAILED and error: lines are the controls' own, :5202 to :6489, bar :77 in the build system's tests (ci-steps.txt, ci-log-reds.txt). No guest test: the change reaches no code. git merge-tree --write-tree origin/main 16776357c: exit 0.

What the round found beyond its fence (679-r5/found-beyond-the-fence.txt: four more cut tests the same lines cite, and tests/e1000case named in three places) is no finding on this branch. No issues/ file holds it: the scratch file and 16776357c's message do.

BLOCKER

None.

NOTE

None.

REMOVE

  • pull request body, "Not recorded here", fourth bullet — "The three kernel issues that cite … are not corrected … files them." — it is recorded here, and "What changed, per decision" says so in its own bullet.
  • pull request body, "What changed, per decision", the bullet on the line the cut left — "and this branch files none of its own for it" and "The branch does not change that file; what it leaves out is under "Not recorded here"." — the last bullet of "Not recorded here" says what the branch leaves, once.

LAND AFTER NAMED CHANGES

@Japabu
Japabu marked this pull request as ready for review October 2, 2026 10:48
@Japabu
Japabu added this pull request to the merge queue Oct 2, 2026
Merged via the queue into main with commit 7c4a648 Oct 2, 2026
2 checks passed
@Japabu
Japabu deleted the wt/toyos-selfhostplan branch October 2, 2026 10:58
Japabu added a commit that referenced this pull request Oct 2, 2026
Cargo.lock alone conflicted: both sides kept, main's pcap-file and
byteorder_slice beside this branch's ureq, flate2 and tar trees, and cargo
left the result as it resolves the merged manifests. Against origin/main the
lockfile differs by what it did before the merge, +801 -6.

#659 moves the rust gitlink and the kernel, so the freestanding and sysroot
keys move with it.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013UDZQ6fSKw14e4w2TKTRfm
Japabu added a commit that referenced this pull request Oct 2, 2026
Six conflicts.

- rust: the gitlink is 01b8626673f, the fork's main (012fdce3c79, which holds
  main's pin 6c7f996a4fe) with this branch's 61adcea7362 merged into it. Over
  6c7f996a4fe it carries `configure_cmake`'s `toyos` arm and `src/llvm-project`
  at ceaf0fbb844, and nothing else: 012fdce3c79 still held the three
  cross-platform bootstrap commits 61adcea7362 reverts.
- src/sysroot.rs: main's two keys. `clang::CMAKE` joins the sysroot's, beside
  the C++ runtime's options, and `RECIPE` is main's text with CMake's
  description of ToyOS named in it, at a number neither side had.
- src/libc.rs: `build_c` writes the CMake files and then links main's probe.
- src/libcxx.rs: main moved n2 out of the file; the configure through the
  sysroot's toolchain file is this branch's.
- issues/build/toyos-builds-itself.md: main's Decided and To build sections
  whole. Main dropped the signal-set calls from the Compile bullet this
  branch had already replaced, with Configure and Link, by its pointer to the
  bootstrap issue; the pointer stays.
- issues/build/bootstrap-cannot-build-llvm-clang-and-lld-for-a-toyos-host.md:
  this branch's body. Main's one hunk took `alarm` and the signal-set calls
  out of a paragraph this branch had deleted; what the build stops on at this
  tree is measured and written in the commits that follow.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013UDZQ6fSKw14e4w2TKTRfm
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