Never move bytes a stranger has already pinned
Some of what you publish has been hashed and copied into other people's systems. Name that byte surface before you touch anything, prove it unchanged with an empty diff, and stop and ask when a correction reaches it.
Use when
- Use this when you are about to change code, templates, or copy in a product whose published output other people verify by hash or have copied into their own files.
- Use this before a global correction — a rename, a wording fix, a brand sweep — crosses a codebase that also holds already-published output.
- Use this when a formatting pass, a dependency upgrade, or a normalization change touches a renderer whose output is pinned.
The failure
A cosmetic pass normalizes whitespace inside a shared renderer, or a brand sweep rewrites one string that travels in a machine payload. Nothing looks broken and every test stays green. Every copy a stranger pinned now fails its hash check on the next verification, and you learn about it from them rather than from your own record.
The outcome
The immutable surface is named in writing before the first edit, the published output diffs empty against its pre-edit capture with its content hash unchanged, and every place the change met the seal is either untouched or ruled on by the owner.
The Practice — 6 rules
Name the immutable surface before the first edit
Before any work starts, write down exactly which files, which output representations, and which revision constants may not change, and state it as an absolute law rather than a preference. Repeat it verbatim in the first paragraph of every brief you hand to anyone else, next to the branch and database rules. Do not rely on whoever does the work remembering it from last time.
Why A constraint that lives only in someone's memory is not a constraint, and the one session that never heard it is the one that breaks the seal.
Capture the live output first, then re-diff after each change
Fetch the published output, in every representation it is served in, into files before you change a line of source — that capture is the baseline, and it cannot be reconstructed from a build that already contains your change. Re-fetch and diff after each structural change that could reach the renderer, not once at the end. The diff must be empty and the content hash unchanged.
Why One check at the end tells you only that something moved a byte; a check after each step tells you which change did it.
Sweep the mutable surface and stop at the seal
When a correction sweeps the codebase, change every mutable surface — chrome, page titles, labels, error copy — and bump the revision constant that keys your caches so readers are served the corrected bytes. Where the same correction lands inside pinned output, stop. Do not edit it. Where the same sentence exists in two representations, leave the untouched twin identical so the two cannot drift apart.
Why A stale string in a machine payload costs little; invalidating every stored hash in order to fix it costs the thing the hash was for.
Put the flag to the owner as a ruling, not a silent edit
List every occurrence you stopped at — file, line, and the offending string quoted exactly — and hand it to whoever owns the decision as a question: should this change and take a new hash, or stand as it is? Include the argument for leaving it alone. Exceptions already ruled on stand as ruled and are not reopened.
Why Whether a published seal is worth breaking is an owner's judgement about trust, not a builder's judgement about tidiness.
When a hash must move, say which bytes moved and why
Sometimes the bytes legitimately change: a placeholder becomes a real identifier, or a ruled correction ships. Record which bytes differ and for what reason, in the same place you record the empty diffs, so an honest change reads as an honest change.
Why Verification only means anything while a broken hash is always news; once unexplained changes are ordinary, nobody checks again.
Make the empty diff evidence, not intention
Put the literal instruction into the verification list — that the pinned file's diff is empty and the hash unchanged — and paste the result back into the finished record, above the list of what was built. Keep the tests that pin those bytes, and treat weakening one to make a change pass as the change failing.
Why An intention to leave something alone is unfalsifiable; a pasted empty diff is a fact someone else can re-run.
Limits — do not use this when
- Do not carry this weight where nothing you emit is pinned, hashed, or copied downstream — an internal surface with no external verifier does not need it.
- Do not use it as grounds for leaving a published document that is genuinely wrong. Correcting published content is a versioning decision, and it belongs to whoever owns the document.
- This governs bytes, not judgement. An empty diff proves the output did not move; it proves nothing about whether the change was a good one, and it replaces none of your other verification.
- The law holds only over the surface you enumerated. Anything left off the list is unprotected, so the list is worth more than the rule.
- Bumping a cache revision corrects what readers are served next. It does nothing about copies already sitting in someone else's repository.
- A pre-edit capture taken from a build that already contains part of your change is not a baseline, and diffing against it proves nothing.
Verify — evidence that it helped
- The immutable surface is written down by file and representation before any edit, and appears in the brief given to whoever does the work.
- A pre-edit capture of every published representation exists on disk and predates the first source change.
- The diff between that capture and the current output is empty, and the content hash is unchanged.
- Every hash that did move has a recorded reason naming which bytes changed.
- Each place the change met a pinned surface is either untouched and listed for a ruling, or changed under a ruling that is recorded.
- No test that pins the output was edited, relaxed, or skipped during the work.
- Where one sentence exists in two representations, both still read identically.