Engineering Attention: Why Your README is a 404 for the Human Brain
Why Your README is a 404 for the Human Brain
A system with 99.99% availability fails to gain users. A library with perfect test coverage sits abandoned on GitHub. Why?
We optimize for Time to First Byte and Largest Contentful Paint, obsessing over milliseconds of latency. We completely ignore the latency of the human mind: Time to First Interest.
Your readers, whether they're users, junior devs, or CTOs, are running a resource-constrained single-threaded event loop. If you don't inject a high-priority interrupt immediately, your message gets garbage collected.
The context trap
We're trained to be logical. Define variables before using them. Set up the schema before querying. So when we write, we instinctively start with context.
How many blog posts have you closed because they started with:
"In the early days of web development, managing state was difficult. Then came Redux... and in 2024, we have..."
That's a blocking synchronous call on the main thread. You're forcing the reader to parse history before they know why any of it matters.
If you don't establish the "why," the "how" is irrelevant.
The Venice example
A standard description of Venice:
"Venice is a city in Italy founded in the 5th century due to barbarian invasions..."
Accurate. Boring. A 200 OK with a generic body.
Now try this:
"Venice was an empire built without land. A superpower that couldn't feed itself, floating on mud, yet it dominated the Mediterranean."
That creates a knowledge gap. A paradox (empire vs. no food) that the brain wants to resolve. It's a Promise<Solution> in a pending state. The reader has to await the resolution.
Porting the Venice pattern to engineering
Stop writing documentation. Start writing interfaces for human attention.
1. Present the impossibility, not the feature
Feature listing (boring):
/**
* AsyncQueue allows for processing tasks in parallel.
* It has a concurrency limit and retry logic.
* Usage: new AsyncQueue(5).add(task);
*/
class AsyncQueue { ... }The paradox approach:
/**
* How do you process 1,000,000 requests without crashing the API
* or running out of memory, while keeping the UI responsive?
*
* AsyncQueue acts as a pressure valve for your backend.
*/
class AsyncQueue { ... }The second version highlights pain (crashing API) and impossibility (millions of requests vs. responsiveness) before presenting the solution.
2. Type-safe storytelling
Model a blog post as a function. If the arguments (opening sentences) don't match the required types (reader interest), execution fails.
// The standard flow
type BoringArticle = {
introduction: string; // "History of X"
body: string; // "How X works"
conclusion: string; // "Summary"
};
// The engaging flow
type EngagingNarrative = {
hook: Paradox | KnowledgeGap; // Must come first
investigation: Evidence[];
resolution: Insight;
};
type Paradox = {
statement: string;
contradiction: string;
};
type KnowledgeGap = {
question: string;
missingPiece: "unknown";
};
function renderArticle(input: EngagingNarrative): AttentionSpan {
if (!input.hook) throw new Error("Reader left at 300ms");
return new AttentionSpan("High");
}Curiosity is the emotional reaction to a missing piece in your mental model. If your intro creates that gap, the reader's brain will keep reading to close it.
The BLUF-Hook pattern in practice
BLUF: Bottom Line Up Front. Combine it with a hook.
Refactored a legacy auth system? Here's how to write the PR.
Default PR description:
"This PR refactors AuthService. Removes dependency on old UserSession object. Migrates tokens to Redis. Updates tests."
Result: reviewer skims, approves without looking, production breaks.
System thinking description:
Problem: We were sending the user's password hash over the wire on every request. Security time bomb. Solution: Decoupled the session. Opaque tokens instead. The weird part: Deleted 400 lines, test coverage increased 10%. Here's how that's possible.
The reviewer is now hunting for the interesting part. You gave them a reason to care.
A hook generator, if we were to automate the thought process:
import { Idea, Hook } from './mind-architecture';
class HookFactory {
static create(fact: string): Hook {
if (this.isCounterIntuitive(fact)) {
return `Most developers think [Common Belief], but actually [Fact].`;
}
if (this.solvesPain(fact)) {
return `Stop wasting hours on [Pain]. Here is the fix.`;
}
return `Why does [Subject] behave like [Strange Metaphor]?`;
}
private static isCounterIntuitive(fact: string): boolean {
return true;
}
private static solvesPain(fact: string): boolean {
return true;
}
}
const technicalFact = "This library uses a virtual DOM diffing algorithm.";
// Output: "Why is direct DOM manipulation 10x slower than this virtual proxy?"
console.log(HookFactory.create(technicalFact));The rule
We hide our best engineering decisions behind walls of context. We assume that because the code is good, people will read the docs. They won't.
Don't tell me where Venice is. Tell me about the empire that shouldn't exist. Don't tell me what your library does. Tell me why my current workflow is broken without it.
First, make me care. Then I'll parse your syntax.
Now go refactor your README.