ctos honesty ledger
Status words are claims. Each row needs a probe. Unprobed = Unknown. Never round Unknown up to Verified because the file exists, a PR is open, or a README teaches cargo run.
Allowed flags: Verified (probe passed), Unknown (no probe or probe blocked), Planned (not built yet), Failed (probe ran and lost).
| Claim | Probe | Status | Notes |
|---|---|---|---|
UART hello source present (println!("Hello World!"); + PL011 writer) | Read src/main.rs and src/uart.rs on this branch | Verified | Source inspection. Boot is a separate row. |
.cargo/config.toml present (build-std, aarch64-ctos.json, qemu runner, json-target-spec) | Read .cargo/config.toml | Verified | Presence. Build success is the next row. |
cargo build for aarch64-ctos.json | cargo +nightly build on 2026-09-08 (rustc 1.100.0-nightly cea272fa3) | Verified | First attempt failed: invalid aarch64 ABI combination until the JSON had both "abi": "softfloat" and "rustc-abi": "softfloat". Then the ELF built (target/aarch64-ctos/debug/ctos, AArch64, entry 0x40080000). |
| QEMU aarch64 serial shows Hello World | qemu-system-aarch64 8.2.2, -machine virt -cpu cortex-a57 -display none -serial stdio -kernel target/aarch64-ctos/debug/ctos; timeout 4 | Verified | Serial printed Hello World! then the VM was killed (exit 124). Same string on -machine virt,gic-version=3 and -cpu max. One cloud environment, not CI. Not a Raspberry Pi probe. |
| x86_64 VGA / bootimage path | Historical probes on 2026-09-08 (PR #2) | Historical | Path removed by ADR-003. Those Verified rows do not apply to this tree. |
| CI on GitHub | Workflow file exists and a run is green | Verified | .github/workflows/smoke.yml: push run 34285784458 success (ubuntu-24.04 52s, ubuntu-24.04-arm 1m9s). PR run 34285786641 success. ubuntu-24.04-arm label is available on this repo. |
Docker smoke (Dockerfile / scripts/docker-smoke.sh) | the arm64 workstation Docker Desktop linux/arm64, 2026-09-09: docker build -t ctos-smoke . && docker run --rm ctos-smoke → exit 0 | Verified | After three Failed runs, ratchets landed in git and the full smoke passed on the arm64 workstation: serial Hello World! (hello QEMU timeout 124, expected); cargo test [ok]; force-fail exit 1; qemu-smoke: ok. Failures that were ratcheted: (1) CRLF shebang → exec ./scripts/qemu-smoke.sh: no such file or directory (.gitattributes *.sh/Dockerfile eol=lf, image sed, CMD bash); (2) linker cc not found on compiler_builtins (build-essential); (3) failed to find romfile "efi-virtio.rom" (qemu-efi-aarch64 + ipxe-qemu). One sponsor host, not CI and not this cloud VM (still no Docker engine here). |
Second-brain vaults (research/) | Paths exist; README explains Procedure / Correction / Relationship / Daily Brief | Verified | Structure present. Not a claim that vaults are richly filled. Optional Obsidian UI is structure-only (PR #3). |
Thin ctos-* roles | AGENTS.md + .cursor/skills/ctos-*/SKILL.md exist | Verified | Four roles. No aea-* names. |
Frozen FR/NFR IDs (FR-01–FR-15, NFR-01–NFR-14) | Read docs/02-requirements/fr-nfr.md; IDs present; ISA text revised under ADR-003 | Verified | Frozen IDs. Text now AArch64/UART. Do not invent extra FR/NFR IDs in chat. File presence is not a claim that every Now row is implemented. |
PR identity split (author ≠ merger; artofdream vs cursor[bot]) | Read ADR-002 (amended 2026-09-12), AGENTS.md, .cursor/rules/pr-identity-no-self-merge.mdc | Verified | Docs present. Principle reused from Café Fausse pr-coordinator (identity only). Going-forward rule: owner-opened → cursor[bot] merges; bot-opened → artofdream merges. File presence of the rule is not a practiced split. Distinct-identity merge on this repo (author ≠ mergedBy): Unknown until gh shows it on a post-amendment PR. cursor[bot] merge / App APPROVE on this repo: Unknown until probed on artofdream/ctos. Track A same-login merges are the Historical row below, not this probe. |
| Track A A1–A9 same-login merge (ADR-002 historical exception) | gh pr view --json author,mergedBy on 2026-09-12 for #49, #52–#57, #59, #60 | Historical | Each PR: author=artofdream and mergedBy=artofdream. Commits typically cursoragent + Co-authored-by: artofdream. Named exception (2026-09-11–2026-09-12); do not rewrite those PRs. Not a kernel-boot claim. Not permission to repeat. |
| Primary ISA is AArch64 | Read ADR-003; x86_64-ctos.json / src/vga_buffer.rs absent | Verified | Decision + file tree. QEMU boot is a separate row. |
| Integration tests / QEMU test exit (M2) | cargo +nightly test → QEMU virt + -semihosting; #[test_case]; QEMU host exit 0 | Verified | 2026-09-08 cloud: Running 2 tests / [ok]. 2026-09-09 M3: 4 tests. 2026-09-09 M4 re-probe: Running 6 tests / all [ok] (adds SPSel + stack-range cases). |
| Fail-closed test panic | cargo +nightly test --features force-fail | Verified | 2026-09-08 and 2026-09-09 cloud: panic force-fail, QEMU/host exit 1. |
scripts/qemu-smoke.sh | Ran on this cloud VM | Verified | 2026-09-09 M4 (qemu-system-aarch64 8.2.2, rustc 1.100.0-nightly 4aa1fbcf4): hello (timeout 124), exception: sync BRK (esr=0xf2000000), exception: fatal nested (kind=0x200), cargo test 0 (6 cases), force-fail 1, qemu-smoke: ok. First hello run Failed: MSR SP_EL1 at EL1 is UNDEF (esr=0x2000000) before Hello World! — fixed by setting SP_EL1 via mov sp while SPSel=1 (ADR-005). Not Docker. GHA on this PR is a separate row. |
VBAR_EL1 installed at 2 KiB-aligned exception_vectors (M3 / FR-06) | cargo +nightly test vbar_el1_points_at_table | Verified | 2026-09-09 cloud: [ok]. CurrentEL==1 and mrs vbar_el1 equals exception_vectors. ELF also had the table at 0x40080800. |
Current-EL sync BRK handler runs and returns (M3 / FR-06) | cargo +nightly test breakpoint_from_current_el; hello-kernel serial | Verified | 2026-09-09 cloud: test [ok]; hello serial exception: sync BRK esr=0xf2000000 elr=0x40081190 then timeout 124 (wfe loop). Other sync classes and lower-EL slots are parks — taking those is unprobed. |
| qemu-smoke requires BRK handler string | scripts/qemu-smoke.sh hello phase greps exception: sync BRK | Verified | 2026-09-09 cloud: qemu-smoke: BRK handler string present. Extends the M2 sensor (FR-06 / NFR-04). |
| Lower-EL AArch64 sync is live (SVC / IABORT); IRQ while standing live (ADR-040/041); FIQ while standing live (ADR-043); SError park | Source read of vector table; taken path is the EL0 first-mile / ADR-040 / ADR-041 / ADR-043 rows | Verified | Source: sync_lower_el + irq_lower_el + fiq_lower_el; default eret_to_el0 SPSR 0x340. SError lower-EL is standing-aware (ADR-045 EXPECT) but no working host inject on virt/a57; AArch32 still parks. Taken lower-EL FIQ: see ADR-043 row. Taken SError: see ADR-045 row. |
| CI on GitHub (M3 PR / this branch) | .github/workflows/smoke.yml on cursor/m3-vbar-el1-exceptions-bd73 | Verified | Push 34389110709 success (ubuntu-24.04 + ubuntu-24.04-arm). PR 34389132580 success. Same qemu-smoke.sh as the cloud probe (hello + BRK string + 4 tests + force-fail). Commit 72ecd37. |
Dedicated SP_EL1 exception stack + SPSel=0 thread stack (M4 / FR-07) | cargo +nightly test spsel_uses_thread_stack + stacks_are_distinct_and_aligned | Verified | 2026-09-09 cloud: both [ok]. SPSel==0 and current SP in __stack_*; three stack ranges 16-byte aligned and disjoint. |
| Nested current-EL exception uses fatal stack and is observable (M4 / FR-07) | Hello-kernel serial exception: fatal nested via scripts/qemu-smoke.sh | Verified | 2026-09-09 cloud: after two exception: sync BRK lines, serial exception: fatal nested then exception: fatal esr=0xf2000000 elr=0x400816cc kind=0x200. Nested AArch64 BRK after near-empty thread SP (ADR-005). Not an MMU overflow fault. Not GIC (M5). |
| qemu-smoke requires fatal nested string | scripts/qemu-smoke.sh hello phase greps exception: fatal nested and rejects fatal probe missed | Verified | 2026-09-09 cloud: qemu-smoke: fatal nested string present. Extends the M3 sensor (FR-07 / NFR-04). |
| CI on GitHub (M4 PR / this branch) | .github/workflows/smoke.yml on cursor/m4-fatal-exception-stack-c8b7 | Unknown | Not a green GHA URL on the post-fix revision before merge. M4 merged as PR #7 (180dbf2). |
| GICv2 init + CNTP PPI 30 tick observable (M5 / FR-08) | Hello-kernel serial timer: tick via scripts/qemu-smoke.sh; #[test_case] timer_tick_is_observable | Verified | 2026-09-09 cloud (QEMU 8.2.2, rustc 1.100.0-nightly 4aa1fbcf4): after Hello World!, serial timer: tick, then M3/M4 BRK + fatal. cargo test Running 9 tests all [ok] including gicd_typer_readable, cntfrq_is_nonzero, timer_tick_is_observable. Not GICv3. Not UART input (M6). |
| qemu-smoke requires timer tick string | scripts/qemu-smoke.sh hello phase greps timer: tick and rejects timer: tick missed | Verified | 2026-09-09 cloud: qemu-smoke: timer tick string present. Extends the M4 sensor (FR-08 / NFR-04). |
| CI on GitHub (M5 PR / this branch) | .github/workflows/smoke.yml on cursor/m5-hardware-interrupts-d5a6 | Verified | Push/PR run 34391557761 success (ubuntu-24.04 + ubuntu-24.04-arm) on the cloud-probe commit. Implementation commit run 34391552019 also success. Same qemu-smoke.sh (hello + tick + BRK + fatal + 9 tests + force-fail). Commit e28e4bb. |
PL011 RX of injected 0x41 observable (M6 / FR-08 input) | Hello-kernel serial input: rx 0x41 via scripts/qemu-smoke.sh + qemu-serial-inject.py | Verified | 2026-09-09 cloud (QEMU 8.2.2, rustc 1.100.0-nightly 4aa1fbcf4): after Hello World! and timer: tick, serial input: rx 0x41, then M3/M4 BRK + fatal. Not virtio-keyboard. Not QEMU LBE (unimplemented on 8.2). |
| qemu-smoke requires UART RX string | scripts/qemu-smoke.sh hello phase greps input: rx 0x41 and rejects input: rx missed | Verified | 2026-09-09 cloud: qemu-smoke: UART RX string present. Extends the M5 sensor (FR-08 input / NFR-04). |
Empty RX FIFO under cargo test (M6) | #[test_case] uart_rx_fifo_empty_without_host_byte | Verified | 2026-09-09 cloud: cargo test Running 10 tests all [ok]. Character proof is the serial row. |
| CI on GitHub (M6 PR / this branch) | .github/workflows/smoke.yml on cursor/m6-uart-rx-input-7ef6 | Unknown | No green GHA URL on the cloud-probe commit yet. |
| EL1 identity map + MMU on (M7 / FR-09) | Hello-kernel serial paging: ok via scripts/qemu-smoke.sh; #[test_case] mmu_is_enabled | Verified | 2026-09-09 cloud (QEMU 8.2.2, rustc 1.100.0-nightly 4aa1fbcf4): after Hello World!, serial paging: ok, then M5/M6/M3/M4 markers. cargo test mmu_is_enabled [ok]. Identity 1 GiB blocks (ADR-008). Not a DTB walk. |
| Frame alloc + map/unmap window (M7 / FR-09) | #[test_case] frame_alloc_aligned_and_distinct + map_unmap_roundtrip; serial marker from paging::observe_probe | Verified | 2026-09-09 cloud: both [ok]. Write-through window VA 0x8000_0000 matches identity PA. |
| qemu-smoke requires paging string | scripts/qemu-smoke.sh hello phase greps paging: ok and rejects paging: probe missed | Verified | 2026-09-09 cloud: qemu-smoke: paging string present. Extends the M6 sensor (FR-09 / NFR-04). |
| CI on GitHub (M7 PR / this branch) | .github/workflows/smoke.yml on cursor/m7-paging-frame-allocator-b567 | Unknown | No green GHA URL on the cloud-probe commit yet. |
GlobalAlloc + Box/Vec on identity-mapped frames (M8 / FR-10) | Hello-kernel serial heap: ok via scripts/qemu-smoke.sh; #[test_case] box_alloc_roundtrip + vec_grows + heap_lives_in_frame_pool | Verified | 2026-09-09 cloud (QEMU 8.2.2, rustc 1.100.0-nightly 4aa1fbcf4): after paging: ok, serial heap: ok, then M5/M6/M3/M4 markers. cargo test Running 17 tests all [ok]. First-fit + coalesce (ADR-009). Not a growing heap. Not M9. |
| qemu-smoke requires heap string | scripts/qemu-smoke.sh hello phase greps heap: ok and rejects heap: probe missed | Verified | 2026-09-09 cloud: qemu-smoke: heap string present. Extends the M7 sensor (FR-10 / NFR-04). |
| CI on GitHub (M8 PR / this branch) | .github/workflows/smoke.yml on cursor/m8-heap-globalalloc-0ee8 | Verified | Push run 34394697056 success (ubuntu-24.04-arm 59s, ubuntu-24.04 1m36s) on the cloud-probe commit ba6096a. Same qemu-smoke.sh (hello + paging + heap + tick + RX + BRK + fatal + 17 tests + force-fail). |
| Cooperative two-task yield (M9 / FR-11) | Hello-kernel serial sched: task a / sched: task b / sched: ok via scripts/qemu-smoke.sh; #[test_case] two_tasks_run_on_distinct_heap_stacks + yield_round_robin_resumes_both | Verified | 2026-09-09 cloud (QEMU 8.2.2, rustc 1.100.0-nightly 4aa1fbcf4): after heap: ok, serial sched: task a, sched: task b, sched: ok, then M5/M6/M3/M4 markers. cargo test Running 19 tests all [ok]. Cooperative EL1 yield (ADR-010). Not preemptive. Not SMP. |
| qemu-smoke requires scheduler strings | scripts/qemu-smoke.sh hello phase greps sched: ok and both task markers; rejects sched: probe missed | Verified | 2026-09-09 cloud: qemu-smoke: scheduler strings present. Extends the M8 sensor (FR-11 / NFR-04). |
| qemu-smoke requires CNTPCT perf string | scripts/qemu-smoke.sh hello phase greps perf: cntpct and rejects perf: probe missed | Verified | 2026-09-09 cloud: qemu-smoke: CNTPCT perf string present. Extends the M9 sensor (NFR-07 / NFR-04). |
| CI on GitHub (M9 PR / this branch) | .github/workflows/smoke.yml on cursor/m9-cooperative-scheduler-7da9 | Verified | Folded from #16 (not re-probed here): push 34395786658 and PR 34395791288 success (ubuntu-24.04-arm + ubuntu-24.04) on 88a9305. Merge-commit push 34396135202 success on 4e3b732. Same qemu-smoke.sh (hello + paging + heap + two-task sched + tick + RX + BRK + fatal + 19 tests + force-fail). |
| Three pillars accepted (ADR-011); NFR-05 / NFR-07 / NFR-10 text revised in place | Read ADR-011 and fr-nfr.md; IDs still NFR-05/NFR-07/NFR-10 | Verified | Document inspection. Not a kernel boot claim. |
| Threat-model v1 exists (NFR-10) | Read security.md (assets, adversaries, trust boundaries, non-goals, mitigations→probes) | Verified | File + review (2026-09-10, #18). Replaces the ADR-011 stub. “Secure OS” / “hardened”: unclaimed. |
| Threat-model v1.1 slice (NFR-10) | Read security.md (linker stacks, guards, EL0 first mile, remaining W^X gaps) | Verified | File + review. v1.1 update, not “secure.” |
| Threat-model v1.5 slice (NFR-10) | Read security.md (standing EL0, TTBR1 first cut, EL1 high-VA fetch, PAN/identity teardown still Planned) | Verified | File + PR #25. v1.5 update, not “secure.” |
| Threat-model v1.6 slice (NFR-10) | Read security.md (identity-tear first cut, PAN/full teardown still Planned) | Verified | File + PR #26. v1.6 update, not “secure.” |
| Threat-model v1.7 slice (NFR-10) | Read security.md (high-VA jump + 16 KiB dedicated identity text range, live .text stays, PAN/full teardown still Planned) | Verified | File + PR #27 (on main 24d94e6). v1.7 update, not “secure.” |
| Threat-model v1.8 slice (NFR-10) | Read security.md (high-VA vtable rewrite + live identity .text tear, .rodata/.data/heap stay, PAN/full teardown still Planned) | Verified | File + PR #28 (on main e80dc93). v1.8 update, not “secure.” |
| W^X / NX heap + coop stacks (ADR-012) | Hello-kernel serial wx: nx heap + wx: ok via scripts/qemu-smoke.sh; #[test_case] heap_and_mmio_are_pxn + kernel_text_is_executable + execute_from_heap_is_caught | Verified | 2026-09-10 cloud (QEMU 8.2.2, rustc 1.100.0-nightly a36d05efa): after sched: ok, serial wx: nx heap then wx: ok. cargo test Running 25 tests all [ok]. L2/L3 PXN on [__kernel_end, RAM end) (ADR-012). Linker SP_EL0 / SP_EL1 / fatal stacks stay in the executable image. Device MMIO L1 is XN. Not a “secure OS” or “the kernel is W^X” claim. |
| qemu-smoke requires W^X string | scripts/qemu-smoke.sh hello phase greps wx: ok and rejects wx: probe missed | Verified | 2026-09-10 cloud: qemu-smoke: W^X string present. Extends the pillars sensor (NFR-10 / NFR-04). |
| Baseline CNTPCT loop probe (NFR-07) | Hello-kernel serial perf: cntpct via scripts/qemu-smoke.sh; #[test_case] cntpct_advances_over_loop | Verified | 2026-09-10 cloud re-probe (QEMU 8.2.2, rustc 1.100.0-nightly a36d05efa): after wx: ok, serial perf: cntpct delta=22968. Prior 2026-09-09 pillars probe also Verified. Counter-advances baseline. Not a published bench. |
| IRQ-to-handler CNTPCT delta (NFR-07) | Hello-kernel serial perf: irq-delta via scripts/qemu-smoke.sh; #[test_case] irq_delta_samples_recorded | Verified | 2026-09-10 cloud (QEMU 8.2.2): after timer: tick, serial perf: irq-delta min=12973 max=35391 spread=22418 n=8. cargo test irq_delta_samples_recorded [ok]. CNTPCT−CVAL spread on this QEMU virt guest. Not a latency budget. Not “faster than X.” |
| qemu-smoke requires IRQ-delta string | scripts/qemu-smoke.sh hello phase greps perf: irq-delta and rejects perf: irq-delta missed | Verified | 2026-09-10 cloud: qemu-smoke: IRQ-delta perf string present. Extends the NFR-07 sensor (NFR-04). |
| Linker-stack guard pages (ADR-014) | Hello-kernel serial guard: fault + guard: ok via scripts/qemu-smoke.sh; #[test_case] linker_stack_guards_unmapped + store_to_thread_guard_is_caught | Verified | 2026-09-10 cloud (QEMU 8.2.2, rustc 1.100.0-nightly a36d05efa): after wx: ok, serial guard: fault then guard: ok. cargo test both guard cases [ok]. Unmapped 4 KiB holes (ADR-014). Live stack pages stay executable. Not “the kernel is W^X.” |
| qemu-smoke requires guard string | scripts/qemu-smoke.sh hello phase greps guard: ok and rejects guard: probe missed | Verified | 2026-09-10 cloud: qemu-smoke: stack-guard string present. |
| Host debug ELF size (NFR-08) | scripts/qemu-smoke.sh prints perf: elf-size bytes=<n> and rejects < 4096 | Verified | 2026-09-10 cloud: host perf: elf-size bytes=3752056 after cargo +nightly build. Measurement only. Not a budget. Not a bench. |
| EL0 entered and returned (SVC) | Hello-kernel serial el0: svc + el0: ok; #[test_case] el0_svc_roundtrip | Verified | 2026-09-10 cloud: after guard: ok, serial el0: svc then el0: ok. cargo test el0_svc_roundtrip [ok]. is_active() stays false. Not userspace. |
| EL0 cannot execute kernel data | Hello-kernel serial el0: nx kernel; #[test_case] el0_cannot_execute_kernel_data | Verified | 2026-09-10 cloud: serial el0: nx kernel. cargo test [ok]. Lower-EL UXN IABORT on kernel .data. 2026-09-11 hello re-probe (this branch) still prints el0: nx kernel (now also a translation IABORT under user TTBR0). Not isolation. |
| EL0 isolation (P-SEC-3) | Standing EL0 + PAN enable + full TTBR1/higher-half teardown; since M6: every ADR-055 §A/§B row Met + sponsor’s written accept (B3) + M6 PR CI re-probe | Verified (scoped: the accepted ADR-091 sentence only) | M6 (2026-09-28): ADR-091 Accepted; “EL0 isolated” means only that sentence, with its limits (one core, the TCG default smoke machine; not a speculative-execution or side-channel claim, not a real-hardware claim, not a certification; app text is EL0 execute-only; EL1 can still read it (no FEAT_EPAN); no multi-core race story). Revision 4 (2026-10-02): the sponsor accepted ADR-091 rev 4 in writing (PAN clause + that limit changed; see the revision-4 row near the end of this file). Earlier notes: Direction ADR-013; decisions ADR-047; checklist ADR-055; sponsor closure ADR-060. Specific miles are different rows. PAN enable Verified on a76 (ADR-080; historical a57 lock ADR-054); taken SError hard-stopped (ADR-053 / ADR-081); never yank _start. Do not widen “EL0 isolated” past the ADR-091 sentence. |
| RO+NX text/data (ADR-015) | Hello-kernel serial ro: nx data + ro: write fault + ro: ok; #[test_case] execute-from-.data + write-to-RO-text | Verified | 2026-09-11 cloud qemu-smoke (QEMU 8.2.2, rustc 1.100.0-nightly 67eda617e, -cpu cortex-a57): after guard: ok, serial ro: nx data then ro: write fault then ro: ok. cargo test both RO cases [ok]. Identity image W^X on this virt guest (text RO+X, data/stacks/heap RW+NX, SCTLR.WXN on). Not a “secure OS.” |
| qemu-smoke requires RO+NX strings | scripts/qemu-smoke.sh hello phase greps ro: ok / ro: nx data / ro: write fault | Verified | 2026-09-11 cloud: qemu-smoke: RO+NX string present. |
| Boot-to-ready CNTPCT (NFR-08) | Hello-kernel serial perf: boot-delta; #[test_case] boot_delta_sample_exists | Verified | 2026-09-11 cloud qemu-smoke: perf: boot-delta ticks=111019 (after paging::init → after Hello World!). First attempt Failed: pre-MMU .bss store lost on the test image. Measurement only. Not a budget. Not a bench. |
| qemu-smoke requires boot-delta string | scripts/qemu-smoke.sh hello phase greps perf: boot-delta | Verified | 2026-09-11 cloud: qemu-smoke: boot-delta perf string present. |
User TTBR0 omits kernel .data | #[test_case] user_ttbr0_omits_kernel_data; walk L1_USER | Verified | 2026-09-11 cloud cargo test: user_ttbr0_omits_kernel_data [ok]. ASID=1 programmed. Not ASID isolation. |
EL0 cannot read kernel .data | Hello-kernel serial el0: no kernel read; #[test_case] el0_cannot_read_kernel_data | Verified | 2026-09-11 cloud qemu-smoke: after el0: nx kernel, serial el0: no kernel read then el0: ok. cargo test [ok]. User TTBR0 omits .data. is_active() stays false. Not isolation. Not PAN. |
| PAN enable on virt | ID_AA64MMFR1_EL1.PAN != 0 and an EL1-vs-EL0 access fault | Verified (ADR-080) | Default -cpu cortex-a76 (ADR-079 / ADR-080 / #125): pan: present + pan: enabled + pan: el1-fault (SPSR.PAN). Historical a57 pan: absent (ADR-026). Not “EL0 isolated.” |
| ASID isolation | Hello-kernel serial asid: dual + asid: conflict + asid: ok; #[test_case] asid_isolation_without_vmalle1; no TLBI VMALLE1 on the switch | Verified | 2026-09-11 cloud qemu-smoke (QEMU 8.2.2, rustc 1.100.0-nightly 67eda617e, -cpu cortex-a57): after el0: ok, serial asid: dual then asid: conflict then asid: ok. cargo test asid_isolation_without_vmalle1 [ok] (Running 39 tests). Dual TTBR0 (ASID 1 vs 2) with nG pages; switch is MSR TTBR0 + ISB. At probe time the EL0 trampoline still TLBI VMALLE1 (.data leaves were global); ADR-039 later drops trampoline VMALLE1. Not “EL0 isolated.” Not PAN. |
| Standing EL0 context | Hello-kernel serial el0: standing + el0: restored; #[test_case] standing_el0_enter_leave; is_active() true only while standing | Verified | 2026-09-11 cloud qemu-smoke (QEMU 8.2.2, rustc 1.100.0-nightly 67eda617e, -cpu cortex-a57): after el0: no kernel read, serial el0: standing then el0: restored then el0: ok. cargo test standing_el0_enter_leave [ok] (Running 42 tests). Dual-SVC on user TTBR0 (not a trampoline flag). Default ERET clears IRQ mask (ADR-041). Not POSIX. Not isolation. |
| TTBR1 kernel-private page (ADR-016 first cut) | Hello-kernel serial ttbr1: el1 + ttbr1: no el0 + ttbr1: ok; #[test_case] ttbr1_el1_sees_priv_el0_does_not | Verified | 2026-09-11 cloud qemu-smoke: after asid: ok, serial ttbr1: el1 then ttbr1: no el0 then ttbr1: ok. cargo test ttbr1_el1_sees_priv_el0_does_not [ok]. EL1-only high page. Identity teardown Planned. Not a relocated kernel. Not “EL0 isolated.” |
| qemu-smoke requires standing EL0 strings | scripts/qemu-smoke.sh hello phase greps el0: standing / el0: restored | Verified | 2026-09-11 cloud: qemu-smoke: EL0 first-mile + read-mile + standing strings present. |
| qemu-smoke requires TTBR1 strings | scripts/qemu-smoke.sh hello phase greps ttbr1: ok / ttbr1: el1 / ttbr1: no el0; rejects ttbr1: leaked and ttbr1: probe missed | Verified | 2026-09-11 cloud: qemu-smoke: TTBR1 private-page strings present. |
| EL1 fetch from TTBR1 high VA (ADR-017) | Hello-kernel serial ttbr1: el1 exec + ttbr1: vbar; #[test_case] el1_executes_from_ttbr1_high_va + high_alias_maps_kernel_text | Verified | 2026-09-11 cloud qemu-smoke (QEMU 8.2.2, rustc 1.100.0-nightly 67eda617e, -cpu cortex-a57): after asid: ok, serial ttbr1: el1 exec then ttbr1: vbar then the ADR-016 private-page lines. cargo test both new cases [ok] (Running 44 tests). _start stays at 0x4008_0000. Nested fatal ELR can be the high alias (elr=0xffffff80400839e4). Not a relocated kernel. Not “EL0 isolated.” |
| qemu-smoke requires TTBR1 high-VA exec strings | scripts/qemu-smoke.sh hello phase greps ttbr1: el1 exec / ttbr1: vbar; rejects ttbr1: exec missed | Verified | 2026-09-11 cloud: qemu-smoke: TTBR1 private-page + high-VA exec strings present. |
| Full higher-half / identity teardown | Remaining identity RAM after the heap plus identity _start unmapped | Decided partial | ADR-020/025/037/038/049 tear live image + leftover frame RAM. Never yank _start while -kernel needs 0x4008_0000 (ADR-047). ident: start-stay Verified honesty. Leftover frame RAM after heap: Verified optional mile (ident: ram*, ADR-049). Do not claim the kernel moved. |
Identity .rodata tear (ADR-025) | Serial ident: rodata / ident: rodata-fault / ident: rodata-high | Verified | See earlier ADR-025 rows. |
Identity .data / stack tear (ADR-037) | Hello-kernel serial ident: data-reloc + ident: data + ident: data-fault + ident: data-high; heap stay; #[test_case] data-torn + heap-still-mapped | Verified | 2026-09-12 agent-box qemu-smoke (QEMU, nightly): ident: data-reloc n=241 / ident: data lo=0x40201000 hi=0x40258000 pages=87 / ident: data-fault / ident: data-high / ident: heap-stay / ident: ok; Running 85 tests all [ok] incl. identity_data_torn_high_stays + identity_heap_still_mapped; qemu-smoke: ok. (amd64 workstation) checkout target noted; this probe ran on the agent box. Heap stay is Historical after ADR-038. Not “EL0 isolated.” |
| Identity heap still mapped | Hello-kernel serial ident: heap-stay; #[test_case] identity_heap_still_mapped | Verified | Same smoke as ADR-037 row. Honesty marker, not a tear. Historical: superseded by ADR-038 on later tips. |
| Identity heap tear (ADR-038) | Hello-kernel serial ident: heap-reloc + ident: heap + ident: heap-fault + ident: heap-high; #[test_case] heap-torn | Verified | 2026-09-12 agent-box qemu-smoke (QEMU 10.0.13, rustc 1.100.0-nightly 0fc141305, -cpu cortex-a57) on ident-heap-tear after dde185f: hello ident: heap-reloc n=0 / ident: heap lo=0x40258000 hi=0x40268000 pages=16 / ident: heap-fault / ident: heap-high / ident: ok; no ident: heap-stay; Running 86 tests all [ok] incl. identity_heap_torn_high_stays + identity_heap_unmapped_high_stays; A9 cross-update both slot:ok; force-fail exit 1; qemu-smoke: ok. (amd64 workstation) checkout target noted; this probe ran on the agent box — Docker on the amd64 workstation not re-run (CloudAgent HELD). Not “EL0 isolated.” Not “the kernel moved.” |
| Threat-model v1.18 slice (NFR-10) | Read security.md (identity heap tear; PAN enable Planned) | Verified | File + this PR. v1.18 update, not “secure.” |
| Docs site at https://ctos.artof.link | HTTP(S) fetch of the published Pages site on that host | Verified | 2026-09-11 after #30: curl -sL https://ctos.artof.link/ → HTTP 200; HTML title/menu ctos (ctsOS); landing #driving-principles. This VM repeat: same 200 + title + heading. Also 200: overview/what-can-run.html, overview/porting.html, framework/honesty-ledger.html. Deploy cited on the published-site row. Not a kernel boot claim. |
High-VA vtable rewrite + live identity .text tear (ADR-020) | Hello-kernel serial ident: reloc + ident: live + existing ident: ok; #[test_case] identity_fn_ptrs_rewritten_high + live_identity_text_unmapped_boot_stub_stays | Verified | 2026-09-11 cloud qemu-smoke (QEMU 8.2.2, rustc 1.100.0-nightly 67eda617e, -cpu cortex-a57): ident: jump then ident: reloc n=12 then ident: range lo=0x400ae000 hi=0x400b2000 pages=4 then ident: live lo=0x40081000 hi=0x400a6000 pages=37 then Hello World! then later ident: split / ident: fault / ident: high / ident: text / ident: no el0 / ident: ok. Hello BRK ELRs high (elr=0xffffff8040082990). cargo test Running 50 tests all [ok] (ident: reloc n=74, ident: live pages=45). Not a relocated kernel. Not “EL0 isolated.” .rodata/.data/heap stay. Full teardown Planned. |
| Identity text range tear (ADR-019) | Hello-kernel serial ident: jump + ident: range + ident: text + existing ident: ok; #[test_case] identity_text_range_unmapped_boot_stub_stays | Verified | 2026-09-11 cloud qemu-smoke (QEMU 8.2.2, rustc 1.100.0-nightly 67eda617e, -cpu cortex-a57): ident: jump then ident: range lo=0x400ac000 hi=0x400b0000 pages=4 then later ident: split / ident: fault / ident: high / ident: text / ident: no el0 / ident: ok. Hello BRK ELRs high (elr=0xffffff8040082758). cargo test identity_text_range_unmapped_boot_stub_stays [ok] (Running 48 tests). Live .text stays. First attempt to yank live .text after the stub Failed (unhandled sync on println! — rustc dyn Write vtables). Not a relocated kernel. Not “EL0 isolated.” Full teardown Planned. |
| Identity-tear first cut (ADR-018) | Hello-kernel serial ident: split + ident: fault + ident: high + ident: no el0 + ident: ok; #[test_case] high_ram_tables_are_independent + identity_tear_page_unmapped_high_stays + identity_tear_el1_faults_high_stays | Verified | 2026-09-11 cloud qemu-smoke (QEMU 8.2.2, rustc 1.100.0-nightly 67eda617e, -cpu cortex-a57): after ttbr1: ok, serial ident: split then ident: fault then ident: high then ident: no el0 then ident: ok. cargo test all three new cases [ok] (Running 47 tests). _start stays at 0x4008_0000. Nested fatal ELR can be the high alias (elr=0xffffff8040083bec). Not a relocated kernel. Not “EL0 isolated.” Full teardown Planned. |
| qemu-smoke requires identity-tear strings | scripts/qemu-smoke.sh hello phase greps ident: ok / ident: split / ident: fault / ident: high / ident: no el0; rejects ident: leaked and ident: probe missed | Verified | 2026-09-11 cloud: qemu-smoke: identity-tear strings present. |
| Obsidian open-vault checklist | Read research/obsidian-checklist.md; .gitignore has .obsidian/ | Verified | Structure only. .obsidian/ not committed. Not a claim that Obsidian is installed or synced. |
| CI on GitHub (pillars PR / ADR-011) | .github/workflows/smoke.yml on cursor/pillars-adr-011-325f | Verified | Cloud-probe commit cdf75eb: push 34396574483 and PR 34396590545 success. Ledger follow-up d716599: push 34396774022 and PR 34396779239 success. Same qemu-smoke.sh (hello + paging + heap + sched + CNTPCT + tick + RX + BRK + fatal + 20 tests + force-fail). |
scripts/qemu-smoke.sh (pillars follow-up / #18) | Ran on that cloud VM | Verified | 2026-09-10 (QEMU 8.2.2, rustc 1.100.0-nightly a36d05efa): hello (timeout 124) with paging: ok, heap: ok, sched: ok, wx: nx heap / wx: ok, perf: cntpct delta=22968, timer: tick, perf: irq-delta min=12973 max=35391 spread=22418 n=8, input: rx 0x41, two exception: sync BRK, exception: fatal nested / kind=0x200. cargo test Running 25 tests all [ok]. force-fail exit 1. qemu-smoke: ok. Not Docker. |
scripts/qemu-smoke.sh (pillar deepen / this branch) | Ran on this cloud VM | Verified | 2026-09-10 (QEMU 8.2.2, rustc 1.100.0-nightly a36d05efa): host perf: elf-size bytes=3752056; hello (timeout 124) with paging: ok, heap: ok, sched: ok, wx: nx heap / wx: ok, guard: fault / guard: ok, el0: svc / el0: nx kernel / el0: ok, perf: cntpct delta=20592, timer: tick, perf: irq-delta min=14477 max=24149 spread=9672 n=8, input: rx 0x41, two exception: sync BRK, exception: fatal nested / kind=0x200. cargo test Running 29 tests all [ok]. force-fail exit 1. qemu-smoke: ok. Not Docker. GHA on this PR is a separate row. |
| CI on GitHub (pillars follow-up PR / #18) | .github/workflows/smoke.yml on cursor/pillars-sec-perf-el0-9bc0 | Verified | Cloud-probe commit 8ae63bb: push 34541457222 and PR 34541473721 success (ubuntu-24.04 + ubuntu-24.04-arm). Ledger follow-up 4c610a2: push 34541534491 and PR 34541537733 success. Same qemu-smoke.sh (hello + paging + heap + sched + W^X + CNTPCT + IRQ-delta + tick + RX + BRK + fatal + 25 tests + force-fail). |
| CI on GitHub (pillar deepen PR / #19) | .github/workflows/smoke.yml on cursor/pillar-loops-deepen-48ae | Unknown | No green GHA URL on the cloud-probe commit recorded here. Merged as #19. |
scripts/qemu-smoke.sh (RO+NX / boot-delta / user TTBR0 / PR #20) | Ran on that cloud VM | Verified | 2026-09-11 (QEMU 8.2.2, rustc 1.100.0-nightly 67eda617e): host perf: elf-size bytes=3785520; hello (timeout 124) with paging: ok, heap: ok, sched: ok, wx: nx heap / wx: ok, guard: fault / guard: ok, ro: nx data / ro: write fault / ro: ok, el0: svc / el0: nx kernel / el0: no kernel read / el0: ok, perf: cntpct delta=20506, perf: boot-delta ticks=111019, timer: tick, perf: irq-delta min=4885 max=26301 spread=21416 n=8, input: rx 0x41, two exception: sync BRK, exception: fatal nested / kind=0x200. cargo test Running 36 tests all [ok]. force-fail exit 1. qemu-smoke: ok. Not Docker. GHA on that PR is a separate row. |
| CI on GitHub (RO+NX / boot-delta / user TTBR0 / PR #20) | .github/workflows/smoke.yml on cursor/pillar-deepen-ro-boot-el0-aadc | Verified | Cloud-probe commit 6606be8: push 34561716967 and PR 34561719542 success (ubuntu-24.04 + ubuntu-24.04-arm). Host ELF there ~3.69 MiB — smaller than the arm64 workstation Docker 3786384. Do not copy that Verified onto the Docker host. |
Docker smoke on main b2bbb99 (post PR #20) | the arm64 workstation Docker Desktop linux/arm64 ./scripts/docker-smoke.sh after sync to b2bbb99 | Failed | Sponsor serial: perf: elf-size bytes=3786384; Hello World!; paging: probe missed; heap: probe missed; sched: probe missed; wx: probe missed; guard: fault / guard: ok; ro: nx data / ro: write fault / ro: ok; el0: probe missed; then CNTPCT / boot-delta / tick / irq-delta / RX / BRK / fatal still printed. qemu-smoke: missing 'paging: ok' EXIT 1. Guard/ro are current-EL identity walks — they do not need frame::ALLOC or USER_MAP_OK. Same class as the PR #20 pre-MMU .bss miss, plus a single shared L3 / first-2-MiB user map that a larger nightly layout can also break. Antifragility: this host found what GHA missed. Not this cloud VM. |
scripts/qemu-smoke.sh (layout L3 pool / post-MMU frame init / this branch) | Ran on this cloud VM | Verified | 2026-09-11 (QEMU 8.2.2, rustc 1.100.0-nightly 67eda617e): host perf: elf-size bytes=3837736; hello (timeout 124) with paging: layout data=0x40201000 end=0x4023c000 pool=0x4023c000 user=1, paging: ok, heap: ok, sched: ok, wx: nx heap / wx: ok, guard: fault / guard: ok, ro: nx data / ro: write fault / ro: ok, el0: svc / el0: nx kernel / el0: no kernel read / el0: ok, perf: cntpct delta=21094, perf: boot-delta ticks=115251, timer: tick, perf: irq-delta min=12053 max=24899 spread=12846 n=8, input: rx 0x41, two exception: sync BRK, exception: fatal nested / kind=0x200. cargo test Running 38 tests all [ok] (adds layout_stress_crosses_first_ram_l2 + frame_allocator_ready_after_mmu). force-fail exit 1. qemu-smoke: ok. Loaded layout larger than the arm64 workstation Docker’s 3.78 MiB class (__data_start in the second RAM 2 MiB). Not Docker. GHA on this PR is a separate row. |
| CI on GitHub (layout L3 pool / PR #21) | .github/workflows/smoke.yml on cursor/layout-l3-user-map-c915 | Verified | Cloud-probe commit c04b84b: push 34563006005 and PR 34563008516 success (ubuntu-24.04 + ubuntu-24.04-arm). Merge-commit push 34563104020 success on 71ee15f. MRC grepped both-matrix serial: paging: layout data=0x40201000 … user=1, paging: ok, heap: ok, sched: ok, wx: ok, el0: ok, 38 tests, force-fail fail-closed. Do not copy that Verified onto arm64 workstation Docker. |
Docker smoke after the layout fix (main 71ee15f) | the arm64 workstation Docker Desktop linux/arm64 ./scripts/docker-smoke.sh after #21 merge | Verified | Sponsor re-run on 71ee15f: perf: elf-size bytes=3838592; Hello World!; paging: layout data=0x40201000 end=0x4023c000 pool=0x4023c000 user=1; paging: ok; heap: ok; sched: ok; wx: ok; guard: ok; ro: ok; el0: svc / el0: nx kernel / el0: no kernel read / el0: ok; perf: cntpct …; perf: boot-delta ticks=217103; perf: irq-delta …; input: rx 0x41; exception: sync BRK … / fatal nested …; Running 38 tests all [ok]; force-fail exit 1; qemu-smoke: ok; EXIT 0. Keep the b2bbb99 Failed row (antifragility history). Not this cloud VM. |
| qemu-smoke requires ASID isolation strings | scripts/qemu-smoke.sh hello phase greps asid: ok / asid: dual / asid: conflict; rejects asid: stale and asid: probe missed | Verified | 2026-09-11 cloud: qemu-smoke: ASID isolation strings present. |
scripts/qemu-smoke.sh (ASID isolation / this branch) | Ran on this cloud VM | Verified | 2026-09-11 (QEMU 8.2.2, rustc 1.100.0-nightly 67eda617e): host perf: elf-size bytes=3853144; hello (timeout 124) with paging: layout data=0x40201000 end=0x4023f000 pool=0x4023f000 user=1, paging: ok, heap: ok, sched: ok, wx: nx heap / wx: ok, guard: fault / guard: ok, ro: nx data / ro: write fault / ro: ok, el0: svc / el0: nx kernel / el0: no kernel read / el0: ok, asid: dual / asid: conflict / asid: ok, perf: cntpct delta=21093, perf: boot-delta ticks=115983, timer: tick, perf: irq-delta min=9499 max=29721 spread=20222 n=8, input: rx 0x41, two exception: sync BRK, exception: fatal nested / kind=0x200. cargo test Running 39 tests all [ok]. force-fail exit 1. qemu-smoke: ok. Not Docker. GHA on this PR is a separate row. |
| CI on GitHub (ASID isolation / PR #23) | .github/workflows/smoke.yml on cursor/el0-asid-isolation-f98d | Unknown | No green GHA URL on the cloud-probe commit recorded here. Merged as #23 (fb050b7). |
scripts/qemu-smoke.sh (standing EL0 + TTBR1 / this branch) | Ran on this cloud VM | Verified | 2026-09-11 (QEMU 8.2.2, rustc 1.100.0-nightly 67eda617e): host perf: elf-size bytes=3872120; hello (timeout 124) with paging: layout data=0x40201000 end=0x40243000 pool=0x40243000 user=1, paging: ok, heap: ok, sched: ok, wx: nx heap / wx: ok, guard: fault / guard: ok, ro: nx data / ro: write fault / ro: ok, el0: svc / el0: nx kernel / el0: no kernel read / el0: standing / el0: restored / el0: ok, asid: dual / asid: conflict / asid: ok, ttbr1: el1 / ttbr1: no el0 / ttbr1: ok, perf: cntpct delta=23782, perf: boot-delta ticks=127971, timer: tick, perf: irq-delta min=11604 max=27616 spread=16012 n=8, input: rx 0x41, two exception: sync BRK, exception: fatal nested / kind=0x200. cargo test Running 42 tests all [ok]. force-fail exit 1. qemu-smoke: ok. Not Docker. GHA on this PR is a separate row. |
| CI on GitHub (standing EL0 + TTBR1 / PR #24) | .github/workflows/smoke.yml on cursor/el0-standing-ttbr1-5ce0 | Unknown | No green GHA URL on the cloud-probe commit recorded here. Merged as #24 (8745939). |
scripts/qemu-smoke.sh (TTBR1 high-VA exec / this branch) | Ran on this cloud VM | Verified | 2026-09-11 (QEMU 8.2.2, rustc 1.100.0-nightly 67eda617e): host perf: elf-size bytes=3877712; hello (timeout 124) with paging: layout data=0x40201000 end=0x40243000 pool=0x40243000 user=1, paging: ok, heap: ok, sched: ok, wx: nx heap / wx: ok, guard: fault / guard: ok, ro: nx data / ro: write fault / ro: ok, el0: svc / el0: nx kernel / el0: no kernel read / el0: standing / el0: restored / el0: ok, asid: dual / asid: conflict / asid: ok, ttbr1: el1 exec / ttbr1: vbar / ttbr1: el1 / ttbr1: no el0 / ttbr1: ok, perf: cntpct delta=20622, perf: boot-delta ticks=117383, timer: tick, perf: irq-delta min=11983 max=21932 spread=9949 n=8, input: rx 0x41, two exception: sync BRK, exception: fatal nested / kind=0x200 (fatal elr=0xffffff80400839e4). cargo test Running 44 tests all [ok]. force-fail exit 1. qemu-smoke: ok. Not Docker. GHA on this PR is a separate row. |
| CI on GitHub (TTBR1 high-VA exec / PR #25) | .github/workflows/smoke.yml on cursor/ttbr1-high-el1-exec-136c | Unknown | No green GHA URL on the cloud-probe commit recorded here. Merged as #25 (008f7c7). |
scripts/qemu-smoke.sh (identity-tear first cut / this branch) | Ran on this cloud VM | Verified | 2026-09-11 (QEMU 8.2.2, rustc 1.100.0-nightly 67eda617e): host perf: elf-size bytes=3895632; hello (timeout 124) with paging: layout data=0x40201000 end=0x40255000 pool=0x40255000 user=1, paging: ok, heap: ok, sched: ok, wx: nx heap / wx: ok, guard: fault / guard: ok, ro: nx data / ro: write fault / ro: ok, el0: svc / el0: nx kernel / el0: no kernel read / el0: standing / el0: restored / el0: ok, asid: dual / asid: conflict / asid: ok, ttbr1: el1 exec / ttbr1: vbar / ttbr1: el1 / ttbr1: no el0 / ttbr1: ok, ident: split / ident: fault / ident: high / ident: no el0 / ident: ok, perf: cntpct delta=25355, perf: boot-delta ticks=130631, timer: tick, perf: irq-delta min=14217 max=34342 spread=20125 n=8, input: rx 0x41, two exception: sync BRK, exception: fatal nested / kind=0x200 (fatal elr=0xffffff8040083bec). cargo test Running 47 tests all [ok]. force-fail exit 1. qemu-smoke: ok. Not Docker. GHA on this PR is a separate row. |
| CI on GitHub (identity-tear first cut / PR #26) | .github/workflows/smoke.yml on cursor/identity-teardown-c0fd | Unknown | No green GHA URL on the cloud-probe commit recorded here. Merged as #26 (b0f0ee5). |
Docker smoke on main b0f0ee5 (post PR #26 / ADR-018) | the arm64 workstation Docker Desktop linux/arm64 ./scripts/docker-smoke.sh after #26 merge | Verified | Sponsor re-run on b0f0ee5: 47 tests, ident: ok, fatal nested ELR high alias. Not this cloud VM. Keep prior Failed b2bbb99 row (antifragility history). |
qemu-smoke requires identity .text range-tear strings | scripts/qemu-smoke.sh hello phase greps ident: jump / ident: range / ident: text; rejects ident: range missed | Verified | 2026-09-11 cloud: qemu-smoke: identity-tear strings present (includes jump/range/text). |
scripts/qemu-smoke.sh (identity text range tear / this branch) | Ran on this cloud VM | Verified | 2026-09-11 3e710e1 (QEMU 8.2.2, rustc 1.100.0-nightly 67eda617e): host perf: elf-size bytes=3905712; hello (timeout 124) with ident: jump, ident: range lo=0x400ac000 hi=0x400b0000 pages=4, paging: layout data=0x40201000 end=0x40255000 pool=0x40255000 user=1, paging: ok, heap: ok, sched: ok, wx: ok, guard: ok, ro: ok, el0: ok, asid: ok, ttbr1: ok, ident: split / ident: fault / ident: high / ident: text / ident: no el0 / ident: ok, perf: cntpct delta=20293, perf: boot-delta ticks=92466, timer: tick, perf: irq-delta min=12711 max=26328 spread=13617 n=8, input: rx 0x41, two exception: sync BRK (ELRs 0xffffff8040082758 / 0xffffff8040082730), exception: fatal nested / kind=0x200 (fatal elr=0xffffff8040083bf4). cargo test Running 48 tests all [ok]. force-fail exit 1. qemu-smoke: ok. Not Docker. GHA on this PR is a separate row. |
CI on GitHub (identity text range tear / PR #27 ac3ad0b) | .github/workflows/smoke.yml on cursor/identity-tear-text-range-ea15 @ ac3ad0b | Failed | Both matrices: hello printed ident: jump / ident: range then ident: probe missed (init still required a 4 KiB __ident_tear_*; ADR-019 is 16 KiB). Keep this Failed row. |
CI on GitHub (identity text range tear / main 24d94e6) | .github/workflows/smoke.yml merge-commit push on 24d94e6 | Verified | Push 34640667227 success (ubuntu-24.04 + ubuntu-24.04-arm). Grepped both jobs: hello ident: jump / ident: range lo=0x400ac000 hi=0x400b0000 pages=4 / ident: text / ident: ok; BRK/fatal ELRs high; Running 48 tests; force-fail exit 1; qemu-smoke: ok. |
Docker smoke on main 24d94e6 (post PR #27 / ADR-019) | the arm64 workstation Docker Desktop linux/arm64 ./scripts/docker-smoke.sh after #27 merge | Verified | Sponsor re-run on 24d94e6: ident: jump, 16 KiB range tear, ident: ok, BRK/fatal on high ELRs, 48 tests + force-fail. Not this cloud VM. Keep the b2bbb99 Failed row. |
qemu-smoke requires identity reloc + live .text strings | scripts/qemu-smoke.sh hello phase greps ident: reloc / ident: live; rejects ident: reloc missed / ident: live missed | Verified | 2026-09-11 cloud: qemu-smoke: identity-tear strings present (includes reloc/live). |
scripts/qemu-smoke.sh (ADR-020 live .text tear / this branch) | Ran on this cloud VM | Verified | 2026-09-11 0fda690 (QEMU 8.2.2, rustc 1.100.0-nightly 67eda617e): host perf: elf-size bytes=3988408; hello (timeout 124) with ident: jump, ident: reloc n=12, ident: range lo=0x400ae000 hi=0x400b2000 pages=4, ident: live lo=0x40081000 hi=0x400a6000 pages=37, paging: layout data=0x40201000 end=0x40255000 pool=0x40255000 user=1, paging: ok, heap: ok, sched: ok, wx: nx heap / wx: ok, guard: fault / guard: ok, ro: nx data / ro: write fault / ro: ok, el0: svc / el0: nx kernel / el0: no kernel read / el0: standing / el0: restored / el0: ok, asid: dual / asid: conflict / asid: ok, ttbr1: el1 exec / ttbr1: vbar / ttbr1: el1 / ttbr1: no el0 / ttbr1: ok, ident: split / ident: fault / ident: high / ident: text / ident: no el0 / ident: ok, perf: cntpct delta=21002, perf: boot-delta ticks=94258, timer: tick, perf: irq-delta min=10686 max=27025 spread=16339 n=8, input: rx 0x41, two exception: sync BRK (ELRs 0xffffff8040082990 / 0xffffff8040082968), exception: fatal nested / kind=0x200 (fatal elr=0xffffff8040083e2c). cargo test Running 50 tests all [ok]. force-fail exit 1. qemu-smoke: ok. Not Docker. GHA on this PR is a separate row. |
CI on GitHub (ADR-020 live .text tear / this branch) | .github/workflows/smoke.yml on cursor/adr-020-live-text-reloc-322c | Unknown | No green GHA URL on the cloud-probe commit recorded here. Merged as #28 (e80dc93). |
CI on GitHub (ADR-020 live .text tear / main e80dc93) | .github/workflows/smoke.yml merge-commit push on e80dc93 | Verified | Push 34651404108 success (ubuntu-24.04 + ubuntu-24.04-arm). Grepped both jobs: hello ident: jump / ident: reloc n=12 / ident: live lo=0x40081000 hi=0x400a6000 pages=37 / ident: ok; Hello World! after the tear; Running 50 tests; force-fail exit 1; qemu-smoke: ok. |
Docker smoke on main e80dc93 (post PR #28 / ADR-020) | the arm64 workstation Docker Desktop linux/arm64 ./scripts/docker-smoke.sh after #28 merge | Verified | Sponsor re-run on e80dc93: 50 tests, ident: reloc n=12, live pages=37, force-fail ok. Not this cloud VM. Keep the earlier 24d94e6 Docker Verified row and the b2bbb99 Failed row. |
| mdBook docs site builds locally | ./scripts/docs-build.sh (mdBook 0.5.4 + mdbook-mermaid 0.17.1) writes book/ and book/CNAME is ctos.artof.link | Verified | 2026-09-11 this cloud VM (plain-English / mermaid branch): mdbook v0.5.4; mdbook-mermaid 0.17.1; docs-build: ok; mermaid class="mermaid" nodes on landing + overview + pillars. Generator only. Live URL is a separate row. Re-probe on this Darwin-pin rebase is a separate row. |
mdBook PATH pin compare strips clap v | PATH mdbook v0.5.4; ./scripts/docs-build.sh does not print the mismatch warning | Verified | 2026-09-12 this cloud VM on 8d14d08 rebase tip: real binary mdbook --version = mdbook v0.5.4; ${have#v} = 0.5.4; script output had no using PATH binary anyway and no re-download. Same strip on a bare 0.5.4 stays 0.5.4. Not a Darwin install probe. |
| docs-build auto-install on Linux (this rebase) | ./scripts/docs-build.sh with no PATH mdbook / mdbook-mermaid | Verified | 2026-09-12 this cloud VM (Linux/x86_64): downloaded x86_64-unknown-linux-gnu for mdBook 0.5.4 and mdbook-mermaid 0.17.1; docs-build: ok; mermaid class="mermaid" + book/CNAME = ctos.artof.link. Generator only. |
| docs-build auto-install on Darwin | Run ./scripts/docs-build.sh with no PATH mdbook / mdbook-mermaid on macOS (uname -s = Darwin) | Unknown | Source maps Darwin:arm64 / Darwin:x86_64 to published aarch64-apple-darwin / x86_64-apple-darwin assets for mdBook 0.5.4 and mdbook-mermaid 0.17.1 (GitHub release API listed those tarballs). This VM is Linux; Darwin download/extract was not run. |
| mdBook docs site builds locally (B7 / this branch) | ./scripts/docs-build.sh on cursor/b7-containers-nongoal-6b58 | Verified | 2026-09-12 this cloud VM: mdbook v0.5.4; mdbook-mermaid 0.17.1; docs-build: ok; book/CNAME is ctos.artof.link; generated hosting-apps.html / track-b.html contain ADR-029 + non-goal. Generator only. Pages GHA on this PR is a separate row. |
| Pages workflow builds this PR (B7 containers non-goal) | .github/workflows/pages.yml on cursor/b7-containers-nongoal-6b58 @ 1dd0a4f | Verified | PR run 34688560928 success (mdBook build 7s). Deploy job skipped on pull_request (expected). Not a new live-site deploy. Later docs-only SHAs on this branch are not this probe. |
| Pages workflow file exists | Read .github/workflows/pages.yml | Verified | Workflow present: PR builds the book; main uploads + actions/deploy-pages. Not a live URL. |
| Pages workflow builds this PR | .github/workflows/pages.yml on cursor/docs-pages-site-c371 | Verified | PR run 34651704287 success (mdBook build 7s). Deploy job skipped on pull_request (expected). Not a live site. |
| Pages workflow builds this PR (plain-English / mermaid) | .github/workflows/pages.yml on cursor/docs-plain-english-diagrams-e4a9 | Verified | PR run 34654325467 success (mdBook build 5s). Deploy job skipped on pull_request (expected). Not a new live-site deploy. |
| Docs website published (GitHub Pages) | Green pages workflow on main and an HTTPS fetch of https://ctos.artof.link | Verified | 2026-09-11 this cloud VM after #30: main deploy 34653046584 success (mdBook build + Deploy GitHub Pages). curl -sSI https://ctos.artof.link HTTP 200; body includes Driving principles. https://artofdream.github.io/ctos (no trailing slash) 301s to the custom domain; .../ctos/ 404’d — not a second live tree. From #51; not re-probed on this A1 rebase. |
Public CNAME ctos.artof.link → artofdream.github.io | dig CNAME ctos.artof.link +short | Verified | 2026-09-11 this cloud VM (repeat): artofdream.github.io. DNS is in place at the public resolver. Serving the book is the Verified docs-site / reachability rows. From #51; not re-probed here. |
Route 53 ctos CNAME in account <aws-account-id> zone <route53-zone-id> | Sponsor stated CREATE done (zone <route53-zone-id>); API list-resource-record-sets as that account | Unknown | This environment still has no AWS CLI / credentials. Sponsor named the zone and said the record exists. Do not CREATE again. Public dig is the Verified row above, not this API probe. |
Custom domain ctos.artof.link reachability | Pages Settings/API lists the hostname and curl -sSI https://ctos.artof.link is HTTP 200 with a cert for that name | Verified | 2026-09-11 this cloud VM: Pages API cname=ctos.artof.link, https_enforced=true, cert state=approved (expires 2026-12-10). HTTPS 200; TLS CN=ctos.artof.link (Let’s Encrypt). Route 53 API LIST stays the Unknown row above. From #51; not re-probed here. |
| Guest filesystem (virtio-blk + FAT16) | Hello-kernel serial blk: ok + fat: ok; VFS /probe | Verified | This tip’s qemu-smoke (see A7 rows below). Host -drive alone is not the probe. memfs is a separate A6 row. Do not say “supports FAT” as a product. |
| Guest runs host apps (Linux ELF / shell / Python) | No exec, libc, or app-load serial marker | Planned | Site: docs/overview/hosting-apps.md. Extra: host-apps.md. Today: in-tree samples only. A1 is a kernel ABI mile, not this row. |
| Guest is a container host (OCI / Docker / k8s) | Source: no OCI, runc, cgroup, or namespace code in src/ | Verified | Absence + non-goal (ADR-029, Track B B7 / #47). Site: hosting-apps.md. Host docker-smoke.sh is a build harness, not a guest runtime. Not Planned. Reopen only with a new epic + ADR. |
| Product “immutable OS” | Marketing sentence vs immutability.md | Planned | Non-claim. Absolute immutability is incompatible (heap/PTEs/devices mutate). Scoped RO is ADR-015 / ADR-020. Site: advantages.md. File presence is not Verified. |
| OS image vs app payloads disconnected (A9 first cut) | Host OS ELF + target/hello-libctos.elf; FAT /hello; hello serial slot: fat + slot: mapped + slot: ok; #[test_case] slot_load_from_fat_erets | Verified | 2026-09-12 this cloud VM (QEMU 8.2.2, rustc 1.100.0-nightly 0fc141305): host OS perf: elf-size bytes=4392040 + app 8624 bytes; FAT /hello; serial slot: fat bytes=8624 / slot: mapped segs=3 entry=0x80002000 / slot: ok / perf: app-load ticks=1134019. A1–A8 markers still present. First-cut note: A2–A4 still include_bytes! on that SHA. Leftover embed-off is a later row. Not “apps update independently.” |
| A9 cross-update (same app on OS n and n+1) | Same published hello-libctos.elf (sha256sum) on this OS tip and documented prior OS ba6541c (A9 merge; earliest main tip with the slot/FAT path); scripts/qemu-smoke.sh greps slot: ok on both boots | Verified | 2026-09-12 this cloud VM (QEMU 8.2.2, rustc 1.100.0-nightly 0fc141305): app sha256=142dedf1c3f6452555fe3af86c8bfafa260f083fecfdc81159063c433872d865 bytes=8624; host cross-update prior-os=ba6541c8e17c75c89c42451cd721735eddb36c2f slot:ok + cross-update this-os=800f52d183d0d58839f4c7363ac9d069414e55fc slot:ok. Both boots slot: fat bytes=8624 / slot: mapped / slot: ok. Prior kernel built from that SHA (no stored blob). Not “apps update independently.” |
| A9 slot-disconnect performance delta (ADR-046) | Hello serial perf: app-load ticks=<n> + perf: embed-load ticks=<n> + perf: slot-delta app=<a> embed=<b>; #[test_case] embed CNTPCT + bytes match FAT; smoke rejects slot: embed / percent marketing | Verified | 2026-09-13 agent-box qemu-smoke (QEMU 10.0.13, rustc 1.100.0-nightly 0fc141305, -cpu cortex-a57) on a9/slot-perf-delta bb0379d: hello slot: fat bytes=8624 / slot: mapped / slot: ok / perf: app-load ticks=1079247 / perf: embed-load ticks=62805 / perf: slot-delta app=1079247 embed=62805 (no slot: embed); Running 92 tests all [ok] incl. slot_embed_probe_bytes_match_fat; force-fail exit 1; A9 cross-update both slot:ok; qemu-smoke: ok. Probe-only include_bytes! in src/slot.rs only. QEMU TCG lab — not a published bench, not a percent. Isolation leftovers (PAN enable / taken SError / yank _start / umbrella) unchanged Planned. (amd64 workstation) intent; CloudAgent HELD — probe on agent box clone. ADR-046. |
| Threat-model v1.9 slice (NFR-10) | Read security.md (SVC ABI mile; app hosting Planned) | Verified | File + A1 PR. v1.9 update, not “secure.” |
| Threat-model v1.10 slice (NFR-10) | Read security.md (libctos CRT mile; app hosting Planned) | Verified | File + A2 PR. v1.10 update, not “secure.” |
| Threat-model v1.11 slice (NFR-10) | Read security.md (guest ELF PT_LOAD loader mile; app hosting Planned) | Verified | File + this PR. v1.11 update, not “secure.” |
SVC ABI (exit / uart_write / yield) (ADR-021 / Track A A1) | Hello-kernel serial svc: yield + svc: user-hi + svc: uart + svc: exit + svc: ok; #[test_case] el0_svc_abi_yield_uart_exit + el0_uart_write_rejects_kernel_data + el0_uart_write_rejects_high_alias | Verified | 2026-09-11 tip 09425c0 (onto aa46219 / #29). Serial below. App hosting stays Planned. Not Linux. |
| qemu-smoke requires SVC ABI strings | scripts/qemu-smoke.sh hello phase greps svc: ok / svc: yield / svc: user-hi / svc: uart / svc: exit; rejects svc: probe missed | Verified | 2026-09-11 09425c0: qemu-smoke: SVC ABI strings present. |
scripts/qemu-smoke.sh (SVC ABI / this branch) | Ran on this cloud VM | Verified | 2026-09-11 09425c0 (QEMU 8.2.2, rustc 1.100.0-nightly 67eda617e): host perf: elf-size bytes=4020520; hello (timeout 124) with ident: jump / ident: reloc n=12 / ident: live / paging: ok / heap: ok / sched: ok / wx: ok / guard: ok / ro: ok / el0: standing / el0: restored / el0: ok / svc: yield / svc: user-hi / svc: uart n=13 / svc: exit / svc: ok / asid: ok / ttbr1: ok / ident: ok / perf: cntpct delta=20326 / perf: boot-delta ticks=104297 / timer: tick / input: rx 0x41 / exception: fatal nested. cargo test Running 54 tests all [ok] (includes el0_uart_write_rejects_high_alias). force-fail exit 1. qemu-smoke: ok. Not Docker. GHA on this tip is a separate row. |
| CI on GitHub (SVC ABI / this branch) | .github/workflows/smoke.yml on cursor/svc-syscall-abi-0dc5 | Unknown | Prior GHA is not this tip (09425c0). |
| Track A app hosting (slots) | Product “apps run independently of the OS” | Verified | Parent issue #31. Claim gate ADR-048 criteria 1–5 Met on tip be789c5+; sponsor accept ADR-052 (sponsor: “address 1. app hosting” after still-Planned #5-only review). Evidence: A8 recipes Verified; A9 cross-update cross-update … slot:ok on this OS + ba6541c; no production embed (probe-only include_bytes! in src/slot.rs / ADR-046; smoke rejects slot: embed); honesty — not Linux/POSIX/containers (ADR-029). Not Linux userspace, POSIX, glibc/musl, guest OCI, “EL0 isolated,” PAN enable, taken SError Verified, immutable-OS marketing, or OTA. |
| Documented sample apps (Track A A8) | Read what-can-run.md, apps-today.md, in-tree user/README.md; recipes cite only existing serial markers; ./scripts/docs-build.sh | Verified | 2026-09-12 this cloud VM: file read of the recipes + docs-build after rebase onto main c63077e (B7 / ADR-029; next row). Coop UART (sched:*), RX echo (input: rx 0x41), standing EL0 / libctos hello (libctos:* / loader:* / el0: task-*), optional memfs (fs:*) + FAT16 (blk:* / fat:*). No new runtime markers. No ADR (docs-only). App hosting stays Planned. A9 first cut is a later row. Guest containers stay non-goal. Kernel qemu-smoke not re-run (no src/ edit). |
scripts/docs-build.sh (A8 recipes / this branch) | Ran on this cloud VM | Verified | 2026-09-12 after rebase onto c63077e (B7 / ADR-029 + Darwin pin): mdbook v0.5.4; mdbook-mermaid 0.17.1; Linux auto-install x86_64-unknown-linux-gnu; docs-build: ok; book/CNAME is ctos.artof.link. Generator only. Live URL is a separate row. Kernel qemu-smoke not re-run (no src/ edit). |
| Standing EL0 as normal mode (ADR-024 / Track A A4) | Hello-kernel serial el0: task-enter + el0: task-active + el0: task-exit + el0: task-restored + el0: restore-fail + el0: task-ok; #[test_case] standing_task_runs_until_exit + standing_task_fault_restores | Verified | 2026-09-12 this cloud VM (QEMU 8.2.2, rustc 1.100.0-nightly 0fc141305): after loader: ok, serial el0: task-enter / el0: task-active / payload libctos: hi / libctos: ok / svc: exit / el0: task-exit / el0: task-restored / second el0: task-enter / el0: restore-fail / el0: task-ok. A1–A3 markers still present. Not isolation. App hosting stays Planned. |
| qemu-smoke requires standing-task strings | scripts/qemu-smoke.sh hello phase greps el0: task-ok / el0: task-enter / el0: task-active / el0: task-exit / el0: task-restored / el0: restore-fail; rejects el0: task missed | Verified | 2026-09-12 this cloud VM: qemu-smoke: standing-task (A4) strings present. |
scripts/qemu-smoke.sh (standing-as-normal / this branch) | Ran on this cloud VM | Verified | 2026-09-12 this tip (QEMU 8.2.2, rustc 1.100.0-nightly 0fc141305): host perf: elf-size bytes=4108960; hello (timeout 124) with ident: jump / ident: reloc n=12 / ident: live lo=0x40081000 hi=0x400ac000 pages=43 / paging: ok / heap: ok / sched: ok / wx: ok / guard: ok / ro: ok / el0: standing / el0: restored / el0: ok / svc: yield / svc: user-hi / svc: uart n=13 / svc: exit / svc: ok / libctos: hi / libctos: ok / libctos: linked / loader: mapped segs=3 entry=0x80002000 / loader: ok / el0: task-enter / el0: task-active / el0: task-exit / el0: task-restored / el0: restore-fail / el0: task-ok / asid: ok / ttbr1: ok / ident: ok / perf: cntpct delta=20161 / perf: boot-delta ticks=94742 / timer: tick / input: rx 0x41 / exception: fatal nested. cargo test Running 66 tests all [ok] (adds standing_task_runs_until_exit + standing_task_fault_restores). force-fail exit 1. qemu-smoke: ok. Not Docker. GHA on this tip is a separate row. |
| CI on GitHub (standing-as-normal / this branch) | .github/workflows/smoke.yml on cursor/a4-standing-el0-normal-1e14 | Unknown | No green GHA URL on the cloud-probe commit recorded here. |
| Threat-model v1.12 slice (NFR-10) | Read security.md (standing-as-normal mile; app hosting Planned) | Verified | File + A4 PR. v1.12 update, not “secure.” |
| Threat-model v1.13 slice (NFR-10) | Read security.md (identity .rodata tear + PAN ID-field; app hosting Planned) | Verified | File + A5 PR. v1.13 update, not “secure.” |
| Threat-model v1.14 slice (NFR-10) | Read security.md (thin VFS + memfs mile; app hosting Planned) | Verified | File + this PR. v1.14 update, not “secure.” |
| Thin VFS + memfs (ADR-027 / Track A A6) | Hello-kernel serial fs: create + fs: write + fs: read + fs: el0 + fs: ok; #[test_case] vfs_memfs_create_write_read_close + el0_fs_svc_roundtrip + el0_fs_write_rejects_kernel_data | Verified | 2026-09-12 this cloud VM (QEMU 8.2.2, rustc 1.100.0-nightly 0fc141305, -cpu cortex-a57): after el0: task-ok, serial fs: create / fs: write / fs: read / svc: exit / fs: el0 / fs: ok. cargo test all three new cases [ok]. Not POSIX. Not FAT. App hosting stays Planned. |
| qemu-smoke requires memfs strings | scripts/qemu-smoke.sh hello phase greps fs: ok / fs: create / fs: write / fs: read / fs: el0; rejects fs: probe missed | Verified | 2026-09-12 this cloud VM: qemu-smoke: thin VFS + memfs (A6) strings present. |
scripts/qemu-smoke.sh (thin VFS + memfs / this branch) | Ran on this cloud VM | Verified | 2026-09-12 this tip (QEMU 8.2.2, rustc 1.100.0-nightly 0fc141305): host perf: elf-size bytes=4291384; hello (timeout 124) with ident: jump / ident: reloc n=12 / ident: live lo=0x40081000 hi=0x400b4000 pages=51 / ident: ro-reloc n=683 / ident: rodata lo=0x400b4000 hi=0x400c0000 pages=12 / pan: id=0 / pan: absent / paging: ok / heap: ok / sched: ok / wx: ok / guard: ok / ro: ok / el0: standing / el0: restored / el0: ok / svc: ok / libctos: ok / loader: ok / el0: task-ok / fs: create / fs: write / fs: read / fs: el0 / fs: ok / asid: ok / ttbr1: ok / ident: split / ident: fault / ident: high / ident: text / ident: no el0 / ident: rodata-fault / ident: rodata-high / ident: ok / perf: cntpct delta=21003 / perf: boot-delta ticks=104836 / timer: tick / input: rx 0x41 / exception: fatal nested. cargo test Running 73 tests all [ok] (adds vfs_memfs_create_write_read_close + vfs_open_missing_is_err + el0_fs_svc_roundtrip + el0_fs_write_rejects_kernel_data + vfs_paths_and_caps_are_documented). force-fail exit 1. qemu-smoke: ok. Not Docker. GHA on this tip is a separate row. |
| CI on GitHub (thin VFS + memfs / this branch) | .github/workflows/smoke.yml on cursor/a6-thin-vfs-memfs-766a | Unknown | No green GHA URL on this tip yet. |
Identity .rodata tear (ADR-025 / Track A A5) | Hello-kernel serial ident: ro-reloc + ident: rodata + ident: rodata-fault + ident: rodata-high + existing ident: ok; #[test_case] identity_rodata_unmapped_high_stays | Verified | 2026-09-12 this cloud VM (QEMU 8.2.2, rustc 1.100.0-nightly 0fc141305, -cpu cortex-a57): after ident: live, serial ident: ro-reloc n=589 / ident: rodata lo=0x400ad000 hi=0x400b8000 pages=11 then later ident: rodata-fault / ident: rodata-high / ident: ok. Hello World! after the tear. cargo test identity_rodata_unmapped_high_stays [ok]. .data/heap stay. Not “EL0 isolated.” |
| PAN capability ID field (ADR-026 / Track A A5) | Hello-kernel serial pan: id= + pan: absent; #[test_case] pan_unimplemented_on_probe_cpu | Verified | 2026-09-12 this cloud VM: pan: id=0 / pan: absent. cargo test pan_unimplemented_on_probe_cpu [ok]. Enable stays Planned. Do not switch -cpu. |
qemu-smoke requires identity .rodata + PAN strings | scripts/qemu-smoke.sh hello phase greps ident: rodata / ident: rodata-fault / ident: rodata-high / pan: id= / pan: absent; rejects ident: rodata missed / pan: probe missed / pan: enabled | Verified | 2026-09-12 this cloud VM: qemu-smoke: identity-tear strings present + qemu-smoke: PAN capability strings present. |
scripts/qemu-smoke.sh (A5 identity .rodata + PAN / this branch) | Ran on this cloud VM | Verified | 2026-09-12 this tip (QEMU 8.2.2, rustc 1.100.0-nightly 0fc141305): host perf: elf-size bytes=4121360; hello (timeout 124) with ident: jump / ident: reloc n=12 / ident: live lo=0x40081000 hi=0x400ad000 pages=44 / ident: ro-reloc n=589 / ident: rodata lo=0x400ad000 hi=0x400b8000 pages=11 / pan: id=0 / pan: absent / paging: ok / heap: ok / sched: ok / wx: ok / guard: ok / ro: ok / el0: standing / el0: restored / el0: ok / svc: ok / libctos: ok / loader: ok / el0: task-ok / asid: ok / ttbr1: ok / ident: split / ident: fault / ident: high / ident: text / ident: no el0 / ident: rodata-fault / ident: rodata-high / ident: ok / perf: cntpct delta=21378 / perf: boot-delta ticks=96439 / timer: tick / input: rx 0x41 / exception: fatal nested. cargo test Running 68 tests all [ok] (adds identity_rodata_unmapped_high_stays + pan_unimplemented_on_probe_cpu). force-fail exit 1. qemu-smoke: ok. Not Docker. GHA on this tip is a separate row. |
| CI on GitHub (A5 / this branch) | .github/workflows/smoke.yml on cursor/a5-identity-tear-pan-0355 | Verified | PR run 34678808063 success on 726a4a2 (ubuntu-24.04 job 103513419325 + ubuntu-24.04-arm job 103513419189). Both matrices grepped: hello ident: ro-reloc n=588 / ident: rodata lo=0x400ad000 hi=0x400b8000 pages=11 / ident: rodata-fault / ident: rodata-high / pan: id=0 / pan: absent / ident: live / el0: task-ok / loader: ok / libctos: ok / svc: ok; Running 68 tests; qemu-smoke: identity-tear strings present / qemu-smoke: PAN capability strings present / qemu-smoke: ok. Push run 34678806604 success. mdBook 34678808079 success (Pages deploy skipped on PR). Cursor Bugbot pass on 726a4a2. Later docs-only SHAs on this branch are not this probe. |
| Guest ELF PT_LOAD loader (ADR-023 / Track A A3) | Hello-kernel serial loader: mapped + loader: ok; payload libctos: hi / libctos: ok; #[test_case] loader_maps_hello_and_erets | Verified | 2026-09-12 this cloud VM (QEMU 8.2.2, rustc 1.100.0-nightly 0fc141305): loader: mapped segs=3 entry=0x80002000 then loader: ok. Payload printed libctos: hi / libctos: ok on the loaded trip (after the A2 memcpy trip). Not a Linux ABI. App hosting stays Planned. |
| qemu-smoke requires guest loader strings | scripts/qemu-smoke.sh hello phase greps loader: ok / loader: mapped; rejects loader: probe missed | Verified | 2026-09-12 this cloud VM: qemu-smoke: guest ELF loader strings present. |
scripts/qemu-smoke.sh (guest ELF loader / this branch) | Ran on this cloud VM | Verified | 2026-09-12 this tip (QEMU 8.2.2, rustc 1.100.0-nightly 0fc141305): host perf: elf-size bytes=4101056; hello (timeout 124) with ident: jump / ident: reloc n=12 / ident: live lo=0x40081000 hi=0x400ac000 pages=43 / paging: ok / heap: ok / sched: ok / wx: ok / guard: ok / ro: ok / el0: standing / el0: restored / el0: ok / svc: yield / svc: user-hi / svc: uart n=13 / svc: exit / svc: ok / libctos: hi / libctos: ok / libctos: linked / loader: mapped segs=3 entry=0x80002000 / loader: ok / asid: ok / ttbr1: ok / ident: ok / perf: cntpct delta=21608 / perf: boot-delta ticks=98798 / timer: tick / input: rx 0x41 / exception: fatal nested. cargo test Running 64 tests all [ok] (adds loader_maps_hello_and_erets + parse / PT_INTERP / W+X / RX+R union). force-fail exit 1. qemu-smoke: ok. Not Docker. GHA on this tip is a separate row. |
| CI on GitHub (guest ELF loader / this branch) | .github/workflows/smoke.yml on cursor/a3-elf-loader-ttbr0-49f0 | Unknown | No green GHA URL on the cloud-probe commit recorded here. |
libctos CRT (exit / uart_write / yield wrappers) (ADR-022 / Track A A2) | Hello-kernel serial libctos: hi + libctos: ok + libctos: linked; #[test_case] libctos_hello_yield_uart_exit + libctos_payload_encodes_public_svc_only | Verified | 2026-09-12 tip c9b292b. Serial below. App hosting stays Planned. Not a guest ELF loader. Not Linux. |
| qemu-smoke requires libctos CRT strings | scripts/qemu-smoke.sh hello phase greps libctos: hi / libctos: ok / libctos: linked; rejects libctos: probe missed | Verified | 2026-09-12 this cloud VM: qemu-smoke: libctos CRT strings present. |
scripts/qemu-smoke.sh (libctos CRT / this branch) | Ran on this cloud VM | Verified | 2026-09-12 c9b292b (QEMU 8.2.2, rustc 1.100.0-nightly 0fc141305): host perf: elf-size bytes=4024936; hello (timeout 124) with ident: jump / ident: reloc n=12 / ident: live / paging: ok / heap: ok / sched: ok / wx: ok / guard: ok / ro: ok / el0: standing / el0: restored / el0: ok / svc: yield / svc: user-hi / svc: uart n=13 / svc: exit / svc: ok / libctos: hi / libctos: ok / libctos: linked / asid: ok / ttbr1: ok / ident: ok / perf: cntpct delta=38969 / perf: boot-delta ticks=153560 / timer: tick / input: rx 0x41 / exception: fatal nested. cargo test Running 57 tests all [ok] (adds libctos_hello_yield_uart_exit + payload SVC-only + ABI number match). force-fail exit 1. qemu-smoke: ok. Not Docker. GHA on this tip is a separate row. |
| CI on GitHub (libctos CRT / this branch) | .github/workflows/smoke.yml on cursor/libctos-crt-a2-590e | Unknown | No green GHA URL on the cloud-probe commit recorded here. |
| Threat-model v1.15 slice (NFR-10) | Read security.md (virtio-blk + FAT16 mile; app hosting Planned) | Verified | File + A7 PR. v1.15 update, not “secure.” |
| Threat-model v1.16 slice (NFR-10) | Read security.md (OS/app slot first cut; cross-update Planned) | Verified | File + A9 PR. v1.16 update, not “secure.” |
| Threat-model v1.17 slice (NFR-10) | Read security.md (leftover cross-update + FAT-only hello + stay markers; PAN enable Planned) | Verified | File + this PR. v1.17 update, not “secure.” |
A2–A4 hello without include_bytes! (ADR-032) | src/ has no include_bytes!.*hello-libctos; hello serial libctos: linked / loader: ok / el0: task-ok still from FAT /hello; build.rs still publishes target/hello-libctos.elf | Verified | 2026-09-12 this cloud VM: host qemu-smoke: kernel does not include_bytes! hello-libctos + kernel rebuild compiled app payload; serial libctos: linked / loader: ok / el0: task-ok / slot: ok. Same FAT /hello 8624 bytes. |
| virtio-blk (ADR-028 / Track A A7) | Hello-kernel serial blk: virtio + blk: cap + blk: rw + blk: ok; #[test_case] virtio_blk_capacity_and_rw | Verified | 2026-09-12 this cloud VM (QEMU 8.2.2, rustc 1.100.0-nightly 0fc141305, -cpu cortex-a57): after fs: ok, serial blk: virtio / blk: cap sectors=8192 / blk: rw / blk: ok. cargo test virtio_blk_capacity_and_rw + virtio_blk_boot_sector_is_fat [ok]. QEMU virt virtio-mmio legacy v1. Host -drive is not this row. |
| FAT16 via thin VFS (ADR-028 / Track A A7) | Hello-kernel serial fat: mount + fat: read + fat: ok; VFS /probe = fat-hi; #[test_case] fat16_vfs_open_probe | Verified | 2026-09-12 this cloud VM: fat: mount / fat: read / fat: ok. Same vfs::open as memfs. cargo test fat16_vfs_open_probe + fat16_missing_and_readonly + vfs_fat_probe_is_same_open [ok]. Not POSIX. Not FAT32. Not writeable FAT. |
| qemu-smoke requires virtio-blk + FAT16 strings | scripts/qemu-smoke.sh hello phase greps blk: ok / fat: ok; rejects blk: probe missed / fat: probe missed | Verified | 2026-09-12 this cloud VM: qemu-smoke: virtio-blk (A7) strings present + qemu-smoke: FAT16 (A7) strings present. |
scripts/qemu-smoke.sh (virtio-blk + FAT16 / this branch) | Ran on this cloud VM | Verified | 2026-09-12 435bf2d cache-sync follow-up (QEMU 8.2.2, rustc 1.100.0-nightly 0fc141305): host perf: elf-size bytes=4379520; hello (timeout 124) with blk: virtio / blk: cap sectors=8192 / blk: rw / blk: ok / fat: mount / fat: read / fat: ok plus A1–A6 markers (svc: ok / libctos: ok / loader: ok / el0: task-ok / fs: ok / ident: ok / pan: id=0). cargo test Running 79 tests all [ok]. force-fail exit 1. qemu-smoke: ok. Prior b4903e8 cloud + GHA rows stay. Not Docker. GHA on 435bf2d is a separate row. |
CI on GitHub (virtio-blk + FAT16 / b4903e8) | .github/workflows/smoke.yml on cursor/a7-virtio-blk-fat-a587 @ b4903e8 | Verified | PR run 34687722316 success (ubuntu-24.04 job 103537544581 + ubuntu-24.04-arm job 103537544698). Both matrices grepped: hello blk: virtio / blk: cap sectors=8192 / blk: rw / blk: ok / fat: mount / fat: read / fat: ok / fs: ok / el0: task-ok / loader: ok / libctos: ok / svc: ok / ident: ok / pan: id=0 / pan: absent; qemu-smoke: virtio-blk (A7) strings present / qemu-smoke: FAT16 (A7) strings present / Running 79 tests / qemu-smoke: ok. Push run 34687720964 success. mdBook 34687722361 success (Pages deploy skipped on PR). First 79c6432 PR smoke 34687537221 Failed (modern-only / blk: probe missed). |
| CI on GitHub (virtio-blk + FAT16 / cache-sync tip) | .github/workflows/smoke.yml on cursor/a7-virtio-blk-fat-a587 @ 435bf2d | Unknown | Cloud qemu-smoke Verified on this SHA (row above). No green gh run URL on 435bf2d yet. |
| OS/app slot first cut (ADR-030 / Track A A9) | Host OS ELF + target/hello-libctos.elf; FAT /hello; hello serial slot: fat + slot: mapped + slot: ok + perf: app-load; #[test_case] slot_fat_hello_is_elf + slot_load_from_fat_erets | Verified | Same 2026-09-12 cloud qemu-smoke as the row above. cargo test both new cases [ok]. A2–A4 still embed. Not cross-update. Not app hosting. |
| qemu-smoke requires A9 slot strings | scripts/qemu-smoke.sh greps slot: ok / slot: fat / slot: mapped / perf: app-load / perf: embed-load / perf: slot-delta; rejects slot: probe missed / slot: embed / percent marketing | Verified | 2026-09-12 this cloud VM: qemu-smoke: OS/app slot (A9) strings present. ADR-046 extends greps on this PR tip. |
scripts/qemu-smoke.sh (A9 slots / this branch) | Ran on this cloud VM | Verified | 2026-09-12 9ca7372 (QEMU 8.2.2, rustc 1.100.0-nightly 0fc141305): host perf: elf-size bytes=4392040; app target/hello-libctos.elf 8624 bytes; hello (timeout 124) with slot: fat bytes=8624 / slot: mapped segs=3 entry=0x80002000 / slot: ok / perf: app-load ticks=1134019 plus A1–A8 markers (svc: ok / libctos: ok / loader: ok / el0: task-ok / fs: ok / blk: ok / fat: ok / ident: ok / pan: id=0). cargo test Running 82 tests all [ok] (adds slot_fat_hello_is_elf + slot_load_from_fat_erets + slot_path_is_not_probe). force-fail exit 1. qemu-smoke: ok. Not Docker. GHA on this tip is a separate row. |
| CI on GitHub (A9 slots / this branch) | .github/workflows/smoke.yml on cursor/a9-os-app-slots-cf00 | Unknown | Cloud qemu-smoke Verified on 9ca7372. No green gh run URL on this tip yet. |
| mdBook docs site builds locally (A9 / this branch) | ./scripts/docs-build.sh on cursor/a9-os-app-slots-cf00 | Verified | 2026-09-12 this cloud VM: mdbook v0.5.4; mdbook-mermaid 0.17.1; docs-build: ok; book/CNAME is ctos.artof.link. Generator only. Pages GHA on this PR is a separate row. |
| mdBook docs site builds locally (ADR-002 Track A merge-hat / this branch) | ./scripts/docs-build.sh on cursor/adr-002-track-a-merge-hat-0e11 | Verified | 2026-09-12 this cloud VM: mdbook v0.5.4; mdbook-mermaid 0.17.1; Linux auto-install x86_64-unknown-linux-gnu; docs-build: ok. Generator only. Kernel qemu-smoke not run (no src/ edit). Distinct-identity merge stays Unknown. |
| Linux-compat goals documented (ADR-031 / Track B B1) | Read ADR-031 and track-b.md | Verified | Document inspection. ABI subset research frame. Not claiming Linux userspace. Guest containers stay non-goal (ADR-029). B2–B6 stay Planned. File presence is not a Linux ABI. Kernel qemu-smoke not run (no src/ edit). |
| mdBook docs site builds locally (B1 / this branch) | ./scripts/docs-build.sh on cursor/b1-linux-compat-goals-9374 | Verified | 2026-09-12 this cloud VM after rebase onto 4459b93 (#61): mdbook v0.5.4; mdbook-mermaid 0.17.1; Linux auto-install x86_64-unknown-linux-gnu; docs-build: ok; book/CNAME is ctos.artof.link; generated ADR-031 + track-b contain not claiming Linux userspace; ADR-002 page still has the Track A historical exception. Generator only. Pages GHA on this PR is a separate row. |
| mdBook docs site builds locally (mobile theme / this branch) | ./scripts/docs-build.sh on cursor/docs-mobile-responsive-81c4 | Verified | 2026-09-12 this cloud VM: mdbook v0.5.4; mdbook-mermaid 0.17.1; Linux auto-install x86_64-unknown-linux-gnu; docs-build: ok; book/CNAME is ctos.artof.link; *theme.css present in book/. Generator only. Pages GHA on this PR is a separate row. |
| Docs site mobile-compliant (narrow viewport) | ./scripts/docs-mobile-probe.sh after ./scripts/docs-build.sh (viewport meta + theme.css + Chrome iframe scrollWidth vs clientWidth) | Verified | 2026-09-12 this cloud VM (Google Chrome 148.0.7778.96): landing index.html overflow=no at 320 (client=320 scroll=320), 768, and 1280; framework/honesty-ledger.html @ 320 overflow=no; website.html @ 320 overflow=no. Wide tables/pre may scroll inside their widget. Mermaid CDN was blocked for this numeric probe (source text). Not a live https://ctos.artof.link mobile claim until a post-merge Pages fetch. |
scripts/qemu-smoke.sh (Track A leftovers / this branch) | Ran on this cloud VM | Verified | 2026-09-12 800f52d (QEMU 8.2.2, rustc 1.100.0-nightly 0fc141305): host OS perf: elf-size bytes=4410056; app 8624 bytes; hello (timeout 124) with A1–A9 markers (svc: ok / libctos: ok / loader: ok / el0: task-ok / fs: ok / blk: ok / fat: ok / slot: ok / ident: data-stay / ident: heap-stay / ident: ok / pan: id=0 / pan: absent); host embed ratchet; same-app cross-update on ba6541c + this tip (sha256=142dedf1…); cargo test Running 83 tests all [ok]; force-fail exit 1; qemu-smoke: ok. Re-probe on 17778ca and post-rebase 6abcb1b (onto e6255c0; same markers + qemu-smoke: ok). Re-probe on 7f52572 after the Docker-git / portable-sha256 ratchet: same A1–A9 + stay + sha256=142dedf1… + both cross-update … slot:ok + 83 tests + force-fail 1 + qemu-smoke: ok. Re-probe on 4a6b4f7 after moving /tmp/ctos-prior-os-* aside (stale .git/worktrees registration): git worktree add prior OS ba6541c then both cross-update … slot:ok + 83 tests + force-fail 1 + qemu-smoke: ok. Not Docker. GHA on 7b68d08 / 7f52572 are separate Verified rows. GHA on 4a6b4f7 / 70058db is Unknown until grepped. |
CI on GitHub (Track A leftovers / 17778ca) | .github/workflows/smoke.yml on cursor/track-a-leftovers-d2ee @ 17778ca | Verified | Push run 34701455001 success (ubuntu-24.04 job 103573837236 + ubuntu-24.04-arm job 103573837300). Both matrices grepped: kernel does not include_bytes! hello-libctos; hello slot: fat bytes=8624 / slot: ok / ident: data-stay / ident: heap-stay / svc: ok / libctos: ok / loader: ok / el0: task-ok / fs: ok / blk: ok / fat: ok / pan: absent; cross-update prior-os=ba6541c… slot:ok + cross-update this-os=17778ca… slot:ok; Running 83 tests; force-fail exited 1; qemu-smoke: ok. Prior ef9ff56 Failed closed (shallow clone missing ba6541c). |
CI on GitHub (Track A leftovers / 7b68d08) | .github/workflows/smoke.yml on cursor/track-a-leftovers-d2ee @ 7b68d08 (rebase onto 522c543 / #63) | Verified | Push run 34702218168 success (ubuntu-24.04-arm job 103575880564 + ubuntu-24.04 job 103575880766). PR run 34702220491 success (merge-ref ebdcc8d). Both matrices grepped: kernel does not include_bytes! hello-libctos; hello slot: fat bytes=8624 / slot: ok / ident: data-stay / ident: heap-stay / ident: ok / svc: ok / libctos: ok / loader: ok / el0: task-ok / fs: ok / blk: ok / fat: ok / pan: absent; cross-update prior-os=ba6541c… slot:ok + cross-update this-os=7b68d08… slot:ok (PR event this-os=ebdcc8d); Running 83 tests; force-fail exited 1; qemu-smoke: ok. Later ledger-only SHA is not this probe. |
| mdBook docs site builds locally (leftovers / this branch) | ./scripts/docs-build.sh on cursor/track-a-leftovers-d2ee | Verified | 2026-09-12 this cloud VM: mdbook v0.5.4; mdbook-mermaid 0.17.1; docs-build: ok. Generator only. Pages GHA on this PR is a separate row. |
| qemu-smoke requires A9 cross-update + stay + embed-off | scripts/qemu-smoke.sh greps both cross-update … slot:ok lines, ident: data-stay / ident: heap-stay, and rejects src/ hello include_bytes! | Verified | 2026-09-12 this cloud VM: qemu-smoke: A9 cross-update … strings present + identity-tear strings (includes stay) + kernel does not include_bytes! hello-libctos. |
| Leftover docker-smoke (git + prior SHA) | Dockerfile installs git; .dockerignore keeps .git objects but drops .git/worktrees; smoke git worktree prunes before add | Unknown | Source ratchet after Bugbot Mediums on 7b68d08 / 7b296e2. This cloud VM: command -v docker empty. File presence is not docker-smoke. |
| Leftover app sha256 pin (NFR-03) | qemu-smoke hashes via sha256sum / shasum -a 256 / openssl dgst -sha256 | Unknown | Source ratchet after Bugbot Medium on 7b68d08. This Linux tip used sha256sum (sha256=142dedf1… on 7f52572). Darwin shasum path not probed here. Same-app proof remains the cp of the published ELF. |
CI on GitHub (Track A leftovers / 7f52572) | .github/workflows/smoke.yml on cursor/track-a-leftovers-d2ee @ 7f52572 | Verified | Push run 34702699720 success (ubuntu-24.04 job 103577150895 + ubuntu-24.04-arm job 103577151020). PR run 34702702359 success (merge-ref 709bafd). Both matrices grepped: embed-off, A9 slot: + A1–A8 + stay, both cross-update … slot:ok (push this-os=7f52572), 83 tests, force-fail 1, qemu-smoke: ok. Later ledger-only SHA is not this probe. |
| Linux AArch64 vs ctos SVC gap documented (Track B B2) | Read linux-aarch64-syscall-gap.md, src/syscall.rs (SYS_* 16–23), and Linux v6.10 include/uapi/asm-generic/unistd.h | Verified | Document inspection. Representative table + convention gap. Not claiming Linux userspace. No Linux numbers in src/. B3–B6 stay Planned. File presence is not a Linux ABI. Kernel qemu-smoke not run (no src/ edit). |
| mdBook docs site builds locally (B2 / this branch) | ./scripts/docs-build.sh on cursor/b2-linux-syscall-gap-c35b | Verified | 2026-09-12 this cloud VM: mdbook v0.5.4; mdbook-mermaid 0.17.1; Linux auto-install x86_64-unknown-linux-gnu; docs-build: ok; book/CNAME is ctos.artof.link; generated gap page + track-b contain never-per-ADR-031 and not claiming Linux userspace. Generator only. Pages GHA on this PR is a separate row. Kernel qemu-smoke not run (no src/ edit). |
| CI on GitHub (B2 / this branch) | .github/workflows/smoke.yml on cursor/b2-linux-syscall-gap-c35b @ 60478ac | Verified | PR run 34701938481 success (ubuntu-24.04 job 103575136780 + ubuntu-24.04-arm job 103575136921). Both matrices grepped: hello slot: fat bytes=8624 / slot: mapped / slot: ok / svc: ok / libctos: ok / loader: ok / el0: task-ok / fs: ok / blk: ok / fat: ok; Running 82 tests; force-fail exit 1; qemu-smoke: ok. Push run 34701935451 success. Docs-only; not a new kernel mile. Later ledger SHAs on this branch are not this probe. |
| Pages workflow builds this PR (B2 syscall gap) | .github/workflows/pages.yml on cursor/b2-linux-syscall-gap-c35b @ 60478ac | Verified | PR run 34701938331 success (mdBook build job 103575136524). Deploy job skipped on pull_request (expected). Not a new live-site deploy. |
Linux ELF / auxv / PT_INTERP vs freestanding loader documented (ADR-033 / Track B B4) | Read ADR-033, src/loader.rs (PT_INTERP reject, ET_EXEC / PT_LOAD only), Linux v6.10 include/uapi/linux/elf.h + auxvec.h | Verified | Document inspection. Gap ADR. Track A loader stays reusable. Does not accept PT_INTERP. Not claiming dynamic Linux ELF. No src/ change. B3 / B5 / B6 stay Planned. File presence is not a Linux ELF ABI. Kernel qemu-smoke not run (no src/ edit). |
| mdBook docs site builds locally (B4 / this branch) | ./scripts/docs-build.sh on cursor/b4-elf-auxv-pt-interp-51bc | Verified | 2026-09-12 this cloud VM: mdbook v0.5.4; mdbook-mermaid 0.17.1; Linux auto-install x86_64-unknown-linux-gnu; docs-build: ok; book/CNAME is ctos.artof.link; generated ADR-033 + track-b contain stay-rejected and not claiming dynamic Linux ELF. Generator only. Pages GHA on this PR is a separate row. Kernel qemu-smoke not run (no src/ edit). |
| Process model vs standing EL0 documented (ADR-035 / Track B B3) | Read ADR-035 and track-b.md | Verified | Document inspection. Standing EL0 stays the ctos model. Linux clone/execve/wait4 is a gap. Not claiming Linux userspace. Do not add those syscalls to src/. B4 is Documented on main (774c672 / #68). B5 / B6 stay Planned. File presence is not a Linux process table. Kernel qemu-smoke not run (no src/ edit). |
| mdBook docs site builds locally (B3 / this branch) | ./scripts/docs-build.sh on cursor/b3-process-model-3443 | Verified | 2026-09-12 this cloud VM after rebase onto 774c672 (#68 / ADR-033 ELF): mdbook v0.5.4; mdbook-mermaid 0.17.1; Linux auto-install x86_64-unknown-linux-gnu; docs-build: ok; book/CNAME is ctos.artof.link; generated ADR-035 + track-b contain Standing EL0 stays the ctos model and not claiming Linux userspace; generated ADR-033 page contains stay-rejected and not claiming dynamic Linux ELF. No ADR-033-process-model or ADR-034-process-model page. Generator only. Pages GHA on this PR is a separate row. Kernel qemu-smoke not run (no src/ edit). |
| Linux VFS vs thin ctos VFS documented (ADR-034 / Track B B5) | Read ADR-034, src/vfs.rs (VfsOps + valid_path), src/fat.rs, and linux-aarch64-syscall-gap.md (openat / read / write / close) | Verified | Document inspection. Concept compare only. Not claiming a Linux filesystem. No POSIX flags / dentries in src/. B6 stays Planned. B3 is Documented (ADR-035). B4 is Documented (ADR-033). File presence is not Linux VFS. Kernel qemu-smoke not run (no src/ edit). |
| mdBook docs site builds locally (B5 / this branch) | ./scripts/docs-build.sh on cursor/b5-linux-vfs-vs-thin-ctos-f294 | Verified | 2026-09-12 this cloud VM: mdbook v0.5.4; mdbook-mermaid 0.17.1; Linux auto-install x86_64-unknown-linux-gnu; docs-build: ok; book/CNAME is ctos.artof.link; generated ADR-034 + track-b contain Not claiming a Linux filesystem and No Linux VFS object is present. Generator only. Pages GHA on this PR is a separate row. Kernel qemu-smoke not run (no src/ edit). |
CI on GitHub (B5 / prior SHA fc4bf89) | .github/workflows/smoke.yml on cursor/b5-linux-vfs-vs-thin-ctos-f294 @ fc4bf89 (then titled ADR-034) | Verified | MRC-grepped on #66: push 34713366059 (this-os=fc4bf89… slot:ok) + PR 34713368698 (merge-ref this-os=c0492c3… slot:ok). Both matrices: slot: fat / mapped / ok + stay + qemu-smoke: ok. Docs-only; not a new kernel mile. Later rename SHAs on this branch are not this probe. |
CI on GitHub (B5 / prior SHA ea2469e) | .github/workflows/smoke.yml on cursor/b5-linux-vfs-vs-thin-ctos-f294 @ ea2469e | Verified | Pre-rebase tip grepped: push 34713639443 (ubuntu-24.04 job 103606766099 + ubuntu-24.04-arm job 103606766239; this-os=ea2469e… slot:ok). PR 34713642019 success (merge-ref this-os=178d7fd… slot:ok). Both matrices: embed-off, slot: fat / mapped / ok, stay, prior-os=ba6541c… slot:ok, 83 tests, force-fail 1, qemu-smoke: ok. Docs-only; not a new kernel mile. Later rebase SHAs are not this probe. |
Pages workflow builds this PR (B5 VFS compare / ea2469e) | .github/workflows/pages.yml on cursor/b5-linux-vfs-vs-thin-ctos-f294 @ ea2469e | Verified | PR run 34713642021 success (mdBook build job 103606772101). Deploy job skipped on pull_request (expected). Not a new live-site deploy. Later rebase SHAs are not this probe. |
mdBook docs site builds locally (B5 / rebase onto 774c672) | ./scripts/docs-build.sh on cursor/b5-linux-vfs-vs-thin-ctos-f294 after rebase onto #68 | Verified | 2026-09-12 this cloud VM: mdbook v0.5.4; mdbook-mermaid 0.17.1; Linux auto-install x86_64-unknown-linux-gnu; docs-build: ok; book/CNAME is ctos.artof.link; generated ADR-033 ELF + ADR-034 VFS both present; track-b has B4 Documented and B5 Documented with Not claiming a Linux filesystem and No Linux VFS object is present. Generator only. Kernel qemu-smoke not run (no src/ edit). |
CI on GitHub (B5 / rebase tip 0cd62c2) | .github/workflows/smoke.yml on cursor/b5-linux-vfs-vs-thin-ctos-f294 @ 0cd62c2 (onto 774c672) | Verified | This session grepped: push 34714163309 (ubuntu-24.04 job 103608155056 + ubuntu-24.04-arm job 103608154963; this-os=0cd62c2… slot:ok). PR 34714165232 success (merge-ref this-os=20a544f6… slot:ok). Both matrices: embed-off, slot: fat / mapped / ok, stay, prior-os=ba6541c… slot:ok, 83 tests, force-fail 1, qemu-smoke: ok. Docs-only; not a new kernel mile. Later ledger SHAs are not this probe. |
Pages workflow builds this PR (B5 VFS compare / 0cd62c2) | .github/workflows/pages.yml on cursor/b5-linux-vfs-vs-thin-ctos-f294 @ 0cd62c2 | Verified | PR run 34714165116 success (mdBook build job 103608159994). Deploy job skipped on pull_request (expected). Not a new live-site deploy. |
mdBook docs site builds locally (B5 / rebase onto d81a53a) | ./scripts/docs-build.sh on cursor/b5-linux-vfs-vs-thin-ctos-f294 after rebase onto #67 | Verified | 2026-09-12 this cloud VM: mdbook v0.5.4; mdbook-mermaid 0.17.1; Linux auto-install x86_64-unknown-linux-gnu; docs-build: ok; book/CNAME is ctos.artof.link; generated ADR-033 ELF + ADR-034 VFS + ADR-035 process-model all present; track-b has B3/B4/B5 Documented with Not claiming a Linux filesystem. Generator only. This-tip GHA Unknown until grepped. Kernel qemu-smoke not run (no src/ edit). |
| qemu-smoke requires identity heap tear strings | scripts/qemu-smoke.sh hello phase greps ident: heap-reloc / ident: heap lo= / ident: heap-fault / ident: heap-high; rejects ident: heap-stay | Verified | 2026-09-12 agent-box: qemu-smoke: identity-tear strings present and heap-stay absent. |
scripts/qemu-smoke.sh (ADR-038 identity heap tear / this branch) | Ran on this agent box | Verified | 2026-09-12 ident-heap-tear after dde185f (QEMU 10.0.13, rustc 1.100.0-nightly 0fc141305): host perf: elf-size bytes=4432632; hello (timeout 124) with ident: heap-reloc n=0 / ident: heap lo=0x40258000 hi=0x40268000 pages=16 / ident: heap-fault / ident: heap-high plus A1–A9 + data tear markers; no ident: heap-stay; cargo test Running 86 tests all [ok]; force-fail exit 1; A9 cross-update prior-os=ba6541c… slot:ok + this-os=dde185f… slot:ok; qemu-smoke: ok. Not Docker. GHA on this PR is a separate row. |
| CI on GitHub (ADR-038 / this branch) | .github/workflows/smoke.yml on ident-heap-tear | Unknown | No green GHA URL on the cloud-probe commit yet. |
the arm64 workstation / amd64 workstation Docker smoke on dde185f (ADR-037 tip) | (amd64 workstation) 2026-09-13 amd64 Docker: ident: data-reloc n=241, ident: data … pages=87, ident: data-fault / ident: data-high, ident: heap-stay, slot: ok, A9 cross-update this-os=dde185f, qemu-smoke: ok | Verified | Host bash/WSL still missing — docker build/docker run directly. Heap stay is Historical after ADR-038. PAN enable / umbrella isolation still Planned. |
| Threat-model v1.19 slice (NFR-10) | Read security.md (EL0 trampoline without VMALLE1; PAN enable Planned) | Verified | File + this PR. v1.19 update, not “secure.” |
EL0 entry without TLBI VMALLE1 (ADR-039) | Hello-kernel serial el0: no-vmalle1; src/exception.rs has no tlbi vmalle1; #[test_case] el0_entry_without_vmalle1 | Verified | 2026-09-12 agent-box qemu-smoke (QEMU 10.0.13, rustc 1.100.0-nightly 0fc141305, -cpu cortex-a57) on isolation/adr-039-el0-tlbi-without-vmalle1 after f2c0c5a: hello el0: no kernel read / el0: standing / el0: restored / el0: no-vmalle1 / el0: ok / el0: task-ok / asid: ok; qemu-smoke: exception.rs has no tlbi vmalle1; Running 87 tests all [ok] incl. el0_entry_without_vmalle1; force-fail exit 1; A9 cross-update both slot:ok; qemu-smoke: ok. What TLBI remains: paging::init VMALLE1 at MMU enable + TLBI VAAE1 on unmaps. Not “EL0 isolated.” Not PAN. (amd64 workstation) intent; CloudAgent HELD — probe on agent box clone. |
qemu-smoke requires el0: no-vmalle1 + exception.rs ratchet | scripts/qemu-smoke.sh greps el0: no-vmalle1 and rejects tlbi vmalle1 in src/exception.rs | Verified | 2026-09-12 agent-box: qemu-smoke: exception.rs has no tlbi vmalle1 + EL0 first-mile + read-mile + standing + no-vmalle1 strings present. |
scripts/qemu-smoke.sh (ADR-039 EL0 no-VMALLE1 / this branch) | Ran on this agent box | Verified | 2026-09-12 after f2c0c5a (QEMU 10.0.13, rustc 1.100.0-nightly 0fc141305): host perf: elf-size bytes=4432656; hello (timeout 124) with el0: no-vmalle1 plus A1–A9 + identity data/heap tear markers; Running 87 tests all [ok]; force-fail exit 1; A9 cross-update prior-os=ba6541c… slot:ok + this-os=f2c0c5a… slot:ok; qemu-smoke: ok. Not Docker. GHA on this PR is a separate row. |
| CI on GitHub (ADR-039 / this branch) | .github/workflows/smoke.yml on this branch | Unknown | No green GHA URL yet. |
| Threat-model v1.20 slice (NFR-10) | Read security.md (lower-EL IRQ while standing; FIQ/SError still park; PAN enable Planned) | Verified | File + this PR. v1.20 update, not “secure.” |
| Lower-EL IRQ while standing (ADR-040) | Hello-kernel serial el0: irq; #[test_case] lower_el_irq_while_standing; vector irq_lower_el | Verified | 2026-09-13 agent-box qemu-smoke (QEMU 10.0.13, rustc 1.100.0-nightly 0fc141305, -cpu cortex-a57) on isolation/adr-040-lower-el-irq-standing after 28d3755: hello el0: standing / el0: restored / el0: standing / timer: tick / el0: irq / el0: restored / el0: no-vmalle1 / el0: ok; Running 88 tests all [ok] incl. lower_el_irq_while_standing; force-fail exit 1; A9 cross-update both slot:ok; qemu-smoke: ok. What still parks: lower-EL FIQ/SError. Default ERET I-clear is ADR-041. Not “EL0 isolated.” Not PAN. (amd64 workstation) intent; CloudAgent HELD — probe on agent box clone. |
qemu-smoke requires el0: irq | scripts/qemu-smoke.sh greps el0: irq | Verified | 2026-09-13 agent-box: qemu-smoke: EL0 first-mile + read-mile + standing + irq + no-vmalle1 strings present. |
scripts/qemu-smoke.sh (ADR-040 lower-EL IRQ / this branch) | Ran on this agent box | Verified | 2026-09-13 after 28d3755 (QEMU 10.0.13, rustc 1.100.0-nightly 0fc141305): host perf: elf-size bytes=4438008; hello (timeout 124) with el0: irq plus A1–A9 + identity data/heap tear + no-vmalle1 markers; Running 88 tests all [ok]; force-fail exit 1; A9 cross-update prior-os=ba6541c… slot:ok + this-os=28d3755… slot:ok (pre-commit tip); qemu-smoke: ok. Not Docker. GHA on this PR is a separate row. |
| CI on GitHub (ADR-040 / this branch) | .github/workflows/smoke.yml on this branch | Unknown | No green GHA URL yet. |
| Threat-model v1.21 slice (NFR-10) | Read security.md (IRQ-unmasked default ERET; FIQ/SError still park; PAN enable Planned) | Verified | File + this PR. v1.21 update, not “secure.” |
| IRQ-unmasked default standing/task ERET (ADR-041) | Hello-kernel serial el0: irq-default (+ el0: irq); #[test_case] lower_el_irq_default_eret; default eret_to_el0 SPSR 0x340 | Verified | 2026-09-13 agent-box qemu-smoke (QEMU 10.0.13, rustc 1.100.0-nightly 0fc141305, -cpu cortex-a57) on isolation/adr-041-irq-unmasked-standing after 473a73d: hello el0: standing / el0: restored / el0: standing / el0: irq / el0: restored / el0: irq-default / el0: no-vmalle1 / el0: ok; Running 89 tests all [ok] incl. lower_el_irq_default_eret + lower_el_irq_while_standing; force-fail exit 1; A9 cross-update both slot:ok; qemu-smoke: ok. Entry 0x40080000. Short non-standing probes use eret_to_el0_masked. What still parks: lower-EL FIQ/SError. Not “EL0 isolated.” Not PAN. (amd64 workstation) intent; CloudAgent HELD — probe on agent box clone. |
qemu-smoke requires el0: irq-default | scripts/qemu-smoke.sh greps el0: irq-default | Verified | 2026-09-13 agent-box: qemu-smoke: EL0 first-mile + read-mile + standing + irq + irq-default + no-vmalle1 strings present. |
scripts/qemu-smoke.sh (ADR-041 default IRQ-unmasked ERET / this branch) | Ran on this agent box | Verified | 2026-09-13 after 473a73d (QEMU 10.0.13, rustc 1.100.0-nightly 0fc141305): host perf: elf-size bytes=4438016; hello (timeout 124) with el0: irq-default plus A1–A9 + identity data/heap tear + no-vmalle1 markers; Running 89 tests all [ok]; force-fail exit 1; A9 cross-update prior-os=ba6541c… slot:ok + this-os=473a73d… slot:ok (pre-commit tip); qemu-smoke: ok. Not Docker. GHA on this PR is a separate row. |
| CI on GitHub (ADR-041 / this branch) | .github/workflows/smoke.yml on this branch | Unknown | No green GHA URL yet. |
| Threat-model v1.22 slice (NFR-10) | Read security.md (start-stay / ram-stay honesty; FIQ/SError still park; PAN enable Planned; umbrella Planned) | Verified | File + this PR. v1.22 update, not “secure.” |
Identity _start / leftover-RAM stay honesty (ADR-042) | Hello-kernel serial ident: start-stay + ident: ram-stay; #[test_case] identity_boot_stub_stays_while_live_torn | Verified | 2026-09-13 agent-box qemu-smoke (QEMU 10.0.13, rustc 1.100.0-nightly 0fc141305, -cpu cortex-a57) on isolation/adr-042-isolation-wrap after 75feef9: hello ident: start-stay lo=0x40080000 hi=0x40081000 / ident: ram-stay lo=0x40268000 hi=0x48000000 / ident: ok; Running 90 tests all [ok] incl. identity_boot_stub_stays_while_live_torn; force-fail exit 1; A9 cross-update both slot:ok; qemu-smoke: ok. Entry 0x40080000. Still Planned: PAN enable; lower-EL FIQ/SError; yank _start; umbrella “EL0 isolated.” Not “the kernel moved.” (amd64 workstation) intent; CloudAgent HELD — probe on agent box clone. |
| Threat-model v1.23 slice (NFR-10) | Read security.md (lower-EL FIQ while standing; SError park honesty; PAN enable Planned; umbrella Planned) | Verified | File + this PR. v1.23 update, not “secure.” |
| Lower-EL FIQ while standing + SError park (ADR-043) | Hello-kernel serial el0: fiq + el0: serror-park; #[test_case] lower_el_fiq_while_standing; vector fiq_lower_el | Verified | 2026-09-13 agent-box qemu-smoke (QEMU 10.0.13, rustc 1.100.0-nightly 0fc141305, -cpu cortex-a57) on isolation/adr-043-lower-el-fiq-serror after 472d78e: hello el0: standing / el0: irq / el0: fiq / el0: irq-default / el0: serror-park / el0: no-vmalle1 / el0: ok; Running 91 tests all [ok] incl. lower_el_fiq_while_standing; force-fail exit 1; A9 cross-update both slot:ok; qemu-smoke: ok. FIQ via temporary GICC FIQEn + SPSR 0x380. Taken SError still Planned (no safe inject). Entry 0x40080000. Not “EL0 isolated.” Not PAN. (amd64 workstation) intent; CloudAgent HELD — probe on agent box clone. |
| qemu-smoke requires ident: start-stay / ident: ram-stay | scripts/qemu-smoke.sh greps ident: start-stay and ident: ram-stay | Verified | 2026-09-13 agent-box: qemu-smoke: identity-tear strings present (includes start-stay / ram-stay). |
| scripts/qemu-smoke.sh (ADR-042 isolation leftover wrap / this branch) | Ran on this agent box | Verified | 2026-09-13 after 75feef9 (QEMU 10.0.13, rustc 1.100.0-nightly 0fc141305): host perf: elf-size bytes=4440560; hello (timeout 124) with ident: start-stay lo=0x40080000 hi=0x40081000 / ident: ram-stay plus ADR-037…041 markers; Running 90 tests all [ok]; force-fail exit 1; A9 cross-update prior-os=ba6541c… slot:ok + this-os=75feef9… slot:ok (pre-commit tip); qemu-smoke: ok. Not Docker. GHA on this PR is a separate row. |
| CI on GitHub (ADR-042 / this branch) | .github/workflows/smoke.yml on this branch | Unknown | No green GHA URL yet. |
How to update
- Run or cite the probe (command, file path + revision, or
gh runURL). - Change only the rows you probed.
- If you could not run QEMU, leave boot Unknown and say so in the PR. A prior Verified row is one environment and one boot path; do not copy the 2026-09-08 x86 VGA probe forward.
| Track B B6 decision documented (ADR-036 / never) | Read ADR-036 and track-b.md | Verified | Document inspection. Explicit never: no Linux-compat layer or reimplementation from B1–B5. Research ladder complete. Not claiming Linux userspace. Track A freestanding path stays. No src/ change. Kernel qemu-smoke not run. |
| mdBook docs site builds locally (B6 / Grok Bot docs path) | ./scripts/docs-build.sh when available on a host with mdBook; else Pages GHA on the PR | Unknown | Generator probe deferred to GHA/docs-build on this PR. File presence of ADR-036 is document inspection only. |
| the arm64 workstation / amd64 workstation Docker smoke on aeec16c (B6 tip) | (arm64 workstation) earlier on 00ebfc2: slot: ok + A9 cross-update; (amd64 workstation) 2026-09-13 amd64 Docker Desktop 29.7.2, 32 CPU / 31 GiB: docker build -t ctos-smoke . && docker run --rm ctos-smoke → slot: ok, cross-update prior ba6541c + this tip, qemu-smoke: ok | Verified | Host bash/WSL missing on the amd64 workstation — smoke via docker CLI directly (same as scripts/docker-smoke.sh). GHA also green on #69. |
| the amd64 workstation Docker smoke on f2c0c5a (ADR-038 tip) | (amd64 workstation) 2026-09-13 amd64 Docker: ident: heap-reloc n=0, ident: heap … pages=16, ident: heap-fault / ident: heap-high, ident: data-*, slot: ok, qemu-smoke: ok | Verified | Host bash/WSL still missing — docker CLI directly. PAN enable / umbrella isolation still Planned. |
| the amd64 workstation Docker smoke on 28d3755 (ADR-039 tip) | (amd64 workstation) 2026-09-13 amd64 Docker: el0: no-vmalle1, ident: heap-*, slot: ok, qemu-smoke: ok | Verified | Host bash/WSL missing — docker CLI. PAN enable / lower-EL IRQ while standing / umbrella still Planned. |
| the amd64 workstation Docker smoke on 473a73d (ADR-040 tip) | (amd64 workstation) 2026-09-13 amd64 Docker: el0: irq, el0: no-vmalle1, slot: ok, qemu-smoke: ok | Verified | Host bash/WSL missing — docker CLI. PAN / FIQ-SError / default IRQ-unmasked standing / umbrella still Planned. |
| the amd64 workstation Docker smoke on 75feef9 (ADR-041 tip) | (amd64 workstation) 2026-09-13 amd64 Docker: el0: irq / el0: irq-default, slot: ok, qemu-smoke: ok | Verified | Host bash/WSL missing — docker CLI. PAN / FIQ-SError / identity _start / umbrella still Planned. |
| the amd64 workstation Docker smoke on 472d78e (ADR-042 tip) | (amd64 workstation) 2026-09-13 amd64 Docker: ident: start-stay, ident: ram-stay, el0: irq-default, slot: ok, qemu-smoke: ok | Verified | Host bash/WSL missing — docker CLI. Isolation ladder wrap complete; PAN / FIQ-SError / full _start tear / umbrella stay Planned (ADR-042). |
| the amd64 workstation Docker smoke on 65cf515 (ADR-043 tip) | (amd64 workstation) 2026-09-13 amd64 Docker: el0: fiq, el0: serror-park, slot: ok, qemu-smoke: ok | Verified | Host bash/WSL missing — docker CLI. Taken SError / PAN enable / _start tear / umbrella still Planned. |
| Taken lower-EL SError research (ADR-044) | Read ADR-044; park marker still ADR-043 | Verified (research) | Docs-only. Candidate inject failed on QEMU 10 virt+a57 (ADR-045). Taken path = deferred/non-goal on this smoke machine (ADR-047) — do not copy Verified onto a taken serial. |
| the amd64 workstation Docker smoke on 3f7d3c5 (ADR-045 tip) | (amd64 workstation) 2026-09-13 amd64 Docker: el0: serror-arm, qmp inject-nmi => error:machine does not provide NMIs, el0: serror-park, qemu-smoke: ok | Verified | Taken el0: serror not printed — inject blocked on this QEMU virt. Taken SError / PAN / _start tear / umbrella still Planned. |
| the amd64 workstation Docker smoke on 608f643 (ADR-046 tip) | (amd64 workstation) 2026-09-13 amd64 Docker: perf: app-load, perf: embed-load, perf: slot-delta app=… embed=…, slot: ok, qemu-smoke: ok | Verified | Measurement pair only (QEMU TCG lab). No percent / faster-slower claim. Isolation leftovers decided in ADR-047 (this PR). |
| Taken lower-EL SError on stock smoke QEMU (ADR-047 / ADR-053 / ADR-081) | Stock distro QEMU: deferred/non-goal; park + A-clear prep | Deferred / non-goal (stock) | Stock path unchanged. Pin Verified: ADR-083; the CI job qemu-nmi-pin has been unconditional since ADR-090 (2026-09-26, D1 evidence class with B2-P). B2-P (real arm64 + KVM) Verified opt-in, one-off: ADR-085. Keep el0: serror-park on distro QEMU. Do not require taken without CTOS_REQUIRE_TAKEN_SERROR=1. B2 (different runner/accelerator) blocked on free hosted runners: ADR-084 (2026-09-25). |
| PAN enable on default cortex-a57 (ADR-047 / ADR-054) | Decision: enable non-goal locked; ID-field stays Verified | Non-goal (default probe CPU) — locked | ADR-054 / ADR-047 / ADR-026. Explicit reopen gate in ADR-054. Do not silent -cpu switch. |
| Never yank _start (ADR-047) | Decision while QEMU -kernel needs 0x4008_0000; ident: start-stay | Decided (honesty Verified) | ADR-047 / ADR-042. Leftover RAM after heap Verified optional (ADR-049). |
| App hosting claim criteria documented (ADR-048) | Read ADR-048; product row still Planned | Verified (docs) | Checklist only. Do not claim “app hosting is done.” |
| Threat-model v1.26 slice (NFR-10) | Read security.md (ADR-047 leftover decisions + ADR-048 claim gate) | Verified | File + this PR. v1.26 update, not “secure.” Not “EL0 isolated.” |
| Leftover identity RAM tear (ADR-049) | Hello-kernel serial ident: ram lo= + ident: ram-fault + ident: ram-high; reject ident: ram-stay; ident: start-stay still required; #[test_case] identity_ram_torn_high_stays / identity_ram_unmapped_high_stays | Verified | 2026-09-13 agent-box smoke on this branch (see smoke row). High twin stays. Never yank _start. Not “EL0 isolated.” Not “kernel moved.” ADR-049. |
| Threat-model v1.27 slice (NFR-10) | Read security.md (ADR-049 leftover identity RAM tear) | Verified | File + this PR. v1.27 update, not “secure.” Not “EL0 isolated.” |
| scripts/qemu-smoke.sh (ADR-049 leftover identity RAM tear / this branch) | Ran on this agent box | Verified | 2026-09-13 agent-box qemu-smoke (QEMU 10.0.13, rustc 1.100.0-nightly 0fc141305, -cpu cortex-a57) on feat/ident-ram-unmap: hello ident: ram lo=0x40268000 hi=0x48000000 pages=32152 / ident: ram-fault / ident: ram-high / ident: start-stay lo=0x40080000 hi=0x40081000 / ident: ok (no ident: ram-stay); Running 94 tests all [ok] incl. identity_ram_torn_high_stays / identity_ram_unmapped_high_stays / identity_boot_stub_stays_while_live_torn; force-fail exit 1; A9 cross-update both slot:ok; qemu-smoke: ok. Not Docker. Not “EL0 isolated.” Not “kernel moved.” (amd64 workstation) not re-run — CloudAgent HELD; evidence tagged agent-box. |
| ADR-048 progress checklist + stale embed/cross-update doc honesty (Future slice 1) | Read progress tables in this ledger + hosting-apps.md; stale “A2–A4 still embed” / “Cross-update stays Planned” / Planned delta wording aligned with Verified ADR-032/046 rows; product row still Planned | Verified (docs) | Tip b47bbfc audit on this PR. Docs-only; no src/ change; kernel smoke not re-run. Do not claim “app hosting is done.” |
| (amd64 workstation) Alpine WSL bash + Docker Desktop PATH hygiene | Documented host notes for later smoke (docs-only OK) | Verified (docs) | Alpine WSL2 default; install bash: wsl -d Alpine -u root -- apk add bash. Use wsl -d Alpine -u <user> -- bash (not WindowsApps bash stub). Docker Desktop WSL integration not enabled for Alpine — call docker.exe via PATH /mnt/c/Users/<user>/AppData/Local/Programs/DockerDesktop/resources/bin or cmd docker build/run. scripts/docker-smoke.sh is already #!/bin/sh. (amd64 workstation) intent for any later smoke; CloudAgent HELD — this PR is docs-only. |
| FAT16 write behind thin VFS (ADR-050 / Future slice 3) | Hello-kernel serial fat: write + fat: rewrite + fat: create + keep fat: ok; host mkfat16.py --check-write; #[test_case] fat16_vfs_write_and_restore + fat16_create_write_small_file | Verified | 2026-09-13 agent-box smoke on feat/fat16-write @ e539813 (see smoke row). Guest wrote FAT16 bytes through thin VFS; created /fwr=fat-nw; restored /probe=fat-hi. Not POSIX. Not FAT32. Not “supports FAT.” App hosting stays Planned. ADR-050. |
| Threat-model v1.28 slice (NFR-10) | Read security.md (ADR-050 FAT16 write) | Verified | File + this PR. v1.28 update, not “secure.” |
| scripts/qemu-smoke.sh (ADR-050 FAT16 write / this branch) | Ran on this agent box | Verified | 2026-09-13 agent-box qemu-smoke (QEMU 10.0.13, rustc 1.100.0-nightly 0fc141305, -cpu cortex-a57) on feat/fat16-write @ e539813: hello fat: mount / fat: read / fat: write / fat: rewrite / fat: create / fat: ok; host mkfat16: check-write ok file=/fwr bytes=fat-nw; slot: ok; A9 cross-update both slot:ok; Running 96 tests all [ok] incl. fat16_vfs_write_and_restore + fat16_create_write_small_file; force-fail exit 1; qemu-smoke: ok. Not Docker. Not POSIX. Not FAT32. (amd64 workstation) not re-run — CloudAgent HELD; evidence tagged agent-box. Tip e539813. |
| FAT16 vs memfs write CNTPCT pair (ADR-051 / Future slice 4 / P-PERF-6) | Hello serial perf: fat-write ticks=<n> + perf: memfs-write ticks=<n> + perf: fs-write-delta fat=<a> memfs=<b>; #[test_case] fat_memfs_write_cntpct_pair samples > 0; smoke rejects percent marketing | Verified | 2026-09-13 agent-box qemu-smoke (QEMU 10.0.13, rustc 1.100.0-nightly 0fc141305, -cpu cortex-a57) on feat/fat-write-cntpct @ 45dc9e1: hello fat: write / fat: rewrite / fat: create / perf: fat-write ticks=66638 / perf: memfs-write ticks=5303 / perf: fs-write-delta fat=66638 memfs=5303 / fat: ok / slot: ok; Running 97 tests all [ok] incl. fat_memfs_write_cntpct_pair; force-fail exit 1; qemu-smoke: ok. QEMU TCG lab — not a published bench, not a percent. Keep ADR-050 write mile. App hosting stays Planned. (amd64 workstation) intent; CloudAgent HELD — probe on agent box clone. ADR-051. |
| scripts/qemu-smoke.sh (ADR-051 FAT-vs-memfs write CNTPCT / this branch) | Ran on this agent box | Verified | 2026-09-13 agent-box qemu-smoke (QEMU 10.0.13, rustc 1.100.0-nightly 0fc141305, -cpu cortex-a57) on feat/fat-write-cntpct: markers above; host --check-write still ok; A9 cross-update both slot:ok; Running 97 tests all [ok]; force-fail exit 1; qemu-smoke: ok. Not Docker. Not a latency SLA. Tip 45dc9e1. |
| Companion / overview polish (Future slice 6) | Read overview + linked framework pages: no live “A2–A4 still embed,” “cross-update Planned,” ram-stay as the story, “FAT read-only” as the only FAT story; ADR-048 checklist pointer present; ADR-047…051 reflected; product hosting row still Planned | Verified (docs) | Tip ebc968e (includes ADR-051). Docs-only; ./scripts/docs-build.sh ok; no src/ change; kernel smoke not re-run. Do not claim “app hosting is done,” “EL0 isolated,” PAN enable, or taken SError Verified. |
| Sponsor accept product app hosting (ADR-048 #5 / ADR-052) | Sponsor signal + this flip PR; criteria 1–4 already Met on tip be789c5+; no self-merge | Verified (docs) | 2026-09-13: sponsor said “address 1. app hosting” after a still-Planned review that listed product app hosting as blocked only on criterion #5. ADR-052. Product row flipped Planned → Verified. Docs-only; ./scripts/docs-build.sh ok; no src/ change; kernel smoke not re-run (criteria 1–4 already Met). Not Linux userspace, POSIX, containers, “EL0 isolated,” PAN enable, taken SError Verified, immutable OS, or OTA. |
| Threat-model v1.29 slice (NFR-10) | Read security.md (ADR-048/052 product app-hosting claim Verified; non-claims unchanged) | Verified | File + this PR. v1.29 update, not “secure.” Not “EL0 isolated.” Not Linux/POSIX/containers. |
| Taken lower-EL SError hard-stop (ADR-053) | Dated QMP re-probe: inject-nmi / HMP nmi → machine does not provide NMIs; park stays Verified; taken locked deferred/non-goal | Deferred / non-goal (locked) | 2026-09-14 agent-box QEMU 10.0.13 -machine virt -cpu cortex-a57: QMP inject-nmi error machine does not provide NMIs; HMP nmi same. Prior smoke: amd64 workstation 3f7d3c5 / ADR-045. Reopen attempt ADR-081. Do not claim taken Verified. ADR-053. |
| PAN enable lock (ADR-054) | Enable non-goal locked on default cortex-a57; reopen gate documented; ID-field stays Verified | Non-goal (locked) | Docs-only 2026-09-14. Evidence: ADR-026 pan: absent; scripts keep -cpu cortex-a57. Reopen = sponsor-approved CPU + FEAT_PAN + enable+fault ADR. Do not claim PAN enabled. ADR-054. |
| Umbrella “EL0 isolated” checklist (ADR-055; audited 2026-09-26 in ADR-086) | Evidence table: Verified miles vs unmet (PAN enable, taken SError, yank _start, sponsor umbrella accept) | Verified (§B rows 1–3 Met; umbrella = the ADR-091 sentence only) | M6 (2026-09-28): row 3 Met (sponsor’s written accept, B3); see the P-SEC-3 row. Docs-only 2026-09-14: “Cannot become Verified under current constraints” (as of then). Do not round Verified miles into “EL0 isolated.” ADR-055. Sponsor one-pager ADR-060. |
| Threat-model v1.30 slice (NFR-10) | Read security.md (ADR-053/054/055 isolation-gap locks; non-claims unchanged) | Verified | File + this PR. v1.30 update, not “secure.” Not “EL0 isolated.” Not PAN enabled. Not taken SError Verified. |
| FAT16 readdir behind thin VFS (ADR-056) | Hello-kernel serial fat: readdir + fat: entries n=<k> + keep fat: ok / write / slot: ok; #[test_case] fat16_readdir_lists_root + fat16_readdir_fail_closed_cap | Verified | 2026-09-14 agent-box smoke on feat/fat16-readdir: hello fat: readdir / fat: entries n=3 / fat: ok; Running 99 tests all [ok] incl. readdir cases; force-fail exit 1; qemu-smoke: ok. Guest listed FAT16 root paths through thin VFS (/probe, /hello, /fwr). Not POSIX getdents/opendir. Not FAT32. Not “supports FAT.” Not EL0 isolated / PAN / taken SError. CloudAgent HELD — evidence tagged agent-box. Tip abe72cf. ADR-056. |
| Threat-model v1.31 slice (NFR-10) | Read security.md (ADR-056 FAT16 readdir) | Verified | File + this PR. v1.31 update, not “secure.” Not POSIX getdents. |
| scripts/qemu-smoke.sh (ADR-056 FAT16 readdir / this branch) | Ran on this agent box | Verified | 2026-09-14 agent-box qemu-smoke (QEMU 10.0.13, -cpu cortex-a57) on feat/fat16-readdir: markers fat: mount / fat: read / fat: write / fat: rewrite / fat: create / fat: readdir / fat: entries n=3 / fat: ok / slot: ok; host --check-write ok; A9 cross-update both slot:ok; Running 99 tests all [ok]; force-fail exit 1; qemu-smoke: ok. Not Docker. Not POSIX. Tip abe72cf. |
| FAT16 delete behind thin VFS (ADR-057) | Hello-kernel serial fat: delete + keep fat: ok / write / readdir / slot: ok; #[test_case] fat16_unlink_removes_file + fat16_unlink_missing_is_err | Verified | 2026-09-14 agent-box smoke on feat/fat16-delete: hello fat: delete / fat: readdir / fat: entries n=3 / fat: ok; Running 101 tests all [ok] incl. unlink cases; force-fail exit 1; qemu-smoke: ok. Guest deleted FAT16 root dirent /fdel through thin VFS (vfs::unlink). Not POSIX unlink/remove. Not FAT32. Not “supports FAT.” Not EL0 isolated / PAN / taken SError. CloudAgent HELD — evidence tagged agent-box. Tip c945ec8. ADR-057. |
| Threat-model v1.32 slice (NFR-10) | Read security.md (ADR-057 FAT16 delete) | Verified | File + this PR. v1.32 update, not “secure.” Not POSIX unlink. |
| scripts/qemu-smoke.sh (ADR-057 FAT16 delete / this branch) | Ran on this agent box | Verified | 2026-09-14 agent-box qemu-smoke (QEMU 10.0.13, rustc 1.100.0-nightly 0fc141305, -cpu cortex-a57) on feat/fat16-delete: markers fat: mount / fat: read / fat: write / fat: rewrite / fat: create / fat: readdir / fat: entries n=3 / fat: delete / fat: ok / slot: ok; host --check-write ok; A9 cross-update both slot:ok; Running 101 tests all [ok]; force-fail exit 1; qemu-smoke: ok. Not Docker. Not POSIX. Tip c945ec8. |
| Thin VFS prefix mounts (ADR-058) | Hello-kernel serial vfs: mount + vfs: mounts + keep fs: ok / fat: ok / slot: ok; #[test_case] vfs_prefix_mounts_route_backends + vfs_memfs_mount_create_stays_off_fat | Verified | 2026-09-14 agent-box smoke on feat/vfs-virtual-mounts @ 4814735: hello vfs: mount /kprobe -> memfs … vfs: mount / -> fat / vfs: mounts / fs: ok / fat: ok / slot: ok; Running 103 tests all [ok] incl. mount cases; force-fail exit 1; qemu-smoke: ok. Guest routed path prefixes through a thin VFS mount table (/mem+A6 names → memfs; / → FAT16). Not POSIX mount(2). Not Linux VFS. Not a new disk FS. Not EL0 isolated / PAN / taken SError. CloudAgent HELD — evidence tagged agent-box. ADR-058. |
| scripts/qemu-smoke.sh (ADR-058 VFS prefix mounts / this branch) | Ran on this agent box | Verified | 2026-09-14 agent-box qemu-smoke (QEMU 10.x, -cpu cortex-a57) on feat/vfs-virtual-mounts @ 4814735: markers vfs: mount / vfs: mounts / fs: ok / fat: mount / fat: read / fat: write / fat: rewrite / fat: create / fat: readdir / fat: entries n=3 / fat: delete / fat: ok / slot: ok; host --check-write ok; A9 cross-update both slot:ok; Running 103 tests all [ok]; force-fail exit 1; qemu-smoke: ok. Not Docker. Not POSIX. Tip 4814735. |
| Freestanding fs-libctos sample + catalog (ADR-059) | Hello-kernel serial libctos: fs-hi + libctos: fs-ok + fsdemo: ok + keep slot: ok / /hello; #[test_case] fsdemo_fat_is_elf + fsdemo_load_from_fat_erets + fsdemo_path_is_memdemo_mount | Verified | 2026-09-14 agent-box smoke on feat/fs-libctos-sample: hello libctos: fs-hi / libctos: fs-ok / fsdemo: fat / fsdemo: mapped / fsdemo: ok / slot: ok; Running 106 tests all [ok] incl. fsdemo cases; force-fail exit 1; qemu-smoke: ok. Guest loaded FAT /fsdemo and the payload exercised libctos VFS on /memdemo (memfs via ADR-058 /mem prefix; EL0 exec pages fetch-only — compare with immediates). Not POSIX. Not getdents. Not EL0 isolated / PAN / taken SError. Do not reopen ADR-048/052 app hosting. CloudAgent HELD — evidence tagged agent-box (amd64 workstation Computer tool unavailable this turn). ADR-059. |
| Threat-model v1.34 slice (NFR-10) | Read security.md (ADR-059 fs-libctos catalog) | Verified | File + this PR. v1.34 update, not “secure.” Not POSIX. |
| scripts/qemu-smoke.sh (ADR-059 fs-libctos / this branch) | Ran on this agent box | Verified | 2026-09-14 agent-box qemu-smoke (QEMU 10.0.13, rustc 1.100.0-nightly 0fc141305, -cpu cortex-a57) on feat/fs-libctos-sample: markers libctos: fs-hi / libctos: fs-ok / fsdemo: ok + preserved vfs: mounts / fs: ok / fat: ok / slot: ok / A9 cross-update both slot:ok; Running 106 tests all [ok]; force-fail exit 1; qemu-smoke: ok. Not Docker. Not POSIX. Tip ca707e7. |
| Sponsor isolation leftovers closure checklist (ADR-060) | Single table: taken SError / PAN enable / umbrella / never-yank _start — locks + reopen gates only | Docs lock (non-Verified) | Docs-only 2026-09-15. Cites ADR-047 / ADR-053 / ADR-054 / ADR-055 / #98. Does not invent Verified for taken SError / PAN enable / “EL0 isolated.” M6 (2026-09-28): its umbrella row now reads Verified, only as the accepted ADR-091 sentence; the other locks are unchanged. Does not silent -cpu, yank _start, or reopen Guest Linux/containers/immutable marketing. ADR-060. |
| Threat-model v1.35 slice (NFR-10) | Read security.md (ADR-060 sponsor leftovers closure; non-claims unchanged) | Verified | File + this PR. v1.35 update, not “secure.” Not “EL0 isolated.” Not PAN enabled. Not taken SError Verified. |
| Freestanding fat-libctos sample + catalog (ADR-061) | Hello-kernel serial libctos: fat-hi + libctos: fat-ok + fatdemo: ok + keep slot: ok / fsdemo: ok / /hello / /fsdemo; #[test_case] fatdemo_fat_is_elf + fatdemo_load_from_fat_erets + fatdemo_path_is_fat_probe | Verified | 2026-09-15 agent-box smoke on feat/fat-libctos-sample: hello libctos: fat-hi / libctos: fat-ok / fatdemo: fat / fatdemo: mapped / fatdemo: ok / slot: ok / fsdemo: ok; Running 109 tests all [ok] incl. fatdemo cases; force-fail exit 1; qemu-smoke: ok. Guest loaded FAT /fatdemo and the payload opened/read FAT /probe (fat-hi) via thin VFS (EL0 exec pages fetch-only — compare with immediates). Not POSIX. Not getdents. Not EL0 isolated / PAN / taken SError. Do not reopen ADR-048/052 app hosting. CloudAgent HELD — evidence tagged agent-box (amd64 workstation Computer/CloudAgent unavailable this turn). Tip 8bf25d2. ADR-061. |
| Threat-model v1.36 slice (NFR-10) | Read security.md (ADR-061 fat-libctos catalog) | Verified | File + this PR. v1.36 update, not “secure.” Not POSIX. |
| Freestanding yield-libctos sample + catalog (ADR-062) | Hello-kernel serial libctos: yld-hi + ≥3× libctos: beat + libctos: yld-ok + yldemo: ok + keep slot: ok / fsdemo: ok / fatdemo: ok / /hello / /fsdemo / /fatdemo; #[test_case] yldemo_fat_is_elf + yldemo_load_from_fat_erets + yldemo_path_is_fat | Verified | 2026-09-16 agent-box smoke on feat/yield-libctos-el0-sample: hello libctos: yld-hi / 3× libctos: beat / libctos: yld-ok / yldemo: fat / yldemo: mapped / yldemo: ok / slot: ok / fsdemo: ok / fatdemo: ok; Running 112 tests all [ok] incl. yldemo cases; force-fail exit 1; qemu-smoke: ok (QEMU 10.0.13, rustc 1.100.0-nightly 0fc141305). Guest loaded FAT /yldemo and the payload issued several cooperative yield_now() rounds (deeper than hello’s single yield). Not preemption. Not multi-task EL0. Not a process table. Not POSIX. Not EL0 isolated / PAN / taken SError. Do not reopen ADR-048/052 app hosting. CloudAgent HELD — evidence tagged agent-box. Tip 7a5a529. ADR-062. |
| Threat-model v1.37 slice (NFR-10) | Read security.md (ADR-062 yield-libctos catalog) | Verified | File + this PR. v1.37 update, not “secure.” Not preemption. |
| scripts/qemu-smoke.sh (ADR-061 fat-libctos / this branch) | Ran on this agent box | Verified | 2026-09-15 agent-box qemu-smoke (QEMU 10.0.13, rustc 1.100.0-nightly 0fc141305, -cpu cortex-a57) on feat/fat-libctos-sample: markers libctos: fat-hi / libctos: fat-ok / fatdemo: ok + preserved libctos: fs-ok / fsdemo: ok / vfs: mounts / fs: ok / fat: ok / slot: ok / A9 cross-update both slot:ok; Running 109 tests all [ok]; force-fail exit 1; qemu-smoke: ok. Not Docker. Not POSIX. Tip 8bf25d2. |
| Track N network foundation scope (ADR-063 / N0) | Read ADR-063 + track-n.md; SUMMARY / roadmap / limits wired; no virtio-net driver in this PR | Docs lock (non-Verified) | Docs-only 2026-09-16. Opens Track N. Runtime link/first-frame stays Planned. Do not invent Verified. Do not claim TCP/UDP/sockets/DHCP/DNS/Wi‑Fi/Linux net/“has networking.” ADR-063. |
| Track N virtio-net first frame (N1 / ADR-066) | Hello-kernel serial net: virtio + net: mac + net: tx + net: rx + net: ok; QEMU -netdev user,id=net0 -device virtio-net-device,netdev=net0; keep blk: ok / fat: ok; #[test_case] virtio_net_discover_and_arp | Verified | 2026-09-16 agent-box qemu-smoke (QEMU 10.0.13, rustc 1.100.0-nightly 0fc141305, -cpu cortex-a57) on feat/n1-virtio-net-first-frame: hello net: virtio / net: mac 52:54:00:12:34:56 / net: tx / net: rx / net: ok + optional perf: net-tx / perf: net-rx + keep blk: ok / fat: ok / slot: ok; Running 116 tests all [ok] incl. virtio_net_discover_and_arp; force-fail exit 1; qemu-smoke: ok. Probe = ARP request for SLIRP gateway 10.0.2.2 + reply. Not TCP/UDP/sockets/DHCP/DNS/Wi‑Fi/“has networking.” CloudAgent HELD — evidence tagged agent-box. ADR-066. |
| Threat-model v1.38 slice (NFR-10) | Read security.md (ADR-063 Track N Planned; I/O surface) | Verified | File + #109. v1.38 update, not “secure.” Not “has networking.” |
| FAT16 multi-cluster grow (ADR-064) | Hello-kernel serial fat: grow + libctos: fat-grow + keep fat: ok / fat: write / fatdemo: ok; #[test_case] fat16_multi_cluster_grow + fat16_grow_refuses_over_file_max | Verified | 2026-09-16 agent-box smoke on feat/fat-multi-cluster-grow (rebased on main post-#109): hello fat: grow / libctos: fat-grow / libctos: fat-ok / fatdemo: ok / fat: ok; Running 114 tests all [ok] incl. grow cases; force-fail exit 1; qemu-smoke: ok (QEMU 10.x, rustc 1.100.0-nightly 0fc141305, -cpu cortex-a57). Guest allocated a FAT chain and wrote 600 bytes across a 512-byte cluster boundary; EL0 chunked SVC write/read-back. FILE_MAX raised to 1024. Not POSIX write API. Not exFAT/FAT32. Not Track N. CloudAgent HELD — evidence tagged agent-box. Tip cb3a946. ADR-064. |
| Threat-model v1.39 slice (NFR-10) | Read security.md (ADR-064 FAT16 multi-cluster grow; keeps ADR-063 Track N Planned) | Verified | File + this PR. v1.39 update on tip post-#109 v1.38, not “secure.” Not POSIX. Not “has networking.” |
| scripts/qemu-smoke.sh (ADR-064 multi-cluster grow / this branch) | Ran on this agent box | Verified | 2026-09-16 agent-box qemu-smoke on feat/fat-multi-cluster-grow (rebased on b4efb5f): markers fat: grow / libctos: fat-grow + preserved fat: write / fat: delete / fat: ok / fatdemo: ok / slot: ok; Running 114 tests all [ok]; force-fail exit 1; qemu-smoke: ok. Not Docker. Not POSIX. Tip cb3a946. |
| FAT16 vs memfs read CNTPCT pair (ADR-065 / perf slice 3 / P-PERF-7) | Hello serial perf: fat-read ticks=<n> + perf: memfs-read ticks=<n> + perf: fs-read-delta fat=<a> memfs=<b>; #[test_case] fat_memfs_read_cntpct_pair samples > 0; smoke rejects percent marketing; /mrprobe memfs mount prefix | Verified | 2026-09-16 agent-box qemu-smoke (QEMU 10.0.13, rustc 1.100.0-nightly 0fc141305, -cpu cortex-a57) on feat/fat-memfs-read-cntpct @ 0abba31: hello perf: fat-read ticks=7752 / perf: memfs-read ticks=2210 / perf: fs-read-delta fat=7752 memfs=2210 + keep perf: fat-write / perf: fs-write-delta / fat: ok / slot: ok; Running 115 tests all [ok] incl. fat_memfs_read_cntpct_pair; force-fail exit 1; qemu-smoke: ok. QEMU TCG lab — not a published bench, not a percent. Keep ADR-051 write pair. App hosting stays Planned. CloudAgent HELD — probe on agent box. ADR-065. |
| Threat-model v1.40 slice (NFR-10) | Read security.md (ADR-065 FAT vs memfs read CNTPCT; keeps ADR-063 Track N Planned) | Verified | File + this PR. v1.40 update on tip post-#110 v1.39, not “secure.” Not a latency SLA. Not “has networking.” |
| scripts/qemu-smoke.sh (ADR-065 FAT-vs-memfs read CNTPCT / this branch) | Ran on this agent box | Verified | 2026-09-16 agent-box qemu-smoke on feat/fat-memfs-read-cntpct: markers above; ADR-051 write pair still present; Running 115 tests all [ok]; force-fail exit 1; qemu-smoke: ok. Not Docker. Not a latency SLA. Tip 0abba31. |
| Threat-model v1.41 slice (NFR-10) | Read security.md (ADR-066 N1 virtio-net first frame; I/O surface names blk+net) | Verified | File + this PR. v1.41 update on tip post-#111 v1.40, not “secure.” Not TCP/UDP. Not “has networking.” |
| scripts/qemu-smoke.sh (ADR-066 N1 virtio-net / this branch) | Ran on this agent box | Verified | 2026-09-16 agent-box qemu-smoke on feat/n1-virtio-net-first-frame: markers net: virtio / net: mac / net: tx / net: rx / net: ok + preserved blk: ok / fat: ok / slot: ok / ADR-065 read pair; qemu-smoke: virtio-net (N1) strings present; Running 116 tests all [ok]; force-fail exit 1; qemu-smoke: ok. Not Docker. Not a product stack. Tip b87ddba. |
| Track N virtio-net ICMP ping (N2 / ADR-067) | Hello-kernel serial net: icmp-tx + net: icmp-rx + net: ping-ok (+ keep N1 net: ok); QEMU -netdev user,id=net0 -device virtio-net-device,netdev=net0 unchanged; keep blk: ok / fat: ok; #[test_case] virtio_net_icmp_echo_ping | Verified | 2026-09-16 agent-box qemu-smoke (QEMU 10.0.13, rustc 1.100.0-nightly 0fc141305, -cpu cortex-a57) on feat/n2-icmp-ping: hello net: virtio / net: mac 52:54:00:12:34:56 / net: tx / net: rx / net: ok / net: icmp-tx / net: icmp-rx / net: ping-ok + optional perf: net-icmp-tx / perf: net-icmp-rx + keep blk: ok / fat: ok / slot: ok; Running 117 tests all [ok] incl. virtio_net_discover_and_arp + virtio_net_icmp_echo_ping; force-fail exit 1; qemu-smoke: ok. Probe = ICMP echo vs SLIRP gateway 10.0.2.2 after ARP. Not TCP/UDP/sockets/DHCP/DNS/Wi‑Fi/“has networking.” CloudAgent HELD — evidence tagged agent-box. ADR-067. |
| Threat-model v1.42 slice (NFR-10) | Read security.md (ADR-067 N2 ICMP ping; I/O surface still blk+net) | Verified | File + this PR. v1.42 update on tip post-#112 v1.41, not “secure.” Not TCP/UDP. Not “has networking.” |
| scripts/qemu-smoke.sh (ADR-067 N2 ICMP ping / this branch) | Ran on this agent box | Verified | 2026-09-16 agent-box qemu-smoke on feat/n2-icmp-ping: markers net: icmp-tx / net: icmp-rx / net: ping-ok + N1 net: ok + preserved blk: ok / fat: ok / slot: ok / ADR-065 read pair; qemu-smoke: virtio-net (N1+N2) strings present; Running 117 tests all [ok]; force-fail exit 1; qemu-smoke: ok. Not Docker. Not a product stack. Tip b71d7f4. |
| Track N EL0 net SVC + net-libctos (N4 / ADR-068) | Hello-kernel serial libctos: net-hi + libctos: net-mac + libctos: net-ok + netdemo: ok (+ keep N1 net: ok / N2 net: ping-ok / prior samples); #[test_case] netdemo_fat_is_elf + netdemo_load_from_fat_erets + netdemo_path_is_fat | Verified | 2026-09-16 agent-box qemu-smoke (QEMU 10.0.13, rustc 1.100.0-nightly 0fc141305, -cpu cortex-a57) on feat/n4-el0-net-svc: hello libctos: net-hi / libctos: net-mac / libctos: net-ok / netdemo: fat / netdemo: mapped / netdemo: ok + keep net: ok / net: ping-ok / blk: ok / fat: ok / slot: ok / yldemo: ok; Running 120 tests all [ok] incl. netdemo cases; force-fail exit 1; qemu-smoke: ok. SVC surface: net_mac=24, net_ping=25. Kernel owns virtio-net. Not TCP/UDP/sockets/DHCP/DNS/Wi‑Fi/“has networking.” CloudAgent HELD — evidence tagged agent-box. Tip f1942ab. ADR-068. |
| Threat-model v1.43 slice (NFR-10) | Read security.md (ADR-068 N4 EL0 net SVC sample; I/O surface still blk+net) | Verified | File + this PR. v1.43 update on tip post-#113 v1.42, not “secure.” Not TCP/UDP. Not “has networking.” |
| scripts/qemu-smoke.sh (ADR-068 N4 net-libctos / this branch) | Ran on this agent box | Verified | 2026-09-16 agent-box qemu-smoke on feat/n4-el0-net-svc: markers libctos: net-ok / netdemo: ok + preserved N1/N2/samples; qemu-smoke: ADR-068 net-libctos /netdemo strings present; Running 120 tests all [ok]; force-fail exit 1; qemu-smoke: ok. Not Docker. Not a product stack. Tip f1942ab. |
| Net-ping path CNTPCT (ADR-069 / P-PERF-8) | Hello serial perf: net-ping ticks=<n> (prefix grep; not exact ticks); #[test_case] el0_net_ping_cntpct_advances sample > 0; smoke rejects percent marketing; keep N1/N2/N4 | Verified | 2026-09-16 agent-box qemu-smoke (QEMU 10.0.13, rustc 1.100.0-nightly 0fc141305, -cpu cortex-a57) on feat/net-ping-cntpct: hello perf: net-ping ticks=20370 + keep net: ping-ok / libctos: net-ok / netdemo: ok / blk: ok / fat: ok / slot: ok; Running 121 tests all [ok] incl. el0_net_ping_cntpct_advances (perf: net-ping ticks=13052 in that case); force-fail exit 1; qemu-smoke: ok. QEMU TCG lab — not a published bench, not a percent, not a ping SLA. Window = quiet ARP+ICMP as SYS_NET_PING / el0_icmp_ping. CloudAgent HELD — evidence tagged agent-box. ADR-069. |
| Threat-model v1.44 slice (NFR-10) | Read security.md (ADR-069 net-ping CNTPCT; keeps N1/N2/N4) | Verified | File + this PR. v1.44 update on tip post-#114 v1.43, not “secure.” Not a latency SLA. Not “has networking.” |
| scripts/qemu-smoke.sh (ADR-069 net-ping CNTPCT / this branch) | Ran on this agent box | Verified | 2026-09-16 agent-box qemu-smoke on feat/net-ping-cntpct: marker perf: net-ping ticks=20370 + preserved N1/N2/N4/samples; qemu-smoke: ADR-069 net-ping CNTPCT marker present; Running 121 tests all [ok]; force-fail exit 1; qemu-smoke: ok. Not Docker. Not a product stack. Tip e20c852. |
| Track N UDP transport (N3 / ADR-070) | Hello-kernel serial net: udp-tx + net: udp-rx + net: udp-ok (+ keep N1 net: ok / N2 net: ping-ok / N4 samples / ADR-069); QEMU -netdev user,id=net0 -device virtio-net-device,netdev=net0 unchanged; #[test_case] virtio_net_udp_dns_probe | Verified | 2026-09-16 agent-box qemu-smoke (QEMU 10.0.13, rustc 1.100.0-nightly 0fc141305, -cpu cortex-a57) on feat/n3-udp-transport: hello net: udp-tx / net: udp-rx / net: udp-ok + keep net: ok / net: ping-ok / libctos: net-ok / netdemo: ok / perf: net-ping / blk: ok / fat: ok / slot: ok; Running 122 tests all [ok] incl. virtio_net_udp_dns_probe; force-fail exit 1; qemu-smoke: ok. Probe = UDP DNS query to SLIRP 10.0.2.3:53 + matching DNS response (QR=1). Not BSD sockets / TCP product / DHCP/DNS product / Wi‑Fi / “has networking.” CloudAgent HELD — evidence tagged agent-box. ADR-070. |
| Threat-model v1.45 slice (NFR-10) | Read security.md (ADR-070 N3 minimal UDP; I/O surface still blk+net) | Verified | File + this PR. v1.45 update on tip post-#115 v1.44, not “secure.” Not BSD sockets. Not “has networking.” |
| scripts/qemu-smoke.sh (ADR-070 N3 UDP / this branch) | Ran on this agent box | Verified | 2026-09-16 agent-box qemu-smoke on feat/n3-udp-transport: markers net: udp-tx / net: udp-rx / net: udp-ok + preserved N1/N2/N4/samples/ADR-069; qemu-smoke: virtio-net (N1+N2+N3) strings present; Running 122 tests all [ok]; force-fail exit 1; qemu-smoke: ok. Not Docker. Not a product stack. Tip 7e74752. |
| Track N EL0 UDP DNS SVC + udp-libctos (N3.x / ADR-071) | Hello-kernel serial libctos: udp-hi + libctos: udp-ok + udpdemo: ok (+ keep N1 net: ok / N2 net: ping-ok / N3 net: udp-ok / N4 libctos: net-ok / prior samples / ADR-069); #[test_case] udpdemo_fat_is_elf + udpdemo_load_from_fat_erets + udpdemo_path_is_fat + el0_udp_dns_probe | Verified | 2026-09-16 agent-box qemu-smoke (QEMU 10.0.13, rustc 1.100.0-nightly 0fc141305, -cpu cortex-a57) on feat/n3x-el0-udp-svc: hello libctos: udp-hi / libctos: udp-ok / udpdemo: fat / udpdemo: mapped / udpdemo: ok + keep net: ok / net: ping-ok / net: udp-ok / libctos: net-ok / netdemo: ok / perf: net-ping / blk: ok / fat: ok / slot: ok; Running 126 tests all [ok] incl. el0_udp_dns_probe + udpdemo cases; force-fail exit 1; qemu-smoke: ok. SVC surface: net_udp_dns=26 (keep 24/25). FAT /udpdemo. Kernel owns virtio-net. DNS probe bait only. Not TCP/sockets/DHCP/DNS product/Wi‑Fi/“has networking.” CloudAgent HELD — evidence tagged agent-box. Tip 4c9e8a8. ADR-071. |
| Threat-model v1.46 slice (NFR-10) | Read security.md (ADR-071 N3.x EL0 UDP DNS SVC; I/O surface still blk+net) | Verified | File + this PR. v1.46 update on tip post-#116 v1.45, not “secure.” Not BSD sockets. Not “has networking.” |
| scripts/qemu-smoke.sh (ADR-071 N3.x / this branch) | Ran on this agent box | Verified | 2026-09-16 agent-box qemu-smoke on feat/n3x-el0-udp-svc: markers libctos: udp-hi / libctos: udp-ok / udpdemo: ok + preserved N1/N2/N3/N4/samples/ADR-069; qemu-smoke: ADR-071 udp-libctos /udpdemo strings present; Running 126 tests all [ok]; force-fail exit 1; qemu-smoke: ok. Not Docker. Not a product stack. Tip 4c9e8a8. |
| UDP DNS path CNTPCT (ADR-072 / P-PERF-9) | Hello serial perf: udp-dns ticks=<n> (prefix grep; not exact ticks); #[test_case] el0_udp_dns_cntpct_advances sample > 0; smoke rejects percent marketing; keep N1/N2/N3/N3.x/N4 + ADR-069 | Verified | 2026-09-16 agent-box qemu-smoke (QEMU 10.0.13, rustc 1.100.0-nightly 0fc141305, -cpu cortex-a57) on feat/udp-dns-cntpct: hello perf: udp-dns ticks=30943 + keep net: udp-ok / libctos: udp-ok / udpdemo: ok / perf: net-ping / blk: ok / fat: ok / slot: ok; Running 127 tests all [ok] incl. el0_udp_dns_cntpct_advances (perf: udp-dns ticks=65700 in that case); force-fail exit 1; qemu-smoke: ok. QEMU TCG lab — not a published bench, not a percent, not a DNS SLA. Window = quiet ARP+UDP DNS as SYS_NET_UDP_DNS / el0_udp_dns. CloudAgent HELD — evidence tagged agent-box. Tip 4989d68. ADR-072. |
| Threat-model v1.47 slice (NFR-10) | Read security.md (ADR-072 UDP DNS CNTPCT; keeps N1–N4 + ADR-069) | Verified | File + this PR. v1.47 update on tip post-#117 v1.46, not “secure.” Not a latency SLA. Not “has networking.” |
| scripts/qemu-smoke.sh (ADR-072 UDP DNS CNTPCT / this branch) | Ran on this agent box | Verified | 2026-09-16 agent-box qemu-smoke on feat/udp-dns-cntpct: marker perf: udp-dns ticks=30943 + preserved N1/N2/N3/N3.x/N4/samples/ADR-069; qemu-smoke: ADR-072 udp-dns CNTPCT marker present; Running 127 tests all [ok]; force-fail exit 1; qemu-smoke: ok. Not Docker. Not a product stack. Tip 4989d68. |
| FAT16 mkdir behind thin VFS (ADR-073 / sponsor mile 2) | Hello-kernel serial fat: mkdir + keep fat: ok / write / readdir / delete / grow / slot: ok; #[test_case] fat16_mkdir_root_dir + fat16_mkdir_exists_and_bad_path | Verified | 2026-09-16 agent-box qemu-smoke (QEMU 10.0.13, rustc 1.100.0-nightly 0fc141305, -cpu cortex-a57) on feat/fat-mkdir: hello fat: mkdir + keep fat: grow / fat: delete / fat: ok / slot: ok / net+sample markers; Running 129 tests all [ok] incl. mkdir cases; force-fail exit 1; qemu-smoke: ok. Guest created FAT16 root dir /fdir (dirent + ./.. cluster) via thin VFS. Not POSIX mkdir. Not a directory tree. Not exFAT/FAT32. No new SVC (EL0 follow-up). CloudAgent HELD — evidence tagged agent-box. Tip b0aa139. ADR-073. |
| Threat-model v1.48 slice (NFR-10) | Read security.md (ADR-073 FAT16 mkdir; keeps N1–N4 + ADR-069/072) | Verified | File + this PR. v1.48 update on tip post-#118 v1.47, not “secure.” Not POSIX mkdir. Not TCP. |
| scripts/qemu-smoke.sh (ADR-073 FAT16 mkdir / this branch) | Ran on this agent box | Verified | 2026-09-16 agent-box qemu-smoke on feat/fat-mkdir: marker fat: mkdir + preserved grow/delete/ok/net/samples; qemu-smoke: FAT16 mkdir (ADR-073) strings present; force-fail exit 1; qemu-smoke: ok. Not Docker. Not POSIX. Tip b0aa139. |
ADR-048 progress checklist
Living audit of ADR-048 against tip main @ be789c5 (or newer). Site mirror: hosting-apps.md. Product “app hosting is done” is Verified under criteria Met×5 (ADR-052). Still not Linux/POSIX/containers/“EL0 isolated.”
| # | Criterion | Status | Tip evidence |
|---|---|---|---|
| 1 | Documented recipes (A8) | Met | Row “Documented sample apps (Track A A8)” Verified; what-can-run.md. |
| 2 | Slot cross-update | Met | Row “A9 cross-update (same app on OS n and n+1)” Verified (cross-update … slot:ok on this OS + ba6541c). Later tips re-probed (ADR-046 / amd64 workstation Docker rows). |
| 3 | No production embed | Met | Row “A2–A4 hello without include_bytes! (ADR-032)” Verified; smoke rejects slot: embed. Probe-only include_bytes! in src/slot.rs only (ADR-046). Tip src/ audit: production A2–A4 FAT-only. |
| 4 | Honesty: no Linux/POSIX/containers | Met | Containers non-goal Verified (ADR-029); docs refuse Linux ABI / POSIX / guest OCI. |
| 5 | Explicit sponsor accept | Met | Sponsor: “address 1. app hosting” after still-Planned review blocked only on #5. Record: ADR-052. Flip PR cites ADR-048 checklist; no self-merge (ADR-002). |
| Track N thin TCP (N5 / ADR-074) | Hello-kernel serial net: tcp-syn + net: tcp-est + net: tcp-tx + net: tcp-rx + net: tcp-ok (+ keep N1 net: ok / N2 net: ping-ok / N3 net: udp-ok / N3.x/N4 samples / FAT); QEMU -netdev user,id=net0,guestfwd=tcp:10.0.2.4:7-cmd:…/tcp-echo-stdio.sh -device virtio-net-device,netdev=net0; #[test_case] virtio_net_tcp_echo_probe | Verified | 2026-09-16 agent-box qemu-smoke (QEMU 10.0.13, rustc 1.100.0-nightly 0fc141305, -cpu cortex-a57) on feat/n5-thin-tcp: hello net: tcp-syn / net: tcp-est / net: tcp-tx / net: tcp-rx / net: tcp-ok + keep prior net/FAT/sample markers; Running 130 tests all [ok] incl. virtio_net_tcp_echo_probe; force-fail exit 1; qemu-smoke: ok. Probe = TCP active-open + one payload echo via QEMU guestfwd 10.0.2.4:7. Not BSD sockets / listen-accept / TLS/HTTP / DHCP/DNS product / Wi‑Fi / “has networking.” CloudAgent HELD — evidence tagged agent-box. Tip a780f67. ADR-074. |
| Threat-model v1.49 slice (NFR-10) | Read security.md (ADR-074 N5 thin TCP; I/O surface still blk+net) | Verified | File + this PR. v1.49 update on tip post-#119 v1.48, not “secure.” Not BSD sockets. Not “has networking.” |
| scripts/qemu-smoke.sh (ADR-074 N5 thin TCP / this branch) | Ran on this agent box | Verified | 2026-09-16 agent-box qemu-smoke on feat/n5-thin-tcp: markers net: tcp-syn / net: tcp-est / net: tcp-tx / net: tcp-rx / net: tcp-ok + preserved N1–N3/N3.x/N4/FAT/samples; qemu-smoke: virtio-net (N1+N2+N3+N5) strings present; force-fail exit 1; qemu-smoke: ok. Not Docker. Not a sockets product. Tip a780f67. |
| EL0 fs_mkdir + mkdir-libctos catalog (ADR-075) | Hello-kernel serial libctos: mkdir-hi + libctos: mkdir-ok + mkdemo: ok + keep fat: mkdir / prior six samples / net; #[test_case] mkdemo_fat_is_elf + mkdemo_load_from_fat_erets + mkdemo_path_is_fat | Verified | 2026-09-17 agent-box qemu-smoke (QEMU 10.0.13, rustc 1.100.0-nightly 0fc141305, -cpu cortex-a57) on feat/el0-fs-mkdir: hello libctos: mkdir-hi / libctos: mkdir-ok / mkdemo: fat / mkdemo: mapped / mkdemo: ok + keep fat: mkdir / sample+net markers; Running 133 tests all [ok] incl. mkdemo cases; force-fail exit 1; qemu-smoke: ok. Guest loaded FAT /mkdemo and EL0 issued fs_mkdir (27) creating /edir with Exists→1 / BadPath→2 mapping. Not POSIX mkdir. Not a nested tree. Not EL0 TCP. CloudAgent HELD — evidence tagged agent-box. Tip 1c9c4dd. ADR-075. |
| Threat-model v1.50 slice (NFR-10) | Read security.md (ADR-075 EL0 fs_mkdir; keeps N1–N5 + ADR-073) | Verified | File + this PR. v1.50 update on tip post-#120 v1.49, not “secure.” Not POSIX mkdir. Not nested trees. |
| scripts/qemu-smoke.sh (ADR-075 EL0 fs_mkdir / this branch) | Ran on this agent box | Verified | 2026-09-17 agent-box qemu-smoke on feat/el0-fs-mkdir: markers libctos: mkdir-ok / mkdemo: ok + preserved fat: mkdir / net/samples; qemu-smoke: ADR-075 mkdir-libctos /mkdemo strings present; force-fail exit 1; qemu-smoke: ok. Not Docker. Not POSIX. Tip 1c9c4dd. |
| EL0 net_tcp_echo + tcp-libctos catalog (ADR-076) | Hello-kernel serial libctos: tcp-hi + libctos: tcp-ok + tcpdemo: ok + keep net: tcp-ok / prior seven samples / FAT; #[test_case] tcpdemo_fat_is_elf + tcpdemo_load_from_fat_erets + tcpdemo_path_is_fat + el0_tcp_echo_probe | Verified | 2026-09-17 agent-box qemu-smoke (QEMU 10.0.13, rustc 1.100.0-nightly 0fc141305, -cpu cortex-a57) on feat/el0-tcp-svc: hello libctos: tcp-hi / libctos: tcp-ok / tcpdemo: fat / tcpdemo: mapped / tcpdemo: ok + keep net: tcp-ok / sample+FAT markers; Running 137 tests all [ok] incl. tcpdemo + el0_tcp_echo_probe; force-fail exit 1; qemu-smoke: ok. Guest loaded FAT /tcpdemo and EL0 issued net_tcp_echo (28) quiet guestfwd echo. Not BSD sockets. Not listen/accept. Not TLS. Not TCP CNTPCT. CloudAgent HELD — evidence tagged agent-box. Tip 3704f2a. ADR-076. |
| Threat-model v1.51 slice (NFR-10) | Read security.md (ADR-076 EL0 TCP echo SVC; keeps N1–N5 + ADR-075) | Verified | File + this PR. v1.51 update on tip post-#121 v1.50, not “secure.” Not BSD sockets. Not “has networking.” |
| scripts/qemu-smoke.sh (ADR-076 EL0 TCP SVC / this branch) | Ran on this agent box | Verified | 2026-09-17 agent-box qemu-smoke on feat/el0-tcp-svc: markers libctos: tcp-ok / tcpdemo: ok + preserved net: tcp-ok / net/samples/FAT; qemu-smoke: ADR-076 tcp-libctos /tcpdemo strings present; force-fail exit 1; qemu-smoke: ok. Not Docker. Not a sockets product. Tip 3704f2a. |
| FAT16 nested mkdir + empty rmdir (ADR-077) | Hello-kernel serial fat: nested + fat: rmdir + keep fat: mkdir / grow / delete / ok / net / samples; #[test_case] fat16_nested_mkdir_and_empty_rmdir + fat16_dir_path_grammar | Verified | 2026-09-17 agent-box qemu-smoke (QEMU 10.0.13, rustc 1.100.0-nightly 0fc141305, -cpu cortex-a57) on feat/fat-nested-rmdir: hello fat: nested / fat: rmdir + keep fat: mkdir / sample+net markers; Running 139 tests all [ok] incl. nested+rmdir + path-grammar cases; force-fail exit 1 (timeout 180s); qemu-smoke: ok. Guest created /fdir/nest (dirent + ./.. with parent cluster) and empty-rmdir’d it via thin VFS. Not POSIX mkdir/rmdir. Not arbitrary-depth trees. No new SVC. Not TCP CNTPCT. CloudAgent HELD — evidence tagged agent-box. Tip 0025721. ADR-077. |
| Threat-model v1.52 slice (NFR-10) | Read security.md (ADR-077 nested mkdir + empty rmdir; keeps N1–N5 + ADR-073/075/076) | Verified | File + this PR. v1.52 update on tip post-#122 v1.51, not “secure.” Not POSIX mkdir/rmdir. Not TCP CNTPCT. |
| scripts/qemu-smoke.sh (ADR-077 nested+rmdir / this branch) | Ran on this agent box | Verified | 2026-09-17 agent-box qemu-smoke on feat/fat-nested-rmdir: markers fat: nested / fat: rmdir + preserved fat: mkdir / net/samples; qemu-smoke: FAT16 nested+rmdir (ADR-077) strings present; force-fail exit 1; qemu-smoke: ok. Not Docker. Not POSIX. Tip 0025721. |
| Thin TCP echo path CNTPCT (ADR-078 / P-PERF-10) | Hello serial perf: tcp-echo ticks=<n> (prefix grep; not exact ticks); #[test_case] el0_tcp_echo_cntpct_advances sample > 0; smoke rejects percent marketing; keep N1–N5 / N5.x + ADR-069/072/076/077 | Verified | 2026-09-17 agent-box qemu-smoke (QEMU 10.0.13, rustc 1.100.0-nightly 0fc141305, -cpu cortex-a57) on feat/tcp-echo-cntpct: hello perf: tcp-echo ticks=1124937 + keep net: tcp-ok / libctos: tcp-ok / tcpdemo: ok / perf: net-ping / perf: udp-dns / fat: nested / fat: rmdir / samples; Running 140 tests all [ok] incl. el0_tcp_echo_cntpct_advances (perf: tcp-echo ticks=1028684 in that case); force-fail exit 1 (timeout 180s); qemu-smoke: ok. QEMU TCG lab — not a published bench, not a percent, not a TCP SLA. Window = quiet ARP+thin TCP guestfwd as SYS_NET_TCP_ECHO / el0_tcp_echo (EL0 surface; kernel N5 untimed). CloudAgent HELD — evidence tagged agent-box. Tip 8f08f88. ADR-078. |
| Threat-model v1.53 slice (NFR-10) | Read security.md (ADR-078 TCP echo CNTPCT; keeps N1–N5 + ADR-069/072/076/077) | Verified | File + this PR. v1.53 update on tip post-#123 v1.52, not “secure.” Not a latency SLA. Not “has networking.” |
| scripts/qemu-smoke.sh (ADR-078 TCP echo CNTPCT / this branch) | Ran on this agent box | Verified | 2026-09-17 agent-box qemu-smoke on feat/tcp-echo-cntpct: marker perf: tcp-echo ticks=1124937 + preserved net/samples/FAT/ADR-069/072/076/077; qemu-smoke: ADR-078 tcp-echo CNTPCT marker present; Running 140 tests all [ok]; force-fail exit 1 (timeout 180s); qemu-smoke: ok. Not Docker. Not a sockets product. Tip 8f08f88. |
| PAN CPU reopen foundation (ADR-079 / #125) | Default -cpu cortex-a76; hello serial pan: id= + pan: present; smoke rejects pan: enabled / unexpected pan: absent; #[test_case] pan_present_on_probe_cpu | Verified (ID-field on new default) | 2026-09-19 agent-box research + smoke (QEMU 10.0.13): short probe table in ADR-079; hello pan: present on cortex-a76. Enable not Verified (ADR-080). inject-nmi still machine does not provide NMIs (ADR-081). CloudAgent HELD — agent-box. Tip 634ed8d. |
| Threat-model v1.54 slice (NFR-10) | Read security.md (ADR-079 PAN CPU reopen; enable still locked) | Verified | File + this PR. v1.54 update on tip post-#124 v1.53, not “secure.” Not PAN enabled. Not “EL0 isolated.” |
| scripts/qemu-smoke.sh (ADR-079 PAN CPU reopen / this branch) | Ran on this agent box | Verified | 2026-09-19 agent-box qemu-smoke on isolation/adr-079-pan-cpu-reopen: markers pan: id= / pan: present + preserved net/FAT/samples; qemu-smoke: PAN capability strings present; force-fail exit 1; qemu-smoke: ok. Not Docker. Tip 634ed8d. |
| PAN enable + EL1-vs-EL0 fault (ADR-080 / #125 mile 2) | Hello serial pan: enabled + pan: el1-fault (+ keep pan: id= / pan: present); smoke requires enable markers; #[test_case] pan_enable_el1_fault_on_probe_cpu; syscall uaccess clears PAN around copies | Verified | 2026-09-19 agent-box (QEMU 10.0.13, rustc 1.100.0-nightly 0fc141305, -cpu cortex-a76): hello pan: id=2 / pan: present / pan: enabled / pan: el1-fault; SPSR.PAN at fault; net/FAT/samples preserved. Umbrella still non-claim. CloudAgent HELD — agent-box. Tip 765a8d0. |
| Threat-model v1.55 slice (NFR-10) | Read security.md (ADR-080 PAN enable + EL1-vs-EL0 fault; umbrella still non-claim) | Verified | File + this PR. v1.55 update on tip post-#126 v1.54, not “secure.” Not “EL0 isolated.” |
| scripts/qemu-smoke.sh (ADR-080 PAN enable / this branch) | Ran on this agent box | Verified | 2026-09-19 agent-box qemu-smoke on isolation/adr-080-pan-enable-fault: markers pan: enabled / pan: el1-fault + preserved net/FAT/samples; qemu-smoke: PAN capability + enable + el1-fault strings present; force-fail exit 1; qemu-smoke: ok. Not Docker. Tip 765a8d0. |
| Taken lower-EL SError reopen (ADR-081 / #125 mile 3) | Dated QMP/HMP matrix on virt TCG + cortex-a76 (+ GICv3 / virtualization=on / secure=on / max): inject-nmi → machine does not provide NMIs; KVM absent; FEAT_NMI ≠ SError | Deferred / non-goal (locked; reopen unmet) | 2026-09-19 agent-box QEMU 10.0.13. Research brief research/daily-briefs/2026-09-19-adr-081-serror-inject-probe.md. Unlock = ADR-081 B1/B2/B3; B1 research ADR-082 (2026-09-19): no shippable pin yet. Park Verified; A-clear dormant prep. Do not invent Verified. ADR-081. |
| Threat-model v1.56 slice (NFR-10) | Read security.md (ADR-081 taken-SError re-probe still blocked; umbrella still non-claim) | Verified | File + this PR. v1.56 update on tip post-#127 v1.55, not “secure.” Not taken SError Verified. Not “EL0 isolated.” |
| scripts/qemu-smoke.sh (ADR-081 docs / this branch) | Ran on this agent box | Verified | 2026-09-19 agent-box qemu-smoke (QEMU 10.0.13, rustc 1.100.0-nightly 0fc141305, -cpu cortex-a76) on isolation/adr-081-taken-serror-reopen: hello el0: serror-arm / qmp inject-nmi => error:machine does not provide NMIs (ADR-045/081 dormant; park if not taken) / el0: serror-park (no bare el0: serror); pan: enabled / pan: el1-fault; net/FAT/samples green; force-fail exit 1; qemu-smoke: ok. Tip 903c7448d508ae0338c64868aac2319941f3c4cb. |
| Taken lower-EL SError B1 QEMU pin research (ADR-082 / #125) | Sponsor chose B1; dated upstream+agent-box research: virt through QEMU master still has no TYPE_NMI→async SError; apt/git pin alone does not unlock; draft local patch research-only | Deferred / non-goal (locked; B1 unmet this session) | 2026-09-19 agent-box QEMU 10.0.13. Probe scripts/qemu-nmi-probe.py + brief research/daily-briefs/2026-09-19-adr-082-b1-qemu-nmi.md. Blocker: wait upstream or sponsor-reviewed pinned QEMU build with proven el0: serror. Park Verified; do not require el0: serror. Not B2/B3. ADR-082. |
| Taken lower-EL SError B1 pinned QEMU (ADR-083 / #125) | Pin QEMU v10.0.0 + TYPE_NMI→SError patch; CTOS_QEMU + CTOS_REQUIRE_TAKEN_SERROR=1 smoke shows bare el0: serror; stock QEMU still parks | Verified (pin; CI job unconditional since ADR-090, 2026-09-26) | 2026-09-19 agent-box: build 7c949c53 + patch; probe inject-nmi ok; smoke qemu-smoke: taken 'el0: serror' present + qemu-smoke: ok. Stock 10.0.13: inject error + el0: serror-park. (amd64 workstation) intent <machine-id>; CloudAgent HELD — proof on agent-box. Not umbrella isolated. ADR-083. |
| Threat-model v1.58 slice (NFR-10) | Read security.md (ADR-083 pinned QEMU opt-in taken SError; umbrella still non-claim) | Verified | File + this PR. v1.58 on tip post-#129 v1.57. Not “secure.” Not “EL0 isolated.” |
| scripts/qemu-smoke.sh (ADR-083 pin / this branch) | Ran on this agent box with pin | Verified | 2026-09-19 agent-box CTOS_QEMU=tools/qemu-nmi/bin/qemu-system-aarch64 CTOS_REQUIRE_TAKEN_SERROR=1: taken el0: serror; force-fail exit 1; qemu-smoke: ok. Default path (no env) still park. |
| Threat-model v1.57 slice (NFR-10) | Read security.md (ADR-082 B1 research blocker; umbrella still non-claim) | Verified | File + this PR. v1.57 update on tip post-#128 v1.56, not “secure.” Not taken SError Verified. Not “EL0 isolated.” |
| scripts/qemu-smoke.sh (ADR-082 docs / this branch) | Ran on this agent box | Verified | 2026-09-19 agent-box qemu-smoke (QEMU 10.0.13, rustc 1.100.0-nightly 0fc141305, -cpu cortex-a76) on isolation/adr-082-b1-qemu-nmi-research: expect el0: serror-arm / inject-nmi error / el0: serror-park (no bare el0: serror); pan: enabled / pan: el1-fault; net/FAT/samples green; force-fail exit 1; qemu-smoke: ok. Hello el0: serror-arm / el0: serror-park (no bare el0: serror); pan: enabled / pan: el1-fault; net/FAT green; force-fail exit 1; qemu-smoke: ok. Tip ac61efbdd97a84f20aef67568d772d7e6aaabf44. |
| Taken lower-EL SError via B2 on free GitHub-hosted runners (ADR-084; not the B1 pin) | Temp workflow b2-serror-probe on probe/adr-084-b2-kvm: /dev/kvm + -accel kvm on ubuntu-24.04-arm / ubuntu-22.04-arm; -accel hvf on macos-15; VT/WHPX on windows-11-arm; x86 ubuntu-24.04 control; stock TCG inject-nmi matrix + all-machine sweep | Failed | 2026-09-25 CEST GHA runs 36193423604 + 36193613972 (all 5 jobs green on run 2; the probe lost). arm64 Linux: kvm [1]: HYP mode not available, /dev/kvm=absent, Could not access KVM kernel module. macOS M1 (Virtual): HV_UNSUPPORTED. Windows arm64: VMMonitorModeExtensions : False, WHPX Disabled. x86: /dev/kvm present but invalid accelerator kvm for AArch64. TCG everywhere: machine does not provide NMIs; sweep inject-nmi-ok=0 (118/101/117 machines). Free (public repo, standard runners). No self-hosted / paid / larger runner. Raw lines research/daily-briefs/2026-09-25-adr-084-b2-probe.txt. ADR-084. |
| P-SEC-3r B2 path (non-B1: different runner/accelerator delivering async SError) | arm64 host exposing KVM + QEMU 0002 KVM_SET_VCPU_EVENTS serror_pending on el0: serror-arm + fail-closed smoke requiring bare el0: serror | Verified (opt-in, one-off paid run) | 2026-09-26: sponsor chose B2-P; ADR-085 run 4 on AWS Graviton3 c7g.metal (eu-north-1b, Spot) PASS. Not a CI gate: no ctos CI job runs KVM, and re-running needs paid metal or a self-hosted arm64 KVM runner (B2-S, not registered). Free-runner probe stays Failed (ADR-084). B1 opt-in pin is not B2. Not “EL0 isolated.” |
| Threat-model v1.59 slice (NFR-10) | Read security.md (ADR-084 B2 free-runner spike blocked; umbrella still non-claim) | Verified | File + this PR. v1.59 on tip post-#130 v1.58. Not “secure.” Not taken SError Verified via B2. Not “EL0 isolated.” |
| CI on GitHub (ADR-084 docs / this PR) | .github/workflows/smoke.yml + pages.yml on isolation/adr-084-b2-free-runner-serror @ 5c4c38b (PR #136) | Verified | 2026-09-26 CEST PR run 36193979804 success: ubuntu-24.04-arm job 108265450556 (native arm64 runner, TCG) inject-nmi=>error:machine does not provide NMIs + el0: serror-park + qemu-smoke: ok; ubuntu-24.04 job 108265450597 success; opt-in qemu-nmi-pin job 108265450350 (B1, ADR-083) inject-nmi=>ok + bare el0: serror + qemu-smoke: taken 'el0: serror' present. Pages run 36193979996 mdBook build success. The B1 pin job is not B2 evidence. |
| Taken lower-EL SError via B2-P: real arm64 + KVM (ADR-085; not the B1 pin) | AWS c7g.metal (Graviton3 Neoverse-V1, CPU: All CPU(s) started at EL2, /dev/kvm=present); QEMU v10.0.0 + 0001 + 0002 -accel kvm -machine virt,gic-version=3 -cpu host; cargo build --features b2-serror; scripts/b2-kvm-smoke.py (fail-closed) via no-SSH user-data; serial console via ec2 get-console-output --latest | Verified (opt-in, one-off paid run) | 2026-09-26 13:26–13:33 CEST run 4 <instance-id-run4> (eu-north-1b Spot, head 159b178): qmp stop=>ok inject-nmi=>ok cont=>ok (ADR-085: KVM_SET_VCPU_EVENTS serror_pending) → el0: standing / el0: serror / el0: restored / b2: taken → b2-kvm-smoke: PASS taken lower-EL SError observed under accel=kvm. Excerpt: research/daily-briefs/2026-09-26-adr-085-b2p-console.txt. Limits: b2 profile only (no GIC/timer/virtio/FAT under KVM); no host ioctl trace; not CI. Not “EL0 isolated.” |
| B2-P metal runs 0–3 (ADR-085 bring-up) | Same host class; earlier heads | Failed | Run 0 m6g.metal <instance-id-run0> and run 1 c7g.metal <instance-id-run1>: cloud-init HOME unset, so cargo: command not found (patched QEMU did build with kvm on Graviton2). Run 2 <instance-id-run2>: zero guest UART bytes (3×90 s). Run 3 <instance-id-run3>: reached b2: p1 mmu-on, then PC=ffffff8040080a00 (high VBAR+0x200) PSTATE=a00003c5 EL1h. A pre-MMU-spin-lock control behaved the same, so that hypothesis was refuted. Root cause: TCR_EL1.TG1 reserved. All fail-closed, none claimed. |
| TCR_EL1.TG1 = 4 KiB explicit (ADR-085; real-hardware fix) | src/paging.rs TCR_TG1_4K = 0b10 << 30 (was reserved 0b00; TCG sanitised it to 4K) | Verified | Real Graviton3 run 3 stalled on the first TTBR1 fetch; run 4 with the fix printed ident: jump … ident: ram … pages=32150 under KVM. TCG unchanged: GHA run 36238549525 at 159b178 green (ubuntu-24.04-arm + ubuntu-24.04 el0: serror-park + qemu-smoke: ok; qemu-nmi-pin bare el0: serror). |
| Threat-model v1.60 slice (NFR-10) | Read security.md (ADR-085 B2-P Verified opt-in on Graviton3 KVM; TG1 fix; umbrella still non-claim) | Verified | File + this PR. v1.60 on the ADR-084 v1.59 branch. Not “secure.” Not “EL0 isolated.” Not “runs on real hardware” beyond the b2 profile. |
| AWS B2-P spike resources (ADR-085) | Tag audit project=ctos in eu-north-1 after runs: DescribeInstances (non-terminated) + resourcegroupstaggingapi GetResources + SG/key-pair/IAM check | Verified | See research/daily-briefs/2026-09-26-adr-085-b2p-graviton-kvm.md §Cleanup. Metal ≈43 min Spot, ≈ $0.19 total. |
| CI on GitHub (ADR-085 / PR #137) | .github/workflows/smoke.yml on isolation/adr-085-b2p-graviton-kvm-serror @ 159b178 (code tip incl. TG1 fix) | Verified | 2026-09-26 CEST push run 36238549525 success: ubuntu-24.04-arm job 108394690860 and ubuntu-24.04 job 108394690937 inject-nmi=>error:machine does not provide NMIs + el0: serror-park + qemu-smoke: ok; opt-in qemu-nmi-pin job 108394690974 (B1) inject-nmi=>ok + qemu-smoke: taken 'el0: serror' present. The docs-only commit on top is covered by the PR checks. CI never runs KVM, so it is not B2 evidence. |
| Umbrella checklist audit (ADR-086) | Every ADR-055 / ADR-060 row vs this-session probes: agent-box qemu-smoke on 915796f (2026-09-26 13:59–14:04 CEST, QEMU 10.0.13, cortex-a76 TCG, qemu-smoke: ok) + GHA PR run 36239619910 (13:41–13:53 CEST, all jobs success) + ADR-085 run 4 | Verified (audit) / umbrella Planned / non-claim | ADR-086: §A 13/13 miles + PAN enable Verified, CI-gated by qemu-smoke.sh. §B not Met: taken SError only on opt-in paths (B1 qemu-nmi-pin needs repo var CTOS_BUILD_QEMU_NMI=1; B2-P one-off, not CI), and the accepted smoke machine still parks. Full identity teardown Unmet and unmeetable as worded (yank _start vs ADR-047 never-yank). No umbrella accept ADR. Sponsor decisions D1–D5. Not “EL0 isolated.” |
| Residual TTBR0 identity inventory (ADR-086 scratch probe) | 915796f + scratch walker patch (not committed to src/); walks kernel + user TTBR0 before Hello World! | Documented (scratch; ratchet Planned M1) | 2026-09-26 ~14:10 CEST box run (output): kernel TTBR0 identity = MMIO 1 GiB Device block 0x0–0x4000_0000; low RAM 0x4000_0000–0x4008_0000 RW; stub page 0x4008_0000 RO+X (start-stay); padding tail [.ident_tear end, 0x4020_1000) RO+X; __kernel_end page RW. User TTBR0: stub page + padding tail (EL1-only). Not a CI gate until M1 commits ident: inv. |
| Threat-model v1.61 slice (NFR-10) | Read security.md (ADR-086 audit; residual identity inventory; umbrella still non-claim) | Verified | File + this PR. v1.61 on the ADR-085 v1.60 branch. Not “secure.” Not “EL0 isolated.” |
| CI on GitHub (ADR-086 docs / PR #138) | .github/workflows/smoke.yml + pages.yml on isolation/adr-086-el0-isolated-audit @ 3f4de00 | Verified | 2026-09-26 14:13–14:26 CEST PR run 36241262508 + push run 36241255248 success: ubuntu-24.04-arm + ubuntu-24.04 default smoke (park + qemu-smoke: ok), opt-in qemu-nmi-pin (B1) pass, Pages mdBook build 36241262505 pass. Docs-only. |
| Identity leftovers I2/I4/I5 tear + TTBR0 identity inventory ratchet (ADR-087, M1) | Hello serial ident: low/tail/kend lo=… + ident: low/tail/kend-fault + ident: inv-range … + ident: inv k=2 u=1 a=2 leaks=0 + ident: inv-neg k/u caught + ident: inv-neg clean + ident: inv-ok allow=mmio,stub; smoke rejects ident: inv-leak; inv-leak-probe kernel must be caught; #[test_case] identity_leftovers_torn_stub_stays + identity_inventory_allowlist_only_catches_plant | Verified | 2026-09-26 14:35–14:40 CEST agent-box qemu-smoke: ok (QEMU 10.0.13, cortex-a76 TCG, rustc 0fc141305): low 128 pages, tail 270 (+270 user), kend 1; kernel TTBR0 identity ranges 5 → 2 (MMIO block, _start stub), user 2 → 1 (stub). inv-leak-probe: ident: inv-leak k lo=0x40000000 + no ident: inv-ok → qemu-smoke: inv-leak-probe caught. MMIO + stub still identity-mapped: not full teardown. Not “EL0 isolated.” |
| Threat-model v1.62 slice (NFR-10) | Read security.md (ADR-087 residual identity = MMIO block + stub; ratchet) | Verified | File + this PR. v1.62 on the ADR-086 v1.61 branch. Not “secure.” Not “EL0 isolated.” |
| CI on GitHub (ADR-087 M1 / PR #139) | .github/workflows/smoke.yml on isolation/adr-087-identity-inventory-ratchet @ 6fcdc4e | Verified | 2026-09-26 14:41–14:52 CEST push run 36242707571 success: ubuntu-24.04-arm job 108406107386 + ubuntu-24.04 job 108406107365 ident: inv k=2 u=1 a=2 leaks=0 / ident: inv-ok allow=mmio,stub / qemu-smoke: inv-leak-probe caught (fail-closed ok) / qemu-smoke: ok; opt-in qemu-nmi-pin job 108406107228 inv-ok + taken el0: serror. PR run 36242713730 default jobs success. |
| Device MMIO TTBR1 alias + identity MMIO block tear (ADR-088, M2) | Hello serial ident: mmio-high gic=0xffffff8008000000 uart=0xffffff8009000000 virtio=0xffffff800a000000 + ident: mmio lo=0x0 hi=0x40000000 l1=1 + ident: mmio-fault va=0x9000018 + ident: inv k=1 u=1 a=1 leaks=0 + ident: inv-ok allow=stub; smoke rejects any inv-range k|a lo=0x0; #[test_case] identity_mmio_torn_high_alias_xn; wx: ok via mmio_xn | Verified | 2026-09-26 ~14:43 CEST agent-box qemu-smoke: ok. Only the _start stub page stays identity-mapped (kernel, user, ASID-B; EL1 RO+X). b2 profile TCG-booted only; B2-P KVM evidence predates M1/M2 (re-run ≈ $0.2, not done). Not “EL0 isolated.” |
| Threat-model v1.63 slice (NFR-10) | Read security.md (ADR-088 MMIO high alias; identity = stub only) | Verified | File + this PR. Not “secure.” Not “EL0 isolated.” |
| ADR-055 §B row 2 reworded: full identity teardown except the _start stub page (ADR-089, M3, sponsor D2) | Default-smoke inventory ident: inv k=1 u=1 a=1 leaks=0 + ident: inv-ok allow=stub + ident: start-stay (ADR-087/088) | Met (this session; not the umbrella) | Sponsor D2 relayed 2026-09-26 ~14:35 CEST. Box smoke ~14:43 CEST on ADR-088; CI on #140 recorded separately. ADR-047 §3 amended in place. Umbrella still needs taken-SError evidence class (M4) + sponsor accept (M5 draft → sponsor). Not “EL0 isolated.” |
| Threat-model v1.64 slice (NFR-10) | Read security.md (ADR-089 stub exception) | Verified | File + this PR. Not “secure.” Not “EL0 isolated.” |
| CI on GitHub (ADR-088 M2 / PR #140) | .github/workflows/smoke.yml on isolation/adr-088-mmio-high-alias @ 09076d4 | Verified | 2026-09-26 14:56–15:10 CEST push run 36243493356 + PR run 36243501093 all success. ubuntu-24.04-arm job 108408303774: ident: mmio-high gic=0xffffff8008000000 uart=0xffffff8009000000 virtio=0xffffff800a000000 / ident: mmio-fault va=0x9000018 / ident: inv k=1 u=1 a=1 leaks=0 / ident: inv-ok allow=stub / qemu-smoke: inv-leak-probe caught (fail-closed ok) / qemu-smoke: ok. Pin job 108408283187: inject-nmi=>ok → bare el0: serror + inv-ok allow=stub. Not “EL0 isolated.” |
| CI on GitHub (ADR-089 M3 docs / PR #141) | smoke.yml + pages.yml on docs/adr-089-stub-exception @ 8093721 | Verified | 2026-09-26 14:56–15:10 CEST push run 36243529890 all success (both default jobs + pin job 108408379969); mdBook build success. Not “EL0 isolated.” |
| ADR-055 §B row 1 reworded: taken lower-EL SError on the D1 evidence class (ADR-090, M4, sponsor D1) | B1 qemu-nmi-pin (pinned QEMU v10.0.0 + patch 0001, CTOS_REQUIRE_TAKEN_SERROR=1, bare el0: serror fail-closed), now unconditional on every push/PR, + B2-P ADR-085 run 4 (Graviton3 KVM, el0: serror + b2: taken, one-off at 159b178) | Met (D1 evidence class; not the umbrella) | Sponsor D1 relayed 2026-09-26 ~14:35 CEST. Workflow if: vars.CTOS_BUILD_QEMU_NMI removed (a skipped job would pass a D5 required check); job renamed “QEMU NMI pin smoke (taken SError)”. Stock QEMU still parks (el0: serror-park). B2-P predates M1/M2 (KVM re-verify ≈ $0.2, not done). First unconditional run: CI on this PR. Umbrella still needs the sponsor’s written accept (B3). Not “EL0 isolated.” |
| Threat-model v1.65 slice (NFR-10) | Read security.md (ADR-090 taken-SError evidence class) | Verified | File + this PR. Not “secure.” Not “EL0 isolated.” |
| Umbrella accept draft (ADR-091, M5, sponsor D4) — ADR-055 §B row 3 | Proposed umbrella sentence + scope S1–S7 + non-scope + gaps G1–G3 + M6 prerequisites, quoting ADR-090 §1 verbatim | Documented (Draft); row 3 not Met; umbrella Planned / non-claim | Drafted 2026-09-26. B3 needs the sponsor’s written accept after reading this draft; merging the draft is not acceptance. Found while drafting: no exhaustive EL0-permission walk (G1) and no EL0 write probe (G2); B2-P re-verify optional (G3, ≈ $0.2). Not “EL0 isolated.” → Accepted 2026-09-28 (M6 row below). |
| Threat-model v1.66 slice (NFR-10) | Read security.md (ADR-091 draft scope / non-scope) | Verified | File + this PR. Not “secure.” Not “EL0 isolated.” |
| CI on GitHub (ADR-090 M4 / PR #142) | smoke.yml on isolation/adr-090-serror-accepted-machine @ be829fe | Verified | 2026-09-26 15:12–15:28 CEST push run 36244384336 + PR run 36244391658 all success. First unconditional pin job 108410713515 (“QEMU NMI pin smoke (taken SError)”, 15:12–15:26): inject-nmi=>ok → bare el0: serror + ident: inv-ok allow=stub + qemu-smoke: ok. Default jobs 108410713544 (arm) / 108410713462 (x86). Not “EL0 isolated.” |
| CI on GitHub (ADR-091 M5 draft / PR #143) | smoke.yml + pages.yml on docs/adr-091-el0-isolated-accept-draft @ b6f324a | Verified | 2026-09-26 15:13–15:28 CEST PR run 36244433643 (arm 108410849837, x86 108410849682, pin 108410849707) + push run 36244425884 all success; mdBook build (run 36244433661) success. Not “EL0 isolated.” |
| EL0-reachability walk, fail-closed (ADR-092 G1) | Every valid leaf of kernel / user / ASID-B TTBR0 + TTBR1; EL0-reachable = AP[1] or UXN clear; allowlist = five 4 KiB user slots; pool frame outside heap; not Device; not EL0 W+X; nothing in TTBR1. Live (hello-libctos standing) + steady + 4 plants + reach-leak-probe build | Verified | Agent box 2026-09-27 00:20–00:23 CEST qemu-smoke: ok: el0-reach: live k=3 u=3 a=0 h=0 pages=6 leaks=0, el0-reach: steady k=0 u=0 a=0 h=0 pages=0 leaks=0, el0-reach: neg kernel-pa/va/ttbr1/el0-wx caught, el0-reach: neg clean, el0-reach: ok allow=…; leak build el0-reach: leak k/u lo=0x80007000 … why=kernel-pa → caught. CI: row below. Not “EL0 isolated.” |
| EL0 write → permission fault (ADR-092 G2) | EL0 STR to kernel .data via TTBR1 and to an EL0-RO user page: lower-EL data abort, EC 0x24, WnR 1, DFSC perm, FAR = target, ELR = STR, target unchanged; write-leak-probe build must report the completed store | Verified | Agent box 2026-09-27 00:20–00:23 CEST: el0: write-fault kernel va=0xffffff8040201008 esr=0x9200004f far=0xffffff8040201008 ec=0x24 wnr=1 dfsc=perm-l3, el0: write-fault user-ro va=0x80009000 esr=0x9200004f far=0x80009000 …, el0: write-ok kernel,user-ro; leak build el0: write-succeeded user-ro va=0x80009000 esr=0xf2000000 → caught. _start not targeted. Not “EL0 isolated.” |
| Syscall copy helpers check EL0 permission (ADR-092 G4) | user_range_ok_max would need EL0 read/write permission on each user leaf | Documented gap (code reading; not probed, not fixed) → closed by ADR-094 (next row) | Today it accepts any valid user-TTBR0 leaf and copy_user clears PAN. So SYS_UART_WRITE could copy the EL1-only _start stub page or an EL1-only window page; copy_to_user could write the app’s execute-only text. ADR-091 revision 2 limits the sentence to direct EL0 access and lists G4 for the sponsor. |
| Threat-model v1.67 slice (NFR-10) | Read security.md (ADR-092 EL0 reach walk + write fault; G4) | Verified | File + this PR. Not “secure.” Not “EL0 isolated.” |
| CI on GitHub (ADR-092 / PR #144) | smoke.yml + pages.yml on isolation/adr-092-el0-reach-walk @ ab158cb | Verified | 2026-09-27 00:25–00:40 CEST push run 36276236937 + PR run 36276246462 all success; mdBook (run 36276246435) success. ubuntu-24.04-arm job 108499427750, ubuntu-24.04 job 108499427771 and pin job 108499427726 (“QEMU NMI pin smoke (taken SError)”, also bare el0: serror) each show el0: write-fault kernel va=0xffffff8040203008 esr=0x9200004f far=0xffffff8040203008 ec=0x24 wnr=1 dfsc=perm-l3, el0: write-fault user-ro va=0x80009000 …, el0: write-ok kernel,user-ro, el0-reach: live k=3 u=3 a=0 h=0 pages=6 leaks=0, el0-reach: steady k=0 u=0 a=0 h=0 pages=0 leaks=0, el0-reach: neg clean, el0-reach: ok allow=…, qemu-smoke: el0-leak-probe caught (fail-closed ok) (leak build: el0: write-succeeded user-ro …, el0-reach: steady k=1 u=1 a=0 h=0 pages=2 leaks=2), qemu-smoke: ok. Not “EL0 isolated.” |
| Syscall pointers need EL0 permission on every page (ADR-094 G4) | user_range_ok_max requires EL0-readable (AP[1]) for copies from EL0 and EL0-writable (AP[1], !AP[2]) for copies to EL0, per page; loader maps app text+rodata EL0 RO+X (map_el0_text); probes: control + kernel-stub / kernel-window read + xo-text / RO write + straddle + 7-syscall sweep, each needing exactly one refusal by the check; sysptr-leak-probe build | Verified | Agent box 2026-09-27 (CEST) local qemu-smoke: ok: el0: sys-ptr control rw-data n=6, el0: sys-ptr denied kernel-stub, … kernel-window, … xo-text, … write-ro, … straddle, el0: sys-ptr denied sys=uart_write nr=17 read kernel-stub … sys=net_mac nr=24 write xo-text (7), el0: sys-ptr sweep syscalls=7 denied=7, el0: sys-ptr ok; leak build el0: sys-ptr leaked kernel-stub n=8, … kernel-window n=8, … xo-text n=6 intact=false checks=0, el0: sys-ptr skip write-ro → caught. G1 allowlist unchanged (5 slots); el0-reach: live k=3 u=3 a=0 h=0 pages=6 leaks=0 unchanged. App ELF sha256 unchanged (A9 cross-update ok). CI: row below. _start only a refused read target. Not “EL0 isolated.” |
| Umbrella accept draft revision 3 (ADR-091, after ADR-094) | Sentence drops “direct EL0 memory access only”; adds syscall-pointer clause (S9); G3 the only remaining optional limit | Documented (Draft); row 3 not Met; umbrella Planned / non-claim | Standing order applied (sponsor skipped the G4 question). Merging is not acceptance. Not “EL0 isolated.” → Accepted 2026-09-28 (M6 row below). |
| Threat-model v1.68 slice (NFR-10) | Read security.md (ADR-094 syscall pointer EL0 permission) | Verified | File + this PR. Not “secure.” Not “EL0 isolated.” |
| CI on GitHub (ADR-094 / PR #146) | smoke.yml + pages.yml on isolation/adr-094-sys-ptr-perm @ 77cae2a | Verified | 2026-09-27 13:25–13:41 CEST PR run 36315704190 (ubuntu-24.04 job 108609879034 13:25–13:35, ubuntu-24.04-arm job 108609879082 13:25–13:36, pin job 108609879083 “QEMU NMI pin smoke (taken SError)” 13:25–13:40) + push run 36315678386 (ubuntu-24.04 108609807133 13:25–13:35, ubuntu-24.04-arm 108609807340 13:25–13:36, pin 108609807322 13:25–13:41) all success; mdBook (run 36315704200, 13:25–13:26) success. Arm job log shows all 15 el0: sys-ptr … lines (control, 5 denied, 7-syscall sweep, sweep syscalls=7 denied=7, ok), qemu-smoke: syscall pointer EL0-permission strings present (ADR-094), qemu-smoke: el0-leak-probe caught (fail-closed ok; reach + write + sys-ptr), qemu-smoke: ok. Not “EL0 isolated.” |
| Public-identifier scrub (ADR-093) | git grep for the replaced values on this branch + scripts/check-public-ids.sh | Verified | ADR-093: account ID replaced in 11 files, plus hosted-zone, instance, Spot, SG, IAM-user and local-path identifiers (17 content files). Values remain in git history; cleanup is a separate sponsor decision. Not “secure,” not “compliant.” |
| Public-identifier guard is fail-closed (ADR-093) | sh scripts/check-public-ids.sh --self-test (planted synthetic tokens, 7 classes) + scan of unmodified main must FAIL | Verified | Self-test ok; unmodified main FAIL hits=77 (every value line, no extras); this branch hits=0. Wired as first step of qemu-smoke.sh (CI + Docker). Bare 12-digit numbers without context are not flagged (see ADR limits). |
| CI on GitHub (ADR-093 / PR #145) | .github/workflows/smoke.yml + pages.yml on security/scrub-public-ids @ d53eb29 | Verified | PR smoke 36310073042 + push smoke 36310067233: ubuntu-24.04 / ubuntu-24.04-arm / NMI pin all success, 2026-09-27 11:39–11:52 CEST; logs show public-ids: self-test ok classes=7 + public-ids: ok … hits=0 before qemu-smoke: ok. Pages build 36310073058 success (deploy skipped on PR). Docs-only follow-up commit adds this row. |
| CI on GitHub (ADR-093 / PR #145, after merging main @ 8107578) | smoke.yml + pages.yml on security/scrub-public-ids @ 4d644d6 (merge of main into the branch; conflicts in SUMMARY / ledger / MOC resolved by keeping both sides) | Verified | 2026-09-28 13:30-13:45 CEST PR run 36416030136 (ubuntu-24.04 job 108907277988 13:30-13:40, ubuntu-24.04-arm job 108907278179 13:30-13:42, pin job 108907277537 “QEMU NMI pin smoke (taken SError)” 13:30-13:45) + push run 36416025183 (ubuntu-24.04 108907261648 13:30-13:38, ubuntu-24.04-arm 108907261918 13:30-13:40, pin 108907261888 13:30-13:44) all success; mdBook (run 36416030182, job 108907277345, 13:30) success, deploy skipped on PR. First run with the three D5-required checks on this PR. Pin job log: public-ids: self-test ok classes=7, public-ids: ok files=451 hits=0 (whole merged tree, including ADR-087..094 files from the stack; no new scrubs needed), inject-nmi=>ok, bare el0: serror, qemu-smoke: ok. Docs-only follow-up commit adds this row. |
| Taken lower-EL SError via B2-P re-run on current main (ADR-095, G3; not the B1 pin) | Same as ADR-085 run 4: AWS c7g.metal (Graviton3 Neoverse-V1, CPU: All CPU(s) started at EL2, /dev/kvm=present, KVM API 12, host kernel 7.0.0-1013-aws); QEMU v10.0.0 + 0001 + 0002 -accel kvm -machine virt,gic-version=3 -cpu host; cargo build --features b2-serror at main 8107578; scripts/b2-kvm-smoke.py (fail-closed) via no-SSH user-data (in-tree script + small delta in ADR-095); serial console via ec2 get-console-output --latest | Verified (opt-in, one-off paid run) | 2026-09-28 13:50–13:58 CEST (eu-north-1b Spot, all resources tagged project=ctos / component=g3-kvm-recheck, deleted and verified): CTOSB2: head 8107578a6c715a89c9e5861ebb4102460ba20e80 → ident: mmio-high … / ident: low|tail|kend … / ident: mmio lo=0x0 hi=0x40000000 l1=1 / pan: id=2 / pan: enabled / pan: el1-fault → b2: boot → qmp stop=>ok inject-nmi=>ok cont=>ok (ADR-085: KVM_SET_VCPU_EVENTS serror_pending) → el0: standing / el0: serror / el0: restored / b2: taken → b2-kvm-smoke: PASS taken lower-EL SError observed under accel=kvm (attempt 1). Cost ≈ $0.04. Excerpt: research/daily-briefs/2026-09-28-adr-095-g3-console.txt. Closes ADR-091 G3. Limits: b2 profile only (no GIC/timer/virtio/FAT; no inventory / reach / write / sys-ptr probes under KVM); no host ioctl trace; not CI. ADR-091 still Draft, B3 not Met. Not “EL0 isolated.” |
| Threat-model v1.69 slice (NFR-10) | Read security.md (ADR-095 B2-P KVM re-run on current main) | Verified | File + this PR. No posture change. Not “secure.” Not “EL0 isolated.” |
| CI on GitHub (ADR-095 / PR #147) | smoke.yml + pages.yml on isolation/adr-095-g3-kvm-recheck @ 31cdb1d (ADR-095 commit 5af2fd3 + merge of main e1ee4a8, ADR-093) | Verified | 2026-09-28 14:19–14:37 CEST PR run 36421105682 (ubuntu-24.04 job 108923761266 14:19–14:29, ubuntu-24.04-arm job 108923761452 14:19–14:30, pin job 108923761116 “QEMU NMI pin smoke (taken SError)” 14:19–14:36) + push run 36421101861 (ubuntu-24.04 108923747720 14:19–14:28, ubuntu-24.04-arm 108923747783 14:19–14:30, pin 108923747527 14:19–14:33) all success; mdBook (run 36421105718, job 108923761567, 14:19) success. Arm job: public-ids: self-test ok classes=7 / public-ids: ok files=453 hits=0, el0: serror-park, qemu-smoke: ok. PR pin job: qmp stop=>ok inject-nmi=>ok cont=>ok → bare el0: serror → qemu-smoke: taken 'el0: serror' present (ADR-083 pinned QEMU) → qemu-smoke: ok. The first head 5af2fd3 also passed its push runs (36419823465: jobs 108919578949 / 108919579243 / 108919579461; 36419825002: jobs 108919583154 / 108919583418 / 108919583519; 14:07–14:25 CEST); its PR run did not start because main had moved (ADR-093 merge) and the PR conflicted in the append-only ledger, resolved by merging main. Docs only. Not “EL0 isolated.” |
| Umbrella “EL0 isolated” (M6 flip; ADR-091 Accepted; ADR-055 §B row 3) | Sponsor’s written accept (B3) of the revision-3 sentence and scope + ADR-055 §A/§B all Met + D5 branch protection (three required checks) + #139–#147 merged (main 68d4c8f, push CI green) + the M6 PR CI run as the one-session re-probe | Verified (scoped: the accepted ADR-091 sentence only) | B3 verbatim: “I accept the ADR-091 revision-3 sentence and scope as written. After M6, have ctos propose a short costed list of next milestones.” 2026-09-28 16:41 CEST; relay path: sponsor wrote it in the DSO agent chat, DSO relayed it to ctos. The claim is only this sentence: “On the ctos default smoke machine (QEMU virt, -cpu cortex-a76, TCG, one core), EL0 is isolated from the kernel at the architectural page-table / exception-level boundary: each EL0 task runs on its own TTBR0 with its own ASID; EL0 faults when it reads, writes or executes kernel memory; in every translation table (kernel, user and ASID-B TTBR0, and TTBR1) the only EL0-reachable pages are five allowlisted user slots backed by non-kernel frames, checked fail-closed while a user app runs and at rest; PAN is enabled and EL1 faults on EL0 memory; lower-EL IRQ and FIQ are taken while EL0 stands; taken lower-EL SError is evidenced by the ADR-090 evidence class; the only identity (VA = PA) mapping left in any TTBR0 is the documented EL1-only _start stub page (ADR-089); and a system call copies from or to an EL0 pointer only if EL0 itself may read (for a copy from EL0) or write (for a copy to EL0) every page in the range. It is not a speculative-execution or side-channel claim, not a real-hardware claim, and not a certification.” Limits: one core, the TCG default smoke machine; not a speculative-execution or side-channel claim, not a real-hardware claim, not a certification; EL0 can read its own code bytes; no multi-core race story. ADR-091 non-scope stands. Earlier rows that say “Not ‘EL0 isolated’” record their own PR’s scope at the time. ADR-091. Note 2026-10-02: this row records revision 3 as accepted at M6. The current claim is the revision-4 sentence (revision-4 row below); only the PAN clause and the code-bytes limit differ. |
| Threat-model v1.70 slice (NFR-10) | Read security.md (M6: umbrella “EL0 isolated” Verified only as the ADR-091 sentence) | Verified | File + this PR. Not “secure.” Not wider than the ADR-091 sentence. |
| CI on GitHub (M6 / PR #148, one-session re-probe of the ADR-091 sentence) | smoke.yml + pages.yml on isolation/m6-el0-isolated-flip @ 6956d31 (the M6 flip commit on main 68d4c8f) | Verified | 2026-09-28 16:59–17:16 CEST PR run 36440169580 (ubuntu-24.04 job 108988297915 16:59–17:07, ubuntu-24.04-arm job 108988297602 16:59–17:11, pin job 108988298105 “QEMU NMI pin smoke (taken SError)” 16:59–17:16) + push run 36440144452 (ubuntu-24.04 108988211209 16:59–17:10, ubuntu-24.04-arm 108988211425 16:59–17:10, pin 108988211602 16:59–17:16) all success; mdBook (run 36440169616, job 108988298049, 16:59) success, deploy skipped on PR. Every smoke job: ident: inv k=1 u=1 a=1 leaks=0 / ident: inv-ok allow=stub, el0-reach: live k=3 u=3 a=0 h=0 pages=6 leaks=0 / el0-reach: ok allow=…, el0: write-fault kernel … / el0: write-fault user-ro … / el0: write-ok kernel,user-ro, pan: enabled / pan: el1-fault, el0: sys-ptr sweep syscalls=7 denied=7 / el0: sys-ptr ok, qemu-smoke: ok. Default jobs: el0-reach: neg clean, ident: inv-neg clean, el0: serror-park, public-ids: self-test ok classes=7 / public-ids: ok files=454 hits=0. Pin jobs: el0: serror-arm, inject-nmi=>ok, bare el0: serror. Docs only; this row is a follow-up docs-only commit. |
| Task-to-task EL0 isolation probe (ADR-096) | Serial t2t: walk b-frame u-refs=0 u-el0=0 a-el0=1 / t2t: b-own ok asid=2 … / t2t: a-read fault asid=1 va=0x80007000 … got=0x0 after-b no-tlbi / t2t: a-write fault … b-intact=true / t2t: same-va … ×4 / t2t: ok asid-a=1 asid-b=2 va=0x80007000 read,write,same-va; #[test_case] el0_task_cannot_read_or_write_other_task; t2t-leak-probe build must report t2t: leak walk / t2t: leak read … got=0x7a5cb0b0 / t2t: leak write and withhold t2t: ok | Verified (scoped) | Task B (ASID-B TTBR0, ASID 2) writes sentinel 0x7a5cb0b0 to its private page at 0x80007000. Task A (user TTBR0, ASID 1) then loads and stores the same VA with no TLBI of it in between. Both take a lower-EL translation fault (FAR = the VA), A never sees the sentinel, and B’s frame is unchanged. A’s root has no leaf for B’s frame. With A’s own frame at the same VA, each task reads and writes only its own frame. Fail-closed in scripts/qemu-smoke.sh: every marker is required, t2t: leak / t2t: bad / t2t: probe missed are rejected, and the sentinel on any task-A line is rejected. A local negative test of the check block (missing t2t: ok, sentinel on an A line, got= changed on the read line, probe missed, the leak-build serial) failed each time. Limits: one core on the TCG default smoke machine. QEMU TCG flushes its whole software TLB when a TTBR write changes the ASID, so this is not a hardware stale-TLB/ASID-tagging test. It uses two kernel-built tasks, not two loaded apps under a scheduler. It is not a side-channel or speculative claim. Additional evidence only: not part of the ADR-091 sentence. Task-vs-task stays in ADR-091’s non-scope, and a revision 4 needs the sponsor in writing. |
| Threat-model v1.71 slice (NFR-10) | Read security.md (ADR-096 task-to-task probe section + mitigation row) | Verified | File + this PR. Not “secure.” The ADR-091 sentence is unchanged. |
| CI on GitHub (ADR-096 / PR #149, task-to-task EL0 isolation probe) | smoke.yml + pages.yml on isolation/t2t-probe @ 7439607 | Verified | PR run 36476725257: ubuntu-24.04 job 109112172166 (22:05–22:16 CEST), ubuntu-24.04-arm job 109112171989 (22:05–22:16), pin job 109112172193 “QEMU NMI pin smoke (taken SError)” (22:05–22:22). Push run 36476682111: ubuntu-24.04 109112035715 (22:05–22:15), ubuntu-24.04-arm 109112035659 (22:05–22:16), pin 109112035424 (22:05–22:21). All success. mdBook (run 36476725338, job 109112172352, 22:05) success; deploy skipped on PR. Every smoke job printed all nine t2t: lines at boot and again in cargo test (el0_task_cannot_read_or_write_other_task), then qemu-smoke: task-to-task EL0 isolation strings present (ADR-096). The leak build printed t2t: leak walk b-frame u-refs=1 u-el0=1, t2t: leak read asid=1 va=0x80007000 got=0x7a5cb0b0, t2t: leak write … and t2t: probe missed, then qemu-smoke: el0-leak-probe caught (fail-closed ok; reach + write + sys-ptr + t2t). Every job also printed public-ids: ok … hits=0 and qemu-smoke: ok. Local: the full smoke passed in QEMU TCG on a Linux box. A Docker Desktop smoke on the Windows workstation printed all nine t2t: lines, but stopped earlier at net probe missed (UDP step); main 9a1c2bb fails the same way there, so it is not caused by this change. Docs only; this row is a follow-up docs-only commit. |
| CI on GitHub (ADR-096 / PR #149 refreshed onto main 3c47c0c, i.e. after ADR-098 / #151) | smoke.yml + pages.yml on isolation/t2t-probe @ e6e7574 (plain merge of main into the branch; no rebase, no force-push) | Verified | PR run 37000471274: ubuntu-24.04 job 110816770656 (13:20-13:30 CEST), ubuntu-24.04-arm job 110816771290 (13:20-13:31), pin job 110816770893 “QEMU NMI pin smoke (taken SError)” (13:20-13:37). Push run 37000465958: ubuntu-24.04 110816754112 (13:20-13:31), ubuntu-24.04-arm 110816754218 (13:20-13:31), pin 110816754276 (13:20-13:37). All success. mdBook (run 37000471286, job 110816771395) success; deploy skipped on PR. The merged smoke script requires both the nine t2t: lines and the ADR-098 pan: live-syscall / pan: after-el0 / pan: ok held lines. The combined el0-leak-probe build enables t2t-leak-probe and pan-keep-leak-probe together; the t2t: leak ... lines and the pan: lost ... lines are each required individually and t2t: ok / pan: ok held are rejected there. Local: full ./scripts/qemu-smoke.sh on a Linux box (QEMU 10.0.13 TCG) printed qemu-smoke: ok, public-ids: ok files=459 hits=0, all nine t2t: lines, the three pan: lines and both leak families caught. Tampered-log check: deleting the t2t: ok line, and separately the pan: ok held line, each made the checker fail. Docs only; this row is a follow-up docs-only commit. |
| Correction: ADR-091 clause “PAN is enabled” was not true while the kernel handled EL0 exceptions (ADR-098) | Pre-fix behaviour reproduced by the pan-keep-leak-probe build: pan: enabled + pan: el1-fault (boot) and pan: lost live-syscall pstate-pan=0 sctlr-span=1 + pan: lost after-el0 trips=… mrs-pan=0 … fault=no spsr-pan=0 | Verified (defect found and fixed) | From the ADR-080 enable (2026-09-19), and so also from the M6 accept (2026-09-28 16:41 CEST) until this fix, the “PAN is enabled” clause held at boot but not while handling EL0 exceptions: SCTLR_EL1.SPAN was 1, so every exception from EL0 entered EL1 with PAN clear, and return_from_el0 resumed the kernel with SPSR 0x3C4 (PAN clear), so PAN stayed clear after EL0 trips until the next with_user_access. The boot probe missed this because it ran before any EL0 trip. The M6 umbrella row stays Verified only with this correction; the sentence is unchanged and true again with ADR-098. |
| PAN held during EL0 exception handling + after EL0 trips (ADR-098) | Serial pan: live-syscall pstate-pan=1 sctlr-span=0 (in the loaded app’s SYS_YIELD handler) / pan: after-el0 trips=<n≥1> mrs-pan=1 el1-load va=0x80003000 fault=yes spsr-pan=1 / pan: ok held boot,live-syscall,after-el0; #[test_case] pan_span_cleared_after_enable; pan-keep-leak-probe build must report pan: lost … and withhold pan: ok held | Verified (scoped) | Fix: SCTLR_EL1.SPAN=0 after the ADR-080 enable; SPSR.PAN set on return_from_el0. MRS PAN calibrated both ways (1 with a real EL1 fault, 0 in the negative build without one). Tampered-log tests: 7/7 edited logs fail, unedited passes. One core, TCG; one exception type and one post-trip point sampled. |
| Threat-model v1.72 slice (NFR-10) | Read security.md (ADR-098 PAN correction section + mitigation row) | Verified | File + this PR. v1.71 is ADR-096 (PR #149), numbered before this slice and merged after it. Not “secure.” ADR-091 sentence unchanged. |
| EL0 execute-only app text (ADR-097; merge requires sponsor rev 4 written accept) | Serial xo: live app=hello text va=0x80002000 ap=2 uxn=0 pxn=1 el0=x reach=1 hdr … rodata=0x80000120 in-text=0 sys-read text=deny rodata=allow / xo: layout loader app-hdr … app-text va=0x80002000 ap=2 uxn=0 pxn=1 el0=x reach=uxn / xo: el0-exec ok … got=0x584f524441544131 / xo: el0-read-text fault va=0x80002000 esr=0x9200000f far=0x80002000 ec=0x24 wnr=0 dfsc=perm-l3 got=0x0 / xo: el0-uart rodata-str ok / xo: sys-read rodata ok … / xo: sys-read text denied sys=uart_write nr=17 va=0x80002000 n=0 checks=1 / xo: el1-pan … ×2 / xo: el1-write text … fault=yes intact=true / xo: reach xo-plant caught … ap-el0=0 uxn=0 / xo: ok text=el0-xo rodata=app-hdr el0-read=fault sys-read=deny slots=5; #[test_case] el0_app_text_is_execute_only; host tests loader_plans_hello_as_ro_hdr_and_xo_text / loader_rejects_ro_on_text_page / loader_rejects_pages_outside_app_slots; xo-leak-probe build must report xo: leak … and withhold xo: ok | Verified (scoped; branch only until merged; update 2026-10-02: accepted by the sponsor as ADR-091 rev 4 and merged as 8344797) | App .rodata moved onto the app-hdr page (EL0 RO + NX); .text alone on app-text, mapped EL1 RO / EL0 none / UXN=0. Still five slots; allowlist and el0-reach: lines byte-identical. EL0 loads of its text fault, text pointers are refused by the ADR-094 check. EPAN finding: ID_AA64MMFR1_EL1.PAN=2 (no FEAT_EPAN) on QEMU 10.0.13 cortex-a76 (box and CI); with PAN set an EL1 load of the XO page does not fault (fault=no match=true). So the ADR-091 clause “PAN is enabled and EL1 faults on EL0 memory” is not literally true for that page: merge needs a sponsor rev 4 written accept. ADR-091 not edited. Tampered-log tests: 10/10 edited logs fail, unedited passes (ADR-097 §Negative tests). One core, TCG; not real hardware. |
| Threat-model v1.73 slice (NFR-10) | Read security.md (ADR-097 execute-only app text section + mitigation row) | Verified | File + this PR (was v1.72 before the ADR-098 PAN fix was split out and took v1.72). Not “secure.” ADR-091 sentence unchanged; merge requires sponsor rev 4 written accept. Update 2026-10-02: accepted and merged as 8344797; threat model is v1.74 (row below). |
| CI on GitHub (ADR-097 / PR #150, EL0 execute-only app text; stacked on #149; merge requires sponsor rev 4 written accept) | smoke.yml + pages.yml on isolation/xo-text @ e1135b6 | Verified | PR run 36485127669: ubuntu-24.04 job 109140067947 (23:17–23:29 CEST), ubuntu-24.04-arm job 109140068167 (23:17–23:29), pin job 109140068292 “QEMU NMI pin smoke (taken SError)” (23:17–23:35). Push run 36485081546: ubuntu-24.04 109139912849 (23:17–23:27), ubuntu-24.04-arm 109139913176 (23:17–23:28), pin 109139913104 (23:17–23:32). All success. mdBook (run 36485127464, job 109140067363, 23:17) success; deploy skipped on PR. Every smoke job: public-ids: ok files=460 hits=0; all thirteen xo: lines at boot (incl. xo: el0-read-text fault va=0x80002000 esr=0x9200000f … dfsc=perm-l3 got=0x0, xo: el1-pan text … fault=no match=true mmfr1-pan=2 epan=no, xo: pan live-syscall pstate-pan=1 sctlr-span=0, xo: ok … slots=5) and again in cargo test (152 tests, el0_app_text_is_execute_only); qemu-smoke: EL0 execute-only text strings present (ADR-097); the leak build printed xo: leak live text ap=3 el0=rx …, xo: leak el0-read-text va=0x80002000 got=0xf9400001d2800001, xo: leak sys-read text n=8 checks=0, xo: bad pan live-syscall pstate-pan=0 sctlr-span=1, xo: probe missed and was caught (… + t2t + xo)); qemu-smoke: ok. |
| CI on GitHub (ADR-097 / PR #150 refreshed onto main 3c47c0c via the refreshed #149 branch; merge requires sponsor rev 4 written accept) | smoke.yml + pages.yml on isolation/xo-text @ c63d712 (plain merge of isolation/t2t-probe @ e6e7574; no rebase, no force-push) | Verified | PR run 37001810303: ubuntu-24.04 job 110820981036 (13:35-13:45 CEST), ubuntu-24.04-arm job 110820980926 (13:35-13:45), pin job 110820980975 “QEMU NMI pin smoke (taken SError)” (13:35-13:48). Push run 37001811973: ubuntu-24.04 110820986072 (13:35-13:44), ubuntu-24.04-arm 110820985824 (13:35-13:45), pin 110820986091 (13:35-13:51). All success. mdBook (run 37001810402, job 110820981516) success; deploy skipped on PR. The merged smoke script requires the t2t:, xo: and ADR-098 pan: lines; the combined el0-leak-probe build enables t2t-leak-probe, xo-leak-probe and pan-keep-leak-probe together, and each family’s leak lines are required individually (t2t: ok, xo: ok and pan: ok held are rejected there). Local: full ./scripts/qemu-smoke.sh on a Linux box (QEMU 10.0.13 TCG, 153 tests) printed qemu-smoke: ok, public-ids: ok files=462 hits=0, all t2t:, xo: (incl. xo: pan live-syscall pstate-pan=1 sctlr-span=0) and pan: lines, and all three leak families caught (. + t2t + xo + pan)). Tampered-log check: deleting t2t: ok, xo: ok, xo: pan live-syscall . and pan: ok held (one at a time) each made the checker fail. Docs only; this row is a follow-up docs-only commit. |
| Umbrella “EL0 isolated” revision 4 (ADR-091 rev 4 accepted; ADR-097 Accepted; docs only) | Sponsor’s written accept, verbatim “I accept ADR-091 rev 4” (2026-10-02; written in the DSO chat, recorded in the DSO vault, relayed by DSO; answer to the exact wording in ADR-097) + PR #150 (ADR-097, XO app text) merged as 8344797 + PR #151 (ADR-098, PAN held in EL0 exception handling) on main as 3c47c0c. No code change in this PR; the xo: and pan: probes were already CI-gated by those PRs | Verified (scoped: the revision-4 ADR-091 sentence only) | Only the PAN clause and the code-bytes limit changed from revision 3. The claim is only this sentence: “On the ctos default smoke machine (QEMU virt, -cpu cortex-a76, TCG, one core), EL0 is isolated from the kernel at the architectural page-table / exception-level boundary: each EL0 task runs on its own TTBR0 with its own ASID; EL0 faults when it reads, writes or executes kernel memory; in every translation table (kernel, user and ASID-B TTBR0, and TTBR1) the only EL0-reachable pages are five allowlisted user slots backed by non-kernel frames, checked fail-closed while a user app runs and at rest; PAN is enabled, including while the kernel handles exceptions from EL0, and EL1 faults on EL0-readable memory (the execute-only app text page is not covered: this CPU has no FEAT_EPAN); lower-EL IRQ and FIQ are taken while EL0 stands; taken lower-EL SError is evidenced by the ADR-090 evidence class; the only identity (VA = PA) mapping left in any TTBR0 is the documented EL1-only _start stub page (ADR-089); and a system call copies from or to an EL0 pointer only if EL0 itself may read (for a copy from EL0) or write (for a copy to EL0) every page in the range. It is not a speculative-execution or side-channel claim, not a real-hardware claim, and not a certification.” Limits: one core, the TCG default smoke machine; not a speculative-execution or side-channel claim, not a real-hardware claim, not a certification; app text is EL0 execute-only; EL1 can still read it (no FEAT_EPAN); no multi-core race story. ADR-091 non-scope stands. The status rests on the existing probes (pan: live-syscall …, pan: ok held …, xo: ok …, xo: el1-pan text … fault=no … epan=no), not on this PR’s text; this PR’s CI is the re-probe. ADR-091, ADR-097. |
| Threat-model v1.74 slice (NFR-10) | Read security.md (ADR-091 revision 4: PAN clause + code-bytes limit; v1.73 section marked accepted) | Verified | File + this PR. Docs only. Not “secure.” Not wider than the revision-4 sentence. |
| KVM re-check in CI via GitHub OIDC (ADR-099, milestone item 2) | ADR-099: trust and permission policy shape (placeholders), results-out decision (console output, no PassRole), teardown and cost cap, Spot capacity story, risk table; inert .github/workflows/kvm-recheck.yml + scripts/kvm-recheck-userdata.sh | Planned | Documented design sketch, not implemented. The workflow has never run: dispatch-only, not scheduled, not a required check, fails closed while KVM_ROLE_ARN is unset. No AWS call was made. CloudTrail, the OIDC provider, the Spot service-linked role and the exact immutable-subject sub format are not verified; the DSO vault decision record was not read. Nothing about EL0 isolation changes. |
| ADR-099 files present (docs only) | ADR-099, .github/workflows/kvm-recheck.yml, scripts/kvm-recheck-userdata.sh in this PR; YAML parse, actionlint + shellcheck, bash -n, guard run with simulated variables (no AWS) | Verified | File presence and local lint only. Says nothing about AWS behaviour. Not “secure.” |
| ADR-099 pilot spec (2026-10-13, sponsor decision 20:49 CEST via DSO) | ADR-099 “Pilot spec” | One supervised, manual-dispatch run only; environment kvm-pilot; component tag kvm-ci-pilot; region eu-north-1; actions SHA-pinned; exact immutable sub with numeric IDs supplied to DSO out of band. Spot price is not IAM-enforceable (no condition key); capped by MaxPrice guard and budget. No AWS call by the agent; environment and role not created. CloudTrail (P1) met: DSO verified a multi-region trail, home region eu-north-1, from the arm64 workstation on 2026-10-13 about 20:56 CEST. |
| SMP race-story plan + global-state inventory (ADR-100) | rg of static items under src/ on main af5a9d1 + reading the owner modules | Documented (code reading; not a probe of race freedom) | 262 statics: 25 static mut, 10 spin-mutex, 208 atomics, 19 immutable. Riskiest: local-only TLBI, page-table static mut under a convention lock, fixed ASIDs, global EL0/expect flags, per-core PAN/SPAN/VBAR. Nothing here is “SMP-safe”. |
| Secondary CPU bring-up smoke, opt-in (ADR-100 S1, --features smp2-probe, QEMU -smp 2) | Serial smp: cpu0 mpidr=0x0000000080000000 / smp: secondary up mpidr=0x0000000080000001 / smp: cpu_on target=0x1 rc=0 / smp: ok cpu1 mpidr=0x0000000080000001 parked; negative: same ELF under -smp 1 → rc=-2, smp: cpu1 missed seen=0x0, checker fails; default run: no smp: line | Verified (local Linux box, QEMU 10.0.13 TCG, 2026-10-13; CI row below) | Secondary runs MMU off, prints, stores MPIDR to one flag word, parks in wfe. No EL0, no page tables, no heap/scheduler/drivers on cpu1. Not SMP support. ADR-091 rev 4 stays one core. |
| Threat-model v1.75 slice (NFR-10) | Read security.md (ADR-100 SMP plan; one-core non-goal; S1 mitigation row) | Verified | File + this PR. No posture change. Not “secure.” ADR-091 sentence unchanged. |
| CI on GitHub (ADR-100 / PR #154, SMP race story S1) | smoke.yml + pages.yml on smp/adr-100-s1 @ 6d0c324 | Verified | 2026-10-13 ~21:07-21:25 CEST PR run 38452394317 + push run 38452386420: both QEMU aarch64 smoke jobs (ubuntu-24.04-arm, ubuntu-24.04) green with qemu-smoke: default one-core (no smp: markers, ADR-100); QEMU NMI pin smoke (taken SError) green; non-required QEMU -smp 2 bring-up green with smp: secondary up mpidr=0x0000000080000001 / smp: ok cpu1 ... parked and the -smp 1 negative caught (rc=-2, smp: cpu1 missed seen=0x0); mdBook build green. Not SMP support; ADR-091 rev 4 stays one core. |
| Host / user name scrub + guard classes (ADR-101) | ADR-101; sh scripts/check-public-ids.sh --self-test → public-ids: self-test ok classes=15; scan → public-ids: ok … hits=0; same guard on unmodified main af5a9d1 → FAIL hits=151 | Verified (scoped: current tree only) | Forward-only, no history rewrite (sponsor 2026-10-13). Machine names, agent VM / EC2 private / GitHub runner host names and a machine ID replaced by role names or placeholders (counts by class in ADR-101, no values). Two scripts no longer print a host name. Not DLP; history, PR bodies and CI logs not scanned. |
| Repo variable CTOS_BUILD_QEMU_NMI deleted (sponsor 2026-10-13) | gh variable list before: one variable; workflows on main and on #152’s branch grep clean (no vars.CTOS_BUILD_QEMU_NMI since ADR-090 made the pin job unconditional); gh variable delete; gh variable list after: empty (2026-10-13 20:51 CEST) | Verified | GitHub setting, $0. The Dockerfile --build-arg CTOS_BUILD_QEMU_NMI is a separate build argument and is unchanged. |
| ADR-099 pilot setup recorded (DSO, 2026-10-13 22:12-22:16 CEST, on the sponsor’s 22:11 approval) | DSO relay to the agent; text only, no identifier values | Documented (relayed; not probed by this agent, no AWS call) | kvm-pilot environment + OIDC role created by DSO (role tagged project=ctos / component=kvm-ci-pilot, inline policy per ADR-099 incl. hop-limit fix); OIDC provider pre-existing and shared (another project’s Terraform); AMI Ubuntu 24.04 arm64 dated 20261004 (differs from ADR-095); SG no ingress; env: sole reviewer the sponsor, prevent_self_review off, main only, admin bypass off (sponsor 22:15); budget ctos-monthly-5 USD 5/month on project=ctos, alerts 80% actual / 100% forecast. Repo variables still unset; workflow inert. |
| ADR-099 review fixes (Bugbot on PR #152 + pilot findings, 2026-10-13) | Code/text reading of .github/workflows/kvm-recheck.yml + ADR-099; teardown logic exercised with a mocked aws (clean / slow / leak) | Documented (not run on AWS by the agent) | (1) snapshot resource kept out: AWS docs list it for RunInstances, but the live pilot launched without it (public AMI); add only on a concrete denial; (2) sweeper/LEAK counts only this run’s instances, so REFUSED-active-instance is not overwritten; (3) new ABORTED-after-aws-call, NOT-RUN = no AWS call; (4) teardown polls up to 20 min, shutting-down at the end = TEARDOWN-SLOW (red, not LEAK); (5) KVM_SUBNET_IDS accepts spaces and/or commas. |
| KVM pilot smoke under accel=kvm (ADR-099 pilot, relayed by DSO) | Workflow run 38468490030 at main 069fe83, c7g.metal; console markers el0: serror + b2: taken; nonce 685780b675853a95 | Verified (relayed by DSO; smoke PASS) | Run verdict red only from a false LEAK (5-min teardown wait timed out while the metal instance was shutting down); DSO verified the instance terminated. RunInstances worked without a snapshot resource. Reduced b2-serror profile only; not the default image. |
| SMP slice S2 opt-in probe (ADR-102) | ADR-102; CTOS_SMP2_ONLY=1 ./scripts/qemu-smoke.sh on the Linux box: -smp 2 → smp: ok cpu1 s2 mmu-on pan=1 span=0 vbar=own exc=handled console=locked; -smp 1, smp2-neg-pan, smp2-neg-span, smp2-neg-vbar each fail the checker with their miss line | Verified (QEMU TCG, -cpu cortex-a76, -smp 2, opt-in build only) | Core 1 MMU on with shared kernel tables, own stack and vectors, PAN=1 / SPAN=0, one brk handled on core 1. No SMP safety claim; core 1 runs no EL0, scheduler, heap, page-table code, drivers or interrupts. ADR-091 rev 4 (one core) unchanged. Console lock: positive only (no deterministic interleave negative). |
| SMP slice S3 (ADR-103): type-enforced TABLES, broadcast TLBI, cross-core unmap probe | ADR-103; page-table writers need &mut TablesGuard (compile-time); TLBI helpers use dsb ishst; tlbi …is; dsb ish; isb; CTOS_SMP2_SMOKE=1 ./scripts/qemu-smoke.sh on the Linux box: -smp 2 → smp: xtlb unmap cpu0 → cpu1 fault; local-tlbi-leak-probe → smp: xtlb leak (checker fails) | Verified (QEMU TCG, -cpu cortex-a76, -smp 2; leak 27/27 and fault 27/27 runs on the box) | One page, one direction (core 0 unmaps, core 1 faults). Reads of tables stay unlocked. No SMP safety claim; core 1 runs no EL0. ADR-091 rev 4 (one core) unchanged. The leak is a QEMU soft-TLB property, not a hardware claim. |
| Threat-model v1.76 slice (NFR-10) | Read security.md (new section “KVM re-check via GitHub OIDC (ADR-099)”: ADR-099 risk table folded in, as on main after PR #157) | Verified | File + this PR. Docs only. No posture change. Not “secure.” ADR-091 sentence unchanged. |
| SMP slice S4 (ADR-104): PerCpu via TPIDR_EL1, ASID allocator with generations, first EL0 on core 1 | ADR-104; CTOS_SMP2_SMOKE=1 ./scripts/qemu-smoke.sh on the Linux box: -smp 2 → 13 × smp: cpu1 probe <name> ok cpu=1, smp: asidgen alloc cpu0+cpu1 n=300 unique …, smp: asidgen reissue cpu0 rollover → cpu1 fault, smp: ok cpu1 s4 …; S4 leak build (all existing leak features + asid-rollover-local-probe) → every leak reported on cpu1, smp: asidgen leak, checker fails | Verified (QEMU 10.0.13 TCG, -cpu cortex-a76, -smp 2, opt-in build only; positive 20/20, leak 20/20, S3 xtlb leak 20/20) | Probes run on one core at a time (core 0 waits); result flags, user tables and the fatal stack stay shared; allocator not used by the default build. TCG flushes the TLB on any ASID change, so ASID tagging itself is not shown. No multi-core safety claim; ADR-091 rev 4 (one core) unchanged. |
| SMP slice S5 (ADR-105): concurrent EL0, run-queue lock, reserved ASID | ADR-105; CTOS_SMP2_SMOKE=1 ./scripts/qemu-smoke.sh on the Linux box: both cores run EL0; mid-run rollover keeps core 1’s ASID; asid-reserve-drop-probe → smp: s5 asid reissued while running cpu=1; cpu1 fatal on own stack; guards unmapped | Verified (QEMU 10.0.13 TCG, -cpu cortex-a76, -smp 2, opt-in; positive 10/10, reserve-drop 10/10) | No preemption; allocator opt-in only; TCG ASID-tag limit as in ADR-104. No multi-core safety claim; ADR-091 rev 4 unchanged. Multi-core sentence is a separate Proposed ADR. |
| Proposed multi-core claim sentence (ADR-106, docs only) | ADR-106; docs-only PR; no code; does not edit ADR-091 rev 4 | Proposed (not accepted) | Needs the sponsor’s written acceptance. Scope: QEMU TCG, cortex-a76, -smp 2, opt-in `smp2-probe`, with explicit TCG ASID-tag / no-preemption / no-KVM limits. |
| FAT32 read path beyond FAT16 (ADR-107): BPB + FSInfo, FAT32 chains, root as cluster chain, on a second read-only virtio-blk | ADR-107; ./scripts/qemu-smoke.sh: mkfs.fat -F 32 image → fat32: mount clusters=N≥65525 … fsinfo=ok, fat32: read /probe32.txt bytes=9, fat32: chain /big.bin clusters=6 jumps≥1 bytes=3000, fat32: root-chain clusters≥2 last=found, fat32: ok; negative boot with FAT[root] freed → fat32: fail reason=bad-chain, no fat32: ok, FAT16 fat: ok still; cargo test in-memory negatives (free / bad / out-of-range link, cycle, size mismatch, bad FSInfo, FAT16 geometry) | Verified (QEMU virt TCG, this PR’s CI smoke jobs) | Read-only; root directory only; 8.3 names only (LFN skipped); not mounted in the VFS; no write / FSInfo update / FAT mirror check. FAT16 path unchanged. Not hardware. |
| Taken-SError QEMU spike (ADR-108, research) | ADR-108; stand-alone image, research/serror-spike/serror-matrix.py 52/52 ok on stock 8.2.2 / 10.2.1 / master and pinned B1 | Shown: virtual SError (HCR_EL2.VSE, EL2-owned guest) taken from EL0 on cpu0/cpu1 on stock QEMU; pinned nmi targets cpu1. Not shown: any of this in the ctos kernel; physical SError on stock QEMU; bad-PA → SError (it is a sync abort). No claim change. |
| Inbound TCP over QEMU hostfwd (ADR-109 / N6): one passive open on guest port 8080, line → reply → close, RST on closed port 8081 | ADR-109; ./scripts/qemu-smoke.sh: net: tcp-in-listen port=8080 closed=8081, net: tcp-in-rst port=8081, net: tcp-in-syn, net: tcp-in-est, net: tcp-in-rx bytes=11, net: tcp-in-tx bytes=19, net: tcp-in-fin closed, net: tcp-in-ok; host hostfwd-client: neg=reset pos=ok rx=19 eof=yes; cargo test parse / checksum / RST / fragment unit cases | Verified (QEMU virt TCG, SLIRP on host loopback, this PR’s CI smoke jobs) | Kernel path only; one connection; no sockets API / EL0 SVC / retransmit timer / options / IPv6. Not a real-network or security claim. N5 outbound unchanged. |
| N1: taken SError on core 1 at EL0 (ADR-110, opt-in) | ADR-110; scripts/smp2-serror-pin.sh in the qemu-nmi-pin CI job | Shown: pinned QEMU, -smp 2, HMP nmi cpu-index=1 → core 1 takes it at EL0; nmi to cpu0 and A-masked are not taken (fail-closed). Not shown: stock QEMU, hardware, concurrency with S5. No claim change. |
| N2: EL2 shim, taken virtual SError at EL0 on stock QEMU (ADR-111, opt-in) | ADR-111; scripts/el2-vserror-smoke.sh, opt-in CI job | Shown: full image, stock QEMU 8.2.2/10.2.1 virt,virtualization=on + shim → virtual SError (HCR_EL2.VSE, EC 0x2f) taken at EL0; not taken without ask, A-masked, or without EL2. Not shown: physical SError, cpu1, hardware. Default boot has no EL2. No claim change. |