Host identity: Apple silicon running macOS 27 or newer only — hosted by Apple's Virtualization.framework; not Linux, not Unix, not QEMU (see
AGENTS.md). The runner enforces the floor at runtime (macOS 27+).
This file is the project's living status tracker and its multiagent coordination surface: where we are, what we are trying to build next, how far along each step is, who currently claims which piece of work, and pointers to the append-only per-branch changelog. Claims and logs are sharded (see Multiagent coordination) so parallel agents never collide on one file. Update it as work lands — flip the checkboxes, fill in the notes, and append to your branch's log under
docs/logs/. Claims stay honest perAGENTS.md: observed (log evidence underartifacts/) versus inferred (reasoning/docs only).
Premise check (2026-08-06): this tracker was first frozen against the milestone-one-era
main. On the same day, PRs #6/#7 merged the milestone-two kernel proper (ADR 0004), which changed the premises below: the kernel now callsExitBootServices, owns an identity-map MMU, drives a polled TX-only MMIO serial console, and never returns. This file was refreshed accordingly — the plan's shape is kept, its factual anchors are reconciled with the merged state. PR #10 later unified this tracker with the milestone-two gate evidence and added the multiagent changelog (now sharded per branch under docs/logs/; see the Changelog).
| Milestone | What it proved / is | Status |
|---|---|---|
| Zero — boot pipeline | A Zig AArch64 UEFI app on a FAT32 ESP boots under real firmware; output observed on host (\BOOTED.TXT) |
✅ done |
| One — kernel handoff | Separate freestanding KERNEL.BIN loaded, cache-maintained, jumped to, and returned (\RC.TXT = kernel_rc=0x0); ADR 0002 |
✅ done |
| Two — kernel proper | ExitBootServices, captured EFI map, identity TTBR0_EL1 tables, MMIO serial probe + polled TX console (ADR 0004) | ✅ gates passed 2026-08-08 (claim 1517): bad-handoff failure gate passing since 2026-08-06, VZ serial gate now passing (post-MMU virtio TX fixed) |
| 1.5 — Interactive Kernel Monitor ("Dipshit Monitor") | A live, interactive command monitor served by the kernel's serial console (the milestone-two terminal loop becomes its payload) | ✅ done 2026-08-09 — all 7 hard gates pass; the last (filesystem, claim 3475) closed 2026-08-09 and upgraded to a real FAT32 storage driver (claim 6420); tagged m1.5-interactive-monitor |
| Three — allocator, interrupts, tasks | Physical allocator, GIC + timer, tasks, EL0, and syscalls | 🚧 active — allocator, IRQ/timer, and round-robin tasks are done (claims 3972/5162/9187/5275); the first EL0t task + SVC boundary landed in claim 8215; the frozen 64-slot syscall ABI and slots 0–3 (ping/write/yield/exit) pass their live VZ gate (claim 3594); the fault-safe uaccess layer (claim 6120), the per-task address spaces card (claim 5804 — per-task TTBR0 with an EL1-only kernel overlay, VZ TTBR1 fallback), the user task lifecycle card (claim 6729 — explicit states, bounded spawn, exit→zombie, idle-task reaper, plus the callee-saved vector-frame fix that made preemption of compiled tasks safe), and the ESP exec card (claim 6783 — a real user program, USER.BIN, is loaded from the ESP through the claim-6420 FAT path by the exec monitor command, the EL0 user root is rebuilt around its page, and the program runs at EL0, writing via sys_write, round-tripping pings, and exiting through the lifecycle), and the blocking-syscalls card (claim 3200 — sys_sleep slot 4 blocks the caller for N scheduler ticks with timer-driven wakeup, the ESP program sleeps 2 ticks and wakes, and the worker keeps advancing during the sleep window) all landed and pass their live VZ gates. Milestone three is CLOSED 2026-08-10 (claim 0707): the full class A + class B gate set re-ran green at the candidate and the milestone is tagged m3-userspace (see the march tracker docs/march-m3.md row 8). |
| Four — real randomness | Virtio entropy driver + ChaCha20 CSPRNG (RFC 7539), boot-time seed, random command, ASLR, general (non-ESP) filesystem, process abstraction |
✅ done 2026-08-11 (claim 2839, tag m4-processes at 9d7e4d5) — milestone-four cards 1 + 2 + 3 landed 2026-08-10 (claims 2665/3693 + 3678 + 3848, see the march tracker docs/march-m4.md): the kernel now has a REAL randomness source — virtio-pci entropy driver (kernel/src/virtio_entropy.zig, DID 0x1044) with the post-MMU re-arm (observed: VZ resets the device at ExitBootServices — entropy: pre-rearm st=00), a freestanding ChaCha20 CSPRNG (kernel/src/csprng.zig) keyed from a 64-byte boot seed (entropy: seeded n=64), the random [n] monitor command (registry 27→28), and EL0 user-stack ASLR consuming the seed for BOTH exec'd programs and the boot-time static payload (every EL0 task gets per-boot stack placement — exec: loaded … stack=0x…, aslr: boot user stack=0x…). Card 2 generalizes the claim-6420 FAT32 driver into a general (non-ESP) filesystem: fat.mount_partition mounts any volume at any LBA, directory cluster chains + /-path resolution make the image's EFI/BOOT tree reachable (ls [<dir>], `cat <file |
| Five — networking | The runner attaches a virtio-net device (--net, flag-gated); the guest's virtio-net transport drives TX end to end — feature negotiation, queues 0/1, MAC read, bounded frame staging, polled used-ring drain — and the host receives exact Ethernet frames |
🚧 active — milestone five, card N1 (claim 1373, branch agent/buffy/m5-net-tx): the virtio-net TRANSPORT + TX is live on VZ — device DID 0x1041 (class 0x020000), VER1|MTU|MAC negotiated (the device needs MTU accepted — feat=0x28/0x1), host-set MAC read via the feature path (mac=02:00:00:00:00:01 source=feature), queues 0/1 armed size 4, DRIVER_OK through the post-exit re-arm (the net device does NOT reset at ExitBootServices — net: pre-rearm st=0f observed, unlike blk/entropy), a 12-byte virtio_net_hdr consumed on every TX buffer (observed contract — the driver prepends a zeroed header), and netsend sends known frames the host captures byte-exactly (46-byte fixture + ring reuse + honest 1500-byte truncation). New class-B gate bash tools/verify-live-net-tx.sh PASS 2/2; the full class-A set and the 29-gate verify-vz aggregate (incl. the net gate) re-ran green (proof the --net mode left the default VM byte-identical; evidence artifacts/live-net-tx-*, artifacts/live-net-tx-vz-sweep.log). Card N2 (claim 6076, branch agent/buffy/m5-net-rx) — raw Ethernet RX is LIVE 2026-08-11: the runner's --net-inject <file> writes the attachment's socket end ONCE on the guest's net: rx-armed serial trigger (host→guest; OFF by default); queue 0 is supplied with one fixed BSS buffer (4096 bytes), the used ring is drained POLLED (the net device's used-buffer IRQ is not yet observed — recorded, not assumed), each delivery is MAC-filtered (own + broadcast accepted, other dropped with a counter) into a bounded 4-slot frame FIFO, and net recv prints the received frame byte-exact. Claim-time observations: the device WRITES a 12-byte virtio_net_hdr into RX buffers (first frame device-len 72 for 60 bytes, first 16 bytes 00…01 00 ff ff ff ff — num_buffers=1; the RX-header question answered) and REFUSES an RX buffer under 1530 bytes (1526/1528/1529 wedged the device — no frame written, used ring never advanced, TX stalled; 1530 works). New class-B gate bash tools/verify-live-net-rx.sh PASS 3/3: phase 1 injects the 60-byte broadcast known frame — net recv prints it byte-exact AND the guest re-sends it (the host capture is byte-exactly the injected fixture — the round trip); phase 2 own-MAC frame received byte-exact; phase 3 foreign-MAC frame dropped (filtered=1, rx-obs still records the delivery). Full class A green; the 29-gate verify-vz aggregate re-ran green 29/29 (evidence artifacts/live-net-rx-*, artifacts/m5-net-rx-vz-sweep.log). Card N3 (claim 7293, branch agent/buffy/m5-arp) — ARP is LIVE 2026-08-11: kernel/src/arp.zig (pure RFC 826 logic — static IP via net ip <a.b.c.d>, byte-exact request/reply builds, bounded 4-slot BSS table, counters) wired into the RX drain (a request for our IP is answered on the N1 TX path; a reply is learned; the rest dropped with a counter) + net arp [<ip>] subcommand + the runner's --net-arp-respond <host-ip> (deterministic host-side ARP answer inside the capture thread; OFF by default). New class-B gate bash tools/verify-live-net-arp.sh PASS 3/3: phase 1 the guest answers the injected request for its IP (42-byte reply byte-exact in the capture, repl=1); phase 2 the guest resolves 10.0.0.2 (request byte-exact in the capture; the host answer lands as 10.0.0.2 -> 02:00:00:00:00:02, learn=1); phase 3 a request for 10.0.0.99 is dropped (drop=1, repl=0, still observable via net recv). Claim-time observation: the device delivers/transmits the 42-byte ARP frames unpadded (below the Ethernet 60-byte minimum). Full class A green; the 31-gate verify-vz aggregate re-ran green 31/31 (evidence artifacts/live-net-arp-*, artifacts/m5-arp-vz-sweep.log; verify-live-concurrent flaked once on a scheduler-timing interleave=0 and passed on immediate retry — recorded, not hidden). Card N4 (claim 0148, branch agent/buffy/m5-ipv4) — IPv4/ICMP is LIVE 2026-08-11: kernel/src/ipv4.zig (pure RFC 791/792 logic — RFC 1071 one's-complement checksums, parse/build, byte-exact ICMP echo request/reply builders, fragments dropped COUNTED — no reassembly, honest bound) wired into the RX drain BESIDE the ARP dispatch (an echo request for our static IP is answered byte-exact on the N1 TX path; an echo reply is observed — pongs_observed + the echoed sequence; the rest dropped with counters) + net ping <a.b.c.d> subcommand (an echo needs a unicast dst — the peer must be in the ARP table first; refused honestly otherwise) + the runner's --net-icmp-respond <host-ip> (deterministic host-side echo answer inside the capture thread — type 0 reply, id/seq/payload echoed, both checksums recomputed; OFF by default). New class-B gate bash tools/verify-live-net-icmp.sh PASS 3/3: phase 1 the guest answers the injected 46-byte echo request for its IP (reply byte-exact in the capture with the identification + id/seq/payload echoed, repl=1); phase 2 the guest resolves 10.0.0.2 and pings it (the ARP request + 46-byte echo request are byte-exact in the capture; the host answer lands as pong=1 with seq=1); phase 3 an echo request for 10.0.0.99 is dropped (drop=1, repl=0, still observable via net recv). No new hardware-contract entry — the 46-byte frames travel unpadded, consistent with the N3 observation. Full class A green; the 32-gate verify-vz aggregate re-ran green 32/32 (evidence artifacts/live-net-icmp-*, artifacts/m5-ipv4-vz-sweep.log). Card N5 (claim 8552, branch agent/buffy/m5-udp) — UDP is LIVE 2026-08-11: kernel/src/udp.zig (pure RFC 768 logic — the 8-byte header, the checksum over the IPv4 PSEUDO-HEADER computed ALWAYS, a bounded 4-slot LISTEN table, bounded per-listener datagram rings, LOOPBACK — a send to our OWN IP delivers directly into the local receive path, no device round trip) wired into ipv4.zig's protocol dispatch (protocol 17 → udp on ALREADY-VALIDATED frames; TCP/other still dropped_proto) + `net udp [listen |
| Six — graphics: Driving Award + Road Pops | Boot to a graphical interface: a virtio-gpu framebuffer (G1), framebuffer text rendering (G2), the boot terminal re-targeted to the screen as Road Pops (G3), and the Driving Award window manager compositing multiple windows (G5), and a draw/window syscall seam for EL0 programs (G6). Keyboard/pointer input (the original G4) was split into milestone seven (USB XHCI + HID) | ✅ done 2026-08-13 (cards G1–G6 live) — card G1 (claim 6053, branch agent/buffy/m6-gpu) LIVE 2026-08-12 — the FIRST NON-BLANK GUEST FRAMEBUFFER on VZ: the runner's --display/--screenshot mode attaches VZVirtioGraphicsDeviceConfiguration (1280×720 scanout; OFF by default — the default VM byte-identical); kernel/src/virtio_gpu.zig discovers the modern virtio-pci gpu (DID 0x1050 observed, class 0x038000, dev 7; config layout common@+0x0000 / ISR@+0x1000 / notify@+0x4000 / devcfg@+0x8000 — claim-0013's decoded shape), negotiates VER1-only (device offers RING_PACKED|RING_EVENT_IDX|RING_INDIRECT_DESC|VERSION_1), arms controlq (queue 0) + cursorq (queue 1), re-arms post-exit (VZ RESETS the gpu at ExitBootServices — pre-rearm st=00, like blk/entropy, unlike net's st=0f), and drives the spec 2D path GET_DISPLAY_INFO → CREATE_2D (B8G8R8X8) → ATTACH_BACKING (4K-aligned BSS framebuffer) → SET_SCANOUT → TRANSFER → FLUSH. Claim-time findings (hardware-contract + claim doc): virtio-gpu 1.2 wire shapes (the 24-byte display_one; the pre-1.2 20-byte shape wedged the device with DEVICE_NEEDS_RESET), the tail descriptor's next must be 0 (VZ walks it), command/framebuffer cache cleans are mandatory (MMU-on, not caches-off), and the scanout composites with alpha — an X/A byte of 0 renders fully transparent (the final black-screen fix; fills write X=0xff). screen / screen fill <rrggbb> / screen peek monitor commands (registry 34→35). New class-B gate bash tools/verify-live-screen.sh PASS 1/1 — the transport report + guest-side fill bytes + the DECODED capture: 14400/14400 sampled pixels are the fill green (0x00ff00 → ~(117,251,76) through the color-managed pipeline; evidence artifacts/live-screen-*, artifacts/gpu-screen-*s). Full class A green; the 35-gate verify-vz aggregate re-ran green (artifacts/m6-gpu-vz-sweep.log). Card G2 (claim 3194, branch agent/buffy/m6-text) LIVE 2026-08-12 — the machine boots to WORDS on the screen: kernel/src/text.zig (the public-domain 8x8 bitmap font — ASCII 0x20–0x7e, fixed BSS glyph table; putc/puts, cursor, line wrap, a bounded 128-line scrollback ring, clear; the pure renderer is host-tested against an injectable mock canvas — 21 tests incl. golden glyphs, wrap/scroll/clear, bounds, cursor, composition) paints the SAME banner + prompt the serial log carries over G1's framebuffer (fg 0x00ff00 on bg 0x101418) and pushes it through G1's transfer/flush unchanged (text: boot banner presented); text / text put <string> / text clear monitor commands (registry 35→36). New class-B gate bash tools/verify-live-text.sh PASS 1/1 — the DECODED capture shows real glyphs: the banner region samples fg=0.255 (green family) over bg=0.745 (the dark 0x101418) — the screen is no longer monochrome — with the region below all background (evidence artifacts/live-text-*, artifacts/gpu-screen-*s); the live-pixel bound is "text visible with the expected color family" (color-managed + retina-scaled; byte-exact glyphs live in the class A mock — the G1 gate's precedent). Full class A green; the 36-gate verify-vz aggregate re-ran green 36/36 (artifacts/m6-text-vz-sweep.log). Card G3 (claim 1574, branch agent/buffy/m6-roadpops) LIVE 2026-08-12 — ROAD POPS: the boot terminal is on the screen: kernel/src/road_pops.zig is a TEE console — every byte still reaches serial FIRST (the shared seam; the transcript gates keep passing byte-identical) AND G2's text layer paints the same banner + prompt + every reply on the framebuffer, drained ONE full-frame present per output batch by the shell idle loop. The G2 one-shot boot paint is replaced by the tee rendering the shell's OWN banner (its first present emits the G2 text: boot banner presented evidence on serial). Claim-time fix (claim-0015 redux, observed live): a road_pops.Target struct literal with all-constant fields was folded into .rodata, whose &fn entries hold LINK-TIME absolute addresses — the tee's first write jumped to the link-time rp_text_put_bytes and faulted (esr=0x02000000 elr=0x14260); the Target is now built in RAM like ensure_vtable so every &fn resolves PC-relatively. roadpops monitor command (registry 36→37: armed/dirty/presents). New class-B gate bash tools/verify-live-roadpops.sh PASS 1/1 — the DECODED capture shows the boot banner (fg=0.255) AND the LIVE SESSION glyphs below it (fg=0.124 — the echoed echo ROADPOPS/uname commands + replies rendered; the screen is a working terminal, not a one-shot splash), with the serial transcript still carrying the whole session (evidence artifacts/live-roadpops-*, artifacts/gpu-screen-*s). G1/G2 gates updated honestly for the Road Pops reality: the terminal's drain-presents render over the raw fill, so G1's pixel phase now asserts the non-blank terminal frame (the fill is proven guest-side — fill=…ff00 transfer=ok flush=ok + peek p1=0xff; its cmds= is now session-dynamic), and the text report's cur/lines are session-dynamic (its own output feeds the ring). Full class A green; the 37-gate verify-vz aggregate re-ran green 37/37 (artifacts/m6-roadpops-vz-sweep.log) — the default VM stayed byte-identical. Card G5 (claim 1543) LIVE 2026-08-13 — Driving Award, the window manager: kernel/src/driving_award.zig (bounded BSS registry, z-order, focus, hit-test, dirty-rect compositor) makes Road Pops window 0 and a 1 Hz clock overlay window 1; the I3 keyboard read source is gated on the terminal's focus. win/win focus <n>/win raise <n>/win hit <x> <y> (registry 39→40). New class-B gate bash tools/verify-live-win.sh PASS 1/1 — the serial session (windows=2, hit-test focusing the clock then the terminal) + a KEYBOARD-typed uname landing in the focused terminal (DipshitOS aarch64), and the DECODED capture shows two overlapping windows with the right z-order (the clock's amber title bar + navy body over the terminal, the terminal's green glyphs beside it). Full class A green; the default VM stayed byte-identical. Card G6 (claim 0487) LIVE 2026-08-13 — the draw/window syscall seam: the ADR 0007 amendment slots 12/13/14 (sys_win_open/sys_win_fill/sys_win_present, implemented 12 → 15, then a teardown follow-on adds slot 15 sys_win_close + win close → 16) expose the G5 window manager's user-window surface to EL0 — sys_win_open opens a bounded kernel-owned window (id 2..3, fixed BSS back-buffer ≤ 256×192 B8G8R8X8), sys_win_fill fills rects, sys_win_present marks it dirty for the compositor (no uaccess — plain numbers; the kernel owns the buffers; the window persists after the caller exits, the honest bound). WIN.BIN (user/src/win.zig, the first graphics user program, loaded by exec) drives it end to end: win: open id=2 → win: fill ok (dark-blue background + red/cyan/white blocks) → win: present ok → sys_exit(87). New class-B gate bash tools/verify-live-win-syscall.sh PASS 1/1 — the observation phase on the SAME kernel state (win: windows=3 focused=2 + win[2]: user user rect=64,64,256,192 z=2; syscalls implemented=16 with open=1/fill=4/present=1 + slot 15 sys_win_close registered) and the DECODED capture shows the window's own content over the terminal (no terminal foreground showing through — z-order). Full class A green; the default VM stayed byte-identical (sys_win_open returns EINVAL when the manager is unarmed). Teardown follow-on (this branch): win close <n> (monitor) + sys_win_close (slot 15) release a user window so the id (2..3) can be re-opened instead of leaking until reboot — both call driving_award.user_close; open → fill → present → close → re-open is host-tested in driving_award + syscall, and a SEVENTH image WINCLOSE.BIN proves it LIVE from EL0: the class-B gate tools/verify-live-win-close.sh PASS 1/1 — WINCLOSE.BIN opens/fills/presents/CLOSES (slot 15) and exits 88, twice; win shows windows=2 after the close (no win[2]: row) and the re-exec re-opens id 2 (the freed slot reused, never id 3). Ownership follow-on (this branch): windows are OWNED by the opening process and AUTO-CLOSE when it exits (the scheduler's exit_current calls driving_award.close_owner(pid) — the real teardown semantic); sys_win_fill/present/close are owner-restricted (host-tested cross-process refusals); an EIGHTH image WINLOOP.BIN keeps its window alive so the restructured tools/verify-live-win-syscall.sh still pixel-proves EL0 rendering (WIN.BIN's window now vanishes on exit — windows=2, sys_win_close calls=0). Move/raise follow-on (this branch): slots 16/17 (sys_win_move/sys_win_raise, implemented 16 → 18) reposition + restack the caller's window from EL0 (move clamps on-scanout, raise reorders the z-order, both owner-restricted); the monitor's win move <n> <x> <y> is the EL1h half; a NINTH image WINMOVE.BIN drives it live and tools/verify-live-win-move.sh PASS 1/1 shows the clamped rect (win[2]: user user rect=1024,528,256,192) + the counters (move=2/raise=1) + the decoded capture with the window's colors at the NEW position. Read-back follow-on (this branch): slot 18 (sys_win_get, implemented 18 → 19) copies the caller's window rect (four u32 LE words) OUT through uaccess — the ONE pointer-taking win slot — so an EL0 program reads its clamped position back after sys_win_move; WINMOVE.BIN now prints winmove: get 1024,528,256,192 (the gate's get=1 + implemented=19 assertions). Full-state query follow-on (this branch): slot 19 (sys_win_query, implemented 19 → 20) copies the caller's window FULL state (eight u32 LE words: x, y, w, h, z, focused, visible, dirty) OUT through uaccess — so an EL0 program introspects z-order rank + focus + visible/dirty, not just the rect; WINMOVE.BIN now prints winmove: query 1024,528,256,192 z=2 focused=1 visible=1 dirty=1 (the gate's query=1 + implemented=20 assertions). Visibility follow-on (this branch): slot 20 (sys_win_set_visible, implemented 20 → 21) HIDES (visible 0) or SHOWS (visible 1) the caller's window from EL0 (driving_award.user_set_visible, owner-restricted; the fixed terminal + clock are refused, a non-0/1 flag is EINVAL) — hiding marks the terminal dirty so the next composite repaints over the hidden window, showing marks the window dirty so it reappears; the back-buffer + z-order rank are untouched. WINMOVE.BIN now hides its window, sleeps 2 ticks, shows it again, and prints winmove: hide ok / winmove: show ok; tools/verify-live-win-move.sh asserts hide=1/show=1/set_visible=2 + implemented=21 and gained a marker-driven capture (--screenshot-after "winmove: hide ok", a new VMRunner flag) proving the PIXEL DISAPPEARS (no red/cyan/white blocks at the clamped spot while hidden) and RETURNS (the LATEST capture shows them back). Milestone six closed — G1–G6 all live. |
| Seven — input: USB XHCI + HID (keyboard + pointer) | Give Road Pops its FIRST screen-side keystrokes: an XHCI host-controller transport (I1 — MMIO + command/event rings + port status), USB enumeration + HID boot-protocol parsing (I2 — the keyboard + pointing devices behind the XHCI controller), and a bounded event FIFO + keycode decode feeding the line editor (I3). Premise corrected 2026-08-13 (claim 3868): VZ's VZUSBKeyboardConfiguration + VZUSBScreenCoordinatePointingDeviceConfiguration present as an Apple XHCI USB controller (VID=0x106b DID=0x1a06 CLS=0x0c0330, two MMIO BARs 0x50001000 + 0x50000000) with the keyboard/pointer as USB HID devices behind it — the hypothesized virtio-input (DID 0x1052) does not exist in the framework. |
✅ done 2026-08-13 (cards I1–I3 live) — card I1 (claim 4272) LIVE 2026-08-13 — the XHCI host-controller transport works on VZ: kernel/src/xhci.zig discovers the Apple XHCI controller pre-exit (bus 0 dev 8, DID 0x1a06 CLS 0x0c0330), maps its MMIO register space post-MMU (BAR0=0x50001000 cap regs / BAR1=0x50000000; CAPLENGTH=0x20, HCIVERSION=0x110, DBOFF=0x940, RTSOFF=0x520, HCSPARAMS1=0x10002010 = 16 slots/32 intrs/16 ports), sets up the command ring + event ring + ERST + primary interrupter, drives a NO-OP command TRB to CC=1 (the ring machinery proven), and reads the port status. Claim-time observations (hardware-contract + claim doc): the interrupter register set i lives at RTSOFF+0x20+(0x20×i) (writing ERSTSZ into the MFINDEX region wedged the emulation — the fix); VZ does NOT reset the controller at ExitBootServices (pre-reset USBSTS=0x9/USBCMD=0x0 — the XHCI answer to the st=00 vs st=0f question); after HCRST+RS USBSTS=0x0; ports 9 and 10 report CCS=1 — exactly the two attached HID devices (keyboard + pointer), the I2 handoff. usb monitor command (registry 37→38). New class-B gate bash tools/verify-live-xhci.sh PASS 1/1 (14/14 assertions; the gate asserts the guest's own usb report — the card's gate-shape change: byte-exact host capture does not apply to a memory-mapped controller). Full class A green; the default VM is byte-identical (no XHCI lines in the default serial log; the --input mode is flag-gated OFF). Card I2 (claim 4116) LIVE 2026-08-13 — USB enumeration + HID works on VZ: kernel/src/xhci.zig now enumerates BOTH devices end to end (port reset → Enable Slot → Address Device → device + config descriptors over the control endpoint → Set Configuration 1 → interrupt-IN endpoint armed) and parses the HID boot-protocol reports — the keyboard (port 9, slot 1, VID 0x05ac PID 0x8105, boot protocol=1, EP1-IN maxpkt 8, boot=1) and the absolute pointer (port 10, slot 2, VID 0x05ac PID 0x8106, protocol=0 — NOT a boot mouse — EP1-IN maxpkt 10, Set_Protocol(boot) honestly REFUSED boot=0). A synthesized host keyDown (macOS keyCode 0, dispatched by the runner's new minimal --input-key/--input-key-after seam — VZ has NO programmatic keyboard API) produced the observed 8-byte report 00 00 04 00 00 00 00 00 (mod 0, HID usage 0x04 = 'a'). usb gained usb devices/usb report (registry 38 stays). New class-B gate bash tools/verify-live-usb.sh PASS 1/1 (11/11 assertions; the gate asserts the guest's own usb devices + usb report lines — no host-side byte-exact capture applies to a memory-mapped controller). Card I3 (claim 6050) LIVE 2026-08-13 — keystrokes drive Road Pops on VZ: kernel/src/input.zig is a bounded pure-BSS event FIFO + HID-usage → ASCII keymap + the shell-idle drain (the card-3d pattern, next to net RX): the XHCI interrupt-IN reports decode to ASCII bytes that the Road Pops tee's read path hands to the line editor. Claim-time observations (hardware-contract + claim doc): VZ delivers ~one report per Road Pops present cadence, so the runner's scripted key surface types at 2 s per keystroke (faster drops reports); single-TRB arming (re-armed per completion) is the correct shape — a multi-TRB depth experiment wrapped the transfer ring at the 8th report and dropped everything after; the input drain runs BEFORE the Road Pops present so a report is never starved behind a slow full-frame present. The runner's --input-string/--input-string-after synthesizes one NSEvent per keyDown/keyUp into the VZVirtualMachineView (VZ has NO programmatic keyboard API). input monitor command (registry 38→39: armed/fifo/drop count/last keyboard + pointer events). New class-B gate bash tools/verify-live-input.sh PASS 1/1 (8/8 assertions): the keyboard typed input\n and the guest's own input report showed events=6 (i,n,p,u,t,Enter) with dropped=0 and kb-usage=0x28 kb-byte=0xa (Enter) — the typed command ran end to end. Full class A green; the default VM is byte-identical (no xhci/input/usb lines in the default serial log; the --input mode is flag-gated OFF). Milestone seven closed — I1/I2/I3 are all live,handing Road Pops its first screen-side keystrokes. (G5 — Driving Award |
— is now live on milestone six and consumes this input path; see docs/march-m6.md.) |
||
| Eight — usability: human interface (ADR 0008) | One command grammar + grouped help (D1), a real line editor (history, cursor, Ctrl chords, tab completion — D2), one error:/usage:/unknown command shape (D3), a visible-focus window model (D4), an about/welcome/motd/sysinfo support surface (D5), all enforced by gates (D6). Normative contract: docs/decisions/0008-human-interface-guidelines.md |
🚧 active — U0 (ADR 0008, claim 8938) ✅ 2026-08-14; U1 help/catalog (claim 3275) ✅ 2026-08-14; U2 shell editing/history (claim 1809, + the latent XHCI interrupt-ring wrap fix) ✅ 2026-08-14; U3 error/usage contract (claim 1511, + the u4 history-width fix the fuzz found) ✅ 2026-08-14. U4–U8 (pointer focus + cursor, window HIG, first-boot experience, sysinfo, persistent settings) are the next cards — per-card tracker docs/march-m8.md. |
Resolved loose end: the milestone-one KERNEL.TXT corruption is fixed
(ADR 0002 — the loader now places image content at base+0; the write is
byte-perfect and gated by zig build run).
Every gate below is backed by evidence re-verified
2026-08-07 (full suite re-run on merged main 4702548,
artifacts/status-reverify-20260807.txt) and re-run again at HEAD
5160eef on 2026-08-08 (claim 8592 preflight, artifacts/status-preflight-*.txt),
and re-run at the newest HEAD 076ddf1 on 2026-08-08 (claim 8073,
artifacts/gates-reverify-20260808-076ddf1.txt — all class A gates plus
the primary VZ serial gate), and re-run in full at the
m1.5-interactive-monitor tag (74a51f3) on 2026-08-09 (claim 7873,
artifacts/gates-reverify-20260809-m15-tag.txt — the complete class A
set plus the complete class B set: serial takeover, bad-handoff, marker,
nvram-console, host-console, live-transcript, live-fs, live-timer,
live-reboot, live-exceptions); all green — and re-run again at the
newest HEAD 706712c on 2026-08-09 (claim 2233,
artifacts/gates-reverify-20260809-706712c.txt — class A 11/11, class B
10/10: serial takeover, bad-handoff kernel_rc=0x2, marker ladder to
M2_TXOK!, nvram-console, host-console, live-transcript RX 1/1, live-fs
persistence pair 1/1, live-timer 1/1, live-reboot 2/2, live-exceptions
1/1; all green) — and re-run again at the newest HEAD a3644cf
(PR #53, claim 6420's FAT32 storage driver merged) on 2026-08-09
(claim 0658, artifacts/gates-reverify-20260809-a3644cf.txt +
artifacts/classB-chunk{1,2,3}-a3644cf.log — class A 11/11, class B
10/10: serial takeover, bad-handoff kernel_rc=0x2, marker ladder to
M2_TXOK!, nvram-console 82 chunks/5027 B, host-console, live-transcript
RX 1/1, live-fs persistence pair 1/1, live-timer 1/1, live-reboot 2/2,
live-exceptions 1/1; all green); files under artifacts/. The
milestone-three uaccess card (claim 6120) re-ran its affected gates at
f4b3143 + uaccess on 2026-08-10: the new live-uaccess gate 1/1
(artifacts/m3-uaccess-live.txt), live-svc 1/1 with the payload's three
writes (write=3), live-exceptions 1/1, live-userspace 1/1, live-timer
1/1, live-tasks 1/1, live-transcript 1/1, and zig build run (serial
takeover) all green; class A re-run green in full — and re-run in
full at the milestone-three candidate HEAD 0c119d8 on 2026-08-10
(claim 0707, artifacts/gates-reverify-20260810-m3-closeout.txt +
artifacts/classB-chunk{1,2,3,4}-m3-closeout.log — class A 11/11,
class B 17/17: serial takeover, bad-handoff, marker, nvram-console,
host-console, live-transcript, live-fs, live-timer, live-tasks,
live-userspace, live-svc, live-uaccess, live-addrspaces, live-lifecycle,
live-exec, live-sleep, live-reboot; all green). The milestone-three
close-out archived the completed M1.5/M3 prompt + design docs into
docs/archive/ (see the Related docs section).
**Milestone-four close-out (claim 2839, 2026-08-11): the complete class A
set (fmt, unit tests, test-console, build, image, inspect, swift runner
build, context, coordination, coordination tooling, mmu-debt — 11/11) and
the complete class B VZ set (the full 28-gate verify-vz aggregate: serial
takeover, bad-handoff, marker, nvram-console, host-console,
live-transcript, live-fs, live-gfs, live-timer, live-tasks,
live-userspace, live-svc, live-uaccess, live-addrspaces, live-lifecycle,
live-exec, live-args, live-procs, live-concurrent, live-long-lived,
live-kill, live-sleep, live-entropy, live-reboot, live-ipc,
live-procs-syscall, live-scale, live-wait — 28/28) re-ran green at the
milestone-four candidate HEAD 9d7e4d5 on a clean tree; the milestone is
tagged m4-processes. Evidence: artifacts/gates-reverify-20260811-m4-closeout.txt
artifacts/m4-closeout-classA-1.log+ the per-gatevz-live-*logs. The M4 prompt docs were archived todocs/archive/; the next plan is milestone five, card N1 (virtio-net transport + TX,docs/m5-net-tx-prompt.md).
| Gate | Command | Result | Last evidence |
|---|---|---|---|
| Format | zig fmt --check boot/src/*.zig kernel/src/*.zig build.zig |
✅ pass | re-run 2026-08-08 (preflight); re-verified at 076ddf1 (claim 8073) |
| Guest build | zig build |
✅ pass | re-run 2026-08-08 (preflight); re-verified at 076ddf1 (claim 8073) |
| Disk image | zig build image |
✅ pass | re-run 2026-08-08 (preflight); re-verified at 076ddf1 (claim 8073) |
| Binary + image inspect | zig build inspect |
✅ pass | re-run 2026-08-08 (preflight); re-verified at 076ddf1 (claim 8073) |
| Swift runner build | swift build --package-path host/vm-runner |
✅ pass | re-run 2026-08-08 (preflight); re-verified at 076ddf1 (claim 8073) |
| Context snapshot | zig build context |
✅ pass | re-run 2026-08-08 (preflight); re-verified at 076ddf1 (claim 8073) |
| VZ serial gate | zig build run |
✅ PASS 2026-08-08 | banner DipshitOS kernel has seized control. + memory-map descriptors=0x… + kernel terminal state in vm-serial.log (claim 1517; artifacts under artifacts/). Re-verified live at 076ddf1 (claim 8073): banner + 27-descriptor map (key=0x2c4) + dipshit> prompt in artifacts/vm-serial.log, runner exit 0. Re-verified live at 706712c (claim 2233): banner + 27-descriptor map (key=0x2d4) + dipshit> prompt, runner exit 0. Re-verified live at a3644cf (claim 0658): banner + 27-descriptor map (key=0x2c4) + dipshit> prompt, runner exit 0. Root cause was the translation start-level mismatch (claims 6460/7896); fixed in production with T0SZ=16 + tlbi vmalle1 at the switch. Historical blocker detail (claims 0013/0018/0020): console is a virtio-pci device (bus 0 D5 0x1af4/0x1043), transport armed pre-exit, first post-switch BAR/common-config read did not return |
| Live transcript / RX gate | bash tools/verify-live-transcript.sh |
✅ PASS 2026-08-08 | host scripted keystrokes reach the kernel end to end through the polled virtio receive queue and the live dipshit> transcript is asserted in vm-serial.log (claim 6684, 3/3 boots; artifacts live-transcript-*) |
| Live exception-vector gate | bash tools/verify-live-exceptions.sh |
✅ PASS 2026-08-08 | VBAR_EL1 vectors installed; dipshit> fault triggers a real synchronous exception (udf) that the handler reports ([EXC] sync from EL1t, ec=0x00 unknown-reason, ESR/FAR/ELR/SPSR) and resumes — shell continues (fault: handled, resumed after faulting instruction → follow-up echo reply), 2/2 boots (claim 9746; artifacts live-exceptions-*) |
| Live tasks scheduler gate | bash tools/verify-live-tasks.sh |
✅ PASS 2026-08-09 | tick-driven round-robin (claim 5275): the timer PPI preempts the shell, the worker advances (report line tasks worker advances=N, N≥1 — only possible after ≥ 2 real context switches), and the shell resumes to run commands (rx-tasks-ok); tasks command reports both tasks; artifacts live-tasks-* |
| Live EL0/SVC boundary gate | bash tools/verify-live-userspace.sh |
✅ PASS 2026-08-10 | claim 8215 regression: two sequenced pings prove return to EL0; the payload waits for a timer-only witness before cooperative yield, and the shell-side evidence follows real timer preemption |
| Live syscall-table gate | bash tools/verify-live-svc.sh |
✅ PASS 2026-08-10 | claim 3594, 1/1 (re-verified under claim 6120 with write=3): three EL0 writes (good line, bad-pointer EFAULT exercise, marker line), timer IRQ before yield/exit; exact single snapshot ping=2, write=3, yield=1, exit=1; non-returning status-7 exit and one post-exit rx-svc-ok reply. |
| Live uaccess gate | bash tools/verify-live-uaccess.sh |
✅ PASS 2026-08-10 | claim 6120, 1/1: EL0 passes an unmapped bad pointer (0x1_2000_0000, above the identity blanket) to sys_write, receives -3/EFAULT, and survives to write uaccess: efault ok n=8; the uaccess monitor command runs a validated copy (valid=1) and a raw copy from an unmapped address that takes a real EL1 data abort, recovered (recovered=1, fault=1, no [EXC] parking), and the shell answers rx-uaccess-ok. |
| Live ESP exec gate | bash tools/verify-live-exec.sh |
✅ PASS 2026-08-10 | claim 6783, 1/1: USER.BIN (a DSK1 flat image built from user/src/main.zig) is on the ESP (the image builder embeds it; ls lists it), exec USER.BIN reads it through the FAT path and replies exec: loaded USER.BIN size=0x83 entry=0x400000 head=0x200080d2c1020010 (the loaded first instructions), and the program executes at EL0 from the loaded page — its sys_write markers (user: hello from the ESP, user: exec ok), two sequenced pings, sys_exit (status 42 → tasks user-exec exited status=42), and the idle reap (tasks user-exec reaped) are all in vm-serial.log, with the shell responsive (rx-exec-ok). |
| Live blocking-syscalls gate | bash tools/verify-live-sleep.sh |
✅ PASS 2026-08-10 | claim 3200, 1/1: the ESP-loaded program yields (sys_yield, slot 2), sleeps 2 scheduler ticks (sys_sleep, slot 4 — blocked, woken by timer-driven wakeup, return 0), writes the user: awake marker after the wake, and exits (status 43); the scheduler's blocked state and the worker's advance lines during the sleep window prove live progress of other tasks; syscalls reports 4 sys_sleep calls=1 |
| Live timer IRQ gate | bash tools/verify-live-timer.sh |
✅ PASS 2026-08-09 | Real IRQ delivery observed, 3/3 boots (claim 9187): GICv3 (GICD @ 0x10000000, GICR/active frame @ 0x10010000) + CNTP (24 MHz, GTDT level-triggered PPI 30); each serial log contains timer irq delivered ppi=0x1e irq_ticks=1 and timer heartbeat ticks=5 irq=5 poll=0, with a follow-up shell reply. Claim 7948's platform-blocker conclusion was invalidated by a delivery-blocking guest bug: SGI/PPI MMIO aimed at the RD frame instead of its +0x10000 SGI frame. The audit also corrected shifted MADT GIC IDs and the wrong ICFGR field bit. Artifacts: live-timer-*; Xcode 27 host-surface audit: vz-irq-api-audit.txt |
| Live reboot/shutdown gate | bash tools/verify-live-reboot.sh |
✅ PASS 2026-08-08 | hard gate 6 closed — a real EFI ResetSystem from a live dipshit> shell observed end to end (claim 0527, 4/4 boots): reboot reset the machine (second full takeover + fresh map key in vm-serial.log), shutdown powered it off (runner reports VM state → stopped); artifacts live-reboot-*. The claim-0011 M2_RST! marker write is scanned + reported but is best-effort by design (lost in the teardown race; the machine-level effect is the evidence) |
| Live virtio-net TX gate | bash tools/verify-live-net-tx.sh |
✅ PASS 2026-08-11 | claim 1373, 2/2 phases: the virtio-net transport is live on VZ — DID 0x1041, VER1|MTU|MAC negotiated (feat=0x28/0x1), host-set MAC from the feature path (02:00:00:00:00:01), queues 0/1 size 4, DRIVER_OK through the re-arm (pre-rearm st=0f — no EBS reset on the net device), and the host capture holds the EXACT frames (phase 1: 46-byte known frame byte-for-byte; phase 2: 46+46+1514 — ring reuse + honest truncation); the 29-gate verify-vz aggregate re-ran green (artifacts live-net-tx-*, live-net-tx-vz-sweep.log) |
| Live virtio-net RX gate | bash tools/verify-live-net-rx.sh |
✅ PASS 2026-08-11 | claim 6076, 3/3 phases: the guest arms queue 0 with a fixed BSS buffer (net: rx-armed), the host injects a known frame into the SAME attachment's socket via --net-inject (a serial trigger), the polled used-ring drain delivers it, the MAC filter accepts own + broadcast and drops the rest, net recv prints the exact bytes, and the guest re-sends them (the phase-1 capture is byte-exactly the injected fixture — the round trip). Claim-time observations: the device writes a 12-byte virtio_net_hdr into RX buffers (num_buffers=1) and refuses an RX buffer under 1530 bytes; the used-buffer IRQ is unobserved (drain polled). The 29-gate verify-vz aggregate re-ran green 29/29 (artifacts live-net-rx-*, m5-net-rx-vz-sweep.log) |
| Live virtio-net ARP gate | bash tools/verify-live-net-arp.sh |
✅ PASS 2026-08-11 | claim 7293, 3/3 phases: the guest's ARP layer (kernel/src/arp.zig) sits on the N2 RX seam — phase 1 the guest answers the injected request for its static IP (the 42-byte reply is byte-exact in the host capture, repl=1, net recv observes the request); phase 2 the guest resolves a peer (its broadcast request is byte-exact in the capture and the runner's --net-arp-respond 10.0.0.2 answer lands: 10.0.0.2 -> 02:00:00:00:00:02, learn=1); phase 3 a request for a foreign address is dropped (drop=1, repl=0, still observable via net recv). Claim-time observation: the device delivers/transmits the 42-byte ARP frames unpadded (below the Ethernet 60-byte minimum). The 31-gate verify-vz aggregate re-ran green 31/31 (artifacts live-net-arp-*, m5-arp-vz-sweep.log) |
| Live virtio-net ICMP gate | bash tools/verify-live-net-icmp.sh |
✅ PASS 2026-08-11 | claim 0148, 3/3 phases: the guest's IPv4 layer (kernel/src/ipv4.zig) sits on the N2 RX seam BESIDE the ARP dispatch — phase 1 the guest answers the injected 46-byte echo request for its static IP (the reply is byte-exact in the host capture with the identification + id/seq/payload echoed, repl=1, net recv observes the request at device len 58); phase 2 the guest resolves a peer and pings it (the broadcast ARP request + the 46-byte echo request id/seq 1 are byte-exact in the capture and the runner's --net-icmp-respond 10.0.0.2 answer lands: pong=1 with seq=1 — the echoed sequence is the ping proof); phase 3 an echo request for a foreign address is dropped (drop=1, repl=0, still observable via net recv). No new hardware-contract entry — the 46-byte frames travel unpadded, consistent with the N3 observation. The 32-gate verify-vz aggregate re-ran green 32/32 (artifacts live-net-icmp-*, m5-ipv4-vz-sweep.log) |
| Live virtio-net UDP gate | bash tools/verify-live-net-udp.sh |
✅ PASS 2026-08-11 | claim 8552, 4/4 phases: the guest's UDP layer (kernel/src/udp.zig) sits on the N4 IPv4 seam (protocol-17 dispatch over already-validated frames) — phase 1 LOOPBACK: a send to our OWN IP (10.0.0.1:7000) is delivered directly into the listener's buffer byte-exact (src 7000, dst 7000, len 12, payload 01 02 03 04), rx=1 tx=1 loop=1, and the capture stays EMPTY (no device round trip); phase 2 the host's injected datagram 10.0.0.2:9999 → 10.0.0.1:7000 is delivered byte-exact (net udp recv + the raw frame at device len 58 via net recv), rx=1 drop=0; phase 3 the guest resolves a peer and sends to it (the ARP request + the 46-byte datagram are byte-exact in the capture and the runner's --net-udp-respond 10.0.0.2:9999 answer — the same payload — lands in the listener buffer, rx=1 tx=1); phase 4 a datagram to a closed port (10.0.0.1:9998) is dropped (drop=1, no delivery, no reply, still observable via net recv). Claim-time fix recorded: the pseudo-header zero/protocol word was initially reversed (0x1100 vs 0x0011) — caught by the byte-exact fixtures, fixed, re-run green. No new hardware-contract entry — the 46-byte datagrams travel unpadded, consistent with the N3/N4 observation. The 33-gate verify-vz aggregate re-ran green 33/33 (artifacts live-net-udp-*, m5-udp-vz-sweep.log) |
| Live UDP-syscall gate | bash tools/verify-live-net-udp-syscall.sh |
✅ PASS 2026-08-12 | claim 1384, 4/4 phases: the ADR 0007 slots 9/10/11 driven end to end by UDP.BIN (the first network-syscall user program, loaded by exec) — phase 1 the program's transcript IN ORDER: sys_udp_listen(7000) → udp: listen ok; the LOOPBACK send+recv to its OWN IP → udp: loop ping (the 12-byte datagram, byte-exact); the peer send to 10.0.0.2:9999 + poll sys_udp_recv of the host's --net-udp-respond answer → udp: got ping (the cooperative sys_yield between polls — the ring returns to the program and the poll succeeds); the EINVAL mapping from EL0 (unbound-port recv + unresolved-peer send → udp: recv err -1 / udp: send err -1, nothing transmitted); sys_exit(17) → procs UDP.BIN exited status=17 / tasks user-exec exited status=17 / tasks user-exec reaped; the capture is byte-exact (the 42-byte ARP request + the 46-byte datagram); phase 2 the observation commands on the SAME kernel state: syscalls rows 0–11 (implemented=12, rows 9/10/11 counted) + net udp/net counters rx=2 tx=2 loop=1 drop=0. Gate-engineering lessons recorded: the expect is keyed on the program's OWN completion markers (udp: got ping / tasks user-exec reaped) — an early expect killed the VM at ~5 s before the ring returned to the program after its yield and a HEALTHY kernel looked hung (switches=5, all tasks ready); the marker greps carry ` |
| Live NAT gate | bash tools/verify-live-net-nat.sh |
✅ PASS 2026-08-12 | claim 4678 (milestone five, card N7): outbound connectivity through VZNATNetworkDeviceAttachment live on real VZ — the runner's --net-nat attaches the NAT device (mutually exclusive with --net, OFF by default — the default VM stays byte-identical); NO guest code, the existing stack is driven against the NAT gateway and the gate asserts GUEST-OBSERVED COUNTERS (the capture-file byte-exact shape does not apply through NAT — the card's documented gate-shape change). ONE run, 11/11 assertions: net ip 192.168.64.5 (the OBSERVED subnet), the 42-byte ARP request to the gateway, the 46-byte echo request, pong=1 with seq=1 (the deterministic gateway round trip — no internet), the learned gateway MAC (net arp: 192.168.64.1 is at …), the MAC-under-NAT line (mac=02:00:00:00:00:01 source=feature — the NAT attachment honors the configured MAC), arp=req=1,repl=0,learn=1,drop=1,fail=0, transport status=0x0f, the shell echo, and the runner's net-nat: ENABLED line. The 35-gate verify-vz aggregate re-ran green 35/35 (artifacts live-net-nat-*, m5-net-nat-vz-sweep.log) |
| Live DHCP gate | bash tools/verify-live-net-dhcp.sh |
✅ PASS 2026-08-12 | claim 0351 (milestone five, card N8): the bounded RFC 2131 DHCP client on the N5/N6 UDP layer, live on real VZ in TWO phases. Phase 1 (deterministic file-handle): --net + --net-dhcp-respond 10.0.0.2 — the guest's net dhcp runs the FULL handshake against the host's crafted server: the 286-byte DISCOVER byte-exact in the capture (dst ff*6, src 02:00:00:00:00:01, 0x0800, 68→67, op 1, cookie, option 53 = 1) → OFFER → the 298-byte REQUEST (the same xid, option 53 = 3) → ACK → net: dhcp bound ip=10.0.0.2 mask=255.255.255.0 gw=10.0.0.1 server=10.0.0.2 lease=3600; the report counters discover=1,offer=1,request=1,ack=1,nack=0,timeout=0,mal=0; the host's NET-DHCP OFFER + ACK lines. Phase 2 (real NAT, rides --net-nat): the CLAIM-TIME observation — the VZ NAT attachment serves NO DHCP server on this host (the DISCOVER went out, offer=0, mal=0; honestly recorded in the hardware contract with the saved log under artifacts/live-net-dhcp-nat-explore/, never faked), and the guest is NOT stranded: the static fallback still reaches the NAT gateway (pong=1 seq=1). The 36-gate verify-vz aggregate re-ran green 36/36 (artifacts live-net-dhcp-*, m5-net-dhcp-vz-sweep.log) |
| Live DHCP lease-lifecycle gate | bash tools/verify-live-net-dhcp-renew.sh |
✅ PASS 2026-08-12 | claim 9489 (milestone five, card N9): the RFC 2131 §4.4.5 lease lifecycle live on real VZ — the client ENFORCES the lease it recorded (T1 = lease/2, T2 = lease*7/8, expiry releases the address). TWO runs: Run A (lease 100 s, --script2-delay 55 / --script3-delay 92) — at elapsed ~57 the client RENEWs with a UNICAST REQUEST to the server (byte-assertable in the 1222-B capture: dst 02:00:00:00:00:02, src/dst IP 10.0.0.2, ciaddr 10.0.0.2) and restarts the lease on the ACK; at elapsed ~93-95 it REBINDs with a BROADCAST REQUEST (frame 4: dst ff:ff:ff:ff:ff:ff); the counters renew=1,rebind=1,renewed=2,expired=0. Run B (lease 100 s, delay 106) — net dhcp: lease expired (elapsed=… >= lease=100), the released report (dhcp=idle,ip=0.0.0.0,…,expired=1 — arp.own_ip cleared), and the client RECOVERS: a fresh DISCOVER → BOUND again. The runner's --net-dhcp-respond <ip>:<lease> + --script2/3-delay knobs are flag-gated (defaults unchanged — every pre-N9 gate byte-identical). The 37-gate verify-vz aggregate re-ran green 37/37 (artifacts live-net-dhcp-renew-*, m5-net-dhcp-renew-vz-sweep.log) |
| Live TCP gate | bash tools/verify-live-net-tcp.sh |
✅ PASS 2026-08-12 | claim 7026 (milestone five, card N10): the bounded RFC 793 TCP client live on real VZ in THREE runs. Run A (deterministic file-handle): --net + --net-tcp-respond 10.0.0.2:9999 + --net-arp-respond 10.0.0.2 — the guest's net tcp runs the FULL lifecycle: SYN (54 B, byte-exact in the capture — src 8000 → dst 9999, proto 6, flags 0x02) → the host's SYN-ACK (the FIXED server ISN 0x12345678, ack = the guest's ISN+1) → the handshake ACK (ack 0x12345679) → ESTABLISHED → net tcp send 5 (the data segment 01 02 03 04 05) → the host echoes it (the ACK 0x1234567e) → net tcp recv prints 01 02 03 04 05 → net tcp close (FIN) → FIN-ACK → the final ACK (0x1234567f) → closed; then a SECOND connect + net tcp reset (a real RST). The counters syn=2,synack=2,ack=4,data_s=1,data_r=1,fin=1,finack=1,rst_s=1,rst_r=0,timedout=0,mal=0; the 533-byte capture's NINE frames are verified by the gate's python walk (the seq/ack chain, the flags, the ports, the MACs, the payload, and EVERY TCP checksum byte-exact). Run B (deterministic black hole): --net + --net-arp-respond ONLY — the host answers ARP but never TCP — the bounded connect timeout: tcp=syn_sent,syn=1,synack=0 → after 31 s net tcp: connect refused (no SYN-ACK after 30s) → tcp=idle,peer=0.0.0.0:0,timedout=1. Run C (real NAT, rides --net-nat): the CLAIM-TIME observation — the VZ NAT gateway answers the SYN with a RST (no TCP listener on 192.168.64.1:9999 — connection refused; rst_r=1, tcp=closed, the drive returns the client to idle; honestly recorded in the hardware contract [observed] with the saved logs under artifacts/live-net-tcp-explore/, never faked; if a future host's NAT silently drops instead, the honest timeout path fires — proven by Run B). The 38-gate verify-vz aggregate re-ran green 38/38 (artifacts live-net-tcp-*, m5-net-tcp-vz-sweep.log) |
| Live TCP retransmission gate | bash tools/verify-live-net-tcp-rto.sh |
✅ PASS 2026-08-12 | claim 5357 (milestone five, card N11): the bounded retransmission + retransmit timer live on real VZ in THREE runs. Run A (deterministic file-handle, ARP-responder-only — a black-hole SYN): the idle-loop RTO poll retransmits the pending SYN autonomously — net tcp: syn retransmitted (1/10) / (2/10) — the report reads retx=2,abort=0 (still tcp=syn_sent — the 30 s connect timeout has not expired), and the capture holds the byte-identical SYN frames (the SAME seq/bytes/checksums — a python walk verifies them). Run B (deterministic file-handle + the full responder): the SYN-ACK clears the pending state — retx=0 in the report despite the 7 s wait (past the RTO), no retransmission lines, and the capture holds EXACTLY ONE SYN (the handshake completes — established). Run C (deterministic file-handle + the :handshake responder — SYN-ACK yes, data silent, the data black hole): connect → established → send 5 (never ACKed) → the idle loop retransmits the data TEN times (data retransmitted (1/10) … (10/10)) → net tcp: retransmission limit reached (10) — connection aborted → the report releases the connection (tcp=idle,peer=0.0.0.0:0,…,retx=10,abort=1), net tcp reads no connection, and the capture holds the ELEVEN byte-identical data frames (the initial + the 10 retransmissions). The runner's --net-tcp-respond …:handshake mode is flag-gated (default unchanged — every pre-N11 gate byte-identical). The 39-gate verify-vz aggregate re-ran green 39/39 (artifacts live-net-tcp-rto-*, m5-net-tcp-rto-vz-sweep.log) |
| Live FAT32 storage gate (fs hard gate) | bash tools/verify-live-fs.sh |
✅ PASS 2026-08-09 | hard gate 5 closed, upgraded to a real FAT driver (claim 6420, 1/1 pair) — ls/cat/write persist through reboot on the disk itself: run A wrote hello world to the ESP's FAT volume via the virtio-blk transport (write-ok, hello.txt [esp] listed, cat reply) and run B — a fresh boot against the same disk image — still listed HELLO.TXT [esp] (the FAT 8.3 short name) and printed the content. The volume lists the loader's per-boot files too (EFI/, KERNEL.BIN, BOOTED.TXT, MEMMAP.TXT, LOADER.TXT). Two hardware discoveries landed in the claim: VZ presents virtio-blk as DID 0x1042 (the spec's modern virtio-blk DID — the transitional scheme maps net 0x1041, blk 0x1042, console 0x1043), and resets the device at ExitBootServices — the queue is re-armed post-MMU (blk_rearm, common-config MMIO writes verified DRIVER_OK). NVRAM variables are no longer the persistence medium; artifacts live-fs-* |
| Bad-handoff failure gate | bash tools/verify-bad-handoff.sh |
✅ pass | artifacts/m2-badhandoff-fix-after.txt: RC.TXT → kernel_rc=0x0000000000000002, gate exits 0 (first observed 2026-08-06, fixed shim) |
| Marker fallback gate (gate work item 3) | bash tools/verify-marker.sh |
✅ pass | artifacts/m2-marker-gate.txt (2026-08-07, re-verified artifacts/m2-marker-reverify-20260807.txt): NVRAM ladder M2_ENTRY → … → M2_MAPD! → M2_MMUP! → M2_SERIA → M2_READY — identity-map switch completes and probe/transport are reached (see gate work item 3, claims 0009/0010/0013) |
| MMU-takeover root cause & fix (claim 0010) | bash tools/verify-marker.sh |
✅ fixed 2026-08-07 | ladder now advances M2_MAPD! → M2_MMUP! → M2_SERIA — the identity-map switch completes on VZ for the first time (artifacts/m2-mmu-takeover-gate.txt; see claim 0010) |
| VZ serial console discovery (claim 0013) | pre-exit probe + NVRAM dump | ✅ discovered 2026-08-07 | console = modern virtio-pci (bus 0 D5 VID=0x1af4 DID=0x1043 class=0x078000), ECAM 0x40000000, BAR0 (64-bit) @ 0x100010000, transport decoded + armed pre-exit (SEL=VIRTIO, ladder M2_READY); declared MMIO windows decoded as Apple efivars store + internal debug UART. Gate blocked at the time (post-MMU transport access hung, claims 0018/0020) — resolved by claim 1517 (T0SZ=16 + TLBI at the switch) |
| NVRAM console channel (claim 0015) | bash tools/verify-nvram-console.sh |
✅ PASS 2026-08-07 | first post-exit console bytes from a real VZ run: 69–70 chunks reconstructed from efi-vars.bin — takeover banner, full memory map, probe record, shell banner, and real version/mem/echo/help command output (artifacts/nvram-console-gate.txt). Found + fixed a latent kernel bug on the way (ADR 0005: const function-pointer tables are not relocated by the flat loader — the first vtable dispatch on real hardware faulted; tables now built at runtime in BSS). See Current blocker |
RESOLVED 2026-08-08 (claims 1517 + 6684 + 0527). The post-MMU virtio TX blocker is fixed in production (claim 1517: T0SZ=16 + TLBI at the switch — the start-level mismatch from claims 6460/7896) and the RX path is live (claim 6684: the polled virtio receive queue delivers host keystrokes end to end —
bash tools/verify-live-transcript.shasserts the realdipshit>transcript invm-serial.log, 3/3 boots) and the live reboot/shutdown observation is done (claim 0527:rebootresets the machine,shutdownpowers it off — 4/4 boots viabash tools/verify-live-reboot.sh) and the filesystem gate is closed (claim 6420:ls/cat/writepersist through reboot on the real disk via the FAT32 storage driver,verify-live-fs.sh, 1/1 pair). Every M1.5 hard gate now passes (all 7 closed; the last — the deferred filesystem one — closed 2026-08-09 by claim 3475 and upgraded to a real FAT driver by claim 6420). The post-M1.5 allocator and timer interrupt cards are now complete (claims 3972/5162/9187); tasks are next.
Historical blocker (superseded by claim 1517): reliable post-MMU access to the already-discovered virtio-pci console transport (class B) was required before live RX and a real interactive dipshit> session. The console is a modern virtio-pci device (bus 0 D5 0x1af4/0x1043, BAR0 0x100010000, claim 0013); the transport arms pre-exit (M2_READY) and TX works pre-exit (claim 0017) and post-ExitBootServices on the firmware translation (claim 0020 phase B), but hung on the first post-MMU BAR/common-config read after the DipshitOS identity-map install (claims 0018/0020, phase C/D). ExitBootServices itself is exonerated; the MMU switch (B→C) was the transition that destroyed access (claim 0020). Firmware and kernel memory attributes are byte-identical (claim 0021), so the hang was not an attribute mismatch; the no-TLBI safety contract and its validity window were in ADR 0006 (claim 0022; superseded by claim 1517). The NVRAM fallback console (claim 0015) carried post-exit bytes via runtime SetVariable (69–70 chunks, shell + commands observed) but is not the virtio serial pipe; the mock transcript (zig build test-console, class A) is a portable host test, not VZ hardware. Ordering remains explicit: post-MMU virtio TX (done, claim 1517), then virtio RX / live transcript — RX cannot bypass the TX/MMU layer. Claims 6460/7896 characterized the layer: correcting the T0SZ start-level mismatch (25→16) restored end-to-end post-MMU TX in 6/18 boots, and the 4-cell walk-probe matrix proved the residual was stale-TLB interference, not a device hang — cell B (T0SZ=16 + TLBI) completed 9/9, which is exactly what claim 1517 makes production (see docs/gate-inventory.md). Class definitions: docs/gate-inventory.md (class A = portable/CI, class B = Apple-silicon/VZ hardware, class C = interactive, class D = diagnostic); a green CI badge proves class A only.
Re-verified marker/host gates on merged main (2026-08-07): host-console gate ✅ artifacts/m15-host-console-reverify-20260807.txt; marker re-verify ladder M2_ENTRY → … → M2_READY (artifacts/m2-marker-reverify-20260807.txt); bad-handoff re-verify ✅ artifacts/m2-badhandoff-reverify-20260807.txt.
From the bad-handoff run before the fix (re-verified 2026-08-06), fresh from
artifacts/bad-handoff.img:
BOOTED.TXT— written by the loader: observed (loader executed under firmware).LOADER.TXT— written by the loader: observed —base=0x7e4df000 size=0x823e8 entry_offset=0x18, andram_first8=0xaa0103eaaa0003e9, which decodes tomov x9, x0; mov x10, x1— the first two instructions of the kernel's naked shim. The image content is atbase+0and the jump lands on the shim as designed.RC.TXT— absent before the fix: the kernel never returned to the loader.vm-serial.logis empty (expected forConOut; the runner'sterminal=trueis only the no-marker default).
Bad-handoff root cause (now observed, fixed 2026-08-06): the naked
_start shim's bl kernel_main overwrote the link register with the shim's
own return address (disassembly of the current kernel ELF: bl 0x3c at
shim offset 0x30, so LR = 0x34). The shim's final ret therefore looped
0x34 → 0x38 → 0x34 forever instead of returning to the loader, so the
pre-exit return bad_handoff could never reach the loader and RC.TXT was
never written. Fix: save the loader's x30 in x20 (callee-saved under
AAPCS64, preserved by kernel_main) before the bl and restore it before
ret — two instructions in kernel/src/main.zig _start. After the fix:
RC.TXT = kernel_rc=0x0000000000000002 and verify-bad-handoff.sh exits 0
(artifacts/m2-badhandoff-fix-after.txt).
The VZ serial gate is a separate, still-open question: with the fix, the
bad-handoff VM provably returns through the shim, but every good-path run
still produces no serial output and the kernel never returns. Re-run
2026-08-06 21:19 (claim 0002, artifacts/m2-vz-run-20260806.txt):
vm-serial.log 0 bytes after a 30 s run; loader evidence intact
(BOOTED.TXT exact content, LOADER.TXT base=0x7e4df000 size=0x823e8 entry_offset=0x18, ram_first8=0xaa0103eaaa0003e9 = the shim's first two
instructions mov x9,x0; mov x10,x1 — the loader→shim jump is proven);
RC.TXT absent (good path, expected — D6).
Historical — how the serial gate's silence was first explained (claim 0009, superseded by 0010/0013)
The ADR 0004 D4 marker fallback was implemented and its first VZ runs
ended at M2_MAPD! (claim 0009) — the ladder discriminated the death site
as the MMU-takeover window before the serial probe ever ran
(artifacts/m2-marker-gate.txt, historical). A diagnostic run with the
switch disabled showed M2_MAPD! → M2_MMUP! → M2_SERIA (layout=none halt).
Claim 0010 then root-caused and fixed this: the guest implements the
ARMv8.1+ TCR_EL1 layout (claim 0010; re-captured by 0021
artifacts/fw-mmu-capture-lines.txt — raw m2-firmware-regs.txt not in
this checkout), the identity map now covers undeclared MMIO as Device, and
the tlbi vmalle1-forced re-walk that faulted on VZ is dropped (see TLBI
bullets in hardware-contract.md and ADR 0006). The ladder now runs
M2_MAPD! → M2_MMUP! → M2_SERIA (artifacts/m2-mmu-takeover-gate.txt).
That "device absence in the declared windows" reading of M2_SERIA is
itself superseded by claim 0013 (declared windows are Apple's efivars store
- debug UART; the real console is virtio-pci outside them). See Current blocker and The device absence is now fully explained.
Also observed (still current): the ADR 0004 D4 memory-dump form is impossible on VZ — guest RAM is not host-mapped (claim 0009).
The device absence is now fully explained (claim 0013, 2026-08-07). The
console is not in the declared MMIO windows at all. Pre-exit diagnostics
persisted through the NVRAM channel (the probe dump variables DipshitP* in
artifacts/efi-vars.bin) decoded the ground truth: 0x01000000..0x01010000
contains Apple's EFI variable-store region (raw bytes spell efivars\0),
and 0x20050000..0x20051000 is a PL011-family PrimeCell UART whose DR
writes produce zero bytes in vm-serial.log (Apple's internal EFI debug
UART). ACPI names no console (no SPCR/DBG2; the DSDT, Apple's own Apple Vz
AML, declares only PCI0 + efivars). The VZ serial attachment is a
modern virtio-pci console — bus 0 device 5, VID=0x1af4 DID=0x1043 class=0x078000 — found by pre-exit PCI enumeration over ECAM 0x40000000
(MCFG). Its 64-bit BAR0 is firmware-assigned at 0x100010000 (above the
4 GiB identity-map blanket; assignment varies across boots, which is why the
fixed-window probe never saw it), and the transport is fully armed pre-exit
(SEL=VIRTIO, ladder reaches M2_READY). The remaining wall is post-MMU access to the transport window hangs on
VZ — the first post-switch BAR/common-config read does not return
(claims 0018/0020; the MMU switch is the killer, not ExitBootServices).
Claim 0015 then carried the console bytes over a post-exit-safe channel
(the runtime SetVariable NVRAM channel — next paragraph); the open work
is reliable post-MMU access to the transport (see
Current blocker).
The post-exit-safe channel is now live (claim 0015, 2026-08-07). The
NVRAM console channel carries the kernel's console bytes over runtime
SetVariable after ExitBootServices (the channel claim 0009 proved
alive). bash tools/verify-nvram-console.sh passes: 69–70 chunks
reconstructed from efi-vars.bin give the takeover banner, the full
25-descriptor memory map, the probe record, the seam diagnostics, the
shell banner, and real command output (version, mem, echo, help)
— the first post-exit console evidence from a real VZ run
(artifacts/nvram-console-gate.txt, claim 0015). Two findings surfaced:
- Latent kernel bug fixed (ADR 0005): the flat loader copies the
kernel image to a runtime base with no relocations, so every
constfunction-pointer table in.rodata(vtables, the 14-command registry, string-slice tables) held link-time absolute addresses. The first vtable dispatch on real hardware — claim 0015's shell seam — faulted instantly; host tests never caught it (macOS relocates test binaries). All such tables are now built at runtime in BSS. - The NVRAM store is ~61 KiB writable, not 128 KiB — the probe-dump variable was starving the chunk channel; it is gated off in nvram builds (the console stream carries the same evidence). The 64-chunk cap also truncated the session (the store still had ~47 KiB free); raised to 128.
The virtio-console TX gate (claim 0002, zig build run) was blocked at
that time (now passing since claim 1517); claim 0015 is the fallback
channel claim 0013 named, and it makes the
milestone's console evidence host-observable. The VZ post-exit death
window was flaky (claim 0009, re-observed: runs sometimes die at
M2_MAPD! or mid map-dump after M2_TXOK!); the gate retries up to 3
boots with fresh stores.
Do not add more kernel-proper plumbing before making the machine interactive. The milestone-two kernel already owns the machine: it ends UEFI Boot Services, installs its own page tables, probes the MMIO serial candidates (PL011/16550/virtio-MMIO), and drives a polled TX-only console (ADR 0004 — "no interrupts, no FIFO/DMA, no RX path") before entering a terminal WFE loop. That console is exactly enough to serve an interactive monitor — the monitor is simply the loop's payload. No new firmware dependencies, no allocator, no interrupts, no storage drivers.
One immediate blocker, on both ends of the wire: the kernel console has no
RX path at all (ADR 0004), and until 2026-08-06 the VM runner's serial
attachment sent guest output to a file with a nil host-to-guest input
handle (VZFileHandleSerialPortAttachment(fileHandleForReading: nil, ...)
in host/vm-runner/Sources/VMRunner/main.swift). The M1.5 host-plumbing
slice (steps 4–7, landed 2026-08-06) added a --console mode that wires a
real stdin-backed input handle and tees guest output live; the evidence
path (zig build run) keeps the nil-input attachment, unchanged. Until
keystrokes can actually be read by the guest, the monitor is output-only.
DIPSHITOS 0.1
AArch64 firmware-assisted kernel monitor
256 MiB detected
Type 'help' before touching anything expensive.
dipshit> help
about explain this questionable system
cat print a file from the ESP
clear clean up the crime scene
echo repeat your regrettable decisions
elephant operational mascot diagnostics
handoff display boot-to-kernel ABI data
ls list files on the ESP
mem summarize the EFI memory map
reboot restart the machine
shutdown request power-off
version display build information
write write text to a file
dipshit>
-
zig build,zig build image, and the existing regression checks still pass. (The bad-handoff regression gate was failing; its root cause (shim LR clobber) was fixed 2026-08-06 — the gate now passes, see Gate status.) -
zig build consolereachesdipshit>— the post-MMU TX fix (claim 1517) puts the live banner +dipshit>prompt invm-serial.logon real VZ runs. - Host keystrokes reach the kernel (RX path closed end to end) — PASS 2026-08-08 (claim 6684): the polled virtio receive queue delivers host keystrokes;
verify-live-transcript.shdriveshelp/version/mem/echointo a live session and asserts the replies invm-serial.log(3/3 boots). - At least ten commands work (31 commands, host-tested; the registry grew 20 → 21 with claim 5844's
pci, → 22 with claim 5275'stasks, → 23 with claim 3594'ssyscalls, → 24 with claim 6120'suaccess, → 25 with claim 5804'saddrspaces, → 26 with claim 6729'sspawn, → 27 with claim 6783'sexec, → 28 with claim 2665'srandom, → 29 with claim 3678'smount, → 30 with claim 3848'sprocs, → 31 with claim 7786'skill; real command output observed post-exit via the NVRAM channel, claim 0015, and live post-MMU via claim 1517). -
ls,cat, andwritepersist through reboot — PASS 2026-08-09, upgraded to a real FAT storage driver (claim 6420): claim 3475's pre-exit snapshot + NVRAM persistence (passing 1/1) is replaced by a live FAT32 driver on the ESP (kernel/src/fat.zig— GPT + FAT32 mount/list/read/write with injected sector I/O, 11 host tests) over a virtio-blk transport (kernel/src/virtio_blk.zig— DID 0x1042 on this VZ, the spec's modern virtio-blk DID; queue 4, one request at a time).writenow allocates clusters, updates both FAT copies, and writes the directory entry to the disk itself; run A persistedhello worldand listed it[esp], and run B — a fresh boot against the same disk image — still listsHELLO.TXT [esp](the FAT 8.3 short name) and prints the content. Hardware discovery fixed on the way: VZ resets the virtio-blk device at ExitBootServices (its status reads 0 post-exit), so the queue is re-armed post-MMU (blk_rearm, common-config MMIO writes — verified DRIVER_OK + live reads/writes); the NVRAM variable store is no longer the persistence medium.bash tools/verify-live-fs.sh, class B, 1/1 pair. (Claim 3475's other fixes stand: the per-flush TX markers/probe persist are first-flush-only /-Dprobe-var-gated.) - A scripted console session passes automatically (asserting in
vm-serial.log) — the mock transcript (zig build test-console, class A) passes, and the livevm-serial.logtranscript assertion now passes too (bash tools/verify-live-transcript.sh, claim 6684, class B). - The VM can reboot or shut down from the shell — PASS 2026-08-08 (claim 0527): a real EFI
ResetSystemdriven from a livedipshit>shell is observed end to end on VZ —rebootresets the machine (second full takeover, fresh memory-map key invm-serial.log) andshutdownpowers it off (VM state → stopped), 4/4 boots viabash tools/verify-live-reboot.sh(class B). The mechanism itself shipped + unit-proven in claim 0011. (The claim-0011M2_RST!marker write is best-effort by design and was lost in the teardown race; the machine-level reset/power-off is the evidence.) - No allocator, MMU replacement, interrupts, scheduler, or userspace is falsely claimed.
Moved 2026-08-06: the per-step tracker and the best-agent-split tables used to live in this file; agents marking steps collided here with gate and milestone-status edits. They now live in the per-milestone trackers — the active
docs/march-m3.mdand the archiveddocs/march-m15.md(M1.5, closed 2026-08-09) — update a step's row there, never here. This file holds milestone-level facts only (position, gates, hard gates) plus pointers.
Ordering after M1.5 is explicit and enforced by evidence classification (docs/gate-inventory.md):
Reliable post-MMU access to the already-discovered virtio-pci console transport (post-MMU virtio TX, class B).DONE 2026-08-08 (claim 1517) — root cause (translation start-level mismatch + stale-TLB crutch, claims 6460/7896) fixed in production: T0SZ=16 +tlbi vmalle1at the switch;zig build runpasses (banner + memory-map + terminal state invm-serial.log).Virtio RX / live transcript (class BDONE 2026-08-08 (claim 6684) — the polled virtio receive queue delivers host keystrokes end to end;live-transcript-rx).bash tools/verify-live-transcript.shasserts the livedipshit>transcript invm-serial.log(3/3 boots).Live reboot/shutdown observation (M1.5 close-out, hard gate 6).DONE 2026-08-08 (claim 0527) — a real EFIResetSystemfrom a livedipshit>shell observed end to end (bash tools/verify-live-reboot.sh, 4/4 boots:rebootresets the machine,shutdownpowers it off). The last hard gate — the filesystem one — closed 2026-08-09 (claim 3475:ls/cat/writepersist through reboot via the pre-exit ESP snapshot + NVRAM-persisted writes,verify-live-fs.sh) and upgraded the same day to a real FAT32 storage driver (claim 6420):writepersists to the ESP's FAT volume through a virtio-blk transport, files survive reboot on the disk itself, and the NVRAM persistence medium is gone. All 7 M1.5 hard gates pass; the milestone is taggedm1.5-interactive-monitor(2026-08-09).A physical page allocator over the captured EFI map.DONE 2026-08-08 (claim 3972) — first-fit bitmap allocator over the captured map's ConventionalMemory (fixed 128 KiB BSS bitmap over the 4 GiB identity-map span), wired post-exit inkernel_main;pages/pages selftestmonitor commands; 18 unit tests; live-observed on VZ (total=0xee2bpages across 7 regions; selftest allocates the largest contiguous run and restores the pool). Extended 2026-08-09 (claim 5162): the pool now also covers loader + boot-services regions, with exclusion ranges protecting the live kernel image, stack, handoff page, and captured-map buffer —pagesreportsexcluded=…; 25 alloc/memmap unit tests; full class-A set green at HEAD19ad92c(artifacts/verify-portable-5162.txt).Exception vectors (first half of item 5).DONE 2026-08-08 (claim 9746) — VBAR_EL1 vector table + basic synchronous/IRQ handlers installed post-MMU (kernel owns EL1; a pre-exit VBAR write was measured catastrophic on VZ — see the claim),dipshit> faulttriggers a realudfthat is reported and resumed live (class B gatetools/verify-live-exceptions.sh, 2/2).GIC + timer interrupts (second half of item 5).DONE 2026-08-09 (claim 9187; supersedes claim 7948's blocker conclusion). The spec-corrected GICv3 driver uses MADT types 0x0B/0x0C/0x0E, targets SGI/PPI registers in the redistributor's+0x10000SGI frame, selects the boot CPU frame, and programs the GTDT trigger mode. On real VZ, periodic CNTP PPI 30 enters the claim-9746 EL1 IRQ vector, is acknowledged, handled, EOI’d, and re-armed;bash tools/verify-live-timer.shrequires five IRQ ticks and zero poll ticks and passes 3/3 while the shell remains responsive. The old idle-loop timer poll is no longer used in production.Tasks: tick-driven round-robin scheduler.DONE 2026-08-09 (claim 5275) — the first milestone-three tasks card: two kernel tasks (the shell/main task + a demo worker on its own static BSS stack) preempt at every timer PPI, round-robin, with a minimal save/restore (vector-frame pointer + ELR/SPSR only — the claim-9746 stubs already keep the register file on the stack).dipshit> tasksreports per-task saves/resumes/advances; the worker reports its progress from the shell idle loop (tasks worker advances=N); host tests cover frame construction, round-robin round-trips, and the report machinery. Live gatebash tools/verify-live-tasks.shPASS 3/3 (worker report line after >= 2 real context switches + responsive shell), and the strict live-timer gate still passes 3/3 under preemption (heartbeat/report lines now snapshot their counters at the event). Live regressions all green: live-exceptions, live-transcript, live-reboot, live-fs. Class-A green. No userspace, no MMU changes — a later card adds userspace.First EL0t task + SVC boundary.DONE 2026-08-09 (claim 8215, PR #60) — a statically linked EL0 task, page-local user text/stack apertures, x8-selectedsvc #0, SP_EL0-preserving scheduling, and a strict live userspace gate.Frozen syscall ABI + dispatch table.DONE 2026-08-10 (claim 3594) — ADR 0007 freezes x8 number, x0–x5 arguments, x0 result, slots 0–3 implemented and 4–63 reserved. The runtime-built table, bounded user-aperturesys_write, cooperative yield, non-returning exit, deterministic counters, and corrected one-shot live SVC gate pass.uaccess: fault-safe copy-in/copy-out.DONE 2026-08-10 (claim 6120) —kernel/src/uaccess.zigadds boundedcopy_in/copy_outover the kernel-known EL0 apertures (user text read-only, user stack read-write) with the ADR 0007EFAULT(-3) contract enforced (out-of-region, overflow, unmapped, permission), plus a masked fault-recovery window: a real EL1 data abort during a copy is latched, ELR advanced past the 4-byte faulting instruction, and the copy returns EFAULT instead of crashing the kernel (an optimizer-reordering hazard that parked on the first live run was fixed with volatile window state).sys_writemigrated onto uaccess; theuaccessmonitor command provesvalid=1 fault=1 recovered=1on VZ; the EL0 payload passes an unmapped bad pointer, observes-3, and survives to write its marker. New class-B gatebash tools/verify-live-uaccess.shpasses 1/1;verify-live-svcupdated to the payload's three writes (calls=3).Per-task user address spaces.DONE 2026-08-10 (claim 5804) — every task gets its own TTBR0 root; the EL0 task's root is a clone of the kernel identity tree with its text+stack leaves overlaid at their user VAs, so EL0 can reach ONLY those leaves (kernel RAM, firmware, and MMIO are EL1-only AP=0b00 → permission faults), with UXN/PXN (W^X) on every user leaf. VZ TTBR1 fallback: the original kernel-in-TTBR1 KVA-shadow design was measured incompatible on VZ (TTBR1 walks fault at the first descent with 4 KiB tables — the signature of 64 KiB table-address masking — and Normal-WB TTBR1 data accesses abort even with 64 KiB-aligned tables; see ADR 0007 +hardware-contract.md), so the kernel stays identity-mapped in TTBR0 with TTBR1=0 and per-task isolation comes from switching TTBR0 between roots that all carry the EL1-only kernel overlay. The scheduler switches TTBR0 per task; theaddrspacesmonitor command reports TTBR1=0, T0SZ=16, per-task TTBR0 roots, and the user root's leaf inventory (el0=4,el0_device=0on VZ). New class-B gatebash tools/verify-live-addrspaces.shPASS 1/1, all live regressions green (uaccess/svc/userspace/tasks/timer/exceptions/transcript).User task lifecycle.DONE 2026-08-10 (claim 6729) — the scheduler pool gains an explicit lifecycle:Stateper slot (free→ready→running→zombie→free), boundedspawn(first free slot, null when full),exit_current→ zombie, and the scheduler-owned idle task (always-ready ring fallback; reaps one zombie per iteration so the pool drains without a parent/child relationship). Thespawnmonitor command exercises a runtime spawn on a dedicated demo stack;tasksreports per-rowstate=+ pool/zombie header; reports are per-task slots so the worker cannot starve the demo's. Load-bearing fix (measured on VZ): the claim-9746 vector frame saved only x0..x17+x30, so a context switch resumed the next task with the preempting task's live callee-saved registers — the shell'smonin x19 was clobbered by the worker's loop counter (≈0x872) and the shell's next console write faulted (esr=0x96000021,far=0x872; a VM-level error when idle was registered). The frame is now 32 slots (x19..x28+x29 saved; sharedexc_restore_tail; stubs stay inside their 128-byte slots), making preemption of compiled tasks safe. Theaddrspacescommand also printsuser root=directly (the reaper removes the exited user's task row before the gate's post-exit script runs). New class-B gatebash tools/verify-live-lifecycle.shPASS 1/1; all live regressions green (addrspaces/uaccess/svc/userspace/tasks/timer/exceptions/transcript/fs/reboot).Load and exec a real user program from the ESP.DONE 2026-08-10 (claim 6783) — a separate EL0 program (user/src/main.zig, naked asm on the fixed syscall ABI) is built into a flatUSER.BIN(elf2bin DSK1) and embedded on the ESP by the image builder (mkfat32.py+make-image.sh+zig build user). The newexec [<file>]monitor command reads it through the claim-6420 FAT path into a fixed 4 KiB BSS page, strips the 24-byte header, rebuilds the EL0 user root around the loaded page with claim 5804'sbuild_user_root(proven to work post-install because the kernel stays identity-mapped —@intFromPtris still physical), and spawns it as an EL0t task — gated on the previous user task being gone (one user program at a time; the lifecycle's closed loop). The loaded program executes at EL0 from the ESP-loaded page: itssys_writemarkers land in the serial log directly, two sequenced pings prove SVC round-trips from a loaded image, andsys_exit(status 42) + the idle reap close the lifecycle. Two live-measured fixes: the user linker script must discard.eh_frame(the orphan sections landed at VMA 0, so the flat image's entry pointed at CFI bytes), and exec must strip the DSK1 header in place (the user-root leaf masks phys to page granularity, so mappingprogram+24mapped the header page — the EL0 task fetched "DSK1" and faulted on the zero pad). New class-B gatebash tools/verify-live-exec.shPASS 1/1; all shared-seam regressions green (lifecycle/addrspaces/uaccess/svc/userspace/tasks/timer).Blocking syscalls: sleep/yield/wakeup in the tick scheduler.DONE 2026-08-10 (claim 3200) — a newsys_sleep(ticks)row (slot 4, ADR 0007 amendment) blocks the calling task for N scheduler ticks; the scheduler gains an explicitblockedstate with per-task wakeup deadline, a tick counter advancing on every timer PPI, and a timer-drivenwake_expired(IRQ context, console-free) that moves expired sleepers back toready— the same resume path assys_yield. The ESP-loaded user program is extended with a cooperative yield, a 2-tick sleep (asserting the 0 return), and a post-wake marker before exiting with status 43. The worker's advance lines during the sleep window prove other runnable tasks keep progressing.user_root_in_usenow countsblockedtasks too — a sleeping user program still owns the user root. New class-B gatebash tools/verify-live-sleep.sh; all shared-seam regressions green.- Milestone-four close-out (DONE 2026-08-11, claim 2839) — full class A
(11/11) + class B (28/28) gate re-run at the candidate HEAD
9d7e4d5; milestone taggedm4-processes(the claim-0707 pattern). - Milestone six, card G1 — virtio-gpu transport + framebuffer (DONE
2026-08-12, claim 6053; prompt
docs/m6-gpu-prompt.md). The FIRST NON-BLANK GUEST FRAMEBUFFER is live on VZ:--displayrunner mode,kernel/src/virtio_gpu.zig,screen/screen fill/screen peek(registry 34→35), gatetools/verify-live-screen.shPASS 1/1, and the claim-time observations (DID 0x1050, VER1-only, reset at ExitBootServices, B8G8R8X8 + opaque alpha, virtio-gpu 1.2 wire shapes). The full 35-gateverify-vzaggregate re-ran green.What's next: card G2 — framebuffer text rendering.DONE 2026-08-12 (claim 3194):text.zig(the built-in 8x8 bitmap font, putc/puts/cursor/scrollback/clear; 21 host tests against a mock canvas) paints the banner +dipshit>prompt on G1's framebuffer;text/text put/text clear(registry 35→36); gatetools/verify-live-text.shPASS 1/1 (the decoded capture shows glyphs — green fg over the dark bg, screen no longer monochrome); the full 36-gateverify-vzaggregate re-ran green 36/36.What's next: card G3 — Road Pops, the boot terminal goes graphical.DONE 2026-08-12 (claim 1574):road_pops.zigtees the console — serial shared seam + G2's text layer, drained one present per output batch by the shell idle loop; the boot banner is the shell's own, rendered by the tee;roadpopscommand (registry 36→37); gatetools/verify-live-roadpops.shPASS 1/1 (the decoded capture shows banner + live session glyphs below it); the 37-gateverify-vzaggregate re-ran green 37/37. Post-G3 hardening (the SCK switch, 2026-08-12): the pixel gates now REQUIRE the ScreenCaptureKit composited-window evidence (any cacheDisplay fallback fails), and introduced thetools/verify-live-glyphs.shmirror-tripwire gate. Issue #125 correction (claim 8742, 2026-08-14): the imported font rows are LSB-left, but BOTH kernel rasters read bit 7 as the left pixel; the first decoder repeated that same wrong convention, so its historical PASS was self-consistent, not independent proof of orientation.font8x8.row_pixelnow owns the LSB-left contract for the terminal and Driving Award renderers, while the decoder normalizes source rows to screen order and pins the convention with a hard-coded asymmetricCgolden. [observed] The repaired gate passed on VZ/ScreenCaptureKit: the terminal decoded forward with 0 unknowns / 604 ink versus 549/595 mirrored; the clock decoded exactly as titleclockand bodyDRIVING AWARD, versus 4/5 and 10/13 unknown glyphs mirrored. The earlier 38/38 aggregate remains historical; its glyph-orientation result is superseded by this claim's targeted live rerun (artifacts/live-glyphs-gate.txt,artifacts/gpu-screen-15s). What's next: milestone seven — input (keyboard + pointer) so keystrokes come from the screen side. [observed] 2026-08-13 (claim 3868): VZ exposes keyboard/pointer as an Apple XHCI USB controller (VID=0x106b DID=0x1a06 CLS=0x0c0330) with USB HID devices behind it — NOT the hypothesized virtio-input (DID 0x1052), which does not exist in the framework. The G4 card was split into its own milestone (I1 XHCI transport → I2 USB enumeration + HID → I3 event FIFO + keycode decode); then G5 Driving Award back in milestone six. Card I1 (claim 4272) DONE 2026-08-13 — the XHCI host-controller transport (MMIO + command/event rings + NO-OP + port status) is live on VZ. Card I2 (claim 4116) DONE 2026-08-13 — USB enumeration + HID is live on VZ: BOTH devices enumerate end to end (port reset → Enable Slot → Address Device → config descriptors → Set Configuration → interrupt-IN armed) — the keyboard (port 9, PID 0x8105, boot protocol, 8-byte reports) and the absolute pointer (port 10, PID 0x8106, non-boot, 10-byte reports); a synthesized host keyDown produced the observed 8-byte report00 00 04 00 00 00 00 00(mod 0, HID usage 0x04 = 'a'). Card I3 (claim 6050) DONE 2026-08-13 — the bounded BSS event FIFO + keycode decode feeds Road Pops' line editor: the runner's new--input-stringseam (one synthesized NSEvent per keyDown/keyUp; VZ has no keyboard API) typedinput\nand the guest's owninputcommand reportedevents=6(i,n,p,u,t,Enter) withdropped=0— the first screen-side keystrokes reach the terminal end to end. Plandocs/march-m7.md. Card G5 (claim 1543) DONE 2026-08-13 — Driving Award, the window manager:kernel/src/driving_award.zig(bounded BSS registry, z-order, focus, hit-test, dirty-rect compositor) makes Road Pops window 0 and a 1 Hz clock overlay window 1;win/win focus/win raise/win hit(registry 39→40); gatetools/verify-live-win.shPASS 1/1 (two overlapping windows with the right z-order — the decoded capture shows the clock's amber title bar + navy body over the terminal — and a keyboard-typedunamelanding in the focused terminal). The 42-gateverify-vzaggregate now includeslive-win; the default VM stayed byte-identical. Card G6 (claim 0487) DONE 2026-08-13 — the draw/window syscall seam: the ADR 0007 slots 12/13/14 (sys_win_open/sys_win_fill/sys_win_present, implemented 12 → 15, then a teardown follow-on adds slot 15sys_win_close+win close→ 16) expose the G5 user-window surface to EL0; WIN.BIN opens a bounded kernel-owned window (id 2..3, fixed BSS back-buffer ≤ 256×192 B8G8R8X8), fills it (dark-blue background + red/cyan/white blocks), presents it, and exits 87; gatetools/verify-live-win-syscall.shPASS 1/1 (win: windows=3 focused=2+win[2]: user user rect=64,64,256,192z=2,syscallsimplemented=16 with open=1/fill=4/present=1 + slot 15sys_win_closeregistered, and the decoded capture shows the window's own content over the terminal). Teardown follow-on:win close <n>sys_win_close(slot 15) release a user window so the id can be re-opened instead of leaking until reboot (open → close → re-open host-tested indriving_award+syscall, and proven LIVE by WINCLOSE.BIN — the gatetools/verify-live-win-close.shPASS 1/1: the window gone (windows=2) and the freed slot re-opened as id 2). Ownership follow-on: windows are OWNED by the opening process and AUTO-CLOSE when it exits (close_ownerfrom the scheduler's exit path); fill/present/close are owner-restricted (host-tested cross-process refusals); WIN.BIN's window now vanishes on exit (windows=2,sys_win_close calls=0) and WINLOOP.BIN keeps a window alive for the decoded-capture pixel proof. Milestone six closed — G1–G6 all live; the default VM stayed byte-identical.
Milestone five, card N1 — virtio-net transport + TX (the roadmap's network sketch, whose dependency — "the process/IPC foundations" — is now satisfied).DONE 2026-08-11 (claim 1373). The runner gains a flag-gated--netmode (VZFileHandleNetworkDeviceAttachment capture, fixed host MAC; the default VM stays byte-identical — the full 31-gateverify-vzaggregate re-ran green). Guestkernel/src/virtio_net.zigdiscovers DID 0x1041 pre-exit, negotiates VER1|MTU|MAC (claim-time finding: the device NEEDS MTU accepted — VER1-only and VER1|MAC are rejected with FEATURES_OK cleared), reads the host-set MAC via the feature path, sets up queues 0/1 (split rings size 4), re-arms post-exit (claim-time finding: the net device does NOT reset at ExitBootServices — st=0f — unlike blk/entropy), and consumes a 12-byte virtio_net_hdr on every TX buffer (observed; the driver prepends a zeroed one).net/netsendmonitor commands (registry 32→34); bounded BSS frame staging (no heap). Class-B gatetools/verify-live-net-tx.shPASS 2/2 — the host receives known frames byte-exact (46-byte fixture, ring reuse, honest 1500-byte truncation). RX (N2), ARP (N3), IPv4 (N4) are the later cards.- Milestone eight, card U0 — human interface guidelines (ADR 0008).
✅ DONE 2026-08-14 (claim 8938). The normative interface contract
(
docs/decisions/0008-human-interface-guidelines.md: D1 command grammar- grouped
help, D2 prompt/editing, D3 error/usage shapes, D4 window interface, D5 support surface, D6 gate-enforceability) plus the milestone-eight per-card tracker + agent split (docs/march-m8.md: U0–U8 — help/catalog, editing/history, error contract, pointer focus, window HIG, first-boot, sysinfo, persistent settings). Docs only; explicitly NOT an ADR 0007 change and NOT a POSIX/readline promise. Card U1 (claim 3275) DONE 2026-08-14 — the ADR 0008 D1 discovery surface:kernel/src/monitor.ziggains aCategoryfield on all 40 commands + a groupedhelpcatalog in the D1 group order +help <cmd>detail +help <topic>pages (networking, windows, storage, graphics; command-namedsyscalls/inputresolve to their command detail). The byte-identical transcript (shell.zig e2e +tests/transcript-console.txt) regenerated to the grouped listing, and the new live gatetools/verify-live-help.shPASS 1/1 on VZ (scripted help walk). Card U2 (claim 1809) DONE 2026-08-14 — the ADR 0008 D2 editing surface: a bounded history ring, cursor left/right + Home/End, Ctrl- A/E/K/U/L/C, Delete, and tab completion inkernel/src/lineedit.zig; arrow/Home/End/Delete usages + Ctrl-chord decoding inkernel/src/input.zig;\b/\rhonored inkernel/src/text.zig; the registry completer + repaint wired inkernel/src/shell.zig; and the runner's--input-chordsseam. Live gatetools/verify-live-editing.shPASS 1/1 on VZ (scripted chords drive mid-line insert + Up recall; unchanged transcript paths stay byte-identical). En route it root-caused + fixed a latent I3 interrupt- ring wrap OOB inkernel/src/xhci.zig(a phantom stale-report read after the Link-TRB boundary). Card U3 (claim 1511) DONE 2026-08-14 — the ADR 0008 D3 error/usage contract, mechanically enforced: oneusage: <cmd> <args>(registry single usage string viaprint_usage, reused for sub-verb misuse), oneerror: <actionable>(err_prefix) across every refusal/failure site, oneunknown command '<x>' -- try 'help'. The byte-exact misuse transcript now asserts all three shapes, and three deterministic host fuzz tests (tokenizer / arbitrary argv / full editor+shell input path) prove no handler panics. The full-path fuzz found + this card fixed a latent U2 width bug:remember_line's `@min(hist_count, hist_capacity
- 1)
inferred **u4** and overflowed at the 16th distinct history entry (explicitusize` anchor + a fill-past-capacity regression test). Live help + live transcript gates re-run green. U4–U8 are the next cards.
- grouped
The command layer above is portable; docs/archive/march-m15.md step 15's filesystem-command deferral is superseded 2026-08-09 — first by the pre-exit ESP file window (claim 3475) and then, on the same day, by the real FAT32 storage driver (claim 6420): ls/cat/write now read and write the live ESP's FAT volume through a virtio-blk transport, so files persist on the disk itself and no storage driver remains deferred. The allocator, interrupts, first tasks, EL0 boundary, syscall ABI, uaccess, per-task address spaces, lifecycle, ESP exec, and blocking syscalls are all complete; milestone three is closed 2026-08-10 (tag m3-userspace, claim 0707).
- ADR 0004 now exists and matches the plan's citation. It is the
milestone-two kernel-proper ADR; its console is polled TX-only with
explicitly "no RX path" — exactly the constraint the plan warned about
("VZ may expose only a virtio console rather than a simple MMIO UART").
The console identity on VZ is observed — a modern virtio-pci device
(claim 0013, bus 0 D5
0x1af4/0x1043, BAR0x100010000); the transport is armed pre-exit and pre-exit TX works (claims 0013/0017). Post-MMU access to that transport was blocked (claims 0018/0020) until claim 1517 fixed the underlying start-level mismatch; post-MMU TX is now observed (banner + memory-map + terminal state invm-serial.log, claim 1517). The virtio console's register layout is [observed] for the driven queues — queue 1 TX (claim 1517) and queue 0 RX (claim 6684, live keystrokes end to end) — seedocs/hardware-contract.md. - Runner serial input was
nil; it is now a real handle in--consolemode. The evidence path (zig build run) still usesVZFileHandleSerialPortAttachment(fileHandleForReading: nil, ...)unchanged; the M1.5--consolemode (landed 2026-08-06) wires a stdin pipe asfileHandleForReadingand forwards host bytes into it (evidence:artifacts/m15-host-console-gate.txt). - Output observation: evidence path still file-polls; console mode
streams.
zig build runstill re-reads the serial log (Data(contentsOf:)) on a timer — unchanged, evidence semantics intact. The M1.5--consolemode uses a pipe-based duplex attachment and tees guest output live to the terminal and the log (no full-log reloads). - "256 MiB detected" matches the runner's configured
memorySize = 256 * 1024 * 1024(unchanged on mergedmain);memshould derive it from the captured map, not hardcode it. - The kernel is post-Boot-Services and never returns.
ExitBootServicesis called (ADR 0004),x3is the handoff v2 struct (not the ESP root), and the kernel ends in a WFE loop. Consequences baked into the steps above: no UEFI Serial I/O protocol probe, noGetMemoryMap, no Simple File System — the monitor is the terminal loop's payload. - VZ firmware quirks still apply:
ConOutis not routed to the virtio serial port or framebuffer, but the kernel drives the virtio console itself — post-MMU virtio TX is now reliable (claim 1517,zig build runpasses; MMU-takeover, device identity, and post-MMU TX are [observed] per claims 0010/0013/0020/0021/1517, and the RX-side register layout is [observed] for the receive queue (claim 6684); seehardware-contract.md). Transcript tests:zig build test-console(class A mock) gates on bytes the shell actually emitted; the livevm-serial.logassertion is the separate class-B gate (live-transcript-rx, claim 6684 —bash tools/verify-live-transcript.shpasses: live RX observed end to end, re-verified at4ca9fb4by claim 7392) and is not proven by mock or NVRAM bytes.
This repo is developed by multiple agents and humans, sometimes on the same
day (e.g. PR #8's M1.5 tracker and PR #10's gate evidence landed within
hours of each other and collided; PR #12/#13 collided again on the same
changelog section). The rules below make that safe. They are binding
(mirrored in AGENTS.md).
- Claim before you start. Any non-trivial work gets a claim file in
docs/claims/and a log entry indocs/logs/before code is written. Unclaimed work is fair game; claimed work is not. - One editor per file at a time. If two agents need the same file, the
second waits, or merges through the integration branch — never both edit
kernel/src/main.zig(or this file's tracked sections) simultaneously. - Append-only logs, one per branch. The changelog is split by branch
under
docs/logs/<branch>.mdso parallel appends cannot collide. Append-only: never rewrite or delete an entry. Corrections are new entries that reference the old one. - Update on completion (and on blockers). Flip your claim file's status and append a log entry when done; append one when blocked so the next agent doesn't repeat the attempt.
- Own your evidence. Every entry cites
artifacts/files. No observed claim without a saved log. - Doc edits go through this file. Status prose lives here; other docs
link to it. If you must touch
README.md/roadmap.md/testing.md, prefer pointer-level changes and put the substance here. - Never hand-edit a generated index. The claim and log index tables
in
docs/claims/README.md/docs/logs/README.mdare generated from the claim/log files bytools/status/refresh-indexes.sh— create your file, run the script, done.tools/verify-coordination.sh(just verify-coordination, also CI) fails if the indexes drift from the files, so a stale hand-edit cannot slip through a merge.
How to claim: copy
docs/claims/TEMPLATE.mdtodocs/claims/<NNNN>-<slug>.md, fill it in, set Status to🔄 <branch>before starting work, then runbash tools/status/refresh-indexes.sh— the claim and log index tables are generated from the files, so claiming never edits a shared table and never edits this file. Flip your claim file to✅(evidence) or⛔(note why) on completion and re-run the script. Unclaimed (⬜) claims are fair game;🔄/✅claims are not. The canonical index with status isdocs/claims/README.md; this file holds no claims table, so parallel claims never touch the same lines here.
Moved 2026-08-06: the changelog used to live in this file; every agent appended here and parallel work collided (PR #8/#10, then PR #12/#13). It is now sharded by branch under
docs/logs/— each branch owns its own append-only log, so cross-branch merges never touch the same lines. All entries — including the final two stragglers, migrated verbatim todocs/logs/agent-buffy-m15-commands.mdon 2026-08-06 — live in the per-branch logs; this file holds no changelog entries, so there is nothing here for parallel agents to collide on. See the log index for the format and each branch's file.
Ordered; each has a prompt doc and a gate. Status lives in the claim
files (canonical index: docs/claims/README.md) —
this section is pointer-level only, so a gate passing never needs an edit
here.
- Root-cause the failing bad-handoff gate —
docs/m2-bad-handoff-fix-prompt.md. The kernel must return0x2to the loader on a bad magic; it does not. This unblocks M1.5 hard gate 1 and possibly the serial gate too. Gate:bash tools/verify-bad-handoff.shexits 0 withRC.TXT→kernel_rc=0x2; good path unregressed. Status: see0001-bad-handoff-gate— ✅ fixed 2026-08-06 (root cause: shim LR clobber; evidence in the claim anddocs/logs/agent-buffy-m2-badhandoff-fix.md). The serial gate (item 2) no longer shares that suspect. - Run the VZ serial/MMU gate —
docs/m2-vz-serial-gate-prompt.md(M1.5 march step 8's "confirm the serial console",docs/archive/march-m15.md). Gate: exact bannerDipshitOS kernel has seized control.,memory-map descriptors=0x..., andkernel terminal stateinvm-serial.log; then flip matching[inferred] → [observed]entries indocs/hardware-contract.md. Status: see0002-vz-serial-gate— ⛔ blocked (historical) → PASS 2026-08-08 (claim 1517): the gate (zig build run) now exits 0 with the exact banner,memory-map descriptors=0x…, andkernel terminal stateinvm-serial.log. Root cause of the historical block (virtio TX hangs post-MMU) was the translation start-level mismatch; fixed in production with T0SZ=16 +tlbi vmalle1at the switch (claims 6460/7896/1517). The post-exit-safe fallback (claim 0015,bash tools/verify-nvram-console.sh) remains as the NVRAM channel for nvram-console builds. - If no usable serial device exists on VZ, implement the ADR 0004 D4
fixed-memory-marker fallback (host-side dump of the kernel's BSS
takeover_marker). Gate: saved host-side dump matching theM2_*markers. Status: ✅ done 2026-08-07 — see0009-m2-marker-fallbackandartifacts/m2-marker-gate.txt. The gate passes with the NVRAM ladder form (the memory-dump form is impossible on VZ — guest RAM is not host-mapped, observed), and the ladder discriminated the serial gate: every run ended atM2_MAPD!— the death was in the MMU-takeover window. That death is now root-caused and fixed by claim 0010 (see the gate table): the ladder advancesM2_MAPD! → M2_MMUP! → M2_SERIA, the switch completes, and the probe runs to completion finding no usable device in the declared windows (that reading is superseded by claim 0013 — the real console is a virtio-pci device outside them, see the gate table). See claim 0009 for the original ladder and claim 0010 for the root cause and fix.
- This file is the single source of truth for status and coordination.
Update the moment a gate passes, fails, or a milestone completes; claim
work before starting (claim file in
docs/claims/); append to your branch's log underdocs/logs/; regenerate the indexes withbash tools/status/refresh-indexes.shafter creating either. Runbash tools/verify-coordination.shbefore opening a PR. - Evidence lives under
artifacts/(gitignored, except.gitkeep). Every gate claim names its evidence file and date. No evidence, no "observed". - Facts vs. inference: hypotheses are marked
(inferred); hardware tags flip only with matching saved logs (AGENTS.md evidence rules). - Branch hygiene: feature work on
agent/...branches, PRs againstmain(ADR 0003,docs/branch-protection.md); M1.5 work merges through the integration branch. - OS junk:
.DS_Storefiles are gitignored; delete them when noticed (find . -name .DS_Store -not -path './.git/*' -delete).
roadmap.md— milestone planning (the "where we're going"), plus the maintainer's wishlist / hope chest (destinations, not commitments) at the end.archive/march-m15.md— archived M1.5 per-step tracker and best-agent split (milestone closed 2026-08-09; the active tracker ismarch-m3.md).march-m4.md— milestone-four per-card tracker and best-agent split (cards 1 + 2 + 3 + 3a + 3b landed 2026-08-10 — entropy/CSPRNG + ASLR (claims 2665/3693), the general non-ESP filesystem (claim 3678), the process abstraction (claim 3848,procs), the concurrent-processes follow-on (claim 0826, two live user processes), and the long-lived-process follow-on 2 (claim 4613, a never-exiting COUNTER.BIN among live peers); network sketched as ⬜).march-m6.md— milestone-six per-card tracker (graphics: the Driving Award window manager + Road Pops terminal, sketched 2026-08-12; not committed).march-m7.md— milestone-seven per-card tracker (input: XHCI + USB HID + keycode decode).march-m8.md— milestone-eight per-card tracker (usability: ADR 0008 + the U0–U8 ladder).testing.md— the verification sequence and evidence policy.logs/README.md— per-branch append-only changelog index (the sharded changelog).claims/README.md— per-claim files index (the sharded claims table, generated).../tools/status/— index generator (refresh-indexes.sh) and the coordination gate (verify-coordination.sh).hardware-contract.md— hardware assumptions,[observed]/[inferred].architecture.md— components and data flow.archive/m2-bad-handoff-fix-prompt.md— archived prompt: fix the failing failure-path gate (now passing; root cause was the shim LR clobber).archive/m2-vz-serial-gate-prompt.md— archived prompt: run the VZ serial/MMU gate.archive/m15-host-plumbing-prompt.md— archived prompt (agent A): duplex serial attachment, teeing, terminal safety,zig build console.archive/m15-commands-prompt.md— archived prompt (agent C): command registry, identity/memory/utility/control commands, personality (mock-console based).decisions/— ADRs 0001–0008 (binding: 0004 kernel proper, 0005 runtime-built function tables, 0006 MMU debt boundary, 0007 syscall ABI, 0008 human interface guidelines).archive/— archived one-shot prompts and frozen designs from completed milestones (M2 kernel proper, M1.5 shell/commands + T0SZ experiment + tracker, M3 syscall ABI / march tracker / ragshit dogfood / runner scripted input).../AGENTS.md— project rules (now including the multiagent coordination rules).