The Senior, the Junior and the Mediocre

This industry used to run on a simple roster.
The junior wanted to learn, because learning was how you made it big. The senior had reached the maturity to plan: pick correctness and think through a hundred edge cases before touching the code.
Between them sat the median developer. Without the years to be called senior, they could still take a ticket and close it with nobody holding their hand.
The third character in the title is new.
The Senior¶
Who gets called senior now?
For ten years the loudest seniors sold complexity. They wrote the Kubernetes best practices and told people to go full scalability on their WordPress blog and their CV. Not one of them stopped to say: fuck this shit, let me make it simple. Their clusters used to impress people.
The same people are AI experts this year. They teach me that the way forward is a closed-source app. There are plenty to pick from, and I’m not going to advertise any of them.
The title is foggy now.
The Junior¶
The junior used to learn from friction. I wrote that argument in The Lobotomy Pipeline, so this section gets the receipt instead.
Juniors today take the first thing the model gives them and ship it. Rust makes that measurable, because every Cargo.toml records the year its author learned Rust.
Rust 2024 shipped with Rust 1.85 in February 2025. Since then, cargo new puts edition = "2024" in every new project. I pulled the crates.io database dump of October 8, 2026 and looked at the first version of every crate created in the last 90 days. 20,154 of 52,854 still start on edition 2021. That’s 38.1%, twenty months after 2024 became the default.
Split by publisher and it gets sharper. New publishers aren’t all juniors, but they are the closest count crates.io has. Crates from people whose first crate came after Rust 2024 shipped start on 2021 42% of the time. Crates from people who were publishing before that start on it 24.7% of the time.
Then there are files like this one:
[package]
edition = "2021"
rust-version = "1.85"
5,702 of those new 2021 crates declare a minimum Rust of 1.85 or newer. Their toolchain would have written 2024, so nobody ran cargo new. They asked a model for a project, and the model wrote the Cargo.toml from its training data. In the crates it learned from, 2021 was the default: from 2023 through 2024, more than 92% of new crates started on it every month.
I expected the same story with clap. Among new crates that parse arguments at all, 98.9% use it. It already had 93.5% in 2023 and 2024, so clap won that fight fairly and I can’t pin it on the juniors.
The Mediocre¶
The mediocre has confidence the model gave them, plus a few words the model used while explaining something. They’re vibing on words they don’t understand, and the vocabulary is enough to sound like a decade of experience.
Skills are the cleanest exhibit I have.
Anthropic released MCP in November 2024. The first spec already had prompts next to the tools. Prompts, in the spec’s own words, “allow servers to provide structured messages and instructions for interacting with language models.” They can embed resources such as “documentation, code samples, or other reference materials.”
The mediocre used tools only and blamed MCP for the token bill, as I covered in Skills Are Not Skills.
In October 2025 Anthropic shipped Skills: folders of instructions and scripts the model loads when a description matches the task. Launch coverage called MCP’s “high token usage” its “most significant limitation”, and the crowd repeated it. My read is that Anthropic watched people ignore most of what they shipped the first time, and gave the next thing a name small enough for a tiny brain to hold.
The name is wrong. A skill is something you acquire, which is why I called these tutorials last December. Once you can ride a bike, you don’t reread the manual every morning. A model rereads its SKILL.md in every session that needs it. It behaves like a workflow, and nobody wants to sell a product with WORK in its name.
Prompts were better at the job from day one, because a server builds them from arguments. Here is one in ActionMCP, my Rails engine for MCP:
class DeployPrompt < ApplicationMCPPrompt
description "Deploy a git ref to an environment"
argument :target, description: "Where to deploy", required: true, enum: %w[production staging]
argument :ref, description: "Git ref to deploy", required: true
def perform
if target == "production"
render text: "Deploy #{ref} to production."
render text: "Write the rollback command down before you run anything."
render text: "Diff db/migrate against the running release and stop on any destructive migration."
else
render text: "Deploy #{ref} to #{target}. Nobody gets paged."
end
end
end
/deploy production v0.3 and /deploy staging HEAD get two different documents, because code ran in between. /deploy prod v0.3 never reaches the model at all: the server answers with “Target is not included in the list.” Claude Code gets close with its own extensions: $ARGUMENTS placeholders, and shell commands that run before the text reaches the model. The docs say that shell injection doesn’t “function in claude.ai chat or through the API.” In the portable format, an argument-hint field fails validation outright: “Unexpected key(s) in SKILL.md frontmatter: argument-hint.”
Skills look like the model finds them on its own. The harness does that work: it injects every skill’s description into the context up front, and injects the whole file once the model asks for it. Any client could do the same with an MCP server’s prompts/list. That’s a harness feature, and it doesn’t need a new noun.
My own Helmsman calls them skills too. I used the word because nobody would understand anything else, and that’s my whole complaint.
The Port¶
This month the mediocre got their favorite kind of content: two big ports, both written by agents. They don’t deserve the same reaction.
David Heinemeier Hansson had agents port Campfire, the 37signals chat app, to other stacks. The verification repo lists eight implementations next to the Rails original, and the Rust port alone has 437 commits, 413 of them under David’s account. 37signals built Campfire. They know what the original does and what every port has to return, and the checks say so: “Every measured HTTP response must match its route contract: status, headers, complete decoded body, expected messages and content.” The people who wrote the original wrote the checks, and they might run one of these ports for real. That’s why I sent patches to the Rust port.
On October 7 Theo announced tsc-rs, a Rust port of TypeScript 7. TypeScript 7 is itself a port. The TypeScript team moved their own compiler to Go step by step, and they knew what came before because they wrote it. Theo ported their port with no idea what came before it or what Microsoft plans next. Around $400k of Codex tokens got nowhere, then around $20k of Opus got there in two weeks. “I have not read a single line of the code.” Within the hour, Theo added that Opus “ported most of gostd library into Rust” while it was at it.
A port like that carries everything across, bugs and legacy behavior alike, and nobody on the Rust side knows which is which. Of the first five issues filed on tsc-rs, four turned out to be issues in upstream TypeScript that the port had recreated faithfully. Theo’s verdict: “Wild.” When Microsoft changes that behavior in Go, the change has to reach Rust code that Theo has never read.
Anthropic’s own showcase went the same way in February. Sixteen agents spent $20,000 in API costs writing a C compiler in Rust that builds Linux 6.9. Issue #1, filed the same day, was “Hello world does not compile,” using the example from the README. The kernel brings its own headers. A hello world needs the compiler to find stddef.h, and on Fedora and Ubuntu it couldn’t. The seniors shrugged at both, because code like this has no owner.
The mediocre cheered all of it the same way. The juniors were alienated: the thing they’re trying to learn had just been declared optional.
The port with an owner came with a question of its own. Ruby is the slowest, David wrote, and that didn’t matter while the payoff was productivity and developer joy.
“But if you’re no longer reading the code?”
🔗Interstellar Communications
No transmissions detected yet.Be the first to establish contact!
Related Posts
The Republic of Slop
A country where no citizen has ever felt a constraint. The dev box has 128GB, the model never says "this is too much," and the cloud bills instead of refusing. Then it ships to a 2GB server. On languages as materials, and the 100x receipt that proves nobody measured anything.
tools/listChanged Is a Bug, Not a Feature: What Claude Code Gets Wrong
I just watched Claude Code ignore the MCP spec in real-time. The server sent tools/listChanged. The client did nothing. I had to manually reconnect. This is not a feature -- it is a bug hiding behind silence.
Skills Are Not Skills: The MCP Misunderstanding Nobody Wants to Correct
Skills are tutorials. MCP servers are executables. One tells Claude what to do. The other does it. The difference matters, and the ecosystem is lying to you about it.