Skip to content

The host jobs build their driver with line tables alone, and the seal's red since 2026-10-05 is accounted for - #752

Merged
Japabu merged 1 commit into
mainfrom
wt/toyos-nightlyseal
Oct 8, 2026
Merged

Japabu merged 1 commit into
mainfrom
wt/toyos-nightlyseal

Conversation

@Japabu

@Japabu Japabu commented Oct 7, 2026 •

Copy link
Copy Markdown
Collaborator

Head 7f991fbad. Fixes the red on main: nightly's host has failed at its last step, the seal of the host cache, on every scheduled run since 2026-10-05.

What stood red, and for how long

run date image seal line
37190643147 (d47b383cf) 2026-10-04 20260927.320.1 16897 files, 7605844073 B of the 8000000000 B an entry may hold; saved 1,813,819,887 B
37292450697 (f260e0b98) 2026-10-05 20260927.320.1 8540783725 B in 18591 files under the cache's paths, above the 8000000000 B
37444133685 (f260e0b98) 2026-10-06 red the same way
37601225884 (f260e0b98) 2026-10-07 20261004.327.1 8182940473 B in 17350 files under the cache's paths, above the 8000000000 B

Three scheduled runs, found on 2026-10-07 by a review of another pull request. Nothing reported it: the scheduled nightly is a check of no pull request and no merge group, and no role's prompt reads it. Filed as issues/a-red-nightly-on-main-is-reported-to-nobody.md.

The brief said every host check since ran cold because no entry exists. The entry of 2026-10-04 exists and is restored; the readers discard it. Runs 37646740767 and 37687777630 each say Cache restored from key: host-sealed-Linux-X64-37190643147 (1,813,819,887 B) and then d47b383cf…'s entry, built on Linux X64 ubuntu24 20260927.320.1, deleted: the run is cold, since they ran on 20261004.327.1. GitHub served both images on 2026-10-07 (the table above, and runs 37685714260 and 37693139619 on the older one hours after 37601225884 on the newer), so a fresh entry does not end this: filed as issues/a-host-reader-on-another-runner-image-downloads-the-entry-and-discards-it.md.

Root cause

#722 (c4ab2b1e1, os-release) added gix to the build system. Units compiled per step, counted from the logs of 37190643147 and 37601225884:

step 2026-10-04 2026-10-07
the driver's own build (target/ci-driver) 111 203
the build system (target/debug) 115 207
clippy, warnings denied 320 414

The build system's dependency closure is built twice, once for the driver and once for the step that tests it, in two targets by design (src/cicache.rs's header).

What is under the paths, and what a reader reads

Diagnostic run 37693139619 (branch commit 14f49933c, since replaced; its patch is in the first comment) lifted LIMIT, sealed, listed every file under the paths with its size, compressed each directory with tar | zstd -T0, then replayed two readers over the sealed tree with every file's access time reset: A with nothing changed, B with every Cargo.toml changed so every path crate rebuilt. It ran on image 20260927.320.1.

Seal: 18712 files, 8608140775 B. Compressed whole: 2,020,684,970 B.

directory bytes compressed read by A or B
target/debug 3,909,175,987 965,258,324 test binaries 2,549,630,832 of 2,708,603,504 (A runs them); libraries and metadata 686,115,791 of 961,369,725 (B links them)
target/ci-driver 1,757,640,523 436,269,662 below
userland/target/x86_64-unknown-linux-gnu 951,246,596 260,655,237 libraries and metadata 581,164,209 of 631,256,523
userland/target/debug 378,489,954 89,961,462
userland/target/x86_64-pc-windows-msvc 171,769,938 56,756,954 metadata 166,379,925 of 170,333,161
userland/target/aarch64-apple-darwin 148,562,396 50,337,291 metadata 141,603,434 of 147,019,327
~/.cargo/registry/cache, index, git/db 157,454,383 125,760,696 index and git read; registry/cache not, because the replay kept ~/.cargo/registry/src, which a real reader does not have and unpacks from it

Reader times in that run: cold steps 16 min 40 s after a 2 min 47 s driver build; reader A 5 min 11 s; reader B 11 min 30 s; the driver's own rebuild 2.07 s in both, from its incremental state. So the driver's target is reused and stays in the entry.

What a reader does not use is in target/ci-driver. It is built by the workflow's cargo run before carry() runs, so it alone carried full debuginfo:

  • its 167 libraries that target/debug also holds once: 738,377,910 B, against 322,227,512 B there with line tables alone;
  • its binary: 262,085,512 B, against 78,170,512 B for the same binary in target/debug, and counted under two names (a hard link);
  • its incremental state, 409,998,048 B, and build scripts carry the same debuginfo.

The change

  • ci.yml and nightly.yml: the host job's env: gives CARGO_PROFILE_DEV_DEBUG: line-tables-only. The driver's build and every step inherit it.
  • src/ci.rs: carry() no longer sets it, so there is one declaration; the test that asserted carry() set it asserts only what carry() still does.
  • .claude/agents/reviewer.md, Caches: "the one variable an env: gives either" becomes the two. The implementer was not briefed to edit a prompt; the orchestrator gave the edit his go at review (root CLAUDE.md: an agent updates the step its own change renames). Without the edit the prompt is false of the workflows it describes; the orchestrator decides whether it stands.
  • LIMIT is unchanged at 8,000,000,000 B. Its reason holds on re-measurement: at the lowest Linux ratio measured (4.01; the two new ones are 4.19 and 4.26) it stores at most 1,994,138,951 B, and two entries beside main's four toolchain layers (912,484,904 B on 2026-10-07) are 4.9 GB of the 10 GB.
  • No seal code changed, so no seal test was added.

Rejected: dropping target/ci-driver from the entry (a reader would pay the 2 to 3 minute cold driver build each run); debug = "line-tables-only" in the root [profile.dev] (its comment keeps debug on for LLDB); raising LIMIT alone (the content was not all reused).

Outside bounds, as read

  • GitHub Docs, "Dependency caching reference", Usage limits and eviction policy: entries not accessed in over 7 days are removed; "By default, the limit is 10 GB per repository"; past it, caches are deleted "in order of last access date, from oldest to most recent".
  • actions/toolkit packages/cache/src/cache.ts: an archive over 10 * 1024 * 1024 * 1024 B is not saved.
  • gh api repos/ToyOSOrg/ToyOS/actions/cache/usage on 2026-10-07: 10,948,823,786 B in 25 entries, already past 10 GB: one host entry, main's four layers, and twenty sysroot layers of about 420 MB from pull requests and merge groups. Recorded in issues/the-host-caches-limit-reaches-the-10-gb-only-through-one-measured-ratio.md, with the hard links the seal counts twice (521,656,664 B in the diagnostic run) and the files every read rewrites.

What #746 must do

Its dispatch (run 37685714260, 88bcbf4d3) sealed 9348536345 B in 20064 files on image 20260927.320.1; main plus the diagnostic sealed 8,608,140,775 B on the same image the same evening: 740,395,570 B and 1,352 files more. In its log one step grew: "the apps for linux" compiles 282 units against main's 47, and "userland/*" 225 against 285; every other step is within 2 units. That log has no bytes per directory.

So #746's merge must: keep CARGO_PROFILE_DEV_DEBUG in both workflows' env: (review round 1 found the merge with db55db96a writes no conflict on these lines), and keep carry() without it; then dispatch nightly.yml on its branch and show a seal line under LIMIT. This change took 944,362,661 B off main's tree (below). If it takes the same off #746's, whose driver builds the same 203 units, that tree seals 8,404,173,684 B, 404,173,684 B over: it stays red until the apps-for-linux step shares its units with the userland step again, as it does on main in userland/target/x86_64-unknown-linux-gnu. That projection is arithmetic, not a run of #746.

Gates

ci.yml on this head, run 37713267864 (image 20260927.320.1): host success — Cache restored from key: host-sealed-Linux-X64-37190643147, built from d47b383cf…: 203 of 2501 sources dated as built, [ci] Host: 78 step(s), all green; toolchain / build and guest / suite success. It is cargo run -- --ci host on Linux at this head and the first run of ci.yml's changed job.

Nothing was built or tested locally: the owner reserved the development machine's compute while this was written, so no cargo command ran, and the src/ci.rs edit was made by reading. Every result below is run 37699848749's, nightly.yml dispatched on 7f991fbad, read from gh run view 37699848749 --job 113060424069 --log.

gate result
run 37699848749 conclusion success: host, toolchain / build, tcg / suite, portability-linux, portability-macos success; release skipped off main
its host job, cargo run -- --ci seal step success, exit 0; [ci] Seal: 80 step(s), all green; no RED line in the log; the save skipped off main
the seal's tests in that job's "the build system" step: the ten cicache::tests::* and ci::tests::a_step_of_a_job_that_carries_the_cache_builds_in_its_own_target, each ... ok
cargo run -- --ci host not run locally (restriction above). On Linux its steps are the seal job's 80 less the first and last; on macOS portability-macos ran it, success
a mutation that reds the seal's tests not run: no seal code changed, and nothing could be built locally

The seal, on runner image 20260927.320.1 each time:

main, run 37292450697 (f260e0b98):  8540783725 B in 18591 files under the cache's paths, above the 8000000000 B an entry may hold
main + diagnostic, run 37693139619: 18712 files, 8608140775 B of the 80000000000 B an entry may hold   (limit lifted to list the tree)
this head, run 37699848749:         18712 files, 7663778114 B of the 8000000000 B an entry may hold; sealed: 2501 sources, built on Linux X64 ubuntu24 20260927.320.1, every target dated as built

and main's latest failing line, run 37601225884 on image 20261004.327.1: 8182940473 B in 17350 files under the cache's paths, above the 8000000000 B an entry may hold.

  • Measured saving, same image and same file count: 8,608,140,775 − 7,663,778,114 = 944,362,661 B.
  • Measured margin: 336,221,886 B under the limit on image 20260927.320.1.
  • The other image: before this change the same commit f260e0b98 sealed 357,843,252 B less on 20261004.327.1 than on 20260927.320.1 (8,182,940,473 against 8,540,783,725), so the logs say that image seals smaller, not larger. This head has not been sealed on it.
  • Job time: host ran 20 min 26 s (23:02:01Z to 23:22:27Z), its seal step 20 min 15 s, of which the driver's cold build was 2 min 24 s. main's failing host took 20 min 13 s on the same image (run 37292450697) and 13 min 0 s on the newer one (run 37601225884).

Unsure of

  • The margin is 4.2 % of the limit. The next dependency the build system takes can use it up, and the red that follows is still reported to nobody until issues/a-red-nightly-on-main-is-reported-to-nobody.md is closed.
  • No reader has been run against an entry of this head: the save is main's alone. The reader's times above are the diagnostic's replay, made before this change.
  • Whether a host reader between this landing and the next nightly loses anything: no entry on either image matches today, and every reader runs cold.

🤖 Generated with Claude Code

https://claude.ai/code/session_01RvnWQFcMuGqTHYhvSnTe8A

…ps already do

nightly's `host` has been red at its seal since 2026-10-05: #722 brought gix
into the build system, and the cold tree went from 7,605,844,073 B to
8,540,783,725 B, past the 8,000,000,000 B an entry may hold.

Diagnostic run 37693139619 listed every file under the cache's paths and
replayed two readers over the sealed tree. The steps' targets are read by a
reader; the driver's target, 1,757,640,523 B, is built by the workflow's own
`cargo run` before `carry` runs, so it alone carried full debuginfo: its 167
libraries that `target/debug` also holds were 738,377,910 B against
322,227,512 B there, and its binary 262,085,512 B against 78,170,512 B, stored
under two names. Nothing reads debuginfo past the line tables.

So the job's `env:` gives `CARGO_PROFILE_DEV_DEBUG`, which the driver's build
and every step inherit, and `carry` no longer sets it. `LIMIT` stays.

Filed: a red nightly on main is reported to nobody; a reader on another runner
image downloads the entry and discards it. The limit's issue takes the new
ratios, the repository's cache total and what the seal over-counts.

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

Japabu commented Oct 7, 2026

Copy link
Copy Markdown
Collaborator Author

The diagnostic commit 14f49933c that run 37693139619 ran, since replaced on the branch. It never lands. The table of bytes read was made from its L0, L1 and L2 lines: a file counts as read by a reader when its access time moved and its modification time did not.

commit 14f49933c0a8bf4113f64b0f9ac33c1ed175e593
Author: japabu <japa.busse@gmail.com>
Date:   Wed Oct 7 23:58:42 2026 +0200

    DIAGNOSTIC, never lands: list the host cache and replay a reader
    
    Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
    Claude-Session: https://claude.ai/code/session_01RvnWQFcMuGqTHYhvSnTe8A

diff --git a/.github/workflows/nightly.yml b/.github/workflows/nightly.yml
index b26634d85..0e54c5c68 100644
--- a/.github/workflows/nightly.yml
+++ b/.github/workflows/nightly.yml
@@ -1,28 +1,18 @@
 name: nightly
 
-# Every job's logic is `cargo run -- --ci <job>` (src/ci.rs); this file says
-# where each one runs.
+# DIAGNOSTIC, never lands: what is under the host cache's paths, and what a
+# reader reads of it.
 
 on:
-  schedule:
-    - cron: '0 3 * * *'
   workflow_dispatch:
 
-concurrency:
-  group: nightly-${{ github.ref }}
-  cancel-in-progress: false
-
 permissions:
   contents: read
 
 jobs:
-  # The host cache's writer restores nothing, and `seal` is green only once
-  # src/cicache.rs has sealed the tree the save stores.
   host:
     runs-on: ubuntu-24.04
-    timeout-minutes: 90
-    # The driver's own target, and no step's: it says this job carries the
-    # host cache (src/cicache.rs).
+    timeout-minutes: 120
     env:
       CARGO_TARGET_DIR: target/ci-driver
     steps:
@@ -32,95 +22,46 @@ jobs:
 
       - run: cargo run -- --ci seal
 
-      # The host cache's one writer. Only main's entries are readable from
-      # every branch.
-      - if: github.ref == 'refs/heads/main'
-        uses: actions/cache/save@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0
-        with:
-          path: |
-            ~/.cargo/registry/index
-            ~/.cargo/registry/cache
-            ~/.cargo/git/db
-            target
-            userland/target
-            toyos/target
-            kernel/target
-            bootloader/target
-          key: host-sealed-${{ runner.os }}-${{ runner.arch }}-${{ github.run_id }}
-
-  toolchain:
-    uses: ./.github/workflows/toolchain.yml
-
-  # Skipped off main, where the driver refuses it by name.
-  release:
-    needs: toolchain
-    if: github.ref == 'refs/heads/main'
-    runs-on: ubuntu-24.04
-    timeout-minutes: 30
-    permissions:
-      contents: write
-    steps:
-      - uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4.4.0
-
-      - uses: actions/cache/restore@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0
-        with:
-          path: ${{ needs.toolchain.outputs.sysroot-path }}
-          key: ${{ needs.toolchain.outputs.sysroot-key }}
-          fail-on-cache-miss: true
-
-      - env:
-          GH_TOKEN: ${{ github.token }}
-        run: cargo run -- --ci release
-
-  tcg:
-    needs: toolchain
-    if: ${{ !cancelled() }}
-    uses: ./.github/workflows/guest.yml
-    with:
-      kvm: false
-      sysroot-key: ${{ needs.toolchain.outputs.sysroot-key }}
-      sysroot-path: ${{ needs.toolchain.outputs.sysroot-path }}
-
-  # `cargo run -- --build-only` from a fresh machine. `sid` as it stands,
-  # image and archive both, and no cache — a fresh machine is the premise.
-  portability-linux:
-    runs-on: ubuntu-24.04
-    timeout-minutes: 350
-    container:
-      image: debian:sid
-    steps:
-      - name: deps
+      - if: always()
         run: |
-          for attempt in 1 2 3; do
-            apt-get update -qq > /tmp/apt.log 2>&1 \
-              && DEBIAN_FRONTEND=noninteractive apt-get install -y -qq git curl ca-certificates \
-                   build-essential qemu-system-x86 python3 cmake >> /tmp/apt.log 2>&1 \
-              && break
-            [ "$attempt" = 3 ] && { cat /tmp/apt.log; exit 1; }
-            sleep 20
+          cd "$GITHUB_WORKSPACE"
+          E=""
+          for p in "$HOME/.cargo/registry/index" "$HOME/.cargo/registry/cache" "$HOME/.cargo/git/db" target userland/target toyos/target kernel/target bootloader/target; do
+            [ -e "$p" ] && E="$E $p"
           done
-          git config --global --add safe.directory "$GITHUB_WORKSPACE"
-          curl --proto '=https' --tlsv1.2 -sSf -o "$RUNNER_TEMP/rustup-init.sh" https://sh.rustup.rs
-          sh "$RUNNER_TEMP/rustup-init.sh" -y --profile minimal --default-toolchain stable
-          echo "$HOME/.cargo/bin" >> "$GITHUB_PATH"
-
-      - &checkout
-        uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4.4.0
-
-      - run: cargo run -- --build-only
-
-  portability-macos:
-    runs-on: macos-latest
-    timeout-minutes: 350
-    steps:
-      - *checkout
-      # Homebrew keeps one QEMU; `cargo run` notes it if it is not the declared one.
-      - run: |
-          brew install qemu cmake
-      - run: |
-          curl --proto '=https' --tlsv1.2 -sSf -o "$RUNNER_TEMP/rustup-init.sh" https://sh.rustup.rs
-          sh "$RUNNER_TEMP/rustup-init.sh" -y --profile minimal --default-toolchain stable
-          echo "$HOME/.cargo/bin" >> "$GITHUB_PATH"
-      - run: cargo run -- --build-only
-      # The host suite's macOS arms run here alone: `ci.yml`'s `host` is Linux.
-      - run: cargo run -- --ci host
+          echo "DIAG paths:$E"
+          findmnt -T . || true
+          findmnt -T "$HOME" || true
+          df -h . || true
+          echo "DIAG-BEGIN list0"
+          find $E -type f -printf 'L0 %A@ %T@ %s %p\n'
+          echo "DIAG-END list0"
+          echo "DIAG-BEGIN zstd"
+          echo "Z all $(tar -cf - $E 2>/dev/null | zstd -T0 | wc -c)"
+          for d in "$HOME/.cargo/registry/index" "$HOME/.cargo/registry/cache" "$HOME/.cargo/git/db" target/* userland/target/* toyos/target/* target/ci-driver/debug/* target/debug/*; do
+            [ -e "$d" ] && echo "Z $d $(tar -cf - "$d" 2>/dev/null | zstd -T0 | wc -c) $(du -sb "$d" | cut -f1)"
+          done
+          echo "DIAG-END zstd"
+          cp target/ci-sources "$RUNNER_TEMP/ci-sources"
+          find $E -type f -exec touch -a -d '2000-01-01' {} +
+          probe=$(find target/debug/deps -name '*.rlib' | sed -n 1p)
+          head -c 1 "$probe" > /dev/null
+          echo "DIAG atime probe: $(stat -c '%X %n' "$probe")"
+          touch -a -d '2000-01-01' "$probe"
+
+          echo "DIAG reader A (nothing changed) starts $(date -u +%T)"
+          git ls-files -z | xargs -0 touch -c
+          cargo run -- --ci host; echo "DIAG reader A EXIT=$? ends $(date -u +%T)"
+          echo "DIAG-BEGIN list1"
+          find $E -type f -printf 'L1 %A@ %T@ %s %p\n'
+          echo "DIAG-END list1"
+
+          find $E -type f -exec touch -a -d '2000-01-01' {} +
+          cp "$RUNNER_TEMP/ci-sources" target/ci-sources
+          git ls-files -z '*Cargo.toml' ':!rust' ':!tests/testcases' | xargs -0 -n1 sh -c 'echo "# diag" >> "$0"'
+          echo "DIAG reader B (every package changed) starts $(date -u +%T)"
+          git ls-files -z | xargs -0 touch -c
+          cargo run -- --ci host; echo "DIAG reader B EXIT=$? ends $(date -u +%T)"
+          echo "DIAG-BEGIN list2"
+          find $E -type f -printf 'L2 %A@ %T@ %s %p\n'
+          echo "DIAG-END list2"
diff --git a/src/cicache.rs b/src/cicache.rs
index e35039ec7..2c8581a24 100644
--- a/src/cicache.rs
+++ b/src/cicache.rs
@@ -64,7 +64,7 @@ const PATHS: [&str; 8] = [
 
 /// The most the files under [`PATHS`] may hold, uncompressed. The repository's
 /// caches are evicted by last access past 10 GB.
-const LIMIT: u64 = 8_000_000_000;
+const LIMIT: u64 = 80_000_000_000;
 
 /// 2001-09-09T01:46:40Z: older than any build, so a file dated so is never
 /// newer than one.

@Japabu
Japabu marked this pull request as ready for review October 8, 2026 01:30
@Japabu

Japabu commented Oct 8, 2026

Copy link
Copy Markdown
Collaborator Author

Review round 1 of 7f991fbad against origin/main 8506640f1 (branch base e16cb0841, three landings behind). Read only: nothing was built or run here; every figure below is from a run's log or the investigation's listings.

BLOCKER

None.

NOTE

  • .claude/agents/reviewer.md:92 — a role prompt edited without a brief (root CLAUDE.md, Prose) — the clause is true of both workflows and is the least that says it, and it is what makes the cut of the -C debuginfo=line-tables-only assertion in src/ci.rs legal ("when this prompt takes its rule"); it stands only on the orchestrator's go, and the body's "I was not briefed" sentence is then resolved before it becomes main's record.
  • issues/the-host-caches-limit-reaches-the-10-gb-only-through-one-measured-ratio.md:40 — 521,656,664 B is given as what the seal counts twice; run 37693139619's own lines say at least 977,318,242 B — the find listing against du -sb of the same directories: target/ci-driver 2,133,805,759 against 1,757,640,523, target/debug 4,211,395,739 against 3,909,175,987, userland/target/debug 566,708,306 against 378,489,954, userland/target/x86_64-unknown-linux-gnu 1,061,961,498 against 951,246,596. The three kinds named sum correctly; every build script's binary, stored under two names in build/ (225,531,894 listed against 117,351,174 in the driver's alone), is left out.
  • issues/the-host-caches-limit-reaches-the-10-gb-only-through-one-measured-ratio.md:60 — "Two gates that red:" now heads three items, and the third is no gate.
  • issues/a-host-reader-on-another-runner-image-downloads-the-entry-and-discards-it.md:17 — "the 5 a reader of its own image's entry took in run 37693139619" was a replay over the sealed tree in place: no restore, and ~/.cargo/registry/src kept. The PR's own host check is now a real one: run 37713267864 restored 1,813,819,887 B in 24 s and ran cargo run -- --ci host in 16 min 57 s against an entry 30 landings old.
  • PR body, "What One workspace, one lock: the root, the kernel, the loader, userland and the SDK resolve together #746 must do" — "when it resolves the conflict on the path list": git merge-tree --write-tree 7f991fbad origin/wt/toyos-oneworkspace (db55db96a) writes a tree with no conflict; both env: lines and the shortened carry() survive untouched.
  • PR body, "Gates" — the host check of this head is not in it: run 37713267864, job 113103856303, image 20260927.320.1, Cache restored from key: host-sealed-Linux-X64-37190643147, built from d47b383cf…: 203 of 2501 sources dated as built, [ci] Host: 78 step(s), all green, conclusion success; toolchain / build and guest / suite success in the same run. It is cargo run -- --ci host on Linux at this head, and the first run of ci.yml's changed job.
  • PR body, the table of directories — its byte column is du -sb, which counts a hard link once, and sums to 7,474,339,777 B; the seal counted 8,608,140,775 B over the same tree. The column is not what LIMIT judges.

Growth

7 files changed, 87 insertions(+), 16 deletions(-). Production: src/ci.rs carry() −4; the two workflows +2 settings and +4 net comment lines. Tests: src/ci.rs +3 −4. Prompt +3 −3. Issues +71 −1. Accepted: the setting moves, nothing is added.

What was asked

Root cause. Measured as stated, by units: between the last green nightly (37190643147, d47b383cf) and the first red (37292450697, f260e0b98) thirty pull requests landed, and the steps that grew are the driver's build (111 to 203), the build system (115 to 207) and clippy (320 to 414); every other step together compiled 37 fewer. There is no listing of the tree before #722, so the bytes per directory of the growth are not measured, only its sum, 934,939,652 B on one image.

The fix is the cheapest part, not the growth. It removes 944,362,661 B (same image, same 18,712 files) of full debuginfo in target/ci-driver, which was there before #722 too. The gix closure is still built twice and linted once, and stays in the entry. The tree is now 57,934,041 B above the last green one: the margin was 394,155,927 B before #722 and is 336,221,886 B after this. What still carries the bytes, by run 37693139619's listing: target/debug's 240 test binaries, 2,708,603,504 B; names counted twice, at least 977,318,242 B; the driver's incremental state, 409,998,048 B before this change.

What is lost. Nothing a reader or a failing run uses. Every step already built with line tables alone; only the driver's own build changes. A panic's backtrace keeps function, file and line. Variable and type DWARF for a debugger attached to the driver on a hosted runner goes, and nothing attaches one. A developer's build is untouched: the setting exists only in two jobs' env:; portability-linux and portability-macos do not have it.

The margin. 4.2 % on image 20260927.320.1, measured on a base three landings behind main. #722 cost about 10 MB a unit across the three steps, so some 33 units of a build-system dependency use it up. On 20261004.327.1 this head is unmeasured: f260e0b98 sealed 357,843,252 B and 1,241 files less there with the same 961 compiled and 843 checked units, and nothing in the logs says why; the hosted stable is not pinned and neither log prints it. #746 is already known to pass the limit.

One source of truth or two. Two declarations and one sentence: ci.yml, nightly.yml, and the Caches clause that holds them equal, the same standing CARGO_TARGET_DIR and the path list have. Before, the steps' setting was one line of code under a test. A writer that loses it reds at the seal while the margin is thinner than the debuginfo. A reader that loses it reds nothing: the entry is restored, every unit is rebuilt, the check is green and slow. Only the review catches that.

The two issues. Both have an owner that exists and an exit a reader can check. The reader issue's first exit arm contradicts src/cicache.rs's header as it stands ("the cache key cannot carry the image"); the second arm is the one reachable without a redesign.

#746. It must rebase onto this, dispatch nightly.yml on its branch and show a seal line under LIMIT before it lands; 8,404,173,684 B is arithmetic from a run before this change. Its merge needs no hand on these lines. What this PR does not say: #746 changes the path list, which is the cache's version, so the entry the next nightly saves is unreadable from the moment #746 lands, and every host check is cold until a nightly after it seals green. If #746 lands before the next scheduled nightly, this fix is never observed on main.

What main must show for the red to count as fixed. As of this review main's latest nightly is 37601225884, failure. Fixed is:

  1. the next scheduled nightly on main, at or after this merge: host success, its seal line with bytes under 8,000,000,000 and the image named, and the save step run rather than skipped, with the key host-sealed-Linux-X64-<run id> and the stored size, which joins the ratios in the limit's issue;
  2. the first ci.yml host after it on that image: Cache restored from key: naming that run, built from <the merge commit>, and the driver's Finished in seconds rather than two minutes, which is the first measurement that the reader's env: matches the writer's; a reader that draws the other image and logs deleted: the run is cold shows nothing;
  3. toolchain / build on main after that save still restoring its four layers: the repository's caches stood at 10,948,823,786 B before it.

LAND

@Japabu
Japabu added this pull request to the merge queue Oct 8, 2026
Merged via the queue into main with commit b432ed2 Oct 8, 2026
12 checks passed
@Japabu
Japabu deleted the wt/toyos-nightlyseal branch October 8, 2026 02:15
Japabu added a commit that referenced this pull request Oct 8, 2026
…workspace

Git merged every file without a conflict. #752's two `env:` lines
(`CARGO_PROFILE_DEV_DEBUG: line-tables-only` in both workflows' `host`
jobs) and its shortened `carry()` survive as it wrote them. No manifest
and no lock moved, so `Cargo.lock` is unchanged.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RvnWQFcMuGqTHYhvSnTe8A
github-merge-queue Bot pushed a commit that referenced this pull request Oct 8, 2026
…nd the SDK resolve together (#746)

Stage 3 of `issues/the-tree-says-who-uses-each-thing.md`. The root,
`kernel/`, `bootloader/`, `userland/` and `toyos/` were five Cargo
resolutions; they are one workspace with one `Cargo.lock`, one
`[profile.toyos]`, one `[patch]` table and one tracked
`.cargo/config.toml`. No directory moves.

Head `dd12c0b32`, on `origin/main` `6f87cdb9c` (#749; none of #757, #759
or #762 had landed when it was merged and measured). It is `9ef866436`,
where the CI readings of the fold itself were taken, plus two merges of
`main` and the close of the stage's issue. Everything owed at the merged
head is in the next section, measured at `dd12c0b32`.

## The merge of #749, measured at `dd12c0b32`

#749 wrote its new dependency edges into `kernel/Cargo.lock` and
`userland/Cargo.lock`, which this branch deletes. Both modify/delete
conflicts are resolved by deleting the file and re-resolving the root
lock. Git merged the root `Cargo.lock` without a conflict into a lock
that is wrong, as the review found: `cargo metadata --locked` on it
exits 101 (`cannot update the lock file … because --locked was passed`).
It had `toyos-userbound`'s edges to `toyos-abi` and `toyos-bootmap`,
which #749 also wrote into the root lock, and not `acpiserver`'s to
`toyos-acpi` and `toyos-aml`, which #749 wrote into userland's alone.
`cargo metadata --offline` re-resolved it. `diff` of git's merged lock
against the re-resolved one is those two lines under `acpiserver` and
nothing else: no package added, no version moved.

| Owed | Command | Result |
|---|---|---|
| The lock resolves as committed | `cargo metadata --locked
--format-version 1` | exit 0 at this head by the host suite's step "the
licences of what ships", which runs `cargo metadata --locked` for every
shipped crate's manifest and is green in `host.log` and in run
37757675374; the hand run's empty stderr (`metadata-locked.err`)
predates the merge commit and recorded no exit |
| The lock's (name, version) pairs are the union of `main`'s five |
`pairs.sh <worktree> 6f87cdb`: the pairs of `Cargo.lock`, `kernel/`,
`bootloader/`, `userland/` and `toyos/Cargo.lock` at `6f87cdb9c`, `sort
-u`, against the root lock's | 692 against 692, `diff` exit 0
(`pairs.out`) |
| The folded kernel and loader are the control's bytes | `prove.sh
6f87cdb dd12c0b …`, the round 3 script unchanged | exit 0; all four
`control vs fold` byte rows `cmp` exit 0; every row in "The checks"
below (`prove.out`) |
| No new reader of a compiled-in path | `git diff -U0 e3bdff8
dd12c0b -- tests src toyos-blackbox toyos-symbols userland/symbolize`,
its added lines searched for `\.rs`, `taken at`, `panicked at`,
`Location`, `file()`, `PREVIOUS_PANIC`, `strip_prefix`, `src/`, `pure/`
| the merge touches five files there, all under `tests/`; 13 hits, of
which 4 are diff headers and 9 the field `info.rsdp`; none reads a path.
`tests/common/power.rs:429` is still the one reader outside fixtures,
and reads `taken at kernel/src/hardlockup/probe.rs`
(`readers-merge.diff`, `readers-hits.txt`) |
| `cargo run -- --ci host`, once, on the development machine | at
`dd12c0b32`, `cargo run -- --ci host > host.log 2>&1; echo EXIT=$?` |
exit 0; the log ends `[ci] Host: 77 step(s), all green`; 1-minute load
26.60 when it started (`host.log`) |

The logs are in the round's scratch directory (`orch/oneworkspace-r4/`),
which a reader of this pull request cannot reach; `prove.out` and
`pairs.sh` are in the round 4 comment.

## What changed, per decision

- **Members.** `kernel`, `bootloader`, `toyos` and userland's 40
packages join the root `[workspace]`. `userland/Cargo.toml`, four locks,
three `rust-toolchain.toml` and three per-directory `.cargo/config.toml`
are deleted. The toolchain files chose nothing the build read: every
guest `cargo` already runs under `RUSTUP_TOOLCHAIN` naming its sysroot.
- **Flags.** `build.target` is gone, since every guest build already
passes `--target`. The root config holds one `[target.<triple>]` table
per guest triple, six, each with the flags its directory's config gave
it. A host build takes none, as before. Two things do change:
- The guest crates outside the workspace that are built from their own
directory for a ToyOS triple (`tests/toyos-rust-tests` and its `tls-*`
crates) now take `-Dwarnings`, because cargo reads the tracked root
config from above them. On a checkout without a local config they took
no flags.
- The one build that sets `RUSTFLAGS` itself (the test binaries linked
against a `cdylib`, `src/build.rs`) takes none of the table: the
variable replaces it.
- **Profiles.** The root's `[profile.dev]` is `opt-level = 2`. The
kernel library's host tests, its model controls, the SDK's tests and
every surveyed userland crate's host tests used to resolve in their own
workspaces and ran at `opt-level = 0`; they now run at 2.
- **What stays apart** (the root manifest's `exclude` says why at each
entry): `rust/`; `tests/toyos-rust-tests` and its `tls-*` crates and
`tests/ssh-client-host`, because `[patch]` is workspace-wide and they
patch or refuse what the root patches; and `userland/libc`. libc keeps
its own lock because that lock is an input of the sysroot key: as a
member it would be resolved by the root lock, and every dependency
change of any member would move the key and rebuild every sysroot. The
price is a sixth resolution of `toyos`, `toyos-abi`, `toyos-elf`,
`toyos-osrelease` and `dlmalloc` that nothing holds to the root's (both
carry `dlmalloc` 0.2.13 today).
- **The lock** is every `[[package]]` of the five locks, deduplicated
and resolved by `cargo metadata`. Nothing was `cargo update`d. Since the
lock reviewed at `88bcbf4d3` it has changed by #749's four edges alone
(see the section above); `cargo metadata --locked` exits 0 at this head.
- **One target directory.** Every guest is built at the root with `-p`
into `target/`. A stale sysroot used to `cargo clean` a crate's own
target; that would now empty the build system's own, so `Stale::All`
removes `target/toyos` and the guest triples' directories instead, and
the `cargo clean` path, its member assertion and its test are deleted.
- **Kernel and loader build one after the other.** They were built on
two threads. In one target directory cargo serialises them anyway
(measured in round 1: the second prints `Blocking waiting for file lock
on artifact directory`), so the thread scope is deleted.
- **The host suite** can no longer be `--workspace`: the kernel binary,
the loader and most of userland do not build for a host. `src/hostws.rs`
says which members a host tests, and the workspace test and clippy runs
`--exclude` the rest by package name.
- **Fork clones.** The tracked config includes the gitignored
`.cargo/local.toml` when it exists, and `implementer.md` names it.
- **The merge of #745.** `src/sysroot.rs` keeps both sides:
`SYSROOT_SOURCES` carries `"sdk/std"` and `SYSROOT_MANIFESTS` ends in
`".cargo/config.toml"`; its test keeps both loops;
`issues/toyos-has-its-own-allocator.md` keeps `sdk/std/sys/alloc.rs` and
"from the kernel's graph in `Cargo.lock`". Git merged all three without
a conflict.
- **The host's own apps build where the userland tests build.**
`src/ci.rs`'s apps step passes `--target` only where it checks another
host's triple. On `main` the `userland/*` test steps and the host's apps
step both named the host triple and shared `userland/target/<host
triple>`. The fold took `--target` off the test steps, which no longer
need it to keep a guest triple out, and left it on the apps step: the
tests filled `target/debug`, the apps `target/<host triple>`, and every
dependency was compiled twice. That is what made the sealed tree larger
than `main`'s (see CI).
- **The merges of `main`.** #747, #748, #750, #751, #753 and #755 merged
without a conflict. #749 did not: see the section above.
- **The merge of #752.** Git merged it without a conflict: both
workflows' `host` jobs keep `CARGO_PROFILE_DEV_DEBUG: line-tables-only`
in `env:`, and `carry()` no longer sets it. No manifest and no lock
moved in the merge.
- **Issues.**
`issues/the-tree-resolves-in-five-cargo-locks-not-one.md` is deleted:
the one thing it named as left, the T14's run of the metal profile on
the folded build, ran green at `db55db96a`, and review round 2 ruled no
boot owed for what followed on two conditions, both in the section
above. Stages 2 and 3 of `issues/the-tree-says-who-uses-each-thing.md`
now read "Landed in #724, #732 and #738" and "Landed in #746". What the
file carried that stays true is the root manifest's `exclude`, which
says why each excluded directory keeps its own resolution; the deleting
commit's message carries the rest (libc's second resolution of five
crates, and `miniz_oxide` 0.8.9 beside 0.9.1 until `png` takes 0.9).
`issues/cargo-run-inside-kernel-loom-or-kernel-sim-builds-for-a-bare-target.md`
is closed on the two in-directory runs at `9ef866436`.
`issues/the-sdk-is-linted-by-no-clippy-run.md` is filed and names its
owner, the build system.

## The fold changed the kernel's source paths, and the proof did not see
it

The T14's run of the whole metal profile at `88bcbf4d3` exited 1: 295
passed, 1 failed, 30 boots. The red row was
`hard_lockup_ends_a_deaf_cpu`. Its judge looked for `taken at
src/hardlockup/probe.rs` in the previous boot's panic record, and the
readback's loader log says `taken at
kernel/src/hardlockup/probe.rs:145:29`.

**What changed in the kernel's strings.** Cargo hands rustc a workspace
member's source by its path from the workspace root, and rustc writes
that path into every panic and `Location`. The kernel's root was
`kernel/`; it is now the repository. So `src/...` became
`kernel/src/...`, and a path dependency outside the old root, which the
base named by the checkout's absolute path, is now named from the
repository root (`toyos-abi/src/...`). Read from the actuator kernel
staged at this head: 254 distinct `.rs` paths, 158 under `kernel/`, 38
under a `toyos-*` crate or `bcachefs`, none bare `src/` or `pure/`, none
naming the worktree.

**Why the proof did not see it.** Both of its oracles were blind to it
by construction:
- The byte row compared the fold against a control that is the base with
its workspace root moved up. The control moved the root too, so it
carries the same new paths and the bytes agree.
- The `rustc`-lines row compared base against fold after a `sed` that
rewrites `(kernel/|bootloader/)?(src|pure)/x.rs` and
`ROOT/<crate>/src/lib.rs` to one form. That rewrite is needed, or every
path crate's line differs and the row can show nothing else; but it
absorbed the change without reporting it.

`prove.sh` now reports what that rewrite absorbs: per artifact, how many
crates' source arguments were renamed, and a diff of the `.rs` paths the
artifact carries, base against fold and control against fold. The script
is in the round 3 comment and has run twice since, at `9ef866436` and at
this head.

**Every reader of a compiled-in path.** I searched the harness, the
guest tests, the build system, `toyos-blackbox`, `toyos-symbols`,
`userland/symbolize`, the loader and the kernel's panic path for path
literals, prefix strips and `Location` readers. One reader matches a
compiled-in path by its prefix: `tests/common/power.rs`, the red row's
judge, now fixed to the path the kernel records. Everything else is
prefix-blind (`panicked at`, a file name with its line) or a synthetic
fixture. The kernel's panic slot keeps the last 96 bytes of a path; the
longest kernel path is 46, so nothing is cut. Userland's panic sites
gain a `userland/` prefix the same way; no test reads one.

**The record rows.** The judging asked to record three
`boot.testcases-bounds.*` rows. They are not this change's: that boot
was already staged on the base and unrecorded, and `main` recorded it in
#745. They arrive with the merge and nothing is committed here.

## What the fold changes in what is built

The lock row was measured at `dd12c0b32` against `6f87cdb9c`, the
`rustc` row by `prove.sh` at the same pair; the two `cargo tree` rows at
`88bcbf4d3`, and were not taken again.

| Measured | Result |
|---|---|
| Lock: (name, version) pairs, the fold's against the union of
`origin/main`'s five | identical, 692 pairs, `diff` exit 0 |
| Lock: sources | registry `getrandom` 0.2.17, 0.3.4, 0.4.2 are gone;
the forks at the same versions remain |
| Kernel and loader, both arches: every `rustc` command line of `cargo
build -v`, base against fold, path and cargo's path-derived hashes taken
out | identical, `diff` exit 0: 31 units per kernel, 55 and 37 per
loader |
| Userland, both triples: `cargo tree -e features` over every program,
base against fold | identical, `cmp` exit 0 |
| Host members: the same | `diff` exit 1, on `getrandom`'s source alone
|

So one resolved crate changes: the build system and the other host
members compile the ToyOS forks of `getrandom` 0.2.17, 0.3.4 and 0.4.2
instead of the registry's, same versions, same features. And every
source path compiled into the kernel and the loader changes, as above.

## The checks (high-risk: build system)

Measured at `dd12c0b32` against `origin/main` `6f87cdb9c` by `prove.sh`
(the script of the round 3 comment, unchanged), exit 0; its output is in
the round 4 comment. Round 3 measured the same rows at `9ef866436`
against `b432ed21c`, round 1 at `88bcbf4d3` against `e7010129f`.

**Negative control.** The whole change reverted is the base. A second
control is the base with only its workspace root moved up, keeping the
crate's own base lock and its profile. It is given the fold's root
`.cargo/config.toml`, so the control does not hold the flags: the one
row that does is base against fold on normalised `rustc` lines.

**Oracle.** Bytes and cargo's own command lines. Each cell is its own
`cmp` or `diff` exit:

| | kernel x86_64 | kernel AArch64 | loader x86_64 | loader AArch64 |
|---|---|---|---|---|
| control vs fold, bytes | 0 | 0 | 0 | 0 |
| fold vs fold rebuilt, bytes | 0 | 0 | 0 | 0 |
| base vs fold, bytes | 1 | 1 | 1 | 1 |
| base vs fold, `rustc` lines normalised | 0 | 0 | 0 | 0 |
| control vs fold, `rustc` lines verbatim | 0 | 0 | 0 | 0 |

What the normalisation absorbs, reported by the three `paths` rows: base
against fold, cargo hands rustc another source path for 29 of 31 crates
of each kernel and for 35 of 50 and 13 of 35 crates of the loaders
(`diff` exit 1 each, as expected); the `.rs` paths the x86-64 kernel
carries are 250 on both sides, of which the base has 39 under the tree's
absolute path and 150 from the crate's own root and the fold none of
either (`diff` exit 1); control against fold the artifacts' paths are
identical (`diff` exit 0, all four).

**Mutations**, each
on a fresh copy of the fold: M1 (drop the `[target.x86_64-unknown-uefi]`
table) loader build exit 101; M2 (lock `dlmalloc` at 0.2.12) `cmp` exit
1 and lines `diff` exit 1; M3 (select `bcachefs` beside the kernel in
one `cargo`) kernel build exit 101.

## Gates

The rows of the section "The merge of #749" were read at `dd12c0b32`.
Every row below was read at `9ef866436` unless it says otherwise, each
once, the narrowest that judges it. `ci.yml` runs on the push of
`dd12c0b32`; its result is not in this body.

| Gate | Result |
|---|---|
| `cargo run -- --ci host` | at `dd12c0b32`, development machine: exit
0, `[ci] Host: 77 step(s), all green`. Linux runner at `9ef866436`:
`ci.yml` run 37740454881 `host` success; cold inside `--ci seal`,
nightly run 37740449787: `[ci] Seal: 80 step(s), all green`; on macOS,
the same nightly's `portability-macos`: success |
| `cargo test --lib ci::tests` (the changed step's own test) | exit 0,
13 passed |
| The images and the guest suite | at `9ef866436`, run 37740454881:
`toolchain / build` and `guest / suite` success (KVM); run 37740449787:
`toolchain / build` and `tcg / suite` success. At `e3bdff8af`, run
37755369755: `host` and `toolchain / build` success, `guest / suite`
still running when read. Not run locally, and not read at `dd12c0b32` |
| `prove.sh 6f87cdb dd12c0b …` | exit 0; every row as in the table
above |
| `cargo test` inside `kernel/loom` | exit 0 |
| `cargo test` inside `kernel/sim` | exit 0 |
| Cold wall clock, x86-64 kernel and loader (`wall.sh`, one run) | base,
two cargos side by side: 24 s, 1-minute load 34.92 before it. Fold, one
after the other: 20 s, load 42.23. Other agents' builds were running, so
the two are not a controlled pair; the fold was not slower |
| Metal profile | every row green at `db55db96a` (comment 6048782042).
Since then the branch changed `src/ci.rs` and the root lock's two
`acpiserver` edges; the kernel sources that moved are `main`'s own
landings (#747, #748, #749), merged in. Review round 2, ruling (3), owes
no boot for the merge of #749 on two conditions, both met above |
| `cargo test --manifest-path userland/acpiserver/aml/Cargo.toml` at
`e3bdff8af` | exit 0 |
| `git status --porcelain --ignore-submodules=none` at `dd12c0b32` |
empty |

`issues/cargo-run-inside-kernel-loom-or-kernel-sim-builds-for-a-bare-target.md`'s
close now stands on the two in-directory runs at `9ef866436`.

The logs of these rows are files in the scratch directory of the round
that took them (`orch/oneworkspace-r3/`), which a reader of this pull
request cannot reach; the proof's and the measurements' outputs are in
the round 3 comment.

## CI

**Why the sealed tree was larger than `main`'s, measured.** A
`workflow_dispatch` of `nightly.yml` at `88bcbf4d3` (run 37685714260)
sealed `9348536345 B in 20064 files`, red. Units compiled per step,
counted from that log and from `main`'s nightly at `b432ed21c` (run
37717000719, sealed `18708 files, 7664839895 B`):

| step | `88bcbf4d3` | `main` |
|---|---|---|
| the driver's own build | 203 | 203 |
| the build system | 207 | 207 |
| the workspace's host members | 99 | 99 |
| clippy, warnings denied | 412 | 417 |
| the controls | 56 | 56 |
| `userland/*` | 225 | 289 |
| the apps for linux | 282 | 47 |
| the apps for macos | 248 | 248 |
| the apps for windows | 239 | 239 |

Of the 256 distinct crates the apps-for-linux step compiled at
`88bcbf4d3`, 226 had been compiled by an earlier step of the same run;
30 by none. The cause is the target directory: the test steps built
without `--target` into `target/debug`, the apps step with `--target
x86_64-unknown-linux-gnu` into `target/x86_64-unknown-linux-gnu`.
Profile, features and `RUSTFLAGS` are the same in both.

**The fix, measured once on the development machine** (`share.sh` in the
round 3 comment; cold, a target of its own, `aarch64-apple-darwin`):
after the fourteen test steps' builds (271 units), the ten apps with
`--target <host>` compile 270 units and add 616,616 KiB under
`target/<host>` and 135,064 KiB under `target/debug`; the same ten
without `--target` then compile 47 units and add 107,856 KiB. The 47 are
the same crates `main`'s step compiles on the runner.

**The seal at `9ef866436`, nightly run 37740449787** (conclusion
success: `host`, `portability-linux`, `portability-macos`, `toolchain /
build`, `tcg / suite`):

```
the cache entry, read by content: none restored: the run is cold
the apps for linux: 10 app(s) pass `cargo build`; …
the tree, sealed as the host cache's entry: 17010 files, 7493968284 B of the 8000000000 B an entry may hold; sealed: 2496 sources, built on Linux X64 ubuntu24 20261004.327.1, every target dated as built
[ci] Seal: 80 step(s), all green
```

Units per step in its log, against the two columns above:

| step | `9ef866436` | `88bcbf4d3` | `main` |
|---|---|---|---|
| `userland/*` | 225 | 225 | 289 |
| the apps for linux | 42 | 282 | 47 |
| the apps for macos | 264 | 248 | 248 |
| the apps for windows | 240 | 239 | 239 |

Every other step compiles what it did at `88bcbf4d3`. I expected 47 for
the Linux apps: it is `main`'s 47 less `crc32fast`, `log`, `memchr`,
`smallvec` and `toyos-keymap`, which an earlier step had compiled. I did
not expect the macOS step's 16 more: all are host-side units (`syn`,
`thiserror-impl`, `tokio-macros`, `futures-macro`, `autocfg` and the
like), which the Linux step's `--target` build used to compile for the
host and which the first `--target` step now compiles instead. The four
steps together compile 771 units against 994 at `88bcbf4d3` and 823 on
`main`.

- Margin: 506,031,716 B under the limit, 6.3 %, on image 20261004.327.1.
`main`'s 7,664,839,895 B was sealed on 20260927.320.1. The one pair of
figures there is for the two images is `f260e0b98`, built with full
debuginfo before #752 cut it to line tables: 8,540,783,725 B on
20260927.320.1 (run 37292450697) against 8,182,940,473 B on
20261004.327.1 (run 37601225884), 357,843,252 B or 4.2 % less on the
newer. So this head's figure and `main`'s are not a pair, and this head
is unmeasured on the older image.
- Against the same branch before the fix and before #752: 9,348,536,345
B at `88bcbf4d3` on 20260927.320.1.

**`ci.yml` run 37740454881 at `9ef866436`:** `host`, `toolchain / build`
and `guest / suite` success.

After this lands every `host` check runs cold until the first nightly on
`main` seals and saves: the path list is the cache's version.

**Toolchain keys.** The fold moves the sysroot key once:
`userland/.cargo/config.toml` was one of its inputs and
`.cargo/config.toml` replaces it. From now on a change to any guest
triple's flags moves that key. The merges of #747 and #749 moved
`toyos-abi` and `toyos`, so the sysroot key moved with `main`; the key
at this head was not read here.

## No new gate, test or dependency

No guest test is added or changed. No dependency is added. The proof is
a one-off script because its subject is this one change against its
base.

## Size

`git diff --shortstat origin/main...HEAD` at `dd12c0b32`: 53 files,
+5454 −7765. Without the locks: 48 files, +446 −704. `src/`,
`tests/toyos.rs` and `tests/common/`: 12 files, +237 −360, of which
tests are roughly +65 −115 by my reading of the hunks (an estimate, not
a count). `issues/`: 16 files, +49 −115.

## What I am unsure of

- **The seal on the older runner image.** GitHub serves two; this branch
was sealed on the newer one, at `9ef866436`. The only pair of figures
for the two is `f260e0b98` with full debuginfo (above): the older image
sealed it 357,843,252 B larger. Carried unscaled onto this tree that
leaves 148,188,464 B under the limit on the older image; scaled by the
pair's ratio, about 178 MB. Both are arithmetic, not a run.
- **`dd12c0b32` itself:** `ci.yml` run 37757675374 has `host` and
`toolchain / build` success at it; its `guest / suite` is what the
landing waits on. #757 (`b6bcb9691`) landed on `main` after this head
was merged and measured: ten source files under `kernel/src`,
`toyos-abi/src`, `toyos-userbound/src` and `tests/toyos-rust-tests`, no
manifest and no lock; `git merge-tree --write-tree dd12c0b b6bcb96`
exits 0. Nothing here was measured with it in. It differs from the
sealed head by `main`'s #749, #750, #753 and #755 and the root lock's
two edges; the seal's byte count at this head is unmeasured.
- **Build wall clock.** One run under load; the fold was not slower.
- **Clippy reaches further.** The bare-target shapes now also lint the
kernel's and the loader's path dependencies for those targets.
- **The licence gate reads a superset.** `--all-features` for the kernel
now turns on every member's features. It judges more than ships.
- **The runner's cargo.** The nightly's `host` at `88bcbf4d3` parsed the
optional `include`, so the runner's cargo accepts it.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

https://claude.ai/code/session_01RvnWQFcMuGqTHYhvSnTe8A
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