Skip to the content.

The native process

EmiBSD is an operating system in Rust, derived from EmiBSD.LZ, the faithful file-by-file port of the OpenBSD kernel. LZ ports; EmiBSD redesigns. This document is the process: where the code comes from, what never changes, how a change is made, measured and reviewed, how LZ’s later work is absorbed, and the decisions that shaped all of it. The design itself is in docs/ARCHITECTURE.md; the rules Claude follows are in .claude/rules/.

Origin

EmiBSD started as the port itself. On 2026-10-09 the port’s repository became EmiBSD.LZ, with its whole history (tag lz-origin, commit f5985f1d055a, docs: M16b met), and this repository, which keeps that history up to that commit, became the native system from there on (milestone N0). lz/PINNED.md records the LZ commit EmiBSD is synced to; lineage.toml records what every module derives from; docs/JOURNAL.md keeps the port’s milestones M0..M14 as the first part of this system’s history. LZ never refers to this repository: the dependency points one way.

What never changes

Goals, in priority order

  1. Safety. Zero unsafe in the kernel: sys/kernel/ and sys/abi/ are crates with #![forbid(unsafe_code)] at their roots; sys/hal/ is the only crate with unsafe, every site argued and reviewed under a ceiling; the LZ tree (bsd) is replaced subsystem by subsystem and deleted at N9 (docs/ZERO_UNSAFE.md section 0, the one diagram; .claude/rules/unsafe-budget.md).
  2. Maintainability. Idiomatic Rust where the LZ shape exists only to mirror C: Cell-everywhere structs, raw-pointer links, C-shaped out parameters (docs/IDIOMS.md).
  3. Performance. Measured improvements only (just bench), never at the cost of 1 or 2.

These are the criteria of DARPA’s TRACTOR program (functional correctness, safety guarantees, competitive performance, long-term maintainability); LZ covers correctness, this system the rest.

How a change is made

.claude/rules/re-engineering.md, in one line: pick one module of one subsystem, measure it, read the LZ module and the C it ported, redesign with ownership first, prove it (soundness arguments, tests, smokes, diff-openbsd), record it (lineage.toml, //! LZ:, ## Redesign, docs/IDIOMS.md), commit one step with the numbers (.claude/rules/git-commits.md).

Layout (decided 2026-10-07): the subsystem directories under sys/ are fixed, as the unit for metrics and lineage; inside a subsystem the module tree is free; a whole subsystem moves only when it is redesigned, in a lineage: commit. A module is inherited (byte for byte LZ’s, modulo the RCS ident lines), adapted (only its call sites changed, because a module it uses was redesigned) or redesigned; a redesign of an item used by more than 50 modules waits for the LZ milestone that touches them to close (.claude/rules/re-engineering.md).

Who redesigns: the agents

Since 2026-10-10 the redesign is done by Claude Code subagents with fixed roles, defined in .claude/agents/ and sharing one contract, .claude/rules/subagents.md (setup in a worktree, the machine lock, the long-run watcher, when to stop, what to report). The set-up is EmiBSD.LZ’s (its commit b0901dd3, where 196 hand-written launch prompts had carried the same rules), adapted: the porter became the redesigner, ports.toml became lineage.toml, the trailers are this repository’s, and there is no bug-log role, since LZ is never told this repository exists.

Agent Model Does
milestone-coordinator opus an N milestone: measure the baseline, split, launch, integrate, close CI and docs
redesigner opus a delicate redesign: locking, unsafe, data structures, the areas of security-review.md, any module over 3,000 lines
mechanical sonnet tests added to a module, lineage.toml bookkeeping, the same call-site change over many files, docs once decided
integrator opus merge agent branches, resolve the shared files (lineage.toml, the budget, the justfile), just ci
debugger opus the root cause of a failing or flaky smoke, test or diff-openbsd scenario, fixed without weakening an expectation
reviewer opus a read-only review of a branch: behaviour kept, unsafe, rules, security; it writes the Security-Review: text
planner fable a design burst from an inventory: the brief a redesigner executes and the decisions for the user; proposes, never decides
surveyor opus a read-only inventory of a module before its redesign is designed: unsafe by pattern, the primitives it needs, callers, the C’s constraints, coverage; facts, not a design
openbsd-probe sonnet boot the real OpenBSD 8.0 on a QEMU setup and report what it does
image-worker sonnet view, crop, resize images, so the coordinator’s context stays small

Six of them keep a memory, .claude/agent-memory/<agent>/MEMORY.md: one line per lesson that outlives a run (an idiom that took two attempts, a known flake, a conflict pattern), committed with the tree so the whole team of agents learns. An agent in a worktree writes it on its branch; the integrator keeps both sides on merge. Task state lives in a HANDOFF.md, never in memory. The reviewer has no memory on purpose: every change gets fresh eyes.

The main session drives the redesign: it measures the baseline, splits the milestone into clusters, launches the roles one by one with the Agent tool (at most four at once, two for a coordinator), has every branch reviewed, integrates and runs just ci; the user sees every plan and approves every commit. LZ’s batch workflow (/port) was brought over as /redesign and retired the same day, after its first run (the user’s decision of 2026-10-10): it hid the plan inside a script, could not be watched from VS Code, and had never been exercised. The machine lock, /tmp/emibsd/ci.lock, is shared with LZ: one Mac, one ci at a time.

How it is measured

Baseline at lz-origin (f5985f1d055a), from the tools: the Unsafe line and the lineage table of docs/STATUS.md, unsafe-budget.toml (the per-subsystem totals, written by cargo xtask unsafe-report --write), the smoke count and the diff-openbsd result of the first just ci and just diff-openbsd in this tree (recorded in the N0 section of docs/JOURNAL.md), and the benchmarks of just bench once it exists (boot to login: per arch, smoke-tcpbench, a vioblk number; amd64 under TCG is indicative only until M17 brings real hardware). The blockers LZ had at lz-origin are inherited and listed in docs/STATUS.md: an N-milestone report is not a regression for them.

Measuring progress

/progress [milestone] (.claude/skills/progress/) prints one row per ROADMAP milestone, computed when asked from lineage.toml, docs/ROADMAP.md, the LZ clone at the pin and git: modules redesigned, adapted and inherited, LZ lines done and left (the lines of each module’s LZ sources at the pin), Rust lines, and the time the rest would take at the project’s own average of LZ lines redesigned per active day. Its conventions:

The numbers in README, STATUS and JOURNAL do not come from it: they come from cargo xtask lz status, cargo xtask unsafe-report and the git commands docs/JOURNAL.md names.

How LZ’s later work is absorbed

.claude/rules/lz-sync.md and docs/SYNC.md: cargo xtask lz drift lists the LZ commits after the pin, the native modules they touch and (--functions) the items; every one gets a record in lz-sync.toml (applied with the EmiBSD commit and its method: cherry-pick, cherry-pick-conflicts or reimplemented; not-applicable with a reason; covered-by-redesign with the proof); security fixes are never skipped silently; the pin moves in a lz: bump pin commit. just ci fails on an untriaged LZ commit. The three method totals in each sync commit say whether the roadmap’s order is costing re-implementations.

How security changes are reviewed

.claude/rules/security-review.md: the listed areas are redesigned last in their subsystem, carry a Security-Review: trailer, and pass just diff-openbsd and their smokes before the commit; crypto, IPsec, WireGuard and softraid CRYPTO change last of all, with extra tests.

Decisions

Date Decision
2026-10-07 Three stages: OpenBSD -> EmiBSD.LZ (the port, continuous) -> EmiBSD (native). Governance files live inside each repository.
2026-10-07 The migration happens when M14 is complete, on the user’s signal, never with agents running.
2026-10-07 enavarre-cl/EmiBSD stays the public home of the native system; enavarre-cl/EmiBSD.LZ is public and locked down (Issues only).
2026-10-07 LZ never names EmiBSD; EmiBSD declares LZ in lz/PINNED.md, lineage.toml, the LZ: trailer, this section and the README.
2026-10-07 Layout: subsystem directories fixed, free inside.
2026-10-08 Function-level traceability lives in lineage.toml ([[module.fn]], exceptions only), not in the files; the RCS ident lines are dropped (decision 20).
2026-10-09 The port’s repository became EmiBSD.LZ (public, locked down); this one is native from lz-origin = f5985f1d055a; reference/openbsd-src kept at LZ’s pin; the milestone order N1..N8 recommended, the user’s call at each start.
2026-10-09 Authorship, the user’s decision: every .rs under sys/ and tools/ carries the author’s ISC block (“Copyright (c) 2026 Emilio Navarrete Lineros enavarre@outlook.com”) in its <LICENSES> zone, first (the latest change), before the original blocks, which never change, or alone where there are none; license = "none" now describes the C source, not the Rust file; lz check requires the block and compares inherited modules without it.
2026-10-09 From the external review: adapted as a third module status; the method of every applied sync; a timing rule for widely used items; docs/SYNC.md; the blockers inherited at lz-origin recorded in the baseline.
2026-10-10 EmiBSD.LZ’s subagent set-up (b0901dd3) adopted: roles in .claude/agents/ (redesigner and mechanical for LZ’s porters), one contract in .claude/rules/subagents.md, .claude/agent-memory/ committed, the machine lock /tmp/emibsd/ci.lock shared with LZ, /redesign and /progress (the ROADMAP scope resolved against lineage.toml; no milestone key in its rows); no external-bugs role: slips go to the user.
2026-10-10 /redesign retired after its first run, stopped in its Plan phase: the session drives the redesign and launches the roles one by one (a milestone-coordinator when a whole milestone runs in the background); a workflow hid the plan, could not be watched from VS Code and was never tested. The roles, the contract, the memories and /progress stay.
2026-10-10 Zero unsafe outside a listed core (docs/ZERO_UNSAFE.md): every module outside unsafe-core.toml compiles under #[forbid(unsafe_code)], set on its mod declaration; the core (hardware, boot, the host harness, a runtime of primitives, explicit_bzero.rs) is budgeted and reviewed; the legacy total only falls, an LZ sync aside; “redesigned” means “compiles with forbid”; N2 becomes “Core runtime”, N9 “Close” is added; first slice pipe(2); Adapter a safe trait checked by lz check; reimplemented normal for forbid modules; Miri and the core crate decided at N9. Iterative: the plan follows what each step teaches.
2026-10-16 v2 of the zero-unsafe plan (docs/ZERO_UNSAFE.md section 0, decisions 20-24): the kernel is the crate sys/kernel/ with #![forbid(unsafe_code)] at its root; sys/abi/, also forbid, is OpenBSD’s userland interface as the loadable module abi_openbsd.ko with no logic; sys/hal/ holds the only unsafe (hardware and runtime, ceiling 2,150 at N2); bsd (the LZ tree) is replaced subsystem by subsystem through bridges registered in hal and deleted at N9; develop first, compile later (no build per commit; just check and QEMU at the milestone close). Supersedes the row above: no core list, no per-module forbid.
2026-10-18 Decisions 42 and 43 (docs/ZERO_UNSAFE.md section 10): N3’s performance regression measured before N4 (a release diagnostic, host microbenchmarks over the real kernel::vm, seven optimizations: host fork and exec -36 to -49 %; under QEMU amd64 forkexit -12 %, forkexec -10 %, arm64 unchanged, the rest in the pmaps and the trap), and the hot-path rule: Bench: lines before every hot-path commit, an op more than 10 % slower without a reason stops the agent.
2026-10-18 Decision 44: arm64 first. Only arm64 is built, booted and measured until N10 homologates amd64 (EMIBSD_ARCHS, landed by N4.0); no amd64 code is written or fixed before then; the planner records the amd64 constraints of every hal boundary type; N9 closes on arm64 with the amd64 tree frozen; N10 homologates amd64, N11 verifies (the TRACTOR gaps of 2026-10-17), N12 closes performance on both archs. The user’s reason: the tokens spent advancing two architectures in parallel.

Later

Graphics (drm, nouveau, Mesa, GSP firmware) is a proposal for LZ after M17; it would reach this system through lz-sync like any other LZ work.