Skip to content

One workspace, one lock: the root, the kernel, the loader, userland and the SDK resolve together - #746

Merged
Japabu merged 9 commits into
mainfrom
wt/toyos-oneworkspace
Oct 8, 2026
Merged

Japabu merged 9 commits into
mainfrom
wt/toyos-oneworkspace

Conversation

@Japabu

@Japabu Japabu commented Oct 7, 2026 •

Copy link
Copy Markdown
Collaborator

Stage 3 of issues/the-tree-says-who-uses-each-thing.md. The root, kernel/, bootloader/, userland/ and toyos/ were five Cargo resolutions; they are one workspace with one Cargo.lock, one [profile.toyos], one [patch] table and one tracked .cargo/config.toml. No directory moves.

Head dd12c0b32, on origin/main 6f87cdb9c (#749; none of #757, #759 or #762 had landed when it was merged and measured). It is 9ef866436, where the CI readings of the fold itself were taken, plus two merges of main and the close of the stage's issue. Everything owed at the merged head is in the next section, measured at dd12c0b32.

The merge of #749, measured at dd12c0b32

#749 wrote its new dependency edges into kernel/Cargo.lock and userland/Cargo.lock, which this branch deletes. Both modify/delete conflicts are resolved by deleting the file and re-resolving the root lock. Git merged the root Cargo.lock without a conflict into a lock that is wrong, as the review found: cargo metadata --locked on it exits 101 (cannot update the lock file … because --locked was passed). It had toyos-userbound's edges to toyos-abi and toyos-bootmap, which #749 also wrote into the root lock, and not acpiserver's to toyos-acpi and toyos-aml, which #749 wrote into userland's alone. cargo metadata --offline re-resolved it. diff of git's merged lock against the re-resolved one is those two lines under acpiserver and nothing else: no package added, no version moved.

Owed Command Result
The lock resolves as committed cargo metadata --locked --format-version 1 exit 0 at this head by the host suite's step "the licences of what ships", which runs cargo metadata --locked for every shipped crate's manifest and is green in host.log and in run 37757675374; the hand run's empty stderr (metadata-locked.err) predates the merge commit and recorded no exit
The lock's (name, version) pairs are the union of main's five pairs.sh <worktree> 6f87cdb9c: the pairs of Cargo.lock, kernel/, bootloader/, userland/ and toyos/Cargo.lock at 6f87cdb9c, sort -u, against the root lock's 692 against 692, diff exit 0 (pairs.out)
The folded kernel and loader are the control's bytes prove.sh 6f87cdb9c dd12c0b32 …, the round 3 script unchanged exit 0; all four control vs fold byte rows cmp exit 0; every row in "The checks" below (prove.out)
No new reader of a compiled-in path git diff -U0 e3bdff8af dd12c0b32 -- tests src toyos-blackbox toyos-symbols userland/symbolize, its added lines searched for \.rs, taken at, panicked at, Location, file(), PREVIOUS_PANIC, strip_prefix, src/, pure/ the merge touches five files there, all under tests/; 13 hits, of which 4 are diff headers and 9 the field info.rsdp; none reads a path. tests/common/power.rs:429 is still the one reader outside fixtures, and reads taken at kernel/src/hardlockup/probe.rs (readers-merge.diff, readers-hits.txt)
cargo run -- --ci host, once, on the development machine at dd12c0b32, cargo run -- --ci host > host.log 2>&1; echo EXIT=$? exit 0; the log ends [ci] Host: 77 step(s), all green; 1-minute load 26.60 when it started (host.log)

The logs are in the round's scratch directory (orch/oneworkspace-r4/), which a reader of this pull request cannot reach; prove.out and pairs.sh are in the round 4 comment.

What changed, per decision

The fold changed the kernel's source paths, and the proof did not see it

The T14's run of the whole metal profile at 88bcbf4d3 exited 1: 295 passed, 1 failed, 30 boots. The red row was hard_lockup_ends_a_deaf_cpu. Its judge looked for taken at src/hardlockup/probe.rs in the previous boot's panic record, and the readback's loader log says taken at kernel/src/hardlockup/probe.rs:145:29.

What changed in the kernel's strings. Cargo hands rustc a workspace member's source by its path from the workspace root, and rustc writes that path into every panic and Location. The kernel's root was kernel/; it is now the repository. So src/... became kernel/src/..., and a path dependency outside the old root, which the base named by the checkout's absolute path, is now named from the repository root (toyos-abi/src/...). Read from the actuator kernel staged at this head: 254 distinct .rs paths, 158 under kernel/, 38 under a toyos-* crate or bcachefs, none bare src/ or pure/, none naming the worktree.

Why the proof did not see it. Both of its oracles were blind to it by construction:

  • The byte row compared the fold against a control that is the base with its workspace root moved up. The control moved the root too, so it carries the same new paths and the bytes agree.
  • The rustc-lines row compared base against fold after a sed that rewrites (kernel/|bootloader/)?(src|pure)/x.rs and ROOT/<crate>/src/lib.rs to one form. That rewrite is needed, or every path crate's line differs and the row can show nothing else; but it absorbed the change without reporting it.

prove.sh now reports what that rewrite absorbs: per artifact, how many crates' source arguments were renamed, and a diff of the .rs paths the artifact carries, base against fold and control against fold. The script is in the round 3 comment and has run twice since, at 9ef866436 and at this head.

Every reader of a compiled-in path. I searched the harness, the guest tests, the build system, toyos-blackbox, toyos-symbols, userland/symbolize, the loader and the kernel's panic path for path literals, prefix strips and Location readers. One reader matches a compiled-in path by its prefix: tests/common/power.rs, the red row's judge, now fixed to the path the kernel records. Everything else is prefix-blind (panicked at, a file name with its line) or a synthetic fixture. The kernel's panic slot keeps the last 96 bytes of a path; the longest kernel path is 46, so nothing is cut. Userland's panic sites gain a userland/ prefix the same way; no test reads one.

The record rows. The judging asked to record three boot.testcases-bounds.* rows. They are not this change's: that boot was already staged on the base and unrecorded, and main recorded it in #745. They arrive with the merge and nothing is committed here.

What the fold changes in what is built

The lock row was measured at dd12c0b32 against 6f87cdb9c, the rustc row by prove.sh at the same pair; the two cargo tree rows at 88bcbf4d3, and were not taken again.

Measured Result
Lock: (name, version) pairs, the fold's against the union of origin/main's five identical, 692 pairs, diff exit 0
Lock: sources registry getrandom 0.2.17, 0.3.4, 0.4.2 are gone; the forks at the same versions remain
Kernel and loader, both arches: every rustc command line of cargo build -v, base against fold, path and cargo's path-derived hashes taken out identical, diff exit 0: 31 units per kernel, 55 and 37 per loader
Userland, both triples: cargo tree -e features over every program, base against fold identical, cmp exit 0
Host members: the same diff exit 1, on getrandom's source alone

So one resolved crate changes: the build system and the other host members compile the ToyOS forks of getrandom 0.2.17, 0.3.4 and 0.4.2 instead of the registry's, same versions, same features. And every source path compiled into the kernel and the loader changes, as above.

The checks (high-risk: build system)

Measured at dd12c0b32 against origin/main 6f87cdb9c by prove.sh (the script of the round 3 comment, unchanged), exit 0; its output is in the round 4 comment. Round 3 measured the same rows at 9ef866436 against b432ed21c, round 1 at 88bcbf4d3 against e7010129f.

Negative control. The whole change reverted is the base. A second control is the base with only its workspace root moved up, keeping the crate's own base lock and its profile. It is given the fold's root .cargo/config.toml, so the control does not hold the flags: the one row that does is base against fold on normalised rustc lines.

Oracle. Bytes and cargo's own command lines. Each cell is its own cmp or diff exit:

kernel x86_64 kernel AArch64 loader x86_64 loader AArch64
control vs fold, bytes 0 0 0 0
fold vs fold rebuilt, bytes 0 0 0 0
base vs fold, bytes 1 1 1 1
base vs fold, rustc lines normalised 0 0 0 0
control vs fold, rustc lines verbatim 0 0 0 0

What the normalisation absorbs, reported by the three paths rows: base against fold, cargo hands rustc another source path for 29 of 31 crates of each kernel and for 35 of 50 and 13 of 35 crates of the loaders (diff exit 1 each, as expected); the .rs paths the x86-64 kernel carries are 250 on both sides, of which the base has 39 under the tree's absolute path and 150 from the crate's own root and the fold none of either (diff exit 1); control against fold the artifacts' paths are identical (diff exit 0, all four).

Mutations, each
on a fresh copy of the fold: M1 (drop the [target.x86_64-unknown-uefi] table) loader build exit 101; M2 (lock dlmalloc at 0.2.12) cmp exit 1 and lines diff exit 1; M3 (select bcachefs beside the kernel in one cargo) kernel build exit 101.

Gates

The rows of the section "The merge of #749" were read at dd12c0b32. Every row below was read at 9ef866436 unless it says otherwise, each once, the narrowest that judges it. ci.yml runs on the push of dd12c0b32; its result is not in this body.

Gate Result
cargo run -- --ci host at dd12c0b32, development machine: exit 0, [ci] Host: 77 step(s), all green. Linux runner at 9ef866436: ci.yml run 37740454881 host success; cold inside --ci seal, nightly run 37740449787: [ci] Seal: 80 step(s), all green; on macOS, the same nightly's portability-macos: success
cargo test --lib ci::tests (the changed step's own test) exit 0, 13 passed
The images and the guest suite at 9ef866436, run 37740454881: toolchain / build and guest / suite success (KVM); run 37740449787: toolchain / build and tcg / suite success. At e3bdff8af, run 37755369755: host and toolchain / build success, guest / suite still running when read. Not run locally, and not read at dd12c0b32
prove.sh 6f87cdb9c dd12c0b32 … exit 0; every row as in the table above
cargo test inside kernel/loom exit 0
cargo test inside kernel/sim exit 0
Cold wall clock, x86-64 kernel and loader (wall.sh, one run) base, two cargos side by side: 24 s, 1-minute load 34.92 before it. Fold, one after the other: 20 s, load 42.23. Other agents' builds were running, so the two are not a controlled pair; the fold was not slower
Metal profile every row green at db55db96a (comment 6048782042). Since then the branch changed src/ci.rs and the root lock's two acpiserver edges; the kernel sources that moved are main's own landings (#747, #748, #749), merged in. Review round 2, ruling (3), owes no boot for the merge of #749 on two conditions, both met above
cargo test --manifest-path userland/acpiserver/aml/Cargo.toml at e3bdff8af exit 0
git status --porcelain --ignore-submodules=none at dd12c0b32 empty

issues/cargo-run-inside-kernel-loom-or-kernel-sim-builds-for-a-bare-target.md's close now stands on the two in-directory runs at 9ef866436.

The logs of these rows are files in the scratch directory of the round that took them (orch/oneworkspace-r3/), which a reader of this pull request cannot reach; the proof's and the measurements' outputs are in the round 3 comment.

CI

Why the sealed tree was larger than main's, measured. A workflow_dispatch of nightly.yml at 88bcbf4d3 (run 37685714260) sealed 9348536345 B in 20064 files, red. Units compiled per step, counted from that log and from main's nightly at b432ed21c (run 37717000719, sealed 18708 files, 7664839895 B):

step 88bcbf4d3 main
the driver's own build 203 203
the build system 207 207
the workspace's host members 99 99
clippy, warnings denied 412 417
the controls 56 56
userland/* 225 289
the apps for linux 282 47
the apps for macos 248 248
the apps for windows 239 239

Of the 256 distinct crates the apps-for-linux step compiled at 88bcbf4d3, 226 had been compiled by an earlier step of the same run; 30 by none. The cause is the target directory: the test steps built without --target into target/debug, the apps step with --target x86_64-unknown-linux-gnu into target/x86_64-unknown-linux-gnu. Profile, features and RUSTFLAGS are the same in both.

The fix, measured once on the development machine (share.sh in the round 3 comment; cold, a target of its own, aarch64-apple-darwin): after the fourteen test steps' builds (271 units), the ten apps with --target <host> compile 270 units and add 616,616 KiB under target/<host> and 135,064 KiB under target/debug; the same ten without --target then compile 47 units and add 107,856 KiB. The 47 are the same crates main's step compiles on the runner.

The seal at 9ef866436, nightly run 37740449787 (conclusion success: host, portability-linux, portability-macos, toolchain / build, tcg / suite):

the cache entry, read by content: none restored: the run is cold
the apps for linux: 10 app(s) pass `cargo build`; …
the tree, sealed as the host cache's entry: 17010 files, 7493968284 B of the 8000000000 B an entry may hold; sealed: 2496 sources, built on Linux X64 ubuntu24 20261004.327.1, every target dated as built
[ci] Seal: 80 step(s), all green

Units per step in its log, against the two columns above:

step 9ef866436 88bcbf4d3 main
userland/* 225 225 289
the apps for linux 42 282 47
the apps for macos 264 248 248
the apps for windows 240 239 239

Every other step compiles what it did at 88bcbf4d3. I expected 47 for the Linux apps: it is main's 47 less crc32fast, log, memchr, smallvec and toyos-keymap, which an earlier step had compiled. I did not expect the macOS step's 16 more: all are host-side units (syn, thiserror-impl, tokio-macros, futures-macro, autocfg and the like), which the Linux step's --target build used to compile for the host and which the first --target step now compiles instead. The four steps together compile 771 units against 994 at 88bcbf4d3 and 823 on main.

ci.yml run 37740454881 at 9ef866436: host, toolchain / build and guest / suite success.

After this lands every host check runs cold until the first nightly on main seals and saves: the path list is the cache's version.

Toolchain keys. The fold moves the sysroot key once: userland/.cargo/config.toml was one of its inputs and .cargo/config.toml replaces it. From now on a change to any guest triple's flags moves that key. The merges of #747 and #749 moved toyos-abi and toyos, so the sysroot key moved with main; the key at this head was not read here.

No new gate, test or dependency

No guest test is added or changed. No dependency is added. The proof is a one-off script because its subject is this one change against its base.

Size

git diff --shortstat origin/main...HEAD at dd12c0b32: 53 files, +5454 −7765. Without the locks: 48 files, +446 −704. src/, tests/toyos.rs and tests/common/: 12 files, +237 −360, of which tests are roughly +65 −115 by my reading of the hunks (an estimate, not a count). issues/: 16 files, +49 −115.

What I am unsure of

🤖 Generated with Claude Code

https://claude.ai/code/session_01RvnWQFcMuGqTHYhvSnTe8A

Japabu and others added 2 commits October 7, 2026 18:32
…and join the root's

The root, kernel/, bootloader/, userland/ and toyos/ were five Cargo
resolutions with five locks and three copies of [profile.toyos]. They are
one workspace now: the root [workspace] names every crate but rust/, the
guest test programs, the SSH judge and userland/libc, the root takes
userland's [patch] table and the one [profile.toyos], and the root
.cargo/config.toml is tracked with one [target.<triple>] table per guest
triple in place of three per-directory build.target configs. Four locks,
three rust-toolchain.toml and userland's virtual manifest are gone.

The lock is every package of the five, resolved: its name and version
pairs are their union. The registry getrandom 0.2.17, 0.3.4 and 0.4.2 the
root alone resolved give way to the forks at the same versions, which the
root [patch] now names for every member.

The build system builds every guest at the root with -p into the one
target/. What went with the several workspaces: cargo clean of a crate's
target (a stale sysroot now takes target/toyos and the guest triples'
directories, never the build system's own), the kernel and the loader
built on two threads (cargo holds one lock on a target directory, measured:
"Blocking waiting for file lock on artifact directory"), the kernel's
manifest-path and target-dir on the host, the per-directory clippy runs,
and four of the host cache's five target paths. src/hostws.rs says which
members a host tests: all but the kernel, the loader, the SDK and
userland's, which keep the steps they had.

A fork clone under edit is listed in .cargo/local.toml, which the tracked
config includes when it exists.

What the fold changes of a kernel or a loader is the workspace root and
nothing else: both are byte-identical, on both architectures, to a control
that is the base with only its workspace root moved up, built at one path,
and every rustc command line cargo runs for them is the base's once the
tree's path and cargo's path-derived hashes are taken out. They are not
byte-identical to the base's own build, and could not be: cargo hashes a
path package's path relative to the workspace root into -C metadata, and
the base built at a second path differs from itself.

cargo test inside kernel/loom and kernel/sim now builds for the host, so
that issue closes; the SDK turned out to be linted by no clippy run, which
is filed.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RvnWQFcMuGqTHYhvSnTe8A
#739 added userland/acpiserver/aml to userland's member list and its three
path packages to userland's lock, both of which this branch deletes. The
member joins the root list as userland/acpiserver/aml; the root lock gains
toyos-aml, and already held toyos-acpi and toyos-bootmap. Its name and
version pairs are again the union of main's five locks.

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

Japabu commented Oct 7, 2026

Copy link
Copy Markdown
Collaborator Author

The proof the body cites, as run (its two absolute paths made arguments for posting). Exit 0 at 88bcbf4d3 against e7010129f.

#!/bin/sh
# The one-workspace fold's proof, run by hand and not part of the tree.
#
#   prove.sh <base commit> <fold commit> <sysroot directory> <image key hex> <scratch directory> <worktree>
#
# Every arrangement is built at ONE absolute path, $P, from `git archive`:
#   A   the base, untouched: kernel/ and bootloader/ are their own roots.
#   C   the base with only the workspace root moved up: the crate's own base
#       lock, its profile, and the base's flags in a root .cargo/config.toml.
#   B   the fold. B2 is B built again from nothing.
#   M1  B without the [target.x86_64-unknown-uefi] table.
#   M2  B with dlmalloc 0.2.13 locked at 0.2.12.
#   M3  B's kernel built in one cargo with bcachefs selected beside it.
# It prints one line per comparison with the exit code of its cmp or diff.
set -u
BASE=$1; FOLD=$2; export RUSTUP_TOOLCHAIN=$3; export TOYOS_IMAGE_KEY=$4
export TOYOS_IMAGE_FLOOR=image
unset RUSTFLAGS RUSTC CARGO_TARGET_DIR
S=$5   # a scratch directory
W=$6   # the worktree
O=$S/proof; P=$S/proof-tree
rm -rf $O $P; mkdir -p $O
KT="x86_64-unknown-none aarch64-unknown-none-softfloat"
LT="x86_64-unknown-uefi aarch64-unknown-uefi"
PROFILE='
[profile.toyos]
inherits = "dev"
opt-level = 2
debug = true
strip = "debuginfo"
debug-assertions = true
overflow-checks = true
'
tree() { rm -rf $P; mkdir -p $P; git -C $W archive $1 | tar -x -C $P; }
# build <tag> <directory under $P> <artifact> <target> <cargo args...>
build() {
  tag=$1; dir=$2; art=$3; t=$4; shift 4
  (cd $P/$dir && cargo build -v --profile toyos --target $t "$@" > $O/$tag-$t.log 2>&1)
  code=$?
  echo "build $tag $t exit $code"
  [ $code -eq 0 ] && cp $art $O/$tag-$t.bin
  return $code
}
# The base's flags, as the fold's root config states them per triple.
config() { mkdir -p $P/.cargo; git -C $W show $FOLD:.cargo/config.toml > $P/.cargo/config.toml; }
moved() { # the crate whose root moves
  tree $BASE
  cp $P/$1/Cargo.lock $P/Cargo.lock
  rm -rf $P/kernel/Cargo.lock $P/bootloader/Cargo.lock $P/kernel/.cargo $P/bootloader/.cargo $P/userland/.cargo \
         $P/kernel/rust-toolchain.toml $P/bootloader/rust-toolchain.toml
  perl -0pi -e 's|\[profile\.toyos\].*?overflow-checks = true\n||s' $P/kernel/Cargo.toml $P/bootloader/Cargo.toml
  printf '[workspace]\nresolver = "2"\nmembers = ["%s"]\nexclude = ["userland", "toyos", "tests", "rust"]\n%s' $1 "$PROFILE" > $P/Cargo.toml
  config
}

tree $BASE
for t in $KT; do build A-kernel kernel $P/kernel/target/$t/toyos/kernel $t; done
for t in $LT; do build A-loader bootloader $P/bootloader/target/$t/toyos/bootloader.efi $t; done
moved kernel
for t in $KT; do build C-kernel . $P/target/$t/toyos/kernel $t -p kernel; done
moved bootloader
for t in $LT; do build C-loader . $P/target/$t/toyos/bootloader.efi $t -p bootloader; done
for b in B B2; do
  tree $FOLD
  for t in $KT; do build $b-kernel . $P/target/$t/toyos/kernel $t -p kernel; done
  for t in $LT; do build $b-loader . $P/target/$t/toyos/bootloader.efi $t -p bootloader; done
done

# Every rustc cargo ran, with the tree's path and cargo's path-derived hashes
# taken out, and each path package's source named from the repository root.
lines() {
  grep -E '^\s+Running `' $1 | sed -E "s#$P#ROOT#g; s#ROOT/(kernel|bootloader)/target#ROOT/target#g; \
    s#-C metadata=[0-9a-f]+#-C metadata=H#g; s#-C extra-filename=-[0-9a-f]+#-C extra-filename=-H#g; \
    s#-[0-9a-f]{16}([./ \`])#-H\1#g; s#(cd|CARGO_MANIFEST_PATH|CARGO_MANIFEST_DIR)[= ][^ ]+ ##g; \
    s# (ROOT/)?(kernel/|bootloader/)?((src|pure)/[a-z]+\.rs) # \3 #; s# ROOT/([a-z0-9-]+(/[a-z]+)?/src/lib\.rs) # \1 #; \
    s# (kernel/)?((dma|gicv3|pci|ps2)/src/lib\.rs) # kernel/\2 #" | sort
}
for a in kernel loader; do
  [ $a = kernel ] && ts=$KT || ts=$LT
  for t in $ts; do
    cmp -s $O/C-$a-$t.bin $O/B-$a-$t.bin; echo "bytes   control vs fold        $a $t: cmp exit $? ($(shasum -a 256 < $O/B-$a-$t.bin | cut -c1-16))"
    cmp -s $O/B-$a-$t.bin $O/B2-$a-$t.bin; echo "bytes   fold vs fold rebuilt   $a $t: cmp exit $?"
    cmp -s $O/A-$a-$t.bin $O/B-$a-$t.bin; echo "bytes   base vs fold           $a $t: cmp exit $?"
    lines $O/A-$a-$t.log > $O/a.lines; lines $O/C-$a-$t.log > $O/c.lines; lines $O/B-$a-$t.log > $O/b.lines
    diff $O/a.lines $O/b.lines > /dev/null; echo "rustc   base vs fold, normalised $a $t: diff exit $? ($(wc -l < $O/b.lines | tr -d ' ') units)"
    grep -E '^\s+Running `' $O/C-$a-$t.log | sort > $O/c.raw; grep -E '^\s+Running `' $O/B-$a-$t.log | sort > $O/b.raw
    diff $O/c.raw $O/b.raw > /dev/null; echo "rustc   control vs fold, verbatim $a $t: diff exit $?"
  done
done

# The mutations: each a fresh fold tree, so nothing is left to restore.
tree $FOLD
perl -0pi -e 's|\[target\.x86_64-unknown-uefi\]\nrustflags = [^\n]*\n||' $P/.cargo/config.toml
t=x86_64-unknown-uefi
if build M1-loader . $P/target/$t/toyos/bootloader.efi $t -p bootloader; then
  cmp -s $O/B-loader-$t.bin $O/M1-loader-$t.bin; echo "M1 no uefi table: loader $t cmp exit $?"
  lines $O/B-loader-$t.log > $O/b.lines; lines $O/M1-loader-$t.log > $O/m.lines
  diff $O/b.lines $O/m.lines > /dev/null; echo "M1 no uefi table: rustc lines diff exit $? ($(wc -l < $O/m.lines | tr -d ' ') units against $(wc -l < $O/b.lines | tr -d ' '))"
fi
t=x86_64-unknown-none
tree $FOLD
(cd $P && cargo update dlmalloc@0.2.13 --precise 0.2.12 > $O/M2-update.log 2>&1; echo "M2 cargo update exit $?")
if build M2-kernel . $P/target/$t/toyos/kernel $t -p kernel; then
  cmp -s $O/B-kernel-$t.bin $O/M2-kernel-$t.bin; echo "M2 dlmalloc 0.2.12: kernel $t cmp exit $?"
  lines $O/B-kernel-$t.log > $O/b.lines; lines $O/M2-kernel-$t.log > $O/m.lines
  diff $O/b.lines $O/m.lines > /dev/null; echo "M2 dlmalloc 0.2.12: rustc lines diff exit $?"
fi
tree $FOLD
if build M3-kernel . $P/target/$t/toyos/kernel $t -p kernel -p bcachefs; then
  cmp -s $O/B-kernel-$t.bin $O/M3-kernel-$t.bin; echo "M3 bcachefs selected beside the kernel: kernel $t cmp exit $?"
  lines $O/B-kernel-$t.log > $O/b.lines; lines $O/M3-kernel-$t.log > $O/m.lines
  diff $O/b.lines $O/m.lines > /dev/null; echo "M3 bcachefs selected beside the kernel: rustc lines diff exit $?"
fi
rm -rf $P $O/*.lines $O/*.raw
echo DONE

Its output:

build A-kernel x86_64-unknown-none exit 0
build A-kernel aarch64-unknown-none-softfloat exit 0
build A-loader x86_64-unknown-uefi exit 0
build A-loader aarch64-unknown-uefi exit 0
build C-kernel x86_64-unknown-none exit 0
build C-kernel aarch64-unknown-none-softfloat exit 0
build C-loader x86_64-unknown-uefi exit 0
build C-loader aarch64-unknown-uefi exit 0
build B-kernel x86_64-unknown-none exit 0
build B-kernel aarch64-unknown-none-softfloat exit 0
build B-loader x86_64-unknown-uefi exit 0
build B-loader aarch64-unknown-uefi exit 0
build B2-kernel x86_64-unknown-none exit 0
build B2-kernel aarch64-unknown-none-softfloat exit 0
build B2-loader x86_64-unknown-uefi exit 0
build B2-loader aarch64-unknown-uefi exit 0
bytes   control vs fold        kernel x86_64-unknown-none: cmp exit 0 (71b01b3129216762)
bytes   fold vs fold rebuilt   kernel x86_64-unknown-none: cmp exit 0
bytes   base vs fold           kernel x86_64-unknown-none: cmp exit 1
rustc   base vs fold, normalised kernel x86_64-unknown-none: diff exit 0 (31 units)
rustc   control vs fold, verbatim kernel x86_64-unknown-none: diff exit 0
bytes   control vs fold        kernel aarch64-unknown-none-softfloat: cmp exit 0 (9c955093fd0b0697)
bytes   fold vs fold rebuilt   kernel aarch64-unknown-none-softfloat: cmp exit 0
bytes   base vs fold           kernel aarch64-unknown-none-softfloat: cmp exit 1
rustc   base vs fold, normalised kernel aarch64-unknown-none-softfloat: diff exit 0 (31 units)
rustc   control vs fold, verbatim kernel aarch64-unknown-none-softfloat: diff exit 0
bytes   control vs fold        loader x86_64-unknown-uefi: cmp exit 0 (295fdff45cd5a2f3)
bytes   fold vs fold rebuilt   loader x86_64-unknown-uefi: cmp exit 0
bytes   base vs fold           loader x86_64-unknown-uefi: cmp exit 1
rustc   base vs fold, normalised loader x86_64-unknown-uefi: diff exit 0 (55 units)
rustc   control vs fold, verbatim loader x86_64-unknown-uefi: diff exit 0
bytes   control vs fold        loader aarch64-unknown-uefi: cmp exit 0 (7dabdcb6e32c68a7)
bytes   fold vs fold rebuilt   loader aarch64-unknown-uefi: cmp exit 0
bytes   base vs fold           loader aarch64-unknown-uefi: cmp exit 1
rustc   base vs fold, normalised loader aarch64-unknown-uefi: diff exit 0 (37 units)
rustc   control vs fold, verbatim loader aarch64-unknown-uefi: diff exit 0
build M1-loader x86_64-unknown-uefi exit 101
M2 cargo update exit 0
build M2-kernel x86_64-unknown-none exit 0
M2 dlmalloc 0.2.12: kernel x86_64-unknown-none cmp exit 1
M2 dlmalloc 0.2.12: rustc lines diff exit 1
build M3-kernel x86_64-unknown-none exit 101
DONE
EXIT=0

@Japabu

Japabu commented Oct 7, 2026

Copy link
Copy Markdown
Collaborator Author

Review of 88bcbf4d3 against origin/main e7010129f, round 1. Read only: nothing built, nothing run in the worktree.

Net lines (git diff --shortstat origin/main...88bcbf4d3): 51 files, +5494 −7728. Locks +5017 −7066; src/ and tests/toyos.rs +222 −351 (production and its tests together, the test share by the body's estimate about +65 −115); issues +95 −82; manifests, configs, workflows and prompts +160 −229. Production shrinks; no deletion is owed.

BLOCKER

  • Evidence, hardware — the metal profile's result at 88bcbf4d3 is not on the pull request — the change decides every byte the test machine boots, and QEMU is not that machine. It must show: the command, its exit code and the log; every row of the profile green on images built by the folded build at this head; no row's timing or audio verdict moved outside its recorded bound; and the kernel and loader it flashed are the ones target/<triple>/toyos/ holds, not a leftover kernel/target or bootloader/target of the same checkout.
  • Evidence, CI — the body's claims about CI rest on no run (the pull request is a draft and all three checks are skipped) — it edits both workflows' cache paths and one cache key's inputs. The run must show: host on the Linux runner green inside its 45 minutes with the line the cache entry, read by content: none restored: the run is cold; toolchain restoring the freestanding and compiler layers under unchanged keys and building one new sysroot under the moved key; guest / suite green under KVM on that sysroot; and the merge queue's host, cold again, green. Main's nightly cold host took 13 to 20 minutes over its last four runs, so the cold run fits the timeout.
  • Evidence, another head — issues/cargo-run-inside-kernel-loom-or-kernel-sim-builds-for-a-bare-target.md is closed on cargo test inside kernel/loom and kernel/sim, listed under "Gates, at 88bcbf4d3" — both logs were written at 18:28, before e0dccfdae (18:32) and the merge that made this head (18:41). Rerun both at the landing head and post command, exit and log; the close stands on that.
  • Evidence, the next head — std's ToyOS backend lives in sdk/std, and the fork names it by #[path] #745 will be merged into this branch, which makes a new head — every gate in the body's table is then from another head. Rerun --ci host, both --build-only, the guest suite and prove.sh there. See "The std's ToyOS backend lives in sdk/std, and the fork names it by #[path] #745 merge" below.

NOTE

  • .github/workflows/nightly.yml:22, src/cicache.rs:61 — "runs cold until nightly's host saves the next one" has no measurement behind it, and main's writer does not save today — nightly run 37601225884 (and the two before it) ends 8182940473 B in 17350 files under the cache's paths, above the 8000000000 B an entry may hold, so no entry has been written since 2026-10-04. Whether the folded tree seals under the limit is unknown; one workflow_dispatch of nightly.yml on this branch prints the seal's byte count (the save is guarded to main). Put the number in the body, or say the cold period is open-ended.
  • issues/the-sdk-is-linted-by-no-clippy-run.md — no owner — root CLAUDE.md asks ownership of a recorded compromise. The gap itself predates the branch (the base linted toyos in no shape either), and filing rather than fixing toyos/src here is right: each fix moves a sysroot.
  • .cargo/config.toml:46-50, src/build.rs:2118,2202 — the tracked root config now gives -Dwarnings to guest crates outside the workspace built from their own directory for a ToyOS triple (tests/toyos-rust-tests and its tls-* crates), which took no flags on a checkout without a local config; and not to the one build at src/build.rs:2139-2141 that sets RUSTFLAGS, which replaces the table. The body says only that a host build takes none. State it.
  • Cargo.toml [profile.dev] — the kernel library's host tests, its model controls, the SDK's tests and every surveyed userland crate's host tests now run at opt-level = 2; on the base each resolved in its own workspace and ran at 0. The controls still reach their verdicts (final2/host.log). The body does not say it.
  • issues/the-tree-resolves-in-five-cargo-locks-not-one.md, "What stays apart" — the reason given for userland/libc (a panic = "abort" profile cargo ignores in a member) is one a named root profile answers; the reason that holds is the one only Cargo.toml's comment gives, that its lock is a sysroot-key input and the root lock would move that key on every dependency change. Its lock is a sixth resolution of toyos, toyos-abi, toyos-elf and dlmalloc that nothing holds to the root's (both carry dlmalloc 0.2.13 today). Record that in the issue before its close deletes the only account of it.
  • src/build.rs:1777-1779 — kernel and loader now build one after the other and the cold wall clock against the base is unmeasured; the body says so. Measure once and put the number in the body.
  • Body, "Negative control" — the control is described as carrying the base's flags and "nothing else of this branch"; prove.sh's config() gives it the fold's .cargo/config.toml. The flags are therefore held by one row only, base against fold on normalised rustc lines. Correct the sentence.
  • Body, gates — the host and guest logs are on no record a reader of the pull request can reach; I read them in the round's scratch directory at this head (77 steps green; 30 of 30).
  • For the orchestrator at landing: a checkout holding an untracked .cargo/config.toml refuses the merge until it is moved to .cargo/local.toml; every existing worktree keeps orphaned kernel/target, bootloader/target, userland/target and toyos/target; dispatch the nightly once main has this.

What was asked to be judged

Whether the proof shows what the old exit was for. It does, for the kernel and the loader. Version: I recomputed the lock independently from git — 692 (name, version) pairs at head, identical to the union of main's five, and three source changes, the registry getrandom 0.2.17, 0.3.4 and 0.4.2, none in the kernel's or loader's graph. Feature and flag: the one lock's edges are a superset (the loader's curve25519-dalek, ed25519-dalek, digest and signature gain zeroize, rand_core, serde and pkcs8 edges other members enable), so the lock cannot show the loader takes none of them; the normalised rustc rows do, at 31, 31, 55 and 37 units with every --cfg feature, rustflag and source path on the line. I read the normalisation: it rewrites paths, -C metadata, -C extra-filename and 16-hex suffixes, and no flag, --cfg or version. The byte rows add that lock, profile and membership move nothing.

Whether the control and the mutations can fail. M2 turns both oracles red (cmp 1, lines diff 1), so each can. M1 and M3 red by failing to build, which shows the table and the lone -p are load-bearing, not that a comparison catches them; a flag change that still builds is caught by the lines row, which a reader of the sed can check, so no further mutation is asked. After landing nothing re-runs this; what holds M3's defect out is build_kernel and the loader's call naming one package each, which is readable.

Userland is shown weaker — cargo tree -e features per triple, no command lines, no bytes — and that is enough: its flags and profile are textually the base's, and the guest suite is green.

CI. The path lists in both workflows equal PATHS; no rule of the cache or workflow sections is broken by the diff. The sysroot key moving once is correct and now over-wide by design (any guest triple's flags move it); the freestanding and compiler layers need no new input, since bootstrap passes its flags by CARGO_ENCODED_RUSTFLAGS, which replaces a config's tables.

The tracked config and implementer.md. The line changed is the one step the change renames, and no other prompt names it. The include was measured with target-dir, not with the [patch] the prompt has agents write there; cargo documents the same precedence for both.

Beyond the brief. The eleven citation edits are owed by deleting what they cited; the issue close is right on reading (its cause, kernel/.cargo/config.toml, is gone and the root config sets no build.target) and waits only on the rerun above; the filed issue is in order but for its owner.

The #745 merge

src/sysroot.rs must keep both sides: SYSROOT_SOURCES at seven entries with "sdk/std", and SYSROOT_MANIFESTS ending in ".cargo/config.toml", never "userland/.cargo/config.toml", which no longer exists and would key every sysroot on a missing file. In the test near line 1222 both loops survive: ["toyos/src", "sdk/std", "userland/libc/src"] and ["userland/libc/Cargo.toml", "userland/libc/Cargo.lock", ".cargo/config.toml"]. issues/toyos-has-its-own-allocator.md is edited by both, in different paragraphs: keep #745's sdk/std/sys/alloc.rs and this branch's "from the kernel's graph in Cargo.lock". #745 moves the rust gitlink, so the compiler and sysroot keys move with it and the body's key figures must be restated at the merged head.

SEND BACK

@Japabu

Japabu commented Oct 7, 2026

Copy link
Copy Markdown
Collaborator Author

The whole metal profile at 88bcbf4d3, run by the orchestrator from the clean worktree (cargo test --test toyos-build -- --metal): EXIT=1, [metal] 295 passed, 1 failed, 30 boot(s), 2647 s.

The one red row is hard_lockup_ends_a_deaf_cpu: "taken at src/hardlockup/probe.rs" never reached the hardlockup's loader pass after the reset after "Previous boot's panic:". The row reads a source path out of the kernel's panic record; whether the folded build now names that file by another path is for the fix round to read from the readback before changing anything. Every other row is green on images built by the folded build.

Japabu and others added 2 commits October 7, 2026 23:54
src/sysroot.rs keeps both sides: SYSROOT_SOURCES carries "sdk/std" and
SYSROOT_MANIFESTS ends in ".cargo/config.toml". #745 moved no manifest and
no lock, so the root lock stands as it was: `cargo metadata --locked` exits 0.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RvnWQFcMuGqTHYhvSnTe8A
…the repository root, and two issues say who owns them and why libc stays apart

The fold moved the workspace root, and cargo hands rustc a member's source by
its path from that root: the kernel's compiled-in source paths went from
`src/...` to `kernel/src/...`. The T14's run of the metal profile at
88bcbf4 was red in one row for it, `hard_lockup_ends_a_deaf_cpu`, whose
judge looked for `taken at src/hardlockup/probe.rs` in the previous boot's
panic record and was given `taken at kernel/src/hardlockup/probe.rs:145:29`.
It is the one reader in the tree that matches a compiled-in path by its
prefix; the judge now names the path the kernel records.

The stage's issue records that the root's move changes those paths, and gives
the reason `userland/libc` keeps its own lock that holds: the lock is an input
of the sysroot key. The SDK's clippy issue names its owner.

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

Japabu commented Oct 7, 2026

Copy link
Copy Markdown
Collaborator Author

Round 2 scripts, at db55db96a. Neither has been run: the development machine was reserved before they could be. prove.sh is round 1's with three paths rows added, which report the source-path change its normalisation absorbs, and with its description of the control corrected. wall.sh is the cold wall clock of the kernel and loader builds, the base side by side against the fold one after the other.

prove.sh <base commit> <fold commit> <sysroot directory> <image key hex> <scratch directory> <worktree>

#!/bin/sh
# The one-workspace fold's proof, run by hand and not part of the tree.
#
#   prove.sh <base commit> <fold commit> <sysroot directory> <image key hex> <scratch directory> <worktree>
#
# Every arrangement is built at ONE absolute path, $P, from `git archive`:
#   A   the base, untouched: kernel/ and bootloader/ are their own roots.
#   C   the base with only the workspace root moved up: the crate's own base
#       lock, its profile, and the fold's root .cargo/config.toml, which is
#       where its flags come from: the control does not hold the flags, the
#       normalised rustc row does.
#   B   the fold. B2 is B built again from nothing.
#   M1  B without the [target.x86_64-unknown-uefi] table.
#   M2  B with dlmalloc 0.2.13 locked at 0.2.12.
#   M3  B's kernel built in one cargo with bcachefs selected beside it.
# It prints one line per comparison with the exit code of its cmp or diff.
set -u
BASE=$1; FOLD=$2; export RUSTUP_TOOLCHAIN=$3; export TOYOS_IMAGE_KEY=$4
export TOYOS_IMAGE_FLOOR=image
unset RUSTFLAGS RUSTC CARGO_TARGET_DIR
S=$5   # a scratch directory
W=$6   # the worktree
O=$S/proof; P=$S/proof-tree
rm -rf $O $P; mkdir -p $O
KT="x86_64-unknown-none aarch64-unknown-none-softfloat"
LT="x86_64-unknown-uefi aarch64-unknown-uefi"
PROFILE='
[profile.toyos]
inherits = "dev"
opt-level = 2
debug = true
strip = "debuginfo"
debug-assertions = true
overflow-checks = true
'
tree() { rm -rf $P; mkdir -p $P; git -C $W archive $1 | tar -x -C $P; }
# build <tag> <directory under $P> <artifact> <target> <cargo args...>
build() {
  tag=$1; dir=$2; art=$3; t=$4; shift 4
  (cd $P/$dir && cargo build -v --profile toyos --target $t "$@" > $O/$tag-$t.log 2>&1)
  code=$?
  echo "build $tag $t exit $code"
  [ $code -eq 0 ] && cp $art $O/$tag-$t.bin
  return $code
}
# The base's flags, as the fold's root config states them per triple.
config() { mkdir -p $P/.cargo; git -C $W show $FOLD:.cargo/config.toml > $P/.cargo/config.toml; }
moved() { # the crate whose root moves
  tree $BASE
  cp $P/$1/Cargo.lock $P/Cargo.lock
  rm -rf $P/kernel/Cargo.lock $P/bootloader/Cargo.lock $P/kernel/.cargo $P/bootloader/.cargo $P/userland/.cargo \
         $P/kernel/rust-toolchain.toml $P/bootloader/rust-toolchain.toml
  perl -0pi -e 's|\[profile\.toyos\].*?overflow-checks = true\n||s' $P/kernel/Cargo.toml $P/bootloader/Cargo.toml
  printf '[workspace]\nresolver = "2"\nmembers = ["%s"]\nexclude = ["userland", "toyos", "tests", "rust"]\n%s' $1 "$PROFILE" > $P/Cargo.toml
  config
}

tree $BASE
for t in $KT; do build A-kernel kernel $P/kernel/target/$t/toyos/kernel $t; done
for t in $LT; do build A-loader bootloader $P/bootloader/target/$t/toyos/bootloader.efi $t; done
moved kernel
for t in $KT; do build C-kernel . $P/target/$t/toyos/kernel $t -p kernel; done
moved bootloader
for t in $LT; do build C-loader . $P/target/$t/toyos/bootloader.efi $t -p bootloader; done
for b in B B2; do
  tree $FOLD
  for t in $KT; do build $b-kernel . $P/target/$t/toyos/kernel $t -p kernel; done
  for t in $LT; do build $b-loader . $P/target/$t/toyos/bootloader.efi $t -p bootloader; done
done

# Every rustc cargo ran, with the tree's path and cargo's path-derived hashes
# taken out, and each path package's source named from the repository root.
lines() {
  grep -E '^\s+Running `' $1 | sed -E "s#$P#ROOT#g; s#ROOT/(kernel|bootloader)/target#ROOT/target#g; \
    s#-C metadata=[0-9a-f]+#-C metadata=H#g; s#-C extra-filename=-[0-9a-f]+#-C extra-filename=-H#g; \
    s#-[0-9a-f]{16}([./ \`])#-H\1#g; s#(cd|CARGO_MANIFEST_PATH|CARGO_MANIFEST_DIR)[= ][^ ]+ ##g; \
    s# (ROOT/)?(kernel/|bootloader/)?((src|pure)/[a-z]+\.rs) # \3 #; s# ROOT/([a-z0-9-]+(/[a-z]+)?/src/lib\.rs) # \1 #; \
    s# (kernel/)?((dma|gicv3|pci|ps2)/src/lib\.rs) # kernel/\2 #" | sort
}
for a in kernel loader; do
  [ $a = kernel ] && ts=$KT || ts=$LT
  for t in $ts; do
    cmp -s $O/C-$a-$t.bin $O/B-$a-$t.bin; echo "bytes   control vs fold        $a $t: cmp exit $? ($(shasum -a 256 < $O/B-$a-$t.bin | cut -c1-16))"
    cmp -s $O/B-$a-$t.bin $O/B2-$a-$t.bin; echo "bytes   fold vs fold rebuilt   $a $t: cmp exit $?"
    cmp -s $O/A-$a-$t.bin $O/B-$a-$t.bin; echo "bytes   base vs fold           $a $t: cmp exit $?"
    lines $O/A-$a-$t.log > $O/a.lines; lines $O/C-$a-$t.log > $O/c.lines; lines $O/B-$a-$t.log > $O/b.lines
    diff $O/a.lines $O/b.lines > /dev/null; echo "rustc   base vs fold, normalised $a $t: diff exit $? ($(wc -l < $O/b.lines | tr -d ' ') units)"
    grep -E '^\s+Running `' $O/C-$a-$t.log | sort > $O/c.raw; grep -E '^\s+Running `' $O/B-$a-$t.log | sort > $O/b.raw
    diff $O/c.raw $O/b.raw > /dev/null; echo "rustc   control vs fold, verbatim $a $t: diff exit $?"
  done
done

# What the normalisation above takes out, reported instead of hidden: the
# source path cargo hands rustc for each crate, and the source paths the
# artifact carries. `lines` has to rewrite the first, or every path crate's
# line would differ by the root's move and the row could show nothing else;
# these two rows say what that rewrite absorbed. Both are expected to differ.
srcs() { grep -E '^\s+Running `' $1 | sed -E "s#$P#ROOT#g" | sed -nE 's#.*rustc --crate-name ([a-z0-9_]+) (--edition=[0-9]+ )?([^ ]+\.rs) .*#\1 \3#p' | sort -u; }
named() { strings -a $1 | grep -oE '[A-Za-z0-9_./~-]+\.rs' | sed -E "s#^$P/#ROOT/#; s#^$HOME/#~/#" | sort -u; }
for a in kernel loader; do
  [ $a = kernel ] && ts=$KT || ts=$LT
  for t in $ts; do
    srcs $O/A-$a-$t.log > $O/A-$a-$t.srcs; srcs $O/B-$a-$t.log > $O/B-$a-$t.srcs
    diff $O/A-$a-$t.srcs $O/B-$a-$t.srcs > /dev/null
    echo "paths   base vs fold, rustc's source argument $a $t: diff exit $? ($(join $O/A-$a-$t.srcs $O/B-$a-$t.srcs | awk '$2 != $3' | wc -l | tr -d ' ') of $(wc -l < $O/B-$a-$t.srcs | tr -d ' ') crates renamed)"
    named $O/A-$a-$t.bin > $O/A-$a-$t.named; named $O/B-$a-$t.bin > $O/B-$a-$t.named
    diff $O/A-$a-$t.named $O/B-$a-$t.named > /dev/null
    echo "paths   base vs fold, .rs paths in the artifact $a $t: diff exit $? (base $(wc -l < $O/A-$a-$t.named | tr -d ' ') paths, $(grep -c '^ROOT/' $O/A-$a-$t.named) under the tree's absolute path, $(grep -c '^src/\|^pure/' $O/A-$a-$t.named) from the crate's own root; fold $(wc -l < $O/B-$a-$t.named | tr -d ' '), $(grep -c '^ROOT/' $O/B-$a-$t.named), $(grep -c '^src/\|^pure/' $O/B-$a-$t.named))"
    named $O/C-$a-$t.bin | diff - $O/B-$a-$t.named > /dev/null; echo "paths   control vs fold, .rs paths in the artifact $a $t: diff exit $?"
  done
done

# The mutations: each a fresh fold tree, so nothing is left to restore.
tree $FOLD
perl -0pi -e 's|\[target\.x86_64-unknown-uefi\]\nrustflags = [^\n]*\n||' $P/.cargo/config.toml
t=x86_64-unknown-uefi
if build M1-loader . $P/target/$t/toyos/bootloader.efi $t -p bootloader; then
  cmp -s $O/B-loader-$t.bin $O/M1-loader-$t.bin; echo "M1 no uefi table: loader $t cmp exit $?"
  lines $O/B-loader-$t.log > $O/b.lines; lines $O/M1-loader-$t.log > $O/m.lines
  diff $O/b.lines $O/m.lines > /dev/null; echo "M1 no uefi table: rustc lines diff exit $? ($(wc -l < $O/m.lines | tr -d ' ') units against $(wc -l < $O/b.lines | tr -d ' '))"
fi
t=x86_64-unknown-none
tree $FOLD
(cd $P && cargo update dlmalloc@0.2.13 --precise 0.2.12 > $O/M2-update.log 2>&1; echo "M2 cargo update exit $?")
if build M2-kernel . $P/target/$t/toyos/kernel $t -p kernel; then
  cmp -s $O/B-kernel-$t.bin $O/M2-kernel-$t.bin; echo "M2 dlmalloc 0.2.12: kernel $t cmp exit $?"
  lines $O/B-kernel-$t.log > $O/b.lines; lines $O/M2-kernel-$t.log > $O/m.lines
  diff $O/b.lines $O/m.lines > /dev/null; echo "M2 dlmalloc 0.2.12: rustc lines diff exit $?"
fi
tree $FOLD
if build M3-kernel . $P/target/$t/toyos/kernel $t -p kernel -p bcachefs; then
  cmp -s $O/B-kernel-$t.bin $O/M3-kernel-$t.bin; echo "M3 bcachefs selected beside the kernel: kernel $t cmp exit $?"
  lines $O/B-kernel-$t.log > $O/b.lines; lines $O/M3-kernel-$t.log > $O/m.lines
  diff $O/b.lines $O/m.lines > /dev/null; echo "M3 bcachefs selected beside the kernel: rustc lines diff exit $?"
fi
rm -rf $P $O/*.lines $O/*.raw
echo DONE

wall.sh, same arguments

#!/bin/sh
# One-off: the cold wall clock of the kernel's and the loader's x86_64 builds,
# the base's two cargos side by side against the fold's one after the other.
#   wall.sh <base commit> <fold commit> <sysroot directory> <image key hex> <scratch directory> <worktree>
set -u
BASE=$1; FOLD=$2; export RUSTUP_TOOLCHAIN=$3; export TOYOS_IMAGE_KEY=$4
export TOYOS_IMAGE_FLOOR=image
unset RUSTFLAGS RUSTC CARGO_TARGET_DIR
S=$5; W=$6; P=$S/wall-tree; O=$S/wall; rm -rf $P $O; mkdir -p $O
tree() { rm -rf $P; mkdir -p $P; git -C $W archive $1 | tar -x -C $P; }
tree $BASE
echo "load before base: $(uptime | sed 's/.*load averages: //')"
t0=$(date +%s)
(cd $P/kernel && cargo build --profile toyos --target x86_64-unknown-none > $O/base-kernel.log 2>&1; echo "base kernel exit $?") &
(cd $P/bootloader && cargo build --profile toyos --target x86_64-unknown-uefi > $O/base-loader.log 2>&1; echo "base loader exit $?") &
wait
t1=$(date +%s); echo "base, side by side: $((t1 - t0)) s"
tree $FOLD
echo "load before fold: $(uptime | sed 's/.*load averages: //')"
t0=$(date +%s)
(cd $P && cargo build --profile toyos --target x86_64-unknown-none -p kernel > $O/fold-kernel.log 2>&1; echo "fold kernel exit $?")
(cd $P && cargo build --profile toyos --target x86_64-unknown-uefi -p bootloader > $O/fold-loader.log 2>&1; echo "fold loader exit $?")
t1=$(date +%s); echo "fold, one after the other: $((t1 - t0)) s"
rm -rf $P
echo DONE

@Japabu

Japabu commented Oct 7, 2026

Copy link
Copy Markdown
Collaborator Author

The metal profile at db55db96a, run by the orchestrator from the images this round staged (30 boots, the worktree clean at the head before each boot and judgement, every boot rc=0, each image deleted once booted): the whole-directory judgement read [metal] 294 passed, 2 failed, 30 boot(s), and both reds were the orchestrator's loop, not the change: it booted lanleasecase and lantalkcase without the per-boot options the request gives them, so lan_dhcp_lease and lan_talk had no readback to judge. Those two images were staged again at the same head and booted with the request's own options: --metal --metal-readback … lan_ → EXIT=0, [metal] 4 passed, 0 failed, 2 boot(s).

So every row of the profile is green at db55db96a on images built by the folded build, hard_lockup_ends_a_deaf_cpu among them (red at 88bcbf4d3 on the source path the folded kernel records). CI at this head: host, toolchain / build and guest / suite pass.

Japabu and others added 2 commits October 8, 2026 08:53
…workspace

Git merged every file without a conflict. #752's two `env:` lines
(`CARGO_PROFILE_DEV_DEBUG: line-tables-only` in both workflows' `host`
jobs) and its shortened `carry()` survive as it wrote them. No manifest
and no lock moved, so `Cargo.lock` is unchanged.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RvnWQFcMuGqTHYhvSnTe8A
The fold dropped `--target <host triple>` from the `userland/*` test
steps, which no longer need it to keep a guest triple out, and left it on
the apps step. On `main` both carried it and shared
`userland/target/<host triple>`; after the fold the tests filled
`target/debug` and the apps `target/<host triple>`, so the apps step
compiled every dependency a second time. Counted from the nightly logs:
282 units in "the apps for linux" at 88bcbf4 (run 37685714260) against
47 on main (run 37717000719), 226 of its 256 distinct crates already
compiled by an earlier step of the same run, and the sealed tree
740,395,570 B larger than main's on the same runner image.

The step now names a triple only where it checks another host's. Measured
cold on an aarch64-apple-darwin host, after the fourteen test steps'
builds (271 units): the ten apps with `--target` compile 270 units into
751,680 KiB; without it 47 units into 107,856 KiB, the same 47 crates
main's step compiles.

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

Japabu commented Oct 8, 2026

Copy link
Copy Markdown
Collaborator Author

Round 3, at 9ef866436 against origin/main b432ed21c. Each ran once.

prove.sh b432ed21c 9ef866436 <sysroot directory> <image key hex> <scratch> <worktree> (the script of the round 2 comment, unchanged): EXIT=0

build A-kernel x86_64-unknown-none exit 0
build A-kernel aarch64-unknown-none-softfloat exit 0
build A-loader x86_64-unknown-uefi exit 0
build A-loader aarch64-unknown-uefi exit 0
build C-kernel x86_64-unknown-none exit 0
build C-kernel aarch64-unknown-none-softfloat exit 0
build C-loader x86_64-unknown-uefi exit 0
build C-loader aarch64-unknown-uefi exit 0
build B-kernel x86_64-unknown-none exit 0
build B-kernel aarch64-unknown-none-softfloat exit 0
build B-loader x86_64-unknown-uefi exit 0
build B-loader aarch64-unknown-uefi exit 0
build B2-kernel x86_64-unknown-none exit 0
build B2-kernel aarch64-unknown-none-softfloat exit 0
build B2-loader x86_64-unknown-uefi exit 0
build B2-loader aarch64-unknown-uefi exit 0
bytes   control vs fold        kernel x86_64-unknown-none: cmp exit 0 (9b038ead572a9224)
bytes   fold vs fold rebuilt   kernel x86_64-unknown-none: cmp exit 0
bytes   base vs fold           kernel x86_64-unknown-none: cmp exit 1
rustc   base vs fold, normalised kernel x86_64-unknown-none: diff exit 0 (31 units)
rustc   control vs fold, verbatim kernel x86_64-unknown-none: diff exit 0
bytes   control vs fold        kernel aarch64-unknown-none-softfloat: cmp exit 0 (b26e03083c5e83f9)
bytes   fold vs fold rebuilt   kernel aarch64-unknown-none-softfloat: cmp exit 0
bytes   base vs fold           kernel aarch64-unknown-none-softfloat: cmp exit 1
rustc   base vs fold, normalised kernel aarch64-unknown-none-softfloat: diff exit 0 (31 units)
rustc   control vs fold, verbatim kernel aarch64-unknown-none-softfloat: diff exit 0
bytes   control vs fold        loader x86_64-unknown-uefi: cmp exit 0 (295fdff45cd5a2f3)
bytes   fold vs fold rebuilt   loader x86_64-unknown-uefi: cmp exit 0
bytes   base vs fold           loader x86_64-unknown-uefi: cmp exit 1
rustc   base vs fold, normalised loader x86_64-unknown-uefi: diff exit 0 (55 units)
rustc   control vs fold, verbatim loader x86_64-unknown-uefi: diff exit 0
bytes   control vs fold        loader aarch64-unknown-uefi: cmp exit 0 (7dabdcb6e32c68a7)
bytes   fold vs fold rebuilt   loader aarch64-unknown-uefi: cmp exit 0
bytes   base vs fold           loader aarch64-unknown-uefi: cmp exit 1
rustc   base vs fold, normalised loader aarch64-unknown-uefi: diff exit 0 (37 units)
rustc   control vs fold, verbatim loader aarch64-unknown-uefi: diff exit 0
paths   base vs fold, rustc's source argument kernel x86_64-unknown-none: diff exit 1 (29 of 31 crates renamed)
paths   base vs fold, .rs paths in the artifact kernel x86_64-unknown-none: diff exit 1 (base 249 paths, 38 under the tree's absolute path, 150 from the crate's own root; fold 249, 0, 0)
paths   control vs fold, .rs paths in the artifact kernel x86_64-unknown-none: diff exit 0
paths   base vs fold, rustc's source argument kernel aarch64-unknown-none-softfloat: diff exit 1 (29 of 31 crates renamed)
paths   base vs fold, .rs paths in the artifact kernel aarch64-unknown-none-softfloat: diff exit 1 (base 229 paths, 35 under the tree's absolute path, 133 from the crate's own root; fold 229, 0, 0)
paths   control vs fold, .rs paths in the artifact kernel aarch64-unknown-none-softfloat: diff exit 0
paths   base vs fold, rustc's source argument loader x86_64-unknown-uefi: diff exit 1 (35 of 50 crates renamed)
paths   base vs fold, .rs paths in the artifact loader x86_64-unknown-uefi: diff exit 1 (base 87 paths, 9 under the tree's absolute path, 9 from the crate's own root; fold 86, 0, 0)
paths   control vs fold, .rs paths in the artifact loader x86_64-unknown-uefi: diff exit 0
paths   base vs fold, rustc's source argument loader aarch64-unknown-uefi: diff exit 1 (13 of 35 crates renamed)
paths   base vs fold, .rs paths in the artifact loader aarch64-unknown-uefi: diff exit 1 (base 82 paths, 8 under the tree's absolute path, 8 from the crate's own root; fold 83, 0, 0)
paths   control vs fold, .rs paths in the artifact loader aarch64-unknown-uefi: diff exit 0
build M1-loader x86_64-unknown-uefi exit 101
M2 cargo update exit 0
build M2-kernel x86_64-unknown-none exit 0
M2 dlmalloc 0.2.12: kernel x86_64-unknown-none cmp exit 1
M2 dlmalloc 0.2.12: rustc lines diff exit 1
build M3-kernel x86_64-unknown-none exit 101
DONE

cargo test inside kernel/loom: EXIT=0. Inside kernel/sim: EXIT=0.

wall.sh, same arguments (the script of the round 2 comment, unchanged): EXIT=0

load before base: 34.92 28.15 17.84
base loader exit 0
base kernel exit 0
base, side by side: 24 s
load before fold: 42.23 30.57 19.02
fold kernel exit 0
fold loader exit 0
fold, one after the other: 20 s
DONE

share.sh <worktree> <scratch>: which arrangement of the host's own apps step shares units with the userland test steps. EXIT=0

#!/bin/sh
# One-off: which arrangement of the host's own apps step shares compiled units
# with the userland test steps. Cold, in a target of its own.
#   share.sh <worktree> <scratch directory>
set -u
W=$1; S=$2; T=$S/share-target; rm -rf $T
export CARGO_TARGET_DIR=$T CARGO_INCREMENTAL=0 CARGO_PROFILE_DEV_DEBUG=line-tables-only
HOST=$(rustc -vV | sed -n 's/^host: //p')
cd $W
count() { grep -cE '^ +(Compiling|Checking) ' $1; }
: > $S/share-tests.log; : > $S/share-target.log; : > $S/share-own.log
for c in acpiserver acpiserver/aml calc compositor/desktop diskserver fileserver logkeeper netstack netstack/mdns pkg soundserver soundserver/mixer sshserver symbolize; do
  cargo test --no-run --manifest-path userland/$c/Cargo.toml >> $S/share-tests.log 2>&1; echo "tests $c exit $?"
done
echo "userland test steps: $(count $S/share-tests.log) units; target/debug $(du -sk $T/debug | cut -f1) KiB"
APPS="calc editor filepicker files host paint pkg snake sshserver symbolize"
for a in $APPS; do
  cargo build --manifest-path userland/$a/Cargo.toml --target $HOST >> $S/share-target.log 2>&1; echo "apps --target $a exit $?"
done
echo "apps, cargo build --target $HOST: $(count $S/share-target.log) units; target/$HOST $(du -sk $T/$HOST | cut -f1) KiB; target/debug $(du -sk $T/debug | cut -f1) KiB"
for a in $APPS; do
  cargo build --manifest-path userland/$a/Cargo.toml >> $S/share-own.log 2>&1; echo "apps own $a exit $?"
done
echo "apps, cargo build: $(count $S/share-own.log) units; target/debug $(du -sk $T/debug | cut -f1) KiB"
rm -rf $T
echo DONE
tests acpiserver exit 0
tests acpiserver/aml exit 0
tests calc exit 0
tests compositor/desktop exit 0
tests diskserver exit 0
tests fileserver exit 0
tests logkeeper exit 0
tests netstack exit 0
tests netstack/mdns exit 0
tests pkg exit 0
tests soundserver exit 0
tests soundserver/mixer exit 0
tests sshserver exit 0
tests symbolize exit 0
userland test steps: 271 units; target/debug 710084 KiB
apps --target calc exit 0
apps --target editor exit 0
apps --target filepicker exit 0
apps --target files exit 0
apps --target host exit 0
apps --target paint exit 0
apps --target pkg exit 0
apps --target snake exit 0
apps --target sshserver exit 0
apps --target symbolize exit 0
apps, cargo build --target aarch64-apple-darwin: 270 units; target/aarch64-apple-darwin 616616 KiB; target/debug 845148 KiB
apps own calc exit 0
apps own editor exit 0
apps own filepicker exit 0
apps own files exit 0
apps own host exit 0
apps own paint exit 0
apps own pkg exit 0
apps own snake exit 0
apps own sshserver exit 0
apps own symbolize exit 0
apps, cargo build: 47 units; target/debug 953004 KiB
DONE
EXIT=0

The 47 units of the last row:

arrayref v0.3.9;arrayvec v0.7.8;base64 v0.22.1;bytemuck v1.25.0;crc32fast v1.5.0;data-url v0.3.2;editor v0.1.0 (/Users/jan/Dev/jan/toyos-oneworkspace/userland/editor);fdeflate v0.3.7;filepicker v0.1.0 (/Users/jan/Dev/jan/toyos-oneworkspace/userland/filepicker);filepicker-api v0.1.0 (/Users/jan/Dev/jan/toyos-oneworkspace/userland/filepicker-api);files v0.1.0 (/Users/jan/Dev/jan/toyos-oneworkspace/userland/files);flate2 v1.1.10;float-cmp v0.9.0;getrandom v0.2.17 (https://github.com/ToyOSOrg/getrandom?branch=toyos-0.2-sdk-0.12#2092d1cc);host v0.1.0 (/Users/jan/Dev/jan/toyos-oneworkspace/userland/host);imagesize v0.14.0;kurbo v0.13.0;log v0.4.29;memchr v2.8.0;miniz_oxide v0.8.9;miniz_oxide v0.9.1;paint v0.1.0 (/Users/jan/Dev/jan/toyos-oneworkspace/userland/paint);pico-args v0.5.0;pkg v0.1.0 (/Users/jan/Dev/jan/toyos-oneworkspace/userland/pkg);png v0.18.1;rand v0.8.5;rand_chacha v0.3.1;rand_core v0.6.4;resvg v0.47.0;rgb v0.8.53;roxmltree v0.21.1;simd-adler32 v0.3.10;simplecss v0.2.2;siphasher v1.0.2;smallvec v1.15.1;snake v0.1.0 (/Users/jan/Dev/jan/toyos-oneworkspace/userland/snake);sprite v0.1.0 (/Users/jan/Dev/jan/toyos-oneworkspace/userland/sprite);sshserver v0.0.0 (/Users/jan/Dev/jan/toyos-oneworkspace/userland/sshserver);strict-num v0.1.1;svgtypes v0.16.1;symbolize v0.1.0 (/Users/jan/Dev/jan/toyos-oneworkspace/userland/symbolize);tiny-skia v0.12.0;tiny-skia-path v0.12.0;toyos-keymap v0.1.0 (/Users/jan/Dev/jan/toyos-oneworkspace/toyos-keymap);toyos-window v0.20.0 (/Users/jan/Dev/jan/toyos-oneworkspace/userland/toyos-window);usvg v0.47.0;xmlwriter v0.1.0;

Git merged every file without a conflict. #750 moves
`userland/acpiserver/aml`'s sources and tests; #753 and #755 move issues
alone. No manifest, no lock, no workflow and nothing under `src/` moved.

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

Japabu commented Oct 8, 2026

Copy link
Copy Markdown
Collaborator Author

Review of e3bdff8af against origin/main 2e781a49d, round 2. Read only: nothing built, nothing run in the worktree.

Net lines (git diff --shortstat origin/main...e3bdff8af): 52 files, +5520 −7737. Locks +5017 −7066; src/, tests/toyos.rs and tests/common/ +237 −360 (production and its tests together; the test share is the body's estimate, about +65 −115); issues +106 −82. Production shrinks; no deletion is owed.

Round 1's BLOCKERs

  • Evidence, hardware — CLOSED. The orchestrator's comment of 2026-10-07T23:16Z: the whole metal profile at db55db96a, 30 boots, 294 green and the two lan_ rows green on their own boots with the request's options ([metal] 4 passed, 0 failed, 2 boot(s), exit 0); hard_lockup_ends_a_deaf_cpu green on the path the folded kernel records. What this head owes the T14 is ruled under (3).
  • Evidence, CI — CLOSED at 9ef866436. I read both runs by gh run view: 37740454881 (pull_request, head 9ef866436) host, toolchain / build, guest / suite success; 37740449787 (workflow_dispatch, same head) host, portability-linux, portability-macos, toolchain / build, tcg / suite success, release skipped. The saved host log carries none restored: the run is cold, 17010 files, 7493968284 B of the 8000000000 B an entry may hold; sealed: 2496 sources, built on Linux X64 ubuntu24 20261004.327.1 and [ci] Seal: 80 step(s), all green. The merge queue's cold host is the landing itself.
  • Evidence, another head (loom and sim) — CLOSED. Both in-directory runs at 9ef866436, exit 0; the logs in the round's scratch end test result: ok. Nothing under kernel/loom, kernel/sim or a manifest moved since.
  • Evidence, the next head — CLOSED for 9ef866436 (prove.sh b432ed21c 9ef866436, exit 0, every row posted; CI as above), and open again for this head: see the BLOCKER below.

Round 1's NOTEs: the seal's byte count is measured; issues/the-sdk-is-linted-by-no-clippy-run.md names its owner; the body states the -Dwarnings reach, the opt-level = 2 reach and the control's flags; the stage's issue gives the reason libc stays apart and what it costs; the wall clock is measured once (24 s against 20 s, under load, said so). All closed. The landing note stands and is restated under (5).

What changed since 88bcbf4d3

git show --cc of both merges of main is empty: no hand resolution. Per file, the branch's own diff at db55db96a against its base and at this head against 2e781a49d differs in src/ci.rs alone. 9ef866436 is that change: judged_as gives the host's own apps build with no --target, and its test asserts all three hosts' arguments, so it can fail on the claim.

BLOCKER

  • Evidence, this head — cargo run -- --ci host and the guest suite have no result at e3bdff8af — ci.yml run 37755369755 was in_progress when read, once. The head adds main's userland/acpiserver/aml sources and tests to the measured one; the body's one local row for them is cargo test in that crate on macOS. It closes on that run's host, toolchain / build and guest / suite success, with no change to the tree. It is moot if The acpi claim's mediated access and the Global Lock, and acpiserver loading the machine's tables through them #749 lands first: see (5), this head cannot land after it.

NOTE

Rulings asked for

(1) The margin. The size gate is enough, and nothing is owed in the tree. src/cicache.rs refuses a tree above LIMIT by name before anything is saved, so the failure is a red writer and cold readers, never a wrong verdict. Two things make that red dearer after this landing than before it, both already tracked and neither this branch's to fix: nothing reports a red nightly (issues/a-red-nightly-on-main-is-reported-to-nobody.md), and the limit is read only after main has moved (issues/the-host-caches-limit-reaches-the-10-gb-only-through-one-measured-ratio.md, exit, second gate). What is new is that the path list is the cache's version: no entry of the old list is restorable, so until a seal of the new list is green every host check is cold, about 16 minutes of steps in run 37740449787 against the 45-minute timeout. The margin is not shown to be better than main's: on the one image pair there is, this tree would seal near 7.85 GB on 20260927.320.1 against main's measured 7.66 GB there. That is arithmetic and the body says so; which image a run draws cannot be chosen, so no measurement is owed.

(2) The unit counts. Acceptable; not a regression to fix here. The four steps compile 771 units against main's 823 (42 + 264 + 240 + 225 against 47 + 248 + 239 + 289), counted from the two logs. The 16 and 1 are host-side units the first --target step now compiles because no earlier step names a triple; the only arrangement that removes them puts --target <host> back on the fourteen test steps, which separates them from the workspace's host members' target/debug again and costs more than 17 units. The byte verdict is the seal's, and it is green.

(3) The T14. No boot is owed for this head. Checked with git diff: db55db96a..e3bdff8af is empty over Cargo.toml, Cargo.lock, .cargo/, src/build.rs, src/sysroot.rs, src/hostws.rs, src/clippy.rs, kernel/Cargo.toml, bootloader/, toyos/Cargo.toml and userland/libc/; main moved no manifest and no lock between e16cb0841 and 2e781a49d; every kernel, toyos-abi, toyos-userbound and toyos source that moved is in git diff e16cb0841 origin/main (#747, #748), and #750 and #755 moved userland/acpiserver/aml and issues only. So what boots is main's sources, each landed on its own T14 reading, built by a fold whose whole profile was read at db55db96a; and prove.sh b432ed21c 9ef866436 has the folded kernel and loader byte-identical to the control with #747 and #748 in, on both architectures. The one way the two could meet is a judge reading a compiled-in path: git grep over tests/, src/, toyos-blackbox, toyos-symbols and userland/symbolize at this head finds tests/common/power.rs:429 alone outside synthetic fixtures, and the three metal judges #747 changed (counters_on_metal, acpi_events_on_metal, acpi_death_on_metal) read no path. The same holds across the merge of #749 on two conditions, both cheap: prove.sh <main with #749> <merged head> exits 0 with the control rows 0, and the merged tree has no new reader of a path (#749's diff under tests/ adds none at 54e08c632).

(4) What the landing rests on. On the merge group's host, cold, and guest / suite. Two things run for the first time only after main has this, and the orchestrator reads both in the first nightly on main (dispatch it at landing rather than wait for 03:00Z):

  • host: none restored: the run is cold; the seal line with its bytes under 8,000,000,000 and the image it ran on; [ci] Seal: N step(s), all green; then the save step's Cache saved with key: host-sealed-Linux-X64-<run id> and its stored size. A red seal on bytes means main holds no entry of the new list and every host check stays cold until a landing shrinks the tree: a defect to fix at once, with nothing to restore to.
  • release: it is skipped off main, so src/release.rs's read of the root manifest's raw-window-handle line has never run. Red there is no release and no SDK alias that day.
  • Then the first ci.yml host after the save, on a runner of the same image: Cache restored from key: host-sealed-… and built from <sha>: N of M sources dated as built. none restored there says the writer's and the reader's lists disagree, which is this change's; deleted: the run is cold says the image differed, which is the tracked issue's.

(5) #749 and the open branches. #749 must be merged in and measured before this lands; this head cannot land after it. git merge-tree e3bdff8af 54e08c632: modify/delete on kernel/Cargo.lock and userland/Cargo.lock, and the root Cargo.lock merges without a conflict into a lock that is wrong: it takes toyos-userbound's new edges and not acpiserver's new toyos-acpi and toyos-aml, which #749 wrote only into the deleted userland/Cargo.lock. Owed at the merged head: cargo metadata --locked exit 0; the lock's (name, version) pairs equal to the union of main's five, diff exit 0; prove.sh against that main; ci.yml green. #749 adds no crate. A crate in neither list is refused three ways: src/hostws.rs's gate reds in --ci host; cargo build -p <name> at the root matches no package, so the image does not build; and a branch that adds a member the old way edits userland/Cargo.toml, which is a modify/delete conflict.

For the agents of #756 to #762, when this lands: merge main before anything else; a local .cargo/config.toml moves to .cargo/local.toml first; every lock but the root's and userland/libc's is gone, and so is userland/Cargo.toml, so a dependency or a new crate goes into the root Cargo.toml and Cargo.lock and a modify/delete conflict on an old lock is resolved by re-resolving the root lock, never by keeping the file; guests build into target/<triple>/toyos/ and the old kernel/target, bootloader/target, userland/target and toyos/target are deleted by hand; a kernel source path in a panic or lock site now reads kernel/src/…; every measurement is taken again at the merged head. #756 also edits src/build.rs and src/ci.rs and merges them by hand.

SEND BACK

Japabu and others added 2 commits October 8, 2026 11:29
#749 wrote its new dependency edges into `kernel/Cargo.lock` and
`userland/Cargo.lock`, which this branch deletes: both modify/delete
conflicts are resolved by deleting the file. Git merged the root
`Cargo.lock` without a conflict into a lock `cargo metadata --locked`
refuses (exit 101): it took `toyos-userbound`'s edges to `toyos-abi` and
`toyos-bootmap`, which #749 also wrote into the root lock, and not
`acpiserver`'s to `toyos-acpi` and `toyos-aml`, which it wrote into
userland's alone. `cargo metadata --offline` re-resolved it; the only
change against git's merge is those two lines, no package is added and no
version moves, and `cargo metadata --locked` exits 0.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RvnWQFcMuGqTHYhvSnTe8A
…ts two stages landed

`issues/the-tree-resolves-in-five-cargo-locks-not-one.md` named one thing
left, the T14's run of the metal profile on the folded build. It ran green
at `db55db96a`, and the review ruled no boot owed for what followed, so the
exit is met and the file goes. Stages 2 and 3 of
`issues/the-tree-says-who-uses-each-thing.md` cited it: the alignments
landed in #724, #732 and #738, the workspace in #746.

What the file carried that is still true is at its site: the root
manifest's `exclude` says why `userland/libc` and the guest test crates
keep their own resolution. Two facts go with the file. libc's lock resolves
`toyos`, `toyos-abi`, `toyos-elf`, `toyos-osrelease` and `dlmalloc` a
second time and nothing holds it to the root's; both carry `dlmalloc`
0.2.13. `Cargo.lock` carries `miniz_oxide` 0.8.9 for `png` 0.18.1 beside
0.9.1 for `flate2` 1.1.10 until `png` takes 0.9.

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

Japabu commented Oct 8, 2026

Copy link
Copy Markdown
Collaborator Author

Round 4, measured at dd12c0b32 against origin/main 6f87cdb9c. The body carries what each row means.

prove.sh 6f87cdb9c dd12c0b32 <sysroot> <image key> <scratch> <worktree> (the round 3 comment's script, byte for byte), exit 0:

build A-kernel x86_64-unknown-none exit 0
build A-kernel aarch64-unknown-none-softfloat exit 0
build A-loader x86_64-unknown-uefi exit 0
build A-loader aarch64-unknown-uefi exit 0
build C-kernel x86_64-unknown-none exit 0
build C-kernel aarch64-unknown-none-softfloat exit 0
build C-loader x86_64-unknown-uefi exit 0
build C-loader aarch64-unknown-uefi exit 0
build B-kernel x86_64-unknown-none exit 0
build B-kernel aarch64-unknown-none-softfloat exit 0
build B-loader x86_64-unknown-uefi exit 0
build B-loader aarch64-unknown-uefi exit 0
build B2-kernel x86_64-unknown-none exit 0
build B2-kernel aarch64-unknown-none-softfloat exit 0
build B2-loader x86_64-unknown-uefi exit 0
build B2-loader aarch64-unknown-uefi exit 0
bytes   control vs fold        kernel x86_64-unknown-none: cmp exit 0 (3b80007aac3cf4bc)
bytes   fold vs fold rebuilt   kernel x86_64-unknown-none: cmp exit 0
bytes   base vs fold           kernel x86_64-unknown-none: cmp exit 1
rustc   base vs fold, normalised kernel x86_64-unknown-none: diff exit 0 (31 units)
rustc   control vs fold, verbatim kernel x86_64-unknown-none: diff exit 0
bytes   control vs fold        kernel aarch64-unknown-none-softfloat: cmp exit 0 (a8ea08b3d0362a03)
bytes   fold vs fold rebuilt   kernel aarch64-unknown-none-softfloat: cmp exit 0
bytes   base vs fold           kernel aarch64-unknown-none-softfloat: cmp exit 1
rustc   base vs fold, normalised kernel aarch64-unknown-none-softfloat: diff exit 0 (31 units)
rustc   control vs fold, verbatim kernel aarch64-unknown-none-softfloat: diff exit 0
bytes   control vs fold        loader x86_64-unknown-uefi: cmp exit 0 (0a73d01faa8c81b2)
bytes   fold vs fold rebuilt   loader x86_64-unknown-uefi: cmp exit 0
bytes   base vs fold           loader x86_64-unknown-uefi: cmp exit 1
rustc   base vs fold, normalised loader x86_64-unknown-uefi: diff exit 0 (55 units)
rustc   control vs fold, verbatim loader x86_64-unknown-uefi: diff exit 0
bytes   control vs fold        loader aarch64-unknown-uefi: cmp exit 0 (7dabdcb6e32c68a7)
bytes   fold vs fold rebuilt   loader aarch64-unknown-uefi: cmp exit 0
bytes   base vs fold           loader aarch64-unknown-uefi: cmp exit 1
rustc   base vs fold, normalised loader aarch64-unknown-uefi: diff exit 0 (37 units)
rustc   control vs fold, verbatim loader aarch64-unknown-uefi: diff exit 0
paths   base vs fold, rustc's source argument kernel x86_64-unknown-none: diff exit 1 (29 of 31 crates renamed)
paths   base vs fold, .rs paths in the artifact kernel x86_64-unknown-none: diff exit 1 (base 250 paths, 39 under the tree's absolute path, 150 from the crate's own root; fold 250, 0, 0)
paths   control vs fold, .rs paths in the artifact kernel x86_64-unknown-none: diff exit 0
paths   base vs fold, rustc's source argument kernel aarch64-unknown-none-softfloat: diff exit 1 (29 of 31 crates renamed)
paths   base vs fold, .rs paths in the artifact kernel aarch64-unknown-none-softfloat: diff exit 1 (base 229 paths, 35 under the tree's absolute path, 133 from the crate's own root; fold 229, 0, 0)
paths   control vs fold, .rs paths in the artifact kernel aarch64-unknown-none-softfloat: diff exit 0
paths   base vs fold, rustc's source argument loader x86_64-unknown-uefi: diff exit 1 (35 of 50 crates renamed)
paths   base vs fold, .rs paths in the artifact loader x86_64-unknown-uefi: diff exit 1 (base 85 paths, 9 under the tree's absolute path, 10 from the crate's own root; fold 85, 0, 0)
paths   control vs fold, .rs paths in the artifact loader x86_64-unknown-uefi: diff exit 0
paths   base vs fold, rustc's source argument loader aarch64-unknown-uefi: diff exit 1 (13 of 35 crates renamed)
paths   base vs fold, .rs paths in the artifact loader aarch64-unknown-uefi: diff exit 1 (base 83 paths, 8 under the tree's absolute path, 9 from the crate's own root; fold 83, 0, 0)
paths   control vs fold, .rs paths in the artifact loader aarch64-unknown-uefi: diff exit 0
build M1-loader x86_64-unknown-uefi exit 101
M2 cargo update exit 0
build M2-kernel x86_64-unknown-none exit 0
M2 dlmalloc 0.2.12: kernel x86_64-unknown-none cmp exit 1
M2 dlmalloc 0.2.12: rustc lines diff exit 1
build M3-kernel x86_64-unknown-none exit 101
DONE

pairs.sh <worktree> 6f87cdb9c <scratch>:

#!/bin/sh
# pairs.sh <worktree> <main commit> <scratch>: the root lock's (name, version)
# pairs against the union of main's five locks.
W=$1; M=$2; S=$3
pairs() { awk '/^\[\[package\]\]/{p=1;next} p&&/^name = /{n=$3} p&&/^version = /{print n, $3; p=0}' | tr -d '"'; }
for l in Cargo.lock kernel/Cargo.lock bootloader/Cargo.lock userland/Cargo.lock toyos/Cargo.lock; do git -C $W show $M:$l | pairs; done | sort -u > $S/pairs-five.txt
pairs < $W/Cargo.lock | sort -u > $S/pairs-one.txt
wc -l $S/pairs-five.txt $S/pairs-one.txt
diff $S/pairs-five.txt $S/pairs-one.txt; echo "pairs diff EXIT=$?"
     692 pairs-five.txt
     692 pairs-one.txt
    1384 total
pairs diff EXIT=0

Git's merged root lock against the re-resolved one (diff exit 1):

10a11,12
>  "toyos-acpi",
>  "toyos-aml",

cargo metadata --locked on git's merged lock, exit 101:

error: cannot update the lock file <worktree>/Cargo.lock because --locked was passed to prevent this
help: to generate the lock file without accessing the network, remove the --locked flag and use --offline instead.

The merge's added lines under the five reader directories that match the path search (readers-hits.txt, numbered by line of the -U0 diff):

15:+++ b/tests/common/isa.rs
22:+++ b/tests/common/power.rs
78:+++ b/tests/toyos-rust-tests/src/bin/acpi_mediated.rs
257:+    let (signature, ty) = holder.ask(Access::read(Space::SystemMemory, info.rsdp, Width::QWord));
260:+    assert_eq!(holder.write(Space::SystemMemory, info.rsdp, Width::Byte, b'X'.into()), Err(Refused::TableWrite));
261:+    assert_eq!(holder.memory(info.rsdp, Width::Byte), u64::from(b'R'), "acpi: a refused write reached the RSDP");
263:+    assert_eq!(holder.memory(info.rsdp + 1, Width::Word), u64::from(u16::from_le_bytes(*b"SD")));
264:+    assert_eq!(holder.memory(info.rsdp + 1, Width::DWord), u64::from(u32::from_le_bytes(*b"SD P")));
298:+    let fadt = holder.table(info.rsdp, b"FACP");
361:+    let fadt = holder.table(info.rsdp, b"FACP");
395:+    let ecam = holder.memory(holder.table(info.rsdp, b"MCFG") + 44, Width::QWord);
414:+    let fadt = holder.table(info.rsdp, b"FACP");
474:+++ b/tests/toyos.rs

@Japabu

Japabu commented Oct 8, 2026

Copy link
Copy Markdown
Collaborator Author

Review of dd12c0b32 against origin/main, round 3. Read only: no cargo command run; every figure is from the round's logs (orch/oneworkspace-r4/), from git and from gh. origin/main was b6bcb9691 (#757) when read; the head is merged on 6f87cdb9c.

Net lines (git diff --shortstat origin/main...dd12c0b32): 53 files, +5454 −7765. Without the locks 48 files, +446 −704; src/, tests/toyos.rs and tests/common/ 12 files, +237 −360 (production and its tests together); issues/ 16 files, +49 −115. Production shrinks; no deletion is owed.

Round 2's BLOCKER

  • Evidence, a result at the head — OPEN on one job, with no change to the tree owed. host: CLOSED, twice at dd12c0b32: host.exit host EXIT=0, host.head dd12c0b32…, host.log ending [ci] Host: 77 step(s), all green, started at 1-minute load 26.60; and ci.yml run 37757675374 (pull_request, headSha dd12c0b32) host success, toolchain / build success. guest / suite of that run was in_progress when read, once. The suite's last green is run 37755369755 at e3bdff8af, which has neither The acpi claim's mediated access and the Global Lock, and acpiserver loading the machine's tables through them #749's kernel and acpiserver sources nor the re-resolved lock.

Ruling (5) of round 2, each owed item against its log

The merge of #749

git show --cc 4e4ff9b96 has one hunk: the root Cargo.lock, acpiserver's "toyos-acpi" and "toyos-aml". Checked without the implementer's files: git merge-tree --write-tree e3bdff8af 6f87cdb9c conflicts on kernel/Cargo.lock and userland/Cargo.lock (modify/delete) and nowhere else; its Cargo.lock is byte-identical to the saved Cargo.lock.git-merged; and its tree against 4e4ff9b96 differs by those two lines and the two deleted locks, nothing more. The merge moved two manifests, userland/acpiserver/Cargo.toml and toyos-userbound/Cargo.toml, and the lock's entries for both carry exactly their [dependencies]. dd12c0b32 on top touches two files under issues/.

BLOCKER

NOTE

The landing

Arming. It may be armed now. The ruleset on main requires host and guest / suite and nothing else, not strict, so an armed pull request enters the queue only when the open BLOCKER's own job is green on dd12c0b32: the arm is that exit, enforced by GitHub. A red guest / suite there leaves it armed and unqueued, and is this branch's defect.

The landings ahead. No merge and no re-measure is owed here for #757, #759, #762 or #758. Read, not assumed:

The rule for anything else that gets ahead: a landing that touches a Cargo.toml, a Cargo.lock, .cargo/, rust-toolchain.toml, src/, .github/, or adds a reader of a path under tests/, src/, toyos-blackbox, toyos-symbols or userland/symbolize, owes a merge here and the four rows of ruling (5) again. #756 is that case (src/build.rs, src/ci.rs, tests/toyos.rs); it is not queued and must not be queued ahead of this.

The check that says the lock was right. It runs before the landing, not after: the merge group's host, whose licence step is cargo metadata --locked on the exact tree main becomes. A lock wrong for the merge group is a red host and no landing; a wrong lock cannot reach main through the queue. Of the three named, cargo metadata --locked on main repeats that step and tells nothing new, and neither the seal nor the first cached host reads the lock at all. What they tell is the cache, as round 2's (4) set out and which stands: dispatch the nightly at landing and read its host (cold, sealed under 8,000,000,000 B, saved) and its release; then the first ci.yml host after the save for Cache restored from key: host-sealed-…. The merge group's own host is cold, about 16 minutes of steps against the 45-minute timeout.

SEND BACK

Japabu added a commit that referenced this pull request Oct 8, 2026
…e says what is true of the folded tree

The three files both sides changed, src/build.rs, src/ci.rs and
tests/toyos.rs, are main's whole plus this branch's hunks and nothing else:
`git diff origin/main` on them shows the `ALL_CONFIGS` row, the
`forget_own_package` call, function and test pair, and the panelcase path.

The issue file: `[profile.toyos]` is the root manifest's; the bullet that the
five-locks issue folds three target directories is gone with that issue, the
fold having landed; the development machine's figures for a fresh suite and
for an entry's bytes are said to be from before the fold and not measured
since; "No runner has measured either" is dropped. Job 113260475768, #746's
merge group at `1084ddc9a`, is added as column D: the one baseline that
builds as the tree now does. It still shows both costs this branch removes,
`BUILT x86_64 ROOT of tests/metalcase ... (158s)` and ring, rustls,
rustls-webpki, ureq and toyos-build compiled a second time under
`=== [ci] the suite` (`Finished test` in 44.82s).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RvnWQFcMuGqTHYhvSnTe8A
Japabu added a commit that referenced this pull request Oct 8, 2026
Clean. This branch names no dependency and no lockfile, so the root lock is
main's.

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