Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 6 additions & 6 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ Modern x86-64 (2020+) and AArch64 are equal targets, UEFI only. Metal is first-c
- **Existing Rust just works.** Programs build and run unchanged through proper platform support in ecosystem forks, not ToyOS-specific replacement crates. Apps use the same source on ToyOS, Linux under Wayland, macOS and Windows. A ToyOS-only program must do a ToyOS-only job; its manifest's `exempt` explains it (`build/userlandhost.rs`). X11 is legacy.
- **No silent debt.** Remove a discovered compromise or record its evidence, owner and exit in `issues/`. Filing it does not make it acceptable or complete. Never weaken audible or visual quality without the owner's explicit agreement.

Never use a fixed delay where an event can be awaited. A wait has a failure timeout. A hardware-mandated delay with no notification is the exception, with the requirement cited at the operation.
Never use a fixed delay where an event can be awaited. Waits must expose stalled progress. On timeout, return an error where the operation permits it; otherwise report the stall and preserve state. A timeout alone does not authorize termination or restart. A hardware-mandated delay with no notification is the exception, with the requirement cited at the operation.

## Architecture and sources of truth

Expand All @@ -27,7 +27,7 @@ Read the code for current behavior. `Cargo.toml` accounts for packages; `images/

The supervisor constructs process namespaces and endowments. The kernel enforces object authority; each userland protocol validates its own inputs and grants. The target is per-program filesystem views; inspect the storage track and code for the remaining shared kernel paths.

ToyOS trusts only what it cannot avoid trusting: the CPU and chipset vendor with its signed microcode, the platform firmware (UEFI, AML, SMM), which already controls the whole machine, and the signed image with its pinned toolchain and crates. Everything else is isolated: programs, users and sessions, the network, file contents, and external or hot-plug devices, whose DMA stays behind the IOMMU. The single exception is a privilege beyond a normal device claim, such as a reset line, DMA without an IOMMU or a firmware register window: it is granted only in the signed image's `system.toml`, to a program that image ships, and a package installed later never gets one, whoever signed it. Inside the trusted base a check is a bug fence, kept where it is cheap and catches our own mistakes, such as a write landing in RAM, the IOMMU, the interrupt controllers or another driver's device; it never withholds a feature for want of a vendor document.
ToyOS trusts only what it cannot avoid trusting: the CPU and chipset vendor with its signed microcode, the platform firmware (UEFI, AML, SMM), and the verified signed OS image with its pinned toolchain and crates. Programs, users, sessions and untrusted inputs remain isolated. Distro hardware drivers use isolation wherever the hardware provides it. When hardware genuinely lacks isolation, those drivers may operate as trusted system code under one distro-wide policy, without per-driver exceptions or machine-specific images. External DMA-capable devices still require isolation, even with a distro driver; separately installed drivers never acquire the bypass merely by being signed. Unknown isolation, unsupported isolation hardware and failed setup are errors, not evidence that isolation is absent. Other exceptional powers, such as reset lines or firmware register access, remain explicit grants in the signed image's `system.toml` to programs it ships. Inside the trusted base a check is a bug fence, kept where it is cheap and catches our own mistakes, such as a write landing in RAM, the IOMMU, the interrupt controllers or another driver's device; it never withholds a feature for want of a vendor document. Names and paths never establish trusted-driver identity. See `issues/a-machine-without-an-iommu-refuses-every-claim.md` for the remaining implementation.

The loader owns every UEFI call, before ExitBootServices. CPU control registers come from one declaration, applied and asserted on every CPU. Input translation belongs in userland, per surface. The kernel's logging responsibility is its record ring and console; logkeeper owns the log file. POSIX compatibility belongs in `sdk/libc`, never in the kernel's native interface.

Expand All @@ -39,11 +39,11 @@ Choose designs on their merits for modern hardware. Use vendor documentation, pu

Read another implementation's code, whoever wrote it, only clean-room: one agent derives facts and keeps the provenance of each in its evidence, never in the repository; another implements from those facts without seeing the code. The derived specification goes in the implementation brief, not the repository. A vendor's document is still cited at the site. Editing an upstream fork is governed by the implementer's fork rules. No upstream pull request is sent for now.

Use general, widely used crates as published when they are the cleanest solution. Write ToyOS-specific functionality ourselves, including drivers; minimize kernel dependencies and keep libc out of the kernel. A security boundary may justify our own well-tested crate. A fork carries upstream-quality source changes and goes when upstream supplies them; packaging alone uses unmodified source pinned by hash.
Prefer ToyOS-owned implementations for core machinery, including the scheduler, cryptography and allocator; preserve security, correctness and measured performance requirements. Use general, widely used crates as published where they remain the cleanest solution. Write ToyOS-specific functionality ourselves, including drivers; minimize kernel dependencies and keep libc out of the kernel. A security boundary may justify our own well-tested crate. A fork carries upstream-quality source changes and goes when upstream supplies them; packaging alone uses unmodified source pinned by hash.

Rust and QEMU are the development prerequisites. Other host tools must be buildable from C or C++ for eventual self-hosting, justified where Rust tools do not suffice, and declared in `issues/the-build-runs-host-tools-outside-rust-and-qemu.md`. No dependency on a binary for only one host OS. ToyOS's own maintained code is Rust, not Python, Perl or shell. Bootstrapping all the way from source without a binary seed is out of scope.

`NOTICE` records committed third-party files, hashes, origins and licences. Vendor-signed firmware may ship pinned by version and hash when redistribution permits it. Device firmware is loaded by its owning driver through its IOMMU domain; CPU microcode loading is privileged kernel work. Loading responsibility does not require embedding firmware payloads in the kernel binary.
`NOTICE` records committed third-party files, hashes, origins and licences. Vendor-signed firmware may ship pinned by version and hash when redistribution permits it. Device firmware is loaded by its owning driver through the DMA API under the isolation policy above; CPU microcode loading is privileged kernel work. Loading responsibility does not require embedding firmware payloads in the kernel binary.

## Testing and evidence

Expand All @@ -66,12 +66,12 @@ One agent, one worktree, one branch. The primary checkout owns `main` and `rust/

Implement the agreed outcome across the components it requires; a file boundary is not an approval boundary. Ask the owner when a discovery changes an owner-approved architectural decision, or when the architectural choice is uncertain. Routine implementation choices belong to the agents. Record unrelated discoveries without letting them consume the task.

Keep full command output in logs when it is long; truncation loses evidence. Report observed results, and label estimates and unverified claims. Never put personal data, machine or network identifiers into network requests, commits or published evidence. The build user-agent is `toyos-build (https://github.com/ToyOSOrg/ToyOS)`; `build/sourcegate.rs` defines identifying shapes to exclude.
Keep full command output in logs when it is long; truncation loses evidence. Report observed results, and label estimates and unverified claims. Hardware model/product numbers and firmware versions may appear in published evidence for reproducibility. Never put personal data or machine-specific identifiers, such as serial numbers, MAC addresses or network endpoints, into network requests, commits or published evidence. The build user-agent is `toyos-build (https://github.com/ToyOSOrg/ToyOS)`; `build/sourcegate.rs` defines identifying shapes to exclude.

## Comments and instructions

Comments are a maintenance cost. Prefer expressive code and names. Delete false, stale, redundant or unnecessarily long comments rather than polishing them. Keep concise boundary contracts, non-obvious invariants, unsafe preconditions and hardware requirements that code cannot express, such as why an MSR needs a particular value. A source citation is useful when it explains that constraint. History, investigations and measurements belong in commits or evidence.

A module header is not an essay or an inventory. Keep only what a reader needs to use or safely change the module. Durable rules belong at their relevant boundary; do not build a second specification in comments or private agent memory.
A module header is not an essay or an inventory. Keep only what a reader needs to use or safely change the module. Engineering work must stand on its own: do not cite private planning notes or requirement identifiers in code, comments, tests, plans or issue records. Give agents self-contained briefs. Durable rules belong at their relevant boundary; do not build a second specification in comments or private agent memory.

Change instruction files when the owner briefs it or a change removes or renames something they instruct agents to use. Replace conflicting rules instead of appending exceptions. Keep these files short, give each rule one home, and prefer judgment over a procedure for every incident. Update issue records directly affected by the change so they remain accurate. Record unrelated discoveries without expanding the assignment into their implementation or a general tracker cleanup.
28 changes: 24 additions & 4 deletions issues/a-device-function-is-driven-from-its-arrival-to-its-end.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,10 @@ started. Nothing reaches userland when a device arrives or leaves.
**Ruled** (owner, 2026-10-13):

1. The kernel hands out only what the IOMMU can tell apart: PCI functions, ISA
rows, platform devices. The supervisor brokers those from `system.toml`, at
boot and whenever one arrives later, by moving the claim to a driver. A bus
rows, platform devices. The supervisor brokers those at boot and whenever
one arrives later, by moving the claim to a driver. Image drivers come from
`system.toml`; the owner's 2026-10-16 package decision below adds authorized
installed drivers. A bus
service (usbd, one per xHCI controller) owns everything behind its
controller, keeps its device classes (HID, mass storage) inside its process,
and speaks the client protocols directly (input, block). The supervisor
Expand Down Expand Up @@ -50,8 +52,7 @@ started. Nothing reaches userland when a device arrives or leaves.
- A driver instance reaches its consumer as a client of the consumer's port,
wired as ports are today. It never serves a name for connect-by-name.
- The claim-slot limit is removed by stage 1 if cheap, otherwise by its own
pull request before stage 1's guest smoke
(`issues/a-cargo-run-boot-claims-every-pcidev-slot.md`).
pull request before stage 1's guest smoke.

**Ruled** (orchestrator, 2026-10-20, on the step-10 brief; it replaces #901's
`block@<location>` ports, `each`, `pci@` and several block services):
Expand Down Expand Up @@ -92,6 +93,25 @@ started. Nothing reaches userland when a device arrives or leaves.
- With `ICH9-LPC.acpi-pci-hotplug-with-bridge-support=off`, the delete
completes at once.

## Installed driver integration

The separate-driver-package decision is owned by
`issues/a-package-is-a-directory-under-apps-and-the-installer-is-a-program.md`.
The supervisor starts authorized installed drivers through the same
function-claim lifecycle and process/protocol boundaries above. usbd continues
to own its whole controller and device classes within one process.

Privileges beyond normal isolated device claims remain restricted to
image-shipped programs under `CLAUDE.md`. Preserve the image-only exception in
`issues/a-machine-without-an-iommu-refuses-every-claim.md` and the external-device
DMA-isolation requirement and persistent firmware weakness in
`issues/a-driver-that-reflashes-its-device-escapes-its-isolation.md`.

Protected registration, matching conflicts, authorization scope and coordinated
device release, restart, update and uninstall remain design work. Drivers needed
to reach installed-package storage must be available before that storage mounts.
The target does not establish seamless live driver replacement.

## Stages

1. **A holder's end is the event.**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,11 @@ driver: the next holder, and the next boot's firmware before any IOMMU is
on, drive what the last holder wrote. That reach is the IOMMU design's
reading, not a measurement.

**Ruled** (owner, 2026-10-04, "Refuse external, record reflash"):
"External-port devices can't be claimed by userland drivers for now;
reflashing is a recorded weakness with an exit (firmware verification) to
design later."
Owner decision, 2026-10-17: external DMA-capable devices still require
isolation, even when operated by distro drivers. The no-isolation policy in
`issues/a-machine-without-an-iommu-refuses-every-claim.md` does not waive that
boundary or solve firmware persistence. Reflashing remains the recorded
weakness whose firmware-verification exit needs design.

Owner: the orchestrator, under `issues/the-iommu-refuses-nothing-yet.md`.

Expand Down
15 changes: 11 additions & 4 deletions issues/a-file-held-across-a-file-servers-restart-answers-gone.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,14 @@ put at its path since, and a file held across a restart answers `Gone`
(`toyos::files`, so std's `File` and a C descriptor alike); `logd` loses
`/log` for the boot if LOG's server restarts.

**Exit**: DATA's entry carries an object id and a generation that nothing
reuses, a held handle reopens only when both match, and a host test that
makes a same-length file in a held file's freed block within the second has
the reopen refused.
Owner decision, 2026-10-17: interrupted handles may report `Gone`; transparent
reopening is not a general first-release requirement. Do not require object
ids and generations solely to restore every held handle. See
`issues/the-supervisor-is-host-tested-and-owns-the-stop.md` for the recovery
policy.

**Exit**: resolve the recorded loss of logging for the rest of the boot through
explicit, protocol-safe reconnection, or report that logging remains unavailable.
Do not silently bind an existing file handle to a replacement at the old path
or replay writes whose outcomes are uncertain. Verify the current logkeeper
behavior before implementation; the paths above predate its rename.
Original file line number Diff line number Diff line change
Expand Up @@ -120,14 +120,29 @@ is the slice's that evaluates the methods which call.
Owned by `issues/toyos-runs-the-machine-in-acpi-mode-and-interprets-its-aml.md`,
beside `issues/the-acpi-servers-holder-drives-the-embedded-controller-unfiltered.md`.

**Exit**: a call is made only for a byte the machine's loaded tables store
to the port, checked by something other than the holder, or the owner rules
the bound above is the one ToyOS keeps; and the rate is held against the
calls a T14 row reads the machine's own AML making, with the time each held
the boot processor; and the span is ruled.
The T14 reading owed is the time each call its AML makes holds cpu0 (the
slice that passes those writes landed in `d2006cc65`, and no such reading or
ruling is recorded here), and the owner rules, against those readings,
whether a handler that returns after `DEAF_CPU` ends the machine. Where the
interrupt stops every CPU the kernel such a handler returns to is whole, so
the panic there is this kernel's choice.
## Owner decisions, 2026-10-21

Firmware is necessarily trusted on the supported machines; acpiserver is
trusted platform code. Keep explicit authority and inexpensive checks protecting
kernel-owned memory and registers. Do not add a second AML interpreter/checker
merely to independently approve its firmware requests. This does not make
firmware access available to ordinary programs or contain firmware behavior.

Owner correction, 2026-10-21: retain the five-second fatal firmware-stall
policy, even if the call eventually returns. This supersedes the earlier
continue-after-return direction. Name the firmware call and elapsed duration in
the failure report. Five seconds is a catastrophic-stall threshold, not an
acceptable normal latency budget. Fatal handling is a chosen policy; elapsed
time alone does not prove corruption. Preserve independent safety checks and
review watchdog/completion interactions. The threshold cannot interrupt firmware
holding every CPU; enforcement requires kernel execution to resume or another
CPU still running. Never-returning firmware may leave no software recovery path.

**Exit**: verify the approved fatal-stall policy and watchdog/completion
interactions, with accurate firmware attribution. Establish the command-rate
policy against actual platform needs and record the duration and frequency of
calls from the machine's AML. The existing eight-per-second figure is not
established as universally adequate and does not bound all possible sources of
SMI. Keep measurement scope and remaining non-returning-firmware limits explicit.
The trust/checker and five-second fatal-stall choices no longer await an owner
ruling.
Loading