D302 - The conformance matrix - one capture per launch shape, named for the shape
Status: [decided] Date: 2026-09-03
Context: data/hardware/ had accumulated
five files named on four different principles, and a third hardware
capture arrived with nowhere obvious to put it.
The problem
The directory named its contents by whatever seemed salient at the time:
| file | named for |
|---|---|
ps5-full.txt |
the suite's scope |
ps5-imports.txt |
a record type it added |
crashers.txt |
a finding |
libkernel-vaddrs.txt |
a symbol class |
ps5-sprx-manifest.tsv |
a survey |
Four principles, five files. None of the names says how the
artefact was launched, which is the axis that changes the
answers: a native title-eboot run answered
sceKernelLoadStartModule differently from the module-target
runs, and nothing in either filename would have predicted it.
The convention
A capture is named for the cell it fills, and nothing else identifies it:
obscene-probe-<target>-<mode>-<privilege>-<category>.log
| axis | values | from |
|---|---|---|
| target | hardware orbistoun shadps4
fpps4 host |
who ran it |
| mode | ps5 ps4 elf |
native title, backwards-compatible title, raw payload |
| privilege | app sysmodule system
root |
the authority id in the SELF header (D301) |
| category | bigapp systemapp miniapp
none |
applicationCategoryType (D301) |
obscene-tool matrix reads the directory and parses the
names. The directory is the matrix, so a cell nobody
added is a cell nobody can forget to pass on a command line - which is
the difference from consensus, where the caller supplies
name=path pairs by hand.
Category is an axis because D301 measured it being one
The obvious scheme has three axes and files by privilege alone. That
would be wrong, and this project's own measurement from the same day
says so: privilege tier and application category are
independent, and the one governing direct memory and
display is category. At the same root privilege,
category 0 got full Big App resources while category 65536 got
zero bytes of direct memory and
sceVideoOutOpen refusing 0x80290001.
Filing those two runs in one cell would make every memory and display measurement read as a disagreement with itself, and the report would blame whichever target was named second.
none is a
category, and not a default
A raw ELF carries no param.json, so it has no
applicationCategoryType. Recording one would be inventing a
fact about a file that does not have the field, which is principle
2.
Latest per cell, overwritten in place
A capture is not accumulated with a date suffix. The
history of a cell is the file's history, and reconstructing
git log by hand in a directory listing is strictly worse
than using it.
The argument against - that the spread across runs is the
finding, since only disagreement distinguishes a constant from a
per-boot calibration - is real but does not need dated files: each cell
is a different run, so the spread is visible across the
matrix as well as across time. And where a value genuinely
varies between two runs of the same cell, git log -p on
that one file is a better record than two files whose relationship is
implied by their names.
Hardware is the authority, not a vote
consensus.rs opens by stating that nothing in this
suite carries hardware provenance, and until a console is available
nothing will, and builds a substitute oracle out of
majority-agreement between emulators. That was correct when it was
written.
A console answers now. So where a
hardware cell is present, it settles the question and the
other cells are measured against it - an emulator disagreeing with three
other emulators is interesting, and an emulator disagreeing with the
console is simply wrong. Where no hardware cell is present, disagreement
is reported as unsettled rather than blamed on anybody,
and the report says so in as many words.
consensus is not replaced: majority agreement is still
the right tool for the shapes no console has run.
Missing cells come from evidence, not from the cross-product
The full product is 5 x 3 x 4 x 4 = 240 cells, almost all meaningless
- a raw ELF has no category, nothing runs a mini app as root. So a gap
is defined as a shape somebody has already produced that another
target lacks: if hardware was captured as
ps5/root/bigapp, an emulator that never ran that shape is a
real gap; a shape nobody has run anywhere is not.
Reported because a matrix showing only the cells it holds looks complete when it is two runs out of twelve.
What is not settled
The existing five files are not migrated by this
decision. Two of them are the awkward case:
ps5-full.txt and ps5-imports.txt are both
module-target hardware runs at the same privilege, so they
are one cell under this scheme - but they are not the same run repeated,
they are different suite configurations (one emits
import records, the other does not). The right fix is for
the probe to emit those records unconditionally, at which point they
collapse to one cell honestly rather than by discarding a
difference.
The other three - crashers.txt,
libkernel-vaddrs.txt, ps5-sprx-manifest.tsv -
are derived findings, not runs, and want a separate
home rather than a cell.
Neither is done here, because both discard or move committed evidence and that is a decision for the person whose console produced it.
Also unresolved: the two older captures carry no
OBS|context record at all, only OBS|build. So
there is nothing in them to derive a mode or a category from, and the
probe should start emitting context unconditionally before
anything tries.