D099 - The inner size was never unknown, and entry 0x1001 is computed like every other derivable entry
Status: decided. 2026-09-10.
playgo-chunk.dat is now built by
selfish-pkg from data/pkg-format.tsv, with no
caller input at all. --format pkg and pack
need no --entry for any entry.
What was blocking it, and what it actually was
obSCEne's build-pkg.sh derives entry 0x1001
in an inline Python block, cited to LibOrbisPkg's
PlayGo/ChunkDat.cs. Porting it needs three inputs. Two are
computed here already - the content id is given and the package is
0x80000 + image. The third was
INNER_SIZE=11141120, a bare literal with nothing beside
it.
That literal is 0xAA0000, and the package
containing it is 7,536,640 bytes - so the value could not be a
measurement of anything inside that package. On that reasoning the port
was stopped and the question filed into obSCEne's inbox
(REQ-20260910T0325Z-6b04): measured, arbitrary, or citable? Writing a
number nobody could account for into data/ is principle 5
exactly, and the day before had been spent withdrawing two claims that
arrived that way.
The question was already answered, twice, inside this repository's own citations.
ChunkDat.FromProject leaves both mchunk sizes zero with
a comment on each:
size = 0, // must update this to outer pfs image size + pfs offsetsize = 0, // must update this to inner pfs image size
So the field is inner_mchunk_attrs[0].size and it means
the inner PFS image - named, in the file obSCEne's own comment cites, in
a project ACKNOWLEDGEMENTS.md has listed since the
packaging work began. shadPS4's playgo_chunk.h declares the
same structure independently and names every field the same way.
And selfish-cli had a function that computes
it. inner_image_size walks the outer filesystem,
finds pfs_image.dat, and reads the length its
PFSC header records - written for the cache-size warning in
D071, sitting eleven hundred lines above the builder it was needed
in.
What was actually wrong, then
Not the field. obSCEne's value. SELFish computes
this package's inner image as 6,488,064
(0x630000), and the nesting is coherent at last:
inner PFS image 6,488,064 0x630000
outer image 7,012,352 0x6B0000
package 7,536,640 0x730000
Built from the table against obSCEne's own artifact as an oracle,
415 of 416 bytes are identical - two implementations in
two languages from one cited source, agreeing on every field including
the sub-table index that is deliberately not in address order. The one
byte that differs is 0x15A, inside the inner size, and it
is the byte their script hardcoded.
Why the entry is computed rather than supplied
The same argument that moved 0x200 in worklog 064, one
step further. Every value in the structure is fixed for a single-chunk
title except those two sizes, and both are in hand at
Builder::build. Demanding it from a caller was asking for a
fact the builder was holding. A supplied entry still wins, so a package
being rebuilt to match existing material can carry its own.
inner_image_size moved into selfish-pkg
with it. Two callers needing one number is the definition of a fact
belonging to the library rather than to a consumer.
The rule this is here for
A number with no derivation beside it is not the same as a field with no meaning, and the second does not follow from the first.
The reasoning that stopped the port was sound as far as it went - the
value really is impossible, and refusing to bake it into
data/ was right. What it did not do was ask the next
question. It inferred "the field is unknown" from "this instance of the
field is unaccountable", took a transcription in a shell script as the
state of the evidence, and filed a question outward without first
reading the source that transcription names.
Before filing an ask, read the sources already cited for the thing being asked about. The cost here was small and the finding was better than the answer would have been. It will not always be.
This is the fifth instance of one shape: judging what something is from what it is called - a candidate label, a verdict headline, a field name, a doc comment, a title id in a citation, and now a constant's variable name. The discriminator each time was going to the material.
What this has not shown, which matters more than usual here
The corrected value has never been on hardware, and the value it replaces has.
obSCEne's script records that a header-only version of this entry was
refused - scePlayGoCoreGetRawContentInfo returning
0x80f00200 after the header passed - and that the full
structure, 0xAA0000 and all, is what stopped that
happening. So 11141120 is a number that appears in a
package a console accepted.
Two readings survive that, and this repository cannot tell them apart from here:
- The console does not validate this field against anything, in which case both values install and the correction is a tidiness argument backed by arithmetic.
- It does, in which case the old value was tolerated for some reason and the new one is either an improvement or a regression.
The arithmetic is not in doubt - 0xAA0000 is larger than
the package that contains it, so it cannot be describing the inner
image, whatever else it is doing. What is in doubt is whether anything
reads it. That is a hardware question, it belongs to obSCEne, and it is
filed (REQ-20260910T0520Z-9c33).
Recording this rather than leaving it implied,
because the failure mode is specific: a change justified entirely by
reasoning, replacing a value justified entirely by "it worked", is
exactly the shape that gets adopted quietly and blamed six months later
for something unrelated. If a probe comes back refused on this entry,
the finding reverses this decision's value without touching its
argument - the field would still be the inner PFS image, and
Builder would gain a way to override what it measures.
Answered: reading 1 (2026-09-10)
obSCEne resolved the provenance question (REQ-20260910T0325Z-6b04):
0xAA0000 was a default copied from LibOrbisPkg
samples during early bring-up, before dynamic inner-image sizing
existed, and the console accepted it without validation. So
reading 1 is the true one - the field is not checked, both values
install, and the correction is the tidiness-backed-by-arithmetic
improvement it looked like, not a regression risk.
That also retired the value for good on their side: obSCEne deleted
the hardcoded generator, and its make pkg now builds the
entry through this crate - so the number it ships is the measured
0x630000, not the old literal.
Confirmed on hardware (2026-09-10)
The caveat this entry opened with - "the corrected value has never
been on hardware" - is now closed. obSCEne ran a full package sweep on
target hardware (REQ-20260910T0520Z-9c33, sweep
20260910-161904): a package built with the auto-generated
0x1001 carrying the computed 0x630000
installs and launches cleanly, 54 sections to
completion, 174 pass, scePlayGoCoreGetRawContentInfo
accepting it without refusal. So the value is no longer justified by
arithmetic alone - it is a measurement of acceptance on the console, the
standard this repository holds a container to. The change is settled in
both directions: the old value's provenance explained, and the new
value's acceptance demonstrated.