Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
520c0d1
tests: the guest suite keeps what only a guest shows; the harness tha…
Japabu Oct 1, 2026
29e1006
kernel, userland, src: the actuators and hooks only cut guest tests a…
Japabu Oct 1, 2026
732fbac
src: the entry-window gate judges every kernel hold-free
Japabu Oct 1, 2026
bd3efcf
kernel: the last of the cut tests' hooks, and the comments that named…
Japabu Oct 1, 2026
c3f037f
tests, toyos-sched: the last citations of cut tests, and the pass-cos…
Japabu Oct 1, 2026
ed1902f
Merge origin/main (#635) into wt/toyos-guestcut
Japabu Oct 1, 2026
cff5bce
tests: one C comparison rule left, so the check that two agree goes
Japabu Oct 1, 2026
2534c83
kernel, tests: comments whose code the cut deleted go with it
Japabu Oct 1, 2026
98199b7
kernel, loader: what no test arms goes, and the control-register inst…
Japabu Oct 1, 2026
13f71c5
test-runner, metaltalk: what only the cut tests called goes
Japabu Oct 1, 2026
c3c8aa0
ci, harness: one nightly guest job runs the whole suite, with no shar…
Japabu Oct 1, 2026
97e83df
tests, kernel: comments naming cut tests, and citations of deleted fi…
Japabu Oct 1, 2026
c83df49
review, issues: one rule for cutting a test, a track of owed work, an…
Japabu Oct 1, 2026
57ca76a
Merge origin/main (#639, #656, #652) into wt/toyos-guestcut
Japabu Oct 1, 2026
ab165d4
issues: the loader's exclusive GOP open is refused at build time, so …
Japabu Oct 1, 2026
24e9d5a
loader: every protocol is opened in protocol.rs, and clippy refuses b…
Japabu Oct 1, 2026
b581b0f
kernel: FOREIGN_PROBE goes with its readers, and Storm takes main's n…
Japabu Oct 1, 2026
0830817
tests: prose about QEMU registrations the cut deleted goes
Japabu Oct 1, 2026
83bac08
issues: the track names what the seven cuts' rows and copies do not hold
Japabu Oct 1, 2026
edd6e2e
issues: the ways back this branch broke, and the guards it cut, go
Japabu Oct 1, 2026
9c6689d
Merge origin/main (c7c725fa5) into wt/toyos-guestcut
Japabu Oct 1, 2026
b5ac169
Review round 3: protocol.rs's false clause, usb_stick_left's four red…
Japabu Oct 1, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 10 additions & 2 deletions .claude/agents/reviewer.md
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ above; otherwise it is a NOTE.
with its tag in a trailing comment or names a local path that resolves.
A file added to or deleted from `tests/testcases/tinycc/` moves the count
`tests/testcases/LICENSE` states in the same diff, and `46_grep.c` never comes back. Nothing
else is tracked under `tests/testcases/` but that `LICENSE`, `system.toml` and `hello.c`.
else is tracked under `tests/testcases/` but that `LICENSE` and `system.toml`.
- **What no gate reads.** A BLOCKER each: a diff that declares a retired ABI name or reuses a
retired syscall, `SYS_DEBUG` action or inbox op number (the retired numbers are
`kernel/src/syscall/dispatch.rs`'s `retired_syscalls!` and the "formerly …" and "retired and
Expand All @@ -80,7 +80,7 @@ above; otherwise it is a NOTE.
needs a reason you accept; a branch that could delete more than it adds and does not goes back
with the deletion named. What could be deleted, merged into what exists, or made smaller? An
abstraction with one caller, a parameter with one value, dead code. Size is never bought with a
weaker check: tests are cut only when they test nothing. A compromise the branch found is removed or
weaker check: a test is cut only when it tests nothing, or as **Guest tests** says. A compromise the branch found is removed or
recorded in `issues/` with an owner, evidence and an exit condition.
Code is liability: code that does not earn its keep is deleted or simplified, and code kept
"just in case", or because nobody knows whether it is needed, is an instant delete. Doubt is
Expand All @@ -92,6 +92,14 @@ above; otherwise it is a NOTE.
held across a user copy or a device wait. Arithmetic on a value the caller chooses. A short
read, an exit status nobody reads. An `at_most(<int>::MAX)` or `index(usize::MAX)` on an
`Untrusted` is an unwrap wearing a check's name.
- **Guest tests.** A behaviour is tested on the cheapest tier that reaches it: a type that makes
the bug unrepresentable, then a host test, then a metal row on the T14, and a QEMU guest test
last. A new guest test, or one whose behaviour changes, whose pull request body does not say
why a type, a host test and a metal row cannot reach its behaviour is a BLOCKER, and so is one
whose reason a cheaper tier answers. A guest test is cut for a cheaper tier only where that
tier already holds its behaviour, named in the pull request body, or where a stage of a track
names it, in the same diff, with the behaviour it guarded and an exit a build or test can fail;
any other cut is a BLOCKER.
- **Waits.** A flat wait — sleep, then assume it happened — is a BLOCKER, in code and in tests,
unless a hardware document mandates that time and offers no notification, cited at the site.
Wait on the event itself, bounded by a timeout that fails loudly. Defensive code that hides a
Expand Down
21 changes: 8 additions & 13 deletions .github/workflows/nightly.yml
Original file line number Diff line number Diff line change
Expand Up @@ -78,10 +78,6 @@ jobs:
runs-on: ubuntu-24.04
# A wedge guard, not a budget.
timeout-minutes: 60
strategy:
fail-fast: false
matrix:
shard: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]
# The digest is the instrument's one pin: a dated image names the snapshot
# archive it was built from, and `deps` installs QEMU from that archive.
# The node ships `crw-rw---- root:kvm` and root opens it.
Expand All @@ -104,7 +100,8 @@ jobs:
for attempt in 1 2 3; do
apt-get -o Acquire::Check-Valid-Until=false update -qq > /tmp/apt.log 2>&1 \
&& DEBIAN_FRONTEND=noninteractive apt-get install -y -qq git curl ca-certificates \
zstd build-essential qemu-system-x86 ovmf-generic >> /tmp/apt.log 2>&1 \
zstd build-essential qemu-system-x86 ovmf-generic qemu-system-arm \
qemu-efi-aarch64 >> /tmp/apt.log 2>&1 \
&& break
[ "$attempt" = 3 ] && { cat /tmp/apt.log; exit 1; }
sleep 20
Expand All @@ -131,12 +128,10 @@ jobs:
userland/target
tests/target
tests/toyos-rust-tests/*/target
tests/https-fetch-host/target
tests/https-server-host/target
key: guest-${{ github.run_id }}
restore-keys: guest-

- run: cargo run -- --ci guest ${{ matrix.shard }}/12
- run: cargo run -- --ci guest

# Every boot's 16550 log: what a guest that died early still leaves.
- &serial
Expand All @@ -145,14 +140,14 @@ jobs:
continue-on-error: true
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
with:
name: serial-${{ github.job }}-${{ strategy.job-index }}
name: serial-${{ github.job }}
path: target/red-run-serial/**/uart-*.log
if-no-files-found: warn
retention-days: 7

# The only lane with no `/dev/kvm`, so the only one that decodes the paths a
# KVM host's CPU never does; and the guest cache's one writer, since what it
# builds does not depend on the accelerator.
# The guest suite again with no `/dev/kvm`, so the only lane that decodes the
# paths a KVM host's CPU never does; and the guest cache's one writer, since
# what it builds does not depend on the accelerator.
tcg:
needs: build
runs-on: ubuntu-24.04
Expand All @@ -165,7 +160,7 @@ jobs:
- *deps
- *checkout
- *guest-cache
- run: cargo run -- --ci tcg
- run: cargo run -- --ci guest
# After the test: what is worth keeping is a tree that built and booted.
- if: github.ref == 'refs/heads/main'
uses: actions/cache/save@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0
Expand Down
62 changes: 0 additions & 62 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

13 changes: 2 additions & 11 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -160,11 +160,8 @@ getrandom = "0.3"
# disagree about which files on it are `logd`'s.
toyos-wallclock = { path = "toyos-wallclock" }
image = { version = "0.25", default-features = false, features = ["jpeg"] }
# The digest behind two readings that must not be able to agree by accident:
# `NOTICE`'s record of every committed binary file (`src/sourcegate.rs`), and a
# disk this system was not given, before and after a boot
# (`src/fingerprint.rs`). Already resolved here through a dev-dependency, so
# nothing new is fetched — but `cargo run` did not compile it before this.
# The digest behind `NOTICE`'s record of every committed binary file
# (`src/sourcegate.rs`).
sha2 = "0.10"

[dev-dependencies]
Expand All @@ -180,12 +177,6 @@ toyos-sched = { path = "toyos-sched" }
# The Bulk-Only phases, so the harness judging a wedge reads the word
# `toyos_xhci::bot::Phase` declares instead of spelling it a second time.
toyos-xhci = { path = "toyos-xhci" }
# The second reader `pkg_install_gbae` is judged against: what is read back off
# the guest's volume is compared with a third party's decoding of the committed
# archive, never with `userland/pkg`'s own. The archive itself is committed
# under `tests/fixtures` and no test fetches anything.
flate2 = { version = "1", default-features = false, features = ["rust_backend"] }
tar = "0.4"

[patch.crates-io]
loom = { git = "https://github.com/ToyOSOrg/loom", branch = "toyos" }
Expand Down
55 changes: 0 additions & 55 deletions NOTICE
Original file line number Diff line number Diff line change
Expand Up @@ -215,61 +215,6 @@ and forbids selling them by themselves. The licence reserves no font name, and
none of these files is modified.


tests/iced-counter/src/bin/iced-counter.rs — iced's own counter example, MIT
----------------------------------------------------------------------------

iced's `examples/counter/src/main.rs` at tag 0.14.0
(commit 3997291f318a8bc06fa522f5579836fb3feb94df), https://github.com/iced-rs/iced,
byte for byte
sha256 f1dcea1c15ce264ba73db644d9ad0d7ce5507d88a6ec49f9c7273d834c6ffa99
Copyright 2019 Héctor Ramón, Iced contributors
Licence text: licenses/MIT-iced.txt (upstream's LICENSE at that tag)
SPDX-License-Identifier: MIT

`toolkit_iced` builds it and carries it into `tests/toolkitcase`; no image a
`system.toml` builds ships it.


tests/fixtures/gbae-v0.2.0-* — gbae, MIT
-----------------------------------------

gbae-v0.2.0-toyos-x86_64.tar.gz 604,872 bytes
sha256 99fcd8a7263b5c25cd90cead1baaa7200ef272100fc2226e008a4e8205ba2916
SHA256SUMS 394 bytes
sha256 b13611227aac3fddb6daa20fdc9929fc96eeea46270f168887f9f6acb7403861

Copyright (c) 2025-2026 japabu
Upstream: https://github.com/Japabu/gbae, release v0.2.0
Licence text: licenses/MIT-gbae.txt
SPDX-License-Identifier: MIT

A Game Boy Advance emulator built for `x86_64-unknown-toyos`, and the release's
own sums file covering every asset of that release. `pkg_install_gbae` installs
the archive with `/system/bin/pkg` and runs the binary, which is what makes the
package path a thing that has been done rather than a thing that compiles.

gbae's own terms are read out of `gbae/LICENSE` **inside the archive**, so the notice
MIT requires travels with the bytes as well as sitting in `licenses/`. Copying,
distributing and sublicensing are permitted outright, so committing it here puts
no constraint on a ToyOS build the way `assets/DOOM1.WAD` does.

**These are committed because a test may not fetch.** Owner ruling, 2026-09-05:
*"do not use external resources as gbae for testing. we must keep our
dependencies minimal and stay independent."* They were downloaded once, by hand,
with

gh release download v0.2.0 --repo Japabu/gbae \
--pattern 'gbae-v0.2.0-toyos-x86_64.tar.gz' --pattern 'SHA256SUMS'

and checked with `shasum -a 256` against the release's own `SHA256SUMS`. Nothing
in this repository fetches them, and `gh` is a development tool no test runs.

`SHA256SUMS` is text and outside `assets/`, so `src/sourcegate.rs`'s two
populations do not walk it and only the archive has a row there. What holds it is
`tests/common/pkg.rs`, which refuses to run unless the archive hashes to the
digest above and that file carries the matching line.


tests/testcases/ — TinyCC's corpus, LGPL-2.1, and picoc, BSD-3-Clause
---------------------------------------------------------------------

Expand Down
4 changes: 2 additions & 2 deletions bootloader/src/bootnext.rs
Original file line number Diff line number Diff line change
Expand Up @@ -73,9 +73,9 @@ pub fn point_at_us(handle: Handle, system_table: &SystemTable<Boot>) {
/// The GPT partition GUID of the volume firmware loaded this image from.
fn our_partition(handle: Handle, system_table: &SystemTable<Boot>) -> Option<[u8; 16]> {
let bs = system_table.boot_services();
let image = bs.open_protocol_exclusive::<LoadedImage>(handle).ok()?;
let image = crate::protocol::exclusive::<LoadedImage>(bs, handle).ok()?;
let device = image.device()?;
let path = bs.open_protocol_exclusive::<DevicePath>(device).ok()?;
let path = crate::protocol::exclusive::<DevicePath>(bs, device).ok()?;
hard_drive_guid(path.node_iter())
}

Expand Down
23 changes: 4 additions & 19 deletions bootloader/src/loaderlog.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ use core::fmt;
use uefi::proto::media::file::{Directory, File, FileAttribute, FileMode, RegularFile};
use uefi::proto::media::fs::SimpleFileSystem;
use uefi::proto::media::partition::PartitionInfo;
use uefi::table::boot::{BootServices, OpenProtocolAttributes, OpenProtocolParams, SearchType};
use uefi::table::boot::{BootServices, SearchType};
use uefi::{prelude::*, CStr16, Handle};

/// The loader's first line, which is also the file's: [`open`] runs before it.
Expand Down Expand Up @@ -111,8 +111,7 @@ pub fn with_volume<T>(
) -> Result<T, alloc::string::String> {
let bs = system_table.boot_services();
let handle = volume_handle(bs, guid)?;
let mut fs = bs
.open_protocol_exclusive::<SimpleFileSystem>(handle)
let mut fs = crate::protocol::exclusive::<SimpleFileSystem>(bs, handle)
.map_err(|e| alloc::format!("the log partition would not open ({e})"))?;
let mut root = fs
.open_volume()
Expand All @@ -138,7 +137,7 @@ pub fn open(system_table: &SystemTable<Boot>, guid: &[u8; 16], truncate: bool) {
Ok(handle) => handle,
Err(why) => return refused(format_args!("{why}")),
};
let mut fs = match bs.open_protocol_exclusive::<SimpleFileSystem>(handle) {
let mut fs = match crate::protocol::exclusive::<SimpleFileSystem>(bs, handle) {
Ok(fs) => fs,
Err(e) => return refused(format_args!("the log partition would not open ({e})")),
};
Expand Down Expand Up @@ -216,21 +215,7 @@ pub fn close() {
/// The unique GUID of the GPT partition `handle` sits on. `None` is a handle
/// that publishes no partition record, or one on a table that is not GPT.
fn unique_guid(bs: &BootServices, handle: Handle) -> Option<[u8; 16]> {
// `GetProtocol`, never `Exclusive`: this runs over every filesystem on the
// machine, and EXCLUSIVE would call `Stop` on whatever driver holds each.
//
// SAFETY: `open_protocol`'s obligation is that this handle and its protocol
// stay installed until the `ScopedProtocol` drops. Nothing between the two
// can uninstall either: the loader is the one image running, it registers
// no event callback, and it calls no boot service that connects or
// disconnects a controller.
let info = unsafe {
bs.open_protocol::<PartitionInfo>(
OpenProtocolParams { handle, agent: bs.image_handle(), controller: None },
OpenProtocolAttributes::GetProtocol,
)
}
.ok()?;
let info = crate::protocol::get::<PartitionInfo>(bs, handle).ok()?;
let entry = info.gpt_partition_entry()?;
// A `repr(packed)` entry, where a reference into it would be unaligned.
Some({ entry.unique_partition_guid }.to_bytes())
Expand Down
Loading
Loading