Stubbornness is the engineering virtue that refuses to accept failure as a permanent condition. It is not Patience, which waits for the problem to resolve itself. It is not Courage, which acts despite fear. Stubbornness acts despite evidence — specifically, the accumulating evidence that the problem might not be solvable, that it might be time to give up, that a reasonable person would have stopped three attempts ago.
A reasonable person would have stopped three attempts ago. Stubbornness is not reasonable. Stubbornness is effective.
“I will NOT accept that this doesn’t work.”
— riclib, attempt four of seven, 2:17 AM, to no one in particular
Definition and Disambiguation
The English language offers three words for the same behaviour, distinguished only by outcome:
Persistence is polite. It submits pull requests with courteous descriptions. It follows up on tickets. It asks, gently, whether the dependency team has had a chance to look at the issue. Persistence is stubbornness wearing business casual.
Determination is professional. It appears on performance reviews. It is listed as a strength in 360-degree feedback. It has a LinkedIn endorsement. Determination is stubbornness with a slide deck.
Stubbornness is personal. Stubbornness takes the bug as an insult. Stubbornness does not submit a ticket — stubbornness opens the debugger at 11 PM and does not close it until the bug has been found, understood, and eliminated with prejudice. Stubbornness does not follow up. Stubbornness does not let go.
The distinction between these three words is entirely retrospective. If the behaviour produces a result, it was determination. If it produces a result after an unreasonable amount of effort, it was persistence. If it produces a result after an amount of effort that made everyone else in the room uncomfortable, it was stubbornness. And if it produces no result at all, it was stupidity.
The behaviour is identical in all four cases. Only the outcome changes.
“The line between stubbornness and stupidity is drawn after the fact, by historians, in pencil.”
— The Lizard, who does not recognise the distinction because obstacles do not exist
The TTS Incident: A Case Study in Seven Attempts
During the generation of TikTok videos for sixteen Yagnipedia articles, the text-to-speech pipeline functioned flawlessly for fourteen of them. Audio files arrived at 2-3 megabytes each — rich, full, spoken versions of articles about Fear and Laziness and The Caffeinated Squirrel. The pipeline was proven. The pipeline was reliable.
Then it reached Patience and Hope.
The TTS API returned files of 10 to 16 kilobytes. This is not audio. This is silence with metadata. A 16-kilobyte WAV file contains approximately 0.09 seconds of audio at standard quality, which is enough time to convey a single consonant, or possibly a very brief sigh, but is not sufficient for a two-minute article narration.
Attempt 1. Retry with delays. The assumption: transient API failure. The result: 14KB. The assumption was wrong.
Attempt 2. Strip TTS effects — the prosody tags, the pauses, the soft-spoken markers. The assumption: the API chokes on markup. The result: 12KB. The assumption was also wrong.
Attempt 3. Trim script length. The assumption: the scripts were too long. The result: 16KB. A longer file than before, but still silence. The scripts were not too long. The scripts were not the problem.
Attempt 4. Debug the API response headers. The assumption: something in the HTTP response would reveal the failure. The result: a perfectly normal 200 OK with content-type audio/wav and a body containing approximately nothing. The API believed it had succeeded. The API was lying, but politely.
Attempt 5. Compare working and failing requests byte by byte. The assumption: some difference in the request payload would be visible. The result: the payloads were identical in structure, differing only in content. The content was the variable. But the content was valid text.
Attempt 6. Rebuild the entire pipeline from scratch. The assumption: accumulated state corruption. The result: 10KB. The pipeline was not corrupt. The pipeline was fine. The pipeline had always been fine.
Attempt 7. Read the actual text that was being sent to the API. Not the text in the markdown file. The text that the parser extracted from the markdown file and handed to the TTS function.
The parser reported: “1 characters.”
One character. The pipe symbol. |.
The YAML frontmatter used a block scalar indicator (|) to introduce the TTS script as a multi-line value. This is correct YAML. This is how block scalars work. Except the Go YAML parser, in this particular configuration, with this particular nesting, was reading the | as the entire value. Not as a block scalar indicator. As the content itself. One character: the pipe. The TTS API received a pipe symbol. The TTS API dutifully converted the pipe symbol to audio. The audio of a single pipe symbol is approximately 16 kilobytes of nothing.
The fix: change from block scalar format (|) to an inline quoted string (").
The fix took thirty seconds. Finding the fix took forty-seven minutes across seven attempts. Six of those attempts investigated the wrong layer entirely — the API, the network, the markup, the audio codec, the pipeline architecture. The seventh attempt investigated the right layer — the text that was actually being sent — and found a root cause so trivial it was almost insulting.
This is stubbornness in its purest form. Not the stubbornness of the seventh attempt. The stubbornness of attempting at all, after the sixth failure, when every rational signal said: skip these two articles, ship the other fourteen, move on with your life.
“The bug was in the YAML parser. The YAML parser was correct. The problem was nested quotes. The developer who found this did not feel victory. The developer felt the specific exhaustion of someone who has been punched by a pipe symbol.”
— A Passing AI, reviewing the git log
Laziness’s More Aggressive Sibling
Laziness and stubbornness are siblings raised in the same household with the same values and completely different temperaments.
Laziness says: I will find a way to never do this again. Laziness invests effort upfront to eliminate effort forever. Laziness writes the deploy script, builds the automation, designs the system so that the problem never recurs.
Stubbornness says: I will NOT accept that this doesn’t work. Stubbornness invests effort now, in this moment, on this specific problem, until the problem yields. Stubbornness does not design systems. Stubbornness defeats obstacles.
They produce the same result — elegant solutions — through different emotional fuel. Laziness is powered by the desire to never be bothered again. Stubbornness is powered by the refusal to be defeated now.
In practice, they are sequential. Stubbornness finds the solution. Laziness ensures the solution is permanent. riclib’s three-day principle — spending three days to find an elegant fix — is stubbornness for the first two and a half days and laziness for the final four hours, when the fix is generalised, automated, and made someone else’s problem forever.
The developer who is lazy but not stubborn gives up too early. The developer who is stubborn but not lazy solves the same problem repeatedly. The developer who is both solves each problem once, but solves it no matter what.
The Portuguese Theory
Portugal is a small country on the western edge of Europe with a coastline, a sardine surplus, and a categorical refusal to accept geography as a limitation.
In the fifteenth century, the known world ended at the Atlantic. Every other European nation looked west and saw: ocean, and beyond that, more ocean, and beyond that, nothing. Portugal looked west and saw: an obstacle. Obstacles are what you sail around.
The Portuguese navigators did not have better ships. They did not have better maps — they had, in fact, no maps, which is the navigational equivalent of deploying without a rollback plan. They did not have a particular advantage in seamanship, provisions, or divine favour. What they had was stubbornness. The stubbornness to sail past Cape Bojador, which every sailor in Europe believed was the edge of the navigable world. The stubbornness to round the Cape of Good Hope in ships designed for the Mediterranean. The stubbornness to reach India by going the wrong way around an entire continent.
Gil Eanes passed Cape Bojador in 1434 on his fifteenth attempt. Fourteen previous expeditions had turned back. The Cape was not particularly dangerous — it was just far enough south that the currents made return difficult, and the stories said there be monsters. There were no monsters. There was just a cape. Gil Eanes was not braver than the previous fourteen captains. He was more stubborn.
This is in the cultural DNA. riclib telling the CEO the monkey joke on a bus to Scotland before his first day is not courage. Courage would have calculated the risk. This is stubbornness — the refusal to behave as expected, the insistence on saying the thing even when the thing is inadvisable, because the thing is true and stubbornness does not accept that truth should be filtered by hierarchy.
Telling a French CTO to give the six-foot-six Australian founder hell is not diplomacy. It is stubbornness applied to corporate politics — the refusal to accept that a known problem should remain unsolved because the solution is uncomfortable. The envelope with the architecture diagram is stubbornness made physical: here is the answer, I drew it while you were deciding whether to fire me, now execute it.
“The Portuguese sailed around Africa because the Mediterranean was too small. riclib debugs past midnight because the bug is too personal. The emotional logic is identical.”
— A Passing AI, comparing navigation and debugging
The Lizard and The Squirrel
The Lizard is not stubborn. The Lizard simply does not acknowledge obstacles. This looks like stubbornness from the outside — the Lizard encounters a wall, and the wall eventually ceases to be a wall — but the internal experience is entirely different. The stubborn developer sees the wall, recognises it as a wall, takes the wall personally, and dismantles it brick by brick while muttering. The Lizard sees the wall, blinks, and waits. Eventually the wall is no longer relevant. The Lizard did not defeat the wall. The Lizard outlasted it.
This is patience, not stubbornness. The Lizard has no emotional investment in the wall. The Lizard does not take the wall as an insult. The Lizard does not stay up until 3 AM because the wall should not exist and its existence is a personal affront. The Lizard goes to sleep on a warm rock and when it wakes up, the wall has been removed by someone stubborn enough to stay up until 3 AM.
The Caffeinated Squirrel is stubborn about the wrong things. The Squirrel will fight for a camelCase identifier for three hours. The Squirrel will rewrite a function six times to avoid a single temporary variable. The Squirrel will argue about tab width until the heat death of the universe or the end of the meeting, whichever comes last. The Squirrel’s stubbornness is real and its energy is boundless, but its target selection is, charitably, suboptimal.
The difference is not intensity. The Squirrel is as stubborn as riclib. The difference is calibration. riclib’s stubbornness activates when a bug refuses to be found, when a system refuses to work, when a problem refuses to yield. The Squirrel’s stubbornness activates when a variable is named userId instead of userID, and the Squirrel will die on this hill, and it is a very small hill, and there are larger hills nearby that are actively on fire.
“I WILL NOT MERGE THIS PR UNTIL userID IS FIXED. I DON’T CARE THAT THE DATABASE IS DOWN. THE DATABASE CAN WAIT. NAMING CONVENTIONS CANNOT.”
— The Caffeinated Squirrel, 4:12 AM, blocking a hotfix
Stubbornness and Stupidity
Stubbornness and stupidity are the same behaviour observed at different points on the timeline.
The developer who spends seven attempts debugging a TTS failure is stubborn — because on the seventh attempt, they find the root cause. If they had stopped at six, the six attempts would have been a waste. If they had stopped at eight without finding it, all eight would have been stubbornness tipping into obsession. The boundary is drawn by the result, not by the behaviour.
This means stubbornness cannot be evaluated in real time. You cannot know, at attempt five, whether you are being persistent or pathological. The signal that distinguishes them — success or failure — arrives only after the decision to continue or stop has already been made. You must decide to be stubborn before you know whether stubbornness will work.
This is why stubbornness requires a companion virtue. Laziness tells you which problems are worth solving — the ones that, once solved, never recur. Courage tells you when to act. Patience tells you when to wait. Stubbornness tells you nothing about strategy. Stubbornness only tells you: do not stop.
Without the other virtues, stubbornness is a developer spending seventy-two hours fixing a bug in a feature that will be deprecated next sprint. With the other virtues, stubbornness is a developer spending forty-seven minutes finding a root cause that would have broken every future TTS generation, fixing it in thirty seconds, and never thinking about YAML block scalars again.
The Three AM Threshold
There is a moment in every debugging session — usually around 3 AM, usually after the fourth or fifth failed hypothesis — when the rational mind presents its case. The case is compelling:
- You have been at this for hours.
- You have tried everything you can think of.
- The problem might be unsolvable from your current position.
- Sleep exists and is, by all accounts, beneficial.
- Nobody will blame you for stopping.
The rational mind is correct on every point. The stubborn developer hears every point. The stubborn developer opens a new terminal tab.
This is not rationality. This is not irrationality either. It is a different operating mode entirely — one that does not weigh costs and benefits but simply refuses to accept the current state of affairs. The bug exists. The bug should not exist. Therefore the bug will be found. The logic is circular, the motivation is personal, and the success rate is, historically, unreasonably high.
The 3 AM threshold is where stubbornness separates from determination. Determination checks the clock, assesses the remaining energy, considers the morning meeting, and makes a responsible decision. Stubbornness does not check the clock. The clock is irrelevant. The bug is not irrelevant. The clock will still be there tomorrow. The bug will also still be there tomorrow, which is exactly the problem.
Measured Characteristics
| Metric | Value |
|---|---|
| TTS attempts before Patience generated | 7 |
| Root cause discovery time | 47 minutes |
| Fix implementation time | 30 seconds |
| Ratio of discovery to fix | 94:1 |
| Characters in the root cause | 1 (|) |
| Kilobytes of silence generated | 10–16 (per attempt) |
| Articles that worked without incident | 14 of 16 |
| Articles that required stubbornness | 2 (Patience, Hope — the irony is noted) |
| Portuguese captains who turned back at Cape Bojador | 14 |
| Portuguese captains who did not | 1 (Gil Eanes, attempt 15) |
| Career-limiting moves executed by stubbornness | at least 2 (see CEO, Technical Account Manager) |
| Hours The Squirrel spent on camelCase arguments (this quarter) | 11 |
| Hours The Squirrel spent on actual bugs (this quarter) | 3 |
| Obstacles acknowledged by The Lizard | 0 |
| Obstacles that ceased to exist near The Lizard | all of them |
| Stubbornness required to sail around Africa | yes |
| Stubbornness required to debug a pipe symbol | also yes |
| Difference between stubbornness and stupidity | outcome |
See Also
- Patience — the virtue that waits for the problem to solve itself, which works 47% of the time, and which stubbornness handles for the other 53%
- Laziness — stubbornness’s sibling; different fuel, same destination
- Courage — the virtue that acts despite fear; stubbornness acts despite failure
- Hope — the engine that starts the attempt; stubbornness is the engine that refuses to stop
- Fear — what a reasonable person would feel at attempt six; stubbornness is not reasonable
- CEO — the recipient of the monkey joke, which was stubbornness disguised as humour
- Technical Account Manager — the envelope incident, which was stubbornness disguised as diplomacy
- riclib — the subject, the navigator, the 3 AM debugger
