Repository navigation
PRAGMATA (PPSA02530): SaveData Prepare/Commit no-ops, ignored Json2 settings and unsupported UDS statistics #8005
Description
Scope and current status
This tracks library-contract gaps and focused fixes identified while auditing PRAGMATA, PPSA02530, version 01.200.000. Source and PR states were checked on 2026-10-21, against main 27bcd6a29e2f. Recheck the relevant implementation and open PR before starting a patch.
The complete historical audit preserves the previous description unchanged, including source revisions, input hashes, NIDs, caller evidence, parser/probe results and inventory. Its original 922 import records are an accounting boundary, not a compatibility score. Historical statements and PR states in that archive are not current assertions.
This issue does not establish the cause of the game's FPS, memory or shader problems in #6582. Imports and static callers do not prove execution; component probes do not establish gameplay or PS5 equivalence.
Work items
IDs are retained so existing references remain usable. A confirmed gap is not a complete replacement specification.
| ID | Area | Current state | Next action / ownership |
|---|---|---|---|
| C1 | Heap trace table capacity | Fixed: merged #8049 | 65-slot backing storage and slot-0/64 regression; title reachability remains unproved. |
| C2 | Json2 allocator, settings and recovery callbacks | Contract/reference needed | Establish callback ABI, ownership/lifetime and float-mode behavior; test observable allocator/recovery calls. C9 is separate. |
| C3 | UDS statistics and extraction rules | Unsupported shapes documented | Select one aggregation/type/condition family and establish its update/reset/error semantics before implementation. |
| C4 | SaveData transactions | Unimplemented protocol | Specify resource ownership, modes, mount association, durability/rollback and failures; no mode-3-only workaround. |
| C5 | SaveData icon persistence | Open fix #8630 | Buffer persistence and mounted-path tests are covered there; PS5 image validation/error precedence remain unmeasured. |
| C6 | Audio/media controls | Partial implementations; split by API | ACM commands, AudioOut2 attributes/mastering and AvPlayer configuration need separate contracts and behavioral tests. |
| C7 | VideoOut latency and VRR | Contract/event semantics needed | Establish the wait-block fields and event producers. Open #7814 owns output-resolution reporting. |
| C8 | PSML reconstruction / NP signaling lookup | Missing behavior/ABI | Treat these as separate fixes. PSML query helpers have improved; MFSR1100 packet generation remains unsupported. |
| C9 | Json2 parse/insertion allocation ownership | Open fix #8530 | Parser/missing-key cleanup and allocation-failure regression; does not implement C2 settings or callbacks. |
| C10 | SSL context-owned connection lifetime | Open fix #8541 | Remove orphan records while preserving in-flight ownership and the existing post-Term invalid-ID behavior. |
Remaining evidence and useful entry points
Library paths below are relative to core/libs/prx/. The archive contains the detailed original caller locations and input identities. Public regressions should use synthetic data rather than proprietary title assets.
C2: Json2 configuration and recovery
The title supplies a real non-null allocator, null user data, file-buffer size 0x4000 and special-float mode 2. These are concrete non-default inputs, not an inference from imports alone. Main's setters and initializer store the settings but initialization does not apply them. Host allocations do not dispatch the supplied allocator.
Registered element-access-failure and special-float handlers are not invoked on the corresponding refusal paths; type-mismatch and global null-access callbacks do run in supported cases. Establish the PS5 callback arguments, lifetimes and float-mode meanings before changing this behavior. Successful registration is not callback coverage. Extend core/libs/tests/GuestJson.cpp with observable callback/allocator effects and failure cleanup. Open #7215 concerns numeric locale, not these contracts.
C3: UDS statistics/rules, distinct from direct trophy unlocks
The original exact-package probe accepted 0/53 statistic definitions and 0/59 extraction rules. Unsupported families include count, collection, eachLatest, enum/set types and property conditions; main's definition/rule readers still accept only the narrower latest/unsigned-statistic and event-name-only model. These package counts are historical probe results, not a new run against current main.
The separate direct _UnlockTrophy recognizer accepted 35/35 synthetic non-platinum IDs. That does not prove actual title event emission, persistence or platinum completion; unsupported statistics must not be described as proof that all trophies fail. The packages contain no progressive trophies or extraction rules for _UpdateTrophyProgress.
Start with synthetic package/rule fixtures in core/libs/tests/GuestNpTrophyStats.cpp. For example, {"statDefinitionArray":[{"statId":1,"dataType":"uint64","aggregation":"count"}]} captures one rejected shape. Establish repeated-event, reset, range and conversion semantics independently; preserve supported latest-statistic and direct-unlock behavior.
C4: SaveData transaction protocol
CreateTransactionResource/Commit return a synthetic identifier/success without a transaction object or commit operation. Prepare ignores the mount and parameter block. Static title callers supply a resource and mode, then inspect the return status; they do not prove a save session executed.
Establish the general resource/mode/lifetime, persistence and failure transitions before implementing them. Mount3's transaction association and cancellation/rollback belong to that contract. No save corruption or data loss was demonstrated. Icon persistence C5 is a separate change; merged null validation #7785 and block accounting #7960 do not implement transactions.
C6: audio/media controls
The audit found real decode, mix and playback. Remaining observations concern ACM commands/waits, AudioOut2 attributes/mastering and ignored AvPlayer InitEx/PostInit settings. Exact title inputs and boundaries are archived; no audible-output or codec-equivalence measurement was made.
Entry points: libSceAcm/Export.cpp, libSceAudioOut, libSceAvPlayer/src/Player.cpp. Establish each control's meaning and test data/state effects. Merged #7789 covers AJM ownership, #7567 ACM validation and #7680 the first paused picture. Open #7064/#7412/#7622 concern priority/stream-info/worker-state changes; compare before overlapping work. AudioOut2 construction cleanup remains an unvalidated candidate.
C7: VideoOut latency and VRR
The title prepares a 32-byte wait block and marker data, while main's WaitBeforeInput/SetStartPoint validate the handle without performing the corresponding wait/measurement. The block's general ABI and field meanings remain unresolved. VRR registration has bookkeeping, but the audited driver had no transition producer; the status extension was zero-filled. Establish producer/order semantics before adding synthetic event success.
Keep working flip submission, pacing, mode cadence and existing events intact. Open #7814 owns resolution reporting. No GPU latency or PRAGMATA frame-rate effect was measured by this audit.
C8: PSML and signaling
PSML: the old claim that the packet-size query always throws is superseded. Main's query takes a context/output pointer, validates them and writes 0x600 DWORDs. Current debt identifies its APR-EMU reference and unresolved packet semantics. The 1100 requirement/context/dispatch paths still refuse after initialization; a working size query is not reconstruction support.
The inspected title setup and one producer are gated by Trinity/requested-option/availability state. Main reports non-Trinity, blocking those demonstrated chains. This is not a global proof of unreachability and not evidence of a normal-mode startup blocker. Establish layouts, generated packets and actual reachability before implementing the missing APIs.
Signaling: sceNpSessionSignalingGetGroupFromSessionId still throws and has no established input/output ABI. A static direct call does not prove execution while signed out. Establish arguments, outputs and signed-out errors before selecting lookup behavior.
Fixes already under review
- C9 / fix(json2): release partial entries on allocation failure #8530:
[1]plus allocation failure can leak a node before list ownership; object parsing/insertion have related losses.JsonCopyFailure.cppadds failure cleanup and old-value/entry/handler checks. Probe details are archived; no title OOM cause is established. - C10 / fix(ssl): release connections when their context terminates #8541: three original no-network Init/Create/Term/Delete cycles retained 1/2/3 records. The PR tests both cleanup orders, context isolation, concurrency and in-flight ownership. Preserve post-Term invalid-ID behavior; title TLS-session/pool retention was not measured.
- C5 / fix(savedata): persist native save icons #8630: mounted
sce_sys/icon0.pngpersistence, bounded copies/size reporting and read-only rejection have public regressions. PS5 image validation/error precedence and general guest file-write enforcement remain separate.
Adjacent fixes and open ownership
Keep these links as a concise ownership guide; full patch evidence and test results belong in the individual PRs.
- Merged: fix(libc): back every native mspace trace slot #8049 heap table; fix(libkernel): report current thread scheduling policy in attributes #8583 thread-attribute policy; feat(libSceSystemService): fill the player dialog param as the console does #8337 player-dialog parameter defaults (dialog UI remains absent); fix(net): keep MSG_DONTWAIT transfers nonblocking on Windows #8653 Windows MSG_DONTWAIT transfers. Historical adjacent merges and their narrower boundaries are retained in the archive.
- Open: fix(libSceNet): retire invalidated epoll registrations #8598 socket-close/epoll reuse and stale wait snapshots; fix(libSceNpAuth): reject completion queries before request start #8611 NP Auth Poll/Wait after an unstarted abort; fix(net): complete zero-length TCP receives without waiting on Windows #8686 zero-length Windows TCP receives; fix(agc): return the console results of the capture, shader instrumentation and occlusion query size calls #8296 capture-unavailable returns, instrumentation and query sizes. These proposals are not integrated fixes or demonstrated PRAGMATA improvements.
Validation and contribution boundary
This refresh checked source, PR ownership and documentation, without rerunning probes, PR tests, the game or console measurements. Historical probes and author-reported validation remain in the archive/PRs. Metadata checks are not runtime coverage. Distinguish title-supplied libc from host libc when interpreting imports.
Require a general contract/reference and a behavioral regression failing on base and passing with the fix. Follow CONTRIBUTING.md, including full build/relevant runtime validation for library changes. Check overlaps, preserve working behavior and record unknown contracts in library debt; do not invent success or per-title behavior.
AI-assisted: yes.
Activity
[-]PRAGMATA (PPSA02530): imported-library audit with binary evidence and tracked implementation gaps[/-][+]PRAGMATA (PPSA02530): library gaps and contributor tasks[/+][-]PRAGMATA (PPSA02530): library gaps and contributor tasks[/-][+]PRAGMATA (PPSA02530): library gaps and tasks[/+][-]PRAGMATA (PPSA02530): library gaps and tasks[/-][+]PRAGMATA (PPSA02530): SaveData Prepare/Commit no-ops, ignored Json2 settings and unsupported UDS statistics[/+]MarcZX10 commentedon Oct 19, 2026
Update on C1 (heap trace table capacity): this finding is now covered by #8049. That PR extends the table from 64 to 65 entries while preserving the
LibcHeapInfoABI, mask, and base slot. Its first commit adds a boundary test that writes the base and final slots; the PR reports that the test reproduces a global buffer overflow at slot 64 under ASan before the fix and passes afterward. This addresses C1 only; it does not validate the other audit items.Ondra97 commentedon Oct 21, 2026
Archived audit (historical snapshot).
Scope and result
I audited the system-library interfaces referenced by PRAGMATA, PPSA02530, version 01.200.000, using the title's executable/module import registries, title-provided metadata and caller/consumer evidence, AnyPS5 source, existing test sources, technical debt and overlapping pull requests.
Historical baseline: the original findings/links use
7a015c0946e2f421b7977129dc7fc255a133019b(2026-10-19). Current corrections and C9/C10 below are separately pinned to later source. Installed title files were an older bring-up installation, not a build of the reviewed main.Save transactions/icons, Json2 settings/recovery, UDS and gated PSML/signaling remain unresolved. PR status refreshed 2026-10-20; see the ownership table before starting work.
The original pass was import-driven. Static callers do not prove execution. Round2 ran the parser/recognizer probe; C9/C10 use separate component probes. These findings do not establish the cause of title FPS, memory or shader problems in #6582.
Contributor handoff: where to start
Claim a focused item and recheck current
mainplus the PR table before patching. A confirmed gap is not a complete replacement specification. Some items are ready for a synthetic reproducer; others need API behavior established first. No proprietary assets are required for the proposed public fixtures.Library paths below are relative to
core/libs/prx/; test links use the audited revision.Work items
libSceJson2/Export.cpp,Initializer,Node: establish allocation/configuration ownership; instrument a synthetic allocator. Evidence.libSceNpTrophy2/src/TrophyPackage.cpp,TrophyStore.cpp: select one aggregation/type/condition family. Actual shapes.libSceSaveData.native/Export.cpp,SaveData.hpp, Prepare/Commit parameter types: specify lifetime and persistence transitions. Evidence.sceSaveDataSaveIcon/sceSaveDataLoadIcon: specify byte/size behavior, then test a mounted round trip. #7785 validation is merged; persistence remains open.libSceVideoOut/src/Output.cpp,Event.cpp: specify the 32-byte wait block and event producers; test marker/order behavior. #7814 owns resolution. Evidence.C1: precise boundary and acceptance conditions
Fixed by #8049, merged 2026-10-20: 65 entries, unchanged 32-byte LibcHeapInfo ABI/mask/base slot, registered slot-0/64 test. The author reports ASan failure before and success after; not rerun here. R2-I retains the original numeric evidence. PRAGMATA reachability/crash remains unproved.
C2/C3: work without private title assets
Extend public fixtures in GuestJson.cpp, JsonCopyFailure.cpp and GuestNpTrophyStats.cpp. The latter builds synthetic packages and statistic/rule JSON.
For example, this minimal statistic definition captures one currently rejected shape:
{"statDefinitionArray":[{"statId":1,"dataType":"uint64","aggregation":"count"}]}The audited parser rejects this aggregation. Establish repeated/duplicate/reset/out-of-range semantics before testing observable updates. Treat the other aggregation/type families, property conditions and conversions separately. Preserve latest/uint behavior and direct
_UnlockTrophy.For Json2, observe allocator allocation/free callbacks across value/container lifetimes, failure cleanup and default configuration. Preserve old values on allocation failure (#7977). Establish recovery-callback arguments/errors and float-mode meaning separately.
Requirements before a fix is considered complete
Audit probes and author-reported PR tests are distinguished below.
Re-review accounting: 100% (922/922 original records explicitly represented). This includes source, data/alias and native-provider checks at their stated scope. Complete SDK correctness is unmeasured: 358 host contracts and 146 native-function semantics remain reference-incomplete. See C9/C10 and the coverage limits below.
Correctness re-review — 2026-10-20
This pass re-read implemented behavior, not only missing exports. Source was frozen at
44e3389c882c8ee3249e16933aad6479c3e00d08; the later30fda0a03a43339037677d3a9f4a021d5b078566delta was checked. The tested Json2 and SSL files are unchanged there. No production fix or title/console run was made.C9. Json2 parse and missing-key insertion leak on allocation failure — reproduced
Affected imports: Parser::parse(text,size)
S5JxQnoGF3Eand Object::operator[](String const&)ERuf9y0DY84. Parser construction and ObjectEntry construct raw-owned members before list insertion. A later allocation failure loses those temporaries; the outer cleanup reaches only linked entries.An exact-source allocation-budget probe ran 41 processes: 27 clean exits, 14 leak-detection exits, zero unexpected exits. Four success modes and all warm controls were clean; old values/entries stayed valid. After visible cleanup,
[1]with budget 2 leaves one allocation of 104 bytes;{"a":1}at budgets 2/3 leaves 32/136 bytes; inserting a missing key at budgets 1/2 leaves 32/136 bytes. Nested input reproduces the same ownership problem. Counts are host requested bytes, not console sizes or process RSS.Open fix #8530 constructs parser entries in their owning lists and cleans up failed missing-key insertion. Its expanded JsonCopyFailure.cpp checks parse/callback/malformed/nested inputs, existing values and handlers: the author reports 34 operations/479 forced failures without leaks, with a failing baseline. Tests were not rerun for this update. C2 configuration/recovery remains separate; merged #7977 covers SetType and open #7215 numeric locale.
C10. SSL Term leaves undeletable private connection records — reproduced
Affected imports: Term
0K1yQ6Lv-Ycand DeleteConnectionHJ1n138CQ2g. Term erases contexts only; FindConnection then rejects their connections before Delete can erase them.An exact-source, no-network probe repeated Init → CreateConnection → Term → Delete three times. Term returned 0, Delete returned
0x8095F006, and registry entries grew 0→1→2→3. Contexts were removed, sessions stayed null and socket lookup was called zero times. A negative descriptor deliberately uses the current host model's deferred validation; it does not prove SDK descriptor acceptance. The stored descriptor is not consulted on this path. Only orphaned bookkeeping was measured; larger TLS session/pool retention remains unmeasured.Control order Init → Create → Delete → Term returns both calls 0 and records 0→1→0→0, also without socket use.
Open fix #8541 removes context-owned connection records while preserving in-flight shared ownership and post-Term INVALID_ID. The author reports baseline failure and passing regressions for both cleanup orders, multiple contexts, 32 concurrent cycles and an in-flight callback. Tests were not rerun for this update. Original probes: Windows 11 Pro 26300, Ryzen 9 7900X, 31.7 GiB RAM, GCC 15.2; RTX 4070 Ti SUPER unused. SysV/DWARF setup and source bytes were preserved. No title memory/performance cause is claimed.
Coverage and remaining unknowns
All 922 original import records have explicit dispositions: 4 entries in two reproduced defect families, 7 entries in four candidate families, 295 limited/offline models, 358 reference-incomplete host contracts, 90 bounded host/source checks, 6 data/alias checks, 146 native-function provider reviews and 16 native-data reviews. These are row counts, not independent bug counts or a compatibility score.
Candidate follow-up: AttrGet policy reporting is fixed by merged #8583; socket-close/epoll reuse has open fix #8598; unstarted-aborted NP Auth polling has open fix #8611. Their console contracts remain unmeasured. AudioOut2 construction cleanup remains unvalidated. No title blocker is established; the 922-row accounting retains its original classifications.
Module closure covers 59 declarations and 60 reachable owned host PRX targets; the extra host dependency is Keyboard. VideoRecording's build/package target exists but is dummy-only; VideoRecordingP is a separate partial target. Supplied
sce_sys/about/right.sprxadds four separate metadata imports, includingsceKernelMapNamedFlexibleMemoryoutside the original 922. Its loading is unproven; treat GameRight as title-provided code for conversion/provider mapping. Data-dependent plugin names and complete indirect/runtime loading remain unresolved.Import and provider accounting
The executable declares 59 needed libraries. Its 124 records with an empty library name were matched by NID to source/installed exports and narrowed using those declared dependencies, including shared native-library sources. This gives a unique static owner candidate for each of those records; it does not trace a runtime resolver.
Every registry NID has a candidate export in the inspected installed layout when the title's own module is included. That is export availability, not proof of a working implementation or successful startup. Some records refer to data, not functions;
__stack_chk_guardand the IPv6 multicast-address constant must not be called missing functions because a C++ definition scanner cannot identify them.The title's libc is a crucial exclusion
All 162 executable imports declared as
libc.prx, accounting for 1,010 relocation records, exist in the converted title-providedlibc.prx.guest.prxexport table. It contains 2,950 exported NIDs. Of those 162 imports, five are absent from the inspected host libc but present in the title module:9G6z-nF6njg,B2ZbqV9geCM,Slmz4HMpNGs,hNAh1l09UpA,pA9N3VIgEZ4.Source routing searches the matching guest module for a scoped
libc.prximport. Its additional shared-host-libc fallback applies to other requested host libraries. Therefore an apparent hostmemcpy, math, locale or libc thread-helper gap must not be presented as an active PRAGMATA defect merely because that NID occurs in the executable registry. The exact installed executable's runtime-resolved provider addresses were not traced here.Similarly, the guest libc's
__tls_get_addrimport (vNe1w4diLCs) has a throwing host declaration, but the Windows resolver builder emits a guest TLS resolver for this case. It is a false positive for a simple stub/import intersection, not a demonstrated startup blocker.The guest module still contributes 109 distinct
libkernelNIDs / 110 references, sixlibSceLibcInternalimports and onelibSceSysmoduleimport. The LibcInternal routes include four exports from that host library and two from shared host libc; the audit includes these transitive requirements.1. Save-data transaction operations acknowledge work they do not perform
sceSaveDataCreateTransactionResourcegjRZNnw0JPEsceSaveDataPreparesDCBrmc61XUsceSaveDataCommitie7qhZ4X0CcsceSaveDataSaveIconc88Yy54Mx0wsceSaveDataCancele6y3WMBYbiMNotImplemented_nid_no_patch.Each has one executable relocation. Sources: Commit/resource creation, Prepare/SaveIcon, Cancel.
Prepare and Commit do not check initialization, parameter validity, transaction identity or mode. Their declared structures contain a resource identifier and mode fields. Mount3 also ignores the transaction resource and
system_blocks. These functions are present as exports but do not implement a transaction protocol. The exact console durability, rollback, mode and error-order guarantees remain unknown; this report does not assert observed save corruption.Binary corroboration: the title has a real call to Prepare at original VA
0x9FA30F, passing a parameter block whose first word is a resource value and whose second word is 3, and it checks the returned status. At0x9F8C04it builds a zero-initialized Commit parameter block, writes a resource value into its first word, calls Commit and checks for a negative result. The containing control flow has conditions; these are static call sites, not an observed save session. The inspected spans match the original SELF bytes exactly.Additional limits in the same storage model:
MountSlot;setParamcannot enforce it. This is a missing mode model. Enforcement of actual file writes through the path alias needs a separate backend check, and the audit did not establish a read-only PRAGMATA mount._sd/<directory>without a user component, while save-data-memory storage is partitioned by user. The current single-local-user setup limits relevance; no cross-user title failure is claimed.Existing debt records synthetic transaction IDs and unknown cancellation/rollback behavior, but does not explicitly enumerate the Prepare/Commit/SaveIcon no-ops.
GuestSaveDataCanceldeliberately expects a throw. A targeted static search found no direct Prepare/Commit/SaveIcon behavioral tests; existing test names or a passing export check would not establish transaction support.Next evidence: capture the title's resource/mode/mount sequence during an isolated save, establish the general console contract, then test observable state/durability and failures. Do not implement a mode-3-only special case.
2. PSML/MFSR 1100 is imported but cannot generate the title's reconstruction packets
PRAGMATA has nine PSML import records. Four expose unsupported paths:
scePsmlMfsrGetContextBufferRequirement1100VGjrQa-WqdU0x8A810001before init; throws after init.scePsmlMfsrCreateContext1100fccGInHrj8AscePsmlMfsrGetDispatchMfsrPacket110094iBp3KvIuIscePsmlMfsrGetDispatchMfsrPacketSizeInDwordsAHalTX9wFZY1100 exports, packet sizing. The remaining imported setup/release APIs maintain host bookkeeping objects. Their shared-resource blocks are validated but not used to reconstruct an image. Existing debt explicitly acknowledges the guessed memory requirements and unknown layouts.
A caller establishes more than the import alone
The routine at original title VA
0x578FE20, 220 bytes, contains:0x578FE4Bto the packet-size import. It puts a stackuint32_toutput address in RSI, preserves its incoming context in RDI and dispatch parameters in RDX, checks EAX as a status, and reads the DWORD count from the output slot after success.0x8A810006.0x578FECAtoGetDispatchMfsrPacket1100with RDI = context, RSI = pointer to a stack descriptor containing a cursor and a 32-bit DWORD count, RDX = dispatch parameters.This supports a status-returning packet-size query with an output pointer. A future implementation that simply returns a packet length in EAX would not satisfy this caller. The exact types/layouts of the opaque context and dispatch parameters, valid sizes, generated packet semantics and feature-gate reachability remain unresolved. This is ABI/caller evidence, not permission to invent packet contents.
PSML debt describes similar command-buffer behavior in other titles; the caller above is specific evidence from this PRAGMATA input.
GuestPsmlcurrently tests untouched outputs before init and deliberate post-init refusal, not image reconstruction. No relevant PSML implementation PR was found in the captured open-PR inventory.Analysis update: Round2-C recovers setup and one named command-producer gate. Runtime execution, other generic writers and the general packet/output contract remain unverified; imports alone do not prove a normal-console rendering blocker.
3. Imported Json2 options are accepted but ignored; two registered recovery handlers cannot run
The executable references 58 Json2 NIDs, including these one-reference interfaces:
InitParameter2::setAllocatorI2QC8PYhJWYInitParameter2::setFileBufferSizeEu95jmqn5RwInitParameter2::setSpecialFloatFormatTypeWVZBP4IyM+EInitializer::initialize(InitParameter2 const*)IXW-z8pggfgValue::setElementAccessFailureHandler6tTbrt1O1SYValue::setSpecialFloatHandlerbJWBpvGCIJUConfiguration, handler registration, missing-element refusal, non-finite serialization.
Nodes, strings and containers use host allocations; the supplied title allocator is not called. The configured user data, file-buffer size and special-float-format value have no effect. The enum meanings and console recovery-callback arguments are not established, so the current explicit refusals must not be replaced with guessed values.
The type-mismatch callback and global null-access callback do execute in supported cases. They are not wholly unimplemented.
GuestJsonchecks registered element/special-float handlers are called zero times while the corresponding path throws; those tests document current limits, not completed callback semantics. Json2 debt already records the configuration and handler gaps.Merged #7477 adds String/container/iterator/Value methods; its exact diff does not implement these settings or recovery callbacks. Merged #7977 repairs SetType exception safety under host allocation failure; it does not dispatch the title allocator or implement the callbacks. Their debt diff context must not be mistaken for a fix to these paths. Both were checked at the diff level.
Next evidence: determine which non-default settings and exceptional JSON inputs the title actually uses, establish callback arguments/float modes from an authoritative contract, and test observable allocator calls and recovery rather than just successful registration.
4. Imported NP signaling group lookup has no implementation
sceNpSessionSignalingGetGroupFromSessionId, NIDUGcXquhVYrY, has one relocation and unconditionally throws. It is declared without parameters, so its input/output ABI is also unresolved.The title contains a direct call at original VA
0x87C9118, through PLT0x8FC3220/ GOT0xA56DBB8; the inspected caller span matches the original bytes. A direct call still does not establish that an online/session path executes while signed out.The library's own debt file does not name this export, but the cross-library Functional entry in Json2 debt does; it is therefore not globally undocumented.
GuestNpSessionSignalingtests other connection/context operations, not this lookup. No open PR in the captured inventory changes this library.Next evidence: derive the caller's argument/output shape and the console's signed-out behavior before choosing a return code or implementing lookup state.
5. Online service support is deliberately partial; request success and service availability differ
These are source-confirmed limitations, not an assertion that signed-out PSN operations should succeed:
3EI-OSJ65Xc, SendRequestlQOCF84lvzw, ReadDataOOY9+ObfKec0x80553406UNAVAILABLE; no transport exists.fY3QqeNkF8k,lxtHJMwBsaUA+NVAFu4eCg, WaitAsyncMOp-AUhdfi80x80436063, no HTTP request is sent. Some option/empty-queue combinations throw.bGN-6zbo7msuqcPJLWL08M, AbortRequestOzKvTvg3ZYUSources: WebApi2, send/read and callbacks, push-context callbacks, Http2 completion path, async read/send, NP manager poll. UDS registration/handles: Context and Handle. Trophy2 registration/handles: Context and Handle. Existing
GuestNpWebApi2,GuestHttp2,GuestNpManagertests exercise the local/offline model; no network transaction was tested by this audit.UDS ignores
_UpdateTrophyProgress; trophy-stat support is limited tolatestaggregation, uint32/uint64 and simple event-name/property rules. Event handling, rule handling. PRAGMATA shipstrophy00.ucpanduds00.ucp, but the bounded resource check found binary containers rather than loose rule XML/JSON. That first-pass header-only limitation is superseded by the actual payload/parser results in Round 2 below.6. Entitlement behavior is an offline policy; a suspected trial-flag ABI mismatch was not established
Imported entitlement Request/Poll interfaces, including unified request
jautSRs4OdQand pollM4XlLFnzQaQ, are declared without parameters and return0x80550006SIGNED_OUT. They keep no request objects and do not fill caller structures. Abort/Delete return success without request state. Implementation. Their general ABI and validation remain incomplete.GetSkuFlag writes the fixed full-game value 3;
GetGameTrialsFlag(y7JD1gfwyfA) writes a fixed uint32 zero with success, rather than reading a license/trial state. This is a fixed local policy, not a license implementation.Negative finding: at both inspected trial-flag calls, original VA
0x150F0EAand0x150FEE2, PRAGMATA explicitly passes a stack-output address in RDI, checks EAX for success and compares that 32-bit output with 1. This is compatible with the current one-output-pointer shape. Other registers being live is insufficient to prove more arguments. The older debt note about four live registers must not be elevated into a demonstrated ABI bug or memory corruption. Additional console behavior and whole-program uses remain unknown.7. Imported network/thread interfaces have accepted-but-unapplied controls
sceNetResolverStartNtoa(Nd91WaWmG2w) ignores timeout, retry and flags and performs blocking hostgetaddrinfo. The request's deadline/retry/mode cannot govern the lookup; a concurrent abort cannot interrupt that host call. Resolver source. This is established debt, not a reproduced PRAGMATA stall. The next test needs a controllable resolver and the title's actual parameters.scePthreadSetaffinity(bt3CTBKmGyI) updates stored affinity; its source does not set host affinity.scePthreadMutexattrSetprotocol(1FGvU0i9saQ) accepts protocols 0..2 but does not retain/apply them. Mutex source. Existing attribute tests do not establish scheduling order or priority inheritance.sceNetGetSockInfo(hLuXdjHnhiI) could succeed without writing outputs. Merged fix(libSceNet): fill the address and port fields in sceNetGetSockInfo #7959 now writes records; flags/family/statistics limits remain. fix(libkernel): return ESRCH from scePthreadAttrGet for a thread that has ended #7957 integrated thread-attribute liveness/locking; merged fix(libkernel): report current thread scheduling policy in attributes #8583 corrects policy reporting, not host scheduling.No scheduling, DNS, performance or memory effect was measured in PRAGMATA during this audit.
8. Optional input/capture paths contain explicit stops
Six imported VR-controller functions unconditionally throw if reached:
DGCwN1LmmysscePadVrControllerSetVibrationWf6-PNCyY20scePadVrControllerSetVibrationModeTABucyiW6AQscePadVrControllerReadCombinedStatembJHDdjhVeYscePadVrControllerGetDeviceInformationv8P+9PRqg10scePadVrControllerSetTriggerEffectsAVr6AKXGc0MscePadVrControllerGetTriggerEffectStatesPad source and remaining VR exports. #5038 changes overlapping APIs, but its proposed disconnected-device returns were not validated against a console by this audit. VR engine imports do not demonstrate that a non-VR title path calls them.
The separate imported
scePadSetVibrationMode(W2G-yoyMF5U) stores a mode, but the physical output backend does not interpret it. Stored state and output backend. This is a documented input-device partial, without a measured title effect.The imported driver
sceAgcDriverRequestCaptureStart(SAfhzJPcjuk) andRequestCaptureStop(FOwvmNlFLjM) also throw explicitly. They are capture-feature gaps, not proof of missing normal draw submission. The 54 Agc and 11 AgcDriver imports were inventoried; this report does not certify all dynamic PM4/shader/resource behavior behind the implemented entry points. Open #8296 proposes unavailable-error returns for capture, plus instrumentation/query-size behavior; no capture/title validation is claimed. Graphics bring-up remains under #6582.9. UI, system queries and presentation have narrower models than their APIs
These are relevant limits, with distinct severity from transaction/save bytes or a hard API stop:
sceSystemServiceParamGetInt(fZo48un7LK4) writes zero and succeeds for every unknown parameter ID. Source. However, the five direct call sites found in this executable pass IDs 1, 2, 3, 4 and 5 (language, date/time formats, time zone, summertime), all handled by main. Their inspected bytes match the original SELF. The unknown-ID fallback is a general implementation gap, not an established requirement of these PRAGMATA callers.sceSystemServiceInitializePlayerDialogParam(m5CYKX20wfg) checks non-null and succeeds without initializing the buffer; LaunchPlayerDialog (uaieF+glFPs) displays nothing. Source. Open feat(libSceSystemService): fill the player dialog param as the console does #8337 supplies measured 0x40-byte defaults and tests; LaunchPlayerDialog UI remains absent. Title use is unverified.eb-gvTYQcoYand start-point setterMCJ8SkzsQxYvalidate the handle but implement no input-latency wait/measurement. Source. GetOutputStatusWithVrr (gWT7X8H0bYs) returns the normal output status in an 80-byte zero-filled wrapper; the additional console fields remain unmodeled. Source and existing VideoOut debt. Neither proves a frame-rate problem.sceRtcGetCurrentNetworkTick(zO9UL3qIINQ) used the local current-tick implementation at the original baseline. Current main maintains process-local clock state; external network-clock synchronization remains unproved. RTC source. No title timing failure was observed by this audit.Audio/AJM were inventory-only in the first pass. Round 2 below adds source review of all 62 imported audio/media NIDs, with selected byte-verified caller analysis; no audible output, codec equivalence or title playback was tested.
Existing work: avoid duplicate fixes
States checked 2026-10-20. Seven added PR diffs/tests were reviewed at the heads below. Tests are author-reported, not rerun here; their full Build jobs were skipped. Historical evidence keeps its original revision boundaries.
d28dc66e25f315afb8647337ad1650686c06c7032e6acf8c6ce64bdfae1f22cd2ec5c711fe04a3c299a7Other open references: #7881 (controllers/users), #6797 (non-imported keycode), #7814 (VideoOut resolution), #7215 (Json2 locale), #7412/#7622 (media details/worker FP), #7064 (ACM priority). #7658 is Hmd2-only.
Reproducible evidence and validation limits
Input identities
eboot.bin2f75ba7ec4dacd9a763e0bac541e42b19d9a0ba010cbc443fe930b30dd5c3277libc.prx03f2202ca1cbd497e136bc47a91e65677b0e8d7e4ae0fe3dea67b0e8f7b609cfPRAGMATA.exe8d4c60c8ac845041603b34e289bd69a85842d8ff7c92a0734cd9e9bd8f45d3d5libc.prx.guest.prx3b5de2b505af2378668871d287a50e9c8313736a38469523ef80c3a33236495eRegistry SHA-256 values:
0a3952389b2a46c3c5dfc07d7c9bde73a6f169061d01ab285fdfa33944d6cc6a.98f4ae6c539e8e600c981f4a959e8b1d58079092ee46297a9f6ff9cb589987dd.Input identities and source/caller evidence are retained below. No title payloads or account data are attached.
Calling contracts and coverage
The title uses the guest SysV AMD64 calling convention. Host Win64 parameter conventions are not interchangeable. Caller/consumer claims below identify original locations, arguments and output use; selected regions were matched to the original input bytes. They are static observations, not measurements that a title path executed. Whole-program control flow and all indirect targets have not been established.
Original inventory conservation was checked: 806/1,654 plus 116/117. Provider records were inspected as data; existing tests were read, with no CTest rerun. C9/C10 specify separate new component probes. No production implementation, branch, commit or PR was created for this audit.
Coverage by library
NIDs / refsis counted separately per importing image. Empty-library imports are assigned only as the static source/provider candidates described above. Zero means no direct record in either supplied registry; dynamic loading or indirect use is not excluded. Inventory coverage does not mean every contract in a library was semantically validated.All 59 declared dependencies, including transitive guest-libc imports
libSceAcm.prxlibSceAgc.prxlibSceAgcDriver.prxlibSceAjm.native.prxlibSceAmpr.prxlibSceAppContent.prxlibSceAudio3d.prxlibSceAudioIn.prxlibSceAudioOut.prxlibSceAudiodec.native.prxlibSceAvPlayer.native.prxlibSceCommonDialog.prxlibSceContentExport.prxlibSceConvertKeycode.prxlibSceErrorDialog.prxlibSceFiber.prxlibSceGameLiveStreaming.prxlibSceGameUpdate.prxlibSceHttp2.prxlibSceIme.prxlibSceImeDialog.prxlibSceJson2.prxlibSceLibcInternal.prxlibSceMouse.prxlibSceMsgDialog.native.prxlibSceNet.prxlibSceNetCtl.prxlibSceNpAuth.prxlibSceNpCommerce.prxlibSceNpEntitlementAccess.prxlibSceNpGameIntent.prxlibSceNpManager.prxlibSceNpSessionSignaling.prxlibSceNpTrophy2.prxlibSceNpUniversalDataSystem.prxlibSceNpUtility.prxlibSceNpWebApi2.prxlibScePad.prxlibScePlayGo.prxlibScePlayerInvitationDialog.prxlibScePsml_debug.prxlibSceRazorCpu.prxlibSceRemoteplay.prxlibSceRtc.prxlibSceSaveData.native.prxlibSceSaveDataDialog.native.prxlibSceShare.prxlibSceSharePlay.prxlibSceSigninDialog.prxlibSceSsl.prxlibSceSysmodule.prxlibSceSystemGesture.prxlibSceSystemService.prxlibSceUserService.prxlibSceVideoOut.prxlibSceVoice.prxlibSceWebBrowserDialog.prxlibc.prxlibkernel.prxRound 2: deeper analysis and actual title data
This continuation closes several first-pass inventory-only areas. It preserves the distinction between an observed static caller, a read-only parser replay, an implementation limitation, and an unverified runtime consequence. No fixes, title execution, GPU/audio playback, or console measurements were performed.
Round2 source was pinned to
7a015c0946e2f421b7977129dc7fc255a133019b. A follow-up fetch reached68447804dad58653ca21ce0c1263b761047ad8e4; its ten-file delta was reviewed. It changes host libc locale/stream support and relinker null-symbol handling, not the audio, media, trophy/UDS, Json2, PSML, VideoOut or Sysmodule implementations analyzed below. The original input identities remain unchanged.R2-A. Actual UDS payloads expose unsupported statistics and rules
The earlier header-only check is superseded: both UCP containers contain directly readable JSON. No decryption or key was required. A small read-only probe compiled from the baseline
TrophyPackage.cppandUdsEvent.cppsuccessfully read all 19 JSON documents, all 14 trophy locales, and all 36 trophy definitions. It executed the existing repository parsers, rather than only a replacement parser.For these exact inputs, the baseline accepts 0/53 statistic definitions and 0/59 extraction rules:
collection / enumSeteachLatest / enumStatusSetlatest / enumlatest / enumSetcount / uint64The real parser returned skip diagnostics for 50 aggregations, three types, 55 property conditions and four unsupported output statistics: 112 total. All 55 property conditions are outside the parser's event-name-only rule support. The remaining four rules target an already rejected collection statistic. Twelve rules also contain conversions, but are rejected before conversion could matter. Definition and rule readers.
This is not a finding that trophies cannot unlock. All 35 non-platinum trophies are non-progressive and have the shape accepted by the separate direct
_UnlockTrophypath. The probe called the actual event recognizer with synthetic int32 trophy IDs from those definitions: 35/35 recognized. Recognition and dispatch route those events directly to local trophy recording, bypassing statistic extraction. Persistence, platinum completion and actual title event emission were not executed by this probe.The schema contains
_UpdateTrophyProgress, but these packages have zero progressive trophies and zero extraction rules for that event. Its schema presence is not evidence of blocked game progression. The demonstrated gap is UDS activity/statistic rule coverage for real title data; the general aggregation/condition semantics still require an authoritative contract.Input SHA-256: trophy UCP
9b17911265f14a8d1197e7195971b94732d3b0a0f202a5b05407276d63d163ae; UDS UCP34902f31243854c24b3e8c10f650e98eb12158ce9353b007736e44099105e708. The two originals were unchanged after the probe. No proprietary JSON body, image or binary payload is attached.Validation boundary: the final three-translation-unit parser/recognizer probe exited 0. An optional full exported PostEvent probe did not build in this standalone MinGW unwind setup; it was excluded without adding an unwind stub. Full dispatch/store conclusions above are static source/data evidence. Existing CTest suites were not rerun.
R2-B. Json2 receives a real custom allocator and non-default settings
The original title routine
[0x1523E60,0x1523FDF)calls the Json2 parameter constructor and then supplies:self), with null user data, at call0x1523FA9.0x4000, at0x1523FB6.2, at0x1523FC3.0x1523FCE; its status is stored by the title.Five original RELATIVE relocations independently identify the allocator object's virtual-method targets. The allocation/free slots lead to real guest forwarding routines; they are not null placeholder callbacks. The converted allocation routine has a 12-byte TLS rewrite, so that callback was analyzed from its original SELF bytes, not assumed identical to the PE.
Main's configuration setters/initialize store those values but initialization ignores them. This upgrades the first-pass import-based concern to a concrete non-default title configuration that is accepted without effect. It does not prove that callbacks executed, that format 2 has a particular NaN/Infinity meaning, or that an exceptional JSON input occurred during a game run.
R2-C. A concrete Trinity/requested-option gate narrows the PSML finding
The byte-verified renderer constructor
[0xE57340,0xE579C5)starts object flag bit 28 clear. At0xE5772F, a nonzero result fromsceKernelIsTrinityModecauses that bit to be set; a zero result leaves it clear. A separate requested-option byte is copied from constructor parameter offset0xD6into object offset0x844.The inspected initialization chain tests bit 28, then object byte
0x844 == 1, before calling the PSML setup helper at0xE69604. Current main's kernel Trinity query returns zero. Thus the current main result skips this demonstrated PSML initialization chain. The missing packet/1100 APIs remain real implementation gaps, but their imports must not be presented as normal-mode startup blockers.This is local control/data-flow proof, not a global proof that no other object writer, entry point or dispatch path can enable PSML. The opaque dispatch/context contracts remain unresolved.
The separately inspected dispatch route selects command kind
0x1C, subtype 15, then reaches0x206311 -> 0x8B7B120 -> 0x578FE20. Its case/leaf do not repeat the setup gate. RDS-guided analysis now identifies a gated producer:PSSRCore::executePSSRchecks availability byte0x845before callingRenderContext::ps5Extentionat0x8BC7242with type15. That writer allocates kind0x1C and stores subtype15 at record+0x10. The constructor clears byte0x845; setup sets it only after successful initializePSSR. Main's zero Trinity result therefore also blocks this demonstrated producer chain. Seven complete functions / 5071 bytes match SELF. This does not certify every generic writer/flag writer or prove global/runtime unreachability, and does not make the missing packet APIs safe to omit.R2-D. Static dependencies do not capture every module/symbol request
The original executable has 33 verified direct Sysmodule-load sites and 22 unload sites, with 30 distinct constant load IDs. All 55 argument/call spans were checked against the SELF. One load is ID
0x85(libSceVideoRecording) at0x1E9D2D7, outside the 59 declared needed-library names. It occurs beside Share/GameLiveStreaming/SharePlay requests. Module ID table and load bookkeeping distinguish a known-ID counter increment from a real module open. The inspected installation has no exactlibs/libSceVideoRecording.prxfile; neither execution nor a missing-DLL startup failure is established.A separate complete, byte-matched helper
[0x564FC10,0x564FD06)calls realsceKernelLoadStartModule, thensceKernelDlsymforg_pAKPluginList. Its computed NID82XiaP80JDois absent from both import registries. The caller checks the returned symbol pointer and dereferences this Wwise plugin-list data symbol.Its filename is built from a configured/default prefix, a parsed entry name and
.prx; the inspected path does not establish a fixed PRX basename or runtime file availability. Kernel module open performs a realdlopen, unlike Sysmodule bookkeeping. These requests expand the analysis beyond static import accounting; they do not add new relocation records to the 922-pair/1,771-reference total.R2-E. Audio/AJM/ACM and AvPlayer now have detailed source/caller coverage
Source was reviewed for all 62 imported NIDs in this group, with selected byte-verified caller analysis: 21 AudioOut, 18 native AJM, six ACM and 17 native/shared AvPlayer. Legacy AJM declaration stubs were not mistaken for the title's native provider. Decode/mix/playback paths exist; the following gaps must not be generalized into "all audio is a stub":
0x575ABCBthe title explicitly sets RDI = batch-object pointer, ESI = 1; the full prototype/second-argument meaning is unverified. #7064 merely removes the throw and returns 0; #7567 is merged: bookkeeping, not processing.0x5650005the title supplies one attribute: ID 2, size 4, uint32 value 1. Main's setter traces and returns 0 without applying it.+8=1and nonzero video-decoder bytes. Main applies only the first PostInit demux-buffer field.Exact source/table evidence is retained locally for every one of the 62 NIDs. Representative sources: ACM, AvPlayer PostInit. Four inspected caller spans totaling 2,276 bytes match the original SELF exactly. This is static caller evidence, not playback or codec-output validation. #7680 is merged for the first paused picture. Open #7412/#7622 concern stream-info/worker-FP-state; none implements these settings.
R2-F. Whole-file metadata and native symbol roles are now quantified
All 328,652 executable FDE index records decoded with zero failures. The supplied RDS has 328,756 names/93,516 dictionary tokens; all 328,652 indexed starts/sizes match, with 104 additional named records. This is metadata coverage, not complete function/control-flow or runtime proof. RDS SHA-256:
9cc1610e14c9e8ba4fac7a3e62848a53fa91265bbe7b006846b3adc5ff518a81.The 162 imported native-libc NIDs comprise 146 FUNC and 16 OBJECT entries, with nonzero sizes/distinct addresses. These roles do not establish every function's semantics or turn data objects into missing functions.
R2-G. VideoOut latency parameters, event producers and working controls
All 21 imported VideoOut NIDs now have source/helper/test/debt review and a per-interface local table. New byte-verified evidence strengthens the latency finding: the title's marker wrapper increments a uint32, passes it to
LatencyMeasureSetStartPoint, and both inspectedWaitBeforeInputcallers prepare a 32-byte block in RSI (word0=1, marker-minus-one at +8, another context value at +0x10) with EDX=0. Main's one-handle declaration ignores that block and performs no wait. The full console prototype and meanings of those fields remain unknown. Latency implementation.VRR event registration/teardown have real bookkeeping, but the driver has no VRR-transition producer; the output-status extension remains zero-filled. Output-mode events are initially delivered and respond to host HDR-generation changes, while ConfigureOutput itself does not emit that event. Accepted guest flip-mode values share the same presentation policy. Output-resolution reporting is derived from configured buffer dimensions; #7814 already owns the correction, while #7879 was closed without merge.
Negative findings: SetFlipRate actually affects reservations/pacing as
rate+1vblank intervals; ConfigureOutput actually selects emulated 59.94/119.88 Hz cadence; buffer registration, flips and flip events have real effects. The title's inspected configuration caller selects supported mode 1 or 15, so this is not evidence of an unknown-mode failure. Four complete functions / 505 bytes match the SELF exactly. No GPU presentation or latency measurement was run.R2-H. AGC/driver review distinguishes real commands from ignored controls
All 54 Agc plus 11 AgcDriver imported NIDs now have per-interface source/helper/debt coverage. Packet encoders advance checked caller buffers and write/patch real command words; shader helpers transform/register metadata; submission queues and EOP event delivery have actual implementations. A successful return after command encoding is not an empty stub merely because the GPU executes the command later.
Specific limits include SetHsOffchipParam discarding its three values, and SetTFRing retaining queryable base/size without publishing guest tessellation-factor results. Capture exports throw at the baseline; open #8296 proposes unavailable errors. Debug RegisterOwner/Resource return an unavailable error, not made-up success.
Conversely, Init_0090's validated-but-unchanged state and DebugRaiseException's logger behavior are explicit existing models/debt; their names alone do not establish a new title bug. SuspendPoint enqueues a real asynchronous driver boundary; it is not a synchronous caller wait. This API-level coverage does not certify every dynamically submitted packet, shader instruction, image/cache transition or hardware result; those live graphics questions remain separate from this audit's source-contract conclusions.
R2-I. Transitive libc contracts and a conditional heap-table capacity mismatch
All six LibcInternal imports in the title's libc were traced through their installed provider candidates, original thunks and 11 decoded direct-call sites. The two diagnostic exports provide reduced logging; the caller separates heap-error reporting from its own fatal handling. The three TLS/destructor exports have real registration/run/filter state. HeapGetTraceInfo provides real writable shared mask/table pointers: the guest retains and modifies them, so initial zero values are not evidence of an empty stub. Twenty-two inspected spans / 3,236 summed bytes including overlap match both the extracted ELF and the original module SELF, with zero differences.
Original capacity mismatch (fixed by #8049): host heap backing storage has 64 uint64 table elements, valid indices 0..63. The native consumer writes the base heap to index 0, then its mask-based extra-mspace allocation can select 1..64, requiring 65 slots for the entire observed index set.
In the complete inspected native allocation routine
[0xBF30,0xC7C1), no local cap63, reserved high mask bit, or table-pointer minus-eight adjustment was found. Under an otherwise admitted creation, non-null returned pointers and a successful CAS with old mask0x7FFFFFFFFFFFFFFF, the nonzero first-free-bit branch yields trailing-zero count 63, then increments to index64. The table write is at byte offset 512, beyond the host's 512-byte allocation. The base slot and mask allocation are distinct, and observed initialization clears the mask.C1 follow-up: #8049 is merged; 65-slot storage and a boundary test are in main. The original no-matching-PR search predates that fix. Actual PRAGMATA reachability remains unproved.
R2-J. Original validation and execution limits
Round2's parser probe used Windows11/MinGW15.2, Ryzen9 7900X and32GiB RAM; the RTX4070TiSUPER was unused. Three older mixed-build logs (3.51MB) show PSML loading but not command production; absence is not proof of nonexecution. Opaque SDK contracts, indirect paths and title reachability remain unresolved. C9/C10 describe separate new exact-source probes.
AI-assisted: yes.