Skip to content

Worktrees and the primary's sync are git commands in the role prompts, a sysroot placement sweeps its store, and the prompts take the owner's decisions - #678

Merged
Japabu merged 6 commits into
mainfrom
wt/toyos-nomachinery
Oct 1, 2026
Merged

Japabu merged 6 commits into
mainfrom
wt/toyos-nomachinery

Conversation

@Japabu

@Japabu Japabu commented Oct 1, 2026 •

Copy link
Copy Markdown
Collaborator

The worktree and landing machinery becomes git commands in the role prompts, and the prompts take the owner's decisions of 2026-10-01. The authority for every prompt rule below is those decisions, numbered as the owner ruled them.

What goes, and what replaces it

cargo run -- --worktree add|list|remove and cargo run -- --sync go: src/worktree.rs (838 lines, 299 of them tests), src/sync.rs (263, 131 tests), the WORKTREE and SYNC flags, their dispatch in src/main.rs, and the sysroot test of the deleted worktree::remove. The recipe below replaces them. What only refused, reported or measured goes with nothing in its place:

  • the 25 GiB free-disk refusal;
  • --worktree list, with its sizes and its "landed, reclaimable" line;
  • the landed, untouched, behind and diverged branch refusals;
  • --sync's dirty-primary skip and its stranded-commits message.

Each refusal that guarded a real mistake has a replacement:

  • Uncommitted work is caught by the clean check. On a fixture it printed M rust for each of: a tracked edit, an untracked file and a new commit in the fork checkout, and an edit and an untracked file in its library/backtrace.
  • A fork commit on no ref is the implementer's instruction to push every fork commit before it reports.
  • An unpushed branch is refused by git branch -d.
  • Resuming a landed, behind or diverged branch is no longer refused up front. git worktree add -b refuses a name whose branch exists, and the remote refuses a push that does not fast-forward.
  • A main git cannot fast-forward is refused by --ff-only.

--worktree remove swept the sysroot, freestanding, compiler and LLVM stores. The sweep moves into the build: sysroot and freestanding placements now go through keystore::made, as compiler placements and llvm::resolve's already did, and such a placement removes what no registered worktree records and nobody holds. Only the build reads the records and takes the keys' locks, so a recipe step would have needed a command of the build system's own. Accepted by name: a removed worktree's keys now stay on disk until the next placement of their kind, and an LLVM placed through llvm::held sweeps nothing. A store grows only at a placement.

The recipe

.claude/agents/implementer.md makes, resumes and checks a worktree; .claude/agents/orchestrator.md syncs the primary and removes a landed branch's worktree (decision 6). All of it runs in the primary checkout:

git fetch origin && git worktree add -b wt/<name> ../<name> origin/main      # make
git worktree add ../<name> wt/<name>                                         # resume a branch
git status --porcelain --ignore-submodules=none                              # in the worktree: prints nothing, and every fork commit is pushed
git pull --ff-only origin main                                               # after a landing
rm -rf ../<name> && git worktree prune && git -C rust worktree prune && git -C rust/library/backtrace worktree prune && git branch -d wt/<name>

Root CLAUDE.md keeps only the invariant: a worktree is never made with git clone, and git submodule never runs in one. Those are the only sources of the three failures: a 913 MiB fetch of the fork's history, a second toolchain, and the rustup toyos link taken from every other checkout. A clone is its own primary, so ensure_submodules clones the fork, Bootstrap::Full builds a toolchain and the toolchain is linked to rustup; git submodule in a linked worktree writes core.worktree into the fork's shared config. A linked worktree's build runs none of the three: toolchain::owner reads ownership off git rev-parse --git-common-dir, main.rs runs ensure_submodules only for Owner::Us, and toolchain::ensure returns before the bootstrap and the link for Owner::Elsewhere.

Why rm -rf and three prunes rather than git worktree remove. Measured on a scratch fixture of the real shape: a primary whose rust carries library/backtrace, a linked worktree, and its fork checkout made as fork_checkout makes it.

  • Removing the outer worktree, or the fork checkout, is refused: working trees containing submodules cannot be moved or removed, exit 128.
  • Once the backtrace worktree is gone, the fork checkout is refused as contains modified or untracked files, because its library/backtrace is now missing.
  • A forced removal of a path 1,366 bytes deep exits 255 (File name too long) after unregistering the worktree, and leaves it on disk. rm -rf of what is left exits 0.

The proof run

The recipe ran end to end from the primary, with a second worktree toyos-recipeproof; snapshots were taken before, after the add, after the build and after the removal.

  • git fetch origin: EXIT=0. git worktree add -b wt/toyos-recipeproof ../toyos-recipeproof origin/main: EXIT=0.
  • cargo run -- --build-only in it: EXIT=0, 76 s. Its log says Making …/rust a fork checkout at aca5f527f (a git worktree of the primary's), and has no Initializing submodule, no Building full toolchain, no Building compiler and no Building sysroot.
  • Fetched: nothing. The fork repository's count-objects -v was identical in all four snapshots: in-pack 3,518,737, 3 packs, size-pack 1,100,435 KiB.
  • Built: no toolchain. The rust/build/*/stage2 list was identical (3 entries), and so were the store keys: 7 sysroots, 3 freestanding, 2 compilers, 2 LLVMs.
  • The rustup link did not move. ~/.rustup/toolchains/toyos pointed at the primary's stage2 in all four snapshots.
  • The status check printed 0 lines; the removal chain gave EXIT=0, and git branch -d EXIT=0.
  • After removal, git worktree list --porcelain of the repository, the primary's rust/ and its library/backtrace had 86 entries, as before (89 while built); .git/worktrees, .git/modules/rust/worktrees and the store keys were as before.

Every key the proof run's build used was already in the stores, so it placed nothing: the per-placement sweep stands on the unit test and its mutation below, not on this run.

The resume line, on a scratch repository: a worktree made with -b, a commit in it, removed with rm -rf and git worktree prune (EXIT=0, one worktree left registered), then git worktree add ../demo wt/demo: EXIT=0, HEAD at the branch's commit on wt/demo. Making it again with -b under the same name: fatal: a branch named 'wt/demo' already exists, EXIT=255.

The sync line, on a scratch clone whose rust/ read M rust as the primary's does: git pull --ff-only origin main moved main from a97ff80df to the remote's tip, EXIT=0. With a local commit on a current main it printed "Already up to date.", EXIT=0; on a main behind the remote, fatal: Not possible to fast-forward, aborting., EXIT=128, main unmoved.

A sysroot is held while anything compiles against it

Placements now sweep any key nobody holds, so a sysroot's directory must never be read without its guard. TestBuild::begin and the harness's c_sysroot dropped the Sysroot, and its guard with it, then kept compiling against its directory: once a build in the same worktree recorded a new key, the next placement in any worktree could remove the sysroot a running suite compiled with. The race is closed by construction, shown by reading:

  • Sysroot's directory is a private field. Sysroot::dir only lends it, as &Path.
  • Every toolchain::ensure result is moved into a GuestEnv (shipped_parts, build_test_parts, TestBuild::begin) or into the harness's static SYSROOT: OnceLock<Sysroot>, which is never dropped.
  • Every reader of the directory borrows it for one call, from a GuestEnv its caller holds (cargo_build, assert_kernel_is_softfloat, build_and_assemble, and build_programs, whose C environment is used within the call) or from that static.
  • TestBuild owns its GuestEnv across every build→read pair. The kernel build borrows the env from a std::thread::scope thread, which is joined before the env can drop, where it used to clone it into a detached thread.
  • A keyed_idle cannot take a key while any of these hold its shared lock.

One git runner, one removal

  • crate::git was a second runner beside sysroot::git_try. It goes; its four callers read through sysroot::git_out, and release::manifest no longer returns a Result nothing in it can fail.
  • sysroot::remove, sysroot::remove_tree and keystore::remove were three removals of a build product. keystore::remove is the one left: a file or a directory, read-only or not, outlasting a writer that adds a file while it runs, and a name already gone counts as removed. That last is what a second sweeper of one store meets after the first has taken a key's names; before, the second build panicked on the stat. a_switch_that_cannot_remove_records_nothing_and_the_next_one_removes now makes its removal fail with a read-only parent, because a removal gives back the write permission of what it removes.

The prompts

Root CLAUDE.md, orchestrator.md, implementer.md and reviewer.md start from a read-only reviewer's proposals written at round 1's head, and the decisions override them where they differ.

Root CLAUDE.md holds what every agent needs, an agent spawned without a type included. That means every rule whose breach is unrecoverable:

  • personal data stays out of every network request, and any User-Agent is toyos-build (https://github.com/ToyOSOrg/ToyOS);
  • no history rewrite or force-push;
  • main is never touched;
  • no git clone or git submodule for a worktree;
  • the T14 is the orchestrator's alone: no other agent runs --metal without --metal-readback, which builds a metal row's images and touches no machine (src/testargs.rs);
  • no agent kills another agent's process.

Root's other changes:

  • A rule a reader can check lives in a prompt or at its site, and code enforces only what reading cannot see. A gate, lock, check or test is added only for what reading cannot see, and nothing a type refuses is tested.
  • The testing tiers: a type that makes the bug unrepresentable, a host test, a T14 row, then a guest test.
  • Agents run their own guest suites, side by side. A red seen only under load is a defect recorded with the host's load, never a flake to delete (decision 11).
  • "Apps are portable" moves up from userland/CLAUDE.md as a principle. A ToyOS-only program is one whose job exists only on ToyOS, and "system service" stays the panic track's term as Rules and records: the ABI and kernel rulings, the no-panic track, the owner's 2026-09-30 rulings, CPU microcode, the crate track, the LLVM-bytes and TCO-overflow defects #673 landed it (decision 5).
  • "Stale or false prose is deleted, never corrected" binds source comments and docs; pull request bodies, issues and prompts are records kept true (decision 4).
  • "Tooling comes first" is dropped (decision 7).
  • Role rules moved to their role files: models, briefs, worktree removal and landing to orchestrator.md; waiting, worktree making and the PR mechanics to implementer.md.
  • Dropped as rationale no agent needs to follow its rule: the merge-queue mechanics, boot and build speeds, why a long transcript rots, why -m is dangerous, "five artifacts from one wrong model still agree", why no upstream pull request is sent (the rule stays), and the DOOM1.WAD sale line, which NOTICE carries.

orchestrator.md:

  • the owner's assistant: it informs, dispatches and lands, and hands agents pointers instead of reading code, diffs or reviews;
  • it edits a pull request's description and comments and nothing else, because a source comment is code (decision 9);
  • every agent gets an explicit type and model, and an agent spawned without a type is general-purpose and carries none of a role file's rules;
  • the frontmatter tools: line is gone, so a session started as the orchestrator keeps every tool;
  • branches stay drafts through their rounds; on LAND it marks one ready and arms it, or batches several (decision 1). That closes issues/build/who-arms-auto-merge-has-two-answers.md;
  • LAND AFTER NAMED CHANGES is one fix round, then landing with no re-review (decision 3);
  • it intervenes only when an implementer and a reviewer disagree;
  • a T14 RUN REQUESTED: line names <dir>/request.txt, the request file a staging run writes, where implementer.md had it name an image and orchestrator.md a request file;
  • a metal mutation loop is a measurement, not an edit, so it does not break the rule that it edits only pull request descriptions and comments;
  • machinery is the last resort: a ruling first asks whether a prompt sentence does the job, and a gate a review finds a way around becomes a sentence and goes.

implementer.md:

  • it makes its worktree and checks it clean before it reports (decision 6);
  • it runs host tests and every guest test its change reaches itself, never a cargo run that launches QEMU, and --metal only beside --metal-readback: a metal row's images are staged with cargo test --test toyos-build -- --metal --metal-readback <dir> <row>, and the report ends T14 RUN REQUESTED: <dir>/request.txt;
  • its pull request stays a draft;
  • the body states what a new gate, check, lock or test sees that reading cannot;
  • every NOTE is fixed.

reviewer.md:

  • NOT READY FOR REVIEW goes, and missing evidence is a BLOCKER (decision 2): --ci host, every guest test the change reaches, since no guest boots before main, and the hardware's reading where the change targets hardware;
  • a wrong line number, count, date or citation is never a send-back and never corrected in a source comment or a doc, and a record is kept true (decision 4);
  • the verdict follows the open findings;
  • a mutation is named only where a defect would otherwise land unseen;
  • a src/clippy.rs shape is read, never proven by a planted mutation (decision 10);
  • it checks an issues/ change against issues/README.md, as that file already claimed;
  • every runs-on: names a GitHub-hosted runner, moved from src/CLAUDE.md;
  • exempt is for a program whose job exists only on ToyOS.

Deleted: .claude/agents/upstreamer.md and its .gitignore line (decision 8). The private memory the round-1 review named is the orchestrator's own housekeeping (decision 12).

The subdirectory files take the findings the owner listed, and none grows:

  • kernel/CLAUDE.md names AArch64's transition files, labels the direction flag x86, and drops the spinlock count.
  • userland/CLAUDE.md loses the portability rule to root, its POSIX sentence to root, and the filepicker note: c3c42e137 fixed that violation and closed its issue.
  • tests/CLAUDE.md: the sleep caveat stops saying re-run, the T14's CI-container clause goes, and the TCG caveats say which guests are TCG (Arch::accel); the guest-lane line repeated src/CLAUDE.md.
  • src/CLAUDE.md drops the boot modes, which their site documents; "a flashable artifact is built from a committed tree" moves to implementer.md. The lock lines become a pointer to src/buildlock.rs and the track, and the std type-check is made portable.
  • issues/README.md drops its history and the lines that were stale or contradicted root.
  • .github/pull_request_template.md now agrees with implementer.md: the body is the record and the reviewer's evidence, and it says what is unsure.
  • .cargo/config.toml.example clones ToyOSOrg/cpal at toyos-0.18.0, the branch the tree consumes.

Every citation of a moved or deleted line or function follows it: the fork-checkout, loaded-suite, C++-runtime, app-portability and hosted-rustc issues, and a src/hostws.rs comment. The Windows issue keeps its judge. It loses its error list, which no dated run printed, the paragraph after it, which placed a #[cfg(unix)] at src/ci.rs:489 that neither main nor this tree has, and the clause of its last sentence that counted that list's errors.

Every metal command names the harness's test target: cargo test --test toyos-build -- --metal … in root, orchestrator.md, implementer.md and the process-memory track's copy_cost A/B. A bare cargo test -- --metal passes the flag to each test binary of the root package, and src/lib.rs's unit tests refuse it before the harness starts; Gates records both spellings.

One track holds the machinery cut. This branch's track restated the assigned issues/build/the-tooling-is-a-review-prompt-and-three-workflows.md. Its lock stage and its gate stage join that track as two bullets, each with its exit; its line counts, its first stage and its empty fourth stage go, and so does the file.

The example of a gate replaced by a prompt. #669's workflow gate read the workflows as text, and a review found a quoted cache key and a comment on the jobs: line past it (#669 (comment)). It became a YAML parser with a closed allow-list, and the next review found a uses: path that GitHub splits and the gate did not, and a U+2028 line end that GitHub breaks on and yaml-rust2 does not (#669 (comment)). At c282a7669, #669 carries those rules as sentences in reviewer.md, and no parser.

Kept in the build system

  • toolchain::owner and rust_dir: a linked worktree's build reads the primary's compiler through them.
  • sysroot::fork_checkout, unchanged: git worktree add leaves rust/ an empty stub, and std must compile in a checkout at <worktree>/rust, because library/std names ../../../toyos-abi.
  • main.rs's Owner::Us guard on ensure_submodules, which makes a plain git worktree add safe.

Gates

At this head, 7da54b120, run one after another; their logs, and the host's load before and after each, are in #678 (comment).

  • cargo run -- --ci host: EXIT=0, Host: 59 step(s), all green. The build system's cargo test --lib gave 363 passed, 0 failed, 7 ignored.
  • The T14's command in both spellings, for the row metal_sim_scanout_wc, with --metal-readback, which builds images and touches no machine:
    • cargo test -- --metal --metal-readback <dir> metal_sim_scanout_wc: EXIT=101. src/lib.rs's unit tests, the first test binary cargo ran, printed error: Unrecognized option: 'metal', and nothing was staged.
    • cargo test --test toyos-build -- --metal --metal-readback <dir> metal_sim_scanout_wc: EXIT=2, [metal] staged 1 image(s); <dir>/request.txt lists them. The machine was not touched, so this run establishes nothing about it. It reached c_sysroot: [metal] 1 registration(s) and 0 shared member(s) over 1 boot(s) prints only after build_shared_bins returns.
  • git diff --shortstat origin/main...HEAD: 43 files changed, 375 insertions(+), 1711 deletions(-). Its Rust (-- '*.rs'): 15 files, +116 −1249, none of it this round's.

At 3c2cd6408, whose tree differs from this head only in the five Markdown files this round edits (git diff --stat 3c2cd6408..HEAD). The orchestrator's run is in #678 (comment); the others ran one after another, and their logs and the host's load are in #678 (comment).

  • cargo run -- --build-only: EXIT=0, Build finished., target/bootable.img. Every key was already in the stores, so it placed and swept nothing.
  • cargo test --test toyos-build, the whole guest suite: EXIT=0, test result: ok. 21 passed, 21 total (126.9s); the load average was 15.22 on 14 cores as it ended. It reaches TestBuild::begin: virt_readonly_copyout and virt_fatal_halts_the_others_first build their binary through build_toyos_bin. It does not reach c_sysroot, which only build_shared_bins calls, under --metal or --debug.
  • The orchestrator's cargo test --test toyos-build -- --metal --list: EXIT=0, [toyos] Compiling 133 C tests, and attempting 24 declared ones..., [metal] 48 registration(s) and 213 shared member(s) over 27 boot(s). It reached c_sysroot and touched no machine.
  • Negative control for the sysroot sweep: a_sysroot_is_whole_or_it_is_made_again places a sysroot beside an orphan and asserts the orphan is gone. The mutation reverts the sysroot placement in held alone to buildlock::keyed_made; the freestanding placement in build() keeps keystore::made, which no test places. The posted patch (Worktrees and the primary's sync are git commands in the role prompts, a sysroot placement sweeps its store, and the prompts take the owner's decisions #678 (comment)), applied as a checked patch: the test ran green on the clean tree, EXIT=0; the mutated tree built, EXIT=0; the test ran red under it, EXIT=101, placing a sysroot left one no worktree names; the restore left git status --porcelain empty.

Instruction files, in bytes (git cat-file -s), origin/main → round 1's head 5aaec89ce → this head:

file main round 1 now
CLAUDE.md 16,076 15,745 14,688
.claude/agents/orchestrator.md 5,122 4,218 5,424
.claude/agents/implementer.md 5,289 5,453 5,313
.claude/agents/reviewer.md 10,586 10,731 9,332
.claude/agents/upstreamer.md 3,130 3,130 deleted
src/CLAUDE.md 5,765 6,361 2,025
kernel/CLAUDE.md 3,897 3,897 3,894
userland/CLAUDE.md 1,629 1,629 1,053
tests/CLAUDE.md 4,290 4,290 3,976
issues/README.md 8,148 8,148 5,997

Closed issues

  • sync-from-a-worktree-never-moves-main-because-the-primary-reads-dirty: the sync line moved a scratch main with M rust, and the dirty check is gone.
  • worktree-remove-leaves-wt-branch-behind-so-the-name-is-refused-later: the removal ends in git branch -d.
  • who-arms-auto-merge-has-two-answers: decision 1 names one owner, the orchestrator, and every file now says so.

No slug of the three is cited anywhere (git grep).

What I am unsure of

  • Root now lets any agent run --metal beside --metal-readback, so that an implementer can stage a metal row's images, where round 3's brief barred --metal outright. Without it, the orchestrator builds every metal image itself.
  • The clean check is a reading, not a refusal: rm -rf deletes whatever the reader let through, and a fork commit pinned by a pushed branch but on no fork ref is protected only by the instruction.
  • A Finder .DS_Store written during rm -rf makes it exit non-zero, and running it again finishes. The recipe does not say so.
  • src/ci.rs's workflows_run_against_main_on_hosted_runners still holds the runs-on: rule that reviewer.md now carries, until the track's gate bullet judges it.
  • I kept "demand paging" in root's Kernel line, which the proposal dropped. The kernel demand-pages ELF segments, and issues/hardware/anonymous-mmap-is-not-demand-paged.md cites the line and records where it is not true.
  • Host cache: read by content, written by main's cold nightly alone, sealed and bounded, with its workflow rules in the review prompt #669 conflicts with this branch, and this branch lands first. Host cache: read by content, written by main's cold nightly alone, sealed and bounded, with its workflow rules in the review prompt #669's src/cicache.rs calls crate::sync::git, which is now crate::sysroot::git_out. Its reviewer.md hunks meet the rewritten file, and its two Tests sentences restate root's "code enforces only what reading cannot see" and "nothing a type refuses is tested", so it deletes its copy. Its workflow-gates issue meets the track's gate bullet.
  • Not in this pull request: .claude/settings.json's "agent": "orchestrator". .gitignore ignores .claude/*, and the primary holds the owner's own untracked .claude/settings.json. On a scratch repository, the next git pull --ff-only origin main after a commit tracking that path exited 0 and silently replaced the ignored local file, which would erase the owner's permission list. The owner adds the line to the local file, or first moves its permissions into .claude/settings.local.json.

🤖 Generated with Claude Code

https://claude.ai/code/session_016t9wjdQkB8SH7bmfUoiy6L

…ts take the owner's rulings

`--worktree add|list|remove` and `--sync` go, with `src/worktree.rs` (838
lines), `src/sync.rs` (263), their flags, dispatch and tests. What a build
needs stays in the build: `toolchain::owner` sends a linked worktree's
compiler reads to the primary and never runs `ensure_submodules`, a bootstrap
or the rustup link there, and `sysroot::fork_checkout` makes its `rust/` a
git worktree of the primary's fork repository on first build. Those two are
why a plain `git worktree add` is safe: the clone of the fork's history, the
second toolchain and the stolen rustup link come only from a `git clone` or a
`git submodule` in a linked worktree, which root `CLAUDE.md` now forbids by
name.

The recipe, run in the primary checkout:

  make:    git fetch origin && git worktree add -b wt/<name> ../<name> origin/main
  resume:  git worktree add ../<name> wt/<name>
  remove:  git -C ../<name> status --porcelain --ignore-submodules=none   (prints nothing)
           rm -rf ../<name> && git worktree prune && git -C rust worktree prune &&
           git -C rust/library/backtrace worktree prune && git branch -d wt/<name>
  sync:    git pull --ff-only origin main

`rm -rf` and three prunes rather than `git worktree remove`: a worktree's
fork checkout and its `library/backtrace` are worktrees of the primary's, git
refuses to remove a worktree holding a populated submodule unless forced, and
a forced removal of a path deeper than PATH_MAX exits 255 after unregistering
it, leaving the directory (measured on a fixture; `rm -rf` of the remainder
exits 0). The status check is the guard on uncommitted work; `git branch -d`
refuses a branch that is not pushed.

The sweep `--worktree remove` ran moves into the build: sysroot and
freestanding placements go through `keystore::made`, as compiler and LLVM
placements already did, so every placement removes the products no
registered worktree records and nobody holds. A recipe step could not do it
without a command of the build system's own, because only the build reads
the records and takes the keys' locks. `a_sysroot_is_whole_or_it_is_made_again`
now asserts a placement takes an orphan; reverting `held` to
`buildlock::keyed_made` reds it (exit 101).

`remove_tree` moves next to its callers in `src/sysroot.rs`, `sync::git` to
the crate root for `ci`, `sdkversion` and `release`.

The prompts take the owner's rulings: a rule a reader can check lives in a
prompt and code enforces only what reading cannot see; nothing a type refuses
is tested; tooling is code, added only for what a sentence cannot do; agents
run their own guest tests and the T14 alone is the orchestrator's; a
high-risk change names a negative control only where a defect would land
unseen and an oracle where one exists; agents get the model the owner names;
the orchestrator is the owner's assistant, edits only trivial text and lands
on LAND plus green CI. `CLAUDE.md` does not grow (16076 -> 15745 bytes).

Closes sync-from-a-worktree-never-moves-main-because-the-primary-reads-dirty
(the recipe moved a scratch clone's main with ` M rust`) and
worktree-remove-leaves-wt-branch-behind-so-the-name-is-refused-later (the
recipe deletes the branch, and the refusal is gone). Opens the track
issues/build/the-workflow-machinery-becomes-agent-instructions.md.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016t9wjdQkB8SH7bmfUoiy6L
@Japabu

Japabu commented Oct 1, 2026

Copy link
Copy Markdown
Collaborator Author

Negative control for the sweep moved into the build: the whole move reverted at held (sysroot placements back on buildlock::keyed_made, no sweep). Applied with git apply --check and git apply on 5aaec89ce; the tree built and cargo test -p toyos-build --lib -- sysroot::tests::a_sysroot_is_whole_or_it_is_made_again ran red, EXIT=101, at placing a sysroot left one no worktree names (src/sysroot.rs:1401); restored with git apply -R.

--- a/src/sysroot.rs
+++ b/src/sysroot.rs
@@ -512,8 +512,7 @@ fn unfinished(dir: &Path) -> Option<String> {
 /// The sysroot `key` names at `dir`, recorded as `root`'s, made by `make` if
 /// nobody has made it, and held in use for as long as the returned guard lives.
 fn held(root: &Path, key: &Key, dir: &Path, make: impl FnMut()) -> Guard {
-    let store = dir.parent().expect("a sysroot is a directory of its store");
-    keystore::made(root, Keyed::Sysroot, store, key, || unfinished(dir), make)
+    buildlock::keyed_made(root, Keyed::Sysroot, key, || unfinished(dir), make)
 }
 
 /// The sysroot this worktree's sources name, made if nobody has made it, and

@Japabu
Japabu marked this pull request as ready for review October 1, 2026 19:32
@Japabu

Japabu commented Oct 1, 2026

Copy link
Copy Markdown
Collaborator Author

CI: host pass at 5aaec89 (run 36915078375, 14m36s); it was still pending when this review began.
Growth: 27 files, +190 −1305 (git diff --shortstat origin/main...HEAD); src/*.rs +70 −1166, of which 454 deleted lines are test modules (worktree.rs 299 and sync.rs 131 counted here, sysroot.rs 24 per the body); *.md +118 −136.
Checked, nothing found: the make, resume, remove and sync lines against worktree.rs and sync.rs, less the refusals the body drops by name; the three failures stay behind toolchain::owner (src/main.rs:202, src/toolchain.rs:501-510) as before, and the proof run measured none of them; the sweep with several worktrees building, for every user that holds its guard (the record precedes the key lock, keyed_idle skips a held key); root CLAUDE.md 16,076 → 15,745 bytes; no --worktree or --sync left in the tree (git grep -F), and the bare word sync survives only as the step at .claude/agents/orchestrator.md:45, which CLAUDE.md:91 spells, and in the third REMOVE line.

BLOCKER

  • src/build.rs:2153, tests/common/compile.rs:25 — TestBuild::begin and c_sysroot drop the Sysroot, and its _using guard with it, then keep compiling against its dir (GuestEnv.toolchain, CSysroot.clang and .dir) — this branch sweeps at every sysroot placement and takes any key no worktree records and nobody holds, so once a second build in the same worktree records a new key (any change to what the key reads: toyos-abi, toyos, userland/libc, the fork), its placement or any other worktree's deletes the sysroot a running suite compiles with; before, only --worktree remove swept sysroots. Nothing hands out the dir without its guard (TestBuild and the OnceLock keep the Sysroot, or GuestEnv and CSysroot own it).
  • issues/build/the-workflow-machinery-becomes-agent-instructions.md:19-35 — stages 2 and 3 restate issues/build/the-tooling-is-a-review-prompt-and-three-workflows.md, an assigned track: its src/buildlock.rs deletion, and its "rules a prompt can read move into reviewer.md, and the gates that held them go" — two tracks own one cut; one holds it.

NOTE

  • src/keystore.rs:185-196 — after keyed_idle, sweep_by removes names it listed before taking the lock; a second sweeper of the same store hits a <key>.partial, .swept or .libcxx-* the first removed, and remove → writable (src/keystore.rs:227) panics on its stat — now that sysroot and freestanding placements sweep, two worktrees placing at once fail the later build; a name that is gone is removed.
  • src/lib.rs:56 — git is a sibling of sysroot::git_try (src/sysroot.rs:931): one runner, two error shapes; the move was where one of them goes.
  • src/sysroot.rs:910 — remove_tree now sits beside remove (src/sysroot.rs:757) and keystore::remove (src/keystore.rs:220): three removals of a build product, one of them retrying.
  • CLAUDE.md:83 — removal no longer reclaims a removed worktree's own compiler or LLVM (0.5–0.75 and 0.5–2.3 GiB per the body) until some worktree places one; the body lists it as unsure — record it or accept it by name.
  • CLAUDE.md:91 "judged by it", .claude/agents/reviewer.md:11 "The orchestrator judges." — give the orchestrator more than .claude/agents/orchestrator.md:39-40 now does: disagreements only.
  • .claude/agents/reviewer.md:15-18 — still stops NOT READY FOR REVIEW on CI that is not green, while orchestrator.md drops "a review only after green CI" and this review was spawned with host pending — one of the two says what the owner ruled.
  • CLAUDE.md:97 "It arms auto-merge" — contradicts .claude/agents/implementer.md:77 and .claude/agents/orchestrator.md:44, where the orchestrator arms on LAND and green CI; standing, beside lines this branch rewrote.
  • .claude/agents/implementer.md:27 "or any other cargo run" — bars the cargo run -- --clippy run .claude/agents/reviewer.md:83 asks to see in the body; standing, in the sentence this branch rewrote.
  • CLAUDE.md:73 — every agent now runs its own suite; issues/build/parallel-tests-red-under-other-suites.md records reds that appear only beside another worktree's suite, and CLAUDE.md:93 deletes a flaky test at once — with "one suite at a time" gone, nothing tells an agent such a red is the host.
  • Host cache: read by content, written by main's cold nightly alone, sealed and bounded, with its workflow rules in the review prompt #669 — git merge-tree --write-tree 5aaec89ce c282a7669: CONFLICT (content) in .claude/agents/reviewer.md, the Tests bullet; Host cache: read by content, written by main's cold nightly alone, sealed and bounded, with its workflow rules in the review prompt #669's new src/cicache.rs calls crate::sync::git, which this branch deletes, so whichever lands second is red in the queue until it calls crate::git; Host cache: read by content, written by main's cold nightly alone, sealed and bounded, with its workflow rules in the review prompt #669's two Tests sentences restate CLAUDE.md:18-20 and :33 here — the second to land deletes its copy.
  • Proof run — every key was already in the stores, so nothing was placed and the per-placement sweep stands on a_sysroot_is_whole_or_it_is_made_again alone; the resume line never ran.
  • Outside the tree — the orchestrator's memory primary-checkout-goes-stale.md and its MEMORY.md line still say cargo run -- --sync.

REMOVE

  • src/CLAUDE.md:31 — new rationale: src/CLAUDE.md grows 5,765 → 6,361 bytes (wc -c), and the story is in the commit message.
  • src/CLAUDE.md:21 "Every placement … at the next one." — rewritten instead of deleted, restates four module headers, and false for llvm::held (src/llvm.rs:225 places through buildlock::keyed_made and sweeps nothing); the title's "every store placement sweeps" with it.
  • src/CLAUDE.md:22, src/sysroot.rs:21-22 "nothing but the primary's own sync moves the primary's rust/" — the bare word cites --sync, which never moved rust/; git pull moves none either.
  • issues/build/the-build-system-does-not-compile-on-windows.md:9,25,47,68 — counts corrected (seven → five, fourth → third, three → two) under "Measured 2026-09-01", which printed seven.
  • issues/build/the-workflow-machinery-becomes-agent-instructions.md:12-13 and every wc -l count in it (will rot); :15-18, stage 1 (this branch, history once it lands); :36, stage 4 (no content, no exit).
  • PR body — "This does not duplicate Host cache: read by content, written by main's cold nightly alone, sealed and bounded, with its workflow rules in the review prompt #669's two Tests sentences" (CLAUDE.md:18-20 is Host cache: read by content, written by main's cold nightly alone, sealed and bounded, with its workflow rules in the review prompt #669's second, :33 its first); "the whole move reverted at held" (the patch leaves build()'s freestanding keystore::made in place).

SEND BACK

Japabu and others added 3 commits October 1, 2026 22:34
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016t9wjdQkB8SH7bmfUoiy6L
… one git runner, one removal

Round 1's first BLOCKER: `TestBuild::begin` and the harness's `c_sysroot`
dropped the `Sysroot`, and its `_using` guard with it, while they kept
compiling against its directory, and every placement now sweeps any key
nobody holds. `Sysroot`'s directory is private and lent only by
`Sysroot::dir`. `GuestEnv` owns the `Sysroot`, so `TestBuild`,
`shipped_parts` and `build_test_parts` hold it for as long as they build;
the kernel build borrows it from a scoped thread instead of a clone; the
harness's `OnceLock` keeps the `Sysroot` itself, held until the process
ends.

Two of round 1's NOTEs:
- `crate::git` was a second git runner beside `sysroot::git_try`. It goes,
  and its four callers read through `sysroot::git_out`; `release::manifest`
  stops returning a `Result` nothing in it can fail.
- `sysroot::remove`, `sysroot::remove_tree` and `keystore::remove` were three
  removals of a build product. `keystore::remove` is the one left: a file,
  or a directory read-only or not, outlasting a writer that adds a file while
  it runs, and a name already gone is removed. A second sweeper of one store
  meets exactly that once the first has taken a key's names, which panicked
  on the stat before. The switch test makes a removal fail with a read-only
  parent instead of a read-only child, since a removal now gives back the
  write permission of what it removes.

The bare-word "sync" clause in `src/sysroot.rs`'s header goes (REMOVE).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016t9wjdQkB8SH7bmfUoiy6L
…e decisions

Round 1's second BLOCKER: this branch's track restated
`issues/build/the-tooling-is-a-review-prompt-and-three-workflows.md`, an
assigned track. Its lock stage and its gate stage join that track as two of
its bullets, `src/keystore.rs` beside `src/buildlock.rs`, each with its exit;
its line counts, its first stage (this branch) and its empty fourth go, and
so does the file. Nothing cited it.

Root `CLAUDE.md`, `orchestrator.md`, `implementer.md` and `reviewer.md` are
the read-only reviewer's proposals with the owner's decisions of 2026-10-01
applied over them:
- branches stay drafts through their rounds; the orchestrator marks one
  ready and arms it on LAND, or batches several, which closes
  `issues/build/who-arms-auto-merge-has-two-answers.md`;
- NOT READY FOR REVIEW goes, and missing evidence is a BLOCKER;
- LAND AFTER NAMED CHANGES is one fix round and landing, with no re-review;
- "deleted, never corrected" binds source comments and docs; bodies, issues
  and prompts are records kept true;
- a ToyOS-only app is one whose job exists only on ToyOS, and "system
  service" stays the panic track's term;
- an implementer makes and resumes its worktree and checks it clean before
  it reports, the orchestrator removes it and syncs the primary, and root
  keeps only why a worktree is never a `git clone` and never runs
  `git submodule`;
- "tooling comes first" goes;
- `.claude/agents/upstreamer.md` goes, with its `.gitignore` line;
- the orchestrator edits a pull request's description and comments, nothing
  else;
- a `src/clippy.rs` shape is read, never proven by a planted mutation;
- guest suites run side by side, and a red seen only under load is a defect
  recorded with the host's load.
Root keeps every rule whose breach no role file could undo: personal data
and the User-Agent, history, `main`, `git clone` and `git submodule`, the
T14, and another agent's process. `orchestrator.md` loses its `tools:` line,
so the main session keeps every tool, and every agent gets a type as well
as a model.

The subdirectory files take the clear findings and shrink: the kernel's
caveats name AArch64's files, label the direction flag x86 and drop the
spinlock count; userland's portability rule moves to root, its POSIX line
and stale filepicker note go (`c3c42e137` fixed that violation); tests' sleep
caveat stops saying re-run, the T14's CI-container clause goes, and the TCG
caveats are true of the HVF and KVM hosts; `src/CLAUDE.md` drops the boot
modes, the locks it restated and both REMOVE lines, points at the lock header
and the track, makes the std type-check portable, and its hosted-runner rule
moves into `reviewer.md`'s Arrivals; `issues/README.md` drops its history
and its stale or contradicting lines; the PR template agrees with
`implementer.md`; the fork example clones `ToyOSOrg/cpal`. Citations of the
lines that moved follow them, and the Windows issue's corrected counts are
deleted (REMOVE).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016t9wjdQkB8SH7bmfUoiy6L
@Japabu
Japabu marked this pull request as draft October 1, 2026 20:57
@Japabu Japabu changed the title Worktrees and the primary's sync are git commands in CLAUDE.md, every store placement sweeps, and the prompts take the owner's rulings Worktrees and the primary's sync are git commands in the role prompts, a sysroot placement sweeps its store, and the prompts take the owner's decisions Oct 1, 2026
@Japabu

Japabu commented Oct 1, 2026

Copy link
Copy Markdown
Collaborator Author

Round 2 gate logs at f325be7df, kept here so the evidence does not live only in a scratch directory.

cargo run -- --ci host → EXIT=0. Every step's command line, every model control's header, and the verdict (the full log is 7,693 lines; the 36 test result: FAILED lines in it are all under === [ci] control headers, the model controls that must red):

=== [ci] the build system
[ci] the build system: cargo test --lib
=== [ci] the harness's own checks
[ci] the harness's own checks: cargo test --test toyos-checks
=== [ci] the host workspace
[ci] the host workspace: cargo test --workspace --exclude toyos-build
=== [ci] the licences of what ships
[ci] the licences of what ships: 6 exception(s) stand, and nothing else is refused
=== [ci] clippy and the bare targets
[ci] clippy and the bare targets: installed
=== [ci] clippy, warnings denied
[ci] clippy, warnings denied: clean
=== [ci] kernel-loom without loom
[ci] kernel-loom without loom: cargo test --manifest-path kernel-loom/Cargo.toml --no-default-features --test log_zeroed_init --test log_body_words
=== [ci] control `wake-fence-off`
[ci] control `wake-fence-off`: 1 verdict(s) reached
=== [ci] control `lock-acquire-off`
[ci] control `lock-acquire-off`: 1 verdict(s) reached
=== [ci] control `seqlock-writer-fence-off`
[ci] control `seqlock-writer-fence-off`: 1 verdict(s) reached
=== [ci] control `serial-try-lock-then-some`
[ci] control `serial-try-lock-then-some`: 2 verdict(s) reached
=== [ci] control `reap-raise-relaxed`
[ci] control `reap-raise-relaxed`: 1 verdict(s) reached
=== [ci] control `shootdown-serve-relaxed`
[ci] control `shootdown-serve-relaxed`: 2 verdict(s) reached
=== [ci] control `roster-commit-relaxed`
[ci] control `roster-commit-relaxed`: 1 verdict(s) reached
=== [ci] control `smp-ready-split`
[ci] control `smp-ready-split`: 1 verdict(s) reached
=== [ci] control `log-commit-release-off`
[ci] control `log-commit-release-off`: 2 verdict(s) reached
=== [ci] control `shard-publish-relaxed`
[ci] control `shard-publish-relaxed`: 1 verdict(s) reached
=== [ci] control `log-ring-publish-relaxed`
[ci] control `log-ring-publish-relaxed`: 3 verdict(s) reached
=== [ci] control `log-ring-tail-relaxed`
[ci] control `log-ring-tail-relaxed`: 3 verdict(s) reached
=== [ci] control `log-ring-loads-swapped`
[ci] control `log-ring-loads-swapped`: 1 verdict(s) reached
=== [ci] control `poll-fire-load-store`
[ci] control `poll-fire-load-store`: 2 verdict(s) reached
=== [ci] control `sleeplock-acquire-off`
[ci] control `sleeplock-acquire-off`: 2 verdict(s) reached
=== [ci] control `device-irq-lossy`
[ci] control `device-irq-lossy`: 1 verdict(s) reached
=== [ci] control `dump-report-relaxed`
[ci] control `dump-report-relaxed`: 1 verdict(s) reached
=== [ci] control `no-preempt-guard`
[ci] control `no-preempt-guard`: 1 verdict(s) reached
=== [ci] control `doorbell-kick-relaxed`
[ci] control `doorbell-kick-relaxed`: 1 verdict(s) reached
=== [ci] control `push-fence-relaxed`
[ci] control `push-fence-relaxed`: 1 verdict(s) reached
=== [ci] control `commit-ignores-notify`
[ci] control `commit-ignores-notify`: 2 verdict(s) reached
=== [ci] control `notify-flag-load-only`
[ci] control `notify-flag-load-only`: 1 verdict(s) reached
=== [ci] control `gate-fence-off`
[ci] control `gate-fence-off`: 1 verdict(s) reached
=== [ci] control `poll-fire-load-store`
[ci] control `poll-fire-load-store`: 3 verdict(s) reached
=== [ci] control `fault-posted-before-it-is-set`
[ci] control `fault-posted-before-it-is-set`: 3 verdict(s) reached
=== [ci] control `victim-retires-mid-probe`
[ci] control `victim-retires-mid-probe`: 1 verdict(s) reached
=== [ci] control `mutate-spawn-skips-the-insert-recheck`
[ci] control `mutate-spawn-skips-the-insert-recheck`: 2 verdict(s) reached
=== [ci] control `mutate-claim-teardown-always-wins`
[ci] control `mutate-claim-teardown-always-wins`: 1 verdict(s) reached
=== [ci] control `mutate-kill-waits-for-its-victims`
[ci] control `mutate-kill-waits-for-its-victims`: 2 verdict(s) reached
=== [ci] control `mutate-first-out-tears-down`
[ci] control `mutate-first-out-tears-down`: 1 verdict(s) reached
=== [ci] control `mutate-join-collects-in-a-teardown`
[ci] control `mutate-join-collects-in-a-teardown`: 1 verdict(s) reached
=== [ci] control `mutate-last-out-leaves-before-its-teardown`
[ci] control `mutate-last-out-leaves-before-its-teardown`: 2 verdict(s) reached
=== [ci] control `placement-ignores-staleness`
[ci] control `placement-ignores-staleness`: 1 verdict(s) reached
=== [ci] control `mutate-session-end-forgets`
[ci] control `mutate-session-end-forgets`: 1 verdict(s) reached
=== [ci] control `mutate-abort-keeps-inflight`
[ci] control `mutate-abort-keeps-inflight`: 1 verdict(s) reached
=== [ci] control `mutate-no-reissue-after-loss`
[ci] control `mutate-no-reissue-after-loss`: 1 verdict(s) reached
=== [ci] control `publish-relaxed`
[ci] control `publish-relaxed`: 1 verdict(s) reached
=== [ci] control `no-clamp`
[ci] control `no-clamp`: 1 verdict(s) reached
=== [ci] control `end-keeps-inflight`
[ci] control `end-keeps-inflight`: 1 verdict(s) reached
=== [ci] userland/blockd
[ci] userland/blockd: cargo test --manifest-path userland/blockd/Cargo.toml --target aarch64-apple-darwin
=== [ci] userland/calc
[ci] userland/calc: cargo test --manifest-path userland/calc/Cargo.toml --target aarch64-apple-darwin
=== [ci] userland/fsd
[ci] userland/fsd: cargo test --manifest-path userland/fsd/Cargo.toml --target aarch64-apple-darwin
=== [ci] userland/logd
[ci] userland/logd: cargo test --manifest-path userland/logd/Cargo.toml --target aarch64-apple-darwin
=== [ci] userland/netd
[ci] userland/netd: cargo test --manifest-path userland/netd/Cargo.toml --target aarch64-apple-darwin
=== [ci] userland/pkg
[ci] userland/pkg: cargo test --manifest-path userland/pkg/Cargo.toml --target aarch64-apple-darwin
=== [ci] userland/soundd
[ci] userland/soundd: cargo test --manifest-path userland/soundd/Cargo.toml --target aarch64-apple-darwin
=== [ci] userland/sshd
[ci] userland/sshd: cargo test --manifest-path userland/sshd/Cargo.toml --target aarch64-apple-darwin
=== [ci] the apps for linux
[ci] the apps for linux: 11 app(s) pass `cargo check --target x86_64-unknown-linux-gnu`; userland/doom, userland/proctest, userland/shell, userland/terminal, userland/toybox not attempted, as their manifests declare
=== [ci] the apps for macos
[ci] the apps for macos: 11 app(s) pass `cargo build --target aarch64-apple-darwin`; userland/doom, userland/proctest, userland/shell, userland/terminal, userland/toybox not attempted, as their manifests declare
=== [ci] the apps for windows
[ci] the apps for windows: 11 app(s) pass `cargo check --target x86_64-pc-windows-msvc`; userland/doom, userland/proctest, userland/shell, userland/terminal, userland/toybox not attempted, as their manifests declare
=== [ci] the toyos SDK
[ci] the toyos SDK: cargo test --manifest-path toyos/Cargo.toml --target aarch64-apple-darwin
=== [ci] nothing left in $TMPDIR or /tmp
[ci] nothing left in $TMPDIR or /tmp: every test took its scratch with it
[ci] Host: 59 step(s), all green

The build system's cargo test --lib: test result: ok. 363 passed; 0 failed; 7 ignored; 0 measured; 0 filtered out; finished in 7.95s

cargo run -- --build-only → EXIT=0, the whole log:

    Finished `dev` profile [optimized + debuginfo] target(s) in 0.04s
     Running `target/debug/toyos-build --build-only`
    Blocking waiting for file lock on package cache
    Blocking waiting for file lock on package cache
    Blocking waiting for file lock on package cache
    Blocking waiting for file lock on package cache
    Blocking waiting for file lock on package cache
    Blocking waiting for file lock on package cache
   Compiling kernel v0.1.0 (/Users/jan/Dev/jan/toyos-nomachinery/kernel)
    Finished `toyos` profile [optimized + debuginfo] target(s) in 0.30s
    Finished `toyos` profile [optimized + debuginfo] target(s) in 5.52s
   Compiling doom v0.1.0 (/Users/jan/Dev/jan/toyos-nomachinery/userland/doom)
    Finished `toyos` profile [optimized + debuginfo] target(s) in 3.84s
warning: the following packages contain code that will be rejected by a future version of Rust: winit v0.30.13 (https://github.com/ToyOSOrg/winit?branch=toyos-0.30.13#f58e1f3b)
note: to see what the problems were, use the option `--future-incompat-report`, or run `cargo report future-incompatibilities --id 1`
    Finished `toyos` profile [optimized + debuginfo] target(s) in 0.11s
root: adding 'bin/blockd' (981136 bytes)
root: adding 'bin/calc' (1547128 bytes)
root: adding 'bin/compositor' (3013792 bytes)
root: adding 'bin/doom' (2146640 bytes)
root: adding 'bin/editor' (997184 bytes)
root: adding 'bin/filepicker' (953440 bytes)
root: adding 'bin/files' (2790648 bytes)
root: adding 'bin/fsd' (1848520 bytes)
root: adding 'bin/host' (756616 bytes)
root: adding 'bin/init' (1582152 bytes)
root: adding 'bin/input-test' (740528 bytes)
root: adding 'bin/inspect' (932968 bytes)
root: adding 'bin/logd' (1243032 bytes)
root: adding 'bin/netd' (1329496 bytes)
root: adding 'bin/paint' (935624 bytes)
root: adding 'bin/pkg' (1044904 bytes)
root: adding 'bin/proctest' (904296 bytes)
root: adding 'bin/shell' (1015592 bytes)
root: adding 'bin/snake' (1247832 bytes)
root: adding 'bin/soundd' (1172504 bytes)
root: adding 'bin/sshd' (5412408 bytes)
root: adding 'bin/swap' (923256 bytes)
root: adding 'bin/terminal' (1030800 bytes)
root: adding 'bin/toybox' (1399592 bytes)
root: adding 'bin/toyos-ld' (2024304 bytes)
root: adding 'bin/update' (1014920 bytes)
root: adding 'etc/system.manifest' (1973 bytes)
root: adding 'share/doom1.wad' (4196020 bytes)
root: adding 'share/fonts/JetBrainsMono-Regular-8x16.font' (66404 bytes)
root: adding 'share/fonts/ofl.txt' (4216 bytes)
root: adding 'share/fonts/opensans-bold.ttf' (147264 bytes)
root: adding 'share/fonts/opensans-bolditalic.ttf' (153308 bytes)
root: adding 'share/fonts/opensans-italic.ttf' (153256 bytes)
root: adding 'share/fonts/opensans-regular.ttf' (147528 bytes)
root: adding 'share/hello.rs' (55 bytes)
root: adding 'share/icons/arrow-down-right-bold.svg' (211 bytes)
root: adding 'share/icons/crosshair-simple-bold.svg' (809 bytes)
root: adding 'share/icons/cursor-bold.svg' (560 bytes)
root: adding 'share/icons/file-bold.svg' (293 bytes)
root: adding 'share/icons/folder-bold.svg' (303 bytes)
root: adding 'share/icons/minus-bold.svg' (253 bytes)
root: adding 'share/icons/square-bold.svg' (264 bytes)
root: adding 'share/icons/x-bold.svg' (392 bytes)
root: adding 'share/soundfont.sf2' (15546764 bytes)
root: adding 'share/wallpaper.rgb' (6220808 bytes)
root: symlink 'bin/cat' -> '/system/bin/toybox'
root: symlink 'bin/cp' -> '/system/bin/toybox'
root: symlink 'bin/echo' -> '/system/bin/toybox'
root: symlink 'bin/free' -> '/system/bin/toybox'
root: symlink 'bin/grep' -> '/system/bin/toybox'
root: symlink 'bin/hexdump' -> '/system/bin/toybox'
root: symlink 'bin/locale' -> '/system/bin/toybox'
root: symlink 'bin/ls' -> '/system/bin/toybox'
root: symlink 'bin/mkdir' -> '/system/bin/toybox'
root: symlink 'bin/mv' -> '/system/bin/toybox'
root: symlink 'bin/net' -> '/system/bin/toybox'
root: symlink 'bin/ps' -> '/system/bin/toybox'
root: symlink 'bin/pwd' -> '/system/bin/toybox'
root: symlink 'bin/reboot' -> '/system/bin/toybox'
root: symlink 'bin/rm' -> '/system/bin/toybox'
root: symlink 'bin/screen' -> '/system/bin/toybox'
root: symlink 'bin/shutdown' -> '/system/bin/toybox'
root: symlink 'bin/spin' -> '/system/bin/toybox'
root: symlink 'bin/stats' -> '/system/bin/toybox'
root: symlink 'bin/tone' -> '/system/bin/toybox'
Signed with this checkout's throwaway key SHA256:9+6Ic/FFPJKd8xEEdx3NWICFB9tf8SDkjN8Y3dgAkaQ at version 1790888062
Build finished.
Boot image: /Users/jan/Dev/jan/toyos-nomachinery/target/bootable.img

@Japabu

Japabu commented Oct 1, 2026

Copy link
Copy Markdown
Collaborator Author

Round 2, at f325be7. Evidence: issuecomment-5940391731: cargo run -- --ci host EXIT=0 (Host: 59 step(s), all green), the build system's cargo test --lib 363 passed, 0 failed, and cargo run -- --build-only EXIT=0. No guest run. The merge of 76d0d93 is clean: git show --remerge-diff c31298449 is empty.
Growth: 41 files, +368 −1692 (git diff --shortstat origin/main...HEAD). Rust is +117 −1249. Round 2's Rust is +91 −127, of which tests are +10 −8 (tests/common/compile.rs and the switch test). Round 2's prose is +241 −414.

Round 1

  • BLOCKER 1 (sysroot guard): CLOSED, by reading at f325be7.
    • Sysroot.dir is private and only lent (src/sysroot.rs:122,142).
    • GuestEnv owns the Sysroot and is no longer Clone (src/build.rs:377-397). So shipped_parts (:1716), build_test_parts (:1933) and TestBuild (:2130-2144) hold the guard across every read.
    • The kernel build runs on a scoped thread (:1727-1738).
    • The harness's static SYSROOT holds the guard for the whole process (tests/common/compile.rs:24).
    • A sweep's keyed_idle is a try-lock (src/buildlock.rs:305-308), so it skips a held key.
    • Of this code, only the --build-only path has run.
  • BLOCKER 2 (two tracks, one cut): CLOSED. The file is gone. Its stages 2 and 3 are now bullets with exits at issues/build/the-tooling-is-a-review-prompt-and-three-workflows.md:13-23. Nothing names its slug (git grep -F, exit 1).

Checked, nothing found:

  • Decision 1's drafts and arming are in orchestrator.md:50-52 and implementer.md:70-71. Decisions 2, 3 and 5-12 and the owner's four further lines are each where decisions.md puts them. system service is untouched.
  • NOT READY FOR REVIEW, --worktree, --sync, upstreamer, who-arms-auto-merge-has-two-answers and crate::git( each give git grep -F exit 1.
  • The subdirectory files take every finding decisions.md lists, and each one shrank (git cat-file -s).
  • Root CLAUDE.md holds every rule a typeless agent can break past repair: personal data :85, history :87, main :88, clone and submodule :86, the T14 :69, another agent's process :74 and an upstream pull request :58.
  • host skips a draft (.github/workflows/ci.yml:19), so CLAUDE.md:67 is true.
  • Round 1's sweep NOTE is closed: a second sweeper's keyed_idle skips a held key, and keystore::remove treats a name already gone as removed (src/keystore.rs:227-246).
  • publish reads the now untrimmed ls-remote output with split_whitespace (src/ci.rs:873).

BLOCKER

  • .claude/agents/reviewer.md:113-114 — "a citation: never a send-back, never corrected" — Decision 4 keeps a record true (CLAUDE.md:92). CLAUDE.md:88 and issues/README.md:112 move every citation in the same merge. :77-78 here makes an issues/ change against issues/README.md a BLOCKER. Read together, a moved line's citation in an issue is owed, never corrected and never a send-back, all at once. Scope the sentence to source comments and docs, as CLAUDE.md:92 does.
  • .claude/agents/reviewer.md:16-18 — Decision 1 rests a review on the body's guest exit codes, but this list asks for them only from tests a branch adds. Nothing boots a guest before main: ci.yml:18-41 runs host alone, and guests run nightly (CLAUDE.md:67). So a change a guest reaches lands without a guest boot. This branch is one: TestBuild::begin and c_sysroot (src/build.rs:2138-2144, tests/common/compile.rs:23-29) run only under cargo test, and the body records no guest exit code. Fix: ask for the guest exit codes of whatever a change reaches, and record a run here that reaches both paths.

NOTE

  • .claude/agents/implementer.md:28-29 — "For a metal row, build its image": the harness builds a row's images under --metal, and only --metal-readback keeps it off the machine (src/testargs.rs:20-23). CLAUDE.md:69 bars --metal to every agent but the orchestrator. orchestrator.md:71-72 also reads the T14 RUN REQUESTED: line as naming the request file, while this line makes it the image path. Say which command builds the image, and which path the line carries.
  • .claude/agents/orchestrator.md:9-11 — "You edit only a pull request's description and comments", yet at :74-76 and :66-67 the orchestrator applies and reverts a mutation in a worktree with git apply. Either say a bench mutation applied and reverted in one run is a measurement, or give it to an agent.
  • issues/build/a-worktree-cannot-build-a-hosted-rustc-of-its-own.md:13 — cites env.primary_compiler, which this round moved to env.sysroot.primary_compiler (src/build.rs:707).

REMOVE

  • .claude/agents/implementer.md:64 "CI capacity is limited:" — a push to a draft runs no host (.github/workflows/ci.yml:19).
  • tests/common/compile.rs:21 "a hundred and fifty C programs build against it" — a count that others' landings move, in a line this branch rewrote (CLAUDE.md:93).
  • issues/build/the-build-system-does-not-compile-on-windows.md:9-17 — an error list no command printed (the 2026-09-01 output less round 1's two worktree.rs lines), and this round deleted the line that dated it.
  • issues/build/the-tooling-is-a-review-prompt-and-three-workflows.md:18-19 "Two agents building at once cannot be told apart by prose, so" — a rationale, which a track does not carry (issues/README.md:69-71).
  • PR body, "The example of a gate replaced by a prompt." — another pull request's history, and a claim about its head that will rot.

SEND BACK

…ce and docs leave a citation uncorrected

Applies the round-2 re-review of #678 (issuecomment-5940927376).

BLOCKER, reviewer.md "Prose": the sentence that made a wrong line number,
count, date or citation never a send-back and never corrected now binds
source comments and docs alone, as root CLAUDE.md's "Prose" does; a record
(a pull request body, an issue, a prompt) is kept true. Its heading,
"Prose is removed, never reviewed", said the same of records, and is now
"Prose".

BLOCKER, reviewer.md "Evidence": a missing guest exit code was a BLOCKER
only for a test the branch adds, and no guest boots before main: ci.yml
runs `host` alone, and guests run nightly. It is now a BLOCKER for every
guest test the change reaches.

NOTE, the T14 handoff: implementer.md told an agent to build a metal row's
image while root CLAUDE.md barred `--metal`, and the harness builds a row's
images only under `--metal`. `--metal --metal-readback <dir>` builds them,
writes `<dir>/request.txt` and touches no machine (src/testargs.rs,
tests/common/metal.rs). Root now bars `--metal` without `--metal-readback`,
implementer.md names the staging command, and the report line and
orchestrator.md both carry `<dir>/request.txt`, where one named an image
and the other a request file.

NOTE, orchestrator.md: a metal mutation loop is a measurement, not an edit,
so the loop no longer contradicts "you edit only a pull request's
description and comments".

NOTE: the hosted-rustc issue cites `env.sysroot.primary_compiler`, where
round 2 moved it.

REMOVE: implementer.md's "CI capacity is limited:", compile.rs's count of
C programs, the Windows issue's undated error list, and the tooling
track's rationale clause. The Windows issue also loses the paragraph after
the list: its "every other crate" meant every crate but the list's, and the
`#[cfg(unix)]` it places at src/ci.rs:489 is in neither main nor this tree
(`git grep -F 'cfg(unix)' <rev> -- src` exits 1 on both).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016t9wjdQkB8SH7bmfUoiy6L
@Japabu

Japabu commented Oct 1, 2026

Copy link
Copy Markdown
Collaborator Author

Round 3 gate logs at 3c2cd6408, kept here so the evidence does not live only in a scratch directory. In the logs, the worktree's path is written as <worktree> and the per-user temporary directory as $TMPDIR. The three gates ran one after another; the host's load (uptime, 14 cores) before and after each:

start 3c2cd6408 2026-10-01T21:35:46Z
23:35  up 2 days, 11:20, 3 users, load averages: 2.17 1.85 1.81
after ci-host 2026-10-01T21:38:10Z
23:38  up 2 days, 11:22, 3 users, load averages: 6.67 3.86 2.64
after build-only 2026-10-01T21:38:15Z
23:38  up 2 days, 11:22, 3 users, load averages: 6.46 3.86 2.65
after guest 2026-10-01T21:40:27Z
23:40  up 2 days, 11:24, 3 users, load averages: 15.22 7.97 4.44

cargo run -- --ci host → EXIT=0. Every step's command line, every model control's header, and the verdict (the full log is 6,726 lines; the 36 test result: FAILED lines in it are all under === [ci] control headers, the model controls that must red):

=== [ci] the build system
[ci] the build system: cargo test --lib
=== [ci] the harness's own checks
[ci] the harness's own checks: cargo test --test toyos-checks
=== [ci] the host workspace
[ci] the host workspace: cargo test --workspace --exclude toyos-build
=== [ci] the licences of what ships
[ci] the licences of what ships: 6 exception(s) stand, and nothing else is refused
=== [ci] clippy and the bare targets
[ci] clippy and the bare targets: installed
=== [ci] clippy, warnings denied
[ci] clippy, warnings denied: clean
=== [ci] kernel-loom without loom
[ci] kernel-loom without loom: cargo test --manifest-path kernel-loom/Cargo.toml --no-default-features --test log_zeroed_init --test log_body_words
=== [ci] control `wake-fence-off`
[ci] control `wake-fence-off`: 1 verdict(s) reached
=== [ci] control `lock-acquire-off`
[ci] control `lock-acquire-off`: 1 verdict(s) reached
=== [ci] control `seqlock-writer-fence-off`
[ci] control `seqlock-writer-fence-off`: 1 verdict(s) reached
=== [ci] control `serial-try-lock-then-some`
[ci] control `serial-try-lock-then-some`: 2 verdict(s) reached
=== [ci] control `reap-raise-relaxed`
[ci] control `reap-raise-relaxed`: 1 verdict(s) reached
=== [ci] control `shootdown-serve-relaxed`
[ci] control `shootdown-serve-relaxed`: 2 verdict(s) reached
=== [ci] control `roster-commit-relaxed`
[ci] control `roster-commit-relaxed`: 1 verdict(s) reached
=== [ci] control `smp-ready-split`
[ci] control `smp-ready-split`: 1 verdict(s) reached
=== [ci] control `log-commit-release-off`
[ci] control `log-commit-release-off`: 2 verdict(s) reached
=== [ci] control `shard-publish-relaxed`
[ci] control `shard-publish-relaxed`: 1 verdict(s) reached
=== [ci] control `log-ring-publish-relaxed`
[ci] control `log-ring-publish-relaxed`: 3 verdict(s) reached
=== [ci] control `log-ring-tail-relaxed`
[ci] control `log-ring-tail-relaxed`: 3 verdict(s) reached
=== [ci] control `log-ring-loads-swapped`
[ci] control `log-ring-loads-swapped`: 1 verdict(s) reached
=== [ci] control `poll-fire-load-store`
[ci] control `poll-fire-load-store`: 2 verdict(s) reached
=== [ci] control `sleeplock-acquire-off`
[ci] control `sleeplock-acquire-off`: 2 verdict(s) reached
=== [ci] control `device-irq-lossy`
[ci] control `device-irq-lossy`: 1 verdict(s) reached
=== [ci] control `dump-report-relaxed`
[ci] control `dump-report-relaxed`: 1 verdict(s) reached
=== [ci] control `no-preempt-guard`
[ci] control `no-preempt-guard`: 1 verdict(s) reached
=== [ci] control `doorbell-kick-relaxed`
[ci] control `doorbell-kick-relaxed`: 1 verdict(s) reached
=== [ci] control `push-fence-relaxed`
[ci] control `push-fence-relaxed`: 1 verdict(s) reached
=== [ci] control `commit-ignores-notify`
[ci] control `commit-ignores-notify`: 2 verdict(s) reached
=== [ci] control `notify-flag-load-only`
[ci] control `notify-flag-load-only`: 1 verdict(s) reached
=== [ci] control `gate-fence-off`
[ci] control `gate-fence-off`: 1 verdict(s) reached
=== [ci] control `poll-fire-load-store`
[ci] control `poll-fire-load-store`: 3 verdict(s) reached
=== [ci] control `fault-posted-before-it-is-set`
[ci] control `fault-posted-before-it-is-set`: 3 verdict(s) reached
=== [ci] control `victim-retires-mid-probe`
[ci] control `victim-retires-mid-probe`: 1 verdict(s) reached
=== [ci] control `mutate-spawn-skips-the-insert-recheck`
[ci] control `mutate-spawn-skips-the-insert-recheck`: 2 verdict(s) reached
=== [ci] control `mutate-claim-teardown-always-wins`
[ci] control `mutate-claim-teardown-always-wins`: 1 verdict(s) reached
=== [ci] control `mutate-kill-waits-for-its-victims`
[ci] control `mutate-kill-waits-for-its-victims`: 2 verdict(s) reached
=== [ci] control `mutate-first-out-tears-down`
[ci] control `mutate-first-out-tears-down`: 1 verdict(s) reached
=== [ci] control `mutate-join-collects-in-a-teardown`
[ci] control `mutate-join-collects-in-a-teardown`: 1 verdict(s) reached
=== [ci] control `mutate-last-out-leaves-before-its-teardown`
[ci] control `mutate-last-out-leaves-before-its-teardown`: 2 verdict(s) reached
=== [ci] control `placement-ignores-staleness`
[ci] control `placement-ignores-staleness`: 1 verdict(s) reached
=== [ci] control `mutate-session-end-forgets`
[ci] control `mutate-session-end-forgets`: 1 verdict(s) reached
=== [ci] control `mutate-abort-keeps-inflight`
[ci] control `mutate-abort-keeps-inflight`: 1 verdict(s) reached
=== [ci] control `mutate-no-reissue-after-loss`
[ci] control `mutate-no-reissue-after-loss`: 1 verdict(s) reached
=== [ci] control `publish-relaxed`
[ci] control `publish-relaxed`: 1 verdict(s) reached
=== [ci] control `no-clamp`
[ci] control `no-clamp`: 1 verdict(s) reached
=== [ci] control `end-keeps-inflight`
[ci] control `end-keeps-inflight`: 1 verdict(s) reached
=== [ci] userland/blockd
[ci] userland/blockd: cargo test --manifest-path userland/blockd/Cargo.toml --target aarch64-apple-darwin
=== [ci] userland/calc
[ci] userland/calc: cargo test --manifest-path userland/calc/Cargo.toml --target aarch64-apple-darwin
=== [ci] userland/fsd
[ci] userland/fsd: cargo test --manifest-path userland/fsd/Cargo.toml --target aarch64-apple-darwin
=== [ci] userland/logd
[ci] userland/logd: cargo test --manifest-path userland/logd/Cargo.toml --target aarch64-apple-darwin
=== [ci] userland/netd
[ci] userland/netd: cargo test --manifest-path userland/netd/Cargo.toml --target aarch64-apple-darwin
=== [ci] userland/pkg
[ci] userland/pkg: cargo test --manifest-path userland/pkg/Cargo.toml --target aarch64-apple-darwin
=== [ci] userland/soundd
[ci] userland/soundd: cargo test --manifest-path userland/soundd/Cargo.toml --target aarch64-apple-darwin
=== [ci] userland/sshd
[ci] userland/sshd: cargo test --manifest-path userland/sshd/Cargo.toml --target aarch64-apple-darwin
=== [ci] the apps for linux
[ci] the apps for linux: 11 app(s) pass `cargo check --target x86_64-unknown-linux-gnu`; userland/doom, userland/proctest, userland/shell, userland/terminal, userland/toybox not attempted, as their manifests declare
=== [ci] the apps for macos
[ci] the apps for macos: 11 app(s) pass `cargo build --target aarch64-apple-darwin`; userland/doom, userland/proctest, userland/shell, userland/terminal, userland/toybox not attempted, as their manifests declare
=== [ci] the apps for windows
[ci] the apps for windows: 11 app(s) pass `cargo check --target x86_64-pc-windows-msvc`; userland/doom, userland/proctest, userland/shell, userland/terminal, userland/toybox not attempted, as their manifests declare
=== [ci] the toyos SDK
[ci] the toyos SDK: cargo test --manifest-path toyos/Cargo.toml --target aarch64-apple-darwin
=== [ci] nothing left in $TMPDIR or /tmp
[ci] nothing left in $TMPDIR or /tmp: every test took its scratch with it
[ci] Host: 59 step(s), all green

The build system's cargo test --lib: test result: ok. 363 passed; 0 failed; 7 ignored; 0 measured; 0 filtered out; finished in 10.16s

cargo run -- --build-only → EXIT=0, the whole log:

    Finished `dev` profile [optimized + debuginfo] target(s) in 0.05s
     Running `target/debug/toyos-build --build-only`
    Blocking waiting for file lock on package cache
    Blocking waiting for file lock on package cache
    Blocking waiting for file lock on package cache
    Blocking waiting for file lock on package cache
    Blocking waiting for file lock on package cache
    Blocking waiting for file lock on package cache
    Finished `toyos` profile [optimized + debuginfo] target(s) in 0.37s
    Finished `toyos` profile [optimized + debuginfo] target(s) in 0.38s
    Finished `toyos` profile [optimized + debuginfo] target(s) in 0.45s
warning: the following packages contain code that will be rejected by a future version of Rust: winit v0.30.13 (https://github.com/ToyOSOrg/winit?branch=toyos-0.30.13#f58e1f3b)
note: to see what the problems were, use the option `--future-incompat-report`, or run `cargo report future-incompatibilities --id 1`
    Finished `toyos` profile [optimized + debuginfo] target(s) in 0.15s
root: adding 'bin/blockd' (981136 bytes)
root: adding 'bin/calc' (1547128 bytes)
root: adding 'bin/compositor' (3013792 bytes)
root: adding 'bin/doom' (2146640 bytes)
root: adding 'bin/editor' (997184 bytes)
root: adding 'bin/filepicker' (953440 bytes)
root: adding 'bin/files' (2790648 bytes)
root: adding 'bin/fsd' (1848520 bytes)
root: adding 'bin/host' (756616 bytes)
root: adding 'bin/init' (1582152 bytes)
root: adding 'bin/input-test' (740528 bytes)
root: adding 'bin/inspect' (932968 bytes)
root: adding 'bin/logd' (1243032 bytes)
root: adding 'bin/netd' (1329496 bytes)
root: adding 'bin/paint' (935624 bytes)
root: adding 'bin/pkg' (1044904 bytes)
root: adding 'bin/proctest' (904296 bytes)
root: adding 'bin/shell' (1015592 bytes)
root: adding 'bin/snake' (1247832 bytes)
root: adding 'bin/soundd' (1172504 bytes)
root: adding 'bin/sshd' (5412408 bytes)
root: adding 'bin/swap' (923256 bytes)
root: adding 'bin/terminal' (1030800 bytes)
root: adding 'bin/toybox' (1399592 bytes)
root: adding 'bin/toyos-ld' (2024304 bytes)
root: adding 'bin/update' (1014920 bytes)
root: adding 'etc/system.manifest' (1973 bytes)
root: adding 'share/doom1.wad' (4196020 bytes)
root: adding 'share/fonts/JetBrainsMono-Regular-8x16.font' (66404 bytes)
root: adding 'share/fonts/ofl.txt' (4216 bytes)
root: adding 'share/fonts/opensans-bold.ttf' (147264 bytes)
root: adding 'share/fonts/opensans-bolditalic.ttf' (153308 bytes)
root: adding 'share/fonts/opensans-italic.ttf' (153256 bytes)
root: adding 'share/fonts/opensans-regular.ttf' (147528 bytes)
root: adding 'share/hello.rs' (55 bytes)
root: adding 'share/icons/arrow-down-right-bold.svg' (211 bytes)
root: adding 'share/icons/crosshair-simple-bold.svg' (809 bytes)
root: adding 'share/icons/cursor-bold.svg' (560 bytes)
root: adding 'share/icons/file-bold.svg' (293 bytes)
root: adding 'share/icons/folder-bold.svg' (303 bytes)
root: adding 'share/icons/minus-bold.svg' (253 bytes)
root: adding 'share/icons/square-bold.svg' (264 bytes)
root: adding 'share/icons/x-bold.svg' (392 bytes)
root: adding 'share/soundfont.sf2' (15546764 bytes)
root: adding 'share/wallpaper.rgb' (6220808 bytes)
root: symlink 'bin/cat' -> '/system/bin/toybox'
root: symlink 'bin/cp' -> '/system/bin/toybox'
root: symlink 'bin/echo' -> '/system/bin/toybox'
root: symlink 'bin/free' -> '/system/bin/toybox'
root: symlink 'bin/grep' -> '/system/bin/toybox'
root: symlink 'bin/hexdump' -> '/system/bin/toybox'
root: symlink 'bin/locale' -> '/system/bin/toybox'
root: symlink 'bin/ls' -> '/system/bin/toybox'
root: symlink 'bin/mkdir' -> '/system/bin/toybox'
root: symlink 'bin/mv' -> '/system/bin/toybox'
root: symlink 'bin/net' -> '/system/bin/toybox'
root: symlink 'bin/ps' -> '/system/bin/toybox'
root: symlink 'bin/pwd' -> '/system/bin/toybox'
root: symlink 'bin/reboot' -> '/system/bin/toybox'
root: symlink 'bin/rm' -> '/system/bin/toybox'
root: symlink 'bin/screen' -> '/system/bin/toybox'
root: symlink 'bin/shutdown' -> '/system/bin/toybox'
root: symlink 'bin/spin' -> '/system/bin/toybox'
root: symlink 'bin/stats' -> '/system/bin/toybox'
root: symlink 'bin/tone' -> '/system/bin/toybox'
Signed with this checkout's throwaway key SHA256:9+6Ic/FFPJKd8xEEdx3NWICFB9tf8SDkjN8Y3dgAkaQ at version 1790890690
Build finished.
Boot image: <worktree>/target/bootable.img

cargo test --test toyos-build, the whole guest suite → EXIT=0, the whole log. virt_readonly_copyout and virt_fatal_halts_the_others_first build their binary through build_toyos_bin, so through TestBuild::begin. No test here reaches c_sysroot: only build_shared_bins calls it, under --metal or --debug, and neither ran.

   Compiling toyos-build v0.1.0 (<worktree>)
    Finished `test` profile [optimized + debuginfo] target(s) in 4.72s
     Running tests/toyos.rs (target/debug/deps/toyos_build-75d90d95c1e02b6b)

running 21 tests, 12 wide

[build-lock] waiting for the artifact lock (artifact staging) — held by pid 57155 (artifact staging), 0s so far
[build-lock] waiting for the artifact lock (artifact staging) — held by pid 57155 (artifact staging), 0s so far
[build-lock] waiting for the build lock (exclusive, clean crate targets against changed external deps) — held by other builds in this tree
[build-lock] waiting for the build lock (shared, test image) — an exclusive phase is queued ahead of it
[build-lock] waiting for the build lock (shared, test image) — an exclusive phase is queued ahead of it
[build-lock] waiting for the build lock (shared, test image) — an exclusive phase is queued ahead of it
[build-lock] waiting for the build lock (shared, test image) — an exclusive phase is queued ahead of it
[build-lock] waiting for the build lock (shared, test image) — an exclusive phase is queued ahead of it
[build-lock] waiting for the build lock (shared, test image) — an exclusive phase is queued ahead of it
[build-lock] waiting for the build lock (shared, test image) — an exclusive phase is queued ahead of it
[build-lock] waiting for the build lock (shared, test image) — an exclusive phase is queued ahead of it
[build-lock] artifact staging acquired after 160.2ms
[build-lock] waiting for the artifact lock (artifact staging) — held, but the holder left no readable note
[build-lock] artifact staging acquired after 12.4s
[build-lock] waiting for the artifact lock (artifact staging) — held, but the holder left no readable note
[build-lock] artifact staging acquired after 12.3s
[build-lock] waiting for the artifact lock (artifact staging) — held, but the holder left no readable note
[build-lock] artifact staging acquired after 6.6s
  [iommu] headless: 3 virtio function(s) behind a unit = true, the audio function 00:04.0 among them
  [iommu] headless-no-iommu: 2 virtio function(s) behind a unit = false, the audio function 00:04.0 among them; the NIC's claim refused for want of a domain
[build-lock] waiting for the build lock (shared, test image) — an exclusive phase is queued ahead of it
[build-lock] still waiting for the build lock (exclusive, clean crate targets against changed external deps), 30s so far — the holder left no readable note
[build-lock] still waiting for the build lock (shared, test image), 30s so far — the holder left no readable note
[build-lock] still waiting for the build lock (shared, test image), 30s so far — the holder left no readable note
[build-lock] still waiting for the build lock (shared, test image), 30s so far — the holder left no readable note
[build-lock] still waiting for the build lock (shared, test image), 30s so far — the holder left no readable note
[build-lock] still waiting for the build lock (shared, test image), 30s so far — the holder left no readable note
[build-lock] still waiting for the build lock (shared, test image), 30s so far — the holder left no readable note
[build-lock] still waiting for the build lock (shared, test image), 30s so far — the holder left no readable note
[build-lock] still waiting for the build lock (shared, test image), 30s so far — the holder left no readable note
[build-lock] artifact staging acquired after 29.5s
assets: leaving out assets/soundfont.sf2 — only /system/bin/doom opens it and this image builds no doom
assets: leaving out assets/DOOM1.WAD — only /system/bin/doom opens it and this image builds no doom
[build-lock] acquired (exclusive, clean crate targets against changed external deps) after 48.4s
external deps changed: cleaning <worktree>/tests/toyos-rust-tests
     Removed 0 files
[build-lock] acquired (shared, test image) after 48.4s
[build-lock] acquired (shared, test image) after 48.4s
[build-lock] acquired (shared, test image) after 48.4s
[build-lock] acquired (shared, test image) after 48.4s
[build-lock] acquired (shared, test image) after 48.4s
[build-lock] acquired (shared, test image) after 48.4s
[build-lock] acquired (shared, test image) after 48.4s
[build-lock] acquired (shared, test image) after 48.4s
[build-lock] acquired (shared, test image) after 20.7s
[build-lock] waiting for the artifact lock (artifact staging) — held by pid 57155 (artifact staging), 0s so far
[build-lock] waiting for the artifact lock (artifact staging) — held by pid 57155 (artifact staging), 0s so far
[build-lock] waiting for the artifact lock (artifact staging) — held by pid 57155 (artifact staging), 0s so far
[build-lock] waiting for the artifact lock (artifact staging) — held by pid 57155 (artifact staging), 0s so far
[build-lock] waiting for the artifact lock (artifact staging) — held by pid 57155 (artifact staging), 0s so far
[build-lock] waiting for the artifact lock (artifact staging) — held by pid 57155 (artifact staging), 0s so far
[build-lock] waiting for the artifact lock (artifact staging) — held by pid 57155 (artifact staging), 0s so far
[build-lock] waiting for the artifact lock (artifact staging) — held by pid 57155 (artifact staging), 0s so far
[build-lock] waiting for the artifact lock (artifact staging) — held by pid 57155 (artifact staging), 2s so far
  [panic] the fatal report is on the panel and sealed in the black box (14223 bytes)
  PASS  screen_fatal_halt_composited  (9s)
  PASS  screen_panic_muted  (7s)
[build-lock] artifact staging acquired after 20.2s
[build-lock] waiting for the artifact lock (artifact staging) — held by pid 57155 (artifact staging), 3s so far
[build-lock] waiting for the artifact lock (artifact staging) — held by pid 57155 (artifact staging), 3s so far
[build-lock] waiting for the artifact lock (artifact staging) — held by pid 57155 (artifact staging), 3s so far
[build-lock] still waiting for the artifact lock (artifact staging), 30s so far — held by pid 57155 (artifact staging), 10s so far
[build-lock] still waiting for the artifact lock (artifact staging), 30s so far — held by pid 57155 (artifact staging), 10s so far
[build-lock] still waiting for the artifact lock (artifact staging), 30s so far — held by pid 57155 (artifact staging), 10s so far
[build-lock] still waiting for the artifact lock (artifact staging), 30s so far — held by pid 57155 (artifact staging), 10s so far
[build-lock] still waiting for the artifact lock (artifact staging), 30s so far — held by pid 57155 (artifact staging), 10s so far
[build-lock] still waiting for the artifact lock (artifact staging), 30s so far — held by pid 57155 (artifact staging), 10s so far
[build-lock] still waiting for the artifact lock (artifact staging), 30s so far — held by pid 57155 (artifact staging), 10s so far
[build-lock] still waiting for the artifact lock (artifact staging), 30s so far — held by pid 57155 (artifact staging), 12s so far
[build-lock] artifact staging acquired after 37.8s
[build-lock] waiting for the artifact lock (artifact staging) — held by pid 57155 (artifact staging), 0s so far
[build-lock] artifact staging acquired after 47.5s
[build-lock] waiting for the artifact lock (artifact staging) — held, but the holder left no readable note
[build-lock] artifact staging acquired after 47.5s
[build-lock] waiting for the artifact lock (artifact staging) — held, but the holder left no readable note
[build-lock] artifact staging acquired after 47.5s
[build-lock] waiting for the artifact lock (artifact staging) — held, but the holder left no readable note
[build-lock] artifact staging acquired after 47.5s
[build-lock] waiting for the artifact lock (artifact staging) — held, but the holder left no readable note
[build-lock] artifact staging acquired after 47.5s
[build-lock] waiting for the artifact lock (artifact staging) — held, but the holder left no readable note
[build-lock] artifact staging acquired after 47.5s
[build-lock] artifact staging acquired after 45.0s
[build-lock] artifact staging acquired after 24.4s
[build-lock] waiting for the artifact lock (artifact staging) — held, but the holder left no readable note
[build-lock] artifact staging acquired after 24.4s
[build-lock] waiting for the artifact lock (artifact staging) — held, but the holder left no readable note
[build-lock] artifact staging acquired after 24.4s
[build-lock] waiting for the artifact lock (artifact staging) — held, but the holder left no readable note
[build-lock] artifact staging acquired after 9.6s
  [nmi] nested: [nmi] NESTED NMI on cpu 0: a second NMI entered while IST2 was still in use.
  PASS  nested_nmi_is_loud  (8s)
  [iommu] declined: [kernel 0.335 cpu0] virtio-sound: NOT INITIALISED — PCI 00:04.0 refused the feature set 0x100000000 the driver accepted, leaving DEVICE_STATUS=0x3 without FEATURES_OK
  PASS  iommu_virtio_platform  (17s)
[build-lock] waiting for the artifact lock (artifact staging) — held by pid 57155 (artifact staging), 11s so far
[build-lock] waiting for the artifact lock (artifact staging) — held by pid 57155 (artifact staging), 11s so far
  PASS  screen_fatal_behind_a_painter  (12s)
[build-lock] artifact staging acquired after 12.1s
[build-lock] artifact staging acquired after 12.3s
[build-lock] artifact staging acquired after 12.5s
[build-lock] artifact staging acquired after 12.6s
[build-lock] artifact staging acquired after 12.8s
[build-lock] artifact staging acquired after 13.0s
  PASS  virt_early_fault  (966ms)
[build-lock] artifact staging acquired after 13.1s
[build-lock] artifact staging acquired after 13.3s
  PASS  virt_early_panic  (755ms)
[build-lock] artifact staging acquired after 2.7s
[build-lock] artifact staging acquired after 2.6s
  PASS  virt_el2_drop  (2s)
  PASS  virt_user_mode  (4s)
  [virt] [kernel 1.620 cpu0] timer-floor: PASS span=10000 floor=10000 ticks: the comparator past the counter it was set from
  PASS  virt_timer_floor  (4s)
  [virt] {2.061 pid=5 test-runner} fp_isolation: v0-v31, FPCR and FPSR survived 3 switches to a thread that loads another state
  PASS  virt_fp_isolation  (22s)
  [virt] {2.145 pid=6 test-runner} first_entry: x1-x30 were zero at a new thread's first instruction
  PASS  virt_first_entry  (18s)
  [virt] {1.950 pid=4 test-runner} preempt: the counting thread was preempted twice, at counts 2253189 and 4631856
  PASS  virt_timer_preempts  (77s)
  [virt] {2.879 pid=7 test-runner} unmap_touch: 4 reads of a page just unmapped on the unmapping thread, and 4 on another, each ended their process
  PASS  virt_unmap_touch  (5s)
  [virt] [kernel 3.823 cpu0] irq-storm: PASS sgis=524448/524448 ticks=1000: the timer fired through the flood, and every SGI sent was taken
  PASS  virt_irq_storm  (6s)
  [virt] {3.240 pid=16 test-runner} debug_refused: SYS_DEBUG's double fault and TLB acknowledgement delay were refused
  PASS  virt_debug_refused  (6s)
  [virt] {3.466 pid=17 test-runner} a syscall writes only where its caller could store
  PASS  virt_readonly_copyout  (6s)
  [virt] {2.327 pid=4 test-runner} unmap_touch: 4 reads of a page just unmapped on the unmapping thread, and 4 on another, each ended their process
  [virt] 8 CPUs entered at EL2, started through SMC, and scheduling
  PASS  virt_smp  (5s)
  [virt] {2.309 pid=4 test-runner} unmap_touch: 4 reads of a page just unmapped on the unmapping thread, and 4 on another, each ended their process
  [virt] 8 CPUs entered at EL1, started through HVC, and scheduling
  PASS  virt_el1_smp  (5s)
  [panic] the fatal path on cpu3 left every other CPU halted with interrupts masked
  PASS  virt_fatal_halts_the_others_first  (7s)
  [virt] {7.009 pid=4 test-runner} unmap_touch: 4 reads of a page just unmapped on the unmapping thread, and 4 on another, each ended their process
  [virt] a non-last AP never started and the dense machine ran its job
  PASS  virt_failed_ap_leaves_no_hole  (10s)
  --- 23 guests, 18 of them not the shipping kernel, 2 kernel build(s): ["", "boot-actuators,test-actuators"]
  --- irq census: 11 guest(s) reported, 1317 interrupt(s), 816 of them on cpu0 (62.0%); per guest cpu0's share is median 100.0% p90 100.0% max 100.0%
      timer           903 (68.6% of all), 47.8% of them on cpu0
      xhci            269 (20.4% of all), 100.0% of them on cpu0
      userdev         112 (8.5% of all), 100.0% of them on cpu0
      tlb              33 (2.5% of all), 9.1% of them on cpu0
      widest guest reported 8 cpu(s)

host: fastest boot 579 ms against the reference 1320 ms — liveness ceilings paid at 1.00x width
host: 14 core(s); a guest wider than that waits vcpus/cores longer again
test result: ok. 21 passed, 21 total (126.9s)

Negative control for the sysroot sweep, re-run at 3c2cd6408: the patch posted in #678 (comment), byte for byte, applied with git apply --check and git apply, then restored with git apply -R. The record of the run (clean-before/clean-after are git status --porcelain):

head 3c2cd6408
clean-before: []
green EXIT=0
apply EXIT=0
 src/sysroot.rs | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)
mutated-build EXIT=0
red EXIT=101
restore EXIT=0
clean-after: []

The green arm, cargo test -p toyos-build --lib -- sysroot::tests::a_sysroot_is_whole_or_it_is_made_again --exact, on the clean head:

    Finished `test` profile [optimized + debuginfo] target(s) in 0.06s
     Running unittests src/lib.rs (target/debug/deps/toyos_build-d73d3393c3d0ed45)

running 1 test
test sysroot::tests::a_sysroot_is_whole_or_it_is_made_again ... ok

test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 369 filtered out; finished in 0.14s

The mutated tree's build, cargo test -p toyos-build --lib --no-run:

   Compiling toyos-build v0.1.0 (<worktree>)
    Finished `test` profile [optimized + debuginfo] target(s) in 5.81s
  Executable unittests src/lib.rs (target/debug/deps/toyos_build-d73d3393c3d0ed45)

The red arm, the same test under the patch. Its first panic is the refusal the test itself asserts (src/sysroot.rs:1356); the red is the orphan assertion, src/sysroot.rs:1370 on the clean tree and :1369 under the patch, which removes a line above it:

    Finished `test` profile [optimized + debuginfo] target(s) in 0.05s
     Running unittests src/lib.rs (target/debug/deps/toyos_build-d73d3393c3d0ed45)

running 1 test
test sysroot::tests::a_sysroot_is_whole_or_it_is_made_again ... FAILED

failures:

---- sysroot::tests::a_sysroot_is_whole_or_it_is_made_again stdout ----

thread 'sysroot::tests::a_sysroot_is_whole_or_it_is_made_again' (72801341) panicked at src/sysroot.rs:563:13:
no sysroot is made from $TMPDIR/toyos-tmp-65641-0/whole-0/rust/build/aarch64-apple-darwin/stage2, and no std was built for one: the toyos toolchain at $TMPDIR/toyos-tmp-65641-0/whole-0/rust/build/aarch64-apple-darwin/stage2/bin is missing cargo, so rustup answers for it by falling back to another toolchain and narrating it on every invocation.
provision_toolchain_cargo is the step that puts them there, and it did not.
A bootstrap in the primary checkout was stopped before it finished: `cargo run -- --build-only` there completes it.
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace

thread 'sysroot::tests::a_sysroot_is_whole_or_it_is_made_again' (72801341) panicked at src/sysroot.rs:1369:9:
placing a sysroot left one no worktree names


failures:
    sysroot::tests::a_sysroot_is_whole_or_it_is_made_again

test result: FAILED. 0 passed; 1 failed; 0 ignored; 0 measured; 369 filtered out; finished in 0.12s

error: test failed, to rerun pass `-p toyos-build --lib`

@Japabu

Japabu commented Oct 1, 2026

Copy link
Copy Markdown
Collaborator Author

Orchestrator's run at 3c2cd6408 (this head), this Mac, no machine touched: cargo test --test toyos-build -- --metal --list EXIT=0. It built the Rust tests and compiled the C tests against the guarded sysroot ([toyos] Compiling 133 C tests, and attempting 24 declared ones...), then listed 27 boots ([metal] 48 registration(s) and 213 shared member(s) over 27 boot(s)). So c_sysroot ran at this head, beside the guest suite's TestBuild::begin (21/21, issuecomment-5941266209).

@Japabu

Japabu commented Oct 1, 2026

Copy link
Copy Markdown
Collaborator Author

Round 3, at 3c2cd64. Evidence at this head: issuecomment-5941266209 — cargo run -- --ci host EXIT=0 (Host: 59 step(s), all green; cargo test --lib 363 passed, 0 failed), cargo run -- --build-only EXIT=0, cargo test --test toyos-build EXIT=0 (21 passed of 21, load 15.22 on 14 cores as it ended), and the sweep's control green EXIT=0, red EXIT=101 under the posted patch, clean after; issuecomment-5941318680 — the orchestrator's cargo test --test toyos-build -- --metal --list EXIT=0. host is SKIPPED on the draft (decision 1).
Growth: 42 files, +372 −1708 (git diff --shortstat origin/main...HEAD); Rust 15 files, +116 −1249. This round (f325be7df..3c2cd6408): 8 files, +35 −47; Rust +1 −2, a doc comment in tests/common/compile.rs.

Round 2

  • BLOCKER 1 (reviewer.md, a citation never corrected): CLOSED, by reading. reviewer.md:113 scopes "never a send-back, never corrected" to a source comment or a doc, as CLAUDE.md:92 does; an issue is a record kept true (CLAUDE.md:92), its moved citations owed by CLAUDE.md:88 and issues/README.md and judged by reviewer.md:77-78. Nothing cites the old heading (git grep -F 'Prose is removed', exit 1).
  • BLOCKER 2 (evidence for every guest test a change reaches): CLOSED. reviewer.md:16-17 asks for it, and both paths ran green at this head:
    • TestBuild::begin: virt_readonly_copyout and virt_fatal_halts_the_others_first passed in the guest suite and build through build_toyos_bin (tests/toyos.rs:1299, :1442 → src/build.rs:2150).
    • c_sysroot: the orchestrator's --metal --list. Every --metal mode calls build_shared_bins (tests/toyos.rs:3681), whose check_not_run and compile_c_tests (:3149-3150) call it (:1050, :1113); [metal] … over 27 boot(s) prints only after they return (tests/common/metal.rs:866), and MetalMode::List returns before any image or drive (:878-883).

Checked, nothing found:

  • Round 2's NOTEs are applied: env.sysroot.primary_compiler is at src/build.rs:707; the metal mutation loop is a measurement (orchestrator.md:74); implementer.md:31 and orchestrator.md:71-72 name one path, <dir>/request.txt, the file metal::run writes (tests/common/metal.rs:933).
  • Round 2's REMOVEs are applied, but for the Host cache: read by content, written by main's cold nightly alone, sealed and bounded, with its workflow rules in the review prompt #669 paragraph the owner kept, which is now accurate: at c282a7669 no Cargo.toml or Cargo.lock names yaml-rust2 (git grep, exit 1), its rules are reviewer.md's "Caches" bullet, and both cited comments say what the paragraph says.
  • --metal-readback touches no machine: refused without --metal or beside --list (src/testargs.rs:73-79, :103-107), it is MetalMode::Offline, which stages or judges; only a run that is not offline drives (tests/common/metal.rs:922-953).
  • git grep -F 'cfg(unix)' <rev> -- src exits 1 on origin/main and on this head, as the Windows issue's removal says.

BLOCKER

  • .claude/agents/implementer.md:29 — cargo test -- --metal --metal-readback <dir> <row> stages nothing — it hands --metal to every test binary of the root package, src/lib.rs's unit tests among them (Cargo.toml exempts no target), and libtest refuses an unknown flag before the harness starts (error: Unrecognized option: 'metal', exit 101; rust/library/test/src/cli.rs:208-210, lib.rs:120-125), as recorded for --host-slots at e7a901e. CLAUDE.md:67, orchestrator.md:71 and the PR body carry the same bare cargo test -- --metal. Spell all four cargo test --test toyos-build -- --metal …, as src/ci.rs:672 and issuecomment-5941318680 do, and record both spellings with --metal-readback: the bare one EXIT=101, the corrected one EXIT=2 and [metal] staged (tests/toyos.rs:3707).

NOTE

  • PR body, "What I am unsure of", first bullet — "No run recorded here reaches c_sysroot" is false since issuecomment-5941318680 — put that run in Gates with its command, exit code and log lines, and delete the bullet.

REMOVE

  • issues/build/the-build-system-does-not-compile-on-windows.md:52 "and it decides two of the errors" — the list it counted was deleted this round.

SEND BACK

`cargo test -- --metal ...` hands `--metal` to every test binary of the
root package. The libtest ones refuse a flag they do not know before the
harness starts (`parse_opts` in library/test/src/cli.rs, exit 101 in
lib.rs's `test_main_inner`), so the command staged nothing. Root
`CLAUDE.md`, `implementer.md`, `orchestrator.md` and the process-memory
track's `copy_cost` A/B now spell it `cargo test --test toyos-build --
--metal ...`, as `suite_args` in src/ci.rs does. The bench paragraph of
`orchestrator.md` is rewrapped at 100 columns around the longer command,
with no other word moved.

The Windows issue's last sentence loses "and it decides two of the
errors": the error list it counted went in round 3.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016t9wjdQkB8SH7bmfUoiy6L
@Japabu

Japabu commented Oct 1, 2026

Copy link
Copy Markdown
Collaborator Author

Round 4 gate logs at 7da54b120, kept here so the evidence does not live only in a scratch directory. In the logs, the worktree's path is written as <worktree>, the per-user temporary directory as $TMPDIR, and the scratch directory both readback directories were named under as <scratch>. The three ran one after another; the host's load (uptime, 14 cores) before and after each, and git status --porcelain --ignore-submodules=none before and after all three:

start 7da54b120 2026-10-01T22:04:56Z
 0:04  up 2 days, 11:49, 3 users, load averages: 8.09 9.35 7.92
clean-before EXIT=0
ci-host EXIT=0
after ci-host 2026-10-01T22:07:29Z
 0:07  up 2 days, 11:51, 3 users, load averages: 16.83 12.00 9.22
metal-bare EXIT=101
after metal-bare 2026-10-01T22:07:31Z
 0:07  up 2 days, 11:51, 3 users, load averages: 16.83 12.00 9.22
metal-test EXIT=2
after metal-test 2026-10-01T22:07:46Z
 0:07  up 2 days, 11:51, 3 users, load averages: 19.29 12.73 9.52
clean-after EXIT=0
gates done

cargo run -- --ci host → EXIT=0. Every step's command line, every model control's header, and the verdict (the full log is 6,728 lines; the 36 test result: FAILED lines in it are all under === [ci] control headers, the model controls that must red):

=== [ci] the build system
[ci] the build system: cargo test --lib
=== [ci] the harness's own checks
[ci] the harness's own checks: cargo test --test toyos-checks
=== [ci] the host workspace
[ci] the host workspace: cargo test --workspace --exclude toyos-build
=== [ci] the licences of what ships
[ci] the licences of what ships: 6 exception(s) stand, and nothing else is refused
=== [ci] clippy and the bare targets
[ci] clippy and the bare targets: installed
=== [ci] clippy, warnings denied
[ci] clippy, warnings denied: clean
=== [ci] kernel-loom without loom
[ci] kernel-loom without loom: cargo test --manifest-path kernel-loom/Cargo.toml --no-default-features --test log_zeroed_init --test log_body_words
=== [ci] control `wake-fence-off`
[ci] control `wake-fence-off`: 1 verdict(s) reached
=== [ci] control `lock-acquire-off`
[ci] control `lock-acquire-off`: 1 verdict(s) reached
=== [ci] control `seqlock-writer-fence-off`
[ci] control `seqlock-writer-fence-off`: 1 verdict(s) reached
=== [ci] control `serial-try-lock-then-some`
[ci] control `serial-try-lock-then-some`: 2 verdict(s) reached
=== [ci] control `reap-raise-relaxed`
[ci] control `reap-raise-relaxed`: 1 verdict(s) reached
=== [ci] control `shootdown-serve-relaxed`
[ci] control `shootdown-serve-relaxed`: 2 verdict(s) reached
=== [ci] control `roster-commit-relaxed`
[ci] control `roster-commit-relaxed`: 1 verdict(s) reached
=== [ci] control `smp-ready-split`
[ci] control `smp-ready-split`: 1 verdict(s) reached
=== [ci] control `log-commit-release-off`
[ci] control `log-commit-release-off`: 2 verdict(s) reached
=== [ci] control `shard-publish-relaxed`
[ci] control `shard-publish-relaxed`: 1 verdict(s) reached
=== [ci] control `log-ring-publish-relaxed`
[ci] control `log-ring-publish-relaxed`: 3 verdict(s) reached
=== [ci] control `log-ring-tail-relaxed`
[ci] control `log-ring-tail-relaxed`: 3 verdict(s) reached
=== [ci] control `log-ring-loads-swapped`
[ci] control `log-ring-loads-swapped`: 1 verdict(s) reached
=== [ci] control `poll-fire-load-store`
[ci] control `poll-fire-load-store`: 2 verdict(s) reached
=== [ci] control `sleeplock-acquire-off`
[ci] control `sleeplock-acquire-off`: 2 verdict(s) reached
=== [ci] control `device-irq-lossy`
[ci] control `device-irq-lossy`: 1 verdict(s) reached
=== [ci] control `dump-report-relaxed`
[ci] control `dump-report-relaxed`: 1 verdict(s) reached
=== [ci] control `no-preempt-guard`
[ci] control `no-preempt-guard`: 1 verdict(s) reached
=== [ci] control `doorbell-kick-relaxed`
[ci] control `doorbell-kick-relaxed`: 1 verdict(s) reached
=== [ci] control `push-fence-relaxed`
[ci] control `push-fence-relaxed`: 1 verdict(s) reached
=== [ci] control `commit-ignores-notify`
[ci] control `commit-ignores-notify`: 2 verdict(s) reached
=== [ci] control `notify-flag-load-only`
[ci] control `notify-flag-load-only`: 1 verdict(s) reached
=== [ci] control `gate-fence-off`
[ci] control `gate-fence-off`: 1 verdict(s) reached
=== [ci] control `poll-fire-load-store`
[ci] control `poll-fire-load-store`: 3 verdict(s) reached
=== [ci] control `fault-posted-before-it-is-set`
[ci] control `fault-posted-before-it-is-set`: 3 verdict(s) reached
=== [ci] control `victim-retires-mid-probe`
[ci] control `victim-retires-mid-probe`: 1 verdict(s) reached
=== [ci] control `mutate-spawn-skips-the-insert-recheck`
[ci] control `mutate-spawn-skips-the-insert-recheck`: 2 verdict(s) reached
=== [ci] control `mutate-claim-teardown-always-wins`
[ci] control `mutate-claim-teardown-always-wins`: 1 verdict(s) reached
=== [ci] control `mutate-kill-waits-for-its-victims`
[ci] control `mutate-kill-waits-for-its-victims`: 2 verdict(s) reached
=== [ci] control `mutate-first-out-tears-down`
[ci] control `mutate-first-out-tears-down`: 1 verdict(s) reached
=== [ci] control `mutate-join-collects-in-a-teardown`
[ci] control `mutate-join-collects-in-a-teardown`: 1 verdict(s) reached
=== [ci] control `mutate-last-out-leaves-before-its-teardown`
[ci] control `mutate-last-out-leaves-before-its-teardown`: 2 verdict(s) reached
=== [ci] control `placement-ignores-staleness`
[ci] control `placement-ignores-staleness`: 1 verdict(s) reached
=== [ci] control `mutate-session-end-forgets`
[ci] control `mutate-session-end-forgets`: 1 verdict(s) reached
=== [ci] control `mutate-abort-keeps-inflight`
[ci] control `mutate-abort-keeps-inflight`: 1 verdict(s) reached
=== [ci] control `mutate-no-reissue-after-loss`
[ci] control `mutate-no-reissue-after-loss`: 1 verdict(s) reached
=== [ci] control `publish-relaxed`
[ci] control `publish-relaxed`: 1 verdict(s) reached
=== [ci] control `no-clamp`
[ci] control `no-clamp`: 1 verdict(s) reached
=== [ci] control `end-keeps-inflight`
[ci] control `end-keeps-inflight`: 1 verdict(s) reached
=== [ci] userland/blockd
[ci] userland/blockd: cargo test --manifest-path userland/blockd/Cargo.toml --target aarch64-apple-darwin
=== [ci] userland/calc
[ci] userland/calc: cargo test --manifest-path userland/calc/Cargo.toml --target aarch64-apple-darwin
=== [ci] userland/fsd
[ci] userland/fsd: cargo test --manifest-path userland/fsd/Cargo.toml --target aarch64-apple-darwin
=== [ci] userland/logd
[ci] userland/logd: cargo test --manifest-path userland/logd/Cargo.toml --target aarch64-apple-darwin
=== [ci] userland/netd
[ci] userland/netd: cargo test --manifest-path userland/netd/Cargo.toml --target aarch64-apple-darwin
=== [ci] userland/pkg
[ci] userland/pkg: cargo test --manifest-path userland/pkg/Cargo.toml --target aarch64-apple-darwin
=== [ci] userland/soundd
[ci] userland/soundd: cargo test --manifest-path userland/soundd/Cargo.toml --target aarch64-apple-darwin
=== [ci] userland/sshd
[ci] userland/sshd: cargo test --manifest-path userland/sshd/Cargo.toml --target aarch64-apple-darwin
=== [ci] the apps for linux
[ci] the apps for linux: 11 app(s) pass `cargo check --target x86_64-unknown-linux-gnu`; userland/doom, userland/proctest, userland/shell, userland/terminal, userland/toybox not attempted, as their manifests declare
=== [ci] the apps for macos
[ci] the apps for macos: 11 app(s) pass `cargo build --target aarch64-apple-darwin`; userland/doom, userland/proctest, userland/shell, userland/terminal, userland/toybox not attempted, as their manifests declare
=== [ci] the apps for windows
[ci] the apps for windows: 11 app(s) pass `cargo check --target x86_64-pc-windows-msvc`; userland/doom, userland/proctest, userland/shell, userland/terminal, userland/toybox not attempted, as their manifests declare
=== [ci] the toyos SDK
[ci] the toyos SDK: cargo test --manifest-path toyos/Cargo.toml --target aarch64-apple-darwin
=== [ci] nothing left in $TMPDIR or /tmp
[ci] nothing left in $TMPDIR or /tmp: every test took its scratch with it
[ci] Host: 59 step(s), all green

The build system's cargo test --lib: test result: ok. 363 passed; 0 failed; 7 ignored; 0 measured; 0 filtered out; finished in 10.54s

The bare spelling, cargo test -- --metal --metal-readback <scratch>/metal-bare metal_sim_scanout_wc → EXIT=101, the whole log. Cargo passes the words after -- to each test binary of the root package it runs; the first is src/lib.rs's unit tests, whose libtest refuses --metal before any test, and cargo stops at that failure. Nothing was staged: <scratch>/metal-bare was never made.

   Compiling toyos-build v0.1.0 (<worktree>)
    Finished `test` profile [optimized + debuginfo] target(s) in 1.27s
     Running unittests src/lib.rs (target/debug/deps/toyos_build-d73d3393c3d0ed45)
error: Unrecognized option: 'metal'
error: test failed, to rerun pass `--lib`

The corrected spelling, cargo test --test toyos-build -- --metal --metal-readback <scratch>/metal-test metal_sim_scanout_wc → EXIT=2, the whole log. [metal] 1 registration(s) … prints only after build_shared_bins returned, whose check_not_run and compile_c_tests call c_sysroot (tests/toyos.rs:1113, :1050), so c_sysroot ran at this head. It staged one image and wrote <scratch>/metal-test/request.txt; the machine was not touched, and the image has since been deleted.

    Finished `test` profile [optimized + debuginfo] target(s) in 0.10s
     Running tests/toyos.rs (target/debug/deps/toyos_build-75d90d95c1e02b6b)
[toyos] Building Rust tests...
[toyos] Compiling 133 C tests, and attempting 24 declared ones...
[metal] 1 registration(s) and 0 shared member(s) over 1 boot(s)
assets: leaving out assets/soundfont.sf2 — only /system/bin/doom opens it and this image builds no doom
assets: leaving out assets/DOOM1.WAD — only /system/bin/doom opens it and this image builds no doom
[metal] metalcase: 0 job(s), armed with [] — <scratch>/metal-test/metalcase/image.img
# One boot per image. Each invocation is `cargo <words>` from this worktree.

metalcase
  image: <scratch>/metal-test/metalcase/image.img
  cargo run --bin toyos-metal -- --image <scratch>/metal-test/metalcase/image.img --readback <scratch>/metal-test/metalcase --fat32-check
[metal] staged 1 image(s); <scratch>/metal-test/request.txt lists them. The machine was not touched, so this run establishes nothing about it.
error: test failed, to rerun pass `--test toyos-build`

Caused by:
  process didn't exit successfully: `<worktree>/target/debug/deps/toyos_build-75d90d95c1e02b6b --metal --metal-readback <scratch>/metal-test metal_sim_scanout_wc` (exit status: 2)

@Japabu
Japabu marked this pull request as ready for review October 1, 2026 22:11
@Japabu
Japabu added this pull request to the merge queue Oct 1, 2026
Merged via the queue into main with commit de5f63c Oct 1, 2026
2 checks passed
@Japabu
Japabu deleted the wt/toyos-nomachinery branch October 1, 2026 22:43
Japabu added a commit that referenced this pull request Oct 2, 2026
Three files conflicted or needed adapting.

.claude/agents/reviewer.md: main's text is taken whole, and this branch's
Caches bullet is kept, between "What no gate reads" and "Growth". The two
sentences this branch added to the Tests bullet are dropped, because main now
states both in its own words: "Rank every finding" names no mutation a type
refuses or a reader of the diff catches, and "Growth" sends back a new gate,
check, lock or test that guards what a reader can check. The round 10 BLOCKER
was against the second of those sentences, which this branch no longer adds.

src/ci.rs: both imports are kept, this branch's `cicache` and main's
`sysroot::git_out`.

src/cicache.rs: main deleted `src/sync.rs`, and with it `sync::git`. The seal
reads HEAD through `sysroot::git_out`, as main's `ci::publish` now does, and
trims it; a git that cannot answer panics instead of returning the refusal.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013UDZQ6fSKw14e4w2TKTRfm
Japabu added a commit that referenced this pull request Oct 2, 2026
#678 (de5f63c) restructured the review prompt, deleted src/sync.rs and
src/worktree.rs, made a Sysroot owned by what compiles against it, and
swept the sysroot stores at each placement. #669 (74a2e70) landed the
host cache: src/cicache.rs, `--ci seal`, and the review prompt's Caches.

Resolved by hand:
- .claude/agents/reviewer.md: main's text whole, with this branch's six
  Workflows rules after Caches. Caches opened "Each cache has one writer,
  a nightly.yml job"; toolchain.yml's `build` saves the toolchain's layers
  from three workflows, so that sentence is now the host cache's alone.
- .github/workflows/ci.yml: main's header comment said "no guest" and
  goes; the host job is main's, the toolchain and guest jobs this branch's.
- src/ci.rs: main's `seal` job beside this branch's `toolchain`,
  `bootstrap` and `release`; five workflow files.
- src/release.rs: this branch's module; `sync::git` is gone, so its four
  git reads are `sysroot::git_out`, as main's `publish` reads them.
- src/build.rs, tests/common/compile.rs: main's owned Sysroot, with this
  branch's `hosted_rustc` argument to `toolchain::ensure`.
- src/llvm.rs: main's unconditional `keystore::remove`, this branch's
  `keep`.
- issues/build/the-build-runs-host-tools-outside-rust-and-qemu.md: main's
  git rows less src/worktree.rs and src/sync.rs, with this branch's
  submodule callers and "CI's containers".

What the merge makes false, and so changes with it:
- CLAUDE.md said "Guests run nightly."; it says where they run now.
- nightly.yml's guest cache is gone with the jobs that carried it, so
  issues/build/the-guest-cache-is-read-by-mtime-and-its-writer-restores-
  before-it-saves.md is deleted, src/cicache.rs's LIMIT no longer names a
  guest entry, and the host-cache limit issue sums two host entries
  beside the toolchain's layers (918,708,556 B a set, run 36934214557's
  saves) where it summed them beside guest entries.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013UDZQ6fSKw14e4w2TKTRfm
Japabu added a commit that referenced this pull request Oct 2, 2026
#660 cut the guest suite to what no cheaper tier reaches and moved the shared
boot to the T14; #678 rewrote the role prompts and the worktree commands.

Conflicts, hunk by hunk:

- `tests/toyos.rs`: main's harness, with this branch's registrations re-made in
  its shape. `process_tree` was a QEMU machine test on `tests/proctreecase`; it
  is now a `METAL` row on that config (`PROCTREECASE`), its binary on
  `RUST_SKIP`, and its judge (`process_tree`) reads off the stick what the QEMU
  arm read off the console: the job's exit, the loader's refusal of
  `/system/bin/no_such_program` once per B, and one depth refusal naming 65.
  `spawn_lands_claimed` stays an `ACTUATOR_TESTS` member, so it rides the
  shared boot on the kernel that carries `SYS_DEBUG`. The `Sched` and `CARRIES`
  rows have no table left to sit in.
- `src/build.rs`: main's list of boot configs, plus `tests/proctreecase`.
- The child-process track: main's text, with stage 4 deleted as this branch
  deletes it. Main's stage 6 gained "A quit reaches the process's subtree by
  stage 4's walk"; the citation of the deleted stage goes and the sentence
  stays.
- `blockd_io.rs`, `spawn_cwd.rs` (modify/delete): this branch's hunk in each
  was the `place` field `SpawnArgs` gained. Main deleted both tests; the hunk
  has nothing left to adapt.
- `compositor_client_death.rs` (modify/delete): this branch's hunk placed the
  test's relay under the test's root, because the relay outlived the creator
  that started it. Main deleted the test; nothing is left to adapt.
- `pkg_launch_gbae.rs` (modify/delete): this branch's hunk has the client start
  gbae under init. Main deleted the client with `pkg_install_gbae`, which the
  guest-suite track brings back as a metal row from main before the cut, where
  the client still exits over a child that now ends with it. That track's
  `pkg_install_gbae` item now says the client starts gbae under init.

Not a conflict, and broken by the merge: `src/ci.rs`'s `CONTROLS` rows take a
`Verdict` on main, so this branch's five `toyos-proclife` rows name their
tests as `Fails(...)` with the module path, and the landed-child control names
its `tree` test as well.

Filed: `issues/build/a-metal-judge-takes-a-names-lowest-pid-for-the-job.md`.
`Readback::exit_code` takes a name's lowest pid for the job, and this branch's
kernel gives a refused spawn's pid to the next admission.

Before this commit, on the merged tree: `cargo run -- --build-only` exit 0,
`cargo test --test toyos-build -- --list` exit 0, and `--metal --list` for
`process_tree`, `abuse_handle_table` and `spawn_lands_claimed` exit 0 each
(one boot each: `proctreecase`, `shared`, `shared-debug`), which builds every
guest binary.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013UDZQ6fSKw14e4w2TKTRfm
Japabu added a commit that referenced this pull request Oct 2, 2026
The four conflicts are the four prompts: CLAUDE.md, implementer.md,
orchestrator.md and reviewer.md. Each is taken from main whole. #678 rewrote
them from the owner's later decisions, which override every prompt rule this
branch wrote on 2026-09-30; none of this branch's prompt hunks survives.

Everything else merged without a conflict: the kernelprobe move, the two case
configs, the closed issue and the filed one.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013UDZQ6fSKw14e4w2TKTRfm
Japabu added a commit that referenced this pull request Oct 2, 2026
…among them) into wt/toyos-winitstall

Three content conflicts, each a deletion on main's side of a block this
branch had edited:

- kernel/src/inbox/mod.rs: main deleted `Staged`, `handler-post`'s ring,
  with the actuator (#660). This branch's hunks inside it — the `owed`
  field, `Poll::new`, the `WatchFlags` direction and "fires" for
  "completes" in its doc — adapted it to the ring's new fields and go with
  it. `Inbox::complete` keeps this branch's wording and loses main's
  `raise_if_staged` call.
- kernel/src/watch.rs: main deleted the `handler_post` module, `holding`,
  `note_post` and the `raise_if_staged` call in `IrqLock::with`. This
  branch's one hunk inside it was "fires" for "completes" in the module's
  doc, which goes with it.
- userland/fsd/src/main.rs: main deleted the four test actuators
  (`--end-on`, `--end-at-read`, `--end-at-mount`, `--let-go-at-read`) and
  kept the acceptor probe; this branch deleted the probe and kept the
  actuators. Both deletions stand: no `caps_len`, no `probe` field, no
  actuator field, and `accept` is this branch's.

Two resolutions no marker asked for:

- src/ci.rs: #668 made a control's verdicts `Fails(..)` values, so
  `post-is-an-answer`'s three verdict strings become three `Fails`.
- issues/build: main filed the C++ runtime's scratch removal as an issue
  of its own (`the-cxx-runtimes-scratch-removal-dies-on-a-finder-file.md`)
  beside the sweep's, which this branch had merged into one file. Main's
  two files stand and this branch's file goes.

The `rust` gitlink is main's, `95960d6c2`.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013UDZQ6fSKw14e4w2TKTRfm
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant