Where it stands

Behavioural checks 501 - 82 spec, 44 derived, 2 implementations, 368 assumed, 2 documented, 3 hardware
Census symbols 39493 across 372 libraries
Sections 53
Imports placed by the manifest 311

Loaders that run the whole suite: five. shadPS4, PS5PCEM, fpPS4 and Kyty all reach the end record, and so does prosper, which is headless and opens no window at all. Two of the five need a local patch to get there and their reports are quarantined accordingly (D176): Kyty's unresolved-import trampoline called EXIT, and fpPS4's called Sleep(INFINITE) (D196).

This line previously read "shadPS4 (the full suite), Kyty (loads and relocates; names the imports it lacks), craziiEmu (loads; resolves nothing yet)" and had been true months earlier. craziiEmu was superseded by PS5PCEM and prosper; nothing struck the sentence.

The table above is generated by obscene-tool counts from the source, and verify.sh fails if it has drifted. Every number in it was wrong at least once when it was hand-written.

The number that matters most is the zero, and the ranking below follows from it. Every expectation here is either settled by a public document or is this project's own guess, and an emulator built to satisfy the guesses has only been made to agree with us.

The ranking changed, and the old one was wrong

§10 used to be first: 4,459 census names, mechanically addable. That is the largest number available and close to the least valuable, for three reasons worth keeping.

An emulator author already has that list, for free and complete. Their own stub log says exactly which symbols they have not implemented. A census tells them something they can generate perfectly themselves.

It would swamp the report. 4,800 presence records against 106 behavioural checks is a report that is 98% inventory, and the headline coverage ratio would improve while the ability to find a bug did not change at all.

Presence is not even a clean measurement. shadPS4 resolves everything through a generic stub, so all 312 already report present while roughly forty per cent behave. The census measures the loader's stubbing policy as much as the platform.

The census's real justification is static - knowing what a title will need before it needs it - which argues for ranking names by how often they appear in real import tables, not for exhaustiveness.

Ranked

Refreshed after the blind prober reached the end of the corpus and a three-way consensus found a bug in this project rather than in an emulator. Four of the previous eight are done, and the shape of what is left has changed: the cheap oracle-free work is spent, and almost everything remaining is either machine time or blocked behind struct layouts.

Item Why here
1 The provenance ladder has no rung for "independent implementations agree" (D166) It has now cost something twice. 015-sync/event-flag-round-trip claimed DOCUMENTED and was backwards; corrected, what supports it is two open-source implementations agreeing, which is real evidence the ladder cannot express. ASSUMED understates it, DOCUMENTED overstates it, and overstating is what went wrong. The sibling project raised the same gap on the measurement axis and we declined it - that decision looks less obviously right now
2 Behaviour described in prose has no gate doccheck verifies that referenced things exist, never that described behaviour is current. PROTOCOL.md spent part of a day describing a loopback bind that had been reverted from the code, and only got caught by accident. Third instance of the house failure - a mechanism saying something reasonable while being wrong (D158, D163, this)
3 §1 current generation, blind-called - in flight The census has 89 libSceAgc* names and §1's own honest limit was "nothing here is called". The prober calls every censused symbol, and it had only ever run against a previous-generation loader: all 118 AGC symbols that answered under shadPS4 returned zero, which measures a PS4 emulator stubbing a PS5 interface. The run against PS5PCEM is the first time these are called on a loader that implements any of them
4 §12 consensus, four-way Three-way already found D166. fpPS4 is the missing fourth and its last report is invalid - a concurrent build overwrote the tree mid-run. Cheap to redo and it widens the majority that made D166 legible
5 FreeBSD provenance About nine checks, not fifty. Measured below. Reading, not research
6 §6c thread-churn threshold Knob exists; ~20 runs per point. Pure machine time, no judgement - the best thing to leave running unattended
7 §7 census cannot detect a lying platform Presence is self-reported. Largely answered by the runtime module census (D157) and quantified by the prober: 96.4% of 32,275 blind calls return zero, and 282 of 342 libraries never refuse anything. The entry predates both and needs closing against them rather than working on
8 §2 struct layouts Not last because it is unimportant - it is the opposite. Everything left in §11, the equeue ordering relation, mapping isolation, directory listings and the whole of §1's behavioural half sit behind it. It is last because this project will not guess a layout (D008) and nothing short of hardware or a confirmed public definition unblocks it
9 §10 census expansion Deliberately last. See above

Done since the last ranking, and struck from it:

Worth stating rather than quietly renumbering, because the entry would have sent somebody at a week of reading for an afternoon of it. Two more looked like analogues by name and are not: sceKernelReadTsc is not read(2) and sceKernelPollEventFlag is not poll(2). A prefix is not a provenance.

Struck in an earlier pass, kept because the reasons still hold: the tooling port (seventeen Python scripts became obscene-tool subcommands, and every checker ported was found miscounting something); N-way consensus, blocked on "needs a second reporting loader" and now having four; current-generation graphics, blocked on "a whole layer absent" until PS5PCEM ran a GEN=5 module to completion; and condition variables and barriers, now four checks.

Not on the list because they need something this project cannot supply: a Steam Deck run (make deck builds, no hardware has run it) and the hardware run (0 hardware confirmations, which is the number that limits every claim in the report).

Items 5, 6 and 7 worked, 2026-08-26 - and two of the three were not what the entry said

Item 5 (FreeBSD provenance) is four checks, not nine. The entry had already been corrected once, from 44 to "roughly nine". Reading the nine settles it at four:

check outcome
040-file/open-rejects-missing derived - FreeBSD open(2) gives ENOENT for a path that is not there
020-memory/unmap derived - munmap(2) returns 0 for a valid mapping
020-memory/unmap-rejects-null derived, on FreeBSD's page and not POSIX's - see below
015-sync/mutexattr-round-trip derived - POSIX settles set-then-get on a mutex attribute
040-file/open-rejects-null stays assumed: a null pointer is undefined in POSIX. FreeBSD's EFAULT is an implementation detail, not a specification
120-measure/sleep-fidelity stays assumed, and its own comment always said so: "Both bounds are this project's, not a document's"
140-oracle/error-codes stays assumed: it asserts nothing. "No expectation is asserted here at all. It records what came back." Provenance describes an expectation; a measurement has none
015-sync/mutex-recursion stays assumed: it probes which numeric type value is recursive, and POSIX fixes the names, not the numbers
017-posix/spellings-agree stays assumed: self-consistency. "Nothing here asks for a particular answer" - no external document can raise it

unmap-rejects-null is the one worth reading twice. POSIX contradicts this check: unmapping an unmapped range "has no effect" and returns 0, so by POSIX the expectation is backwards. FreeBSD returns EINVAL when part of the region is outside the valid address space, and the kernel here derives from FreeBSD - which is exactly what the derived rung means, and exactly why it is a different rung from spec.

The entry's own warning applied to itself: "A prefix is not a provenance." Neither is a plausible-looking analogue. Five of nine had no document behind them at all.

Item 6 (thread-churn threshold) was not blocked on machine time. scripts/repeat.sh still drove multipass and could not run at all; four other scripts were dead the same way (D199). Now portable. What the entry says about the measurement still stands - separating "crashes above N" from "crashes at any N" needs roughly 200 runs a point - but the cost of a run has changed underneath it: the sweep deadlock in D194 meant every run took minutes, and shadPS4 now completes in 13 seconds. Two hundred runs a point is about 45 minutes, not an afternoon. Worth revisiting on economics, still not started.

Item 7 (the census cannot detect a lying platform) is done and can be struck. The entry already says "needs closing against them rather than working on". 900-surface/presence-is-not-behaviour exists, never returns pass, and escalates its wording correctly across all five loaders that now complete the suite:

loader what it says
PS5PCEM "nothing was probed for behaviour, so this census says only which symbols resolve"
shadPS4, fpPS4, Kyty "most probed functions are stubs; read this census as an upper bound, not a coverage figure"
prosper "presence is not behaviour…"

And prosper is the entry's hypothetical made real: it links all 35,518 imports as stub slots, resolves both generations' exclusive symbols for free, and scores the highest pass count of any loader partly because returning zero is often the right answer. The section was written against exactly this platform before one existed to test it on.

The previous ranking, kept so the change above is checkable

Superseded. Do not read a number out of this table - two of them are known wrong and are left standing because correcting a historical record makes it stop being one. §11 said ten relational checks and there are now seventeen; the FreeBSD row said 44 assumed checks settleable by a man page, and the measurement above puts it near nine.

It lost its header row at some point and rendered as a broken table, which is how it went unread long enough to keep two stale figures beside a current list.

rank item why
1 §11 relational checks - ten in 018-relational, more available Oracle-free, needs no struct layout and no documented error code. Routes around §2 and §5 rather than waiting on them
2 §12 N-way consensus - obscene-tool consensus exists; needs a second reporting loader Turns "you failed X" into "you are the only one of four that fails X". Actionable without authority
3 FreeBSD provenance (task #14) 44 assumed checks, many settled by a public man page. Reading, not research
4 §1 current-generation graphics A whole layer absent
5 §6d condvars and barriers Now unblocked: the timed lock calls take a timeout
6 §7 census cannot detect a lying platform Presence is self-reported
7 §6c thread-churn threshold Knob exists; needs ~20 runs per point
8 §10 census expansion Deliberately last. See above