From 7eb4428ddd4d4eb6aeb29da5ab307d214de00d51 Mon Sep 17 00:00:00 2001 From: japabu Date: Wed, 30 Sep 2026 23:30:45 +0200 Subject: [PATCH 1/2] issues: write the owner's rulings of 2026-09-30 where they govern The child-process track's fourteen questions are ruled as recommended, each written as one line at the stage it governs, and issues/kernel/the-child-process-track-waits-on-the-owners-rulings.md goes: - Q2, Q6d at stage 2: an end reads as an exit, a kill or a fault kind alike on every architecture, a bare code reads the last two as failures, and no end reads as a quit's reason. - Q3a, Q3b, Q3c at stage 3: libc imitates SIGCHLD; a handler runs at once, beside the program; a C child starts with descriptors 0-2 and what its file actions name, a stated departure from POSIX. - Q5a, Q5b, Q5c at stage 5: a login's session is a program that only parents what its user starts; init hands the compositor or sshd the right to start programs in it; sshd's right also quits and kills it. - Q6a, Q6b, Q6c, Q6e, Q6f at stage 6, whose text already said each as recommended: a quit carries interrupt, hang-up or terminate, reaches the subtree, kills a process that never listens, reaches a Rust program through std and ctrlc, and a C program as SIGINT, SIGHUP and SIGTERM. - Q7 at stage 7: a second Ctrl+C kills only a program that has not yet taken the first. Cut as moot: the pointer to the question file, the question labels on the stage headings, the Ruled block's session clause (now stage 5's line), stage 6's reason for the shell relaying nothing (now stage 6's reach line), and stage 7's "Stop and continue need a suspend primitive and are not proposed", which scoped the proposal the rulings closed. The track stays at 260 lines. The supervisor track's open item on the ask's ABI cited Q6a; Q6a is ruled and its stage 3 already asks by stage 6's quit, so the item goes. The rest: - The kernel is to load CPU microcode signed by the CPU's maker and pinned by version and hash, as vendor device firmware is. The question becomes the defect issues/kernel/the-kernel-loads-no-cpu-microcode.md, exit: current microcode loaded early on every CPU, at least as current as Linux's. The security track's list follows the rename. - std::os::toyos::io::{AsRawFd, FromRawFd} are renamed the next time the trait is touched in the fork: an open defect with that exit. - A boot start's device refusal is fatal only for a device the [programs] row marks as required; otherwise init logs it loudly and starts the program without it: an open defect whose exit is the row's mark and the two outcomes. - doomgeneric's fetch stays; its question file goes. - doom.jpg is the owner's own screenshot, which he keeps, and no licence question applies; its question file goes and its COMMITTED_FILES row says so in the column that names where its terms are recorded. The terms column stays NOASSERTION. - The blocked-task dump keeps painting its report on the panel and holding it there: one line at the small-kernel track's step 5 replaces that step's open question and stage 6's hold on it. Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_016t9wjdQkB8SH7bmfUoiy6L --- ...g-shows-ids-art-under-no-recorded-terms.md | 17 -- ...neric-becomes-a-submodule-is-the-owners.md | 20 -- ...efused-a-present-device-runs-without-it.md | 33 +- .../os-toyos-io-traits-keep-a-posix-name.md | 43 +-- ...rvisor-is-host-tested-and-owns-the-stop.md | 6 +- ...nt-and-a-parent-takes-its-children-down.md | 126 ++++---- ...ocess-track-waits-on-the-owners-rulings.md | 283 ------------------ ...s-linux-on-every-machine-toyos-supports.md | 2 +- ...-small-interrupts-post-and-threads-wait.md | 9 +- .../the-kernel-loads-no-cpu-microcode.md | 15 + ...ernel-loads-cpu-microcode-is-the-owners.md | 14 - src/licence.rs | 4 +- 12 files changed, 113 insertions(+), 459 deletions(-) delete mode 100644 issues/build/doom-jpg-shows-ids-art-under-no-recorded-terms.md delete mode 100644 issues/build/whether-doomgeneric-becomes-a-submodule-is-the-owners.md delete mode 100644 issues/kernel/the-child-process-track-waits-on-the-owners-rulings.md create mode 100644 issues/kernel/the-kernel-loads-no-cpu-microcode.md delete mode 100644 issues/kernel/whether-the-kernel-loads-cpu-microcode-is-the-owners.md diff --git a/issues/build/doom-jpg-shows-ids-art-under-no-recorded-terms.md b/issues/build/doom-jpg-shows-ids-art-under-no-recorded-terms.md deleted file mode 100644 index 518f966df5f..00000000000 --- a/issues/build/doom-jpg-shows-ids-art-under-no-recorded-terms.md +++ /dev/null @@ -1,17 +0,0 @@ ---- -status: owner -kind: question -opened: 2026-09-26 ---- - -# `doom.jpg` shows id's art, and nothing records the terms it is under - -`doom.jpg`, the screenshot `README.md` shows, is a picture of this system -running doom, so most of its pixels are `assets/DOOM1.WAD`'s graphics. -Its row in `COMMITTED_FILES` (`src/licence.rs`) declares `NOASSERTION`, -because the tree's `MIT OR Apache-2.0` does not reach id's art, and the -shareware terms in `NOTICE` do not name screenshots. No image -ships the file, so the licence gate does not judge it. - -**Exit**: the owner rules on the terms, and the row says them. Or the -screenshot is replaced by one that shows only this tree's own work. diff --git a/issues/build/whether-doomgeneric-becomes-a-submodule-is-the-owners.md b/issues/build/whether-doomgeneric-becomes-a-submodule-is-the-owners.md deleted file mode 100644 index 82fa7f73378..00000000000 --- a/issues/build/whether-doomgeneric-becomes-a-submodule-is-the-owners.md +++ /dev/null @@ -1,20 +0,0 @@ ---- -status: owner -kind: question -opened: 2026-09-29 ---- - -# Whether doomgeneric becomes a submodule is the owner's - -`userland/doom/build.rs` fetches doomgeneric's commit `fc601639` as a GitHub -archive into the gitignored `userland/doom/doomgeneric/` and compiles it. The -fetch costs five build-dependencies in `userland/doom/Cargo.toml` — `ureq`, -`rustls-rustcrypto`, `webpki-roots`, `flate2`, `tar` — and leaves a ToyOS -change to the C nowhere to live but that untracked directory, which the build -replaces whenever its stamp disagrees with the pin. A fork repository of -doomgeneric as a submodule at that path deletes the fetch and the five. Neither -`ToyOSOrg/doomgeneric` nor `Japabu/doomgeneric` exists (`gh repo view`), and -creating one is the owner's. - -**Exit**: the owner rules — the fetch stays, or a submodule on a repository he -creates replaces it. diff --git a/issues/design-debt/a-boot-start-refused-a-present-device-runs-without-it.md b/issues/design-debt/a-boot-start-refused-a-present-device-runs-without-it.md index 14ee6cc58f9..d252767e3e6 100644 --- a/issues/design-debt/a-boot-start-refused-a-present-device-runs-without-it.md +++ b/issues/design-debt/a-boot-start-refused-a-present-device-runs-without-it.md @@ -1,26 +1,21 @@ --- -status: owner -kind: question +status: open +kind: defect opened: 2026-09-24 --- # A boot start refused a device the machine has runs without it -`/system/bin/init`'s `start` mints every device a `[programs]` row names. At a -swap or the restart that rolls one back, a device the process being replaced -held and the new one is refused fails the start (`Served::Restart`'s `owed`). -At boot there is no process before it, and a refusal is said in the kernel's -own word (`init: netd: pci:8086:10c9 is on this machine and could not be -handed over`) and the program is started without that device. +A boot start's device refusal is fatal only for a device its `[programs]` row +marks as required; for any other, init logs the refusal loudly and starts the +program without that device (owner, 2026-09-30). No row can mark a device +required, so every boot start refused a device the machine has — +`NotSupported`, `AlreadyExists`, `ResourceExhausted` — runs without it: +`/system/bin/init`'s `start` says the refusal in the kernel's own word +(`init: netd: pci:8086:10c9 is on this machine and could not be handed over`) +and starts the program. `refused_claim` (`tests/common/faults.rs`) and +`pci_function_is_exclusive` assert that behaviour today. -That is not the swap's defect — init claims nothing about a boot start beyond -`started`, and a row names every device its program can drive, so a machine -with a subset is a configuration, not a fault — but a refusal other than -`NotFound` is a fault, and the program then runs on less than the machine -has. `tests/common/faults.rs`'s `refused_claim` and `pci_function_is_exclusive` -assert exactly this behaviour today. - -The question for the owner: should a boot start refused a device the machine -has — `NotSupported`, `AlreadyExists`, `ResourceExhausted` — be fatal? A failed -boot start is an init panic, so the machine would not boot over one device; -and a row cannot yet say which of its devices its program needs. +**Exit**: a `[programs]` row can mark a device required, and guest tests show +a boot start refused a required device is fatal, and one refused a device its +row does not mark logs it loudly and starts the program without it. diff --git a/issues/design-debt/os-toyos-io-traits-keep-a-posix-name.md b/issues/design-debt/os-toyos-io-traits-keep-a-posix-name.md index d76b3aeaa2e..df9885c522c 100644 --- a/issues/design-debt/os-toyos-io-traits-keep-a-posix-name.md +++ b/issues/design-debt/os-toyos-io-traits-keep-a-posix-name.md @@ -1,37 +1,18 @@ --- -status: owner -kind: question +status: open +kind: defect opened: 2026-08-24 --- -# Does `std::os::toyos::io` get to keep `AsRawFd`/`FromRawFd`? +# `std::os::toyos::io` names its raw-handle traits `AsRawFd` and `FromRawFd` -The owner ruled on 2026-08-19 that **"fds belong only in libc jargon"**: the -kernel has no file descriptors, a process holds typed handles -(`toyos-abi/src/handle.rs`), and `userland/libc` is the one layer whose -interface the word describes. The sweep that followed took the kernel, the ABI, -the SDK, every forced call site and both fork pins. One name it did not settle -is left, and it is the owner's because it is a fork-repo name (`Japabu/rust`) -and not this tree's to rename alone. +`os::toyos::*` is ToyOS's own extension API and speaks ToyOS, and "fds belong +only in libc jargon" (owner, 2026-08-19). The `rust/` fork's +`library/std/src/os/toyos/io.rs` re-exports `std::os::fd`, so +`std::os::toyos::io::{AsRawFd, FromRawFd}` still speak POSIX. +`tests/toyos-rust-tests/src/bin/std_fs.rs` is their one caller in this +repository. -`std::os::toyos::io::{AsRawFd, FromRawFd}`. The naming table ruled that -`os::toyos::*` is ToyOS's own extension API and must speak ToyOS, and it named -every `process` row — but not this one. std's *POSIX* surface keeps the word by -charter; whether an `os::toyos` trait carrying a POSIX name is that surface or -the extension API is what nobody has decided. - -The two answers, both defensible: - -- **It stays**, as a deliberate mirror of std's own - `std::os::unix::io::{AsRawFd, FromRawFd}` convention — the trait names an - `os::toyos` caller reaches for by muscle memory, and diverging costs every - such caller a lookup. -- **It is renamed the next time the trait is touched in the fork**, to whatever - `os::toyos` decides its own non-POSIX vocabulary for a raw handle is, because - the extension API speaking POSIX is precisely what the ruling forbade - everywhere else. - -`tests/toyos-rust-tests/src/bin/std_fs.rs:4` is the only caller in this -repository (`use std::os::toyos::io::{AsRawFd, FromRawFd};`, used at `:59`). -Nothing is blocked on the answer; the word is legal in the two places it is -still spoken here, so this is a naming decision and not a defect. +**Exit**: the next time the trait is touched in the fork, `AsRawFd` and +`FromRawFd` in `std::os::toyos::io` are renamed to `os::toyos`'s own word for +a raw handle, and `std_fs.rs` uses the new names (owner, 2026-09-30). diff --git a/issues/isolation/the-supervisor-is-host-tested-and-owns-the-stop.md b/issues/isolation/the-supervisor-is-host-tested-and-owns-the-stop.md index a68d6923f80..9225b95b0c5 100644 --- a/issues/isolation/the-supervisor-is-host-tested-and-owns-the-stop.md +++ b/issues/isolation/the-supervisor-is-host-tested-and-owns-the-stop.md @@ -84,7 +84,5 @@ A deleted or disabled test covers nothing. ## Open with the owner -- Before stage 3: the ask's ABI, which is Q6a of - `issues/kernel/the-child-process-track-waits-on-the-owners-rulings.md`; whether a program - started through `launcher` is asked or only stopped; whether - `SYS_SHUTDOWN`/`SYS_REBOOT` change at all. +- Before stage 3: whether a program started through `launcher` is asked or + only stopped; whether `SYS_SHUTDOWN`/`SYS_REBOOT` change at all. diff --git a/issues/kernel/a-childs-end-is-an-event-and-a-parent-takes-its-children-down.md b/issues/kernel/a-childs-end-is-an-event-and-a-parent-takes-its-children-down.md index 8a725701db4..96d7ca05c29 100644 --- a/issues/kernel/a-childs-end-is-an-event-and-a-parent-takes-its-children-down.md +++ b/issues/kernel/a-childs-end-is-an-event-and-a-parent-takes-its-children-down.md @@ -10,8 +10,7 @@ libc cannot start a child: `fork` and `execvp` answer `ENOSYS`, `waitpid` `ECHILD` and `system` `-1` (`userland/libc/src/misc.rs`, `userland/libc/src/stdio.rs`), and there is no `posix_spawn`. M2 and M4 of `issues/build/toyos-builds-itself.md` and the exit of -`issues/kernel/toyos-runs-on-arm64.md` need it. Stages 2, 3, 5, 6 and 7 wait -on `issues/kernel/the-child-process-track-waits-on-the-owners-rulings.md`. +`issues/kernel/toyos-runs-on-arm64.md` need it. **Constraints.** libc is built on ToyOS and never ToyOS on libc (owner, 2026-09-30: "toyos moderness and anti legacy may never be compromised because @@ -30,13 +29,11 @@ directory is `issues/isolation/every-program-sees-only-the-files-it-was-given.md — exit, crash or kill — kills its whole subtree at once; quitting gracefully is the parent's job before it exits, never the kernel's. The kernel starts init and init starts everything else, with no rule for services: a server - is init's child and lives as long as init. Each login, desktop or SSH, is a - session process under init that parents everything its user starts; an app - uses a server through handles and is never its child; logging out ends the - session. "Keep running after I close this" asks init, through `launcher`, to - be the parent, and nothing else reparents. A kill is cleanup without - cooperation, run on the causing path in bounded steps. init never dies and - stays tiny. + is init's child and lives as long as init. An app uses a server through + handles and is never its child. "Keep running after I close this" asks init, + through `launcher`, to be the parent, and nothing else reparents. A kill is + cleanup without cooperation, run on the causing path in bounded steps. init + never dies and stays tiny. ## Stages @@ -64,33 +61,36 @@ directory is `issues/isolation/every-program-sees-only-the-files-it-was-given.md handles to a held child closes, a non-blocking submit finds nothing. Negative control: the stage reverted whole (`NotSupported`); mutation: `close_ends_polls` at `true` reds the last arm. Oracle: pidfd_open(2). -2. **An end says how** (Q2, Q6d). *Exit*: exited 137, killed, and each fault +2. **An end says how** (ruled). An end reads as an exit, a kill or a fault kind + alike on every architecture, and a bare code reads the last two as failures. + No end reads as a quit's reason. *Exit*: exited 137, killed, and each fault kind the architecture raises, each read from a child that did it. Negative control: the stage reverted whole, where the first two read alike. Oracle: POSIX ``'s classes. -3. **libc starts and waits for children** (Q3a–Q3c; blocked on +3. **libc starts and waits for children** (ruled; blocked on `issues/isolation/a-childs-stdio-handle-is-not-the-one-command-named.md`). - `posix_spawn` and `posix_spawnp` with file actions and attributes, routed by - std's launch-or-spawn rule moved into `toyos`; a descriptor table with - close-on-exec, a child getting descriptors 0–2 and exactly what its file - actions name; `waitpid`, `wait`, `wait4`; `ppoll`, `sigpending` and the + libc imitates `SIGCHLD`. A C child starts with descriptors 0–2 and exactly + what its file actions name, a stated departure from POSIX. `posix_spawn` and + `posix_spawnp` with file actions and attributes, routed by std's + launch-or-spawn rule moved into `toyos`; a descriptor table with + close-on-exec; `waitpid`, `wait`, `wait4`; `ppoll`, `sigpending` and the signal-set calls; `environ`, `setenv`, `unsetenv`; `kill` with `SIGKILL` for a child or a `-pgid` of its children, 0 as a probe, `EINVAL` for other signals until stage 6; `system`, `popen` and `pclose` through `/system/bin/shell -c`. No `select`: a descriptor is a handle and passes - `FD_SETSIZE`. A handler for any signal libc imitates runs inside a blocking - call of a thread that leaves the signal unblocked (`ppoll` and `sigsuspend` - under their mask); after it `read`, `recv`, `accept`, `wait`, `waitpid` and - `wait4` restart if it was installed with `SA_RESTART` and answer `EINTR` if - not, and `poll`, `ppoll`, `pause`, `sigsuspend`, `nanosleep` and `usleep` - answer `EINTR`, `sleep` the time left. While no thread is in one, it runs at - once on libc's own thread; while every thread blocks the signal, it stays - pending, as `sigpending` reports, until one unblocks it. libc's own thread - watches at most 255 unwaited children on its own inbox, the 256th watch - being stage 6's notice, and wakes a thread in a blocking call through one - pipe, so `poll` takes at most 255 descriptors and children never count - against them. *Exit*, C corpus files, the mutation that reds an arm after - it: a piped stdout read to EOF through `poll`, then `waitpid`; + `FD_SETSIZE`. A handler for any signal libc imitates runs at once, beside the + program: inside a blocking call of a thread that leaves the signal unblocked + (`ppoll` and `sigsuspend` under their mask), and, while no thread is in one, + on libc's own thread. After it `read`, `recv`, `accept`, `wait`, `waitpid` + and `wait4` restart if it was installed with `SA_RESTART` and answer `EINTR` + if not, and `poll`, `ppoll`, `pause`, `sigsuspend`, `nanosleep` and `usleep` + answer `EINTR`, `sleep` the time left; while every thread blocks the signal, + it stays pending, as `sigpending` reports, until one unblocks it. libc's own + thread watches at most 255 unwaited children on its own inbox, the 256th + watch being stage 6's notice, and wakes a thread in a blocking call through + one pipe, so `poll` takes at most 255 descriptors and children never count + against them. *Exit*, C corpus files, the mutation that reds an arm after it: + a piped stdout read to EOF through `poll`, then `waitpid`; `waitpid(-1)` answering three children once each in the order they end, then `ECHILD` (waiting on the first alone), and `wait` and `wait4` alike (either answering `ECHILD` as `waitpid` does today); a killed child `WIFSIGNALED` @@ -168,20 +168,21 @@ directory is `issues/isolation/every-program-sees-only-the-files-it-was-given.md place spawned under init (it starts); std's `NotDeclared` fallback, or its early return for an endowment or extra slot, kept for init (it starts). Oracle: cgroup v2's `cgroup.kill` and `cgroup.max.depth`. -5. **A login is a session under init** (ruled; Q5a–Q5c). init starts a session - process per login — the desktop's at boot, one per SSH connection at sshd's - request — and the compositor and sshd start a login's programs under it. Its - namespace is `issues/filesystem/a-user-is-a-home-tree-and-a-login-row.md`'s - login row. *Exit*: killing the desktop session ends every program the - compositor started and leaves the compositor running; killing the compositor - ends none of them; a dropped SSH connection ends its session and all under - it. Negative control: the stage reverted whole, where the compositor's - programs die with it. Oracle: systemd-logind, whose session scope ends every - process of a login. -6. **A program is asked to quit** (Q3b, Q6a–Q6f). `SYS_PROCESS_QUIT` (124, - never assigned), `(process, reason)`, needs `MANAGE` as the kill does and - reaches the process's subtree by stage 4's walk; the reason is interrupt, - hang-up or terminate. Each process is started holding its notice, a new +5. **A login is a session under init** (ruled). Per login init starts a session + program that logout ends and that only parents what its user starts — the + desktop's at boot, one per SSH connection at sshd's request. As it starts + one, init hands the compositor or sshd a right to start programs in that + session alone. sshd's right also quits and kills it. Its namespace is + `issues/filesystem/a-user-is-a-home-tree-and-a-login-row.md`'s login row. + *Exit*: killing the desktop session ends every program the compositor started + and leaves the compositor running; killing the compositor ends none of them; + a dropped SSH connection ends its session and all under it. Negative control: + the stage reverted whole, where the compositor's programs die with it. + Oracle: systemd-logind, whose session scope ends every process of a login. +6. **A program is asked to quit** (ruled). `SYS_PROCESS_QUIT` (124, never + assigned), `(process, reason)`, needs `MANAGE` as the kill does, and the + reason is interrupt, hang-up or terminate. A quit reaches the process's + subtree by stage 4's walk. Each process is started holding its notice, a new object kind under the label `quit`, `READABLE` while a reason is asked and not yet read, whose read takes it. A quit kills a process that has never watched its notice or whose notice still holds a reason, whoever asks, in @@ -192,8 +193,8 @@ directory is `issues/isolation/every-program-sees-only-the-files-it-was-given.md Unix arm maps; rustc stops skipping its handler on ToyOS (`rust/compiler/rustc_driver_impl/src/lib.rs`, `install_ctrlc_handler`). Stage 5's session, `/system/bin/terminal` and `/system/bin/shell` listen and - relay nothing, the walk having asked what they run: each ends once that has, - `-c` with its status, but an interactive shell does not end on an interrupt. + relay nothing, each ending once what it runs has, `-c` with its status, but + an interactive shell does not end on an interrupt. libc takes the three reasons as `SIGINT`, `SIGHUP` and `SIGTERM`, watching the notice once one is handled, ignored or blocked: an ignored reason is dropped and an unhandled one ends the process with exit code 128 plus the @@ -236,25 +237,24 @@ directory is `issues/isolation/every-program-sees-only-the-files-it-was-given.md watching only from a handler's install (the ignoring child is killed); a spawn carrying no ignore, no mask or no `SETSIGDEF` (each spawned child in turn). Oracle: POSIX's signal actions (XSH 2.4.3) and `posix_spawn`. -7. **Job control** (Q6a–Q6c, Q7). The shell hands its terminal a `MANAGE`-only - duplicate of each process of the foreground line over its `surface` port. - The terminal turns each Ctrl+C into their interrupt, and before it closes it - asks its shell's tree to hang up and kills what is left at its deadline. - sshd does that to a dropped connection's session, and init at shutdown and - test-runner at a test's deadline ask with terminate. `&` is a line the shell - watches. sshd awaits exits through a ToyOS `tokio/src/process` arm in the - tokio fork, shaped as its Linux pidfd arm (`process/unix/pidfd_reaper.rs`). - Stop and continue need a suspend primitive and are not proposed. *Exit*: +7. **Job control** (ruled). The shell hands its terminal a `MANAGE`-only + duplicate of each process of the foreground line over its `surface` port. The + terminal turns each Ctrl+C into their interrupt, and a second kills only a + program that has not yet taken the first. Before it closes, the terminal asks + its shell's tree to hang up and kills what is left at its deadline; sshd does + that to a dropped connection's session, and init at shutdown and test-runner + at a test's deadline ask with terminate. `&` is a line the shell watches. + sshd awaits exits through a ToyOS `tokio/src/process` arm in the tokio fork, + shaped as its Linux pidfd arm (`process/unix/pidfd_reaper.rs`). *Exit*: Ctrl+C ends a pipeline whose stage started a child, none of it left and the prompt back, and ends no shell nested on the foreground line; a child that reads each interrupt survives three Ctrl+C, each pressed once it reports its - watch armed or the one before read, and one that reports its watch armed - and never reads dies on the second; a dropped SSH connection whose session - runs a watching child sees it write its file before it ends; tokio's - `Child::wait` returns with no loop polling `try_wait`. Negative control: - today's terminal and shell, where the pipeline runs on. Mutations: a quit - that kills on a reason already read (the reading child dies); a session - that never listens (the file unwritten); a shell that ends on an interrupt - (the nested shell). Oracle: POSIX's INTR, a `SIGINT` "sent to all processes - in the foreground process group" (XBD 11.1.9), and tokio's - `tests/process_smoke.rs`. + watch armed or the one before read, and one that reports its watch armed and + never reads dies on the second; a dropped SSH connection whose session runs a + watching child sees it write its file before it ends; tokio's `Child::wait` + returns with no loop polling `try_wait`. Negative control: today's terminal + and shell, where the pipeline runs on. Mutations: a quit that kills on a + reason already read (the reading child dies); a session that never listens + (the file unwritten); a shell that ends on an interrupt (the nested shell). + Oracle: POSIX's INTR, a `SIGINT` "sent to all processes in the foreground + process group" (XBD 11.1.9), and tokio's `tests/process_smoke.rs`. diff --git a/issues/kernel/the-child-process-track-waits-on-the-owners-rulings.md b/issues/kernel/the-child-process-track-waits-on-the-owners-rulings.md deleted file mode 100644 index a6d2f66ca93..00000000000 --- a/issues/kernel/the-child-process-track-waits-on-the-owners-rulings.md +++ /dev/null @@ -1,283 +0,0 @@ ---- -status: owner -kind: question -opened: 2026-09-30 ---- - -# The child-process track waits on the owner's rulings - -Stages 2, 3, 5, 6 and 7 of -`issues/kernel/a-childs-end-is-an-event-and-a-parent-takes-its-children-down.md` -wait on these, and are written there as recommended here. Each question is one -decision. Its ruling goes into the track as one line, and its entry here is -deleted. - -## Q2. Can a parent tell a failure from a kill or a crash? (stage 2) - -When a child ends, its parent reads one number. Today a child that exits with -137 and one that is killed both read 137, and a crash reads 139 or -1, numbers -a program can exit with too. - -- **Yes.** The number says whether the program ended itself or the kernel - ended it, and if the kernel did, why: killed, or which kind of crash. A crash - reads the same on x86-64 and on ARM64. A program that reads the number the - old way still sees a kill or a crash as a failure, never as a success. -- **No.** A tool that retries a crashed job cannot tell it from one that - failed, and a program that exits with 137 on purpose reads as killed. - -*Recommended: yes.* - -## Q3a. How does a C program learn that its child ended? (stage 3) - -C programs written for Unix learn it from a Unix signal, `SIGCHLD`: Ninja -waits for one (v1.13.1 `src/subprocess-posix.cc`), and so does libuv where it -has no kqueue (v1.53.0 `src/unix/process.c`). ToyOS has no signals, and its -kernel never will. - -- **libc imitates the signal.** libc, the C library, learns of the end from - ToyOS's own event and runs the program's handler for it. Ninja runs - unchanged, and the kernel gains nothing. -- **Each such program is changed for ToyOS.** Ninja, libuv and every other - program that waits for its children carries a ToyOS change of its own, as a - fork, for what one part of libc would serve. - -*Recommended: libc imitates it.* - -## Q3b. When does a C program's signal handler run? (stages 3 and 6) - -On Unix a signal interrupts the program wherever it is, and the handler runs -in its place. ToyOS never does that; the owner ruled it out as legacy. libc can -run a handler only on a thread it controls. - -- **At once, beside the program.** While one of the program's threads is - waiting inside libc — for input, for a child, for time to pass or for a - signal — the handler runs on that thread and cuts the wait short, as on - Unix: a C prompt waiting for a line comes back on Ctrl+C. As on Unix, a - program can ask that a wait for input or for a child carry on after its - handler instead, and a wait for time or for a signal is always cut short. - While no thread is waiting, libc runs the handler on a thread of its own, and - the program's own code goes on running at the same time. Ctrl+C stops clang - at once, and clang deletes the file it was writing. The cost: the handler and - the program's own code can then work on the same thing at once and collide. - GNU make's Ctrl+C handler collects the compiles that have ended, which make's - own code also does; on Windows, the one system where make's handler already - runs beside its code, make stops its own code first for exactly that reason - (make 4.4.1 `src/commands.c:508-510`). On ToyOS it collides only when Ctrl+C - comes while make is working rather than waiting. A handler that jumps back - into the program's main loop, as some C programs' do, lands on the wrong - thread and breaks the program; and clang can delete that file while its main - code is still writing into it. POSIX lets a handler run on any of a program's - threads that does not block the signal; this one is a thread the program - never made. -- **Only when the program next waits inside libc.** Nothing runs beside the - program. A compiler that is computing does not wait, so Ctrl+C does not stop - clang until it is killed, and its half-written file stays behind. - -*Recommended: at once, beside the program.* - -## Q3c. What does a C child start with? (stage 3) - -On Unix a child starts holding every file its parent has open, unless the -parent marked the file not to be passed on. - -- **Only what the parent names**, a stated departure from POSIX. A C child - starts with its input, output and error, and exactly what its parent names - when it starts it. A program started from C then holds what it holds when - started from Rust: what it is declared to hold. The cost: a C program that - hands its child a file by leaving it open, without naming it, loses it. GNU - make does that to share its limit on how many jobs run at once, with a pipe - it leaves open to a make it starts; LLVM's tools, told to share the limit, - take the same pipe (`llvm/lib/Support/Unix/Jobserver.inc`). Without it, a - make that make starts warns and runs one job at a time (make 4.4.1 - `src/main.c:1849`), and an LLVM tool warns and runs as many as it would - alone. make shares the limit by a named pipe instead where the system has - one, and ToyOS has none. -- **Unix's rule.** A C parent with any other file open passes it on, and every - program it starts runs with what that parent holds, where the same program - started from Rust runs with what it is declared to hold. - -*Recommended: only what the parent names.* - -## Q5a. What program is a login? (stage 5) - -Each login, on the desktop or over SSH, has one program that is the parent of -everything its user starts, so that logging out ends all of it. - -- **A program of its own that does nothing else.** init starts a small session - program for each login, and everything the user starts runs under it. It - listens: when the login is asked to end, its programs are asked too, and it - ends once they have. A crash of any program the user started leaves the - login and the rest of its programs running. -- **The login's first program.** An SSH login's session is the shell sshd - starts for it, and the desktop's is the first program the desktop starts for - the user. When that program ends or crashes, everything the user started - ends with it, as on Unix when the login shell exits. One program fewer runs - per login. - -*Recommended: a program of its own.* - -## Q5b. Who lets the compositor and sshd start programs in a login? (stage 5) - -A login's programs are started under its session, never under the compositor -or sshd, so each of them needs a right to start programs there. - -- **init hands it over when it starts the session.** At boot init starts the - desktop's session and gives the compositor the right to start programs in - it; for SSH, sshd asks init for a session per connection and gets that right - back. Each right reaches one session. -- **The session program hands it over itself**, over a connection init sets up - between them. The session program then has a second job besides being a - parent, and each login costs one connection more. - -*Recommended: init hands it over.* - -## Q5c. Can sshd end a login it asked for? (stage 5) - -When an SSH connection drops, its login ends: its programs are asked to hang -up, which reaches them because the session program listens (Q5a), and what is -left is killed. - -- **Yes, only its own.** The right sshd gets for a connection's session also - lets it ask that session to quit and kill it, so a dropped connection ends - its login with nobody else involved. sshd can end no other login. -- **No, it asks init.** Only init can end a login: sshd tells init that the - connection dropped, and init ends it. init does one more job, and stays the - only program that can end a login. - -*Recommended: yes, only its own.* - -## Q6a. Can one program ask another to quit? (stage 6) - -Today the only way one program can end another is a kill, which leaves it no -chance to save anything. The same answer decides how init asks each service to -finish when the machine shuts down -(`issues/isolation/the-supervisor-is-host-tested-and-owns-the-stop.md`). - -- **Yes, with a reason.** A program allowed to end another — its parent, or - the terminal it runs in — can ask it to quit and say why: interrupt - (Ctrl+C), hang-up (a window closed, a connection dropped) or terminate - (shutdown, a deadline). The program hears it among its other events and - decides what to do: an editor saves, a compiler deletes its half-written - output, Ctrl+C in a shell or an editor stops what it is doing and ends - nothing, and a server may take a hang-up as the signal to reload its - settings. The shell, the terminal and a login's session program listen, so - the programs under them are asked too. Whoever asked still kills if the end - it wants does not come. The kernel gains one call and one kind of object. -- **Yes, without a reason.** A server that reloads on a hang-up and exits on - terminate would exit when asked to reload, and no program could tell Ctrl+C - from shutdown. -- **No: a kill only, as today.** Nothing saves its work when its window closes - or the machine shuts down. - -*Recommended: yes, with a reason.* Rejected: a quit channel std and libc would -make at every start, which a program started any other way would not have; and -a handler that interrupts the program's own code wherever it is, the legacy -the owner ruled out. - -## Q6b. What does a quit do to a program that never listens for one? (stage 6) - -Most programs never listen: `ls`, `cat`, a Rust program that does not ask. - -- **It is killed at once, with everything it started**, as a Unix program - that handles nothing dies of Ctrl+C. Ctrl+C stops such a program on the - first press. The cost: a program that listens still dies at once, without - cleaning up, when the program that started it does not listen, because it - dies with that program; on Unix only the one that does not listen would die. - ToyOS's own shell and terminal and each login's session program listen, so - a compiler run from a login cleans up. -- **Nothing, until whoever asked gives up and kills it.** Ctrl+C does nothing - to `cat` until a second press, and shutdown waits out its whole deadline for - every program that never listens. - -*Recommended: killed at once.* - -## Q6c. How far does a quit reach? (stages 6 and 7) - -- **The program and everything it started**, as a kill does. Ctrl+C reaches - `make` and every compile it is running at once, as on Unix, where Ctrl+C - reaches every program of the job in front. A closing terminal asks its shell - and everything the shell started to hang up. The cost: a program cannot keep - a helper it started out of a Ctrl+C meant for itself, as a Unix program can - by putting the helper in a job of its own. Ninja does that with every - compile and passes the Ctrl+C on to them itself (v1.13.1 - `src/subprocess-posix.cc:102`, `:451-457`), so here each compile is asked - twice, and one that has not yet taken the first when Ninja's comes is - killed (Q7), leaving its half-written file. The shell and the session - program pass nothing on, since the quit already reached what they run. -- **The program alone.** Ctrl+C reaches `make` and not its compiles, and make, - which expects its compiles to have been interrupted with it, waits for every - running one to finish before it stops (GNU make's `fatal_error_signal`). The - shell and the session program must then pass each quit on to what they run, - or a closing terminal reaches its shell and not what the shell started. - -*Recommended: the program and everything it started.* - -## Q6d. Does a program that Ctrl+C ended read as interrupted? (stages 2 and 6) - -Under the answers recommended here, no child that Ctrl+C ended ever reads to -its parent as interrupted. One that never listened reads as killed; a C -program that lets the interrupt end it once it has cleaned up, as clang does, -reads as having exited with 130, which is a failure. - -- **No.** The number keeps meaning only whether a program ended itself or the - kernel ended it. A build tool that tells an interrupt from a failure, as - Ninja does, may report a compile the user interrupted as failed; Ninja still - stops the build, because the Ctrl+C reached it too. -- **Yes.** Q2's reasons gain three — interrupted, hung up, terminated — so a - program a quit ended reads as ended for that reason, and a C program that - started it sees what it would on Unix. For clang to read that way, a program - must be able to end itself for one of those reasons, as a Unix program can - by sending the signal to itself, so the number no longer says only what the - kernel did. - -*Recommended: no.* - -## Q6e. Does an unchanged Rust program's Ctrl+C handler run? (stage 6) - -Rust programs that handle Ctrl+C mostly do it through one widely used library, -`ctrlc`; rustc is one of them. - -- **Yes.** Rust's standard library hands a program its quit notice, and the - `ctrlc` fork ToyOS already carries listens to it, so a Rust program's handler - runs on a quit as it does on Unix, with no change to the program. rustc - stops leaving its handler out on ToyOS. -- **No.** A Rust program hears a quit only through a call written for ToyOS; - rustc and every other `ctrlc` user is treated as a program that never - listens (Q6b). - -*Recommended: yes.* - -## Q6f. Does a C program hear a quit as the Unix signal for it? (stage 6) - -- **Yes.** libc turns interrupt into `SIGINT`, hang-up into `SIGHUP` and - terminate into `SIGTERM`, so a C program written for Unix acts as it does - there: clang deletes the file it was writing and stops, a server reloads on - a hang-up, and a program that says only to ignore Ctrl+C runs on through - it. A C program's `kill` with one of those signals asks for a quit. -- **No.** A C program never hears a quit, and is treated as a program that - never listens (Q6b): clang leaves its half-written file behind, and a server - asked to reload ends. - -*Recommended: yes.* - -## Q7. What does a second Ctrl+C do? (stage 7) - -A program that listens may stop what it is doing on Ctrl+C and carry on: a -Python prompt goes back to its prompt, an editor cancels a command. - -- **It kills only a program that has not yet taken the first.** A program - that takes each Ctrl+C and carries on survives any number of them; one stuck - so that it never takes the first dies on the second. The same holds whoever - asks: a program asked to quit again before it took the last ask is killed. - Two quick presses: a C program, or a Rust program using `ctrlc`, takes each - on a thread of its own as it comes, so it survives them unless the machine - is too busy to run that thread between the two; a program that takes its - Ctrl+C in its own loop and is busy across both presses dies, where on Unix - its handler would have run twice. A program that takes a Ctrl+C and then - hangs is not ended by Ctrl+C: closing its window or a kill ends it, as on - Unix. -- **It always kills.** A hung program always dies on the second press, but a - Python prompt or an editor dies on the second Ctrl+C of its life, and loses - what was not saved. - -*Recommended: only a program that has not yet taken the first.* diff --git a/issues/kernel/the-kernel-is-at-least-as-secure-as-linux-on-every-machine-toyos-supports.md b/issues/kernel/the-kernel-is-at-least-as-secure-as-linux-on-every-machine-toyos-supports.md index 6d7aa2f67a0..72bb264b81a 100644 --- a/issues/kernel/the-kernel-is-at-least-as-secure-as-linux-on-every-machine-toyos-supports.md +++ b/issues/kernel/the-kernel-is-at-least-as-secure-as-linux-on-every-machine-toyos-supports.md @@ -23,7 +23,7 @@ probe is a `boot-actuators` arm or a `test-actuators` `SYS_DEBUG` action. - `issues/kernel/user-pointer-checks-have-no-spectre-v1-fence-and-smap-is-optional.md` - `issues/kernel/indirect-branches-and-returns-run-without-thunks.md` - `issues/kernel/tsx-stays-as-firmware-left-it.md` -- `issues/kernel/whether-the-kernel-loads-cpu-microcode-is-the-owners.md` +- `issues/kernel/the-kernel-loads-no-cpu-microcode.md` - `issues/kernel/no-user-address-is-drawn-per-spawn.md` - `issues/kernel/the-kernel-has-no-stack-protector.md` - `issues/kernel/no-kernel-address-is-drawn-per-boot.md` diff --git a/issues/kernel/the-kernel-is-small-interrupts-post-and-threads-wait.md b/issues/kernel/the-kernel-is-small-interrupts-post-and-threads-wait.md index e7065240b7c..3f91fb57ad5 100644 --- a/issues/kernel/the-kernel-is-small-interrupts-post-and-threads-wait.md +++ b/issues/kernel/the-kernel-is-small-interrupts-post-and-threads-wait.md @@ -151,8 +151,7 @@ times: Each step measures the kernel's lines, and from step 2 the longest interrupts-off and preemption-off windows, against stage 6's first commit. Steps 3 and 4 do not land alone: they land with #592's i8042 stage and - with usbd. Stage 6 stays open past step 5 until the owner rules on the - panel the dump paints. + with usbd. 1. **Interrupts post.** A post is legal in a handler: the watches a handler posts, and the completions of a ring they complete into, sit behind interrupts-off locks nothing allocates or frees under, and every other @@ -182,9 +181,9 @@ times: them. **Exit**: step 10's. 5. **The pass is the scheduler's.** `drain_irqs` goes: the blocked-task dump and the heartbeat become `pass`'s own, and the TCO feed stays, - since what it proves is that passes run. The dump still paints its - report on the panel and holds it there, a device the pass reaches; - whether that stays is the owner's ruling. **Exit**: `drain_irqs` and the + since what it proves is that passes run. The dump keeps painting its + report on the panel and holding it there, a device the pass reaches + (owner, 2026-09-30). **Exit**: `drain_irqs` and the idle loop's device checks are gone, both windows are measured against stage 6's start, and the exits of `issues/kernel/an-irq-watchs-freeing-cancel-compiles-in-a-handler.md` diff --git a/issues/kernel/the-kernel-loads-no-cpu-microcode.md b/issues/kernel/the-kernel-loads-no-cpu-microcode.md new file mode 100644 index 00000000000..914bfc6c6f9 --- /dev/null +++ b/issues/kernel/the-kernel-loads-no-cpu-microcode.md @@ -0,0 +1,15 @@ +--- +status: open +kind: defect +opened: 2026-09-29 +--- + +# The kernel loads no CPU microcode + +The kernel is to load CPU microcode signed by the CPU's maker, pinned by +version and hash the way vendor device firmware is (owner, 2026-09-30). It +loads none, so a CPU whose BIOS ships stale microcode stays below Linux at +`Ubuntu-6.8.0-142.142` on every line that rests on microcode. + +**Exit**: the kernel loads current microcode early on every CPU, at least as +current as Linux's. diff --git a/issues/kernel/whether-the-kernel-loads-cpu-microcode-is-the-owners.md b/issues/kernel/whether-the-kernel-loads-cpu-microcode-is-the-owners.md deleted file mode 100644 index 1e6b8e4fef2..00000000000 --- a/issues/kernel/whether-the-kernel-loads-cpu-microcode-is-the-owners.md +++ /dev/null @@ -1,14 +0,0 @@ ---- -status: owner -kind: question -opened: 2026-09-29 ---- - -# Whether the kernel loads CPU microcode is the owner's - -Microcode is firmware that runs on the CPU, which root `CLAUDE.md` does not -carve out: it admits only device firmware that never executes on the CPU. Until -the kernel loads it, a CPU whose BIOS ships stale microcode stays below Linux -at `Ubuntu-6.8.0-142.142` on every line that rests on microcode. - -**Exit**: the owner rules. diff --git a/src/licence.rs b/src/licence.rs index 437c9ac1924..0e07eb31329 100644 --- a/src/licence.rs +++ b/src/licence.rs @@ -396,8 +396,8 @@ pub const COMMITTED_FILES: &[(&str, &str, &str, Terms)] = &[ ( "doom.jpg", "ae22f71dc732580bd4f789937c9fe564969029413fc2092f27bdae8d1ceaf8e3", - "a screenshot of this system running doom, in README.md; \ - issues/build/doom-jpg-shows-ids-art-under-no-recorded-terms.md", + "the owner's own screenshot of this system running doom, in README.md; he keeps \ + it, and rules that no licence question applies", Terms::Spdx("NOASSERTION"), ), ( From 71b3a57e1b7dc5f669ee266ac5d207d3ac908987 Mon Sep 17 00:00:00 2001 From: japabu Date: Wed, 30 Sep 2026 23:55:10 +0200 Subject: [PATCH 2/2] issues: the microcode defect points at #636, and the review's four cuts Review round 1 on 7eb4428dd. - The microcode ruling orders the kernel to load what root CLAUDE.md's firmware rule still bars: it admits only device firmware that never executes on the CPU. PR #636 amends that sentence to admit the CPU's own microcode, which the kernel loads, and this branch lands after it. The defect regains the deleted question's pointer at that rule, as one line saying the rule admits the microcode once #636 lands. - Step 6 of the small-kernel track loses its heading "The scheduler knows nothing about devices": step 5 now keeps the pass painting the panel, a device the pass reaches. - The child-process track's stage headings lose " (ruled)", and stage 3 loses "ruled; ": every stage carried it, so it distinguished nothing. The track is 35 bytes longer than on main (18608 -> 18643), at 260 lines. - doom.jpg's row loses "he keeps it, and rules that": the committed file shows it is kept, and "no licence question applies" carries the ruling. Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_016t9wjdQkB8SH7bmfUoiy6L --- ...event-and-a-parent-takes-its-children-down.md | 16 ++++++++-------- ...-is-small-interrupts-post-and-threads-wait.md | 2 +- .../kernel/the-kernel-loads-no-cpu-microcode.md | 2 ++ src/licence.rs | 4 ++-- 4 files changed, 13 insertions(+), 11 deletions(-) diff --git a/issues/kernel/a-childs-end-is-an-event-and-a-parent-takes-its-children-down.md b/issues/kernel/a-childs-end-is-an-event-and-a-parent-takes-its-children-down.md index 96d7ca05c29..f22a4a92526 100644 --- a/issues/kernel/a-childs-end-is-an-event-and-a-parent-takes-its-children-down.md +++ b/issues/kernel/a-childs-end-is-an-event-and-a-parent-takes-its-children-down.md @@ -37,7 +37,7 @@ directory is `issues/isolation/every-program-sees-only-the-files-it-was-given.md ## Stages -0. **`SYS_PROCESS_OPEN` goes** (ruled). Deleted: `sys_process_open` and every +0. **`SYS_PROCESS_OPEN` goes**. Deleted: `sys_process_open` and every name only it reaches — `process_open`, `SysCap::open_process`, `MANAGE` in init's `SysCap`, the `reopenable` column, `process::process_object`, `reopen_selftest` and `sched::kthread::open_selftest` with their actuator, @@ -51,7 +51,7 @@ directory is `issues/isolation/every-program-sees-only-the-files-it-was-given.md whose symbols are test data. Negative control: the stage reverted whole, where `sys_process_open` answers 110. Oracle: rustc's name resolution, which fails the build of any caller left. -1. **An end is an event** (ruled). `read_watch` and `has_data` answer for a +1. **An end is an event**. `read_watch` and `has_data` answer for a `Process`, whose watch becomes an `Arc` as an `Acceptor`'s is, and `close_ends_polls` answers `false` for one; init's waiter threads go. *Exit*: children held on their stdin (`process_lifecycle`'s `held` role), @@ -61,13 +61,13 @@ directory is `issues/isolation/every-program-sees-only-the-files-it-was-given.md handles to a held child closes, a non-blocking submit finds nothing. Negative control: the stage reverted whole (`NotSupported`); mutation: `close_ends_polls` at `true` reds the last arm. Oracle: pidfd_open(2). -2. **An end says how** (ruled). An end reads as an exit, a kill or a fault kind +2. **An end says how**. An end reads as an exit, a kill or a fault kind alike on every architecture, and a bare code reads the last two as failures. No end reads as a quit's reason. *Exit*: exited 137, killed, and each fault kind the architecture raises, each read from a child that did it. Negative control: the stage reverted whole, where the first two read alike. Oracle: POSIX ``'s classes. -3. **libc starts and waits for children** (ruled; blocked on +3. **libc starts and waits for children** (blocked on `issues/isolation/a-childs-stdio-handle-is-not-the-one-command-named.md`). libc imitates `SIGCHLD`. A C child starts with descriptors 0–2 and exactly what its file actions name, a stated departure from POSIX. `posix_spawn` and @@ -117,7 +117,7 @@ directory is `issues/isolation/every-program-sees-only-the-files-it-was-given.md the pipe answering (passed to the kernel, which ends the caller). Negative control: today's libc, against which the corpus does not link. Oracle: POSIX's `posix_spawn`, `waitpid`, `poll` and `SA_RESTART`, and signal(7). -4. **A parent takes its children down** (ruled). A spawn's parent is its +4. **A parent takes its children down**. A spawn's parent is its spawner. A launch names its parent in its request, by one of two words: the caller, whose place is a copy of the handle to itself every process starts holding under the label `self` (`WRITE`, `DUP`, `TRANSFER`), carried as one @@ -168,7 +168,7 @@ directory is `issues/isolation/every-program-sees-only-the-files-it-was-given.md place spawned under init (it starts); std's `NotDeclared` fallback, or its early return for an endowment or extra slot, kept for init (it starts). Oracle: cgroup v2's `cgroup.kill` and `cgroup.max.depth`. -5. **A login is a session under init** (ruled). Per login init starts a session +5. **A login is a session under init**. Per login init starts a session program that logout ends and that only parents what its user starts — the desktop's at boot, one per SSH connection at sshd's request. As it starts one, init hands the compositor or sshd a right to start programs in that @@ -179,7 +179,7 @@ directory is `issues/isolation/every-program-sees-only-the-files-it-was-given.md a dropped SSH connection ends its session and all under it. Negative control: the stage reverted whole, where the compositor's programs die with it. Oracle: systemd-logind, whose session scope ends every process of a login. -6. **A program is asked to quit** (ruled). `SYS_PROCESS_QUIT` (124, never +6. **A program is asked to quit**. `SYS_PROCESS_QUIT` (124, never assigned), `(process, reason)`, needs `MANAGE` as the kill does, and the reason is interrupt, hang-up or terminate. A quit reaches the process's subtree by stage 4's walk. Each process is started holding its notice, a new @@ -237,7 +237,7 @@ directory is `issues/isolation/every-program-sees-only-the-files-it-was-given.md watching only from a handler's install (the ignoring child is killed); a spawn carrying no ignore, no mask or no `SETSIGDEF` (each spawned child in turn). Oracle: POSIX's signal actions (XSH 2.4.3) and `posix_spawn`. -7. **Job control** (ruled). The shell hands its terminal a `MANAGE`-only +7. **Job control**. The shell hands its terminal a `MANAGE`-only duplicate of each process of the foreground line over its `surface` port. The terminal turns each Ctrl+C into their interrupt, and a second kills only a program that has not yet taken the first. Before it closes, the terminal asks diff --git a/issues/kernel/the-kernel-is-small-interrupts-post-and-threads-wait.md b/issues/kernel/the-kernel-is-small-interrupts-post-and-threads-wait.md index 3f91fb57ad5..5e90f87e89e 100644 --- a/issues/kernel/the-kernel-is-small-interrupts-post-and-threads-wait.md +++ b/issues/kernel/the-kernel-is-small-interrupts-post-and-threads-wait.md @@ -144,7 +144,7 @@ times: written once as straight-line code. **Exit**: no interrupts-off window longer than a register access, and keyboard input keeps flowing while a stick misbehaves. -6. **The scheduler knows nothing about devices.** A handler posts its +6. A handler posts its device's `Watch` and ends its interrupt; the thread waiting on that watch does the work, and no step creates a kernel thread. `irq_ring`, the driver list in `drain_irqs` and the idle loop's device checks are gone by step 5. diff --git a/issues/kernel/the-kernel-loads-no-cpu-microcode.md b/issues/kernel/the-kernel-loads-no-cpu-microcode.md index 914bfc6c6f9..5b2513c2134 100644 --- a/issues/kernel/the-kernel-loads-no-cpu-microcode.md +++ b/issues/kernel/the-kernel-loads-no-cpu-microcode.md @@ -11,5 +11,7 @@ version and hash the way vendor device firmware is (owner, 2026-09-30). It loads none, so a CPU whose BIOS ships stale microcode stays below Linux at `Ubuntu-6.8.0-142.142` on every line that rests on microcode. +Root `CLAUDE.md`'s firmware rule admits this microcode once PR #636 lands. + **Exit**: the kernel loads current microcode early on every CPU, at least as current as Linux's. diff --git a/src/licence.rs b/src/licence.rs index 0e07eb31329..d12eea314a9 100644 --- a/src/licence.rs +++ b/src/licence.rs @@ -396,8 +396,8 @@ pub const COMMITTED_FILES: &[(&str, &str, &str, Terms)] = &[ ( "doom.jpg", "ae22f71dc732580bd4f789937c9fe564969029413fc2092f27bdae8d1ceaf8e3", - "the owner's own screenshot of this system running doom, in README.md; he keeps \ - it, and rules that no licence question applies", + "the owner's own screenshot of this system running doom, in README.md; \ + no licence question applies", Terms::Spdx("NOASSERTION"), ), (