Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
0427aea
Timing verdicts leave QEMU, and audio leaves QEMU entirely
Japabu Sep 27, 2026
4c5cae9
Merge origin/main into wt/toyos-notiming
Japabu Sep 27, 2026
ba63682
CLAUDE.md files: timing and audio verdicts come only from metal
Japabu Sep 27, 2026
ad3448d
No QEMU test measures time: every deadline becomes the event it waite…
Japabu Sep 27, 2026
f260f3e
Merge origin/main into wt/toyos-notiming
Japabu Sep 27, 2026
ee85b40
Merge origin/main into wt/toyos-notiming
Japabu Sep 28, 2026
5ef7690
tests/doommusiccase is a covered boot config again
Japabu Sep 28, 2026
aae20a0
A fatal path's wait ends on its reset, and the stop is judged by QEMU
Japabu Sep 28, 2026
eff6a6e
futex_wake_counts: counts waits on the roster for its waiters to park
Japabu Sep 28, 2026
ee64639
quiesce_twice: the held thread sleeps, because nanosleep is what the …
Japabu Sep 28, 2026
97d7330
lan_no_lease reads through to netd's READY
Japabu Sep 28, 2026
d533bd4
The usb probes wait for test-runner's answer, and read it
Japabu Sep 28, 2026
4c7ca6c
fsync-budget-spent names each refusal it stages, and only those are c…
Japabu Sep 28, 2026
c9e2142
The swap rig waits for sshd to listen, and asks once
Japabu Sep 28, 2026
8b95391
The backstop's red is counted among the ceiling's
Japabu Sep 28, 2026
ea727a0
futex_wake_counts parks every arm by the roster, with no settle
Japabu Sep 28, 2026
a4ad0e8
Delete prose that restated or cited what is gone
Japabu Sep 28, 2026
97e5154
Issues: the verdicts and the clock the tracker lacked, and exits that…
Japabu Sep 28, 2026
898130f
Merge origin/main into wt/toyos-notiming
Japabu Sep 28, 2026
c6193f0
The two tests main disabled carry this branch's changes into their is…
Japabu Sep 28, 2026
925e1a6
lan_no_lease's drain comment names what ends it
Japabu Sep 28, 2026
f8880ff
Merge origin/main into wt/toyos-notiming
Japabu Sep 28, 2026
93a0225
compositor_stall parks the presenting thread until the ring is full
Japabu Sep 28, 2026
b313f9b
A Rust test's ceiling red prints the test's own lines
Japabu Sep 28, 2026
2a9c77e
File userdev_dma_fault's red on netd's own panic after the staged fault
Japabu Sep 28, 2026
ba14967
Disable two round-5 Fast reds whose binaries this branch edits, behin…
Japabu Sep 28, 2026
845052d
userdev_dma_fault awaits netd's end on its refused claim before judgi…
Japabu Sep 28, 2026
6079c8c
Merge origin/main (ec06384e) into wt/toyos-notiming
Japabu Sep 28, 2026
fe1c4d9
Merge origin/main (807f4561, #564 the measured schedule) into wt/toyo…
Japabu Sep 28, 2026
6c8ff3f
Merge origin/main (bc9ccad8) into wt/toyos-notiming
Japabu Sep 28, 2026
65511a2
tests: the merge that brought back #564's i8042 retiering also brough…
Japabu Sep 28, 2026
0ca1fdb
Merge origin/main (e3a1cdc8) into wt/toyos-notiming
Japabu Sep 28, 2026
2bc3ff9
userdev_dma_fault judges the window between the fault and netd's exit…
Japabu Sep 28, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 1 addition & 21 deletions .github/workflows/nightly.yml
Original file line number Diff line number Diff line change
Expand Up @@ -178,26 +178,6 @@ jobs:
key: guest-${{ github.run_id }}
- *serial

# Gate A's thorough tier, `tests/audio-baseline.toml`: N boots per config,
# strictly one at a time, as two shards of the same configs.
audio:
needs: build
runs-on: ubuntu-24.04
timeout-minutes: 180
strategy:
fail-fast: false
matrix:
shard: [1, 2]
container: *kvm
env:
GH_TOKEN: ${{ github.token }}
steps:
- *deps
- *checkout
- *guest-cache
- run: cargo run -- --ci audio ${{ matrix.shard }}/2
- *serial

# "Only Rust and QEMU", run rather than argued: `cargo run -- --build-only`
# from a fresh machine. `sid` as it stands, image and archive both, and no
# cache — a fresh machine is the premise.
Expand Down Expand Up @@ -255,7 +235,7 @@ jobs:
# One standing issue, found by title and commented on; a dispatch is somebody
# watching the run, so only the schedule files.
nightly-red:
needs: [host, build, guest, tcg, audio, portability-linux, portability-macos]
needs: [host, build, guest, tcg, portability-linux, portability-macos]
if: ${{ !cancelled() && github.event_name == 'schedule' }}
runs-on: ubuntu-latest
permissions:
Expand Down
2 changes: 1 addition & 1 deletion CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ The root `Cargo.toml`'s `[workspace]` `members` and `exclude` lists account for
- **Never rewrite history, and never touch `main`.** No `--amend`, no `rebase`, no `--force` — on your own branch as much as anywhere: a pushed hash may already be cited. `main` is protected — PR required, no force-push, no deletion, no bypass.
- **A red test is a defect unless `src/redlist.rs` disables it with its issue (`cargo run -- --known-red <test>`); a flaky test is disabled at once, never re-run.**
- **A high-risk change names its two checks.** Security boundaries, the scheduler, the ABI, filesystems, devices, memory management, concurrency primitives: the PR names the negative control or mutation that fails if the implementation is wrong, and one epistemically independent oracle — an external specification, a differential implementation, real hardware, a third-party checker, a formal model, or a recorded real failure. A second agent is not independence: five artifacts from one wrong model still agree. A mutation is a negative control only if it reverts the *whole* change onto the base the green arm was measured on — a one-line revert of a change that moved two things measures neither.
- **Host load is not an excuse.** A load-coincident audio failure is investigated as a real defect, never re-run away as noise; evidence against that assumption goes to the owner, not into quiet workarounds.
- **Timing and audio verdicts come only from metal.** A QEMU test asserts order, completion, content and counts, never how long something took, and plays no audio; its only clock is a hang ceiling.
- **Subagents wait in the foreground** — background notifications do not reliably re-wake them: explicit `timeout`s, and for longer work background once and block with a few long foreground waits, polling before each sleep.
- **An agent never waits on CI.** It arms auto-merge, reports, and exits. Sequencing across landings belongs to the orchestrator, done in passes on its own wake-ups; several finished branches land as one batch PR rather than as one agent babysitting N cycles.
- **Subagents get an explicit model, never the session default.** The orchestrator scopes, dispatches and verifies; it edits nothing. Match the tier to the judgment in the task: judgment-bearing coding gets a frontier model, mechanical execution from an exact brief a mid tier, and non-coding mechanical work the cheapest. Never encode a temporary usage circumstance as a rule.
Expand Down
36 changes: 14 additions & 22 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -107,10 +107,9 @@ default-run = "toyos-build"
fatfs = "0.3.6"
fontdue = "0.9"
gpt = "3.1.0"
# `statvfs` for `worktree::free_bytes`; `getloadavg` and the libproc pair
# (`proc_listallpids`/`proc_pidpath`) for gate A's host-conditions line; and the
# unprivileged ICMP datagram socket `icmp::echo` asks a metal boot over, which
# is the platform call that replaces a `ping` binary.
# `statvfs` for `worktree::free_bytes`, and the unprivileged ICMP datagram
# socket `icmp::echo` asks a metal boot over, which is the platform call that
# replaces a `ping` binary.
libc = "0.2"
toml = "0.8"
uuid = { version = "1", features = ["v4"] }
Expand Down Expand Up @@ -172,25 +171,18 @@ toyos-userbound = { path = "toyos-userbound" }
# declaration. Pure and `no_std`, so it compiles for the host as it does for
# the guest.
toyos-i219 = { path = "toyos-i219" }
# The scheduler core, for the one type the check build publishes and the
# harness judges: `cpu::PassCostReport` is the wire form of the pass-cost
# distribution, and its `Display`/`parse` pair is what keeps the kernel that
# writes it and `tests/common/passcost.rs` that reads it on one format.
#
# `check` because that is where the type lives, and it lives there because
# `src/build.rs`'s artifact gate asks the *shipping* kernel to carry none of the
# check instruments' literals — a linker may keep a string constant no code
# reaches, so an unconditional `Display` puts the report's prefix in every
# image. This is a dev-dependency of a host binary and `kernel/` is excluded
# from this workspace with its own lockfile, so nothing here reaches the kernel's
# resolution of the same crate.
# The scheduler core, for two things the harness reads the kernel's words by:
# the watch window's count (`watch::window`) that `blocking_read_window`'s
# metal row judges, and `cpu::PassCostReport`, whose `Display`/`parse` pair
# keeps the check build that publishes the pass-cost report and
# `sched_check_build` that reads it on one format. `check` because that is
# where the report lives: `src/build.rs`'s artifact gate asks the shipping
# kernel to carry none of the check instruments' literals. `kernel/` is
# excluded from this workspace with its own lockfile, so nothing here reaches
# the kernel's resolution of the same crate.
toyos-sched = { path = "toyos-sched", features = ["check"] }
# The root-hub port machine, for the three durations `xhci_slow_connect` derives
# its bounds from: `DEBOUNCE_NS`, `EMPTY_BUS_NS` and `SLOW_CONNECT_NS` are
# declared once there and `use`d by the driver, so the window the harness
# certifies and the one the driver holds cannot drift apart. Also the Bulk-Only
# phases, so the harness judging a wedge reads the word `toyos_xhci::bot::Phase`
# declares instead of spelling it a second time.
# The Bulk-Only phases, so the harness judging a wedge reads the word
# `toyos_xhci::bot::Phase` declares instead of spelling it a second time.
toyos-xhci = { path = "toyos-xhci" }
# The second reader `pkg_install_gbae` is judged against: what is read back off
# the guest's volume is compared with a third party's decoding of the committed
Expand Down
2 changes: 1 addition & 1 deletion issues/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ renamed in the commit that corrects the body, with every citation moved.

## Pointing at one

**Name the file, not the directory.** `issues/audio/hda-tone-phase-check.md`
**Name the file, not the directory.** `issues/audio/null-sink-applies-one-connect.md`
is a claim something can check; `issues/audio/` is a claim that an area
exists, which says nothing about whether the entry you meant is still there.

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,5 +25,6 @@ the stick while a tone plays is the same stimulus.

## Exit condition

`audio_tone_load` at eight CPUs green across repeated boots while a guest
program writes a mebibyte to `/log` during the tone.
On the T14, a `METAL` row plays `hda_tone`'s tone while a program writes a
mebibyte to `/log`, and soundd reports `underruns=0` over the tone's window
across repeated boots. Owner: the metal suite (`tests/toyos.rs`'s `METAL`).
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,6 @@ negotiation, with soundd clamping to `[num_buffers.next_power_of_two(),
MAX_SLOTS]`. A client that asks for nothing gets today's value, so the default
is unchanged. `num_buffers` stays a device property and stops leaking.

**Blocked on the audio gate, not on anything in soundd.** This changes the
latency and wake pattern gate A measures, so it lands in a quiet window with the
thorough tier behind it as a same-session A/B — the fast tier cannot see it, and
these counters drift between batches on one host with no code change at all.

Half of the original coupling is already gone: the `num_buffers > 5` startup
panic became `deferral_floor_nanos` returning `None`, and an unrenderable shape
is refused by name rather than asserted.
18 changes: 10 additions & 8 deletions issues/audio/desktop-session-put-26ms-of-silence.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,7 @@ soundd: wakes=389 completions=690 submitted=690 underruns=1 drains=2 max_wake_la
Nine periods — 26 ms — submitted with a client streaming and no client audio
behind them (`MixStats::period` in `toyos-mixer/src/stats.rs`, which is where
that counter moved when the mixer's decisions became a pure crate).
`tests/audio-baseline.toml` records `underruns` 0
on all 120 runs of its sample, and the fast tier's verdict is exactly this
counter. There is no capture to corroborate it: `--dump-audio` was not on.
There is no capture to corroborate it: `--dump-audio` was not on.

**And it is not confined to those two windows.** Across the whole run, 15 of
119 windows report `drains` (22 events; recorded sample 0/120), and the
Expand All @@ -37,8 +35,7 @@ audio_tone sample 30 5666 — — 10090 (baseline file)
```

The tone phase is 88 windows, none below 18116 us, against a recorded sample
whose *worst of 30* is 10090. The two distributions are disjoint. 106654 us is
past the `audio_tone_load.smp8` ceiling of 80000 (this guest is `--smp 8`).
whose *worst of 30* is 10090. The two distributions are disjoint.

**Whose lateness it is, is not the same question in the two phases, and the
`deferred` column separates them.** `deferred` counts a mix cycle declining to
Expand Down Expand Up @@ -115,6 +112,11 @@ underruns. The counters print every 2 s while a client exists.

Measured harm — 26 ms / 9 periods of silence with a client streaming, plus a
tone-phase wake-lateness cluster the recorded sample never reaches — makes
this a defect under the audio law rather than a comparability note. Owed to
whoever next gives gate A a doom-plus-resume workload and settles `armed_on`
against `target` in `signal_clients`.
this a defect under the audio law rather than a comparability note.

## Exit condition

`armed_on` is settled against `target` in `signal_clients`, and on the T14 a
`METAL` row streams a client while `tone` restarts beside it, as the session
above did, with soundd reporting `underruns=0` in every window a client holds,
across repeated boots. Owner: the metal suite (`tests/toyos.rs`'s `METAL`).
11 changes: 0 additions & 11 deletions issues/audio/disk-wait-pins-a-cpu.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,17 +21,6 @@ the log sink; it is that this kernel cannot touch a disk without pinning a CPU
for the whole device round trip. The log sink is only the writer that runs
continuously, which is why it is the one gate A sees.

`usb-slow-device` (kernel feature) holds every mass-storage bulk completion back
2 ms, which is what a USB stick's erase block does to a 4 KiB write and what
QEMU's `usb-storage` has no device, drive or machine property to express.
`cargo test --test toyos-build -- audio_tone --slow-usb` stages the T14's harm
on this host: soundd's worst wake goes 7,117 → 165,948 µs at smp=1 and
10,632 → 259,706 µs at smp=8 — 7 to 11 whole 23.2 ms pipelines — drains appear
on three of the four configs, and one boot of three submitted 76 silent periods
and tripped gate A's own harm verdict. Baseline arm at host load 5.0–6.6, slow
arm at 1.3–1.5, so the direction is not the host's. Both arms, one session, one
tree.

The log-flush deferral fix — whose affordability heuristic left the kernel with
the log architecture, so no CPU takes a flush now — and
[`stop-the-device-voice-keep-the-wake.md`](stop-the-device-voice-keep-the-wake.md)
Expand Down
19 changes: 2 additions & 17 deletions issues/audio/doom-audio-callback-stalled-on-the-t14.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,7 @@ opened: 2026-08-05
# Nothing explains why doom's audio callback stalled on the T14

doom's sound producer can no longer kill the game when its callback stops
consuming — `doom_sound_flood` stages exactly that and the game lives — and
that is the whole of what is now known. **Why the callback stopped on the
consuming, and that is the whole of what is now known. **Why the callback stopped on the
owner's machine, about five seconds into play, is not.** The evidence is one
abort message, because the process that would have carried the answer is the
one that died.
Expand All @@ -29,19 +28,5 @@ where any syscall on that thread can become the USB
driver's engine for as long as a second; and plain scheduling pressure from a
game thread and a compositor that never yield to it.

**One runner sighting is filed under this name and is not this defect.** In run
`31247206462`, `doom_sound_flood` was `timed out after 88s` when re-run alone,
against 4–26 s on the dev host, and 0 of 5 in the rate probe five days later —
a sighting without a rate, carried as a row in `src/redlist.rs`. It was one of
four reds in that run, three of them soundd's, which is why they were read
together at the time; of the other three, `metal_sim_null_audio` was a test
reading a boot line through a span of host wall clock and is closed,
`hda_client_stall` was a `DEADLOCK` between the idle loop's log-file flush and
the xHCI disk lock and is no longer reachable, and `sshd_fail_closed` is
undiagnosed and has its own row. Nothing in that run's capture names the
callback, so it neither supports the mechanism above nor rules it out.

What would decide it is the callback's own period count against wall clock, on
that machine. doom now keeps that counter (`MIXED_PERIODS`) and now survives
the stall, so the next T14 session can be asked the question instead of losing
the process that would have answered it.
that machine.
41 changes: 0 additions & 41 deletions issues/audio/doom-sound-flood-played-full-scale-once.md

This file was deleted.

56 changes: 0 additions & 56 deletions issues/audio/gate-a-first-run-to-record-its-host.md

This file was deleted.

Loading
Loading