Skip to content
1 change: 1 addition & 0 deletions .claude/agents/implementer.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ guess. Then build, then test on root `CLAUDE.md`'s tiers before anyone reviews:
a metal row, `cargo test --test toyos-build -- --metal --metal-readback <dir> <row>`, from a
committed tree and with the `<dir>` the brief names, builds its images and writes
`<dir>/request.txt`; end your report with `T14 RUN REQUESTED: <dir>/request.txt`.
- A test you write holds to `reviewer.md`'s **Tests**.
- A result is the command's own exit code: `<cmd> > <file> 2>&1; echo EXIT=$?`. A grepped
`test result` line is not one, and a gate you did not run is a gate you do not claim.
- Long commands run in the background with output to a file under the scratchpad the brief names.
Expand Down
26 changes: 18 additions & 8 deletions .claude/agents/reviewer.md
Original file line number Diff line number Diff line change
Expand Up @@ -113,21 +113,31 @@ if it meets the bar above; otherwise it is a NOTE.
reader can check: that rule is a sentence in a prompt. What could be deleted, merged into what
exists, or made smaller? An abstraction with one caller, a parameter with one value, dead code,
code kept "just in case" or because nobody knows whether it is needed. Size is never bought with
a weaker check: a test is cut only when it tests nothing, when this prompt takes its rule, or
as **Guest tests** says. A compromise the branch found is removed or recorded in `issues/` with
an owner, evidence and an exit condition.
- **Tests.** The refusals and the boundary, not the happy path.
a weaker check: a test is cut only when it tests nothing or is a measurement, when this prompt
takes its rule, or as **Guest tests** says. A compromise the branch found is removed or
recorded in `issues/` with an owner, evidence and an exit condition.
- **Tests.** The refusals and the boundary, not the happy path. A test is hermetic, deterministic
and makes one claim, in setup, act and assert under a name that says the claim, and it reaches
no internet. However loaded the host, no guest test goes red: a guest test's only clock is a
hang ceiling, and timing is valid only on metal. A timing row on the T14 is a test, and it goes
red past its bound. A measurement, a number held to no bound — throughput, latency, a
comparison against Ubuntu — is not a test: it is posted on the pull request as evidence and
never becomes a suite row. Another OS's or a reference implementation's output, recorded or
live, is an oracle only when it is committed with its provenance and read hermetically, and a
timing held to another's only when it was read on the same machine. A policy another OS chose is
never an oracle for what ToyOS's own setting must be, and its copy of a fact a primary source
states is never an oracle. A test or row the diff adds or changes that breaks this is a BLOCKER.
- **Edges.** Untrusted input never panics the kernel; it is refused. Check-then-act races. A lock
held across a user copy or a device wait. Arithmetic on a value the caller chooses. A short
read, an exit status nobody reads. An `at_most(<int>::MAX)` or `index(usize::MAX)` on an
`Untrusted` is an unwrap wearing a check's name.
- **Guest tests.** A behaviour is tested on root `CLAUDE.md`'s cheapest tier that reaches it. A new
guest test, or one whose behaviour changes, whose pull request body does not say why a type, a
host test and a metal row cannot reach its behaviour is a BLOCKER, and so is one whose reason a
cheaper tier answers. A guest test is cut only where a cheaper tier already holds its behaviour,
named in the pull request body; where a stage of a track names it, in the same diff, with the
behaviour it guarded and an exit a build or test can fail; or as root `CLAUDE.md` deletes a red
or flaky test. Any other cut is a BLOCKER.
cheaper tier answers. A guest test is cut only where it is a measurement (**Tests**); where a
cheaper tier already holds its behaviour, named in the pull request body; where a stage of a
track names it, in the same diff, with the behaviour it guarded and an exit a build or test can
fail; or as root `CLAUDE.md` deletes a red or flaky test. Any other cut is a BLOCKER.
- **Waits.** A flat wait, or defensive code that hides a failure instead of failing fast (root
`CLAUDE.md`, "Fail fast"), is a BLOCKER, in code and in tests.
- **Actuators.** A kernel static of any kind, atomic or `Lock`-wrapped, that an `actuator::` guard's
Expand Down
20 changes: 20 additions & 0 deletions issues/ci-runs-the-whole-guest-suite.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
---
status: owner
kind: question
opened: 2026-10-10
---

# CI runs the whole guest suite

The owner's ruling: guest tests run on demand, and CI's small tier holds only the tests that must
break when something important breaks. `guest.yml` runs `cargo run -- --ci guest` (`src/ci.rs`,
`guest`), which is every registration in `tests/toyos.rs`, on every ready pull request, in the
merge queue (`ci.yml`) and nightly (`nightly.yml`); no tier is declared, so no review can keep a
new guest test out of it.

The question: which tests belong in the tier. Once the owner names them, the orchestrator
dispatches the reshape.

**Exit condition**: `--ci guest` runs a declared list in `tests/toyos.rs` and nothing else, the
rest of the suite runs on demand, and root `CLAUDE.md`'s "The guest suite is their `guest /
suite` check" and `reviewer.md`'s **Guest tests** say so in the same diff.
43 changes: 43 additions & 0 deletions issues/guest-tests-a-loaded-host-can-turn-red.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
---
status: open
kind: tooling
opened: 2026-10-10
---

# Guest tests a loaded host can turn red

The owner's ruling: however loaded the host, no guest test goes red, and timing is valid only on
metal (`reviewer.md`, **Tests**). Each test below holds its verdict to a fixed wall-clock bound the
harness does not scale, inside a guest whose vCPUs a loaded host deschedules. Found by reading
each one's clock; none of these bounds has been seen red under load, so each is a mechanism and a
measurement owed. The one observed red of this shape, `virtio_sound_counts`, is already deleted.

- `usbd_drives_the_spare` (`usbd_spare.rs`, `CLAIM_RETURN` 2 s and the 2 s halt-or-reset assert):
a killed usbd's claim back, and the controller halted or reset, each within 2 s.
- `kill_ends_every_wait` (`kill_ends_every_wait.rs`, `HELD` 1 s): a kill that takes more than 1 s
of starved wall time to land reads as "the child outlived" it. A timing claim.
- `sched_stress` (`sched_stress.rs`): the post-wake vruntime lag held to ±50 ms after a 10 ms
sleep, where vCPU time the host takes is charged as the thread's runtime. Its connect-storm pace
is `issues/timing-verdicts-ruled-off-qemu-have-no-metal-arm.md`'s.
- `abuse_thread_table` (`abuse_thread_table.rs`, `RUN_BOUND` 10 s): each thread runs within 10 s.
- `acpi_mediated_access` (`acpi_mediated.rs`, `RELEASED` 5 s): a dead holder's claim back within
5 s.
- `netstack_socket_churn` (`netstack_socket_churn.rs`, `LET_GO` 20 s), `netstack_streams` and
`netstack_streams_e1000e` (`netstack_streams.rs`, `WOKEN` 60 s, and the harness's 30 s
`ANSWERED` in `tests/toyos.rs`).

The harness's liveness ceiling (`tests/common/qemu.rs`, `host_scale`, `budget_smp`) is scaled by
the fastest boot the run has seen, so load that arrives after it is not in it.
`issues/a-netcase-boot-under-host-load-said-nothing-past-the-firmwares-screen-clears.md` records
`netstack_socket_churn` and `netstack_streams` each red at boot, before any bound above ran, at
one-minute load averages of 82.78 and 69.67 on 14 cores as their suites began; the first had its
ceilings priced at 1.00x. The stop's wall-clock budget is owned by
`issues/timing-verdicts-ruled-off-qemu-have-no-metal-arm.md` and
`issues/a-woken-klogd-can-wait-seconds-on-an-idle-cpu-under-hvf.md`.

Owner: the orchestrator, which dispatches the reshape.

**Exit condition**: each test named above waits on its event under the harness's scaled hang
ceiling, and a timing claim among them (`kill_ends_every_wait`'s `HELD`) is judged by a `METAL`
row; and the liveness ceiling is priced on the host's speed while each test runs, not on the
fastest boot the run has seen.
30 changes: 30 additions & 0 deletions issues/libc-host-tests-take-the-host-c-library-as-their-oracle.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
---
status: open
kind: defect
opened: 2026-10-10
---

# libc host tests take the host C library as their oracle

`reviewer.md`'s **Tests**: another OS's output, recorded or live, is an oracle only when it is
committed with its provenance and read hermetically. These `tests/libc-arch` tests call the
host's C library at run time and hold libc's answer to it, so the oracle is whichever C library
the host has, and the verdict differs between a Linux host and a macOS host:

- `strtonum_differential.rs`: `strtod`, `strtof`, `strtol`, `strtoul` and their `errno`.
- `internet_addresses.rs`: `inet_pton`, `inet_addr`, `inet_ntop`, `htonl`, `htons` and
`getsockname`, with `darwin_reads` for where macOS parts from Linux.
- `socket_options.rs`: `setsockopt` and `getsockopt` on real host sockets, with `darwin` for where
macOS parts from Linux.
- `fparts_differential.rs`: `modf` and `logb`.
- `text_differential.rs`: `strnlen` (its `strsignal` half is held to a committed glibc table and
conforms).

`long_double.rs` is not one: its oracle is compiler-builtins' `__extenddftf2`, pinned by the
lockfile.

Owner: the orchestrator, which dispatches the reshape.

**Exit condition**: each test above holds libc to a committed table recorded from a named C
library with its provenance, or to the specification's text, and calls no host C library function
as its oracle; the `darwin` exception tables go with it.
43 changes: 43 additions & 0 deletions issues/suite-rows-that-are-measurements-or-make-several-claims.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
---
status: open
kind: defect
opened: 2026-10-10
---

# Suite rows that are measurements or make several claims

`reviewer.md`'s **Tests**: a test makes one claim, under a name that says it, and a measurement,
a number held to no bound, never becomes a suite row. The owner ruled the one-claim reading a
BLOCKER for a new or changed test; these stand in the tree today.

Measurements as `METAL` rows in `tests/toyos.rs`:

- `syscall_cost` and `spawn_cost`: each verdict is that its numbers were printed.
- `trace_record_cost`: the cost is "read, not held", while `trace_flood.rs` also asserts the
ring's accounting, which the row's name does not say.

`METAL` rows that make several claims:

- `counters` (`counters_on_metal`): records fresh and named by APIC id, SMI counts moved only by
the kernel's commands, MPERF against the stamp, an idle second with no log line, the HWP request
and a turbostat frequency floor. The HWP request's oracle is
`issues/t14-rows-hold-toyos-to-linuxs-choice-or-copy.md`'s.
- `acpi_tables_loaded` (`acpi_tables_on_metal`): the definition-block count, the MTRRs compared
across CPUs, nothing refused, and the AML reads. The count's oracle is the same issue's.
- `timer_calibration`: both clocks calibrated, and the TSC within 1% of CPUID.

Guest binaries in `tests/toyos-rust-tests/src/bin/` that make several claims:

- `allocator_stress.rs`: twelve checks.
- `std_process.rs`: eight std process behaviours.
- `std_sync.rs`: mutex, condvar, park and rwlock.
- `sched_stress.rs`: io_uring acceptor isolation, the post-wake vruntime lag, and a connect storm.
- `toybox_file_tools.rs`: `cp`, `mv` and `hexdump`.
- `std_fs.rs`: listing, a self-read, NotFound, and file types.

Owner: the orchestrator, which dispatches the reshape.

**Exit condition**: `syscall_cost` and `spawn_cost` are each held to the T14's record or deleted
with their binaries; `trace_record_cost` is named for the ring-accounting claim and its cost
either held to the record or not printed; and every row and binary above makes one claim under a
name that says it.
24 changes: 24 additions & 0 deletions issues/t14-rows-hold-toyos-to-linuxs-choice-or-copy.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
---
status: open
kind: defect
opened: 2026-10-10
---

# T14 rows hold ToyOS to Linux's choice or copy

`reviewer.md`'s **Tests**: a policy another OS chose is never an oracle for what ToyOS's own
setting must be, and its copy of a fact a primary source states is never an oracle. Two metal
rows in `tests/toyos.rs` use one:

- `counters_on_metal` holds every CPU's read-back `IA32_HWP_REQUEST` equal to Linux's
(`tests/t14-linux/hwp-request.txt`). That value is the request Linux's governor chose, a policy,
not a correctness truth.
- `acpi_tables_on_metal` holds the number of definition blocks the server loaded to
`T14_DEFINITION_BLOCKS`, the 14 Linux reports loading. The firmware's XSDT and FADT, which the
kernel already reads, are the primary source of that count.

Owner: the orchestrator, which dispatches the reshape.

**Exit condition**: `counters_on_metal` holds the request to the value the kernel declares, with
no reference to `hwp-request.txt`; `acpi_tables_on_metal` holds the count to the definition blocks
the same boot's firmware tables list, and `T14_DEFINITION_BLOCKS` is deleted.
Loading