Development#7
Conversation
The Umbrix name turned out to be registered elsewhere. Renamed project-wide to Tyrne — a clean invented name with no prior hits — so the high-security positioning is not diluted by a trademark conflict. Sweep applied to every tracked text file: UmbrixOS → TyrneOS (compound, 58 occurrences) Umbrix → Tyrne (proper, 228 occurrences) umbrix → tyrne (lower, 262 occurrences) Scope: - Source: all Rust crates renamed (umbrix-kernel → tyrne-kernel, umbrix-hal → tyrne-hal, umbrix-bsp-qemu-virt → tyrne-bsp-qemu-virt, umbrix-test-hal → tyrne-test-hal); boot binary is now target/aarch64-unknown-none/debug/tyrne-bsp-qemu-virt. - Docs: 22 ADRs, architecture docs, standards, guides, audit log, roadmap, task files, reviews, templates. Doc-comment URL paths point at github.com/cemililik/TyrneOS/...; the GitHub repo rename is out of scope for this commit (broken links in old commit-history comments are expected). - Project-facing text: README, CLAUDE.md, AGENTS.md, CONTRIBUTING.md, SECURITY.md, NOTICE, LICENSE header. - Tooling: .cargo/config.toml runner path, build scripts, skill library references. Not changed (intentional): - Git history / commit messages — stay as written. Historical references to Umbrix remain; these are the record. - Working directory `/Users/dev/Documents/Projects/OS-Project` — the folder predates the project and the user prefers it unchanged. Verification: - cargo clean && cargo build — clean - 77 kernel + 34 test-hal = 111 host tests green - cargo fmt / host-clippy / kernel-clippy — clean - cargo kernel-build — clean - QEMU smoke — boot trace intact, now prefixed "tyrne:" instead of "umbrix:" across all five lines. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Retrospective pass R1 (manual cargo-geiger equivalent via grep): verify that every UNSAFE-2026-NNNN entry has at least one source reference, and that every unsafe block/fn/impl in production code cites an audit entry per unsafe-policy §1. Inventory: - 14 audit entries (0001-0014); 13 Active + 1 Removed (0012, retired by f9b72f8 per T-006). - Every audit tag has source references (no orphans). - UNSAFE-2026-0012 retains 7 source references despite being Removed — all in rejected-alternatives comments (intentional historical context, no active unsafe block claims coverage under it). One real gap found and closed: - TaskStack::top in bsp-qemu-virt/src/main.rs had a SAFETY comment but no audit-tag citation. Its inner unsafe block dereferences the UnsafeCell interior and computes a one-past-end pointer — operations that fall under the TaskStack sharing pattern UNSAFE-2026-0011 was introduced for, but the entry's text was scoped to the Sync marker only. Extended 0011's Location/Operation/Invariants/Rejected- alternatives sections to cover top() explicitly; added the audit citation + rejected-alternatives rationale to the per-block SAFETY comment (now policy §1 compliant). Verification: 77 kernel + 34 test-hal = 111 host tests green; cargo kernel-build / kernel-clippy / host-clippy all clean. Refs: unsafe-policy §1, §3 Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
First recorded coverage measurement for Tyrne. Overall (workspace excluding the bare-metal BSP): 94.41 % regions, 90.37 % functions, 92.85 % lines. 111 host tests across kernel + test-hal exercise this. Key findings routed to T-011's missing-tests bundle: 1. ipc_send_and_yield has zero direct tests. Three host tests needed (Delivered + unblock, Enqueued without yield, Err propagation) — this was already noted as a T-007 deferred follow-up; coverage data now confirms and quantifies the gap. 2. start() body (lines 426-473) is uncovered because it diverges; recommend splitting the prelude into a testable start_prelude() helper. 3. cap/table.rs has 40 uncovered error-return branches; a small targeted sweep (≤ 5 tests) covers most. 4. hal/src/mmu.rs at 40 % is expected (trait declarations only, no production impl until B2). Explicit non-recommendation: do NOT chase 100 %. The current baseline is strong; the named gaps are where real value sits. BSP excluded: tyrne-bsp-qemu-virt is no_std + no_main, its panic handler conflicts with std when built for host coverage. Covering it needs QEMU-side instrumentation — routed to T-009. Files added: - docs/analysis/reports/2026-04-23-coverage-baseline.md — human report - .gitignore — raw lcov/profraw dumps excluded Raw lcov output lives at docs/analysis/reports/lcov-2026-04-23.info (git-ignored; regenerate on demand). Refs: T-011 (will route T-011 scope additions when opened) Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
First `cargo +nightly miri test` run against the full workspace. This is the dynamic validation of ADR-0021's claim that no `&mut` reference to shared kernel state is live across `cpu.context_switch`. Result: 77 kernel + 34 test-hal = 111 host tests all pass under Miri's Stacked Borrows checker. ADR-0021's aliasing story is now dynamic-test-validated, not only paper-reviewed. Pre-fix find (closed in this commit): The first Miri run caught one real Stacked Borrows violation — inside the T-007 test helper `ResetQueuesCpu`, not in production code. The helper cached a raw pointer via `core::ptr::from_mut(&mut queues)` and the test body later re-derived a second `&mut queues` to pass into the bridge. Per Stacked Borrows, the second `&mut` borrow pops the stack and invalidates the tag on the cached pointer; when `context_switch` then dereferenced the helper's pointer, the tag was already dead. Fix: derive each `*mut` pointer exactly once at the top of the test and reuse the value. This is the same discipline ADR-0021 enforces on the production side — a reminder from the T-006 retro's "trace the call graph" lesson that test helpers need the same aliasing discipline as production code whenever they cache a pointer. Notable non-finding: the production bridge — every momentary `&mut *sched`, the split-borrow on `(*sched).contexts[i]` vs `[j]`, the per-phase re-acquisition in `ipc_recv_and_yield` — is Miri-clean on first try. T-006/T-007's paper argument holds under the Stacked Borrows runtime. Limitations (captured in the report): BSP is not tested under Miri (no_std + no_main host-build issue, same as llvm-cov); Miri does not observe optimizer rewrites and is not preemption-aware. Tree Borrows may surface more patterns when we adopt it. Recommendation: add `cargo +nightly miri test` to the CI matrix (T-R6 / future K3-7) — Miri regression is a hard stop. Files: - docs/analysis/reports/2026-04-23-miri-validation.md — report - kernel/src/sched/mod.rs — test-helper pointer-derivation fix Refs: ADR-0021, UNSAFE-2026-0014 Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Glossary pass after Phase A and B0's T-006/T-007 landed. Added 12 entries for terms that now appear throughout the code and docs but were missing from docs/glossary.md: - Arena, Generation tag — ADR-0016 kernel-object storage - CDT (Capability Derivation Tree) — ADR-0014 / ADR-0023 (pending) - Capability rights (CapRights), Capability transfer — ADR-0014 / ADR-0017 - Cooperative scheduling, Ready queue — ADR-0019 - Rendezvous IPC, Notification — ADR-0017 - Handle (typed) — disambiguates from CapHandle - Stacked Borrows, Miri, StaticCell, UnsafeCell — the Rust-aliasing vocabulary we now use actively after T-006 (ADR-0021) and the R3 miri validation pass (commit ff2aea1) Dropped the stale "Umbra (Latin)" entry: it was the etymology of the original Umbrix name. Per the 2026-04-22 rename (commit 5d7cc87), Tyrne is a clean-slate invented name with no shadow/perimeter motif — the entry was misleading and is removed. Also fixed a minor currency issue in the Trust boundary entry ("[architecture/security-model.md] (planned)" → plain link; that doc exists as of commit de66d68). Entry count: 24 → 35. No code changes. No tests affected. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
R2 coverage baseline and R3 miri validation both produced gap lists
for T-011. This commit opens T-011 with scope expanded to bundle:
(a) Phase A code-review §Test coverage items (ReceiverTableFull
assertion with cap retention; slot-reuse with pending transfer cap).
(b) T-007's deferred follow-up (ipc_send_and_yield three-case
coverage — Delivered+unblock, Enqueued no-yield, Err propagation
— with the same state-restore assertion T-007 applied to
ipc_recv_and_yield).
(c) R2 coverage baseline routings:
- sched::start() body uncovered → extract start_prelude helper,
test directly (small refactor, no behaviour change).
- cap/table.rs 40 uncovered error-return branches → five targeted
tests covering the most-reached paths.
(d) R2 + R3 re-runs post-landing: sched/mod.rs regions ≥ 90 %,
workspace regions ≥ 96 %, miri clean.
Status: Draft. Will move to In Progress only after T-006 and T-007
are promoted to Done, since T-011 writes tests against the final
shape of code those two tasks settled.
No code changes in this commit; only the task file + phase-b task
index + phase-b.md roadmap-row update.
Refs: ADR-0017, ADR-0019, ADR-0021, ADR-0022, T-007
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
First external CI gate for Tyrne. Mirrors the local workflow every contributor runs before opening a PR: Jobs (all ubuntu-latest, Cargo-cached): 1. lint-and-host-test (stable, ~2 min) — cargo fmt --check, cargo host-clippy, cargo host-test. Fast lane. 2. kernel-build (stable + aarch64-unknown-none, ~1 min) — cargo kernel-build and cargo kernel-clippy. Ensures the bare-metal BSP keeps compiling. 3. miri (nightly, ~10–15 min) — cargo +nightly miri test --workspace --exclude tyrne-bsp-qemu-virt. A Stacked Borrows regression is a hard stop per ADR-0021 / UNSAFE-2026-0014; this job is a direct gate on the R3 validation holding. 4. coverage (nightly + cargo-llvm-cov, ~3–5 min) — informational only today (continue-on-error: true). After T-011 lands and the workspace settles around its post-gap-fill shape, flip to enforce a floor. Triggers: every push and PR targeting main or development. Concurrent runs on the same branch cancel each other so only the latest commit's verdict matters. tyrne-bsp-qemu-virt is excluded from miri and coverage for the same reason llvm-cov found locally: no_std + no_main + panic handler conflicts with std when built for the host target. BSP-side CI gating needs QEMU automation and is a T-009 follow-up. Files: - .github/workflows/ci.yml — pipeline definition. - docs/guides/ci.md — operator guide: what runs, when, how to mirror locally, how to add a new check, when coverage starts gating, nightly pin procedure. - docs/guides/README.md — index updated. This closes R6 in the 2026-04-23 retrospective pass: R1 audit cross-check (c25f8c8) R2 coverage baseline (453ab1e) R3 miri validation (ff2aea1) R4 glossary refresh (25a63fb) R5 T-011 open (bf882ca) R6 CI skeleton (this commit) The T-006 mini-retro's "yatayı kalınlaştır" / widen-the-horizontal recommendation — first external review gate — is now a real running pipeline. First push that lands on GitHub will exercise it. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
There was a problem hiding this comment.
Sorry @cemililik, your pull request is larger than the review limit of 150000 diff characters
|
Warning Rate limit exceeded
Your organization is not enrolled in usage-based pricing. Contact your admin to enable usage-based pricing to continue reviews beyond the rate limit, or try again in 10 minutes and 29 seconds. ⌛ How to resolve this issue?After the wait time has elapsed, a review can be triggered using the We recommend that you space out your commits to avoid hitting the rate limit. 🚦 How do rate limits work?CodeRabbit enforces hourly rate limits for each developer per organization. Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout. Please see our FAQ for further information. ℹ️ Review info⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Run ID: ⛔ Files ignored due to path filters (1)
📒 Files selected for processing (132)
✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
CI (R6 fast lane) caught three rustfmt diffs in the T-007 / T-011 test-module helpers: - setup_single_task_with_recv_cap call site reflowed to one-arg- per-line block form. - ipc_recv_and_yield two-test call sites collapsed into single-line form now that each argument is a short identifier. - matches! arm in the assert! collapsed to single-line form. Formatting only; no behaviour change. 77 kernel + 34 test-hal = 111 host tests remain green; miri remains clean. This is the first real gate the just-landed CI pipeline has produced — exactly the kind of mechanical mismatch that auto-fmt should catch before review rather than clogging review attention. Worth noting: had the pipeline existed before T-007 landed, this diff would have surfaced on that PR, not two commits later. Refs: R6 CI pipeline (479e81e) Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
There was a problem hiding this comment.
Code Review
This pull request executes a project-wide rebranding from 'Umbrix' to 'Tyrne,' updating all documentation, crate names, and source code references. It also establishes a baseline for host-test coverage and Miri validation, introduces a new task for test hygiene, and adds a guide for the CI pipeline. The review identified a technical inconsistency in the TaskStack::top implementation where a mutable reference was being implicitly materialized despite safety comments claiming otherwise; a suggestion was provided to use direct pointer casting to strictly adhere to the project's aliasing discipline.
| // SAFETY: `self.0.get()` returns `*mut [u8; 4096]` from the | ||
| // UnsafeCell; dereferencing it is sound because the caller's | ||
| // `# Safety` contract says the TaskStack outlives every task using | ||
| // it, and single-core cooperative scheduling ensures no | ||
| // concurrent access to the same stack. `add(4096)` is the | ||
| // one-past-end sentinel — pointer arithmetic, not a dereference | ||
| // beyond the allocation. Rejected alternatives: safe slice | ||
| // indexing (`&self.0[4096..]`) cannot produce a one-past-end raw | ||
| // pointer without materialising a `&mut [u8]`, which would | ||
| // violate ADR-0021 by carrying a live `&mut` into task setup. | ||
| // Audit: UNSAFE-2026-0011. | ||
| unsafe { (*self.0.get()).as_mut_ptr().add(4096) } |
There was a problem hiding this comment.
The implementation of top() currently materializes a &mut [u8; 4096] reference through the call to as_mut_ptr(). This contradicts the SAFETY comment's claim that it avoids materializing a &mut [u8] to comply with ADR-0021's aliasing discipline.
Using cast().add() instead of (*ptr).as_mut_ptr().add() avoids the implicit dereference and borrow, truly satisfying the stated safety invariant.
| // SAFETY: `self.0.get()` returns `*mut [u8; 4096]` from the | |
| // UnsafeCell; dereferencing it is sound because the caller's | |
| // `# Safety` contract says the TaskStack outlives every task using | |
| // it, and single-core cooperative scheduling ensures no | |
| // concurrent access to the same stack. `add(4096)` is the | |
| // one-past-end sentinel — pointer arithmetic, not a dereference | |
| // beyond the allocation. Rejected alternatives: safe slice | |
| // indexing (`&self.0[4096..]`) cannot produce a one-past-end raw | |
| // pointer without materialising a `&mut [u8]`, which would | |
| // violate ADR-0021 by carrying a live `&mut` into task setup. | |
| // Audit: UNSAFE-2026-0011. | |
| unsafe { (*self.0.get()).as_mut_ptr().add(4096) } | |
| // SAFETY: self.0.get() returns *mut [u8; 4096] from the | |
| // UnsafeCell; obtaining a raw pointer to the interior is sound | |
| // because the caller's # Safety contract says the TaskStack | |
| // outlives every task using it, and single-core cooperative | |
| // scheduling ensures no concurrent access to the same stack. | |
| // add(4096) is the one-past-end sentinel — pointer arithmetic, | |
| // not a dereference beyond the allocation. Rejected alternatives: | |
| // safe slice indexing (&self.0[4096..]) or as_mut_ptr() | |
| // cannot produce a one-past-end raw pointer without materialising | |
| // a &mut [u8], which would violate ADR-0021. | |
| // Audit: UNSAFE-2026-0011. | |
| unsafe { self.0.get().cast::<u8>().add(4096) } |
Second-read of the six-commit 2026-04-23 retrospective arc (c25f8c8…5ba0d44) surfaced one real policy violation and several worth-fixing-now clarifications. Two of the reviewer's "Yüksek" items were false alarms on verification and needed no change. Accepted findings: 1. unsafe-policy §3 append-only violation. R1's commit c25f8c8 edited UNSAFE-2026-0011's original body in place to extend it to TaskStack::top, which the log's own "Entries are append-only" rule forbids. Fix: - Reverted UNSAFE-2026-0011's original body to its pre-R1 shape. - Appended a dated "Amendment (2026-04-23, commit TBD):" block with the top() location / operation / invariants / rejected alternatives — the same content R1 moved, now clearly tagged as a post-hoc extension rather than a rewrite. - Formalised the pattern in unsafe-log.md's header + unsafe- policy.md §3: status-change and dated Amendment blocks are the two permitted post-hoc update forms; in-place body edits remain a policy violation reviewers must reject. - Condensed the in-code SAFETY comment on TaskStack::top to reference the Amendment rather than duplicating its rationale, closing a drift surface the verbose form would have opened. 2. CI: cargo-llvm-cov reinstall every run. The coverage job did not cache ~/.cargo/bin, so `cargo install --locked cargo-llvm-cov` rebuilt the binary on every push (~1–2 min). Added ~/.cargo/bin to every job's cache paths and made the install step idempotent-by-comment. 3. CI: rolling nightly flake risk. Miri and coverage jobs pulled floating `nightly`, so a public-channel regression would break master with no diff to blame. Introduced NIGHTLY_PIN env var (`nightly-2026-01-15`) at the workflow top; both jobs use it. Cache keys include the pin so a bump invalidates the cache cleanly. docs/guides/ci.md "Nightly pinning" section rewritten with a concrete bump procedure. 4. docs/guides/ci.md: `continue-on-error: true` interacts surprisingly with branch-protection (GitHub renders neutral as non-passing, blocking merges when the job is required). Added a "Branch protection and continue-on-error" section spelling out which jobs to add to required-checks today (lint-and- host-test, kernel-build, miri) and which to leave out (coverage, until it flips to enforcing post-T-011). 5. T-011 AC #2 debug_assert mechanic. The original wording ("confirms the assertion's dev-mode behaviour") was underspecified; a test that triggers a debug_assert! panics, which needs explicit `#[should_panic]` + `#[cfg(debug_assertions)]` scaffolding. Replaced AC #2 with a paired-test spec: one should-panic test for the cap-drop case, one must-not-panic test for the no-cap case, both exercising `reset_if_stale_generation` by name. Protects the assert from rotting into either a blanket panic or a no-op. 6. T-011 references to T-009 softened. T-009 has a reserved slot in phase-b.md but no task file; references to it in T-011's Out-of-scope section now link to phase-b.md and note the "not yet opened" state explicitly. Rejected findings (verified, no change needed): - "`reset_if_stale_generation` doesn't exist, it's still `sync_generation`." It exists at ipc/mod.rs:211; the rename landed in 7eaa10a. - "`debug_assert!` wasn't added by 7eaa10a." It was; it's at ipc/mod.rs:215 (`git show 7eaa10a -- kernel/src/ipc/mod.rs` confirms). - "BSP source still has 'umbrix:' strings." `git ls-files | xargs grep -ni umbrix` returns empty; the rename in 5d7cc87 was complete. `cargo pkgid -p tyrne-bsp-qemu-virt` succeeds, so the CI `--exclude` argument is correct. Verification: 77 kernel + 34 test-hal = 111 host tests green; cargo fmt / host-clippy / kernel-clippy / kernel-build clean; YAML workflow parses cleanly. Refs: unsafe-policy §3, ADR-0021, R6 CI pipeline Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The Amendment block landed in d25a185 with "commit TBD" because the SHA is not known until commit time (chicken-and-egg). This follow-up replaces the placeholder with the actual SHA. Per the newly formalised policy (unsafe-policy.md §3, landed in d25a185 itself), this edit is permitted: the Amendment block's SHA slot is part of the block's required header, equivalent to filling in a dated form field. The Amendment's *content* (location, operation, invariants, rejected alternatives) is not touched. When future Amendments land, prefer writing the correct SHA on first landing by using `git commit --amend` after the commit goes in, or accept "TBD" and back-fill in a one-character follow-up like this one. Both patterns preserve the append-only story. Refs: unsafe-policy §3 Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
… 2026-05-08 + 2026-05-07 follow-ups Closes the 12 remaining items flagged by the 2026-05-08 multi-axis review's §Follow-up backlog (3 Track-2 Majors, 1 Track-3 Major fix already closed in `59c08e9`, 6 Track-3 / Track-2 Minors, 2 Track-4 Minors, 2 Track-2 Nits) plus the carry-forward 2026-05-07 Track-H NIT-1. **Track 2 Majors (forward-flagged → ADR-0027 / phase-b ledger riders):** - M1 (escape-hatch doc): ADR-0027 §Decision outcome (c) gains a bullet documenting `mem::forget` / `ManuallyDrop` / `let _ = ...` as deliberate-but-rare escape hatches, mirroring the `x86_64::structures::paging::MapperFlush` precedent. - M2 (MMU-instance binding): ADR-0027 §Decision outcome (c) gains a bullet noting `MapperFlush::flush(self, mmu: &impl Mmu)` accepts any `Mmu`; multi-`Mmu` deployments (B3+ per-task `AddressSpace`, Phase C multi-CPU) will need a stronger token type. Out of scope for v1. - M3 (ADR-0034 placeholder): ADR-0027 §Decision outcome adds an "ADR-0034 (kernel-image section permissions) placeholder" block alongside ADR-0033, and `phase-b.md` ADR ledger gains rows for both ADR-0033 and ADR-0034 with named-but-unallocated discipline. **Track 3 Minors (governance / wording polish):** - m1 + m2 (current.md L52): drop "Phase-2" prefix on "§Simulation table" (the table walks Steps 0–4, not a "Phase 2"); "Accept will be" → "Accept landed as" + actual commit SHA `bb0a6ba`. - m3 (commit-style.md PR-numbering rider): new §"PR-number references in committed artefacts" subsection naming the recurrence (PR #18 + PR #20 each had a one-commit PR-number fix-up) and codifying three acceptable disciplines (defer banner authoring; reference branch slug; or use commit SHA). - n1 (framing alignment): "first to apply Simulation forward" wording in current.md (banner + Active decisions row) and phase-b.md §B2 status block aligned to the precise "first non-recovery-primitive state-machine ADR drafted under §Simulation" phrasing — ADR-0032's Propose did land with a table; the prior framing was technically defensible only under a narrow reading of "retro-extracted". **Track 2 Nits (substance riders in ADR-0027):** - #4 (DSB ISH vs DSB NSH rationale): §Simulation gains a rationale paragraph after the table — `ISH` is forward-compatible with the eventual SMP boot, sub-microsecond cost on single-core, matches Linux aarch64 `arch/arm64/mm/proc.S` for the same reason. - #5 (TCR_EL1.AS wording tighten): line 59 reworded — `AS = 0` selects 8-bit ASID *size*, not "the ASID value is 0" (the value is `TTBR0_EL1.ASID = 0` and is what's "globally used in v1"). - #7 (line 17 §-citation precision) + Track-3 n1: "first non-recovery-primitive state-machine" framing now precise. - #8 (memory-management.md L88 page-table descriptor cosmetic): ASCII bit-field diagram redrawn to match L2 block-descriptor reality (OutputAddress[47:21], not [47:12]); explanatory note added for L1-block / L3-page variants. **Track 4 Minors (perf-harness.sh):** - #1 (Ctrl-C cleanup trap): new `cleanup_in_flight` shell function + `trap '...' EXIT INT TERM` that kills any in-flight QEMU + watchdog PIDs tracked in `CURRENT_CMD_PID` / `CURRENT_WATCHDOG_PID` shell globals. `run_with_timeout` updates the globals at every call so the trap addresses whichever pair is currently in flight; clears them at every clean exit so the trap is a no-op outside iterations. - #2 (p99 small-N reporting hygiene): generated baseline report Methodology section gains a "**Note on p99 at small `n`**" paragraph explaining that under nearest-rank `p99 == max` for `n < 100` and callers should not over-read it as a tail-latency signal until `n >= 100`. **Track 4 Nit #3 (read_stats refactor):** **Already closed by PR #21 review-round commit `ef30b5c`** — the 8 `echo | awk` parses became a single `while read` loop. Verified at HEAD (`grep -c "while read -r key val" tools/perf-harness.sh` → 1 hit). **2026-05-07 Track-H NIT-1 (Pending Amendment closure-path indexing):** UNSAFE-2026-0019 / 0020 / 0021 each gain a 2026-05-08 "closure-path indexed" Amendment naming the canonical clearance trigger (B5 Milestone, ADR-0030 entry-point, deadline-arming syscall) explicitly, so a future reader of `unsafe-log.md` alone has the full picture without leaving the file. No semantic change; co-locates information that was previously distributed across `phase-b.md` cross-references. Verification gates re-run on the integration branch: - `cargo fmt --all -- --check` clean - `cargo host-test` 159/159 (25 + 100 + 34) - `cargo host-clippy` clean (-D warnings) - `cargo kernel-clippy` clean - `cargo kernel-build` clean - `tools/perf-harness.sh --iterations=3` runs end-to-end with the new trap + Methodology note + while-read parsing intact This commit + the prior 2026-05-08 review's recommendations close all follow-ups identified by both 2026-05-07 and 2026-05-08 multi-axis reviews. Forward-flagged items (10/12/13 from 2026-05-07) and any review-round bot input on this integration branch remain the only open items. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…0036 (B5 review finding) The B5 syscall-boundary security review (this PR) re-surfaced the one finding actionable outside a phase gate: security-model.md §threat-model #7 + §Open questions still described QEMU `virt` as "launched with SMMUv3 and used in CI to catch driver misbehaviour" — a live contradiction with Accepted ADR-0036 (QEMU `virt` is GICv2 / no-IOMMU in v1; SMMUv3 is exposed only under an explicit `iommu=smmuv3` launch Tyrne does not use). It was N/A as a v1 *defect* (no bus-master driver exists, so the DMA boundary is inactive) but a stale doc claim, forward-flagged since the 2026-05-28 B4 closure. Reconciled conservatively: both sentences now state the v1 GICv2/no-IOMMU reality, point at ADR-0036, and reframe the SMMU-in-CI gate as a future IOMMU-equipped-target (Jetson Orin) item — preserving the model's IOMMU intent, correcting only the stale QEMU-`virt`-has-SMMUv3 claim. The review doc's §8 + forward-flags are updated to mark this RECONCILED (no longer carried forward). All other review forward-flags are correctly phase-deferred (B6 carry-forward gates / Phase-E fault containment / preemption-time ipc_send hardening / B5+ cap_map rights ADR) — no action now. Refs: ADR-0013, ADR-0036 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…estone B5) (#35) * docs(analysis): security-review B5-syscall-boundary Standalone consolidated security pass over the B5 syscall boundary (T-020 IpcError split + Capability/CapObject Debug redaction K3-9; T-021 EL0→EL1 SVC dispatch), merged via PR #34 (f98e1af). Performed with a fresh 8-axis checklist after the PR's three code-review rounds + the adversarial multi-agent pass. Verdict: **Approve.** All eight applicable axes pass (cryptography N/A). The dispatcher is panic-free on every register-supplied input; every object-naming syscall is capability-gated before any effect (console_write on the new debug-console cap, closing the ambient-authority slip caught before ADR Accept); copy-from/to-user never dereferences an unvalidated user pointer, with the soundness basis honestly recorded as the user/kernel disjointness invariant (an empirical Miri probe disproved an earlier "overlap-tolerant" over-claim — overlap is UB regardless of the copy primitive via the &mut/& borrow exclusivity); T-020's Debug redaction closes the K3-9 secrets-leak path exactly where B5 first creates a userspace-reachable log channel. Both new unsafe entries (UNSAFE-2026-0029 trampoline asm, UNSAFE-2026-0030 copy-user) are policy-conformant; 0029 carries the required second-reviewer sign-off. Gates: host-test 240, test --release green, miri --workspace clean (0 UB), QEMU +0x200 proxy round-trip byte-stable with no new fault class. B5 builds the boundary mechanism but the real EL0 +0x400 transition is B6; three B6 carry-forward gates (per-task console_write window + per-page translation; SP_EL1 init; SYSCALL_STUB_TABLE → current-task table) are tracked in phase-b.md §B6. This pass can serve as the security leg of the eventual B5 closure trio (business + performance legs deferred — "security review first"). Refs: ADR-0013, ADR-0030, ADR-0031, ADR-0014 Security-Review: @cemililik (+ Claude Opus 4.8 agent) Audit: UNSAFE-2026-0029, UNSAFE-2026-0030 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * docs(analysis): reconcile security-model.md SMMUv3-CI claim with ADR-0036 (B5 review finding) The B5 syscall-boundary security review (this PR) re-surfaced the one finding actionable outside a phase gate: security-model.md §threat-model #7 + §Open questions still described QEMU `virt` as "launched with SMMUv3 and used in CI to catch driver misbehaviour" — a live contradiction with Accepted ADR-0036 (QEMU `virt` is GICv2 / no-IOMMU in v1; SMMUv3 is exposed only under an explicit `iommu=smmuv3` launch Tyrne does not use). It was N/A as a v1 *defect* (no bus-master driver exists, so the DMA boundary is inactive) but a stale doc claim, forward-flagged since the 2026-05-28 B4 closure. Reconciled conservatively: both sentences now state the v1 GICv2/no-IOMMU reality, point at ADR-0036, and reframe the SMMU-in-CI gate as a future IOMMU-equipped-target (Jetson Orin) item — preserving the model's IOMMU intent, correcting only the stale QEMU-`virt`-has-SMMUv3 claim. The review doc's §8 + forward-flags are updated to mark this RECONCILED (no longer carried forward). All other review forward-flags are correctly phase-deferred (B6 carry-forward gates / Phase-E fault containment / preemption-time ipc_send hardening / B5+ cap_map rights ADR) — no action now. Refs: ADR-0013, ADR-0036 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * docs(analysis): performance-review B5-closure B5 closure performance baseline — the performance leg of the B5 syscall-boundary closure trio. Re-baseline of kernel footprint + boot-to-end timing after T-020 + T-021 (PR #34, f98e1af) versus the 2026-05-28 B4 closure baseline. Footprint (release): .text 34,648 (+1,524) / .rodata 4,856 (+296) / .bss 50,592 (+2,272) = ~88.0 KiB (+4.76 %) — the smallest non-refactor .text growth in Phase B (the syscall boundary is a thin validator/dispatch layer). Tests 339 (43 hal + 240 kernel + 53 test-hal + 3 doc; +53 kernel), miri clean (0 UB, run locally). Release harness band p10/p50/p90 = 17.645 / 20.300 / 24.706 ms. Verdict: baseline, no proposal. The cycle's decisive measurement was a same-host back-to-back control (the B4 binary 3ab029f rebuilt + re-measured this session): it proves the ~+2.9 ms p10/p50 delta vs B4 is REAL B5 code (the boot SVC-smoke — 2 exception round-trips + cold TCG translation), not host jitter, correcting an initial mis-read of the noisier raw band. One-time-at-boot, ~us on real hardware. The control also shows the QEMU-TCG harness is nearing its resolving floor for small milestones (per-milestone signal ~ session jitter). Adds the harness report docs/analysis/reports/perf-baseline-2026-05-29-B5-closure.md and the README index row. Refs: ADR-0013, ADR-0030, ADR-0031 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * docs(roadmap): business-review B5-closure B5 closure retrospective — the business leg of the B5 syscall-boundary closure trio — plus the roadmap forward motion it drives. Formally closes Milestone B5 (Syscall boundary): T-020 (IpcError taxonomy split + Capability/CapObject Debug redaction) + T-021 (EL0 to EL1 SVC dispatch) merged via PR #34 (f98e1af); ADR-0030 + ADR-0031 Accepted. What landed (canonical metrics, reproduced live at afeed10): 339 host tests (+53 kernel) incl. local miri 0 UB; release ELF ~88.0 KiB (+4.76 % vs B4); release smoke clean to "all tasks complete" (the release trace itself proves the console_write debug-gate — status=0x1 in release); the debug smoke shows the full console_write SVC round-trip (status=0x0, bytes=63); -d = 712/776 PL011 + 2 expected SVC exceptions (EL1 to EL1, ESR 0x15, clean ERET), zero new fault class; audit log 30 entries (29 Active) — UNSAFE-2026-0029/0030. What we learned: the pure-Rust (T-020) / hardware-boundary (T-021) split per CLAUDE.md section 6 let the most security-sensitive milestone land safely in one calendar day without skipping rigor; an adversarial pass + Miri corrected a real copy-user soundness over-claim (disjointness, not the copy primitive, is the basis); a same-host perf control corrected a host-jitter mis-attribution; ABI front-loading kept the syscall numbers a decision, not an accident. Side-effects: current.md banner + Pathfinder flipped to B5-closed / B6-next; phase-b.md section B5 status -> Closed; test-count drift (236/240 mid-arc -> live 339) reconciled; business-reviews README index row added. Next: B6 (first userspace "hello") — the deferred task_create_from_image bridge + the 3 T-021 carry-forward gates + the ADR-0033 high-half opening; B6's review is the Phase B retrospective. Refs: ADR-0013, ADR-0030, ADR-0031, ADR-0017, ADR-0033 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * docs(roadmap): pre-B6 prep — reconcile B5-done status + B6 opening sequence Pre-B6 documentation preparation on the B5-closure branch (rides in PR #35), done before B6 development starts on its own branch off main. Docs-only. (1) B5-done status reconcile (drift sweep). With B5 closed, several live docs still treated the syscall boundary as future/next: - CLAUDE.md: "the syscall ABI and first userspace task are next" -> the syscall boundary is done; the first EL0 task is next. - README.md status table: "Syscall ABI + EL0 entry | Next - Phase B5" -> split into "Syscall ABI + dispatcher = Done (B5)" + "First userspace hello (EL0) = Next (B6)". - phase-b ADR ledger: ADR-0030 / ADR-0031 marked Accepted 2026-05-29; ADR-0033 / ADR-0034 triggers corrected from B5/B5+ to B6 (B5 closed via the SVC proxy without surfacing the per-task TTBR0 swap, so the trigger is now B6). - architecture docs (task-loader / memory-management / boot): "ADR-0033 gated on B5 surfacing per-task TTBR0 swap" -> B6, and "until B5 adds a per-task context surface" -> B6 — these would have misled a B6 dev about which milestone owns the EL0 context + high-half work. (2) B6 opening sequence & prerequisites — the careful B6 plan, made durable in phase-b.md section B6. States the gating prerequisite (the kernel must stay reachable from every task's active translation, else an EL0 SVC vector fetch translation-faults), the ADRs that open B6 (ADR-0033 kernel-in-every-AS + the EL0-task-context decision + optional ADR-0034), and the dependency-ordered task sequence: ADR-0033 impl -> EL0 context -> task_create_from_image -> the 3 T-021 carry-forward gates -> tyrne-user + userland/hello -> wire-up + EL0 round-trip smoke -> Phase B retrospective. Decisions remain open for their ADRs; this fixes only the order + rationale. All links resolve; docs-only, no kernel changes. Refs: ADR-0013, ADR-0027, ADR-0030, ADR-0031, ADR-0033 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * docs: PR #35 review-round — fix assert quote, ADR-0033 link, ADR-0034 table pipe Three review findings on the B5 closure docs, each verified against the source: - abi.rs assert quote (security review section 1): the doc quoted assert!(NULL_CAP_HANDLE > ((u32::MAX << 16) | u16::MAX)) but the actual abi.rs:42 uses `as u64` casts — (((u32::MAX as u64) << 16) | (u16::MAX as u64)) (without them the shift overflows in u32 arithmetic). Quote corrected to match. - ADR-0033 link (security review section 8): the label said "ADR-0033" but the link targeted 0027-kernel-virtual-memory-layout.md (a mismatch). ADR-0033 (high-half migration) is genuinely the right concept — 0027 only reserves the slot — so rather than relabel to ADR-0027 (which would misattribute high-half to 0027), ADR-0033 is now plain text (matching the unlinked ADR-0034 in the same sentence) with a correctly-labeled "reserved in ADR-0027" cross-reference. - ADR-0034 ledger row (phase-b.md): the inline code USER|EXECUTE (introduced in the pre-B6 prep commit) had an unescaped pipe, splitting the table row into five columns; escaped to USER\|EXECUTE. All 14 ledger rows now have 4 columns. Validated: assert quote matches abi.rs:42 verbatim; all links resolve; every ADR-ledger row is well-formed (5 delimiters = 4 columns). Docs-only. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
No description provided.