Repository navigation
Metal judges read the channel their line crosses on - #616
Conversation
main's full T14 run at 7e15181 (233 passed, 19 failed) red eleven names on judges and harness that were wrong about the machine, not on the OS. Each fix below has a host check fed the readback lines that run printed, and a mutation that turns it red. - Serial::alive counted only `[kernel ` heads, so a /log readback, whose records open `[<date> <time> <secs> cpuN]`, carried "no kernel output" and every must_not_say / must_be_clean refused before judging (klogd_hosted, loader_watchdog_arms, hda_tone, hda_client_stall). kernel_lines now counts what toyos_logstream::record_ms parses, the one reader of a record's head. - machine_reboot and log_poll_outlives_a_close asked kernel.log for `Rebooting.`, which the stop writes after init had the file made whole; they now ask bootlog::handed_back of the pass after the reset. deadline_wedge_chain and usb_load_chain read `wedge: staged`, the arrived-deaf line and `usb-load: sweeping` (and the absences beside them) off the page, where they cross; both lose their kernel argument. Deletes issues/hardware/the-metal-wedge-judge-reads-a-channel-the- wedge-cannot-write.md. - toyos-metal refused HungWithoutARecord for blackbox_foreign_record's image, whose pass after the reset hands the machine back by design. The verdict is now boot_verdict(armed, loader, log): an image armed with FOREIGN_RECORD_ARM is judged on its log and not refused for that hang, and its judge asserts the hand-back line. That page is cleared as another image's, so the loop no longer demands the panel census and park count off it; their three foreignrecord profile rows are deleted. - xhci_xecp matched `USB Legacy Support` / `ownership`; the T14 prints `firmware did not claim the controller`. The judge now names the three outcomes that leave the kernel owning the controller, and no longer accepts the "runs past the register window - no handoff" line. - allocator_stress bounded total memory to 2..=9 GB, a QEMU guest's size; the T14 reports 16777216000 bytes. The range is gone; used < total stays. - A shared metal chunk staged only RUST_SKIP helpers its text names, so dlopen_dedup's read of /system/bin/test_rs_std_tls failed when std_tls rode the other chunk. metal::reached stages every binary the chunk's text names that is not already a job; run() and build() lose helpers. - The guest C comparator compared 03_struct's committed warning line the host drops. c_expectation drops it once, and the corpus stages that. Files issues/build/allocator-stress-bounds-a-failed-reservation-by- sixteen-gib.md for the 16 GiB try_reserve beside the deleted range. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01U6SVYFkdvV2t38KzNrESxs
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01U6SVYFkdvV2t38KzNrESxs
#615 filed one issue per cause of main's T14 reds at 7e15181. The seven whose cause c204db1 removes go, each on the host check and mutation that commit names; the T14 rows they name are the close's remaining evidence, run before this lands: - a-readbacks-kernel-records-never-count-as-kernel-output - a-metal-judge-reads-the-log-file-for-a-record-written-after-it-was-made-whole - the-metal-loop-refuses-the-hang-the-foreign-record-arm-stages - the-xecp-judge-names-no-line-the-t14s-handoff-prints - allocator-stress-bounds-total-memory-by-a-qemu-guests-size - a-shared-metal-chunk-stages-no-test-binary-another-member-reads - the-guest-c-comparator-keeps-the-tinycc-warnings-the-host-one-drops The one citation of the first, in a-metal-only-row-cannot-be-disabled, goes with it. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01U6SVYFkdvV2t38KzNrESxs
|
Review of #616 at Net: 18 files, +352 −461. Code is +331 −129. About +183 of that is tests ( BLOCKER
NOTE
REMOVE
SEND BACK 🤖 Generated with Claude Code |
… DONE The foreign-identity arm's verdict dropped `handed_back` and put nothing in its place, so a stop that panicked or that the deadline ended after init's STOPPING line passed: the kernel seals every state under the foreign identity. `boot_verdict` and the `blackbox_foreign_record` judge now demand the loader's `held a DONE record another image left in this memory` (`bootlog::FOREIGN_DONE`), refused as `Unfit::NoForeignDone`. `xhci_xecp` judged only the first handoff line and the first reset, and the T14 prints two controllers. Every `take_ownership` outcome is now paired with the reset after it: each is one that hands the controller over, precedes its own reset, and there are as many as there are resets. `is_kernel_line` is the one definition of a kernel line again: it reads a `/log` file's dated head as well as the console's `[kernel …]`, and `kernel_lines` calls it, so `died()` reads a readback's kernel `PANIC:` as the kernel's. Answers the review of #616; provenance prose removed. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01U6SVYFkdvV2t38KzNrESxs
The T14 run at 6737a44 cleared the kernel-output cause of the row's red, and it reds now on `soundd resumed 0 time(s)`. The file records the lines the log carries and the window the judge cut; the cause is not measured. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01U6SVYFkdvV2t38KzNrESxs
tests/common/serial.rs: main moved the serial vocabulary's self_check out of the module into tests/checks/serial.rs, and this branch had added the /log readback cases to it. The module takes main's side (the block is gone; the file is byte-identical to main's) and the three additions move with the function: the readback and readback_mute captures, their three cases, and the two readback head rows in the who-died table. tests/common/qemu.rs: the two sides edited adjacent doc comments at one seam. Main's build_toyos_bin stays; is_kernel_line keeps this branch's body and its doc comment, which names the /log head beside klogd's. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
Re-review of #616 at Net: 21 files, +503 −481. Harness code is +207 −148; the +59 net pays for seven fixes, and I accept it. Host checks ( The merge's port is whole. Earlier round (
|
…fter the reset
- `bootlog::foreign_done` searched the whole `loader.log`. The pass before
the handoff clears a stale foreign `DONE` record with the same line, so it
let `toyos-metal` exit 0 for a stop that the pass after the reset read as
`PANIC` or `WEDGED`. It now reads from `SEPARATOR` on, through
`bootlog::after_the_reset`, and `Readback::after_the_reset` makes its cut
with the same function. `metal::tests` carries the review's stale case,
and the registered judge's check carries it too.
- `xhci_xecp` had two arms that no check could fail: the `KEPT` refusal, and
the refusal of a handoff that the next one overtakes. The review's cases
`{t14}{kept}` and `{unreset}{t14}` now cover them.
- `metal::clears_its_own_page` says which arm's page the pass after its
reset clears. `boot_verdict` and the harness's boot facts both ask it.
- `reached` stages a binary only where the text names it whole:
`test_rs_std_tls_dlopen` does not name `test_rs_std_tls`.
- The QEMU half of `blackbox_foreign_record` reads `bootlog::FOREIGN_DONE`.
`the_loader_writes_the_lines_the_host_reads` holds that line to the
loader's format, with `State::Done`'s own word in its hole.
- The judge's `HUNG_WITHOUT_A_RECORD` assertion gets a case that fails it.
- `hard_lockup_chain` stops asserting that `/log` lacks `Rebooting.`, a line
that never appears there.
- The "Named and cleared" comment is deleted.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The third review of #616 found that deleting `cleared ||` from the metal loop's boot-facts skip left every host check green. The skip is now `metal::owes_nothing(field, params)`: a path the boot did not take, or a page that `toyos_build::metal::clears_its_own_page` says the pass after the reset cleared. `a_cleared_page_owes_no_fact_off_it` checks it. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The review (issuecomment-5896707051) found the committed T14 record holding rows from boots toyos-metal refused, a live run and an offline re-judge of the same readbacks recording different things, a BIOS change re-baselining silently, and rows that time Ubuntu, the router or a list's membership rather than ToyOS. The loop's verdict travels in the readback. `src/metal.rs` judges the boot before it writes the readback (`boot_verdict`, shaped as #616 shapes it, then the talk verdict) and writes `verdict.txt` last: `passed`, or `refused` and the refusal's own words. `tests/common/metal.rs` refuses a readback whose verdict is not `passed` in both modes, so a live run and an offline re-judge read one verdict off one directory. The record is one function of the readbacks. Everything after the readbacks are read is `judge_readbacks(root, readbacks, runs, shared)`, called by `run` in both modes. A boot with any failure of its own (the loop's verdict, a missing boot number, `log_reached_the_stick`, `stop_completed`, either bound's lateness, or any test or shared member riding it) is judged and adds no row. A red run still judges every reading. `measured` refuses a second value under one name on one boot, and a name two boots measure is judged on the first and recorded off neither. A run under a BIOS other than the record's is judged against the record, fails naming both strings, and records nothing; re-baselining is deleting the file, which the module doc now states as the contract. `Record::get` and the `recorded` arm of `PATH_TAKEN` go: the wedge judges already refuse a page naming the other bound. Rows that are not ToyOS's timing, or cannot fail, are no longer measured: every `back_secs` (firmware POST, Ubuntu and ssh; the loop still refuses past `return_secs` and the line still prints it), `stick_secs` (the loop refuses past `STICK_SECS`), `ping_secs`, `link_up_ms`, `lan.*.lease_ms` (its ceiling was past `LEASE_BOUND_MS`), and `list.*.job_ms` (a mean over a membership every added test moves; a list past the bound already fails as missing exit records). The per-member cost still prints. The two lateness numbers become checks against the period of what polls them, a millisecond either way for the two floored readings. The hard lockup's against its sample period, now `toyos_tco::HARD_LOCKUP_SAMPLE_NS` so the kernel and the host read one declaration. The deadline's against one scheduler quantum, the one-shot every CPU a staged wedge holds re-arms, and counted from the kernel's `boot deadline:` record (`bootlog::DEADLINE_ARMED`, held to `kernel/src/deadline.rs` by the kernel-spelling gate): the old reading was `reached - bound`, with the expiry quoted since boot and the bound running from the arm at 60 ms, so run 2's 64 and 67 were 4 and 7 ms of poll and 60 ms of boot. An early expiry is now a reading and fails, where it used to read as no expiry. `cyclictest` refuses a p99 past its histogram itself (-3), so the 4096 the harness restated goes. `SharedBoot::members` is a `NonZeroUsize`. tests/metal/lenovo-20w0003amz.toml keeps only what this rule would have recorded from the readbacks that wrote it (the offline re-judge of 09fe612's run): 151 rows become 56. Gone are the deleted classes above and every row of the eleven boots that failed there: foreignrecord and lantalkcase (refused by the loop), lancase (lan_dhcp_lease), testcases (klogd_hosted, log_poll_outlives_a_close, hda_tone, hda_client_stall, loader_watchdog_arms), testcases-watchdog (loader_watchdog_arms), deadlinewedge (boot_deadline_ends_a_wedge), usbload (usb_reset_records_the_phase_it_cut), jobcase (machine_reboot), selftests (xhci_xecp_walk), shared (four members) and ccorpus (03_struct). The next run records them once they pass. Host checks: every committed record loads from its own path; a record file naming another machine and a duplicated row are refused; the stop's two refusals, each bound's lateness, the verdict round trip, the failed-boot filter and the duplicate-name refusal each have a test that a mutation of the rule turns red. Filed: the identity read over ssh, whose exit is the boot naming its machine; `test_rs_mutual_kill`'s stdio panic on run 2; and that a record never tightens. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
Negative controls for the third review, at
Patch 07's build compiles the host lib, whose gate reads the loader's source as text; it does not compile the loader. Patch 08's build compiles the mutated
diff --git a/src/bootlog.rs b/src/bootlog.rs
index 8ac0fe2fa..c3b810f8b 100644
--- a/src/bootlog.rs
+++ b/src/bootlog.rs
@@ -367,10 +367,10 @@ pub fn handed_back(loader: &str) -> Result<(), Unfit> {
/// The loader's half of a passing foreign-identity boot, whose own chain the
/// loader ends as a hang: the record it cleared was sealed `DONE`.
pub fn foreign_done(loader: &str) -> Result<(), Unfit> {
- // The pass before the handoff clears a stale foreign record the same way.
- match after_the_reset(loader) {
- Some(after) if after.contains(FOREIGN_DONE) => Ok(()),
- _ => Err(Unfit::NoForeignDone),
+ if loader.contains(FOREIGN_DONE) {
+ Ok(())
+ } else {
+ Err(Unfit::NoForeignDone)
}
}
diff --git a/tests/toyos.rs b/tests/toyos.rs
index 70dc6817c..d5b2eefb1 100644
--- a/tests/toyos.rs
+++ b/tests/toyos.rs
@@ -14747,9 +14747,6 @@ fn xhci_xecp(log: &str) -> Result<(), String> {
let mut handoffs = Vec::new();
let mut pending: Option<&str> = None;
for line in log.lines() {
- if KEPT.iter().any(|said| line.contains(said)) {
- return Err(format!("a controller was never handed over: {line}\n{log}"));
- }
if HANDED_OVER.iter().any(|said| line.contains(said)) {
if let Some(earlier) = pending.replace(line) {
return Err(format!("a handoff with no reset of its own: {earlier}\n{log}"));
diff --git a/tests/toyos.rs b/tests/toyos.rs
index 70dc6817c..d632876c1 100644
--- a/tests/toyos.rs
+++ b/tests/toyos.rs
@@ -14751,9 +14751,7 @@ fn xhci_xecp(log: &str) -> Result<(), String> {
return Err(format!("a controller was never handed over: {line}\n{log}"));
}
if HANDED_OVER.iter().any(|said| line.contains(said)) {
- if let Some(earlier) = pending.replace(line) {
- return Err(format!("a handoff with no reset of its own: {earlier}\n{log}"));
- }
+ pending = Some(line);
} else if line.contains("xHCI: controller reset") {
let Some(handoff) = pending.take() else {
return Err(format!("a controller reset before its handoff: {line}\n{log}"));
diff --git a/tests/common/metal.rs b/tests/common/metal.rs
index c2254eeb0..87245e8ad 100644
--- a/tests/common/metal.rs
+++ b/tests/common/metal.rs
@@ -701,13 +701,6 @@ pub fn reached(
jobs: &[String],
rust_bins: &[(String, Vec<u8>)],
) -> Vec<(String, Vec<u8>)> {
- // Whole: a longer name that opens with this one is another binary's.
- let names = |staged: &str| {
- reachable.match_indices(staged).any(|(at, _)| {
- !reachable[at + staged.len()..]
- .starts_with(|c: char| c.is_ascii_lowercase() || c.is_ascii_digit() || c == '_')
- })
- };
let mut out = Vec::new();
for (name, data) in rust_bins {
let staged = format!("test_rs_{name}");
@@ -716,7 +709,7 @@ pub fn reached(
// together are a fraction of one helper binary.
if name.ends_with(".so") {
out.push((format!("lib/{name}"), data.clone()));
- } else if !jobs.contains(&staged) && names(&staged) {
+ } else if !jobs.contains(&staged) && reachable.contains(&staged) {
out.push((format!("bin/{staged}"), data.clone()));
}
}
diff --git a/tests/common/metal.rs b/tests/common/metal.rs
index c2254eeb0..5c0d4a6d7 100644
--- a/tests/common/metal.rs
+++ b/tests/common/metal.rs
@@ -35,7 +35,7 @@ const PATH_TAKEN: &[&str] =
/// none and the profile prices none: a path it did not take, or a field that
/// crosses only on a page the pass after its reset cleared.
pub fn owes_nothing(field: &str, params: &[&str]) -> bool {
- PATH_TAKEN.contains(&field) || toyos_build::metal::clears_its_own_page(params)
+ PATH_TAKEN.contains(&field)
}
/// One boot a metal test needs.
diff --git a/src/metal.rs b/src/metal.rs
index 3b7966c28..3a6dfa7eb 100644
--- a/src/metal.rs
+++ b/src/metal.rs
@@ -879,7 +879,7 @@ pub fn stages_a_wedge(armed: &[String]) -> bool {
/// as another image's: nothing crosses on the page but the record's state, and
/// that pass hands the machine back as a hang.
pub fn clears_its_own_page(armed: &[impl AsRef<str>]) -> bool {
- armed.iter().any(|name| name.as_ref() == FOREIGN_RECORD_ARM)
+ armed.is_empty()
}
/// [`FLASHABLE`]'s ruling on `name`, or `None` where nobody has made one.
diff --git a/bootloader/src/blackbox.rs b/bootloader/src/blackbox.rs
index 0f7498103..87ad2c441 100644
--- a/bootloader/src/blackbox.rs
+++ b/bootloader/src/blackbox.rs
@@ -150,7 +150,7 @@ pub fn harvest(
return (
None,
Some(alloc::format!(
- "{HEAD} {PHYS:#x} held a {} record another image left in this memory \
+ "{HEAD} {PHYS:#x} held a {} record another image left in memory \
({was:02x?}, and this stick is {identity:02x?}), armed at {}. It has been \
cleared and this pass boots its kernel",
state.named(),
diff --git a/toyos-blackbox/src/lib.rs b/toyos-blackbox/src/lib.rs
index b2e5653a1..ccf34beef 100644
--- a/toyos-blackbox/src/lib.rs
+++ b/toyos-blackbox/src/lib.rs
@@ -165,7 +165,7 @@ impl State {
match self {
Self::Armed => "ARMED",
Self::Panic => "PANIC",
- Self::Done => "DONE",
+ Self::Done => "FINISHED",
Self::Wedged => "WEDGED",
Self::Fault => "FAULT",
}
diff --git a/tests/toyos.rs b/tests/toyos.rs
index 70dc6817c..185c5b7f1 100644
--- a/tests/toyos.rs
+++ b/tests/toyos.rs
@@ -1929,8 +1929,6 @@ const METAL: &[(&str, metal::Metal)] = &[
let said = after.must_say(bootlog::FOREIGN_DONE)?.to_string();
power::says_nothing_of(&after, bootlog::PREVIOUS_PANIC)?;
power::says_nothing_of(&after, "the last boot read")?;
- // The hang `toyos-metal` admits for this arm, and only this one.
- after.must_say(bootlog::HUNG_WITHOUT_A_RECORD)?;
eprintln!(" [power] {}", said.trim());
Ok(())
},
diff --git a/tests/toyos.rs b/tests/toyos.rs
index 70dc6817c..76ad2fc8c 100644
--- a/tests/toyos.rs
+++ b/tests/toyos.rs
@@ -1925,7 +1925,7 @@ const METAL: &[(&str, metal::Metal)] = &[
&[],
)],
judge: |b| {
- let after = b[0].after_the_reset()?;
+ let after = b[0].loader();
let said = after.must_say(bootlog::FOREIGN_DONE)?.to_string();
power::says_nothing_of(&after, bootlog::PREVIOUS_PANIC)?;
power::says_nothing_of(&after, "the last boot read")?; |
|
Delta re-review of #616, Net Re-planted in a scratch worktree detached at
Earlier findings
BLOCKER
NOTE
REMOVE
SEND BACK |
…case, and the T14's hda_tone red is filed - `xhci_xecp` refuses a log in which it recognises no handoff, and no check could fail that refusal: without it, a log with no outcome and no reset passed as long as the controller started. `silent`, the review's case, fails it. - `bootlog::foreign_done`'s `None` arm, a chain that never went round, was reached by no case: reading the whole `loader.log` there passed a stop that only the pass before the handoff had said. The review's `unreturned` log now reaches it through `boot_verdict`. - `power::done_line` spelled `bootlog::HANDED_BACK` a second time, from `State::Done.named()`. Its four callers read the constant and it is deleted. - `owes_nothing`'s doc said a field crosses only on the cleared page. The cleared arm ignores the field, so that clause is deleted. - The orchestrator's T14 run at `f5c80264f` reads `hda_tone` red on the judge's own assertion, where `main`'s run read it red before it judged. `issues/audio/hda-tone-reads-underruns-on-the-t14-where-its-judge-wants-none.md` files the line and the window, and claims no cause. The exit of the deleted `a-readbacks-kernel-records-never-count-as-kernel-output` was that a T14 run of the four rows it names reaches each judge's own assertions, and each does. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
|
Negative controls for the fourth review, at
--- a/tests/toyos.rs
+++ b/tests/toyos.rs
@@ -14764,9 +14764,6 @@
if let Some(unreset) = pending {
return Err(format!("a handoff with no reset of its own: {unreset}\n{log}"));
}
- if handoffs.is_empty() {
- return Err(format!("no controller was handed over and reset:\n{log}"));
- }
// A controller that still enumerates its bus afterwards.
if !log.contains("xHCI: controller started") {
return Err(format!("the controller did not come up:\n{log}"));
--- a/src/bootlog.rs
+++ b/src/bootlog.rs
@@ -368,7 +368,7 @@
/// loader ends as a hang: the record it cleared was sealed `DONE`.
pub fn foreign_done(loader: &str) -> Result<(), Unfit> {
// The pass before the handoff clears a stale foreign record the same way.
- match after_the_reset(loader) {
+ match after_the_reset(loader).or(Some(loader)) {
Some(after) if after.contains(FOREIGN_DONE) => Ok(()),
_ => Err(Unfit::NoForeignDone),
} |
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016t9wjdQkB8SH7bmfUoiy6L
One conflict, content: issues/build/a-metal-only-row-cannot-be-disabled.md. Both sides edited its "Measured" paragraph, on neighbouring lines. Main cut the line citing issues/build/a-readbacks-kernel-records-never-count-as-kernel-output.md, a file #616 deleted; this side renamed `schedule` to `registered` on the line after it. Both edits stand: the citation is gone and the line reads `registered.contains`. None of the eight files #616 deleted is cited by path or by bare name anywhere in the merged tree. Every other file merged without a conflict, and the two that both sides edited were read for what the edits mean together: - tests/toyos.rs: main's hunks are the METAL rows' judges, the C corpus's expectation reader, the xHCI handoff judge and `metal::run` without its `RUST_SKIP` argument; this side's are the registration tables, the selection and the shard partition. The metal arm of `main()` calls this side's `registered` and main's `metal::run`, and no line of it is in both. - tests/checks.rs: main's metal-judge checks follow this side's selection and registration checks, and the `--metal --list` check calls main's `metal::run` with this side's `selected`. #616 brought no tier, reach-flag or schedule wording: its patch, searched whole for them, has none, and a sweep of every CLAUDE.md, .claude/agents/*.md, README.md and issues/ for `tier`, `--nightly`, `--weekly`, `Fast`, `Nightly`, `Weekly`, `Local` and the removed names finds the same lines before and after the merge. The rust gitlink is 90697f14 on both sides and does not move. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016t9wjdQkB8SH7bmfUoiy6L
#616 has the metal judges read the channel their line crosses on. It does not touch `transport_break_on_metal` or its registration, and the merge is clean. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016t9wjdQkB8SH7bmfUoiy6L
#616 lets the foreign-record boot pass the loop, and its page is cleared by the pass after the reset. The merge had three conflicts. Every hunk on both sides is accounted for as follows. src/metal.rs: #616's run tail was boot_verdict, then talk_verdict, then Ok(Some(ms)). judge_and_write_readback already does that, in that order, and writes the verdict into the readback, so the branch's `verdict` stays. boot_verdict takes #616's body whole: the staged hang is admitted for FOREIGN_RECORD_ARM, and foreign_done replaces handed_back for it. tests/common/metal.rs: - #616's owes_nothing and PATH_TAKEN go. This branch deleted PATH_TAKEN and park_open_operations along with the profile loop that read them. - read_readback takes #616's Readback::new, and Readback::new gains the branch's machine and numbers. #616's own checks build a readback with no machine keys, and it still constructs, because machine is a Result the judge reads. - In the profile loop, #616 changed one line so that a cleared page owes nothing. The loop is gone. Its intent now lives in judge_readbacks: the panel census crosses only on the page, so a boot whose pass after the reset cleared its page as another image's (bootlog::foreign_done) owes no panel_max_us or panel_us. It still owes complete_ms. The rule is read off the page, so the record stays one function of the readbacks. - helpers -> reached is taken as #616 wrote it. tests/metal-profile.toml is modify/delete. #616 dropped the foreignrecord panel_max_us, panel_us and park_open_operations rows. This branch deleted the file, so it stays deleted: the rule above carries the panel rows, and park_open_operations exists nowhere on this branch. tests/checks.rs: #616's a_cleared_page_owes_no_fact_off_it goes with owes_nothing. It is replaced by metal_cleared_page_owes_no_panel, which plants two readbacks. The first is foreignrecord with the T14's cleared page after the reset. judge_readbacks judges it green, and it records boot.foreignrecord.complete_ms and nothing else. The second is the same boot and the same lines, but the record was cleared by the pass before the handoff, so this boot's own page still owes the census. With no census it is red and records nothing. The pair reds a judge that owes the panel from every boot and a judge that owes it from none. It also reds a rule keyed on the label, on the hang line, or on the whole loader.log. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016t9wjdQkB8SH7bmfUoiy6L
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016t9wjdQkB8SH7bmfUoiy6L
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016t9wjdQkB8SH7bmfUoiy6L
tests/toyos.rs, ten hunks: #625 drops the tier from every registration, and this branch deletes the kernel's page cache, write-back, /log mount and boot-volume rows and adds fsd's and blockd's. Each hunk keeps this branch's rows and comments, and no row carries a tier. home_overwrite_reads_back's tier change goes with the tiers, and its comment stays this branch's. issues/filesystem/home-budget-refusal-retried-is-red-on-every-nightly.md: modified on main (it drops "(nightly tier)") and deleted here with home_budget_refusal_retried in c191577. The deletion stands, since nothing on either side runs the test it names. tests/checks.rs: #616's metal_judges_read_the_page_for_what_only_the_page_carries planted "Syncing filesystems..." as the tail of a stop that never reached its last word. This branch deletes that line from the kernel's stop, and the stop record is what readers of the stop order against. The fixture is now a stop record from the T14's readback at 10dc46c. The rust gitlink does not conflict. Main's pin is 90697f1401a, the same as at the last merge base, and this branch's c4c65e3e87a contains it. The quiesce-last staging issue: STAGED is 42010 ms now, the stop's own budgets plus PARK, but it is still an in-guest deadline that both sides of the staging panic on. The issue therefore stays. Its slug named ten seconds, which the tree now refutes, so the file is renamed the-quiesce-last-staging-dies-on-a-guest-clock-deadline.md with a heading that names STAGED. It gives up the clause about quiesce_twice's WAITS_WITHIN, which exists on neither side. Nothing cites it under either name. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016t9wjdQkB8SH7bmfUoiy6L
The T14's full metal run at 0d2dda6, the merge of origin/main at 3af4701 (#616), wrote this file and nothing else: - It printed "84 number(s) on LENOVO 20W0003AMZ, BIOS N34ET71W (1.71 ); 0 past its record, 9 off a boot that failed". - It printed "now records 75 number(s) for this machine: commit it". The record held 56. The 19 added rows come from seven boots that the loop read back as `passed` and that carried no failing test or member: ccorpus, deadlinewedge, foreignrecord (`complete_ms` alone, because its page was cleared as another image's), jobcase, selftests, testcases-watchdog and usbload. - Its only FAILs are main's known reds: hda_client_stall ("soundd resumed 1 time(s)"), lan_dhcp_lease, lan_talk, lantalkcase, test_rs_fs_large_file and test_rs_home_backing_revoked. The 9 numbers off a failed boot are lancase's, testcases' and shared's. lantalkcase's readback was refused, so it measured none. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016t9wjdQkB8SH7bmfUoiy6L
#616 landed on main; it touches no file this branch does. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016t9wjdQkB8SH7bmfUoiy6L
…were four `lancase`, `lanicscase` and `lanleasecase` each flashed the stick and booted the machine once more (100-208 s a cycle in the rig's budget) to ask a question the talking boot, `lantalkcase`, now answers: - `lan_dhcp_lease` rides `lantalkcase`, which names the I219's function, so the loop pings the address it held under Ubuntu there as it did on `lancase`. netd's lines cross on the stick since each program has a log ring (#616), and on 630r4's full run `lantalkcase` carried the same MAC, link-up and lease lines `lancase` did. The judge drops `lan_hold`'s exit, which the talking boot's own judge replaces with `lan_talk_hold`'s. `lan.lancase.*` and `boot.lancase.ping_secs` are the talking boot's rows now. - `lan_message_delivery` rides it too, as `delivered_on_metal`. Its issue's exit condition was the shipping boot recording `pcidev: slot N took its first message` without the actuator, and all three LAN boots of 630r4 did, the talking one at 8.498 s. So `--provoke-message` has no question left: it goes from netd, from `toyos-i219` (`provoke_message` and the two tests of it) and from `build.rs`'s Intel-actuator gate, and `issues/hardware/the-lanicscase-boot-is-a-second-t14-flash-for-one-question.md` closes. - `lan_lease_report`'s metal row goes: netd's probe exists for a console line that could not cross, and the lease it reports is `lan_dhcp_lease`'s to judge off netd's own lines. The QEMU registration stays, since its link-flap check reads the probe's report; the issue that tracked the whole probe keeps that half under a slug that says what is left, `issues/diagnostics/netds-lease-probe-answers-a-question-its-lines-already-answer.md`, and `Readback::log_volume_file`, its only reader on the metal side, goes. Deleted with them: the three configs and their `ALL_CONFIGS` rows, their profile rows (the talking and swapping boots' rows that were derived "as lancase" now state that derivation), and `lan::CONFIG`, `BOOT`, `ICS_*`, `LEASE_CONFIG`, `LEASE_BOOT` and `JOBS`. `lan_hold` stays: `testcases-deaf` holds its boot open with it, and the metal-profile check of its window now reads that boot's allowance. The ssh issue's exit condition names the one arm it still owns. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016t9wjdQkB8SH7bmfUoiy6L
The full T14 run of
mainat7e151819(233 passed, 19 failed) reddened eleven rows. The fault in each was a judge or the harness being wrong about the machine. The triage in #615 found no OS defect. This branch fixes the seven causes the evidence makes certain and closes their issues.Each fix has a host check fed readback lines from a T14 run, and a mutation that turns that check red. The recorded T14 run is the independent oracle, and the T14 run at
f5c80264fis in the table below.What changed, per cause
klogd_hosted,loader_watchdog_arms,hda_tone). A/logreadback's records open[<date> <time> <secs> cpuN], and only[kernelheads were counted. So everymust_not_sayandmust_be_cleanrefused before it judged anything.qemu::is_kernel_lineis the harness's one definition of a kernel line. It now reads both heads: the console's[kernel …], and any linetoyos_logstream::record_msparses.Serial::kernel_linesanddied()both call it. So a readback's kernelPANIC:now reads asDied::Kernel.serial::self_checkgains three/logreadback rows (one of them programs-only, which must still refuse). It also gains twodied()rows: a dated kernelPANIC:and a program's.kernel.logfor records only the page carries (machine_reboot,log_poll_outlives_a_close,usb_reset_records_the_phase_it_cut,boot_deadline_ends_a_wedge). The kernel writes these lines after init had the file made whole:Rebooting.,wedge: staged, the arrived-deaf line andusb-load: sweeping. They cross only on the sealed page, in the pass after the reset.bootlog::handed_backof that pass.deadline_wedge_chainandusb_load_chainassert those records afterPrevious boot's panic:. The absences beside them move to the page too.hard_lockup_chainno longer asserts thatkernel.loglacksRebooting., which never reaches/log.metal_judges_read_the_page_for_what_only_the_page_carries.toyos-metalrefused the hang the foreign-record arm stages (blackbox_foreign_record). Its pass after the reset clears the record as another image's and hands the machine back. The verdict is now a pureboot_verdict(armed, loader, log).FOREIGN_RECORD_ARMis not refused forHUNG_WITHOUT_A_RECORD.handed_back, it owesbootlog::FOREIGN_DONE: the loader'sheld a DONE record another image left in this memory. The kernel seals every state under the foreign identity, so onlyDONEsays the stop finished. A stop that panicked or wedged is refused asUnfit::NoForeignDone.boot.foreignrecord.*census rows are deleted.metal::tests::the_foreign_record_arm_reaches_its_judge_through_the_hang_it_stagesgivesOk(1171)armed andHungWithoutARecordunarmed. It givesNoForeignDonefor aPANICorWEDGEDrecord.checks::the_foreign_record_judge_demands_the_stop_sealed_donechecks the registered judge the same way.bootlog::foreign_donereads frombootlog::SEPARATORon, throughbootlog::after_the_reset, andReadback::after_the_resetmakes its cut with that function too. The pass before the handoff clears a stale foreignDONErecord with the same line, so reading the whole file passed a stop that the pass after the reset read asPANIC.metal::clears_its_own_pagesays which arm's page the pass after its reset clears.boot_verdictasks it, and so does the loop'smetal::owes_nothing.bootlog::FOREIGN_DONEas well.the_loader_writes_the_lines_the_host_readsholds that line to the loader's format, withState::Done's own word in its hole.power::done_linespelledbootlog::HANDED_BACKa second time, fromState::Done's word. It is deleted, and its four callers read the constant.boot_verdictand the judge both refuse a staleDONEin the pass before the handoff when the pass after it readPANICorWEDGED. The judge refuses a pass withoutHUNG_WITHOUT_A_RECORD.a_cleared_page_owes_no_fact_off_itchecksowes_nothing.boot_verdictrefuses a chain that never went round: a stale foreignDONEand the handoff's last line, with no pass after the reset (unreturned).xhci_xecpnamed no line the T14 prints, and judged one controller (xhci_xecp_walk). The judge now pairs everytake_ownershipoutcome with thecontroller resetafter it.unusable,runs past the register window, andstill owns.the_xecp_judge_reads_the_t14s_handoff. One and two T14 controllers pass. A second controller that firmware kept reds, and so do a handoff with no reset and a reset with no handoff.{t14}{kept}). The other is a handoff with no reset, followed by a paired one ({unreset}{t14}).silent): the T14's lines with neither an outcome nor a reset, and the controller started.allocator_stressbounded total memory to 2..=9 GB, which is a QEMU guest's size. The range is deleted, and0 < used < totalstays.RUST_SKIPhelpers its text names (dlopen_dedup).metal::reachednow stages every binary a chunk's text spellstest_rs_<name>that is not already one of its jobs. Check:a_shared_chunk_stages_every_binary_its_members_name.test_rs_std_tls_dlopendoes not nametest_rs_std_tls.03_struct).c_expectationdrops it once, and both comparators read the result. Check:the_c_corpus_stages_the_expectation_the_host_compares.Issues
This closes eight files:
the-metal-wedge-judge-reads-a-channel-the-wedge-cannot-writea-readbacks-kernel-records-never-count-as-kernel-outputa-metal-judge-reads-the-log-file-for-a-record-written-after-it-was-made-wholethe-metal-loop-refuses-the-hang-the-foreign-record-arm-stagesthe-xecp-judge-names-no-line-the-t14s-handoff-printsallocator-stress-bounds-total-memory-by-a-qemu-guests-sizea-shared-metal-chunk-stages-no-test-binary-another-member-readsthe-guest-c-comparator-keeps-the-tinycc-warnings-the-host-one-dropsSeven of them name rows that PASS or exit 0 in the T14 run below. The eighth,
a-readbacks-kernel-records-never-count-as-kernel-output, named four rows and asked that a T14 run reach each judge's own assertions.klogd_hostedandloader_watchdog_armsPASS.hda_toneandhda_client_stallnow reach their own assertions and red on them, and each red is filed without a cause:hda_client_stallreds onsoundd resumed 1 time(s). At6737a442it readsoundd resumed 0 time(s). It is filed asissues/audio/hda-client-stall-reads-one-resume-where-its-judge-wants-two.md, with the lines measured.hda_tonereds onsoundd filled 104 period(s) the tone client had not covered, on a client that keeps its ring full. Onmainthe row reddened before it judged. It is filed asissues/audio/hda-tone-reads-underruns-on-the-t14-where-its-judge-wants-none.md, with the window measured.The branch also files
issues/build/allocator-stress-bounds-a-failed-reservation-by-sixteen-gib.md, and does not fix it.These are left red, with their own issues: the LAN rows,
fs_large_file,home_backing_revokedand theusbloadboot's unpricedpanel_*numbers.T14 run at
f5c80264f(the orchestrator's, full metal set)The run ended
252 passed, 6 failed, 27 boot(s), and thetoyos-buildtest binary run with--metalexited withexit status: 1(EXIT=1). The six arelan_dhcp_lease,lan_talk,hda_tone,hda_client_stall,test_rs_fs_large_fileandtest_rs_home_backing_revoked. Thelantalkcaseboot and theusbloadboot's twopanel_*rows red as well.klogd_hosted,loader_watchdog_armsmachine_reboot,log_poll_outlives_a_close,usb_reset_records_the_phase_it_cutboot_deadline_ends_a_wedge,hard_lockup_ends_a_deaf_cpublackbox_foreign_recordforeignrecordboot has no FAILxhci_xecp_walkallocator_stress,dlopen_dedup,03_struct===TEST_END … exit=0===, no FAILhda_tonesoundd filled 104 period(s) the tone client had not covered, on a client that keeps its ring full(issue filed above)hda_client_stallsoundd resumed 1 time(s) — the second stream did not find a suspended daemon(issue filed above)fs_large_file,home_backing_revoked,boot.usbload.panel_*The commit after
f5c80264fadds host cases, deletes a doc clause, replacespower::done_line()by thebootlog::HANDED_BACKit spelled, and files an issue. It changes no line a metal judge asserts, so this run stands for the head.Gates at
7b0ee7fd9cargo run -- --ci host: EXIT=0,Host: 54 step(s), all green.cargo test --test toyos-build -- --list: EXIT=0.cargo test --test toyos-checks: EXIT=0, 18 passed.Negative controls
Each mutation below was a checked patch, applied onto a clean committed tree. It was built with
--no-run(EXIT=0), run by the command shown, and then reversed. Exit 101 means the named test went red. The ten patches of thef5c80264ftable and the two of the7b0ee7fd9table are in full in comments on this PR.At
7b0ee7fd9:xhci_xecpwithout itshandoffs.is_empty()refusalcargo test --test toyos-checkstests/checks.rs:804,xhci_xecp(&silent).is_err(); the other 17 passforeign_donereads the wholeloader.log:after_the_reset(loader).or(Some(loader))cargo test --lib -- metal::tests::the_foreign_record_armsrc/metal.rs:3453, a chain that never went round getsOk(1171)The same two commands on the restored tree are EXIT=0.
At
f5c80264f:foreign_donereads the wholeloader.logagaincargo test --lib -- metal::tests::the_foreign_record_armDONEbefore the handoff getsOk(1171)xhci_xecpwithout theKEPTcheckcargo test --test toyos-checks -- the_xecp_judge{t14}{kept}isOkpending = Some(line);cargo test --test toyos-checks -- the_xecp_judge{unreset}{t14}isOkreachedmatches a substringcargo test --test toyos-checks -- a_shared_chunktest_rs_std_tls_dlopenstagesbin/test_rs_std_tlsowes_nothingwithout its cleared-page armcargo test --test toyos-checks -- a_cleared_pagepanel_usclears_its_own_pageanswersarmed.is_empty()cargo test --lib -- metal::tests::the_foreign_record_arm, andcargo test --test toyos-checks -- a_cleared_pageHungWithoutARecord; the foreign-identity boot owespanel_usleft in memorycargo test --lib -- bootlog::tests::the_loader_writes_the_lines_the_host_readsheld a {} record another image left in this memoryState::Doneis namedFINISHEDcargo test --lib -- bootlog::tests::the_loader_writes_the_lines_the_host_readsheld a DONE record …must_say(HUNG_WITHOUT_A_RECORD)cargo test --test toyos-checks -- the_foreign_record_judgeOkb[0].loader()cargo test --test toyos-checks -- the_foreign_record_judgeDONEbefore the handoff isOkAt
b4e752c12, each mutation put back the base's code at the site:boot_verdictback toif !staged_hang { handed_back }cargo test --lib -- metal::tests::the_foreign_record_armPANICpass getsOk(1171)must_say("record another image left in this memory")cargo test --test toyos-checks -- the_foreign_record_judgePANICpass isOkxhci_xecpwhole, as at6737a442cargo test --test toyos-checks -- the_xecp_judgexhci_xecp(&format!("{t14}{held}")).is_err()failsis_kernel_linewithout therecord_msarmcargo test --test toyos-checks -- serial_vocabularythe test capture carried no kernel output at allThe round before it, on sites that round did not touch, built each mutation with
cargo test --no-run(EXIT=0), and each run went red with EXIT=101:machine_rebootandlog_close_survivedback tokernel().must_say(REBOOTING).deadline_wedge_chainandusb_load_chainwith their call sites back to the base's.reachedgated onRUST_SKIPagain..expectagain.🤖 Generated with Claude Code