The Bytes Are the Fact. The Name Is a Claim.

A file called screenshot.png turned out to be a zip archive. What a program should do about that, and why a correction that reaches only one surface is not a correction.

Date

/

Category

Design

Design

/

Writer

Keon Hwui Kim

Keon Hwui Kim

A file arrived called screenshot.png. It was a zip archive.

Not maliciously. Somebody had renamed something, years ago, and the wrong name had travelled with it ever since through however many drives and handovers. The interesting question is what a program should do about it, and the answer turned into one of the more portable principles I have got out of this project.

Two sources of truth about what a thing is

There is the name: the extension, the label, the declared MIME type. And there is the content: the actual bytes, whose first few establish what format they are in.

The name is a claim. Somebody asserted it. It may be careless, stale, copied from a template, or simply wrong.

The bytes are a fact.

File formats have known signatures, which is the whole reason this is decidable rather than a guess:

Format   First bytes (hex)          As characters
------   ------------------------   -------------
PNG      89 50 4E 47 0D 0A 1A 0A    .PNG....
JPEG     FF D8 FF                   ...
GIF      47 49 46 38                GIF8
PDF      25 50 44 46 2D             %PDF-
ZIP      50 4B 03 04                PK..
PSD      38 42 50 53                8BPS
WEBP     52 49 46 46 .. .. .. ..    RIFF....WEBP
         57 45 42 50
Format   First bytes (hex)          As characters
------   ------------------------   -------------
PNG      89 50 4E 47 0D 0A 1A 0A    .PNG....
JPEG     FF D8 FF                   ...
GIF      47 49 46 38                GIF8
PDF      25 50 44 46 2D             %PDF-
ZIP      50 4B 03 04                PK..
PSD      38 42 50 53                8BPS
WEBP     52 49 46 46 .. .. .. ..    RIFF....WEBP
         57 45 42 50
Format   First bytes (hex)          As characters
------   ------------------------   -------------
PNG      89 50 4E 47 0D 0A 1A 0A    .PNG....
JPEG     FF D8 FF                   ...
GIF      47 49 46 38                GIF8
PDF      25 50 44 46 2D             %PDF-
ZIP      50 4B 03 04                PK..
PSD      38 42 50 53                8BPS
WEBP     52 49 46 46 .. .. .. ..    RIFF....WEBP
         57 45 42 50

So the rule is: try the named path first, because it is cheap and usually right. If it finds nothing, look at the bytes. And then, this is the part that matters, the corrected kind names the thing everywhere.

Not in a tooltip. Not as a warning badge. The card says zip. The filter says zip. The detail view says zip. The search reads its contents from the central directory and indexes them. There is no surface anywhere in the product that still calls it a PNG.

Why halfway is worse than either extreme

The tempting middle path is to trust the name for display and the content for processing. It produces the worst outcome available.

The user sees one thing and the system does another, and the gap between them is exactly where trust dies. The moment a person notices that the label and the behaviour disagree, they stop believing either of them, and they are right to.

A correction that reaches only one surface is not a correction. It is a second opinion.

Pick one source of truth and let it propagate completely. The propagation is the expensive part and it is not optional.

The sibling rule, which I would defend harder

The original is never replaced by the preview.

When you drop an image into JEFIELD, the program makes a small rendering for the card. That preview is derived, disposable, and regenerable at any time. It is not the thing.

So when you later ask for the picture back, you get the original pixels: the file you dropped, at the size you dropped it, under its own name. Never the card-sized rendering the program invented for its own layout convenience.


The original

The preview

Made by

The person

The program

Can be regenerated

No

Yes, always

Stored

Content-addressed, once

Cache beside the bytes

Returned on request

Always

Never

Safe to delete

No

Yes

Table 1. Two files that look similar on screen and have opposite properties.

This sounds obvious and is violated constantly. Plenty of tools will hand you back a compressed, resized, re-encoded version of what you gave them, because that is what was convenient to store. The original was the thing you trusted them with. The preview was their convenience, and somewhere along the way the convenience replaced the trust without anyone deciding it should.

There is an implementation detail that makes this cheap rather than expensive, and it is worth stating because it is the reason the rule is holdable. Bytes live in a content-addressed store, keyed by their SHA-256. Which means the same thing dropped twice is one copy, automatically, with no deduplication logic written anywhere in the product. The identity of a file is its content, which is the same principle one layer down.

Where it stops being about files

I keep finding this distinction outside the code, and it is the reason I am writing it up at all.

A brief is a claim about what a client needs. The way they actually talk about their business in the meeting is the bytes. A project's name is a claim. The work is the bytes. A moodboard is a claim about a direction. What you are still looking at three weeks later is the bytes.

A job title is a claim. What the person actually does all day is the bytes. A design system's documentation is a claim. What is in the production CSS is the bytes.

In every one of those cases the same failure is available: read the claim, build on the claim, and never open the thing. It is faster. It is usually right, which is what makes it survivable as a habit. And when it is wrong, it is wrong in a way that does not surface until very late, because everything downstream inherited the mistake without ever checking.

The studio version of the rule, which we now apply to every inherited project:

Before acting on any description of a thing,
open the thing.

If opening it is expensive, say so, and
mark every downstream decision as
dependent on an unopened claim

Before acting on any description of a thing,
open the thing.

If opening it is expensive, say so, and
mark every downstream decision as
dependent on an unopened claim

Before acting on any description of a thing,
open the thing.

If opening it is expensive, say so, and
mark every downstream decision as
dependent on an unopened claim

That second clause is the one that gets skipped. It is not always possible to open everything. It is always possible to note which of your conclusions are resting on a label.

The zip called screenshot.png

It contained the only complete set of source files for a logo we had been told did not exist. Somebody had zipped the folder, renamed it wrong, and everyone downstream had read the extension and moved on for two years.

Sniff the content. Then let the correction reach everywhere.

Related reading

More from the Moc Mallen Studio journal