No QEMU test measures time, and audio is judged on metal only - #562
Conversation
The owner's ruling: a QEMU guest test asserts order, completion, content and counts, and never how long something took; its only time-based ending is a harness ceiling. Audio is judged on metal and nowhere else. Deleted outright: - gate A's thorough tier (`--audio-gate`, `--slow-usb`, the nightly `audio` shards, `tests/audio-baseline.toml`, `tests/common/stats.rs`, `tests/common/hostload.rs`) and every QEMU audio test: `audio_tone`, `audio_tone_load`, `metal_sim_null_audio`, `null_sink_shipped_client`'s QEMU arm, `doom_sound_flood`, `doom_music`, `soundd_log_stall`, `desktop_audio_client`, `hda_tone`, `hda_client_stall`, `hda_two_live_refused`, the playback half of `inspect_reads_its_owners`, the wav capture (`-audiodev wav` is `none` now) and `tests/common/hda.rs`. - The pass-cost verdict of `sched_check_build` (`tests/common/passcost.rs`). - `kernel_heartbeat`'s CPU-mask and gap verdicts (`src/heartbeat.rs`). - `panic_halts_the_others_first` and `netd_stalled_peer`, whose only verdicts were a 100 ms stamp bound and a busy fraction over 2 s. Timing halves cut, the rest kept: `latency_wake`'s p99 bound, `i8042_absent`'s 300 ms A/B, `timer_calibration`'s ppm bound (metal only now), `tlb_shootdown_waits`' disarmed upper bound, the 3 s bounds and watchdogs of `exit_wait_storm` and `blocking_read_stress`, `poll_wake_pipe`'s 200 ms per-wake deadline, `netd_lookup_let_go`'s "at once", the USB settle ceiling and call/ladder upper bounds, and the flush-bound inference in `log_ring_keeps_the_owners_slots`. Metal-only rows, riding existing boots or three new ones priced in `tests/metal-profile.toml`: `wake_storm_cost`, `audio_idle_suspend`, `hda_tone`, `hda_client_stall`, `null_sink_shipped_client`, `doom_sound_flood`, `doom_music`, `soundd_log_stall`. Disabled rows and issues whose only content was a QEMU timing red go with their tests; what timing properties now have no metal arm is `issues/build/timing-verdicts-ruled-off-qemu-have-no-metal-arm.md`. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The owner's rulings: a QEMU test never judges time and plays no audio. Gate A is gone, so its caveat goes too. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
Review of #562 at Readiness. CI Net lines (
BLOCKER
NOTE
REMOVE
Rulings
Guest runs required (orchestrator)
SEND BACK |
…d for The owner's rulings, applied strictly: a QEMU test measures no time, and the harness's hang ceiling is the only clock left. A hang is red like any other red, named apart. In-guest deadlines become waits on the event: `Poller::wait` with no timeout, `recv` for `recv_timeout`, bounded retry loops without their bound, and the kernel's roster (`tests/toyos-rust-tests/src/roster.rs`) where a test needed a thread parked before its stimulus. The census is waited on to settle (`census_wait.rs`) rather than sampled after a sleep. netd_stream's helpers lose their deadlines. Converted: kill_while_blocked, handle_kill_policy, handle_lifetime, shm_release_reclaims, inbox_cancel_wakes, copy_out_races_munmap, compositor_client_death, compositor_stall, blockd_io, fat_backing_revoked, the window and input binaries, winit_loop, locale_gate, launcher_refusals, mmap_prot, every netd binary, the quiesce binaries, swap_claim_astray, tls_dtv_race, process_lifecycle, process_stats, futex_wake_counts, gpu_set_resolution, std_threading (a child held by its stdin), sched_stress, munmap_reissues_read_window and ftruncate_flush_race. Timing prints go. Host verdicts read over a clock become verdicts over events: the refused-flush window is a per-path count over the whole boot; the usb pull test awaits every probe's answer; flat drains before a judgement become waits on the line judged (lan, netcase, iommu, usb late disk and replacement, gpt, volumes); a halted machine is QEMU's word (`qemu::await_halted`, HLT with IF clear) for nested faults, klogd's halt and the iommu fault boot; screen_pager_keys pages back one key at a time; screen_recoverable_untouched judges through one dump after the child's end. Deleted with their clocks: i8042_health_cadence, i8042_quarantine_verdict and the idle-trip spin check, panic_key_holds, xhci_deaf_registers' budget floor, the usb `unverified - broke` bound, the stop's completion in quiesce boots, winit's idle-wake stage, process_stats' per-call floor, netd_hostile_peer's burst half and netd_caps' pending-connect burst (now established connections against the host's server). To metal only: watchdog_fed, dump_nmi_probe, blocking_read_window, tlb_shootdown_waits, syscall_cost. Restored: panic_halts_the_others_first as an order assertion anchored on the fatal path's own line past `stop_other_cpus`, closed by every vCPU halted; and hda_two_live_refused under `-audiodev none`. The metal audio judges get a host self-test (`metal_audio_judges`): each judge against a log crafted to pass it and logs crafted to fail it. `job_window` ends at soundd's flush on its last client leaving, `hda_tone` also holds `underruns` to 0, and `audio_idle_suspend` reds on a stream started with no client. Doom's sound and music tests go, with their configs, rows and the doom code only they reached. `usb-slow-device` goes with its only caller. Every property deleted or moved without a metal row, and every clock a QEMU test still waits on without deciding a verdict, is `issues/build/timing-verdicts-ruled-off-qemu-have-no-metal-arm.md`. Closed: `doom-sound-flood-played-full-scale-once`, `i8042-health-cadence-counted-three-lines-once-on-mains-nightly`, `harness-reads-after-a-flat-half-second-drain` (every flat drain before a judgement now waits on its line), `hda-tone-phase-check` (its capture is gone) and `idle-suspend-reds-on-a-loaded-host-and-on-main` (its subject was the QEMU arm). Citations of the deleted tests, gate A and `usb-slow-device` go with them. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
main deleted the host's guest and build slots; this branch deleted gate A. Every conflict is the two deletions meeting: - `tests/toyos.rs`: gate A's tier and its serial audio phase stay deleted; main's hunks there only dropped their slot guards. - `src/testargs.rs`: neither `--host-slots`/`--host-builds` nor `--audio-gate` is a suite flag any more, so neither is asserted as one. - `issues/build/there-is-no-attributed-session-ledger.md`: main's `records_holder` wording, without the hostload and audio-baseline sentences this branch deleted. - `issues/audio/thorough-tier-reds-on-unmodified-main.md`: stays deleted; main's one hunk rewrote a citation of `gate-a.yml` in a file whose subject is gone. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Conflicts, resolved: - src/redlist.rs: main's i8042_mouse entry kept; hda_tone stays gone with its issue file. - tests/common/power.rs: main's panic_reboots, klogd_death_resets and syscall_death_resets taken whole. - tests/common/qemu.rs: main's Sockets replace the qmp_socket path; the audio wav and the LIVE count stay gone. - tests/toyos.rs: main's check_ring0_read_unmapped, c_hello, doom_frames and the klogd/syscall death rows kept; main's deletion of screen_recoverable_untouched and screen_survived_panic_not_blamed kept; the doom sound, doom music and audio rows stay gone. netd_refused_accept joins the netcase comment. - userland/doom/src/main.rs: --frame-check kept, --sound-stress and --music-check stay gone. - tests/doommusiccase/system.toml: deleted here, modified on main. Kept, because doom_frames boots it; the sentences naming tests/doomcase and --music-check are deleted. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01W6rME2DoqwjcYFStYHHY4j
The merge kept the config for doom_frames and dropped it from every_shipped_boot_config_is_covered's list, which reds cargo test --lib. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01W6rME2DoqwjcYFStYHHY4j
The fatal CPU never halts: halt_all_cpus paints (seize claims the panel with or without a framebuffer), then holds the panel in hold_the_panel or page_forever, polling the keyboard with the reboot bound armed, until reboot_now resets the machine. So QEMU never shows every vCPU in HLT, and every await_halted wait went quiet at GUEST_QUIET: iommu_context_absent, iommu_empty_domain, nested_fault_is_recursive and panic_halts_the_others_first. - await_halted becomes await_reset. The boots pass panic-reboot-fast, and the wait ends when -no-reboot turns the bound's reset into QEMU's exit, or on a refused line. The exit counts only with a success status and the raw "panic: no key inside the bound" line on the console or the 16550's log. PANIC_REBOOTING moves from power.rs to qemu.rs, so both callers read one constant. - panic_halts_the_others_first keeps the shipped minute, waits for the fatal CPU's arm line, and then asks info registers -a until every vCPU but one is in cli; hlt, guarded by GUEST_QUIET. The records-past-the-stop order check is deleted: with stop_other_cpus emptied the console went quiet too, so no sibling record ever reached it to count. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01W6rME2DoqwjcYFStYHHY4j
wait_until_parked is a wake. The waiters it claims were still on their way back to the word when counts stored 1 and woke one of them, so they saw the new value, returned without parking, and the wake answered 0. Each waiter now counts itself in right before its futex_wait, and the test proceeds once all three have and the roster shows three child threads blocked. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01W6rME2DoqwjcYFStYHHY4j
…stop holds quiesce-last-park holds the named thread in sys_nanosleep. A park never enters it, so the kernel's 10 s staging budget panicked the boot: "quiesce-last-park: no thread named quiesce-last reached its syscall". Both threads now sleep for Duration::MAX, a span the stop always ends first. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01W6rME2DoqwjcYFStYHHY4j
|
Review of #562 at Readiness. CI The seven arms, each EXIT=1:
Net lines ( Round-1 BLOCKERs
BLOCKER
NOTE
REMOVE
SEND BACK |
The drain ended on the no-lease line, and READY, which netd prints after it, was never read, so the order check after it could not pass. The drain now ends on READY seen after the give-up. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01W6rME2DoqwjcYFStYHHY4j
Each probe names a binary no image carries, on purpose: the spawn's refusal is a kernel record, which is the load. test-runner answers it `error=entity not found`, and the waits read `exit=`, so they hung to the ceiling. One helper now sends the probe, ends its wait on any answer for it, and reds naming the answer unless it is the refusal. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01W6rME2DoqwjcYFStYHHY4j
…ounted home_budget_refusal_retried held every path to one retry across the whole boot. A budget that expires on its own on a starved host is a retry too, so that was a timing verdict. The actuator now records each refusal it stages with its run, and the host holds those to one per run. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01W6rME2DoqwjcYFStYHHY4j
The first ask was retried for 30 s of host clock with flat 1 s sleeps, because sshd could still be binding. The rig now awaits sshd's own `listening on port 22` line before handing itself out, under the harness ceiling, and every ask is made once. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01W6rME2DoqwjcYFStYHHY4j
`timed out after` is what a converted in-guest wait produces when the guest keeps talking, and the summary left it out of "N of those reds are the ceiling". It is now a named constant and `a_stall_stays_red` holds it. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01W6rME2DoqwjcYFStYHHY4j
claim_semantics and orphaned_by_unmap proved their waiters parked with a probe, which is itself a wake: the waiters it claims are on their way back to the word, and the 120 ms settle after it covered that. Both now count their waiters in and wait for the roster to show them blocked, as counts does. The spinners' settle becomes a wait for the roster to show a spinner running on every CPU but this one. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01W6rME2DoqwjcYFStYHHY4j
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01W6rME2DoqwjcYFStYHHY4j
… can be met The tracker gains inspect_plays' period sum, boot_from_power_on's host comparison and census_wait::settled's window. Two exits that named the deleted audio_tone_load and gate A now name a METAL row. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01W6rME2DoqwjcYFStYHHY4j
src/redlist.rs: main's five new rows are kept (lan_swap, log_ring_keeps_the_owners_slots, swap_crash_rolls_back, swap_netd, usb_transport_break), and this branch's four deletions stand (doom_sound_flood, hda_tone, latency_wake, sched_check_build). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01W6rME2DoqwjcYFStYHHY4j
…sues log_ring_keeps_the_owners_slots and usb_transport_break are disabled on main, so what this branch changed in each runs nowhere; each disabling issue now says what changed, so it returns with the test. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01W6rME2DoqwjcYFStYHHY4j
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01W6rME2DoqwjcYFStYHHY4j
Review, round 6, at ba14967Readiness. CI Net lines ( Round-2 BLOCKERs
Round-2 NOTEs and REMOVEs: all closed.
Attribution of the round-5 Fast reds
BLOCKER
NOTE
REMOVE
SEND BACK |
…ng the machine On main, foreign_fault drained 2 s into a local capture that was dropped at return, which swallowed netd's lines after the staged DMA fault. This branch deleted that drain, so netd's panic (Card::begin_pass on the claim's Io) reached run_test's window after log_origin's spawn record, and must_be_clean_apart_from redded on it (562r6 Fast, ba14967). The test now awaits, by event, both of netd's own end lines: "netd: this NIC's claim refused an interrupt read: Io" and "exit: netd pid=... code=101". A claim that stops refusing leaves netd running and the wait stalls by name. So the filed issue's premise is gone and it is deleted; this branch has no redlist row for it. The PR's attribution paragraphs in the copy-meets-a-remap and quiesce issues are deleted: an issue records the defect, not a PR's argument. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01W6rME2DoqwjcYFStYHHY4j
Two conflicts, every hunk accounted for: - tests/toyos-rust-tests/src/bin/compositor_client_death.rs: main's 2a5c94c made the same change this branch made (no deadline on the close or the probe) and more (named waits, FOREVER, recv_header, the copy-begin/commit cases from the clipboard work). Every branch hunk is subsumed, so main's file is taken whole. - tests/toyos.rs MACHINE_TESTS: main added metal_sim_hostile_clipboard beside the audio rows this branch deletes; the new row is kept and the deleted rows stay deleted. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01W6rME2DoqwjcYFStYHHY4j
…and every rewritten or scratchpad-only line the tracker owes deleted userdev_dma_fault boots green on main once #562's own log drain is out of the picture: the disable and its issue file belonged on that branch, not here. The four remaining issue-prose fixes each delete a claim the review found false or unresolvable from a reader of main alone — a reworded first sighting, a branch count the deleted table no longer backs, a "seen twice" that was one boot reported twice, a scheduler-unchanged claim #562 contradicts, an orch-runs path nothing here can resolve, and a passing-record count the same logs have already outgrown. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01W6rME2DoqwjcYFStYHHY4j
…hree issues, one evidence line restored - syscall-window-nmi: dropped the two rewritten sighting lines a prior fix already invalidated, and "promoted to `defect`" which contradicted the `kind: tooling` frontmatter. Per the round-2 NOTE, restored the one sighting the deleted table had carried: the FAIL line from a main-level head, `c5d09bb6`. - copy-meets-a-remap: deleted "This is not PR #562's doing" — it argued from `user_ptr.rs` alone while the mechanism is placement/steal in `toyos-sched/src/cpu.rs`, which #562 changes. - quiesce-leaves-the-volume-whole: deleted the passing-record ranges, which cover a log set that keeps growing and cannot be resolved; named `PARK` instead of restating its value, which moves with `QUANTUM_NS` or `block::OPERATION`. PR body: deleted the false "Cherry-picked (`-x`) unchanged" claim (f1d6eda edited both cherry-picked files) and the false per-head count table reference (the table was already deleted). 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
Brings in #572 (host QEMU's edk2), #580 and #579 (disabled reds), #549 (a kill never waits on its victim) and #566 (metaltalk redial). - src/redlist.rs: one row each for user_copy_races_munmap and quiesce_leaves_the_volume_whole, which both sides added. main's new rows stay (netd_refused_accept, quiesce_wakes_on_the_last_teardown, root_chunk_refused_on_a_usb_stick, syscall_window_nmi). The rows for tests or issues this branch deleted go (hda_tone, doom_sound_flood, latency_wake, sched_check_build), and so does lan_swap, whose issue main deleted with swap_netd's and swap_crash_rolls_back's rows. - The two issue files both sides added take main's text. - tests/common/power.rs: main's woken_by_the_held_thread, shared by the new quiesce_wakes_on_the_last_teardown, without the two clock verdicts this branch took off QEMU (stopped_the_machine in stopped_boot, and woken_by_its_threads). - tests/common/qemu.rs: qemu_command takes main's firmware_vars and has no audio_wav, so profile_argv passes six paths. The too_many_arguments allow goes, because seven parameters do not trigger it. - kill_while_blocked.rs: main's text. After #549 a kill does not park in retire_task, so this branch's doc for arm 4 was false. main's arm also has no clock. - tests/toyos.rs check_rust_result: this branch's single-print form, which already carries the stdout main added. 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>
Review, round 7, at 0ca1fdbReadiness.
Net lines (
Round-6 findings
Merges
BLOCKERNone open. NOTE
REMOVE
Conditional on |
… too Round-7 review: `after` was `log` (the boot console, up to the fault) plus `result.serial` (after `log_origin` spawns), so the window `await_guest` captures in between — netd's own panic and its exit — was read only for the two needles that wait waited on, and never judged by `must_be_clean_apart_from`. Another process's panic or a second `iommu: DMA FAULT owner=slot` line in that window would have passed. That window is pushed into `after` now, with netd's own staged panic (the location line immediately above the message the wait already matched) taken out first, so a second panic — netd's or anyone else's — has no line left to hide behind. Close issues/kernel/netd-never-reaches-its-loop-under-iommu-userdev-foreign-dma.md: its exit clause is met by 845052d, which awaits netd's own end lines by event. File issues/build/a-machine-tests-row-with-no-dispatch-arm-is-found-only-by-booting-it.md: `run_machine_test`'s and `run_screen_test`'s catch-all arms mean a registered name with no dispatch arm is not a compile error, so `65511a24`'s orphan passed CI host, --list and clippy and only a nightly boot found it. Delete issues/build/quiesce-leaves-the-volume-whole-…'s attribution paragraph, brought back by 6c8ff3f after round 6 already removed it once. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…lands inside it on every run At 8910046 the gate's non-vacuity check ("concurrent", storm records taken by a read while the producer had not finished) held only when the scheduler happened to interleave the reader and the producer. One TCG run at --smp 2 had the producer finish all 1024 calls before the reader reached a storm record, and the gate refused: a timing verdict, which main's #562 rules out of QEMU tests. The producer now stops after HANDOVER (64) records and waits on a channel until the reader has taken a storm record, then emits the rest. The reader sends only after it has loaded the producer's counter for that read, so that read counts as concurrent on every run: 64 is below the target, and the producer cannot move until the send. The wait is bounded by HANDOVER_WAIT (30 s, inside the host's 60 s) and fails loudly, naming the reader that never arrived. Controls, deterministic both: - join the producer before the first read: the producer times out at the handover and the gate reports it; - the same with the handover deleted: the producer finishes before any read and the concurrent check refuses, as at 8910046. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Both sides touched tests/common/wallclock.rs's clock-drift checks and tests/test-durations; every hunk of both survives. tests/common/wallclock.rs: main's #562 ("No QEMU test measures time") replaced the fixed MAX_BOOT_DRIFT_SECS budget with after_the_base(secs, lived), a causality bound measured from the actual elapsed wall time since QEMU's launch. This branch's own commit 1090cf6 ("The RTC keeps UTC") ruled the hardware clock is always UTC and replaced main's zone_from_firmware test (and its rtc-zone-east actuator) with rtc_is_utc, which plants a firmware RTC timezone variable directly via fwvars::plant and asserts the kernel ignores it — FAT name, FAT stamp, SYS_CLOCK_EPOCH and SYS_CLOCK_REALTIME all sit on the staged instant with no offset applied. Kept this branch's rtc_is_utc body (the ABI decision it tests is this branch's own and main never saw it) but put every one of its drift checks on main's after_the_base/lived measurement instead of the deleted MAX_BOOT_DRIFT_SECS, so the branch's checks fit main's "no QEMU test measures time" rule. boot_and_read keeps both signature changes: this branch's firmware_vars: Option<PathBuf> parameter and main's returned Duration (elapsed since launch). undated, no_century and century_from_the_register keep this branch's extra None argument and main's three-way destructure. tests/test-durations: kept watchdog_fed (this branch's own addition, whose test still exists at the merged head). Dropped wall_clock_zone: its test, zone_from_firmware, was deleted by 1090cf6 and replaced by wall_clock_utc, so the entry names a test that no longer exists. Verified on the merged tree: `cargo run -- --ci host` exit 0, `cargo run -- --build-only` exit 0, `cargo test --test toyos-build -- --list` exit 0. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
B6: an_adopted_root_goes_with_its_adopter added a live root whose name matches the adopted pid's prefix, so the test only passes because adopt's liveness filter actually keeps it out; deleting that filter now turns it red. adopt and State::sweep share the rename-into-reap-<name> step through one reap_into helper, since writing both filters next to each other is what made the gap visible. NOTE: following main's #562, no QEMU test measures how long something took. Owner::killed no longer times the exit; it returns Result<(), String> and the verdict rests on the event alone. Deleted the two REMOVE'd lines without rewriting them. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…st clock decides a verdict Round 3's review of #586 found three holes in the storm gate. - The producer's 30 s `recv_timeout` at the handover was an in-guest deadline deciding a verdict, which #562 rules out. It is `recv` now: only a disconnect is an error, and the host's `CEILING` reds a reader that never arrives. - `concurrent` was at least one batch by construction: the handover read counted even while the producer was parked. A read now counts only if the producer's counter moved across it, and only after the lap. The producer emits until such a read has happened and the reader sets `stop`, so the overlap is waited on rather than sampled. The guest's "raced nothing" refusal could no longer fire and is deleted; the host still refuses `concurrent=0`. - `lost` was zero on two of three runs, so read.rs's `lost +=` was measured by nothing. After the handover the reader now blocks until the producer has emitted `shards * 512 + 1` more records, which puts more than a shard's worth into one shard whichever CPUs the producer ran on, and the host asserts `lost > 0`. `STORM_RECORDS` goes: the emitted count is the producer's counter. REMOVEs: the `LOG_PATTERNED` arm's comment, the "rather than on a kernel thread" clause in `log::user::read`, the unchecked "runs beside it" and "a read lands inside the storm" claims, `STORM_SETTLE` in the timing-verdicts issue, and the narration in the logread-grants issue. The echo-spawn and negative-control-timeout issues are back to main's text. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
PR #562 forbids a time verdict in a QEMU selftest: under TCG load a slow call must not fail a test that measures a value, not a duration. The timer-floor selftest's `window < floor` clause was exactly that — it failed whenever the arm_within call itself ran long, for no defect. The verdict is now only CVAL >= counter_before + floor_ticks(), which holds however long the call took. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Main's #562 deleted this row when it moved watchdog_fed to metal-only; the merge into this branch resurrected it by mistake. Nothing else in the file changes. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Main's rust pin has not moved since the last merge, so the fork is unchanged. Every conflict, and how it was resolved: Modify/delete, main deleted: - issues/build/a-swaps-redial-races-a-hard-dial-ceiling-against-an-unbounded-guest-gap.md: #566 fixed the defect and deleted the issue. This branch had added one sighting to it, and a sighting of a fixed defect has no home, so the file stays deleted. - src/heartbeat.rs: #562 deleted `kernel_heartbeat`'s CPU-mask and gap verdicts with the file. This branch had given its done-line table blockd and fsd rows. The table goes with the verdict it served. - tests/doomcase/system.toml: #562 moved the doom audio tests to metal and deleted their QEMU config. This branch had added blockd and fsd rows to it. Nothing boots it now. Modify/delete, this branch deleted: - tests/toyos-rust-tests/src/bin/ftruncate_flush_race.rs, tests/toyos-rust-tests/src/bin/quiesce_fsync.rs, issues/build/ftruncate-flush-race-reds-intermittently-and-nothing-says-why.md, issues/build/quiesce-leaves-the-volume-whole-needs-its-flush-to-close-inside-the-stops-budget.md and issues/kernel/a-root-metadata-read-refused-on-budget-is-not-retried.md: main's hunks remove timing from them or note its own runs. They are about the kernel FAT flush, the stop's kernel sync and the kernel's metadata read, which this branch deletes, so they stay deleted. Content: - kernel/src/actuator.rs: main's `quiesce_last_teardown` (#549) is kept. The kernel FAT actuators `fat_flush_meta_refuse`, `resize_evict_window` and `resize_fault_refuse` stay deleted. `process_reopen_selftest` stays where this branch has it, with main's doc (#549 also opens every kernel thread's pid). - src/redlist.rs: both conflicted rows go. `doom_sound_flood` left QEMU with #562, and this branch deletes `ftruncate_flush_race`. - tests/common/gpt.rs: this branch's `device_saying` and decoy `boot` are kept. Main drops the `drain_serial` window, so its `qemu` binding is no longer `mut`. - tests/common/inspect.rs: main's "nothing plays audio" (#562 deleted `inspect_plays`) is taken, with this branch's clause on the boot stick. - tests/common/iommu.rs: main's `panic-reboot-fast` and its wait for the fatal path's reset are kept. This branch's `iommu_empty_domain` reads the xHCI's DCBAAP over QMP, and QEMU has exited by the time that reset is seen. So `fault_boot` now takes a `holding` read, which it runs after the fault line and before it waits for the reset, while the fatal path holds its panel. `iommu_context_absent` reads nothing there. - tests/common/origin.rs: main's judgement of `log_ring_keeps_the_owners_slots` is taken whole: init says it waited a flush out, or its stop line is missing. That drops the millisecond inference between two records, whose record this branch had changed from `Syncing filesystems...` to the stop record (#562: no QEMU test measures time). - tests/common/volumes.rs: main's timing edit to `ftruncate_flush_race` goes with the test. - tests/logstallcase/system.toml: main drops `power` and the `shutdown` symlink, since the metal row reads `/log` without a stop. This branch's blockd and fsd rows are kept, because fsd holds `/log`. - tests/toyos-rust-tests/src/bin/blockd_io.rs: main's `claim_when_free`, now generic and with no deadline, is taken inside this branch's `if let Some(syscap)`. `bench` is this branch's blockd-only arm with main's timing removed: no MiB/s, and the line says only how many Flushes each run took. The module doc's "timed" goes. - tests/toyos-rust-tests/src/roster.rs (add/add): both sides wrote one roster decoder. Main's is taken whole, because five binaries read it and it has no deadline (#562). This branch's copy had a 5 s give-up. - tests/toyos-rust-tests/src/bin/process_lifecycle.rs: main's is taken whole. This branch's only change to it was the move onto its own roster.rs. - tests/toyos-rust-tests/src/bin/process_stats.rs: main's `refused_calls_are_counted` and its roster wait for the held child are kept, and so are this branch's two connection arms. The system capability is taken once in `main` and passed to the three arms that read the roster, since a second take of the label finds nothing. The connection arms now wait on main's `threads_of` for the child's main thread to be blocked, with no deadline. - tests/toyos-rust-tests/src/bin/quiesce_twice.rs: main's `Duration`-only import. This branch deletes the owed file, so `File` and `Write` go. - tests/toyos.rs: - RUST_SKIP: main's audio rows are taken. `audio_tone_load` goes, since main deleted it. `log_volume_reread` goes, since this branch deletes it. - MACHINE_TESTS: `quiesce_leaves_the_volume_whole` stays deleted. `quiesce_wakes_on_the_last_teardown` comes from main with main's comment. `blockd_serves_nothing` is kept. `hda_tone` and `hda_client_stall` went to metal with #562, and `hda_two_live_refused` takes main's comment. - CARRIES and dispatch: the same. - `nvme_wide_sector`: this branch's blockd arm, which already had no drain window. - toyos-quiesce/src/lib.rs: this branch's `FILES_MS`, `FLUSH_MS` and `SYNC_MS` are kept, with main's `LAST_THREAD` doc, which names both quiesce-last actuators. - userland/logd/src/policy.rs: this branch deletes the module doc and the `LOG_WRITE_BUDGET` paragraphs main edited one line of, so they stay deleted. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…framing read PR #562's rule against a timing verdict in a QEMU selftest made `floor_selftest` compare CVAL to a counter read taken before the call to `arm_within`. Under TCG that call itself can run tens of thousands of ticks long — far past `floor_ticks()` — so `span >= floor` held whether or not the floor clamp fired: a QEMU host under load hid a missing or bypassed clamp rather than catching it. `arm_ticks` (and `arm_within`, which ends in it) now return the counter value they read to compute CVAL, so the selftest relates CVAL to the exact `now` the arm used — a value relation, not a second, independent read framed around however long the call took. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The owner's rulings, applied: a QEMU test measures no time, and the harness's hang ceiling is its only clock. An in-guest deadline becomes a wait on the event it stood for. A property that cannot be kept without time moves to a
METALrow if it matters on the T14 and is deleted otherwise. Audio is judged on metal and nowhere else. The QEMU machines keep their audio devices, with-audiodev none, for the device-isolation tests that use them as DMA masters. Doom's sound and music tests are gone.The ceiling
A hang is red like any other red. "N of those reds are the ceiling" counts both of the ceiling's reds: a wait's
STALLED:, and the backstop'stimed out after(qemu::TIMED_OUT) for a guest still talking.a_stall_stays_redholds each.In-guest waits
Each wait below now blocks until its event arrives:
Poller::waitwith no timeout,recvin place ofrecv_timeout, or a retry loop with no bound. Where a stimulus needs a thread parked first, the test asks the kernel's roster (tests/toyos-rust-tests/src/roster.rs) instead of sleeping. Census readings wait until the census settles (census_wait.rs).kill_while_blockedGONE_AFTER_NS,ENDS_WITHINhandle_kill_policyPOLL_ANSWER,SETTLE_SAMPLEShandle_lifetime,shm_release_reclaimscensus_waitinbox_cancel_wakescopy_out_races_munmap,tls_dtv_racecompositor_stallHANDSHAKE_WAIT, a timed streamblockd_ioCLAIM_RETURN,AIMED,SILENCE_ENDS, the bench's MB/sfat_backing_revoked,gpu_set_resolutioni8042_mouse,i8042_keyboard,input_events,window_drag,window_child,window_wakewinit_loopCEILING; idle wakes counted overIDLE_WINDOWControlFlow::Wait; the idle-wake stage is deletedlocale_gate,launcher_refusals,mmap_prot,swap_claim_astray, the quiesce binariesquiesce_twice's threads sleep forDuration::MAX, becausenanosleepis the syscallquiesce-last-parkholds the named thread innetd_stream.rsWITHIN,await_untildeadlines, connect timeoutsawait_untilwaits for its check and nothing else; connects passNO_DEADLINEnetd_lookup_let_goWITHIN, the schedule's lower boundnetd_hostile_peernetd_capsprocess_lifecycle,process_statsfutex_wake_countsPARK_MARGIN; 2 s, 1 s and 5 s bounded loops; 120 ms settlescounts,claim_semanticsandorphaned_by_unmapproceed once each waiter has counted itself in before itsfutex_waitand the roster shows them blocked; the spinners, once the roster shows one running on every other CPU; the rest wait for their returns with no boundstd_threadingsched_stressInstantmin_vruntimemovedmunmap_reissues_read_windowhome_overwrite_zeropanic_halts_firstSTARTED_WITHINtest-runner'slog_gateCEILINGftruncate_flush_raceHELD, refusesBROKENand reads the settled sizespawn_cwd,log_flood,demand_window_race,nmi_window_spin,wall_clock_nowMAX_CLOCK_SKEW_SECScompositor_stallyield_nowbeside the writer until the ring filledHost verdicts
usb_boot_stick_pulledlan_dhcp_leasereadylan_no_leaseLEASE_BOUND+ 10 s drainreadyafter the give-up, under the harness ceilinglistening on port 22, then asks oncepci_function_is_exclusive,bar_placement_is_provenreadyqemu::await_resetunderpanic-reboot-fast: the capture closes when the fatal path's reset ends QEMUgpt,log_partition_identityawait_reset, as abovepre_idle_wedge_speaksscreen_diag_bootexit: toyboxscreen_pager_keysscreen_recoverable_untouchedAFTER_END1.5 sscreen_blocked_dumpkernel_heartbeat, nvme wide sectorawait_gueston the frame or heartbeat linesmetal_sim_pointer_churnkernel_log_file, the usb stick with no write cachelog_stream_stalled_readerSTALLEDjudged as a deadlinexhci_deaf_registersunverified − broke≥ 1.4 sxhci_slow_connectquiesce_wakes_on_the_last_parkmetal::Readback::stop_completedholds every metal boot to iti8042_health_cadence,i8042_quarantine_verdict, the idle-trip checki8042_quarantinepanic_key_holdsboot_from_power_onwall_clock_*log_ring_keeps_the_owners_slots/logA usb probe names a binary no image carries, on purpose: the spawn's refusal is a kernel record (
spawn: /system/bin/<probe>: not found), and that record is the load.absent_probeends its wait on test-runner's answer for the probe, whatever it is, and reds naming it unless it iserror=entity not found.A fatal path's CPU never halts:
halt_all_cpusclaims the panel whether or not a framebuffer exists, then holds it (hold_the_panel,page_forever) until the reboot bound resets the machine. Soawait_resetends when-no-rebootturns that reset into QEMU's exit, or at once on a refused line. The exit counts only with a success status and the rawpanic: no key inside the boundline on the console or in the 16550's log.metal_sim_compositor_stall: the test was wrongThe nightly red it: the watcher's
Framenever came. Three diagnostic arms, run by the orchestrator (notiming-r4/mutations/c-diag*.patch), decided which side was wrong:c-diagadds prints only. Nodiag ring fullappeared, anddiag N writes, 0 fillsran to 19922944 writes. The ring never filled, so the watcher never presented.c-diag-blockedblocks the presenter on the writer's first fill. It was green. It presents only after that fill, so the ring filled.c-diag-nostreamstreams nothing. It was green.That is the measurement's row "
diag ring fullappears and the run is green". The presenter spinningyield_nowbeside the writer held the writer below the compositor's drain rate. The presenter now parks until the writer's first fill unparks it. It printscompositor stall: the ring is full; a second window presents under itbefore it presents, so a hang after that point is named by the test's last line. The whole-change control is925e1a66, red as above.r5/c-drain-never-endsshows the fixed test still reds on a real stall (see the arm table).A ceiling red prints the test's lines
check_rust_resultprinted the test'sstdoutfor an exit code and for no exit code, but printed only the kernel's last 60 lines for a ceiling red. On a hang those 60 lines are heartbeats. Som-revoke-no-wakered at 300 s with nothing to say which wait it was in. One print now serves every red, and each carriesstdout:.userdev_dma_faultawaits netd's endOn
main,foreign_faultdrained 2 s into a capture it dropped at return, and that drain swallowed netd's lines after the staged fault. This branch deleted the drain, so netd's panic on its refused claim (Card::begin_pass:netd: this NIC's claim refused an interrupt read: Io) reachedrun_test's window afterlog_origin's spawn record, andmust_be_clean_apart_fromred on it (562r4nightly,562r6Fast). The test now awaits that line andexit: netd pid=… code=101withawait_guest, beforerun_test.r7/take-record-no-refusaldeletes thefaulted()refusal inpcidev::take_record. netd then never ends, and the wait reds. The mutated tree builds (cargo run -- --build-only --kernel-feature boot-actuators --kernel-feature test-actuators: EXIT=0, restored clean), and the orchestrator's run of it at6079c8c1is EXIT=1,FAIL userdev_dma_fault: STALLED: waiting for netd's end on its refused claim — it never stopped talking and never got there(562r7, below).562r6-fast.logatba14967ecarries both lines, after theDMA FAULTthat ends the boot log.Disabled on
main, changed heremaindisabled these tests, so this branch's changes to them run nowhere. Each disabling issue records its change, so the change returns with its test. The merge deletes the sentences in those issues that the merged tree makes false.log_ring_keeps_the_owners_slotsreads an unanswered flush off init'sFLUSH_WAITED_OUT, or off a stop line missing from/log. It no longer reads it off the kernel's sync time.usb_transport_breakloses its 2 s staged-break check.quiesce_wakes_on_the_last_park:stopped_the_machineandwoken_by_its_threadsare no QEMU verdict here, so the failure its issue quotes no longer reds it.quiesce_stops_the_machine:quiesce_writers' 5 s spin-up is deleted. Its issue's sightings are all that give-up.ftruncate_flush_race: the guest's 150 ms verdict is deleted. Its issue's reds are all that verdict.For the last three, the premise the disabling issue records is gone at this head. Whether each test is green is a guest run's to say.
To metal, off QEMU
watchdog_fed,dump_nmi_probe,blocking_read_window's held window,tlb_shootdown_waitsandsyscall_cost. Each has aMETALrow and aMETAL_ONLYreason. The new boots are priced intests/metal-profile.toml, and each parameter isFLASHABLE. The QEMU registrations oflatency_wakeandtlb_shootdown_costare deleted; their metal rows already existed.Restored
panic_halts_the_others_first: QEMU is the verdict. After the fatal CPU's line paststop_other_cpus(panic_reboot::arm's),info registers -amust show every vCPU but one halted withIFclear. The wait is guarded byGUEST_QUIET. The fatal CPU holds its panel under the shipped 60 s bound, so the machine is still up to be asked. Non-vacuity: a sibling made records before the fatal one. There is no record-order check: withstop_other_cpusemptied the console also goes quiet, so no sibling record ever arrives to be counted.hda_two_live_refused, under-audiodev none. The wait ends on whichever sink soundd took.Metal audio judges
The host test
metal_audio_judgesruns every judge against a log crafted to pass it and logs crafted to fail it.job_windowends at soundd's flush on the last client leaving, not at the next spawn.hda_tonealso holdsunderrunsto 0.audio_idle_suspendreds onsoundd: resumedwith no client.null_sink_shipped_clientis renamedshipped_client_departures, because it shares its boot withhda_tone.Kept
sched_check_buildasserts that the CPUs whose reportsPassCostReport::parsereads are exactly the default SMP.Deleted code
--sound-stressand--music-check, the stalled-consumer actuator andMIXED_PERIODS, withtests/doomcase,tests/doommusiccase, their rows and the binaries.usb-slow-device:SLOW_TRANSFER_NS,held_event,slow_device_would_have_answeredand theslot_idthey alone called.sched_fast_health, andtoyos-quiesce'sspent_its_budget.Issues
issues/build/timing-verdicts-ruled-off-qemu-have-no-metal-arm.mdlists every property deleted or moved without a metal row, includingdesktop_audio_client's three verdicts,inspect_plays' period sum andboot_from_power_on's host comparison. It also lists every clock a QEMU test still waits on without deciding a verdict (paces, drains of another thread's work, and product clocks a boot races), and the one that does:census_wait::settled's 10 ms window.a-megabyte-written-to-the-stick-starves-a-tone-beside-itexits on aMETALrow, and so dogate-a-suspend-structure-verdict-unread,desktop-session-put-26ms-of-silenceandlogging-records-from-every-producer…'s preallocation item.hda-tone-phase-check: its capture is gone.idle-suspend-reds-on-a-loaded-host-and-on-main: its subject was the QEMU arm.doom-sound-flood-played-full-scale-once.i8042-health-cadence-counted-three-lines-once-on-mains-nightly.harness-reads-after-a-flat-half-second-drain: every flat drain before a judgement now waits on its line. Whatrg 'drain_serial\(Duration::from_millis' tests/commonstill finds is the pace inside an event wait:await_guest,pkg'swindow_seenand three usb polls.usb-slow-deviceare deleted with them.main, changed here" says what this branch changed.No gate enforces the timing rule, and none is added.
Merged with
mainat807f4561(#564, the measured schedule)home_budget_refusal_retried,usb_disk_index_stable,wall_clock_file,quiesce_wakes_on_the_last_exitandquiesce_dump_holds_the_stopped. This branch'sfsync-budget-spent: staged a spent budget onkernel record went too, since onlyhome_budget_refusal_retriedread it;kernel/src/object/ops.rsismain's again.wallclock::after_the_basestays, becausewall_clock_zonereads it.Schedand comment and 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's tier:netd_hostile_peeris Parallel at Weekly,hda_two_live_refusedWeekly,panic_halts_the_others_firstNightly,userdev_dma_faultNightly. The rows 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 left to this branch keep this branch's form.toyos-checkslibtest tests intests/checks.rs.a_stall_stays_redreplacesstall_is_not_a_verdictthere.i8042_quarantine_verdictwent with the idle-trip check.metal_audio_judgesis one of those tests now, not a guest row:cargo test --test toyos-checks metal_audio_judges. The audio-judge arms below went through the guest harness's dispatch atf260f3e7.--audio-gateis gone and--weeklystays. A reach is refused beside--metalonly.scheduleand--listhold noAUDIO_TESTS.6079c8c1, the merge adds noInstant,Duration,recv_timeout,elapsedor deadline line totests/toyos-rust-testsortests/common. TheDurationlines it adds are the synthetic values of the host checks intests/checks.rs.tests/common/mod.rs'sallow(dead_code)taken off,cargo checkof both test targets names only the three thatissues/build/the-harness-carries-three-helpers-nothing-calls.mdalready names (EXIT=0 each, attributes restored).Merged with
mainatbc9ccad8(#572, #580, #579, #549, #566)Merge commit
6c8ff3f4.src/redlist.rs:user_copy_races_munmapandquiesce_leaves_the_volume_wholewere added on both sides. Each keeps one row, pointing at the issue file onmain.main's new rows stay. The rows for tests or issues this branch deleted go:hda_tone,doom_sound_flood,latency_wakeandsched_check_build.lan_swapgoes too, becausemaindeleted its issue.main's text.tests/common/power.rs:main'swoken_by_the_held_thread, which the newquiesce_wakes_on_the_last_teardownshares, without the two clock verdicts this branch took off QEMU (stopped_the_machineandwoken_by_its_threads). Both tests are disabled onmain.tests/common/qemu.rs:qemu_commandtakesmain'sfirmware_varsand has noaudio_wav. Itstoo_many_argumentsallow goes: at seven parameters the lint does not fire, and--clippywith--all-targets -D warningsis clean without it.kill_while_blocked.rsismain's. After Kernel: a kill never waits on its victim — the last thread out tears its process down #549 a kill no longer parks inretire_task, so this branch's arm-4 doc was false.main's arm has no clock either.check_rust_resultkeeps this branch's form. It already prints the stdout thatmainadded.tests/toyos-rust-testsandtests/common:kill_ends_every_wait: a 10 ms pace while it polls the roster for a parked thread, with no deadline;std::thread::sleep(3600 s)as the thread-join child's park;ceiling_self_checkcase from Disable flaky netd_refused_accept (hung 2341s waiting on a wake) #579.r7/take-record-no-refusalstill applies at6c8ff3f4(git apply --check: EXIT=0).Merged with
origin/mainate3a1cdc8(#578, #581) in0ca1fdb2; no conflicts, and the merge does not touchtests/toyos.rs.At
0ca1fdb2, each gate EXIT=0:cargo test -p toyos-build --lib: 394 passed, 3 ignored.cargo test --test toyos-build -- --list: EXIT=0, 235 Fast, 142 Nightly, 115 Weekly, 3 Local, 21 disabled, noi8042_health_cadence; everyrun_machine_test/run_screen_testregistration and dispatch arm agree both ways.cargo test --test toyos-checks: 11 passed.cargo run -- --clippy: EXIT=0.cargo run -- --build-only: EXIT=0.Metal audio judges, red arms (run here at
f260f3e7;tests/common/audio.rshas not changed since): 15 mutations oftests/common/audio.rs. Each was applied as a checked patch, built, run ascargo test --test toyos-build -- metal_audio_judges, and restored byte-identical. The unmutated run is EXIT=0. Every arm is EXIT=1, naming the crafted log that passed:underruns != 0offresumes < 2→< 1deferredcheck offjob_windowends at the next spawnunsaid == 0offRun by the orchestrator
Agents never boot QEMU.
cargo test --test toyos-build.cargo test --test toyos-build -- --nightly.cargo test --test toyos-build -- --weekly.Measured at
925e1a66by the orchestrator:lan_no_lease,usb_flush_optionalandusb_boot_stick_pulled.m-fsync-staged-every-flush(its test is gone with 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),m-counts-probe-for-park,m-runner-answers-otherwise(both tests) andm-revoke-no-wake.m-revoke-no-wakered at the 300 s ceiling. Its guest lines were not in the report, which the ceiling red now prints.metal_sim_compositor_stall(timed out; fixed above) anduserdev_dma_fault.Measured by the orchestrator at
2a9c77ee(562r5): the nightly EXIT=0 (493/493);metal_sim_compositor_stallEXIT=0;r5/c-drain-never-endsandr4/m-revoke-no-wakeEXIT=1. Atba14967e(562r6): the Fast tier EXIT=1, 386/387, the one reduserdev_dma_fault(fixed above).At
6079c8c1(562r7), before the #564 merge:userdev_dma_faultEXIT=0 (test result: ok. 1 passed, 1 total (9.7s));r7/take-record-no-refusalEXIT=1,FAIL userdev_dma_fault: STALLED: waiting for netd's end on its refused claim — it never stopped talking and never got there(0 passed, 1 failed, 0 invalidated, 1 total (304.4s)); the Fast tier EXIT=0,388 passed, 388 total (190.6s), 104 held back for the nightly tier. Nothing has booted the merged headfe1c4d99.Measured at
ee646399by the orchestrator, each EXIT=1:m-stop-other-cpus-empty,m-dma-fault-no-halt(both tests),m-recursive-fault-reports,m-quiesce-twice-parks,m-counts-probe-for-parkandm-unmap-revokes-no-futex, with the reds below.The patches are in the scratchpad and are not committed:
notiming-r4/mutations/,notiming-r3/mutations/andnotiming-r2/mutations/. Each applies to2a9c77ee. Each mutated tree was built there and restored clean (notiming-r5/arms-build.txt, logsnotiming-r5/build-<patch>-<kind>.log):cargo run -- --build-only --kernel-feature boot-actuators --kernel-feature test-actuators;cargo test --test toyos-build -- --list;cargo run -- --build-only.To run an arm:
git apply <patch>, run the command, thengit apply -R <patch>.r3/m-stop-other-cpus-empty-- panic_halts_the_others_firstSTALLED: waiting for the other CPUs to halt after the fatal path on cpuN stopped them — QEMU shows each vCPU in \cli; hlt` as [false, false, false, false](measured atee64639`)r2/g-hda-binds-the-first-- hda_two_live_refused"has a live link (statests=" never reached the boot consoler3/m-dma-fault-no-halt-- iommu_context_absent,-- iommu_empty_domain"Boot: complete" on a boot console that should not have it(measured)r3/m-recursive-fault-reports-- nested_fault_is_recursive"KERNEL PANIC:" … that should not have it(measured)r2/g-sched-stress-lag-fails-- sched_check_buildsched_stress failed on the check buildr2/g-close-cancels-no-poll-- inbox_cancel_wakestimed out after 300s, with the guest still talking … — it was working and did not finish, counted in "1 of those reds are the ceiling"r3/m-unmap-revokes-no-futex-- futex_wake_countsfutex_wake on this process's own freshly mapped memory answered [...] … another process's waiters, thenthe sweeper found a wake of its own fresh memory answered for by somebody else's parked thread(measured)r4/m-revoke-no-wake-- futex_wake_countstimed out after 300s, with the guest still talking … — it was working and did not finish, counted in "1 of those reds are the ceiling" (measured at925e1a66). TheFAIL rs::futex_wake_countsline'sstdout:ends withclaims: a claim already taken is neither counted nor chargedand the sweeper'ssweeper: 12 fresh frames, and no wake belonged to anybody else, with nounmap: …r5/c-drain-never-ends-- --nightly metal_sim_compositor_stalltimed out afterorSTALLED:), counted among the ceiling's reds. Itsstdoutends withcompositor stall: the ring is full; a second window presents under it, with nocompositor stall: 6 stalls survived. If the unbounded drain keeps the ring from filling, that line is absent too, and the red is the same ceilingr4/m-counts-probe-for-park-- futex_wake_countsfutex_wake(count=1) with two waiters answered 0(measured on the patch's form atee646399)r3/m-quiesce-twice-parks-- quiesce_refuses_a_second_shutdown"PANIC:" on a stopped-boot drain that should not have it: … quiesce.rs(measured)r4/m-runner-answers-otherwise-- --nightly usb_flush_optional,-- --nightly usb_boot_stick_pulledtest-runner answered flush-probe-0 after the give-up with Some("… error=…"), and a name no image carries is answered "===TEST_END flush-probe-0 error=entity not found===", and the same forpull-probe-0 before the pull, at once and not at the ceilingr2/r1-exit_wait_storm-never-releases-- exit_wait_stormr2/r1-blocking_read_stress-echo-writes-nothing-- blocking_readblocking_read_stressandblocking_read_windowr2/r1-poll_wake_pipe-writer-waits-a-round-ahead-- poll_wake_piper2/r1-heartbeat-no-pin-line-- --nightly kernel_heartbeat… heartbeats carry no \i8042: line` of their own`r2/r1-i8042-no-floating-bus-exit-- --nightly i8042_absentno `i8042: absent — port 0x64 reads 0xff` line on a machine with no i8042r2/r1-netd-keeps-a-chatty-client-- netd_lookup_let_goa client that spoke again while its lookup ran was answeredr7/take-record-no-refusal-- userdev_dma_faultSTALLED: waiting for netd's end on its refused claimThe prefix names the directory:
r2isnotiming-r2/mutations/,r3notiming-r3/mutations/,r4notiming-r4/mutations/,r5notiming-r5/mutations/,r7notiming-r7/.Each converted kind has an arm that stages its park:
g-close-cancels-no-poll;m-revoke-no-wake;m-dma-fault-no-halt;m-runner-answers-otherwise.Negative controls are the patches above. Each reverts the one mechanism its test is about, onto this head.
c-drain-never-endstakes out the compositor's drain budget, which is the defectcompositor_stall's streaming case exists for: the drain never ends while a client has something to send, so nothing is composited and the watcher'sFramenever comes. The whole-change control for the presenter's park is925e1a66, where the test red.m-counts-probe-for-parkandm-quiesce-twice-parkseach revert their test's whole change. The whole-change control forawait_resetisf260f3e7itself:iommu_context_absent,iommu_empty_domain,nested_fault_is_recursiveandpanic_halts_the_others_firststalled there, waiting for every vCPU halted. The whole-change control forlan_no_leaseisee646399: it red on the nightly there,"netd: ready, at most " never reached … after "netd: DHCP: no lease as toyos-t14 in ". For the usb probes it isee646399too: both tests hung to the ceiling,STALLED: waiting for probe 0 ….Independent oracles:
info registers -agivesHLT=1withRFLbit 9 clear for a vCPU in the stop'scli; hlt.-no-reboota guest reset ends the process, so the fatal path's reset is seen by the host, not reported by the guest.spawn: … not foundrecord beside it, for the usb probes.🤖 Generated with Claude Code