The Principal IC Moat

The Goal

This started as a simple job search. One I didn't think should last long.

Twenty years as an engineer and architect in a highly regulated enterprise. Much of it as a full-stack developer in an industry allergic to them. Elevated for judgment, but constrained by lack of consistent formal authority. Useful, but underutilized in ways only those who have spent real time inside regulated industries can imagine.

What I didn't know going in: that longevity, that deep understanding of a complex domain, often gets read as disqualifying. Especially from the middle of Kansas.

The Unintended Moat

After a few hundred listings, a pattern emerged.

Companies write Principal IC job descriptions that blend stack requirements, aspirational leadership language, inherited organizational pain, and vague transformation goals until the actual work disappears. They attach titles that mean different things at every company. Then they screen by resume pattern-match against the very title and description they just made up. Dogfooding in reverse?

That isn't a filter for Principal-level judgment. It's a filter for resemblance to one snapshot in an ever-changing industry.

In 2026, a job description may say "Principal Engineer," but the content might look like any of the following:

  • A hands-on senior engineer who still ships features
  • A platform strategist expected to set direction
  • A technical executive without authority
  • A political consensus-builder
  • A vendor evaluator
  • A traveling salesman

What the hiring manager actually wants to buy is judgment. Judgment is hard to specify. So they reach for visible proxies: title, logos, years, stack, scope, artifacts, interview fluency.

That's the moat. Not malicious. Just a consequence of trying to write a spec for something that resists being specified.

The Diagnostic

I quickly realized that one's resume, a document that once needed a bit of polishing now and then, had become a living artifact. A precision instrument whose sole purpose is to evade a gauntlet of overworked humans, their software, their AI assistants, and the inboxes of hiring managers who get 50 more important emails per day.

What goes on a resume is no longer just the list of things you're best at, your expertise and biggest career achievements. Now it could also be anything you've been adjacent to that increases the odds of getting through that arbitrary gate. In the workplace, people attach their names to things they never intend to meaningfully participate in, just to internally rationalize inclusion of a resume bullet point. On the receiving end, this means interviewing people who lack the exact thing you're looking for — sound judgment, decision ownership, and respect among both developers and executives — earned for the right reasons.

Unfortunately, this audition feels like it violates a core belief for some of us. So we "cope" in a few ways. I decided to build a few things.

What I Built

I'm not going to walk through the full implementation. The relevant part is the shape of the problem.

Embeddings alone overweighted vocabulary — they'd rank "Principal Engineer who runs Jira" right next to "Principal Engineer who ships," because the words match. Claude alone could read through the vocabulary on any single listing, but reading isn't ranking. Score a field of candidates one at a time with no shared baseline and the scores drift. Neither approach, on its own, could hold a stable line between resemblance and seniority.

What worked was running them against each other. Three retrieval strategies, same corpus, and the disagreements became the signal.

Embeddings only. MiniLM, vector cosine, no LLM in the loop. Fast, free to run, scales to thousands of listings. Good at "find postings that read like this one." Blind to whether the role is actually senior or just uses senior-sounding words.

Full Claude batch. Every listing and every resume read by Claude with a structured rubric — autonomy, scope, decision authority, hands-on vs. coordinating. Title and seniority language stripped before the model sees it. Expensive. Slow. But it reads through the vocabulary in a way embeddings can't.

Hybrid. Embeddings on the listing side, Claude on the resume side. The asymmetry is the point. Listings are noisy and abundant — you don't need precision on every one, you need a fast filter. Resumes are few and precious. That's where the Claude budget pays off. It's also where the disagreement lives: when the embedding rank and the Claude score diverge on the same candidate against the same listing, the divergence is usually pointing at something real — vocabulary cosplay on one side, hidden judgment on the other.

Written in Go. Runs locally. Every pass versioned so I can rerun any mode against any snapshot.

The other move that mattered: forcing the role categories to emerge from the data instead of projecting them in. Strip seniority and focus language, cluster what's left, and see what the postings actually want.

Across 555 listings, 45 carried the title "Principal Engineer." The model split them: 31 landed in Staff / Principal SWE, 12 in Principal SA, Enterprise. Two didn't cluster at all. The title isn't doing the work. The cluster is.

The clusters that emerged:

  • Field CTO
  • Staff / Principal SWE
  • Staff ML
  • Staff DevRel
  • CTO / VP Engineering
  • Principal SA, Enterprise

Six shapes, hiding behind the same handful of titles. The moat made visible.

Closing

Early on, my own system told me I was a strong fit for Anthropic. Top of the ranked list, across every cut. I was immediately certain that wasn't success. I'd been learning about Claude, MCP, vectors, rerankers, and agents — for weeks. The embedding wasn't measuring fit. It was measuring basic overlap with what I'd recently been talking about.

That moment was more useful than any positive result. It told me what I was actually building: not a search system, a measurement instrument that had to be calibrated against its own biases before it could say anything true.

Of the 555 listings looked at so far, all but one embedded cleanly. The failure: "Member of Technical Staff, Field Eng" — 5,526 chars, over MiniLM's 512-token limit. The canonical IC role was too long to fit in the model.

The unintended consequence of legibility-based hiring is that the people most capable of doing Principal IC work are also among the most likely to detect the incoherence and opt out. They read the description — and all they see is another potential for impossible scope, unclear authority, mismatched title, and generic leadership language.

Some of them route around it, some of them turn their own job hunt into a Go codebase.

-- Justin Higgins. Software Engineer, Midwest. Spent six months job-hunting and built a search engine instead.

Reactions, disagreements, war stories: jchigg2000.dev@gmail.com