diff --git a/issues/isolation/the-power-broker-authority-with-a-human-in-the-loop.md b/issues/isolation/the-power-broker-authority-with-a-human-in-the-loop.md index f4d3f3dab17..c8d0702143c 100644 --- a/issues/isolation/the-power-broker-authority-with-a-human-in-the-loop.md +++ b/issues/isolation/the-power-broker-authority-with-a-human-in-the-loop.md @@ -13,26 +13,21 @@ privileged service, a policy engine, an authentication agent) because its base model only knows identities. ToyOS's capability model IS the mechanism, so the native shape is smaller: -1. **No user-facing program holds `POWER`.** One small daemon — the power - broker — is endowed it in `system.toml`, and its whole job is deciding. - (Today the toybox shutdown applet holds the bit directly; the broker - moves that single endowment one level up, behind judgment.) -2. **Programs request, the broker decides** — a port/connection like every +1. **Programs request, the broker decides** — a port/connection like every other daemon protocol in the tree, under the server-never-blocks doctrine. -3. **The confirmation rides the trusted UI path.** The broker asks the +2. **The confirmation rides the trusted UI path.** The broker asks the compositor to present it, and the tree's own architecture is what makes that mean something: the compositor owns the panel and the kernel delivers key transitions per surface, so no ordinary program can draw a fake dialog or fake the click on a real one. "A human physically present confirmed" is the single-user machine's honest equivalent of Linux's password prompt. -4. **Inhibitors**: a program may register "unsaved work" with the broker; +3. **Inhibitors**: a program may register "unsaved work" with the broker; the broker delays, or names the holdouts in the dialog. Registration is a connection, so a crashed registrant releases its inhibit by the same teardown that releases everything else. Unstaffed until the owner opens it; sequenced naturally with the userland/ product era. What must not happen meanwhile is the accident this track -exists to prevent: `POWER` spreading to more manifest rows because asking -the applet is inconvenient — the broker is the answer to that itch. +exists to prevent: `POWER` spreading to more manifest rows. 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 new file mode 100644 index 00000000000..a9c410d9d9c --- /dev/null +++ b/issues/isolation/the-supervisor-is-host-tested-and-owns-the-stop.md @@ -0,0 +1,88 @@ +--- +status: assigned +kind: track +opened: 2026-09-28 +--- + +# The supervisor is host-tested and owns the machine's stop + +Held by the orchestrator. Every stage waits on PR #536 (`wt/toyos-fsd`). + +## Stages + +Every guest test this track names is registered at `Tier::Fast` or +`Tier::Nightly` with no `src/redlist.rs` row. A deleted or disabled test covers +nothing. + +1. **The rename**, one mechanical PR, first after #536. Before stage 1 is + briefed, the exit's search below runs once over the `rust/` fork's delta as + well as the superproject, so its hits are known going in. It touches `toyos/src`, + `toyos-abi/src`, `userland/libc/src` and the `rust/` fork's delta, so it is + briefed as an ABI brief, and its `CLAUDE.md` edits are placed in the same PR + by an agent briefed for them. Issue slugs carrying an old name are renamed + with every citation. + + | today | becomes | + |---|---| + | `init` | `supervisor` | + | `netd` | `netstack` | + | `logd` | `logkeeper` | + | `soundd` | open with the owner | + | `blockd` | open with the owner | + | `fsd` | open with the owner | + | `sshd` | `sshserver` | + | `compositor` | unchanged | + + **Exit**: over every tracked path and every text file's content, in the + superproject and the `rust/` fork's delta as `src/forkcheck.rs` defines it, + excluding the bodies of `issues/` files (recorded evidence), no hit remains + outside the exclusions, each judged per match and not per line: + - a case-insensitive substring search for `netd`, `logd`, `soundd`, + `blockd`, `fsd`, `sshd`, excluding, case-insensitively, an identifier + containing `klogd`, `blockdev`, `VirtioSoundDev`, `netdev`, `netdb`, + `ENETDOWN` or `fsdir`; + - a case-insensitive search for `init` followed by no lowercase letter + other than one `s` (so `inits` hits alongside `init`) and preceded by a + letter only where it starts with a capital `I` (so `spawn_init`, + `struct Init`, `SpawnInit`, `TimerInit`, `InitPort` and "asks init" all + hit). A match goes where it names the program and stays otherwise; + third-party text (`tests/testcases/tinycc/`, the C ports) stays. +2. **Decisions in a pure crate.** The supervisor's decisions live in + `toyos-supervisor`, with host tests; `userland/supervisor` keeps only + handles, spawns and the loop. The decisions: namespace and claim selection + from a manifest row; the claims a restart is owed; `SysCap` narrowing; + launch resolution and every launcher refusal; the swap ladder and + probation; restart policy; the stop order derived from the manifest, with a + cycle broken only by declaration. + **Exit**: the crate's tests pass in + `cargo test --workspace --exclude toyos-build`; a host test refuses a + manifest whose dependencies form an undeclared cycle; each refusal and + each decision above has a mutation that reds a host test, named in the PR; + and the stage deletes each decision from `userland/supervisor`, which calls + the crate for it, named per decision in the PR. No decision exists in two + places. +3. **The supervisor owns the stop.** It asks each service it started to + finish, in reverse dependency order, storage last, each ask bounded; only + then does it call the kernel, whose part is to stop whatever is left and + cut power. + **Exit**: two guest tests. In one, two non-storage services with a declared + dependency are asked to finish in reverse dependency order; it reds when + they are asked in forward order, and when they are asked all at once with + storage still last. In the other, a service holding unwritten state is + asked to finish, answers, and has its state on disk after the reboot; its + negative control is the same service never answering, where the stop still + lands at the bound and the supervisor's line names the service. +4. **The stop's coverage comes back.** **Exit**: each claim below is asserted + by a host test or a guest test, and a mutation named in the PR reds it. + - A held thread's transition wakes the stop. + - No block operation is open at the stop. + - A dump served during the stop counts every thread it stopped as held. + - Every record reaches the console, `Rebooting.` last. + - Storage is durable before power is cut. + +## Open with the owner + +- The new names of `fsd`, `soundd` and `blockd`. +- Before stage 3: the ask's ABI (no syscall is proposed); whether a program + started through `launcher` is asked or only stopped; whether + `SYS_SHUTDOWN`/`SYS_REBOOT` change at all.