D331 - The *GetSize family is measured against its own builder, not against a borrowed number

decided - 2026-09-12

libSceAgc exposes a *GetSize sibling for most command builders. The guest calls it, reserves that many bytes, and the builder then writes into the reservation - so the two are one ABI contract, and a wrong size is not cosmetic: it is either a builder writing past what the guest set aside, or a guest reserving room nobody uses.

Why reading the implementations does not settle it

Two independent current-generation reimplementations were consulted and they disagree on several of these counts. One of them documents why: its payloads are its own encoding rather than the hardware packet, so its numbers carry a build snapshot here and a predication slot there. Its own guidance is not to shrink a builder to match a published table, because that is how a working title gets broken to satisfy a number.

So there is no consensus to take, and taking either side would mean writing an expectation this project cannot defend. Worse, it would be the failure principle 3 already names one level down: an instrument fitted to the answer it was built to confirm. A check that asserts a borrowed figure and passes has established nothing except that the figure was copied correctly.

What is knowable without either number

The relationship. A reservation that does not cover the write is a fault whoever turns out to be right about the size. That is this project's own reasoning, it is falsifiable, and it needs no prior figure.

So 166-agc/*-getsize records both numbers and judges only the invariant:

record what it is
getsize what the library says it will consume, in bytes
getsize-high32 the top half of the return, because the return width is not established either. Non-zero means this is not a 32-bit byte count and every dword figure derived from it is wrong
getsize-dwords the byte count divided by four, emitted only when it divides
bytes-advanced, bytes-written what the builder then did

The only fail is getsize < bytes-advanced.

sceAgcCbNopGetSize is swept over five argument values rather than read once, because a single reading cannot tell a constant from a function of its argument - and which it is decides whether a translator may cache the answer. The sweep records the curve and asserts no shape for it.

Why these checks stay assumed while their output is the point

The invariant is this project's reasoning, so OBS_FROM_ASSUMED describes it accurately. The measurements are what matter: run on hardware they are the first figures in this space taken from the real library rather than from an emulator measuring its own emitter, and they settle a live disagreement between two implementations by authority rather than by vote.

This is the shape the collection should use for every borrowed answer. A value read somewhere else is a hypothesis, and the honest place to put it is a check that can refute it - not an expectation that launders it into a fact.

The four chosen, and why only four

The pilot is the intersection of two conditions already satisfied in this tree: the builder is prototyped and callable, and the *GetSize identifier is attested in data/mined-names.txt and recorded present by the census.

builder sibling identifier
sceAgcCbNop sceAgcCbNopGetSize 0xb7b3e567d9ede4b7
sceAgcDcbDmaData sceAgcDcbDmaDataGetSize 0xd9c709cfd2d023ec
sceAgcDcbSetIndexCount sceAgcDcbSetIndexCountGetSize 0x9a58f3b860d9450e
sceAgcDcbSetUcRegisterDirect sceAgcDcbSetUcRegisterDirectGetSize 0x68fd4a8bd1b7fbee

Identifiers were derived from the names with obscene-tool nid and then checked against the mined corpus, which agrees on all four from five independent sources. Nothing here rests on another project's hash.

sceAgcDcbSetUcRegisterDirect was prototyped in platform.h and missing from the curated census. That was an omission rather than a judgement - it is attested by five sources and recorded present - and this change closes it.

Declared with six register arguments, deliberately

The arity of these functions is not established. System V AMD64 makes a call with six register arguments safe for any arity up to six, which is the idiom the builders beside them already use. A narrower declaration would assert an argument count nobody here has measured.