Decisions

Numbered, with reasoning, as they are made. The reasoning is the point - it is what stops a choice being re-litigated by somebody who only has the choice.

None of D001-D066 carries a date, and none is being invented. The oldest file in the tree is stamped 2026-08-26, so the whole log was written across two days - that bound is checkable and a per-entry date would not be. Entries from D067 on carry one.

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

# decision status date
🟢 D001 A fourth repository, holding formats and nothing that knows what a consumer is for decided ~<2026-08-29
🟢 D002 The generation is a type with no Default decided ~<2026-08-29
🟡 D003 "Not an SDK" was the wrong line. The line is knowledge against runtime assumed ~<2026-08-29
🟢 D004 One import hash, pinned by 389 pairs somebody else produced decided ~<2026-08-29
🟡 D005 OOPS is additive, never required assumed ~<2026-08-29
🟢 D006 Entry answers for itself, because the first version of it could not be called decided ~<2026-08-29
🟢 D007 The container is byte-identical to the implementation it replaces decided ~<2026-08-29
🟢 D008 The package's outer layer first, because it needs no cryptography decided ~<2026-08-29
🟢 D009 The crypto chain is unchanged between generations, and that is a finding decided ~<2026-08-29
🟢 D010 Every container in three current-generation packages uses the previous generation's magic decided ~<2026-08-29
🟢 D011 The image offset is a header field, and the evidence that it was not could not have failed decided ~<2026-08-29
🟢 D012 What a package writer still needs, and what it does not decided ~<2026-08-29
🟢 D013 Two vendor tag ranges, and each side documented only the one it uses decided ~<2026-08-29
🟢 D014 Reassembly is the inverse of building, and both live together decided ~<2026-08-29
⚪ D015 selfish-elf depends on selfish-nid, which reorders the spine unrecorded ~<2026-08-29
⚪ D016 An import's library is looked up by its id, not by its position in the table unrecorded ~<2026-08-29
⚪ D017 Relocations are read and censused here; applying them stays with the consumer unrecorded ~<2026-08-29
⚪ D018 An unrecognised relocation type gets no name unrecorded ~<2026-08-29
⚪ D019 The PARAM.SFO alignment rule came from a source and was refuted by eleven files unrecorded ~<2026-08-29
⚪ D020 Unterminated text is a separate value variant, not a flag unrecorded ~<2026-08-29
⚪ D021 There is a second package magic, and it is named and refused rather than guessed at unrecorded ~<2026-08-29
⚪ D022 Package writing stays blocked, and the source that looked like it might unblock it does not unrecorded ~<2026-08-29
⚪ D023 Sections are a separate module from dynamic, because they answer a different question unrecorded ~<2026-08-29
⚪ D024 The linker script moves here, and its constants are tested against the crate's unrecorded ~<2026-08-29
⚪ D025 The dynamic-table writer moves here, and the manifest stays with the caller unrecorded ~<2026-08-29
⚪ D026 The end-to-end test is the point of putting both halves in one crate unrecorded ~<2026-08-29
⚪ D027 Filesystem writing is blocked, and now measured rather than asserted unrecorded ~<2026-08-29
⚪ D028 The header identity is stamped here too, and e_type is a parameter rather than a constant unrecorded ~<2026-08-29
⚪ D029 The first consumer migrated, and the migration was the best review this repository has had unrecorded ~<2026-08-29
⚪ D030 The two halves check each other where material is unavailable unrecorded ~<2026-08-29
⚪ D031 The command-line tool does not panic when a pipe closes unrecorded ~<2026-08-29
⚪ D032 This repository gets a CI workflow, and obSCEne's is marked as unable to pass unrecorded ~<2026-08-29
⚪ D033 The six unknown package entries all vary between titles, so there is no constant to fall back on unrecorded ~<2026-08-29
⚪ D034 Two package entries were derived rather than cited, and there is a command that re-derives them unrecorded ~<2026-08-29
⚪ D035 A derivation ships with the command that re-runs it unrecorded ~<2026-08-29
⚪ D036 Entry 0x80 is a digest manifest over named things, and two of its slots are established unrecorded ~<2026-08-29
⚪ D037 A package writer that refuses to invent the entries nothing established explains unrecorded ~<2026-08-29
⚪ D038 What the cryptographic entries are not, recorded so nobody re-runs the searches unrecorded ~<2026-08-29
⚪ D039 LibOrbisPkg named all six, and the derivations were right unrecorded ~<2026-08-29
⚪ D040 PLAYGO_CHUNK_SHA is solved, and material settled what the source left open unrecorded ~<2026-08-29
⚪ D041 The licence entries are stored encrypted, so naming them was not enough unrecorded ~<2026-08-29
⚪ D042 The filesystem superblock was never a wall - it was 95 unnamed bytes unrecorded ~<2026-08-29
⚪ D043 Naming a field is not the same as being able to write one unrecorded ~<2026-08-29
⚪ D044 The licence entries were never unknown - a thirty-two-byte record, not three fields unrecorded ~<2026-08-29
⚪ D045 Understood is not written unrecorded ~<2026-08-29
⚪ D046 The licence structure is measured; producing one needs two keys this repository does not hold unrecorded ~<2026-08-29
⚪ D047 A licence is built from scratch, and a real one is reproduced byte for byte unrecorded ~<2026-08-29
⚪ D048 pack now demands only what a title is, not what a package is unrecorded ~<2026-08-29
⚪ D049 The filesystem is built in two halves, because a package has two filesystems built to different rules unrecorded ~<2026-08-29
⚪ D050 PFSC does not compress, and that is the format rather than a shortcut unrecorded ~<2026-08-29
⚪ D051 The two ways of writing a 1 near the end of the superblock are two fields, not one unrecorded ~<2026-08-29
⚪ D052 A block signature is an HMAC under a key the builder computes unrecorded ~<2026-08-29
⚪ D053 Signature ordering is the correctness argument, so it is written as one sequence unrecorded ~<2026-08-29
⚪ D054 The key blobs are computed, and the proof is that they come out byte-identical to real packages unrecorded ~<2026-08-29
⚪ D055 The passcode reaches further than the key blobs, and a test keyed a package differently to find out unrecorded ~<2026-08-29
⚪ D056 The header past 0x410 was entirely zero, so nothing could be mounted unrecorded ~<2026-08-29
⚪ D057 The flat path table is real now, and it was built precisely because nothing here reads it unrecorded ~<2026-08-29
⚪ D058 selfish image exists because another session asked for it in a script comment unrecorded ~<2026-08-29
⚪ D059 A param.sfo is a format and belongs here. An icon is a picture and does not unrecorded ~<2026-08-29
⚪ D060 The default icon is selfish's own mark, reversing D059 unrecorded ~<2026-08-29
⚪ D061 The param.sfo field set was the previous generation's, and two homebrew packages said so unrecorded ~<2026-08-29
⚪ D062 A second PARAM.SFO implementation, and why it happened unrecorded ~<2026-08-29
⚪ D063 One directory-entry writer, because the copy had the rule without the reasoning unrecorded ~<2026-08-29
⚪ D064 A literal NUL byte in a source file made it invisible to grep, which hid a duplicate constant unrecorded ~<2026-08-29
⚪ D065 cargo doc was failing, and the gate did not build docs unrecorded ~<2026-08-29
⚪ D066 Documentation drifts in the direction of claiming less than the code does unrecorded ~<2026-08-29
⚪ D067 Supporting the current generation is three-quarters done and blocked on one oracle unrecorded ~<2026-08-29
⚪ D068 The logo is one file, committed, and the drawn mark is gone unrecorded ~<2026-08-29
🔴 D070 The cache size is a ceiling measured from the image, not a constant superseded ~<2026-08-29
⚪ D071 D070's rule was wrong, and the corrected one cannot be tested by avoiding it unrecorded ~<2026-08-29
⚪ D072 The inner filesystem's root pointed its parent at the super root unrecorded ~<2026-08-29
⚪ D073 The tool converts a supplied icon, rather than asking four projects to export one unrecorded ~<2026-08-29
🟢 D074 An executable declares no export library, which frees library id zero decided 2026-08-29
🟢 D075 A container entry's memsz is its data's size, not the segment's memory size decided 2026-08-29
🟢 D076 The dynamic table lives at the tail of the vendor segment, not in the image decided 2026-08-29
🟢 D077 The vendor segment begins with a fingerprint region, and leaving it out moves everything decided 2026-08-29
⚪ D078 A bundled library is a third layout, and it needs a third linker script unrecorded ~2026-08-29..09-09
⚪ D079 DT_SCE_ORIGINAL_FILENAME is required, and holds the module's own name unrecorded ~2026-08-29..09-09
⚪ D080 The keystone is derived, not supplied, and every package this crate built was missing one unrecorded ~2026-08-29..09-09
⚪ D081 param.json does not belong in a package, and its presence there was mixing two routes unrecorded ~2026-08-29..09-09
⚪ D082 A package cannot produce a current-generation title, so native is a second delivery route rather than a second package format unrecorded ~2026-08-29..09-09
⚪ D083 A comment in the keyset file broke the licence, because the reader matched prose unrecorded ~2026-08-29..09-09
⚪ D084 A real container can be audited against the format table - the oracle step, as a command unrecorded ~2026-08-29..09-09
⚪ D085 Getting a real current-generation SELF is a measurement obSCEne runs, not a file this repo holds - and the sandbox makes it conditional unrecorded ~2026-08-29..09-09
⚪ D086 Confirm the format on the console and report the verdict - do not carry the bytes off unrecorded ~2026-08-29..09-09
🟢 D087 Native PS5 title manifests (param.json) and differential measurement over fake-signed packaging done ~2026-08-29..09-09
⚪ D088 libkernel_vaddrs example: exports as name vaddr, and why the names are not ours unrecorded ~2026-08-29..09-09
🟢 D089 Naming a hash backwards is a search over somebody else's vocabulary, so the vocabulary is an argument decided 2026-09-09
🟢 D090 The unterminated SFO format is a length, not a promise of text, and reading it as text failed whole files decided 2026-09-09
🟢 D091 A writer must refuse where a reader may guess, and this crate had them the wrong way round decided 2026-09-09
🔴 D092 The container that matched this table was one this table could have written reversed 2026-09-09
🟢 D093 The audit reports what kind of container it just agreed with, before it reports how many rows agreed decided 2026-09-09
🟢 D094 The audit checks the tail it pins, and reports it apart from the header decided 2026-09-09
🟢 D095 A second reader found three disagreements, and only one of them was about the format decided 2026-09-09
🟢 D096 Two answers to the symbol count, and the divergence is kept rather than reconciled decided 2026-09-09
🟢 D097 The wrap default was justified by a population counted in the wrong place, and the default is right anyway decided 2026-09-09
🟢 D098 Measured vendor values are recorded against the rows they refute, never as a profile a writer could reach for decided 2026-09-09
🟢 D099 The inner size was never unknown, and entry 0x1001 is computed like every other derivable entry decided 2026-09-10
🟢 D100 stamp and wrap retire into the pipeline; --format prx, and --privilege/--sdk as pipeline options decided 2026-09-10
🟢 D101 A module built here cannot carry a weak undefined import, by construction; the forcing to GLOBAL stays decided 2026-09-10
🟢 D102 The title metadata a title carries gets pipeline spellings; --root does not decided 2026-09-10
🟢 D103 The AGC shader container is admissible as a format, but only the part a citable source derives - not the vendor-binary part, and not because hardware accepts it decided 2026-09-10
🟢 D104 selfish-cli depends on nothing outside this repository again: the commit stamp is local git, the logging was dead weight decided 2026-09-11
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.