From 98a737d76ae2bbc37d40b2d715c79e54cd6cdf50 Mon Sep 17 00:00:00 2001 From: Claude Date: Sat, 25 Jul 2026 13:14:05 +0000 Subject: [PATCH 1/2] docs: document .claude tooling, fix stale metadata Co-Authored-By: Claude Opus 4.8 Claude-Session: https://claude.ai/code/session_017kfnVWuqXrBvdb3QRkKFrQ --- AGENTS.md | 8 +++++++- CLAUDE.md | 22 +++++++++++++++++++++- 2 files changed, 28 insertions(+), 2 deletions(-) diff --git a/AGENTS.md b/AGENTS.md index 8771e9b..f326148 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -13,6 +13,8 @@ file covers knowledge which agents need but can't easily infer from reading the This is a learning project, so expect lots of brainstorming, experimentation, trial-and-error, and exploration of existing tools and practices. I'm also learning how to use Claude Code in this existing project, so keep that in mind. +Claude Code-specific configuration (output style, skills, subagents under +`.claude/`) is indexed in [CLAUDE.md](CLAUDE.md). ## Long-term goal @@ -40,7 +42,7 @@ Eventually, a C toolchain necessary. However, it is helpful much sooner: ## Project status -Last updated 2026-07-21. The project just finished migrating its boot +Last updated 2026-07-24. The project just finished migrating its boot process from Multiboot2/GRUB to a custom UEFI loader. The loader (`loader/`) now successfully parses the kernel ELF, maps its segments, sets up paging, and jumps into `kernel_entry` in [src/kmain.rs](src/kmain.rs). @@ -219,6 +221,10 @@ of running them all by hand every time. Locally, in order of preference: ### Booting headlessly and bounding the run +Claude Code automates this procedure as the `qemu-boot` skill +(`.claude/skills/qemu-boot/SKILL.md`); it mirrors the steps below, so keep the +two in sync if either changes. + Rebuild first (`./make-image.sh`), then run headless and capture output. QEMU never exits on its own after the kernel halts, and there's **no `timeout`/`gtimeout` on macOS**. A `perl -e 'alarm N; exec ...'` wrapper diff --git a/CLAUDE.md b/CLAUDE.md index 4c20045..7c598e0 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -1,3 +1,23 @@ @AGENTS.md -This file is for Claude-specific notes only; there are none yet. +## Claude-specific tooling + +Everything general lives in [AGENTS.md](AGENTS.md); this section indexes the +Claude Code-specific configuration checked into `.claude/`: + +* **Output style — `Terse`** (`.claude/output-styles/terse.md`). Enabled + project-wide via `.claude/settings.json` (`"outputStyle": "Terse"`), so it + is the default for sessions in this repo: minimum output, reasoning budget + unchanged. +* **Skill — `qemu-boot`** (`.claude/skills/qemu-boot/SKILL.md`). Automates the + "Booting headlessly and bounding the run" procedure in AGENTS.md: rebuilds + the image, boots it in QEMU headlessly under an external `pkill` watchdog, + and distinguishes a real hang from a silent triple-fault reset from a normal + panic. Prefer it over re-deriving the boot dance by hand. +* **Subagent — `source-grounded-explorer`** + (`.claude/agents/source-grounded-explorer.md`). For open-ended + architectural/strategic questions about the kernel; it reads the actual + source before answering and returns a labeled option menu with a + recommendation. Not for concrete, already-decided implementation tasks. + +Keep this list in sync when `.claude/` tooling is added, removed, or renamed. From 94890fb3b76177512d923b05b290c491bf89f532 Mon Sep 17 00:00:00 2001 From: Collin Date: Sun, 26 Jul 2026 20:25:21 -0400 Subject: [PATCH 2/2] Fold PRs #49, #35, #54 into this drift fix Ports the non-overlapping corrections from the other three open drift PRs so a single PR can land and the rest can close: - #49: edition-2024/workspace-lints milestone in Project status; corrected buildutil description (mkimage-only consumer, pre-UEFI leftover) - #35: Miri path-gating + daily scheduled run in Project status and Verifying changes; qemu-boot SKILL.md vendored-OVMF correction - #54: Last-updated date to 2026-07-26 All claims re-verified against Cargo.toml, ci.yml, and make-image.sh at head. Co-Authored-By: Claude Opus 5 --- .claude/skills/qemu-boot/SKILL.md | 10 ++++---- AGENTS.md | 39 +++++++++++++++++++++++-------- 2 files changed, 35 insertions(+), 14 deletions(-) diff --git a/.claude/skills/qemu-boot/SKILL.md b/.claude/skills/qemu-boot/SKILL.md index 4ec4167..8a94185 100644 --- a/.claude/skills/qemu-boot/SKILL.md +++ b/.claude/skills/qemu-boot/SKILL.md @@ -15,10 +15,12 @@ macOS host, so you must bound the run externally. `source .env` and hard-fail if it's missing. If absent, copy `.env.example` to `.env` (empty is fine) before proceeding. -2. **Rebuild.** Run `./make-image.sh` in the repo root. This fetches OVMF - prebuilts (first run only) and builds the loader + kernel into `out/esp`. - Treat a failure here as a build error, not a boot error — report it and - stop; don't proceed to boot a stale image. +2. **Rebuild.** Run `./make-image.sh` in the repo root. It uses the + vendored OVMF firmware under `third_party/ovmf` (committed to the repo, + no network fetch — it errors out if the blobs are missing rather than + downloading them) and builds the loader + kernel into `out/esp`. Treat a + failure here as a build error, not a boot error — report it and stop; + don't proceed to boot a stale image. 3. **Determine the expected success signature before booting.** Read the current [src/kmain.rs](../../../src/kmain.rs) to see what `kernel_entry` diff --git a/AGENTS.md b/AGENTS.md index f326148..e24d5d3 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -42,10 +42,14 @@ Eventually, a C toolchain necessary. However, it is helpful much sooner: ## Project status -Last updated 2026-07-24. The project just finished migrating its boot -process from Multiboot2/GRUB to a custom UEFI loader. The loader -(`loader/`) now successfully parses the kernel ELF, maps its segments, sets -up paging, and jumps into `kernel_entry` in [src/kmain.rs](src/kmain.rs). +Last updated 2026-07-26. The project migrated its boot process from +Multiboot2/GRUB to a custom UEFI loader, and has since moved the whole +workspace to Rust **edition 2024** and centralized its unsafe/safety lints +in `[workspace.lints]` (`unsafe_op_in_unsafe_fn` and the clippy safety lints +— see `Cargo.toml`), which is what the clippy CI gate below enforces. The +loader (`loader/`) now successfully parses the kernel ELF, maps its +segments, sets up paging, and jumps into `kernel_entry` in +[src/kmain.rs](src/kmain.rs). **`kernel_entry` has been re-wired for the new UEFI handoff.** It sets up the GDT and IDT, initializes the frame allocator, and hands off into @@ -59,9 +63,16 @@ and manual QEMU boots) landed in `.github/workflows/ci.yml` (PR #25): three jobs — `cheap` (host unit tests + per-crate compile checks), `expensive` (Miri), and `smoke` (full image build + a headless QEMU boot, gated on a new `src/qemu.rs` isa-debug-exit pass/fail signal, see -"Verifying changes" below). GDB-over-QEMU-stub debugging is still real but -slow for interactive local work, so CI — not local runs — is what now -exercises everything, including a full boot, on every push/PR. Clippy **is** +"Verifying changes" below). The `expensive` job is path-gated (PR #32): it +runs Miri only when a Miri input changed (`shared/**`, `Cargo.lock`, +`Cargo.toml`, `.cargo/config.toml`, `rust-toolchain`, or the workflow +itself) and otherwise reports a fast green no-op, so it never blocks a +docs-only or kernel-only PR; a daily `schedule:` run (cron `0 6 * * *`) +forces the full Miri suite regardless of paths, catching nightly drift the +path filter can't see. GDB-over-QEMU-stub debugging is still real but slow +for interactive local work, so CI — not local runs — is what now exercises +everything: a full boot on every push/PR, and Miri on every push/PR that +touches a Miri input (plus the daily scheduled run). Clippy **is** now gated: the `cheap` job runs `kclippy`/`sclippy`/`lclippy`/`iclippy`/ `tclippy`, covering every workspace package. What it enforces is the safety lints denied in `[workspace.lints.clippy]` (`undocumented_unsafe_blocks`, @@ -150,7 +161,10 @@ Cargo aliases (see `.cargo/config.toml` for the full definitions): * **mkimage**: builds a GRUB/xorriso ISO. Leftover from the pre-UEFI boot flow — **not** invoked by `make-image.sh` anymore; don't assume it's part of the live build path. -* **buildutil**: helpers shared between build scripts and mkimage. +* **buildutil**: host-side helper lib (e.g. `run_and_check`) consumed + **only** by `mkimage` (per `Cargo.toml` and a source grep). Despite the + "build scripts" framing, the live `make-image.sh` path does not use it — + like `mkimage`, it's effectively a pre-UEFI leftover. * **fetch-prebuilts**: manual updater that downloads prebuilt OVMF firmware and refreshes the vendored copy in `third_party/ovmf` (not part of the normal build; needs network). @@ -201,8 +215,13 @@ of running them all by hand every time. Locally, in order of preference: **Not part of the standard local PR loop.** CI runs Miri as its own `expensive` job (see `.github/workflows/ci.yml`), so don't run `cargo smiri` locally as a matter of course before shipping a PR — rely - on that CI job instead. Do run it locally when the specific change - actually hinges on it (e.g. you're touching the unsafe page-table + on that CI job instead. That job is path-gated (PR #32): it runs Miri + only when a Miri input changed (`shared/**` plus a few build files — see + "Project status" for the full list), which covers every change Miri can + actually catch, since Miri only exercises `shared`; a daily scheduled + run additionally forces it to catch nightly drift. Do run it locally + when the specific change actually hinges on it (e.g. you're touching the + unsafe page-table pointer walks in [shared/src/memory/paging.rs](shared/src/memory/paging.rs) and want fast local iteration), but a slow/pending local Miri run should never block otherwise-ready work from being committed or opened as a PR.