Repository-wide bug sweep: fail-closed xtask, honest comments, dead configuration removed - #19
Open
MatejGomboc wants to merge 7 commits into
Open
Repository-wide bug sweep: fail-closed xtask, honest comments, dead configuration removed#19MatejGomboc wants to merge 7 commits into
MatejGomboc wants to merge 7 commits into
Conversation
boot-test no longer pipes QEMU's stderr into a pipe nobody drains — it is inherited, so an emulator-side failure is visible instead of deadlocking into a bogus timeout — and stdin is nulled so the stdio chardev cannot leave an interactive terminal in raw mode after the SIGKILL reap. When QEMU dies before producing console output, the failure now names the emulator and its exit status rather than blaming the kernel's link script for a timeout that never elapsed. Argument parsing fails closed: a flag without a usable value is an error rather than silently swallowing the next flag or falling back to a default, and unrecognised tokens (typos, the unsupported --flag=value form) are rejected instead of ignored. Trade-off recorded: an --expect string beginning with "--" becomes inexpressible; none exists today. Seven unit tests cover the pure helpers, so CI's cargo test --package xtask gate verifies something for the first time. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The changelog's claim that the exhaustive sweep proves a dangling handle "can neither use nor steal a reused slot's occupant" for both resolve and remove was ahead of the test, which swept only resolve. Extend the sweep's else branch so every forged (index, generation) pair is also denied at remove — safe inside the loop because a failing remove restores the slot state before returning. The record is now true as written. The churn test's comment also now says which assertions run per drawn operation and which after every step, instead of claiming all four run every step. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
StaleGeneration's doc named only the slot-vs-handle cause: the variant is also what resolve and derive return when the object itself was destroyed (the destruction half of O-3), and the "has been closed" cause it named actually reports Empty until the slot is reused. The DUPLICATE right now points at Capability::derive, the operation that actually consumes it, rather than diminish, which never checks it. Union's O-2 note said it is never applied to "narrow" a held capability where the risk it dismisses is widening. The compile_fail doctest's comment no longer claims to catch any bounded Clone impl — only those bounded by traits an object reference satisfies, which is the instantiation the kernel will use. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…architecture Two comments credited "QEMU's firmware" with configuring the PL011 — no firmware runs in the -kernel boot path (boot.s names the built-in loader correctly); the console works because QEMU's PL011 model transmits without initialisation. The x86_64 placeholder claimed AArch64 needs no stack before its first print, contradicting boot.s, which installs one before anything else. The SPSel comments in vectors.s claimed the msr is what keeps an SP_EL0-group entry off the uninitialised SP_EL0; per the architecture, exception entry already sets PSTATE.SP to 1, the vector group records the interrupted context's selection, and the msr is defence in depth. The feature comment in kernel/Cargo.toml quoted a boot-test invocation that fails as written (--expect is mandatory). Stale "CLAUDE.md §N" citations now point at CONSTITUTION.md, where the numbered sections live, and build.rs gains the SPDX header every other Rust file carries. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The aarch64 debug config in launch.json pointed at the pre-softfloat target directory, silently loading stale symbols; it now names aarch64-unknown-none-softfloat. rust-toolchain.toml's header instructed bumping a dtolnay/rust-toolchain workflow pin that no longer exists and that check-toolchain-pin.sh itself forbids — it now names the two real places, and dependabot.yml agrees. The pin check's hand-install detector was anchored to line starts and so could never match the idiom it exists to catch (curl ... sh.rustup.rs | sh inside a block scalar); it is now unanchored. ci_main.yml's checks job dropped a dead ghcr login: the job never pushes and the cache image pulls anonymously, as ci_pr.yml already proves on every pull request. The cache-cleanup workflow and script are deleted: no workflow here uses actions/cache, the script's header described another repository's cache groups, and absent beats disabled. .gitignore's /gdb-history entry matched a file GDB never writes and now ignores .gdb_history; .gitattributes' *.S force-text rule never matched this repo's lowercase .s assembly on case-sensitive filesystems and now covers both spellings. The devcontainer's history volume gains the HISTFILE that actually makes bash write into it. The two CI scripts gain SPDX headers, and the stale "CLAUDE.md §N" citations across the config files now point at CONSTITUTION.md, where the numbered sections live. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
All four are mechanical — a citation pointing at the wrong section or the wrong document, changing nothing any document decides. RFC-0003 §11 cited the open questions as §13, which is Obligations discharged; they are §14, as the RFC's own acceptance note and the capability crate both already said. RFC-0004 §14 said the scheduler RFC is what "§6 and §9.2 wait on", but §6 is capability transfer and names no scheduler dependency — the donation that waits on the scheduler is §4. The threat model's O-18 pointed at §7 for a deferral that lives in §9, and O-6 and §11 attributed to the constitution a module designation it does not make and to RFC-0002 a practice it never states. Logged in docs/CHANGELOG.md rather than edited silently: an accepted document's body is a record. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The clippy command in CONTRIBUTING.md, the pull-request template and STYLE.md was unscoped: it lints the kernel for the host triple and never for either Tier-1 target, so it is neither what CI runs nor consistent with the same file's rule about always naming the package. It now points at the one canonical list, which gains the third workspace member CI has been gating on all along. The RFC guidance and /check-primitive still enumerated four graves after §3 grew to seven, so an audit run from either silently skipped three. README.md still advertised zero-copy page transfer for bulk data — the mechanism RFC-0004 pruned as L4's abandoned long IPC. Four files described the toolchain as pinned in three places. The testing table promised boot-test on both architectures, which xtask refuses and CI does not do. The feature-request template called Setonix a credential-handling project, boilerplate from another repository, and now asks the questions a capability kernel actually needs answered. The changelog's SPSel claim and CLAUDE.md's soft-float rationale are corrected to match the vectors the kernel now installs. Stale "CLAUDE.md §N" citations across fifteen files now name CONSTITUTION.md, where the numbered sections live; the PR template's unsafe-module checkbox goes the other way, since CLAUDE.md is what designates the modules and the constitution only requires that something does. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
A comprehensive bug hunt over the whole repository — source, tooling, configuration and documents — run as eight independent review passes, each finding then re-verified by a separate skeptic before anything was changed. Ninety-eight candidate findings were produced; 83 survived verification and are fixed here, 13 are flagged below as yours to decide, and 2 were refuted and dropped.
No kernel logic defect was found. The capability crate and the boot path both came through clean. What the sweep did find, in quantity, is a tree that had drifted from describing itself accurately — which for a project whose thesis is that divergent copies of a truth must be made structurally impossible is the defect class that matters most.
Explanation for the maintainer
Seven commits, each one logical group, reviewable in isolation:
fix(xtask)— the only behavioural code change.boot-testpiped QEMU's stderr into a pipe nobody drained: every emulator-side diagnostic was silently discarded, and enough output would have blocked QEMU on a full buffer and surfaced as a timeout blamed on your link script. stderr is now inherited; stdin is nulled so the stdio chardev cannot leave a terminal in raw mode after the unconditionalkill; and a QEMU that dies before the first console line now says so with its exit status. Argument parsing fails closed — a flag can no longer swallow the next flag as its value, a forgotten value is an error rather than a silent default, and unrecognised tokens are rejected (--arch=x86_64previously built aarch64 without a word). Trade-off recorded: an--expectstring beginning with--is now inexpressible; none exists today, and CI's invocations are unaffected.test(capability)— the forged-handle sweep now denies every forged(index, generation)pair atremoveas well asresolve, which is whatCHANGELOG.mdalready claimed of it. Safe inside the existing loop because a failingremoverestores slot state before returning. No new test function, so the twenty-seven count still holds.docs(capability)— three doc comments corrected against the code:StaleGenerationnamed only the slot-vs-handle cause (it is also whatresolve/derivereturn for a destroyed object — the O-3 half — while the "closed" case it named reportsEmpty);DUPLICATEpointed atdiminish, which never checks it, instead ofCapability::derive;union's O-2 note said "narrow" where the risk it dismisses is widening.fix(kernel)— comments that misdescribe the machine. Two credited "QEMU's firmware" with configuring the PL011, but no firmware runs in the-kernelpath at all; the console works because QEMU's device model transmits uninitialised, which is the load-bearing fact a future real-hardware port must not inherit wrongly. TheSPSelcomments claimed themsris what keeps an SP_EL0-group entry off the uninitialised SP_EL0 — per the architecture, exception entry already setsPSTATE.SP, the vector group records the interrupted context's stack, and the instruction is defence in depth. Plusbuild.rs's missing SPDX header.chore(infra)— configuration that could not do what it said. The aarch64 debug config pointed at the pre-soft-float target directory (a stale binary is still sitting there, so LLDB was silently loading outdated symbols).rust-toolchain.tomlinstructed bumping adtolnay/rust-toolchainpin thatcheck-toolchain-pin.shfails the build over — following the comment would break CI. That script's own hand-install detector was anchored to line starts and so could never matchcurl … sh.rustup.rs | shinside a block scalar, the form every workflow here uses.ci_main.yml's checks job had a dead ghcr login (the job never pushes, andci_pr.ymlproves the image pulls anonymously on every PR)..gitignoreignored a GDB history file GDB never writes;.gitattributes'*.Srule never matched this tree's lowercase.son the case-sensitive filesystems it exists for. Deletion:cleanup_caches.ymlandcleanup-caches.jsare removed — no workflow usesactions/cache, and the script's header describes another repository's cache groups and a "PR #150 sweep" in a 59-commit repo. Absent beats disabled, which is now one of §3's own graves.docs(accepted documents) — four mechanical cross-reference corrections, none touching what any document decides, each logged indocs/CHANGELOG.mdrather than edited silently. RFC-0003 §11 cited "§13" for the open questions (that is Obligations discharged; they are §14 — a typo present since the draft). RFC-0004 §14 said the scheduler RFC is what "§6 and §9.2 wait on", but §6 is capability transfer with no scheduler dependency; the donation is §4. Threat-model O-18 pointed at §7 for a deferral living in §9, and O-6/§11 attributed to the constitution a module designation it does not make and to RFC-0002 a practice it never states.docs(contributor documents) — the clippy command inCONTRIBUTING.md, the PR template andSTYLE.mdwas unscoped, linting the kernel for the host triple and never for either Tier-1 target: not what CI runs, and contradicting the same file's own "always name the package" rule. The RFC guidance and/check-primitivestill listed four graves after §3 grew to seven, so an audit run from either silently skipped three.README.mdstill advertised zero-copy page transfer for bulk data — the mechanism RFC-0004 pruned. Four files said the toolchain is pinned in three places. Twenty-nine "CLAUDE.md §N" citations across fifteen files now nameCONSTITUTION.md; the PR template's unsafe checkbox goes the other way, sinceCLAUDE.mdis what designates the modules and the constitution only requires that something does.Which pillar does this serve?
Mostly toil, in the honest sense — but toil that serves §5.2 and §5.4 directly: a document that misdescribes the system teaches its readers to discount the rest of it, and the xtask fixes remove a class of CI failure that lies about its own cause.
Flagged for you, not taken
Thirteen findings are yours to decide. Constitution text and the meaning of accepted RFCs are not mine to change:
Constitution (§3, §7) — the two that matter most:
README.md, which is freely editable, so the two now disagree until you rule.aarch64-unknown-none— the pre-soft-float triple the project documented as fatal (FP/SIMD withCPACR_EL1.FPEN= 0, dead before the first character) and replaced. The Dockerfile,rust-toolchain.tomland the pin check all install-softfloat; the constitution names the lethal one.Accepted RFCs (yours via dated amendment):
derive"records the parent" and "the kernel records" derivation — contradicting the flat table you built, which records nothing and has a test pinning that absence, and contradicting the RFC's own acceptance note deferring derivation records to RFC-0003a.docs/CHANGELOG.md:171faithfully transcribes the same wording, so both want correcting together.xtask judgement calls I took anyway — the three fail-closed parsing changes were verified as "real, but a design decision for the maintainer". I applied them because they sit with the project's fail-closed instincts everywhere else; say the word and I will revert any of them.
Borrow Ledger
build.rsand the two CI scripts gained the headers they lacked; novendor/tree exists yetunsaferegisterunsafeblocks: None. Nounsafeblock was added, removed or moved; only two descriptive comments invectors.schanged, and that file is assembly, not Rust.unsafeblock carries a// SAFETY:comment (n/a)unsafeblock is inside a module CLAUDE.md designates for it (unchanged)Checklist
aarch64-unknown-none-softfloatandx86_64-unknown-none)-D warningscargo fmt --all --check)bash .github/scripts/check-toolchain-pin.sh)bash .github/scripts/check-british-spelling.sh— 65 files)markdownlint-cli2 "**/*.md"— 0 issues in 21 files)provoke-exceptionself-testCHANGELOG.mdupdated under[Unreleased], anddocs/CHANGELOG.mdfor the document correctionsCONTRIBUTING.md)Related
Found by a repository-wide bug hunt on 2026-08-01: eight finder lenses, an independent skeptic pass per lens, and a completeness critic that swept what the lenses missed (SPDX headers,
.gitattributespatterns,Cargo.lock,README.md— which no lens had owned).🤖 Generated with Claude Code