Decision log

Append-only. Every decision that shaped this codebase, with its reasoning, so it can survive a context compaction and so nobody re-litigates a settled question from first principles six weeks later.

Read this file at the start of any working session.

On the Python tools named in early entries. Entries before D026 refer to nid.py, verify.py, pretty.py and tools/test-tools.sh. Those are gone - D026 records replacing them with the Rust obscene-tool, whose subcommands carry the same names.

The references are left as written, because this file is a dated record of what was decided when, and editing a decision to match the present destroys the only thing it is for. Live documentation points at the current tool; this file points at what existed at the time.

This table is generated. Edit an entry under decisions/, then run tools/split-decisions.sh --index obscene. A number resolves to exactly one file.

# decision status date
🟡 D001 Two builds from one source tree assumed 2026-08-19
🟢 D002 Announce before attempting decided 2026-08-19
🟡 D003 One machine-readable format; colour lives in a script assumed 2026-08-19
🟡 D004 Four statuses, not three assumed 2026-08-19
🟡 D005 Freestanding C, clang only, no vendor SDK assumed 2026-08-19
🟡 D006 Output through the platform's own write, to descriptor 1 assumed 2026-08-19
🟡 D007 Check from the failure side where layouts are unknown assumed 2026-08-19
🟢 D008 Nothing is invented; uncertain signatures are omitted decided 2026-08-19
🟡 D009 The section order is one explicit list assumed 2026-08-19
🟡 D010 Dependencies are capability bits, not check names assumed 2026-08-19
🟢 D011 The synthetic error code is 0xDEADBEEF, returned unmodified decided 2026-08-19
🟡 D012 The build directory is overridable, and has to be assumed 2026-08-19
🟡 D013 The entry point returns rather than exiting assumed 2026-08-19
🟡 D014 Presence and behaviour are separate questions, measured separately assumed 2026-08-19
🟢 D015 A census of absences needs a control in both directions decided 2026-08-19
🟢 D016 The census lists are fenced off from clang-format decided 2026-08-19
🟢 D017 The C runtime is a first-class section, and it is where positive checks live decided 2026-08-19
🟡 D018 Prefer documentation over binary extraction when sourcing names assumed 2026-08-19
🟢 D019 The diff is the point; the report format is downstream of it decided 2026-08-19
🟡 D020 The tooling has tests, and they run against real reports assumed 2026-08-19
🟡 D021 Symbols carry which console generation they belong to assumed 2026-08-19
⚪ D022 Symbol encoding is a build option, and the suffix is never committed partly-superseded 2026-08-19
⚪ D023 The suffix is committed and labelled partly-superseded 2026-08-19
🟢 D024 The NID chain is pinned by a published test vector, not by prose decided 2026-08-19
🟢 D025 Unknown format constants are measured from a loader, not read from a parser decided 2026-08-19
🟢 D026 The tooling is Rust, in one binary decided 2026-08-19
🟢 D027 The vendor dynamic segment is built on every module build, not behind a flag decided ~2026-08-19..08-20
🟢 D028 The tag derivation is a command that runs on every build, not a paragraph decided ~2026-08-19..08-20
🟢 D029 Three loadable segments, because a fourth is refused decided ~2026-08-19..08-20
🟢 D030 The string table is the first entry in the dynamic table, and everything that names something comes last decided ~2026-08-19..08-20
🟢 D031 The module is built with hidden visibility and symbolic binding decided ~2026-08-19..08-20
🟢 D032 The report tries more than one way out, and says which one it used decided ~2026-08-19..08-20
🟢 D033 Which library each import comes from is published by the host build decided ~2026-08-19..08-20
🟢 D034 A finished module has no section headers decided ~2026-08-19..08-20
🟢 D035 The entry point ends the process. It does not return decided ~2026-08-19..08-20
⚪ D036 DT_SCE_JMPREL and DT_SCE_PLTRELSZ were swapped, and the derivation could not have caught it corrected ~2026-08-19..08-20
🟢 D037 puts is an output channel, tried before write decided ~2026-08-19..08-20
🟢 D038 Libraries and modules declare version 1, and they pack it differently decided ~2026-08-19..08-20
🟢 D039 Imported symbols are rewritten to STT_FUNC, and this is what makes a report come out decided ~2026-08-19..08-20
🟢 D040 Checks can be excluded at build time, and the default list is empty decided ~2026-08-19..08-20
🟢 D041 The report is drawn as well as written decided ~2026-08-19..08-20
🟢 D042 The display owns the main video output, and the video checks yield to it decided ~2026-08-19..08-20
🟢 D043 The platform is enumerated, not only asked about decided ~2026-08-19..08-20
🟢 D044 Every check records where its expectation came from decided ~2026-08-19..08-20
🟢 D045 Checks are chosen from what emulators have actually got wrong decided ~2026-08-19..08-20
🟢 D046 An intermittent failure is only a finding once it has been counted decided ~2026-08-19..08-20
🟢 D047 A function is asked whether it reads its arguments, separately from whether it is right decided ~2026-08-19..08-20
🟢 D048 The screen pages through every check, and cycles rather than waiting for input decided ~2026-08-19..08-20
🟢 D049 obscene-tool crack recovers names from NIDs by guessing, and says what a miss is worth decided ~2026-08-19..08-20
🟢 D050 The orchestration is scripts in the repository, not steps somebody remembers decided ~2026-08-19..08-20
🟢 D051 Thirty census names promoted to behavioural checks, all of them settled by a document decided ~2026-08-19..08-20
🟢 D052 div and ldiv were checked, then withdrawn to the census decided ~2026-08-19..08-20
⚪ D053 The census had been carrying a fragment of a symbol name, and now it cannot bug ~2026-08-19..08-20
🟢 D054 The emulators live in <emulators>, source and all, outside this repository decided ~2026-08-19..08-20
⚪ D055 The NID implementation now has an independent 42,010-name confirmation evidence ~2026-08-19..08-20
⚪ D056 A value check whose every expected answer is zero cannot tell a stub from a success bug ~2026-08-19..08-20
🟢 D057 libScePosix is checked, and it is the best provenance available without a console decided ~2026-08-19..08-20
⚪ D058 A check that calls a second library must test that symbol's address itself bug ~2026-08-19..08-20
🟢 D059 A third kind of record: measurements, which assert nothing decided ~2026-08-19..08-20
🟢 D060 Which clock counts what is established by experiment, not assumed decided ~2026-08-19..08-20
🟢 D061 Three loaders, not one, and the second and third each found something the first could not decided ~2026-08-19..08-20
🟢 D062 The console generation is a build option, because the loaders disagree and all of them are right decided ~2026-08-19..08-20
⚪ D063 The NID implementation agrees with an independent one on 78,372 pairs out of 78,372 evidence ~2026-08-19..08-20
⚪ D064 A correction to D063: fpPS4's table is derived from ps4libdoc, not independent of it correction ~2026-08-19..08-20
⚪ D065 The gate could not fail, and that is why everything else survived bug ~2026-08-19..08-20
⚪ D066 The rule from D058 is enforced by a script now, because writing it down did nothing bug ~2026-08-19..08-20
🟢 D067 The headline number is a frontier, not a sum decided ~2026-08-19..08-20
🟢 D068 018-relational: properties instead of values, aimed where no document reaches decided ~2026-08-19..08-20
🟢 D069 Volatile facts are generated; static facts are written. The distinction is the whole fix decided ~2026-08-19..08-20
🟢 D070 Documentation that names a command is checked against the commands that exist decided ~2026-08-19..08-20
🟢 D071 The orchestration scripts are sh. PowerShell was solving one environment variable decided ~2026-08-19..08-20
🟢 D072 obscene-tool consensus: agreement between implementations, used where hardware is not available decided ~2026-08-19..08-20
🟢 D073 Five more relations, and the one with the worst failure mode decided ~2026-08-19..08-20
🟢 D074 derived is a fifth provenance, because the FreeBSD upgrade was not the one the backlog described decided ~2026-08-19..08-20
🟢 D075 The current generation's graphics interface is censused, and its first run is the best evidence yet that presence means little decided ~2026-08-19..08-20
🟢 D076 Condition variables and barriers: the operations that cannot block were available all along decided ~2026-08-19..08-20
🟢 D077 The wakeup path is testable, and the timeout was never the thing that was needed decided ~2026-08-19..08-20
🟢 D078 The census now states its own limit, in the report, where a coverage figure gets quoted decided ~2026-08-19..08-20
🟢 D079 scripts/repeat.sh: an intermittent fault needs a denominator decided ~2026-08-19..08-20
⚪ D080 Kyty cannot emit a report, and the reason is structural rather than a missing flag closed ~2026-08-19..08-20
🟢 D081 130-layout: the instrument half. Bytes recorded, nothing interpreted decided ~2026-08-19..08-20
🟢 D082 Two more libkernel checks, and one of them found a real fault decided ~2026-08-19..08-20
⚪ D083 Why craziiEmu resolves nothing: two bugs, one fixed, and the earlier guess was wrong diagnosed ~2026-08-19..08-20
⚪ D084 obSCEne may consult other projects. orbistoun may not. The asymmetry is load-bearing correction ~2026-08-19..08-20
⚪ D085 Before believing a setting works, set it to something that must visibly break adopted ~2026-08-19..08-20
⚪ D086 Guest output may arrive on stderr, and reading only stdout would have looked like silence fixed ~2026-08-19..08-20
⚪ D087 000-boot/stack-alignment, offered by the orbistoun side and worth taking added ~2026-08-19..08-20
🟢 D088 140-oracle: asking the platform what it knows, and recording what it returns decided ~2026-08-19..08-20
🟢 D089 150-memory-map: the map walked, with the walk's own hypothesis checked as it goes decided ~2026-08-19..08-20
🟢 D090 The compatibility table is generated from reports, because a hand-written one would be stale by tomorrow decided ~2026-08-19..08-20
⚪ D091 fpPS4 builds on a stable compiler, and reads our module perfectly a ~2026-08-19..08-20
🟢 D092 Screenshots of each loader, captured on the summary screen decided ~2026-08-19..08-20
⚪ D093 What the current-generation emulators implement that obSCEne does not touch analysed ~2026-08-19..08-20
⚪ D094 Emulators are built from source. Running a binary that does not match the source read is a method error policy 2026-08-20
🟡 D095 Loaders that share a codebase count once. The compatibility table records lineage assumed ~2026-08-20..08-26
🟡 D096 The blind prober calls what it cannot describe, and that is not a breach of D008 assumed ~2026-08-20..08-26
🟡 D097 Blame for a loader failure is not assigned without a control build assumed ~2026-08-20..08-26
🟢 D098 The missing program headers come from link/module.ld, not from the link mode or the packaging. Two hypotheses were tested and both were wrong derived ~2026-08-20..08-26
🟢 D099 Two loadable segments, not three. A third was silently not mapped, and that was the crash derived ~2026-08-20..08-26
🟢 D100 DT_SCE_NEEDED_MODULE is not enough. A loader keys its implementations on the ordinary DT_NEEDED filename, and obSCEne emits none derived ~2026-08-20..08-26
⚪ D101 obSCEne runs on a second loader. DT_NEEDED was the whole of what was missing hardware-adjacent ~2026-08-20..08-26
🟡 D102 The command protocol is specified before it is implemented, and the captured exchanges are part of the contract assumed ~2026-08-20..08-26
🟢 D103 The hash is confirmed against a second, independent corpus - 281 of 281. And obSCEne will not discover a symbol it has never heard of, ever derived ~2026-08-20..08-26
🟢 D104 The report is written to a file as well, not instead. And the backend is chosen by which file is compiled derived ~2026-08-20..08-26
🟢 D105 166,960 names and 1,130,742 unnamed identifiers, from eleven sources across 23 firmware versions derived ~2026-08-20..08-26
🟢 D106 The driver, and the one thing that lives only at this end derived ~2026-08-20..08-26
🟢 D107 The console socket backend is implemented, and proven inside shadPS4 with no hardware derived ~2026-08-20..08-26
🟢 D108 A report and a corpus are different artifacts, and only the corpus carries origin derived ~2026-08-20..08-26
🟢 D109 The GPU is probed by executing shaders and reading the result bits, not by calling an API derived ~2026-08-20..08-26
⚪ D110 Generation detection exists and gates nothing. obs_detected_generation() has no callers correction ~2026-08-20..08-26
🟢 D111 One source, both generations: the display takes whichever video-out pair resolved derived ~2026-08-20..08-26
🟢 D112 GPU device selection prefers real silicon, and the device type is recorded as gradable provenance derived ~2026-08-20..08-26
🟢 D113 The unary kernel set is widened to the rest of the transcendentals, and the input vector to the edges they strain derived ~2026-08-20..08-26
🟢 D114 The blind prober covered 1% of the census, and pointing it at the rest immediately called a variable derived ~2026-08-20..08-26
🟢 D115 A gpu protocol verb dispatches a compiled-in kernel over the socket - the interactive oracle, with no rebuild derived ~2026-08-20..08-26
🟢 D116 A reference oracle, so a GPU diff says which instructions are approximate rather than merely that two runs differ derived ~2026-08-20..08-26
🟢 D117 A GPU ISA surface census, so "probe every GPU op" has a statement of what every GPU op is derived ~2026-08-20..08-26
🟢 D118 Closing the three GLSL-reachable gaps the census named, and finding a denormal difference by doing it derived ~2026-08-20..08-26
🟢 D119 Integer/bit breadth: a second GPU surface the float census did not map, and the kernels for its first four operations derived ~2026-08-20..08-26
🟢 D120 Controlled-ISA: pinning the fast SFU path against the correctly-rounded one, through the precision the SPIR-V asks for derived ~2026-08-20..08-26
⚪ D121 Console generation is observed, never asserted from presence implemented ~2026-08-20..08-26
🟢 D122 Protocol completion: the blob/run/reset verbs, with the escape hatch off unless a build asks for it derived ~2026-08-20..08-26
🟢 D123 A golden GPU corpus and a regression check, so a change to a kernel's output is caught even where the reference stays silent derived ~2026-08-20..08-26
🟢 D124 More execution breadth: bitfield ops, an FTZ probe, and a bit-pattern input vector for the kernels that work on bits derived ~2026-08-20..08-26
🟢 D125 A gate is not trusted until it has been shown to reject something derived ~2026-08-20..08-26
🟢 D126 The command socket, and why the console backend is deliberately empty derived ~2026-08-20..08-26
🟢 D127 obSCEne's display targets the previous generation's video-out interface. That is why it draws nothing on a current-generation loader derived ~2026-08-20..08-26
🟢 D128 30,610 names mined from seven emulators. The hash reproduces 30,137 of them, and every exception is the source's naming, not the hash derived ~2026-08-20..08-26
🟢 D129 call and read are implemented, proven live over a socket derived ~2026-08-20..08-26
🟢 D130 The census is 5,909 symbols. Growing it turned "present" from a weak signal into a measurement of the loader derived ~2026-08-20..08-26
🟢 D131 GPU kernels are authored in bulk from a generated list, and the GPU capability is gated derived ~2026-08-20..08-26
🟢 D132 A serving build listens first and runs the suite on demand. The report streams over the socket. A named Deck target exists derived ~2026-08-20..08-26
🟢 D133 A consumer's strict decoder found a defective fixture the checker had passed. Both are fixed derived ~2026-08-20..08-26
🟢 D134 Multi-operand kernels sweep the operand cross-product, in a new record that leaves the unary one untouched derived ~2026-08-20..08-26
⚪ D135 The non-platform corpus is the console's own software, and it is a different target rather than a worthless one correction ~2026-08-20..08-26
🟢 D136 352 libraries and 35,518 imports load and run. The ceiling was far higher than assumed derived ~2026-08-20..08-26
🟢 D137 The GPU corpus diff, so a hardware run ends in a gap list rather than a pile of records derived ~2026-08-20..08-26
🟢 D138 A symbol can be imported with no name at all. The identifier is the import; the name only ever existed to compute it derived ~2026-08-20..08-26
🟢 D139 A platform HUD replaces the static tagline: every system fact, value or unknown derived ~2026-08-20..08-26
🟢 D140 A resolved address proves nothing on a loader that stubs what it cannot resolve. The display learned this the hard way derived ~2026-08-20..08-26
🟢 D141 Two loose ends closed: the generation had two inferences, and the generated censuses had no gate derived ~2026-08-20..08-26
⚪ D142 Seventeen decisions were sharing thirteen numbers, and nothing was checking. The log now gates its own numbering unrecorded ~2026-08-20..08-26
⚪ D143 The corpus records what it was mined from, so the half of census drift nothing was watching becomes visible unrecorded ~2026-08-20..08-26
⚪ D144 A timeout is not a hang, and two timeouts are. The sweep now measures the difference instead of asking an operator to assert it unrecorded ~2026-08-20..08-26
⚪ D145 An exclusion entry with no / names a whole section, because a loader can fail a layer rather than a check unrecorded ~2026-08-20..08-26
🟢 D146 Pack/unpack conversions, and the per-kernel input scheme they needed derived ~2026-08-20..08-26
⚪ D147 The three letters in the middle of the name are marked wherever the project renders it unrecorded ~2026-08-20..08-26
🟢 D148 gpustats: the diff as a distance, so the approximation is a number, not a yes/no derived ~2026-08-20..08-26
⚪ D149 A censused library is not a load-time dependency, and saying it is stops obSCEne loading on current shadPS4 at all defect ~2026-08-20..08-26
🟢 D150 The hardware day made turnkey: one analysis command and a runbook, so a Deck corpus needs no new thinking derived ~2026-08-20..08-26
⚪ D151 The blind prober does not belong on the host build, and the harness did not scale to the corpus. Both were found by running it unrecorded ~2026-08-20..08-26
🟢 D152 The Gnm command-building API probe: the console GPU's own calls, the other GPU axis - and a correction to having dismissed it derived ~2026-08-20..08-26
🟢 D153 Scoping the Gnm execution axis: the GCN shader is not the blocker; the input struct layouts are derived ~2026-08-20..08-26
⚪ D154 Three threading contract probes, added at the sibling project's request unrecorded ~2026-08-20..08-26
⚪ D155 One source, as many binaries as the targets need. Single-binary was never the goal and is not a constraint to design around unrecorded ~2026-08-20..08-26
⚪ D156 The compatibility table ignored the census control that was in every report, and presented a void count beside a measured one unrecorded ~2026-08-20..08-26
⚪ D157 The runtime census exists, and its first run settled what the address census could not unrecorded ~2026-08-20..08-26
⚪ D158 Two relational checks had never run anywhere, and the report said so in words that read as a platform limitation unrecorded ~2026-08-20..08-26
⚪ D159 The two new threading relations spin for their child rather than joining it unrecorded ~2026-08-20..08-26
⚪ D160 The flag sweep: measurable without a console, and the dump answered the wrong call unrecorded ~2026-08-20..08-26
⚪ D161 bulk-sweep.sh resumes, because the round budget is the binding constraint and not the size of the surface unrecorded ~2026-08-20..08-26
⚪ D162 A round that produced nothing is retried once unrecorded ~2026-08-20..08-26
⚪ D163 Correction: the blind prober walks the corpus, not the curated census unrecorded ~2026-08-20..08-26
⚪ D164 The blind prober's classifier keeps privileging 0x8002, and the facility table stays out of the probe unrecorded ~2026-08-20..08-26
⚪ D165 The command socket takes a session secret, generated per startup and displayed unrecorded ~2026-08-20..08-26
⚪ D166 A test asserted the opposite of what sceKernelClearEventFlag does, and the stub agreed unrecorded ~2026-08-20..08-26
⚪ D167 The blind prober against a current-generation loader: the two emulators are opposites, and twelve functions hand the guest a host address unrecorded ~2026-08-20..08-26
⚪ D168 A comment inside a table row's braces made a check invisible to every gate, and nothing failed unrecorded ~2026-08-20..08-26
⚪ D169 The provenance ladder gains a rung: implementations unrecorded ~2026-08-20..08-26
⚪ D170 Anchored prose: a document may state one checkable fact about the source beside the passage that depends on it unrecorded ~2026-08-20..08-26
⚪ D171 fpPS4 writes a pointer-sized semaphore handle through an int *, and the check that found it described the wrong thing unrecorded ~2026-08-20..08-26
⚪ D172 The exclusion list moved from build time to run time, so one ELF runs on every loader unrecorded ~2026-08-20..08-26
⚪ D173 The module now carries a DT_INIT, because a loader may call one and ours pointed at the ELF header unrecorded ~2026-08-20..08-26
⚪ D174 The screen said nothing about what it was doing, and the first fix for that made the probe worse unrecorded ~2026-08-20..08-26
⚪ D175 e_type was 0xFE18 - the shared-library type - and the constants were named backwards unrecorded ~2026-08-20..08-26
🟡 D176 A loader can be patched to let the probe run, and doing so measures the patch assumed ~2026-08-20..08-26
🟡 D177 The mutex type constants are one-based and are not the POSIX values assumed ~2026-08-20..08-26
🟢 D178 The shell's process id is not the loader, and the runner had already learnt that once decided ~2026-08-20..08-26
🟢 D179 Four shapes, two axes, and the filename now says which decided ~2026-08-20..08-26
🟢 D180 The loading mechanism is coverage surface, so each one is an artifact decided ~2026-08-20..08-26
🟡 D181 Runtime resume can lose twenty thousand measurements and still report success assumed ~2026-08-20..08-26
🟢 D182 The container format is derived the way NIDs already are: binaries outside, provenance-headed data inside decided ~2026-08-20..08-26
🟢 D183 A shell exists on the real target after all, and the protocol survives it for a better reason decided ~2026-08-20..08-26
🟢 D184 Hardware is registered, and its capabilities are measured on every use rather than stored decided ~2026-08-20..08-26
🟢 D185 mkself works, and the loader that rejected it first is why decided ~2026-08-20..08-26
🟡 D186 The module version is per library, and declaring one value for all of them was why nothing appeared on screen assumed ~2026-08-20..08-26
🟡 D187 "The display accepted it" and "a frame reached the screen" are different facts, and the report only carried the first assumed ~2026-08-20..08-26
🟢 D188 Retail titles render and a CPU-drawn framebuffer does not, and the difference is who wrote the pixels decided ~2026-08-20..08-26
🟢 D189 The half of hardware.rs that talked to a console now lives in a shared crate, and this project depends on it by path decided ~2026-08-20..08-26
🟢 D190 The tool fetches the report off the console itself, rather than telling somebody to go and get it decided ~2026-08-20..08-26
🟢 D191 A check must fail to return on two consecutive runs before it is skipped decided ~2026-08-20..08-26
🟢 D192 A project that reads the others is not another vote, and prosper says so in its own comments decided ~2026-08-20..08-26
🟡 D193 obSCEne writes a dynamic table no retail current-generation module uses, and six real dumps say so assumed ~2026-08-20..08-26
🟢 D194 grep -q reading a Windows program deadlocks the harness, and it hid as a timeout bug for hours derived ~2026-08-20..08-26
🟢 D195 prosper is the sixth loader, the only headless one, and the first to have ground truth to check us against derived ~2026-08-20..08-26
🟢 D196 fpPS4 does not crash on an unimplemented import - it sleeps forever, and that is one line derived ~2026-08-20..08-26
🟢 D197 A consensus across generations is not a consensus, and mixing them destroyed the signal derived ~2026-08-20..08-26
🟢 D198 verify.sh takes fifty minutes, none of it work, and D012's rule had one more place to apply derived ~2026-08-20..08-26
🟢 D199 Five scripts were still driving a build environment that had been deleted that morning derived 2026-08-26
⚪ D200 The file formats moved to selfish, and this repository now depends on them unrecorded ~2026-08-26..08-27
⚪ D201 The migration found four things wrong, and three of them were wrong here unrecorded ~2026-08-26..08-27
⚪ D202 A mined-corpus name that a section wants to call is declared in the section, not in platform.h unrecorded ~2026-08-26..08-27
⚪ D203 105-record, not 170-record: the section numbers carry the layering and the report contract enforces it unrecorded ~2026-08-26..08-27
🟢 D204 The layout verdict counted non-zero bytes while its dump counted changed bytes derived ~2026-08-26..08-27
🟢 D205 First contact with a console, and the answer arrived in ninety seconds: elfldr does not resolve our imports hardware 2026-08-27
🟢 D206 The console runs our payload - the blocker was 16 KB pages, and the loader blocks direct syscalls and passes a bootstrap hardware 2026-08-27
🟢 D207 The backtrace-echo readout is defeated by log caching, and the signal ladder is the trustworthy channel hardware ~2026-08-27
🟢 D208 The payload ABI is fully mapped, and the frontier is precise: word 0 is not a working resolver in the sandbox hardware 2026-08-27
🟢 D209 obSCEne runs on a real PS5 and produces a report with hardware provenance - the first in the project's history hardware 2026-08-27
🟢 D210 Video is reachable from the payload, but the display is owned by the system hardware 2026-08-27
🟢 D211 A general payload crt0 resolves obSCEne's imports on-device - proven on hardware, and the artifact that moves into selfish hardware 2026-08-27
🟢 D212 obSCEne is built by selfish, deployed by prosperous, and runs on the console - the toolchain is real hardware 2026-08-27
🟢 D213 The payload path split along selfish's charter: format knowledge in selfish, runtime in obSCEne - and multi-library resolution works hardware 2026-08-27
🟢 D214 Rendering is blocked by process context, not by the toolchain - the injected process has no display to own hardware 2026-08-27
🟡 D215 selfish is made the explicit, required build path - in the Makefile, in CI, and through a wired make pkg assumed ~2026-08-27..08-29
🟡 D216 obSCEne's end of "the real way" is built and waiting on one selfish command - install and launch via prosperous, into a foreground context assumed ~2026-08-27..08-29
🟢 D217 Import libraries are numbered from zero, needed modules from one decided 2026-08-29
🟢 D218 MIN_DEFINES, and what the importless control turned out not to prove decided 2026-08-29
⚪ D219 The process parameters carry three structures, and the libc one is not optional unrecorded ~2026-08-29..08-30
⚪ D220 The bundled modules are built here, never copied unrecorded ~2026-08-29..08-30
⚪ D221 --kind, replacing --fixed, and the library id base that goes with it unrecorded ~2026-08-29..08-30
⚪ D222 What a bundled library must carry, found one refusal at a time unrecorded ~2026-08-29..08-30
⚪ D223 The title id lives in the content id, and a fresh one routes around a stuck title unrecorded ~2026-08-29..08-30
⚪ D224 The bundled stubs must not be named after a library, and the guard was checking the wrong list unrecorded ~2026-08-29..08-30
⚪ D225 The report goes to the system log first, because a title has no descriptor unrecorded ~2026-08-29..08-30
⚪ D226 An eboot may not require more libraries than a title can load unrecorded ~2026-08-29..08-30
⚪ D227 The harness needs two libraries; the other 350 are measurements unrecorded ~2026-08-29..08-30
⚪ D228 The eboot does not link the census, and the census says so unrecorded ~2026-08-29..08-30
⚪ D229 The census resolves at run time, so an unloadable library is a finding unrecorded ~2026-08-29..08-30
⚪ D230 The generation probe asked by linking, and could have killed what it was probing unrecorded ~2026-08-29..08-30
⚪ D231 EBOOT_KIND, so the same eboot can be put through an emulator first unrecorded ~2026-08-29..08-30
⚪ D232 The run-time census needs a control, because "no" has two meanings unrecorded ~2026-08-29..08-30
⚪ D233 The system log is a second destination, not a candidate channel unrecorded ~2026-08-29..08-30
⚪ D235 "Not present on this platform" was a claim the harness could not support unrecorded ~2026-08-29..08-30
🟢 D236 What a sweep proved crashes belongs in the repository, not in a build directory decided ~2026-08-29..08-30
🟢 D237 The report's file mode is set for the reader, and the reader is never the writer decided ~2026-08-29..08-30
🟢 D238 /download0 exists only while the title does measured ~2026-08-29..08-30
🟢 D239 A run-time module load does not repair an import the loader left unresolved measured ~2026-08-29..08-30
🟢 D240 import records, because the census cannot see this program's own imports decided ~2026-08-29..08-30
🟢 D241 An identity word that decodes cleanly is not a well-formed identity word decided ~2026-08-29..08-30
🟢 D242 sce_process_param was almost entirely empty, and one field's comment was evidence-free measured ~2026-08-29..08-30
🟢 D243 A fact held only in a generated file is held nowhere decided ~2026-08-29..08-30
🟢 D244 Declaring a real SDK version stops sceKernelDlsym answering measured ~2026-08-29..08-30
🟢 D245 The section written to explain D235 committed D235 decided ~2026-08-29..08-30
🟢 D246 A placeholder in a symbol field is not a symbol decided ~2026-08-29..08-30
🟢 D247 An unbound import is unbound in the PLT too, so the gating is right measured ~2026-08-29..08-30
🟢 D248 Every import was weak, and a loader took that at its word measured ~2026-08-29..08-30
🟢 D249 The display path threw away every code it was given decided ~2026-08-29..08-30
🟢 D250 The display held the output while answering that it did not measured ~2026-08-29..08-30
🟢 D251 A sweep inside the probe, instead of a rebuild per guess decided ~2026-08-29..08-30
🟢 D252 Two codes from one call are worth more than one code from two runs measured ~2026-08-29..08-30
🟢 D253 The framebuffer alignment, which was the answer all along measured ~2026-08-29..08-30
🟢 D254 Double-buffering prevents screen tearing during report rendering decided ~2026-08-29..08-30
🟢 D255 GEN in compatibility mode is ps4_mode, not unknown or gen4 measured ~2026-08-29..08-30
🟢 D256 Bounded flip wait ensures display flip takes effect measured ~2026-08-29..08-30
🟢 D257 Frame count advancement confirms presentation measured ~2026-08-29..08-30
🟢 D258 Display HUD integration preserves headless execution decided ~2026-08-29..08-30
🟢 D259 The D-pad pages the results; the auto-cycle is the floor, not the mechanism decided ~2026-08-29..08-30
🟢 D260 Per-file objects, so a build recompiles only what changed measured ~2026-08-29..08-30
🟢 D261 Firmware is the console's, not the compatibility environment's measured ~2026-08-29..08-30
🟢 D262 A build with no status bar does not gather what would fill one decided ~2026-08-29..08-30
🟢 D263 The GEN field names the mode when it cannot name the console; the PS4-compat version is its own field decided ~2026-08-29..08-30
🟢 D264 Export vaddrs are confirmed by behaviour, not read from firmware hardware 2026-08-30
⚪ D265 obscene-tool vaddrs: exports resolved to names, in the tool not a script unrecorded ~2026-08-30..08-31
⚪ D266 Three checks staged for the next hardware run: the layout of a memory type, whether a short size bounds a write, and more export candidates unrecorded 2026-08-31
⚪ D267 The package must stage sce_module/, and a rewrite dropped it unrecorded ~2026-08-31
🟢 D268 On-console libkernel export table enumeration replaces offline sprx dumps done ~2026-08-31
🟢 D269 One verb per hardware task; the report comes off the system log, in the tool done ~2026-08-31
🟢 D270 Real hardware is a pointer from the compatibility table, not a column in it done ~2026-08-31
🟢 D271 The report screen wraps into two columns before it overruns the totals done ~2026-08-31
🟢 D272 A GPU field for the driver, DISK wired through statfs; TEMP stays honestly unknown done ~2026-08-31
🟢 D273 The payload round-trip is a verb too: ./bin/obscene payload done ~2026-08-31
🟢 D274 The TSC-frequency signature is a band, not an equality; four more export candidates measured 2026-08-31
🟡 D275 a measured run-context axis, and the loaded-module link-map that feeds it assumed ~2026-08-31..09-01
🟡 D276 payload mode is the ps4 backward-compatibility context assumed ~2026-08-31..09-01
🟡 D277 enumerate modules by base+vaddr, the way past a payload's three shut doors assumed ~2026-08-31..09-01
🟢 D278 obscene-injector: decoupled freestanding ELF injection via session kernel R/W decided ~2026-08-31..09-01
🟢 D279 canonical release artifact naming scheme across CI workflows and frontend decided ~2026-08-31..09-01
🟡 D280 Porthole scaffolded, and the encoder reachability made a section (106-encoder) assumed 2026-09-01
🟢 D281 Projects live under src/, and the encoder section finished its wiring decided 2026-09-01
⚪ D282 dlsym gets its positive: a known symbol through a valid handle unrecorded ~2026-09-01..09-02
⚪ D283 flexible-configured: the probe orbistoun's allocator work was blocked on unrecorded ~2026-09-01..09-02
⚪ D284 obs_read_header is bounded by the caller's buffer, not by a constant unrecorded ~2026-09-01..09-02
⚪ D285 the measured value is reported on every row, not only on a difference unrecorded ~2026-09-01..09-02
⚪ D286 container-structure: a raw measured dump of a real gen-5 container unrecorded ~2026-09-01..09-02
⚪ D287 the native title carries its eboot and is a ./bin/obscene verb unrecorded ~2026-09-01..09-02
⚪ D288 the title identity has one home: data/identity.toml unrecorded ~2026-09-01..09-02
⚪ D289 the eboot container generation follows EBOOT_GEN unrecorded ~2026-09-01..09-02
⚪ D290 the ctype table accessors get a library assignment unrecorded ~2026-09-01..09-02
⚪ D291 native deploy uploads the title dir to a scan root via prosperous unrecorded ~2026-09-01..09-02
⚪ D292 the native title gets its own id, distinct from the package unrecorded ~2026-09-01..09-02
⚪ D293 a real ps5 native title uses the 4F 15 3D 1D eboot, so native defaults to it unrecorded ~2026-09-01..09-02
⚪ D294 SceShellUI restart recovers from VSH UI softlocks unrecorded 2026-09-02
⚪ D295 Dynamic module resolution for non-essential libraries unrecorded 2026-09-02
⚪ D296 Four-tier privilege model and module categorization unrecorded 2026-09-02
⚪ D297 External SDK Version Dictionary and Targeted SDK Builds in SELFish and obSCEne unrecorded 2026-09-02
⚪ D298 PT_SCE_PROCPARAM and PT_SCE_MODULE_PARAM Contracts on PS5 Native unrecorded 2026-09-02
⚪ D299 Reproducible Process Parameter Audit in 048-selfaudit unrecorded 2026-09-02
🟢 D300 Porthole encoder self-resolution: loading VENC sysmodule and export table traversal decided 2026-09-03
⚪ D301 Application Category, Privilege Tiers, and Display Arbitration on PS5 Native unrecorded 2026-09-03
⚪ D302 The conformance matrix - one capture per launch shape, named for the shape unrecorded 2026-09-03
🟡 D303 a scalar out-parameter is poisoned, not zeroed assumed 2026-09-03
🟢 D314 the decision gate checks the log this repository actually has decided 2026-09-03
🟢 D315 a document beside a Makefile means that Makefile decided 2026-09-03
🟢 D316 Porthole input injection via Ghostpad Virtual Device Interface (VDI) decided 2026-09-03
🟢 D317 Porthole video pipeline reusing oops-sdk display and direct memory decided 2026-09-03
🟢 D320 the orbistoun backlog is generated and tiered by what blocks it decided 2026-09-03
🟡 D321 the encoding and bounds probes poll rather than wait, and resolve by name assumed 2026-09-07
🟡 D322 the futex is called rather than censused, and every wait runs on a thread nobody joins assumed 2026-09-07
🟡 D323 the eboot resolves its output by name, and never calls a raw import assumed 2026-09-07
🟡 D324 a title entry is not a payload_args, so the dlsym gadget is validated before use assumed 2026-09-07
🟡 D325 a fault guard catches a crashing check, so the suite continues assumed 2026-09-07
🟡 D326 the guard carries its own setjmp and imports its signal primitives, so a native title is guarded assumed 2026-09-08
🟡 D327 the payload zeroes its own .bss, because elfldr does not assumed 2026-09-08
🟡 D328 a pending status, and peripheral probes that wait for their input rather than failing assumed 2026-09-08
🟡 D329 a network section for Porthole, and a record for "I could not look" assumed 2026-09-08
🟢 D330 Audio format selectors, mouse stubs in unsigned payloads, and POSIX sockets for Porthole decided 2026-09-08
🟢 D331 The *GetSize family is measured against its own builder, not against a borrowed number decided 2026-09-12
🟢 D332 Hardware AGC Requests, Clean-Room Container Generation, and Sandbox POSIX Probing decided 2026-09-14
meaning
🟢 settled, and the reasoning rests on something checkable
🟡 assumed or proposed - made without input, and in the review queue
🔴 reversed, superseded or blocked
⚪ no status recorded

A date with ~ is not recorded - it is worked out from the dated entries either side, because an entry between two of them was written between their dates. ~ alone is a day both neighbours agree on; ~a..b is a span, and no day inside it is claimed; ~>a and ~<a are entries with a dated neighbour on only one side. A bare - has no dated entry either side to reason from.