tests: the measured schedule — Fast is every PR, then Nightly, then Weekly; 15 never-caught tests and the kernel code only they armed deleted - #564
Conversation
…never-caught tests deleted The owner adopted a schedule from what each guest test has caught: 426 of 524 CI-scheduled guest tests never caught a real defect and were 87% of guest time. - `src/tiers.rs`: `Tier` gains `Weekly`, and a run's `Reach` (plain, `--nightly`, `--weekly`) selects its own tier and every narrower one. A `Schedule` is every registered name at its one tier: a name registered twice is refused by name, and asking the tier of an unregistered one is refused by name. The harness builds it from the shared boot's discovered binaries and the three declared registries, which replaces `check_no_collisions` and `check_registration`'s duplicate loop; the redlist asks it what is registered, and `--list` prints every test at its tier. - `src/testargs.rs`: `--weekly`; `--nightly --weekly` is refused (the second would be read by nothing), and either reach beside `--audio-gate` or `--metal` is refused — `--metal --nightly` used to be accepted and its `--nightly` dropped. - `nightly.yml` runs Monday to Saturday at 03:00 and Sunday at 03:00; the guest job reads which schedule started it (`src/ci.rs`'s `guest_reach`) and runs `--nightly` or `--weekly`, and a schedule the file does not declare is a red step. Same jobs, one workflow. - Every row's tier is its bucket's: Fast is the shared boot and the 22 machine and screen tests of the every-PR bucket. A boot group takes its most frequent member's tier, so six weekly-bucket riders stay Nightly on the boot they share. The audio and timing rows `wt/toyos-notiming` rewrites keep the tier they had, and the fix-first rows are untouched. - Deleted with their harness code, guest binaries, duration rows, redlist rows and the issues that existed only for them: console_line_atomicity, fat_backing_revoked, home_budget_refusal_retried, i8042_keyboard, klogd_panic_halts, launcher_refusals, log_conservation_smp4, log_conservation_smp8, quiesce_dump_holds_the_stopped, quiesce_wakes_on_the_last_exit, screen_early_panic, so_cache_refusals, sshd_fail_closed, usb_disk_index_stable, wall_clock_file, xhci_hid_break, xhci_hotplug. `quiesce_last` loses the exiting thread only the last-exit test held. - `syscall_window_nmi`, `syscall_window_nmi_controls` and `dump_nmi_probe` stay, Weekly: what they guard is the frame an x86 CPU builds for an NMI at CPL 0 on a user `rsp`, which only a CPU produces. - Stale tier reasons in the registration comments are deleted. Filed: the seven kernel actuators no test arms any more, and three harness helpers nothing calls. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ts for a bare pass Two defects only a guest caught, now caught on the host: - B23, #513's `thread_join` answering NotFound: the wait's predicate collected the zombie and the syscall collected again. The kept answer moves into `toyos_proclife::join::Join`, which asks the table until one ask settles and returns that ask after it; `sys_thread_join` asks it under the table lock through `process::ask_join`, which replaces `wait_thread_zombie`. `a_join_asked_after_it_collected_keeps_its_answer` reds on the re-collecting shape. - B09, the blocked-task dump served on a syscall-driven pass: `Entered` and its decision, `may_serve`, move into `sched/dump_request.rs`, the file `kernel-loom` already compiles, and `dump.rs` mints its proof from it. `only_a_pass_entered_at_depth_zero_takes_the_request` reds on a pass entered above zero taking the request. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ore now The two models over `Tally` spawned the ISR, and `Tally::record` begins with its saturation check's load. Loom 0.7 explores only the first schedule when a spawned thread's first operation is a load: measured on a bare loom `AtomicU64`, two adds after a leading load gave 1 execution against 10 without it. So neither model checked an interleaving of the real word, and A16's shape — an empty interrupt counted as one that carried until the burst corrects it — passed both. Both now spawn the reader and run the ISR on the model's own thread, and `explored` refuses a model that ran one execution. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…m that it could not goes With the models exploring, `a_counted_interrupt_carries_its_bytes_with_it` reds with `record`'s release and `read`'s acquire both weakened to `Relaxed`: the measurement that said loom could not see the weakening was taken on a model that ran one execution. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…one execution Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…one execution Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
Missing at 6f9a317: CI has no conclusion (run 36354938564 NOT READY FOR REVIEW |
`writeback_durability`'s CARRIES row still named `test_rs_fat_backing_revoked`, which this branch deleted, so every run panicked in the catalogue check before its first boot. That check ran after `--list` returned, so the list was green over it; it now runs before `--list`, `--debug` and `--audio-gate`. The test runner's `CONSOLE_JOBS` held only `test_rs_console_line_atomicity`, also deleted, so it goes and every job's stdin is a pipe. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01W6rME2DoqwjcYFStYHHY4j
… the word first The filed claim, that a spawned thread opening with a load explores one execution, is false: `dump_request`'s spawned threads open with `DumpRequest::update`'s load and explore 16 to 5777 executions. Loom 0.7.2 keeps one last access per atomic, and a thread's own load overwrites it, so a store is never raced against another thread's earlier load of the same word. The issue now says that, and lists every loom model whose spawned thread opens with a load with its measured execution count; `explored`'s doc in `i8042_tally.rs` says the same. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01W6rME2DoqwjcYFStYHHY4j
The tier tables keep main's deletions (`screen_recoverable_untouched`, `screen_survived_panic_not_blamed` and `heap_ceiling_recovery`, with panic recovery) and this branch's (`screen_early_panic`, `klogd_panic_halts`). Main's new rows keep main's tiers: `netd_refused_accept` Fast, and `klogd_fault_halts`, the four syscall-death rows and `heap_ceiling_bounds` Nightly. Retiered rows keep this branch's tier: `netd_refused_pipes` Nightly, `klogd_hosted` Weekly. `src/ci.rs` keeps `guest_reach` and drops `suite_args`'s host-slot doc, which main deleted with the slots. The actuator issue loses `usbd-panic`, which went with usbd, and is six now. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01W6rME2DoqwjcYFStYHHY4j
Review, round 2, at 4919fbdRound 1 gave no findings: it was NOT READY FOR REVIEW because measurements were missing. Here is where those stand now.
handle_basic is main's
BLOCKER
NOTE
REMOVE
SEND BACK |
The six actuators nothing arms go, with every line only they reached: quiesce-last-exit (the exit hold in SYS_THREAD_EXIT, and `Last` collapses to the one park it still stages), quiesce-dump (`serve_for_the_stop`, `DumpRequest::file_and_take` and its loom model), so-cache-tiny (the tiny budget), xhci-hid-break-first/-late (`stage_break`, `break_at` and the completion count only they read) and klogd-panic. The design-debt issue that recorded them goes with them. The five defect records the deletions closed are restored: deleting a test is no evidence about a defect. Each is `open`, since no redlist row disables anything for them now, and the exit clauses that named a deleted test as the witness are deleted. `fat_backing_revoked` and `launcher_refusals` come back as Weekly guest rows, with their binaries, the FAT oracle in `tests/common/volumes.rs`, their skips, carries, dispatch arms and duration rows. Neither claim can be held on the host without a new abstraction: the FAT revocation is `FatFs::delete`/`revoke` and `FatBacking::read_page` in the kernel adapter, which no host test compiles, and the launcher's refusals are init's syscalls against the kernel's `SYS_NAMESPACE_BUILD` answer, with init built only for the ToyOS target. The ten harness self-checks that boot nothing leave the guest tiers and become libtest tests: `tests/checks.rs` includes `tests/toyos.rs` under the test harness, where its `cfg(test)` module runs them, and the host CI job runs that target. `nvme_image_is_held_by_one_guest` names its claims under CARGO_TARGET_TMPDIR, since a claim is a name and no run directory exists outside a suite run. Smaller findings: `Schedule::tier` becomes `contains`, `guest_reach`'s event decision is a function a host test drives (a run no schedule started reaches nightly), `woken_by_the_held_thread` is inlined into its one caller, `panic_halts_the_others_first` is Nightly and `hda_two_live_refused` Weekly by the data, the two filed issues name an owner, and the REMOVEd sentences are deleted. Three issues are filed: the two mutations only a nightly guest catches (`drain_irqs`'s `Entered`, the join's write-back) and the settled join that still locks the process table. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01W6rME2DoqwjcYFStYHHY4j
Cargo.toml: main's deletion of the target-lexicon patch, beside this branch's `toyos-checks` target. src/redlist.rs: main's six new rows, less the four whose tests this branch deletes (`quiesce_dump_holds_the_stopped`, `quiesce_wakes_on_the_last_exit`, `so_cache_refusals`, `usb_disk_index_stable`). Main's `c_hello` and `doom_frames` keep main's tier. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01W6rME2DoqwjcYFStYHHY4j
`tests/toyos.rs` is a `harness = false` target, so the ten checks' bodies left there were dead in it, and clippy's `cfg(test)` pass over it drops a `#[test]` without a harness. The bodies, and `hand_rolled_deaths`, `needs_actuators`, `driven_binaries` and `DRIVEN_AND_SHARED`, which only they read, move into `tests/checks.rs`'s `checks` module, which only the libtest target compiles. `idle_trip_verdict` takes its test's name, `i8042_quarantine_verdict`. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01W6rME2DoqwjcYFStYHHY4j
…actuator `the_asker_owns_the_report_it_asks_for` modelled `DumpRequest::file_and_take`, which went with `quiesce-dump`, so its execution count describes nothing. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01W6rME2DoqwjcYFStYHHY4j
Review, round 3, at 3b94e06CI: Round-2 BLOCKERs
BLOCKER
NOTE
REMOVE
SEND BACK |
…lock `run_exit_status` boots nothing and gates `Tally::exit_code` and the result line this branch rewrote, so it becomes a `#[test]` in `tests/checks.rs` and its guest row, dispatch arm and duration line go. Under a patch making `exit_code` return 0 for a suspended-only tally it reds with "a suspended run exits 0, and it has to be 2". `Join::ask` takes the collect as a closure and calls it only while the join is unsettled; `process::ask_join` takes `PROCESS_TABLE` inside that closure, so a settled join answers without the lock, and the decision is `toyos-proclife`'s where a host test reaches it. `a_settled_join_does_not_take_the_table_again` reds when the collect runs on a settled join, with the answer still kept. The issue that recorded the regression is closed. `DRIVEN_AND_SHARED` returns beside `RUST_SKIP` in `tests/toyos.rs`, the partition's two halves in one file, byte-identical to main's block; the libtest-free target does not read it, so it carries the one `allow`. `elf/cache.rs` uses `BUDGET_BYTES` itself. The restored defect issues each name the reproducer at `1808fb8d` their fix is shown against, and home-budget names its owner. Chronology in `tests/checks.rs`, the `screen_decoder` note under `SCREEN_TESTS` and the fix's story in the loom issue are deleted. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01W6rME2DoqwjcYFStYHHY4j
#571's removal of `handle_basic` from `DRIVEN_AND_SHARED` merges on its own, since the list is back in `tests/toyos.rs` byte for byte as main had it. `kernel-loom/tests/i8042_tally.rs` takes main's side whole: #567 moved every loom model onto a fork that races a store against every thread's last load, and asserts that the tally models reach their named cases, so this branch's reordering and its `explored` guard, which worked around the gap, go. The branch's issue about that gap (`loom-never-moves-a-store-before-a-load-another-thread-made-first`) closes with it, since #567 meets its exit. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01W6rME2DoqwjcYFStYHHY4j
…rences from it and the harness issue The park issue's slug and title said "threads running" beside the held one, but every record carries 2 thread(s) and one of the two is the held thread by construction — so the stop gave up on one thread beside it, and "running" never held as a scheduler state. Renamed to issues/kernel/quiesce-wakes-on-the-last-park-gave-up-on-one-thread-beside-the-held-one.md and the redlist row moved with it. Deleted the park issue's false inference that 0 open block operations means neither thread was parked: stop_if_blocked refuses a thread parked in SYS_FSYNC's OpenUpdate, which adds 0 to in_flight, so logd parked between refused fsync attempts is a candidate the records cannot exclude. Added it as a second labelled hypothesis beside the dispose_yield one. Deleted the false claim that none of four branches touch the guest's stop path (PR #510 changes fat32_adapter's refused-write path, where an fsync park happens), and the stale count of disabled guest tests that PR #564 moves. Deleted the harness issue's false claim that returned_to_firmware runs before the boot console is read (power.rs judges the boot console and the drained tail first) and its false claim that every writers-issue sighting carries the same never-asked message (a58abf5's give-up line was never recorded). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01W6rME2DoqwjcYFStYHHY4j
…d's name open Answers the SEND BACK on #575 at d346d9d. - fsd's new name is open with the owner (candidate `fileserver`, `files` kept for the file manager); the invented rename of the file manager goes. - The rename is stage 1, first after #536, briefed as an ABI brief since it touches toyos/src, toyos-abi/src, userland/libc/src and the rust fork's ToyOS files. Its exit is a case-insensitive substring search over the six daemon names and a letter-bounded search for `init`, each with an explicit exclusion list judged per match; issue bodies are excluded as recorded evidence. Measured outside issues/ at 62e7e8c: 3641 daemon substring hits (3419 outside the exclusions), 2289 `init` substring hits, 1589 letter-bounded (1073 outside the exclusions). - Stage 2's exit names the crate `toyos-supervisor` and its decisions, now including the stop-order derivation and a host test refusing an undeclared cycle; it is unmet today and cannot go vacuous under the rename. - Stage 3's exit adds a two-service reverse-order test that reds on forward and all-at-once order. - Stage 4's exit names the five claims the stop's coverage must assert, by a host test or a guest test at Tier::Fast or Tier::Nightly with no redlist row, so it cannot be met by deleting tests; the per-test lists that conflicted with #564 and #574 go. - The power-broker track loses its false parenthetical and item 1: toybox holds the `power` connector, not the bit. - Every REMOVE the review listed is taken. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01W6rME2DoqwjcYFStYHHY4j
Review, round 4, at 617e934CI: The orchestrator's guest runs at 617e934, clean tree:
Round-3 BLOCKER
Round-3 NOTEs and REMOVEs
BLOCKER
NOTE
REMOVE
SEND BACK |
src/redlist.rs keeps main's ftruncate_flush_race, quiesce_stops_the_machine and quiesce_wakes_on_the_last_park rows, drops quiesce_dump_holds_the_stopped and quiesce_wakes_on_the_last_exit, whose tests this branch deletes, and takes #554's removal of the xhci_flap row. The writers issue #574 renamed stays expected-red with main's exit, since quiesce_stops_the_machine's row cites it; its opening sentence named the deleted quiesce_dump_holds_the_stopped as booting quiesce_writers and goes. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01W6rME2DoqwjcYFStYHHY4j
…s read `toyos_proclife::join::Join` keeps its answer in a `Cell` and is asked through `&self`, so `sys_thread_join` holds one join and its `ask` closure borrows it: there is no copy to take out and write back after each ask. `a_join_asked_after_it_collected_keeps_its_answer` now runs the syscall's shape, one join shared by the first ask, the wait's predicate and the ask after the wait, so the mutation that keeps no answer reds a host test and `issues/build/a-thread-join-keeping-its-answer-is-gated-only-by-a-nightly-guest.md` meets its exit and goes. `issues/build/a-settled-thread-join-taking-the-table-lock-again-is-gated-by-nothing.md` records that whether `ask_join` takes `PROCESS_TABLE` inside `collect` is held by no test. `DRIVEN_AND_SHARED` is `#[cfg(test)]` rather than allowed dead, so it is compiled only into `toyos-checks`, and the lint names it if `suite_split` stops reading it. `run_exit_status`'s doc loses the sentence about `--land`'s gate, which is retired. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01W6rME2DoqwjcYFStYHHY4j
…under cfg(test) `cargo run -- --clippy` runs `cargo clippy --workspace --all-targets`, which compiles the `harness = false` target `toyos-build` with `cfg(test)` set too. Under `#[cfg(test)]` the list is compiled there with no reader, and the gate fails with "constant `DRIVEN_AND_SHARED` is never used" (`-D dead-code`), so `cfg(test)` does not tell the two targets apart and the allow comes back. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01W6rME2DoqwjcYFStYHHY4j
Review, round 5, at 9b2645eCI: The orchestrator's guest runs at 9b2645e, on a clean tree:
Round-4 BLOCKER
Round-4 NOTEs
NOTE
REMOVE
LAND AFTER NAMED CHANGES |
…issue, two false test-replica claims removed
The host test only replicates sys_thread_join's shape, so the syscall's
answer-keeping stays gated by nothing but the nightly guest fpu_isolation;
record that on the existing table-lock issue rather than filing a new one.
Delete the comment claiming to describe "sys_thread_join's path" (it
describes the test's replica of it) and the claim that no caller holds a
copy to write back (describes the deleted implementation). Drop the issue's
two unsupported claims ("every test passed", "costs contention ... not a
wrong answer") that no run backs.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01W6rME2DoqwjcYFStYHHY4j
origin/main brought #557 (clipboard fix), which registers metal_sim_hostile_clipboard at Fast beside the metal_sim_window_drag row this branch moved to Weekly. Kept #564's move and #557's own row and tier for the new test, per this branch's stated rule that a row main added keeps main's tier. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01W6rME2DoqwjcYFStYHHY4j
#564 landed on main since this branch was cut and deleted 15 never-caught tests, five of them pre-existing redlist rows this branch did not touch: console_line_atomicity, quiesce_dump_holds_the_stopped, quiesce_wakes_on_the_last_exit, so_cache_refusals, usb_disk_index_stable. Kept main's deletions for those and this branch's own three additions (quiesce_leaves_the_volume_whole, syscall_window_nmi, user_copy_races_munmap) in src/redlist.rs, in the file's existing order. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01W6rME2DoqwjcYFStYHHY4j
#564 (the measured schedule) moved the root_* boot-image group's tiers (root_candidate_malformed, root_named_but_absent, root_named_twice to Weekly; root_chunk_refused, root_candidate_overlaps, root_named_twice_on_the_boot_disk to Nightly; log_partition_identity to Weekly) while this branch changed root_chunk_refused's profile and added root_chunk_refused_on_a_usb_stick at Fast, redlisted. Kept #564's tiers for the rows it moved and this branch's Fast registration for the new row, which #564's measured buckets and PR-body exceptions do not cover (it did not exist when that report was measured). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01W6rME2DoqwjcYFStYHHY4j
#564 deleted `quiesce_wakes_on_the_last_exit`, `quiesce_dump_holds_the_stopped`, their actuators `quiesce-last-exit` and `quiesce-dump`, `quiesce_last`'s exiting thread, and collapsed `quiesce::last::Last` to the park. This branch had edited all of them only to carry its new `quiesce-last-teardown` beside them; those edits have no purpose without their subjects, so the deletions are taken. `quiesce-last-teardown` and `quiesce_wakes_on_the_last_teardown` are this branch's own, not something #564 deleted: they are the guest check that the stop waits for a teardown in flight (the last one out stays in its process until `torn_down`). So they stay, and with them `Last` stays an enum of two (Park, Teardown), `hold` keeps its `last` argument and `sys_nanosleep` passes `Last::Park`, and `woken_by_the_held_thread` stays a helper with two callers. - kernel/src/actuator.rs: `quiesce_last_exit` and `quiesce_dump` go (main); `quiesce_last_teardown` stays (branch). - kernel/src/quiesce.rs: `last` keeps the branch's claimed-id hold, `ALONE` and the `may_yield` refusal; `Last::Exit` goes. - kernel/src/syscall/proc.rs: main's `hold()` becomes `hold(Last::Park)`. - tests/common/power.rs: `quiesce_wakes_on_the_last_exit` and `quiesce_dump_holds_the_stopped` go (main); the park and teardown verdicts keep the branch's `counts … alone` and teardown `exit:` checks. - tests/toyos-rust-tests/src/bin/quiesce_last.rs: the exiting thread goes (main); the teardown child stays (branch). - tests/toyos.rs: `quiesce_wakes_on_the_last_teardown` registered Nightly beside `quiesce_wakes_on_the_last_park`, which #564 moved to Nightly: same binary, same verdict, same disabling issue, and a new row has no catch record to put it anywhere else. Its CARRIES row and dispatch arm stay; the exit and dump rows go. - toyos-quiesce `LAST_THREAD`, tests/quiescelastcase/system.toml and the two quiesce issues: name the teardown actuator beside the park, not the exit; the "in a Fast tier" of the gave-up issue's exit conditions is deleted, since both its tests are Nightly now. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01W6rME2DoqwjcYFStYHHY4j
src/redlist.rs conflict: main's #564 deleted so_cache_refusals and usb_disk_index_stable rows (their tests are gone); this branch's redial fix deleted swap_crash_rolls_back, swap_netd and lan_swap rows (their tests now pass). Both sets of deletions kept; no row this branch changed was reverted. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01W6rME2DoqwjcYFStYHHY4j
#564's schedule and its 15 deletions meet this branch's storage move. Where #564 deleted a test or the kernel code only it armed, the deletion stands; where this branch deleted a test #564 retiered, this branch's deletion stands; every surviving row takes #564's tier, and the five this branch adds (fsd_restart, fsd_end_at_mount, fsd_claim_held, fsd_two_data, blockd_serves_nothing) keep the Fast tier they were added at, as #564 kept the tier of every row main added. - kernel/src/actuator.rs: quiesce-last-exit and quiesce-dump go (#564); fat-flush-meta-refuse, resize-evict-window and resize-fault-refuse stay gone (this branch). - kernel/src/syscall/machine.rs: the stop serves no dump (#564) and syncs no filesystem (this branch): neither block survives. - toyos-quiesce/src/lib.rs: this branch's FILES_MS, FLUSH_MS and SYNC_MS, and #564's LAST_THREAD doc naming quiesce-last-park alone. - tests/common/power.rs: quiesce_dump_holds_the_stopped goes with its actuator; quiesce_wakes_on_the_last_park is #564's inlined body with this branch's stop-record ordering in place of "Syncing filesystems...". - tests/common/storage.rs and tests/toyos-rust-tests/src/bin/so_cache_policy.rs: so_cache_refusals and its binary go (#564); this branch's /tmp retarget of them serves no surviving test. The so-cache-tiny actuator went with them. - issues/filesystem/home-budget-refusal-retried-is-red-on-every-nightly.md stays deleted: its test and binary are gone on both sides, and the reproducer #564's exit names is the kernel's /home over its NVMe driver, which this branch deletes. The fsync-budget-spent race it pointed at is still tracked by the partition-claim-gives-up issue. - issues/README.md: boot-media is gated by esp_filesystem, kernel_log_file, log_partition_layout and log_partition_identity, plus toybox_cp_volume: wall_clock_file went in #564, log_backing_read_error and boot_volume_metadata_error on this branch. - tests/toyos.rs: RUST_SKIP, MACHINE_TESTS, CARRIES and the dispatch lose so_cache_refusals, quiesce_wakes_on_the_last_exit and quiesce_dump_holds_the_stopped (#564) and keep this branch's deletions (cache_eviction, the writeback trio, page_cache_partition_offset, quiesce_leaves_the_volume_whole, ftruncate_flush_race, log_backing_read_error, boot_volume_metadata_error); the comment of the deleted ftruncate_flush_race row goes with it. #564's tier for block_duplicate_id, partition_claim_departure, quiesce_refuses_a_second_shutdown, quiesce_wakes_on_the_last_park, late_storage_connect, log_partition_layout, the root_* rows, log_partition_identity, tls_rebase_window, sysret_ss_reload, userdev_residue_is_its_own and blockd_lends_within_its_bound, beside this branch's comments. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01W6rME2DoqwjcYFStYHHY4j
…-notiming Where #564 deleted a test or helper this branch edits, the deletion stands: home_budget_refusal_retried (with this branch's `fsync-budget-spent: staged a spent budget on` record in kernel/src/object/ops.rs, which only that test read), usb_disk_index_stable, wall_clock_file, quiesce_wakes_on_the_last_exit and quiesce_dump_holds_the_stopped. wallclock's `after_the_base` stays: it still bounds wall_clock_zone. Rows both sides changed take this branch's Sched and comment and #564's tier (netd_hostile_peer: Parallel, Weekly; hda_two_live_refused: Weekly; panic_halts_the_others_first: Nightly). Rows #564 left to this branch keep this branch's form. Tests this branch deleted stay deleted. The harness's host checks live in tests/checks.rs now: stall_is_not_a_verdict is renamed a_stall_stays_red there with this branch's backstop case, i8042_quarantine_verdict goes with the idle-trip check this branch deleted, and metal_audio_judges joins them as a libtest test instead of a guest row. `schedule` and `--list` lose AUDIO_TESTS, `--audio-gate` leaves testargs beside `--weekly`, and a reach is refused beside `--metal` only. Sentences the merged tree makes false are deleted: the audio helpers the-harness-carries-three-helpers-nothing-calls named as this branch's to delete, and quiesce_wakes_on_the_last_exit in timing-verdicts-ruled-off-qemu-have-no-metal-arm. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01W6rME2DoqwjcYFStYHHY4j
…t back i8042_health_cadence's dead registration `git log -p -S i8042_health_cadence` on this branch: this branch's own "No QEMU test measures time" commit (ad3448d) deleted the test in full — registration, CARRIES binding, dispatch arm and its issue — ruling its verdict a timing cadence over a real span with no event to wait on instead. origin/main never deleted it (it still carries all three there). The later merge of main's #564 (the measured schedule, which retiered several neighbouring i8042 entries in the same MACHINE_TESTS hunk) reintroduced only the registration line and its comment, while correctly keeping the CARRIES entry and match arm deleted — a partial revert of ad3448d left by that merge's conflict resolution. `cargo test --test toyos-build -- --list` compared against every match arm in `run_machine_test` (the site "unknown input test" comes from) and `run_screen_test` otherwise agrees everywhere; this was the one gap. Fix: delete the orphaned registration and comment. No dispatch to restore — main's version is exactly the timing verdict #562 ruled out, and its issue close and tracker mention already reflect the deletion. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The guest suite runs on the schedule the owner adopted from what each test has caught: 426 of 524 CI-scheduled guest tests never caught a real defect, and they were 87% of guest time.
The schedule
Every price is the sum of the report's per-test medians (
table_pertest.md, "cost s"). "Before" is the report's own tier column; "after" iscargo test --test toyos-build -- --listat 9b2645e, each name joined to its median. Counts are runnable tests; disabled rows run nowhere and are counted apart.cargo test, every PR)--nightly)--weekly)cargo test--nightly--weeklyUnpriced after, and summed as 0: with no row in the report, in Fast,
c_hello,doom_framesandnetd_refused_accept, whichmainadded at Fast, and eight C tests of the shared boot (03_struct,33_ternary_op,79_vla_continue,85_asm_outside_function,94_generic,98_al_ax_extend,122_vla_reuse,127_asm_goto); in Nightly,heap_ceiling_bounds,heap_over_ceiling_halts,klogd_fault_halts,lock_across_switch_halts,syscall_fault_haltsandsyscall_panic_halts, whichmainadded at Nightly. With a row whose median isn/m:abuse_shm_lengthin Fast, andaudio_tone_loadandtls_rebase_windowin Nightly.Where a registration differs from its bucket, the reason is one of these:
metal_sim_scanout_wc,metal_sim_ipc_hostile_peer,metal_sim_compositor_stall,metal_sim_client_death,i8042_no_spurious_wakeandlocale_detect_unrecognizedare weekly-bucket riders on a nightly boot, and stay Nightly.wt/toyos-notimingrewrites keep the tier they had (below).mainadded keepmain's.Decisions
src/tiers.rs:TiergainsWeekly, and a run'sReach(plain,--nightly,--weekly) selects its own tier and every narrower one. A test's tier is declared once, as the word in its registration row.Scheduleis every registered name at its one tier: a second row for a name is refused by name. The harness builds it from the shared boot's binaries and the three declared registries; it replacescheck_no_collisionsandcheck_registration's duplicate loop, answers the redlist's "is this registered" (contains), and drives--list.src/testargs.rs:--weekly.--nightly --weeklyis refused, because the second would be read by nothing. Either reach beside--audio-gateor--metalis refused too:--metal --nightlyused to be accepted and its--nightlydropped.nightly.ymlhas two crons,0 3 * * 1-6and0 3 * * 0, and nothing else changes in YAML. The guest job reads the schedule that started it from$GITHUB_EVENT_PATHand runs--weeklyon Sunday's and--nightlyon the other, on a dispatch and off a runner (src/ci.rs'sreach_of_event, host-tested). A schedule the file does not declare is a red step. A test holds the two crons innightly.ymlagainst the two insrc/ci.rs.cargo test --test toyos-build -- --weekly.not run without --nightly:/--weekly:, and, N held back for --nightly, M held back for --weeklyin the result line.--listsays so. EveryCARRIESrow is checked against the built catalogue before--list,--debugand--audio-gate, not only before the first boot.serial_vocabulary,suspend_detector,suspend_invalidates_a_verdict,stall_is_not_a_verdict,nvme_image_is_held_by_one_guest,control_regs_verdict,i8042_quarantine_verdict,suite_split,run_exit_status,nightly_tier_is_announced,screen_decoder) are libtest tests of a new target,toyos-checks:tests/checks.rsincludestests/toyos.rsunder the test harness and holds the checks and the helpers only they read.src/ci.rs'shostjob runs it, and so does every plaincargo test. No guest row, dispatch arm or duration line is left for any of them.DRIVEN_AND_SHAREDstays besideRUST_SKIPintests/toyos.rs, since the two lists are one partition, and its block is main's byte for byte. Onlytoyos-checks'suite_splitreads it, so theharness = falsetarget carries one#[allow(dead_code, reason = …)]on it.#[cfg(test)]in its place does not tell the two targets apart:cargo run -- --clippycheckstoyos-buildundercfg(test)too, and fails there with "constantDRIVEN_AND_SHAREDis never used" (EXIT=1).Deleted: 15 of the 26
console_line_atomicity,home_budget_refusal_retried,i8042_keyboard,klogd_panic_halts,log_conservation_smp4,log_conservation_smp8,quiesce_dump_holds_the_stopped,quiesce_wakes_on_the_last_exit,screen_early_panic,so_cache_refusals,sshd_fail_closed,usb_disk_index_stable,wall_clock_file,xhci_hid_break,xhci_hotplug.Each one went with its harness code, its dead helpers, its duration row, its redlist row and its CARRIES and RUST_SKIP rows. The guest binaries
console_line_atomicity,home_fsync_budgetandso_cache_policywent too,quiesce_lastlost the exiting thread only the last-exit test held, and the test runner'sCONSOLE_JOBS, whose one entry wastest_rs_console_line_atomicity, went: every job's stdin is a pipe now. So did the kernel code only these tests armed: the actuatorsquiesce-last-exit,quiesce-dump,so-cache-tiny,xhci-hid-break-first,xhci-hid-break-lateandklogd-panic, withquiesce::last's exit hold (Lastcollapses to the park it still stages),sched::dump::serve_for_the_stop,DumpRequest::file_and_takeand its loom model, the cache's tiny budget,HidDevice::stage_breakand its completion count, and klogd's staged panic.kernel/srcis net −133 lines.The three whose exit needs a run name their reproducer as it stands at
1808fb8d, this branch's base onmain:console_line_atomicitywith itsCONSOLE_JOBSstdin,so_cache_refusalswith theso-cache-tinybudget, andhome_budget_refusal_retried, whose file now names its owner, the orchestrator.quiesce-wakes-on-the-last-exit-lost-its-serial-ready-beside-other-guests(kind: finding) goes with its test.a-quiesce-writers-first-pass-outlasts-the-jobs-five-second-spin-upstaysexpected-redbehindquiesce_stops_the_machine, and its sentence naming the deletedquiesce_dump_holds_the_stoppedas bootingquiesce_writersgoes.Where coverage of a deleted test stands:
log_conservation_smp4/_smp8:kernel-loomlog_ring'sa_published_record_is_whole_and_read_onceanda_lane_publishes_whole_and_reuses_only_after_a_read;log_conservation_smp1remains, Weekly.wall_clock_file's retention:userland/logd/src/store.rs'swhole_old_boots_go_first_then_earlier_continuationsanda_flooding_boot_costs_its_own_middle_and_nobody_elses_start.xhci_hotplug:toyos-xhci's sima_device_plugged_in_is_enumerated_onceandunplugging_tears_the_device_down.xhci_hid_break:teardown.rs'sa_halted_endpoint_is_reset_cleared_and_delivering_againanda_recovery_the_controller_refuses_lets_the_device_go.klogd_panic_halts:klogd_fault_haltsdrives the klogd context andsyscall_panic_haltsthepanic!entry.sshd_fail_closed: sshd'sa_file_that_names_nobody_authorizes_nobodyholds the authorization half. The "never listens" half (userland/sshd/src/main.rs) has no gate.screen_early_panic:blackbox_early_panic_sealed_mutedreads the early panic off the panel, withoutcheck_colors.Kept, Weekly, and why:
syscall_window_nmi,syscall_window_nmi_controlsanddump_nmi_probe. What they guard (IST fix NMI and #MC get stacks of their own, because three instructions of syscall entry run at CPL 0 on the user's stack #234, the NMI dump) is the frame an x86 CPU pushes for an NMI taken at CPL 0 on a userrsp, and whether vector 2's IST index keeps it off that stack. Only a CPU produces that frame. The controls' catch data predates The NMI window control holds its victim inside the entry instead of hoping a spray lands there #470's rewrite of the control, so fresh runs judge it.dump_nmi_probe's verdict is also a 1 ms NMI budget, flagged forwt/toyos-notiming.fat_backing_revoked, the only gate on a revoked FAT32 backing never serving reallocated data, andlauncher_refusals, the only gate on init refusing hostile launches and surviving them with no census growth. Neither can be held on the host without a new abstraction. The FAT revocation isFatFs::delete'srevokeandFatBacking::read_pageinkernel/src/fat32_adapter.rs, and no host test compiles the kernel. The launcher's refusals are/system/bin/init'sserve_launchagainst real handles and the kernel'sSYS_NAMESPACE_BUILDanswer, and init builds only for the ToyOS target.Left to
wt/toyos-notiming(not touched here):doom_sound_flood,metal_sim_null_audio,latency_wake,short_sleep_livelock,sched_check_build, andi8042_health_cadence, whose verdict is a cadence over a real span.doom_music,soundd_log_stall,i8042_absent,null_sink_shipped_client,netd_stalled_peer,desktop_audio_client,hda_client_stall,hda_tone,kernel_heartbeat,xhci_slow_connect,audio_tone,audio_tone_load.panic_halts_the_others_firstis Nightly andhda_two_live_refusedWeekly, by their buckets.Host conversions: 5 of 13
kernel-looman_initiator_answers_while_it_waits(already there)b02-initiator-stops-answering:wait_turnstops servingkernel-looman_empty_interrupt_is_never_counted_as_one_that_carried, on main's model under #567's loom forka16-counted-on-the-way-in:recordcounts "carried" first and corrects after the bursttoyos-proclifea_poisoned_main_thread_takes_the_claim_and_ends_the_process(already there)b22-zombified-and-woke-nobody: zombify, name no wakeright: Process(kernel-loomonly_a_pass_entered_at_depth_zero_takes_the_request(new)b09-any-pass-serves: every pass may servetoyos-proclifea_join_asked_after_it_collected_keeps_its_answer(new)b23-join-collects-again: every ask collectsleft: Some(Err(NoSuchThread))Enteredand its decision (may_serve) move fromsched/dump.rsintosched/dump_request.rs, whichkernel-loomalready compiles.dump.rsmints its proof from that decision and re-exports the type.toyos_proclife::join::Join's, held in aCelland asked through&self.sys_thread_joinholds oneJoinand itsaskclosure borrows it, so no copy of the answer is taken out and written back.a_join_asked_after_it_collected_keeps_its_answerruns that shape: one join shared by the ask before the wait, the wait's predicate and the ask after it.Join::asktakes the collect as a closure and calls it only while the join is unsettled.process::ask_join, which replaceswait_thread_zombie, takesPROCESS_TABLEinside that closure, so a settled join answers without the lock, as main'sanswer.get().is_some() ||did. That decision istoyos-proclife's, where a host test reaches it:a_settled_join_does_not_take_the_table_againasks a settled join with a closure that panics. Underjoin-asks-when-settled, which calls the collect every time but keeps the first answer, it exits 101 with "a settled join took the table lock to ask again", anda_join_asked_after_it_collected_keeps_its_answerstays green.exploredguard, went in the merge. The issue this branch had filed about the gap went too, since Loom from a fork that races a store against every thread's last load #567 meets its exit.Not converted, and why:
i8042::service's record-then-bytes read order), A48 (completion::post_n's claim count), B43 (the scheduler's wait loop), and B27, B28 and B30 (the i8042 health verdicts inkernel/src/drivers/i8042/mod.rs;toyos-ps2holds only decoding).-> !call, not a decision any proclife function makes.Gates
At 9b2645e, after the merge of
origin/main(d4e4102):cargo test --libcargo test --workspace --exclude toyos-buildcargo run -- --clippycargo run -- --ci hostHost: 50 step(s), all green;toyos-checks11 passed)cargo test --test toyos-build -- --listcargo run -- --build-onlyHost arms. Each was applied as a checked patch, built, run, and reversed, and the tree was shown clean.
exit-code-suspended-is-zeroTally::exit_codereturns 0 for a suspended-only tallytoyos-checksrun_exit_statusjoin-asks-when-settledJoin::askcalls the collect on a settled join and keeps its first answera_settled_join_does_not_take_the_table_againb23-join-collects-againa_join_asked_after_it_collected_keeps_its_answerjoin-keeps-no-answerJoin::askreturns what it collected and keeps none of ita_join_asked_after_it_collected_keeps_its_answerleft: Some(Err(NoSuchThread))a16-counted-on-the-way-inan_empty_interrupt_is_never_counted_as_one_that_carriedchecks-held-back-unsaidtoyos-checksnightly_tier_is_announcedci-dispatch-runs-weeklya_run_no_schedule_started_reaches_nightlyleft: Ok("--weekly")tiers-contains-a-prefixcontainstakes a prefixonly_a_registered_name_is_containedGuest arms, each applied as a checked patch at b1d8472, shown to build with
cargo run -- --build-only(EXIT=0 each) and reversed:b23-join-collects-again,join-per-ask(sys_thread_joinbuilds a freshJoinfor every ask),b09-any-pass-serves,fat-delete-keeps-the-backingandinit-keeps-a-refused-frames-handles.Run by the orchestrator at 9b2645e (agents run no QEMU), on a clean tree:
cargo test: EXIT=0,test result: ok. 230 passed, 230 total (52.9s), 143 held back for --nightly, 117 held back for --weekly.--nightly fpu_isolation,xhci_flapandusb_boot_stick_pulled.--nightly fpu_isolation,thread_join failed,left: 18446744073709551614,right: 0:b23-join-collects-again, in its form for the&mut selfJoin::ask.join-per-ask(sys_thread_joinbuilds a freshJoinfor every ask).High-risk parts: the kernel's join and dump paths, the deleted kernel code, and the harness's selection.
thread_join, CI run 35360971260's dump panic); for the join's lock, main's ownsys_thread_join, whoseanswer.get().is_some() ||asked no table once settled; for the deletions, the compiler over every kernel feature set clippy checks; for the schedule, the report's independently measured buckets against--list.Unsure
github.event.schedulein the event payload is GitHub's documented field; the first Sunday is the proof.Join::ask's rather than ananswer()accessor read inask_join. An accessor would put the lock decision inprocess.rs, where no host test reaches it.Filed
issues/build/the-harness-carries-three-helpers-nothing-calls.mdissues/build/which-pass-drain-irqs-is-entered-from-is-gated-only-by-a-nightly-guest.mdissues/build/a-settled-thread-join-taking-the-table-lock-again-is-gated-by-nothing.mdNet lines against
origin/main, 1550 insertions and 3703 deletions in all:kernel/srcsrc/(the build system, its unit tests included)toyos-proclife,toyos-quiesce(unit tests included)userland/(the test runner)tests/kernel-loom/issues/.github/,Cargo.tomlkernel/CLAUDE.md,tests/CLAUDE.md🤖 Generated with Claude Code
https://claude.ai/code/session_01W6rME2DoqwjcYFStYHHY4j