libScePosix, and a check that killed the process on the host

The gap analysis said obSCEne did not touch libScePosix at all - a whole library exporting POSIX under a posix_ prefix, 64 symbols, none of them named here. It is the best provenance available without a console, because POSIX settles what these do: a check written against them is answerable from a document rather than from this project's own reasoning (D057).

That matters more than coverage. Fifty-three checks here are assumed and none is hardware, and an emulator implemented to satisfy an assumed check has only been made to agree with us - both wrong together, with a green report saying otherwise. The authority for a spec check sits outside both projects, which is the only thing that breaks the circle before hardware does.

Five checks in 017-posix: page size, signal sets, a short sleep, the try-form read/write lock, and the one this section exists for.

The comparison check

scePthreadRwlockTryrdlock and posix_pthread_rwlock_tryrdlock should be one implementation behind two names. 017-posix/spellings-agree calls both and reports when they differ.

It is the only check in the suite whose expectation comes from the platform rather than from a document. It asks for self-consistency, not for a particular answer - a divergence is a fault whatever the right answer turns out to be, and each path passes its own checks while it happens. Marked assumed, because no document says the two libraries must be one implementation.

It segfaulted, and everything caught it correctly

First run on the host: segmentation fault, process gone. The try record with no res named the check exactly (D058).

The harness skips a check whose declared symbol is null, because jumping to zero ends the run. That guard covers the one symbol in the check's table row and nothing else the body reaches for. This check calls two libraries by design, and on the host the vendor spelling has no stub - so scePthreadRwlockInit was null and the check walked into it.

Two things worked exactly as designed and are worth naming.

The announce-before-attempting invariant identified it precisely rather than saying "somewhere in this run". Third time it has paid for itself.

It happened on the host build. A null vendor symbol is normal on an ordinary machine and unusual under an emulator, so the host met it first - which is the entire argument for having a host build. Under an emulator this would have surfaced as an intermittent crash in a section that usually works.

The rule is now in CLAUDE.md rather than in anyone's memory: a check that reaches outside its own table row is responsible for the addresses it reaches for.

Two smaller corrections

The section was numbered 030-posix, which both collided with 030-thread and sat out of order after 015-sync. The report's own self-check caught it - sections must ascend, and it listed them to prove they did not. Renumbered 017-posix, which is also where it belongs: after the vendor locks it compares against. Free to rename because nothing had ever shipped with the old identifier.

A comment claimed posix_usleep was the only deliberately-blocking call in the suite. 050-time/usleep already does the same thing. Corrected, and the note now points out that sceKernelUsleep is the vendor spelling of the same call - another comparison candidate, deliberately not taken, because two sleeps both returning zero would agree without either having slept.

The rest of the library is censused

Fifty-one symbols. Every one takes a timespec, a sigaction, a sockaddr or an mmap argument, and a wrong layout produces a call that succeeds and does the wrong thing (D008). Presence is the honest claim, and not a small one: this library is a second implementation path onto the same kernel, so which half of it an emulator has bothered with is worth knowing.

The signal-set checks show the layout rule can be worked around rather than broken. A sigset_t is opaque and differently sized per system, so the pointer is declared void *

Census is now 311 symbols across 15 libraries.

The comparison check found something on its first run

Under shadPS4 0.18.0:

015-sync/rwlock            pass    the vendor spelling refuses a writer while readers hold it
017-posix/rwlock           fail    the POSIX spelling lets one in
017-posix/spellings-agree  fail    the two spellings disagree about admitting a writer

Two entry points onto what should be one implementation, disagreeing about the one property a read/write lock exists to have. The vendor path passes its own check in isolation and would have gone on passing it; nothing else in this program could have seen this.

That is the argument for the section, made on the first run rather than in theory.

The rest of the section reads as stubs, and the responsiveness reasoning applies: posix_getpagesize returns 0, and posix_sigaddset reports success and does not add the signal. Both are "not implemented" rather than "implemented wrongly".

posix_usleep passes, and a stub would pass it too - which is worth stating because it is the same defect D056 found elsewhere. It is documented in the check rather than fixed, because both fixes available are worse: a responsiveness probe would compare two return values that are both zero when the function is correct, and a clock comparison would need a time source counting something other than process time, which a sleeping thread may legitimately not accrue. A pass there means "accepted a valid request and reported success", and the value is in the fail.

State

639 records, complete. 62 pass, 5 partial, 38 fail, 7 skip. 313 census symbols, every one present - including all 51 of libScePosix, which shadPS4 resolves in full while implementing almost none of it. The gap between those two numbers is the whole reason the census and the checks are separate things.

A note on process. The sweep that produced these numbers was started while files were still being edited, and that was flagged as untrustworthy at the time. A clean run afterwards reproduced 639 records and the same three rounds exactly. The caution was right and the result happened to survive it.