D578 - The random devices, and a record of what a guest actually opened
Status: measured Date: 2026-09-07
Two gaps, and they turned out to be one question
orbistoun-fs records every path it could not answer and
calls that the filesystem's most useful output (D387). It is -
and it only names what was missing. PPSA03416 opened
what it asked for, performed one file read of zero
bytes against a title directory holding four hundred megabytes
of assets, and the only visible evidence was four paths it probed and
did not find. All four are the archive layout this title does not use,
so all four were red herrings, and what it did open was
recorded nowhere (D576, D577).
So the two asks are the same ask: serve the devices a guest names, and record what it got.
The random devices earn their place on an argument, not on demand
device.rs keeps a deliberately short list, because a
device that answers plausibly is worse than one that is absent - the
guest cannot tell. Its own note put /dev/random on the
wrong side of that line, and the argument that moves it is specific:
A random device's contract is that its bytes carry no
meaning. There is no layout to invent and no vendor semantics
to guess, which is exactly what disqualifies most candidates. It can be
served without inventing anything, which /dev/null and the
rest still cannot claim.
Both names, one device, and it never blocks - FreeBSD's own arrangement, and the target kernel is FreeBSD-derived, so that is a citable shape rather than a preference.
What it hands back is deterministic, and that is the
emulator's trade rather than the device's shortcut. Every
measurement here rests on two runs of one build behaving identically
(D181, D238); a guest seeded from a physically random source takes a
different path each time and the difference between two runs stops
meaning anything. std::random_device has answered on that
reasoning since it was implemented. The generator moved to
orbistoun_core::entropy so both draw from one pool, as two
readers of one kernel pool would, instead of from two copies that
drift.
A guest doing cryptography against this is not getting cryptography. Nothing observed does. If something starts to, that is a decision to take then rather than a property to rely on quietly now - which is why it is written here and in the module rather than left for a reader to find.
A write is refused. On FreeBSD it stirs the pool; this pool is a fixed sequence with nothing to stir, and accepting the write would claim an effect that does not happen.
The record is off by default, and the failures are not
wanted records unconditionally because failures are rare
and an ordinary run pays nothing. Successes are the common case - a
title streaming assets opens hundreds - and a lock and a string for
each, on the guest's own stack, is an observation heavy enough to change
what it observes (principle 9). So it is gated on
ORBISTOUN_TRACE_OPENS and an ordinary run pays one atomic
load.
It is declared a setting rather than a diagnostic,
and the distinction is the one the two axes exist for: a diagnostic
changes the program in order to learn from the difference, and a verdict
under one carries a caveat. This changes what is reported. The
guest cannot tell it is on, so it earns no caveat and poisons no record
- the same place ORBISTOUN_FINDINGS sits.
Recorded on the guest's stack, printed after the guest has stopped,
capped at 256 distinct paths: the same three rules wanted
follows, for the same reasons (D381).
An empty list and a list nobody asked for are different findings, so a run that was recording and opened nothing says so in words rather than printing nothing.
What it said the first time it ran
orbistoun: the guest opened 5 paths:
/app0/Media/Metadata/global-metadata.dat
/app0/Media/boot.config
/app0/Media/globalgamemanagers
/app0/debug.log
/dev/urandom
This overturns the reading in D576. That entry
inferred, from the four missing probes, that the guest never reached the
loose-file layout. It reaches it: globalgamemanagers is the
loose layout's entry point and the guest opens it, along with the IL2CPP
metadata and the boot config. The four missing paths were never the
problem, and only a record of the successes could show it.
/dev/urandom is opened by both PPSA03416 and PPSA02664
on the first run after it existed, which is as direct a confirmation as
the gap being real gets.
Both titles moved: PPSA02664 197 to 198 imports, PPSA03416 192 to 193.
What this does not establish
Corrected by D595: the read was not zero bytes. It
was four hundred and two, complete, of boot.config -
0 KiB is what integer division makes of that. The guest
opening globalgamemanagers and never reading it through the
descriptor is what survives, and it is measured per read now rather than
read off a rounded summary.
Why five opens produce one read. That is the question the record was built to expose and it is now exposed rather than answered. The next measurement is which of those five the guest read from and what it did with the bytes.
Nor anything about a run that ends on the budget or the
clock. Both call std::process::exit directly, so
such a run prints no filesystem or syscall report at all - not this one,
not paths_wanted, not syscalls_asked_for. That
is pre-existing and it is why PPSA25872 shows nothing here. Fixing it
means reporting from a watchdog thread while the guest is still running
and may hold the very locks being read, which is a hazard worth its own
entry rather than a line added in passing.
Nor that the deterministic stream is enough. It is enough for a guest that seeds a generator or salts a hash, which is all anything observed does. A title that checks its randomness for statistical quality, or one that relies on two runs differing, would find neither - and would be right to.