The Company I always wanted

I think people misunderstand what I mean when I say I want to build a startup.

They hear startup and think billion dollar empire, venture capital, hustle culture, some guy on LinkedIn saying “we’re changing the world” because he made a dashboard for invoices or whatever.

And sure, getting rich would be nice. I am not going to pretend money is bad. Money solves real problems. Money buys freedom. Money keeps the lights on.

But that was never really the dream.

The dream was way simpler than that.

I wanted enough money to pay the bills, rent an office, buy some food, keep the computers on, and hack with my friends.

That’s it.

A room. Some desks. Some snacks. Good internet. Maybe a whiteboard. Maybe too many monitors. People arguing about systems and programming languages and product ideas. Somebody building something weird in the corner. Somebody else reading tech news for fun. Somebody pushing a deploy. Somebody saying “wait, what if we just…” and then everyone loses two hours chasing the idea because it might actually work.

That’s the part I always wanted.

Not the empire. Not the press release. Not the fake founder mythology. Not the “we are disrupting X” nonsense.

I wanted the workshop.

The funny thing is my friends already do this. They already build things for fun. They already read about technology for fun. They already have opinions about databases and operating systems and AI and networks and whatever else. They already spend their free time doing the thing most companies have to pay people to pretend to care about.

So part of me is like: why couldn’t we build a company out of that?

Not a company where the joy gets crushed under meetings and process and status games. Not a company where snacks replace compensation or where “we’re a family” means “please work nights for free.”

I mean a real company.

One that makes enough money that people can show up and be paid like adults.

One that has customers, and bills, and boring operational stuff handled, but where the center of gravity is still making things.

A company where the work still feels alive.

I think when we were younger this was easier to understand. If somebody made something on a computer, that was cool. A website, a script, a game, a server doing something weird, whatever. The first reaction was not a policy analysis. It was “whoa, you made that?”

Now everything gets filtered through takes.

Is it good for society? Is it cringe? Is it a startup grift? Is it AI slop? Is it capitalism? Is it replacing someone? Is it going to become a monopoly someday?

Some of those are fair questions. But man, if that is always the first reaction, it kills something.

There used to be a basic joy in making the computer do a thing. I still have that. I do not think I ever lost it.

And I guess I am realizing that the company I always wanted was not really about winning capitalism. It was about making a place where that joy could survive adulthood.

Because adulthood changes things. People have partners, kids, mortgages, health problems, parents getting older, responsibilities. Sitting in a room with friends, free food, and computers does not sound as magical to everyone as it once did. To some people it sounds like one more obligation.

I get that.

So maybe the dream has to grow up too.

Not a hacker house. Not a grind cave. Not “sleep under your desk until we exit.”

More like a sane little lab.

A software shop with a soul.

A place where people can come in, do good work, make real things, get paid, eat lunch, laugh, argue about dumb technical details, and then go home without feeling like the company owns them.

That sounds modest compared to the billion dollar startup dream, but to me it feels bigger in the ways that matter.

Because the point was never just money.

The point was: can we make our natural behavior economically sustainable?

Can the thing we already love doing become the thing that pays for the room?

Can we build something useful enough that it buys us more time to build more things?

That is the company I always wanted.

Not a unicorn.

A workshop with revenue.

A place where the fridge is full, the servers are running, the work is interesting, and the people in the room still think making stuff on computers is cool.

All your CDN are belong to US

Underminr Detection: DNS Says One Thing, TLS Says Another

The detection story for Underminr is actually pretty simple, which is why it is so annoying.

You are not looking for some magic evil packet. You are looking for the layers of the connection telling different stories.

Normal web traffic looks something like this:

DNS: I want goodsite.com
DNS answer: goodsite.com is at 104.x.x.x
TLS: I am connecting to 104.x.x.x
SNI: goodsite.com
HTTP Host: goodsite.com

Everything lines up. Boring. Fine.

Underminr-style traffic looks more like this:

DNS: I want goodsite.com
DNS answer: goodsite.com is at 104.x.x.x
TLS: I am connecting to 104.x.x.x
SNI: sketchy-domain.ai
HTTP Host: sketchy-domain.ai

That is the trick.

The machine uses an allowed domain to get a perfectly valid CDN IP, then reuses that IP to talk to some other tenant living behind the same CDN.

DNSSEC does not really save you here, because the DNS answer can be totally legitimate. DNSSEC can prove that the DNS answer was authentic. Great. Congratulations. The lie happens later, at the TLS / HTTP / CDN routing layer.

So the detector has to correlate things across layers:

What DNS name did this endpoint ask for?
What IP did DNS return?
What IP did the endpoint connect to?
What SNI did it present?
What HTTP Host header did it use?
Did that hostname ever get resolved normally?

In other words, you are looking for this mismatch:

Resolved: harmless-site.com -> CDN edge IP
Connected to: CDN edge IP
Claimed SNI: evil-site.com

That is the “oh come on” moment.

The really cursed version is when the attacker splits it into steps. First they make a clean-looking connection to the allowed domain, then they come back to the same CDN edge IP and swap the SNI / Host header to the real target.

So detection has to remember recent DNS answers and recent CDN connections per machine. It is not enough to look at one packet in isolation.

The direct-to-IP version is even more annoying because there may be no DNS lookup for the bad domain at all. Then the question becomes:

Why is this machine connecting directly to a shared CDN IP
while presenting an SNI / Host name that it never resolved?

That is suspicious as hell.

And with ECH, because of course we needed one more layer of pain, the real SNI can be encrypted. At that point you need endpoint visibility, controlled DNS, policy around HTTPS / SVCB records, or some way to block or strip ECH in managed environments.

So the whole thing boils down to this:

DNS says one thing. TLS / HTTP says another. The CDN accepts both because shared edge infrastructure is a haunted house.

Honestly, it feels like Dan Kaminsky may have faked his own death and come back on the dark side.

Obviously joking. Mostly.

But this is exactly the kind of DNS-adjacent, “everything technically works as designed and that is the problem” nonsense that makes the internet beautiful and horrible at the same time.

The practical detection rule is basically:

For each endpoint:
remember recent DNS answers:
allowed-domain.com -> CDN_IP
watch outbound TLS / HTTP:
endpoint -> CDN_IP:443
SNI / Host = some-other-domain.com
alert if:
the CDN IP came from a recent allowed DNS answer
but the SNI / Host does not match that DNS name
and the SNI / Host name was not separately resolved
in a normal allowed way

That is Underminr detection.

Not “block the IP,” because the IP is probably Cloudflare, Akamai, Fastly, or some other giant shared CDN edge.

Not “DNSSEC fixes it,” because DNSSEC only proves the DNS answer was real.

The actual problem is that the trust decision was made on one name, and the connection was later used for another name.

It is a cross-layer trust bug.

The internet has a lot of those.

Because apparently we enjoy pain.

Thoughts on the Mistakes of the Social Web

The internet was social before the social web. That part gets forgotten. People talked on IRC, forums, mailing lists, Usenet, AIM, Discord-style rooms, and all kinds of weird little places. The difference was that those places had context. You were not just “an account.” You were a person in a room, with some history, some reputation, and some reason for being there.

If you linked to your own thing in one of those spaces, people usually did not lose their minds as long as it was relevant. The question was not, “Did you make this?” The question was, “Is this useful here?” That is a much healthier standard. Sometimes the best link in the conversation is your own link because you are the person who wrote the thing, built the thing, documented the thing, or found the thing.

The social web broke that in a strange way. It created a huge opening for credibility fraud. Suddenly everyone could perform expertise, manufacture popularity, juice engagement, buy followers, write in brand voice, growth-hack sincerity, and pretend to be a participant while actually acting like a little attention-extraction machine. The feed turned normal human sharing into a suspicious transaction.

So now we live in this dumb world where links are both the blood vessels of the web and somehow treated like contraband. A web with no links is barely the web. It is just a set of private malls with recommendation engines and security guards. “Do not link to your own stuff” sounds noble until you realize it mostly helps people who are already big enough that other people link to them automatically.

PageRank made sense in a world where someone else might find your weird little page and link to it from their weird little page. That was the old bargain: publish something good, and the graph of the web slowly discovers it. But a lot of that middle layer is gone or weakened. Personal sites, blogrolls, directories, small forums, and independent linking culture got paved over by platforms. Now the system still wants backlinks, but the places where people actually gather often punish the behavior needed to create them.

That is one of the great little ironies of the modern web. The machine wants evidence that the world cares, but the world has been trained to treat public linking as spam unless it comes from someone already blessed by the machine. Nice little closed loop there. Very elegant. Completely cursed.

There is an important exception here: I am much less hostile to things like Bluesky, Mastodon, ActivityPub, AT Protocol, and other systems that at least try to make the social layer protocol-shaped instead of purely platform-shaped. That matters. Federation is not magic fairy dust, and protocol people can still be annoying in the very special way protocol people are annoying, but the architecture is pointed in a better direction.

A federated or protocol-based social system is not the same animal as a giant closed platform casino. If identity, distribution, clients, moderation, and hosting can be separated, then users are not trapped in quite the same way. The conversation can move. The client can change. The server can change. Communities can set local norms. The graph is not just locked in some corporate basement next to the engagement-optimization goblin.

That does not make every federated system good. It does not mean Bsky or Mastodon or anything else automatically solves the human problems. People can bring status games, mobs, spam, and weird little dominance rituals anywhere. Give humans a protocol and we will eventually find a way to argue about the chairs. But protocol-based social is at least trying to preserve some of what made the internet good: links, portability, interoperability, local context, and the possibility that no single company gets to be the landlord of human conversation.

So the problem is not “people talking online.” That would be an insane take. The internet is one of the best machines humans ever made for finding each other. The problem is the platform-owned social web: permanent, indexed, engagement-maximized, reputation-scored, and monetized within an inch of its life.

I understand why everyone built social features. In the pre-AI era, if you wanted a big site, users were the cheapest way to get content. Users wrote the posts, uploaded the photos, made the comments, tagged the pages, reviewed the restaurants, liked the posts, ranked the content, argued with each other, moderated each other, and generated the graph. The whole thing rode on the backs of users because paying people to produce and organize all that stuff was expensive as hell.

But that bargain had a cost. The user did not just contribute to the product. The user became the product, the inventory, the moderation problem, the credibility signal, and eventually the unpaid little hamster powering the engagement wheel.

And then because everything was public, permanent, indexed, and monetized, normal social behavior got weird. A casual thought became content. A disagreement became a searchable artifact. A joke became evidence. A person became a profile. A community became a growth channel. Human interaction got shrink-wrapped, barcoded, and stacked on a pallet in the warehouse of the feed.

I do think the social web has value. I am not saying people should stop talking online. But social interaction is often temporary, contextual, and messy. The web is durable, searchable, and decontextualized. Those are not naturally the same thing.

That mismatch is where a lot of the damage came from. We took ephemeral human behavior and made it permanent infrastructure. We took conversations that should have lived in rooms and put them on billboards. Then we acted surprised when everyone got performative, defensive, spammy, paranoid, or insane.

Maybe the healthier split is simple: let the web be good at durable reference, and let social be good at human context. Links, pages, sources, guides, documents, indexes — those belong on the web. Jokes, arguments, half-formed thoughts, “you had to be there” moments, and random social chatter probably belong somewhere smaller, softer, more local, or at least more portable than the giant engagement platforms.

AI changes the economics here. It may now be possible to build useful information systems without forcing users to generate the entire content layer. Machines can parse public sources, organize messy information, summarize, classify, dedupe, and turn scattered material into something usable. Humans can review and steer instead of being mined for every post, like, comment, and scrap of attention.

That does not mean AI slop should replace human culture. Please, God, no. The last thing we need is the web turning into a haunted vending machine full of synthetic LinkedIn posts. But it does mean we may not need to make every useful site into a little social casino anymore.

The mistake of the social web was not that people talked to each other. Talking is good. The mistake was turning talk into permanent content, content into ranking fuel, ranking into status, status into credibility, and credibility into a fraud market.

The web should have links. People should be allowed to point at things. Making something useful and saying “here, I made this” should not automatically be treated like some moral failure. That is how the web breathes.

A link-hostile web is an anti-web. It is a graph afraid of its own edges.

But a protocol-shaped social web? A federated web? A web where people can talk without every conversation becoming feed chum for the same giant machines?

That might be worth saving.

A Love Letter to San Leandro

San Leandro is the kind of city that reveals itself slowly. https://sanleandrodaily.com

It does not usually announce itself with the same volume as some of its neighbors. It does not have to. Its character lives in smaller, steadier things: a public library that matters, neighborhoods that still feel like neighborhoods, local restaurants people genuinely return to, parks that get used, and a shoreline that can change the tone of an entire day.

That quiet substance is part of why I keep coming back to it.

San Leandro feels practical in the best sense of the word. It feels lived in. It feels useful. It is a place where civic infrastructure still matters, where community programming is not an afterthought, and where small businesses still help define the texture of daily life. There is a kind of dignity in that. A city does not need to perform for the outside world to be worth loving.

From a technical point of view, San Leandro is more interesting than people sometimes realize. It has real industrial history, a meaningful business base, and even its own unusual infrastructure story through Lit San Leandro and the city’s long-running interest in connectivity and modern economic development. That combination of public life, local identity, and technical ambition is rare. It is one of the reasons building software for this city feels so worthwhile.

That is also the spirit behind San Leandro Daily.

The goal is not to build a generic city app and stamp a local name on it. The goal is to build something that respects the actual rhythms of San Leandro: library events, public meetings, neighborhood happenings, family programs, local deals, and the many small signals that tell you a city is alive if you are paying attention. Under the hood, the work is fairly straightforward on purpose: a FastAPI backend, PostgreSQL for content, and a cross-platform mobile stack that keeps the product maintainable. The technology matters, but only because it helps the city show up more clearly.

That is the heart of it for me. San Leandro deserves clear attention. It deserves tools that make it easier to see what is already here.

Some cities demand to be noticed. San Leandro rewards noticing.

Please send good vibes positive thoughts and prayers to my friend Desta in Kenya

Desta and I have been close friends for a few years now. Unfortunately, she is currently very sick with lung cancer. The world can be a very unfair place. She graduated #1 in her nursing school class with near-perfect test scores, all while struggling through abject poverty. In the middle of her studies, her mother died, and she took care of — and continues to take care of — her two younger siblings.

I know she will not give up, but she could certainly use all the positive thoughts she can get. So I am asking all my readers around the world to take one small moment and mentally wish her well.

Thank you all.

LessVibes release

fuck the claw

lessvibes

lessvibes is an early JetBrains plugin project aimed at a pretty specific problem in the AI coding era: code can appear in your project faster than you can really read it.

The point of lessvibes is not to block AI tools or shame anyone for using them. The point is to make AI-assisted coding more visible and more hands-on. The plugin is meant to notice when a burst of code lands, track whether the affected files were actually opened, and help the developer step through a likely code path instead of just trusting the vibes and moving on.

In its current form, the project is focused on PyCharm first. The rough direction is:

  • track likely assisted or bulk-generated changes
  • show which files were touched
  • show which of those files were never opened
  • show which files were opened but never really edited
  • give the user a way to open a bounded left-to-right code-flow view

The project lives here:

https://github.com/nigeldaniels/lessvibes

Installing It In PyCharm

Right now, the simplest way to install lessvibes is from a locally built plugin zip.

  1. Clone the repo.
  2. From the project root, run:
./gradlew buildPlugin
  1. That produces a plugin archive at:
build/distributions/lessvibes-0.1.0.zip
  1. In PyCharm, open:
Settings / Preferences -> Plugins -> gear icon -> Install Plugin from Disk...
  1. Select the generated zip file.
  2. Restart the IDE if PyCharm asks.

After restart, the plugin should appear as the lessvibes tool window.

Installing It In Similar JetBrains IDEs

Because lessvibes is a JetBrains plugin, it may also load in similar IntelliJ-platform IDEs. That said, this project is being built with PyCharm in mind first, so anything outside PyCharm should be treated as experimental for now.

The install flow is basically the same:

  1. Build the plugin zip with ./gradlew buildPlugin
  2. Open the target JetBrains IDE
  3. Use Install Plugin from Disk...
  4. Pick the generated zip
  5. Restart the IDE

Important Warning

This project is still very much a work in progress.

It is mostly untested, the heuristics are still rough, and the code-flow logic is best-effort rather than guaranteed runtime truth. If you try it today, you should expect edges, gaps, and wrong guesses.

That said, the idea is real, the first plugin scaffold exists, and contributions are absolutely welcome.

If this problem sounds interesting to you, open an issue, send a PR, or just poke around the code here:

https://github.com/nigeldaniels/lessvibes

LessVibes: Because apparently I needed to vibe code a plugin to help me vibe code less

lessvibes: a plugin for making sure I do not become a fucking moron any faster than time already requires

I have been thinking a lot about AI coding tools lately.

Not in the fake moral-panic way. Not in the “real programmers type every character by hand in a dark room lit only by vim” way. I use the tools. The tools are useful. Anyone pretending otherwise is either lying or writing Java for fun.

The problem is not that AI coding tools are bad.

The problem is that they are too convenient in exactly the wrong place.

They make it dangerously easy to end up with code in your repo that you did not really read, did not really trace, and do not really understand. A giant slab of output appears, you skim it, rename two variables, maybe run the tests, and now congratulations: you are responsible for a system you technically approved but do not actually know.

This seems bad.

So I have been working on a plugin idea called lessvibes.

The basic goal is simple: I want something in the editor that pushes back, at least a little, against the smooth-brained workflow of sitting there like a fucking lemming waiting to click Accept.

Because let’s be honest, something has to.

If nothing pushes back on that loop, a lot of us are going to get dumber. Not overnight. Not in some dramatic sci-fi way. Just slowly, comfortably, one magical completion at a time, until our main skill is recognizing when the machine produced something that looks plausible.

That is not a great direction for software development, or for my own brain, it never got much exercise to begin with.

What lessvibes is supposed to do

The core idea behind lessvibes is that the IDE should notice when a coding session has turned into something passive.

Not “evil.” Not “fraudulent.” Just passive.

If a giant block of code lands in the editor faster than any human would normally type it, that should be treated as a moment worth paying attention to. Not because generated code is automatically wrong, but because that is the exact moment where understanding tends to quietly fall off a cliff.

So the plugin would try to estimate how a session is actually happening.

Not with fake certainty. Not with some creepy fantasy that it can prove who “really authored” every line. More like a transparent, best-effort read based on signals such as:

  • manual typing and editing
  • paste events and bulk insertions
  • accepted AI completions when the IDE exposes them
  • edits that arrive much faster than a human would normally type
  • file opens, tab focus, scrolling, dwell time, follow-up edits
  • whether the files that got changed were ever actually opened and manually touched afterward

The point is not to solve philosophy.

The point is to notice when the workflow has quietly become:

accept output, skim it badly, and emotionally hope for the best

That is a real workflow now. A lot of people are doing it. Some of them are doing it successfully, which honestly makes it even more dangerous.

The part I actually care about

The feature I like most is the code-flow view.

If the plugin decides a change was probably AI-generated, heavily pasted, or otherwise suspiciously vibey, it should open a bounded left-to-right execution path through the code.

Up to five panes.

The leftmost pane starts at the main entry point. Then each pane to the right shows the next relevant file in the flow. Not the whole dependency graph. Not one of those giant architecture diagrams that looks like a serial killer’s wall. Just the important path, bounded on purpose, so a normal human can actually follow it.

That boundedness matters.

A lot of developer tools confuse “more complete” with “more useful.” I do not want a giant spiderweb of boxes and arrows that makes me want to close my laptop and go lie on the floor. I want something that says:

hey idiot, it starts here, then goes here, then here, then here. maybe read these before you pretend you understand the feature

That is the product.

And if the project uses containers, the leftmost pane should be split horizontally. Top half: the main code entry point. Bottom half: the Dockerfile or Compose file. Because a surprising amount of confusion in modern software is not just “what does this code do?” It is “what the hell is the runtime context?” The app starts in one place, the environment is defined somewhere else, and both are easy to ignore when the code arrived in your editor in a burst of machine confidence 30 seconds ago.

So the plugin is not just about surfacing generated code. It is about surfacing execution and context together, in a way that is fast enough that I might actually use it instead of admiring it once and forgetting it exists.

The real workflow I want

What I want the plugin to encourage is an older and healthier loop:

open -> read -> edit

Not:

accept -> vibe -> move on

So lessvibes should care about things like:

  • which generated files were never opened
  • which generated files were opened but never manually edited
  • which inserted blocks later got revised by hand
  • whether the important files in a generated path ever saw real follow-up edits
  • whether I spent time reading and navigating, or just waved the code through customs

To me, those are more meaningful metrics than some bullshit chart about lines added.

I do not care how many lines “I wrote” if a glorified autocomplete snowblower dumped them into my repo and I never looked back. The meaningful question is whether I actually went into the code after it appeared.

That is what matters.

Not purity. Not virtue. Not pretending I am above the tools. Just evidence that my brain stayed in the loop.

What this is not

This is not an anti-AI project.

It is also not a surveillance tool, and if it turns into one the whole thing should be thrown in the trash.

It should not block AI. It should not shame people for using AI. It should not send sensitive code off-machine by default. It should not pretend it always knows exactly what happened. And it definitely should not become one of those dead-eyed enterprise dashboards where some manager decides Steve was only 63% hands-on this sprint and therefore needs a meeting.

Absolutely not.

If this idea works at all, it only works if users trust it.

So the defaults should be:

  • local-first
  • clear about what signals are being tracked
  • no hidden scoring
  • opt-in nudges
  • exportable or resettable session history

Basically: helpful, not narc shit.

Why I think this matters

AI coding tools are very good at helping code appear.

They are much worse at helping you metabolize what just happened.

That is the gap.

Right now the ecosystem is mostly optimized around speed, convenience, and the pleasant little dopamine hit of watching the diff get bigger. But “the diff got bigger” and “I understand the system better” are very much not the same thing. In fact, they may now be moving in opposite directions.

And I do not think the answer is fake purity where everyone pretends to reject the tools and return to some mythological golden age of hand-crafted software. The tools are here. They are useful. I am going to use them. Most people are.

What I want is some counter-pressure.

Something that makes it a little harder to drift into a state where I am technically present for the coding session but functionally just acting as a biological approval button.

Because that is the real failure mode here.

Not evil AI. Not the end of programming. Just a slow humiliating slide into becoming the guy who watches the machine cook and occasionally says, “yeah that looks right.”

I would rather avoid that outcome if possible.

So yeah

That is lessvibes.

A plugin for making sure I do not become a fucking moron any faster than time already requires.

If AI is going to stay in the editor, then the editor should do more than help me accept code. It should help me understand what just landed, where it flows, what I have actually looked at, and whether I touched the important parts with my own brain before I ship some haunted Kotlin side project into the world.

That seems like a worthwhile improvement.

Merit, But Make It Legible

Featured

Merit, But Make It Legible

One of the more irritating features of modern life is that people love to say they reward merit when what they often reward is legibility.

Not raw capability.
Not force of will.
Not how much resistance someone had to push through to become good at something.

Legibility.

Did the achievement arrive in packaging the system already knows how to admire? Did it come with a famous school, recognizable institutions, polished references, family support, clean internships, the right tone, the right posture, the right little trail of approved breadcrumbs? If so, people relax. They call it excellence.

Meanwhile, if someone arrives at similar visible competence through a messier path — sparse resources, little formal support, public materials, self-direction, no safety net, and almost no room for error — the response is often weirdly diminished.

That person becomes scrappy.
Surprisingly strong.
Promising.
Impressive, considering.

Considering what, exactly?

What is being “considered” is usually the absence of prestige decoration. The person may have built nearly the same capability, or in some cases more durable capability, but because they did not emerge from a trusted institutional pipeline, people treat the result as somehow less real. Or more provisional. Or faintly suspicious. They get credit, but in the off-brand, slightly patronizing way society reserves for people who succeeded without first being pre-approved.

This is backwards in an important sense.

The person who had elite schooling, money, family support, institutional legitimacy, and low-friction access to opportunity may in fact be highly capable. None of this automatically disqualifies them. Plenty of advantaged people are genuinely excellent.

But there is still a difference between demonstrating excellence under supportive conditions and constructing yourself under weak ones.

The bootstrap path often demands a set of traits that institutions claim to admire but are not especially good at recognizing in the wild:

  • initiative
  • independence
  • persistence
  • improvisation
  • the ability to learn without structure
  • the ability to continue without validation
  • the ability to recover from mistakes that were actually costly

Those are not decorative virtues. Those are core builder traits.

And yet, because they do not come pre-certified by prestige systems, they are routinely under-read. Not merely under-resourced at the start — under-credited even after the fact.

That distinction matters.

Being under-resourced means you lacked inputs.
Being under-credited means the world misreads what you produced.

Those are different problems.

The first makes the climb harder.
The second makes the summit look smaller than it is.

A lot of evaluators will insist this is not bias, just pragmatism. They will say elite labels are useful proxies. And to be fair, they are. Institutions act as compression algorithms. They save busy people the trouble of asking inconvenient questions like:

  • How hard was this path, actually?
  • How much support was quietly embedded in the background?
  • How much independent force did this person have to generate on their own?
  • How many hidden cushions were mistaken for personal greatness?

These are not questions most systems are built to ask, because they are expensive to answer and mildly destabilizing to the mythology. It is much easier to see Harvard, billionaire parents, polished confidence, and familiar signals, then conclude: obviously exceptional.

Clean. Efficient. Safe.

It is much less comfortable to look at someone who assembled themselves from public materials, intermittent guidance, and sheer stubbornness, then admit that what you are seeing may represent a more violent act of self-construction.

The elite profile is often treated as natural greatness.
The bootstrap profile is often treated as an anomaly.

But anomalies are sometimes just reality showing through the branding.

This does not mean the bootstrap person is always better. That would just be reverse snobbery with better PR. The point is narrower and more important: achievement is frequently judged by how frictionless it looks, not by how much force was required to make it happen.

And force matters.

Especially in domains where the environment is unstable, where there is no syllabus, where support is partial, where nobody is coming to organize your progress for you. In those situations, the ability to move without structure, learn without permission, and continue without applause is not some charming side trait. It is often the thing itself.

That person may not sound as polished.
They may not tell the story as elegantly.
They may not have the right names on the résumé.
They may not know how to perform legitimacy in the dialect gatekeepers prefer.

But sometimes they built more real capability with less help and less slack.

And the world, being the world, often reads that as scrappy instead of formidable.

Which is convenient, because formidable would force people to rethink what they are actually rewarding.