D629 - A module handle now narrows the answer, for one handle

Status: measured Date: 2026-09-08

The loudest defect on the differential

900-surface/control is obSCEne saying a symbol that does not exist reported present; every count in this section is meaningless - a defect that reports its own blast radius over ninety-nine census entries (D622). Behind it is a divergence already on record: sceKernelDlsym looks a name up in one flat table and never consults the module handle it was given, so libkernel answers for memcpy, which the console refuses with 0x8002_0003.

The record said the fix needed "a per-module export list for the platform's own libraries", which this project does not have and must not invent. That was half right. It does not know what the console's libkernel exports; it does know what it itself declares in libkernel, and that is enough to correct a wrong success without inventing a refusal.

Narrowed only downward, and only where it can be

Three conditions, all required:

Everything else is untouched. A name nothing has a library for still resolves - "nobody said" must never become "this module does not export it". A name only the guest's own binary exports still resolves, because PPSA02664 asks for its own scriptingGetMem through this call (D517) and breaking a working path to fix a different one is not a fix. Every other handle still resolves anything.

So the change can turn a wrong success into the measured refusal, and cannot turn a working resolution into a failure on a guess.

The whole libkernel family counts. libkernel_fs and libkernel_sync_on_address are this project's own subdivisions of one console library - sceKernelWrite is in the second and the console exports it from the first - so treating them as separate modules would invent a divergence rather than repair one.

Published by the service, because no one crate knows

The three declarations live in three crates that must not reach sideways for each other (D536), and orbistoun-kernel cannot ask orbistoun-service for anything. So the service publishes the set into orbistoun-thunk beside the by-name stubs it already publishes there, and the kernel reads it. name_is_libkernel returns Option<bool>: None and Some(true) are different states and both mean do not refuse, because a list nobody installed is silence.

Built once, because sceKernelDlsym is the busiest call in the corpus - three hundred thousand in one payload run - and consulting a knowledge base per call would be a sink that changes the program it observes (principle 9).

What it does not do, said plainly

110-modules/symbol is unchanged by this. That check does not use handle 0x2001: it walks a list of module paths calling sceKernelLoadStartModule and asks whichever handle first succeeds, which under orbistoun is an /app0 handle counting from 0x40 - every firmware path is refused with ENOENT. So the measurement that motivated this still reports 0x0.

The narrowing is right, and it is right for a handle that check does not exercise. Making it cover an /app0 handle would mean deciding what a title's own module exports, which orbistoun knows only for the executable, and would risk refusing the resolution path the payload makes three hundred thousand calls through. Not attempted on that evidence.

dlsym_divergence.rs is rewritten to what now holds, and it asserts three states rather than one: inert before a list is published, the console's 0x8002_0003 with nothing written after it, and a libkernel-declared name still passing through. The third exists because a guard that refused everything would satisfy the second.