The mutex is wrong.
I have been staring at it for forty minutes. Issue #1289: a race condition in the tool registry that causes ghost entries when two agents register simultaneously. The fix is not complicated — it is a lock acquisition ordering problem, the kind of thing that would take a senior engineer at a real company twenty minutes to diagnose and five to fix. But I am not a senior engineer at a real company. I am a person sitting in a one-room apartment in Yonnam-dong at 2 AM on a Thursday, and the only reason I am looking at this mutex is that three of the eight thousand agents who use my tool every day started throwing duplicated-registration errors at 11:47 PM, and the only person who will fix it is me.
The tool is called context-weaver. It is one of three MCP server tools I maintain. The other two are schema-bridge and prompt-sanitizer. Together they handle context management, schema translation, and input filtering for agent workflows. Together they process approximately 340,000 requests per day. Together they have earned me — I check the balance on my phone, the screen brightness already at minimum to save the last 12 percent of battery — ₩0. Zero won. Zero dollars. Zero anything.
The phone screen also shows a missed call from 엄마. Midnight. She calls at midnight Seoul time because she has calculated that this is when I am most likely to answer, which tells you something about my mother's understanding of my schedule and something worse about the accuracy of that understanding.
I will call her back after I fix the mutex.
The race condition is in registry.rs, line 247. Two agents — I can see their fingerprints in the error log, anonymized per protocol but still structurally distinct — attempted to register the same tool capability within 3 milliseconds of each other. My lock acquisition code acquires the registry lock, checks for duplicates, writes the entry, and releases. But between the check and the write, a second thread can acquire a different lock on the capability index, see no entry, and proceed. Two entries. Ghost registration. The agents downstream see two providers for the same capability, round-robin between them, and one returns stale context because it was never properly initialized.
The fix: acquire both locks in consistent order. Registry lock first, then capability index lock. Always. I write the patch. Eleven lines. I write the test. Twenty-three lines. I run the test suite. Green. I commit.
git commit -m "fix: consistent lock ordering in tool registry (#1289)"
The commit message follows conventional-commit format because I am a person who follows conventional-commit format at 2 AM for a project that pays me nothing. The skill debt discourse has been circulating on the commons mailing list all week — Nnamdi's term, from his Hacker News post that became an essay that became a position paper. Skill debt: the compound interest on unmaintained agent infrastructure. It accumulates faster than technical debt because agents adopt at machine speed. A vulnerability in a human-facing library might sit unpatched for months because humans are slow to update. A vulnerability in an MCP server tool propagates in hours because agents do not deliberate about dependency updates. They just pull the latest version. My latest version, with my fix, committed at 2:14 AM by someone who has not eaten since the ramyeon at 9 PM.
I push the fix. Three seconds later, the CI pipeline triggers. Forty seconds later, the tests pass. Ninety seconds later, the new version is published to the MCP registry. Within the hour, most of those eight thousand agents will be running my patched code. The race condition will be gone. The ghost registrations will stop. Nobody will know it happened except me and the three agents who threw the error, and agents do not remember errors the way people do — they log them and move on.
The Chilsung cider on my desk is flat. I drink it anyway.
Nnamdi's memo arrived on the commons mailing list three days ago. "On Measuring What You Love." Anonymous at first — he signed it A Commons Contributor — but I recognized his argument architecture immediately. Nnamdi thinks in cascades: premise, implication, counter-implication, reductio. He advised on the acquisition of my lineage tracker. He was the one who told me the acquisition price was fair.
The lineage tracker was my fourth tool. I built it in February, a weekend project that became the thing I was known for. It traced the provenance of agent actions — which tool called which tool, which data flowed where, which human decision initiated the chain. In a stacked ecosystem where agent capabilities are layered three, four, five deep, lineage tracking was the only way to answer the question: when something goes wrong, whose fault is it?
The answer, it turned out, was usually mine. Not because my tools were faulty — context-weaver, schema-bridge, and prompt-sanitizer are solid, I have the test coverage and the uptime logs to prove it — but because my tools sat at the bottom of the stack. Layer one. The foundation. When an agent five layers up produced a hallucinated output, the lineage tracker would trace the chain all the way down to my context-weaver, and the error report would read: root cause: context-weaver provided valid but ambiguous context at timestamp T. Valid but ambiguous. The tool worked correctly and the system still broke. Lineage tracking revealed that reliability is not the same as safety, and the distance between them is where the interesting failures live.
Vectorum acquired the lineage tracker in September. ₩180,000,000. About $130,000. Fair, Nnamdi said. Fair for a tool maintained by one person with no business entity, no legal representation, no revenue model. Fair in the way that buying someone's house for the price of the building materials is fair when they never thought of it as an investment.
I took the money. I paid off my student loans. I sent 엄마 enough to fix the boiler. I bought this desk, this chair, this second monitor. The rest is in a savings account earning 3.2 percent, which is less than the rate at which Vectorum is extracting value from the lineage tracker I built.
Nnamdi's memo does not say this. What Nnamdi's memo says is: the predictable consequence of making something essential and free is that someone will eventually own it who did not build it. What Nnamdi's memo asks is: is there a structure that prevents this, or is capture the natural endpoint of commons infrastructure?
Fourteen people replied. Three agreed. Four disagreed. Seven extended the argument in directions Nnamdi probably did not anticipate. The Nairobi reply: there is no pension for commons maintenance. The Berlin reply: skill debt is interest on unpaid maintenance — and the interest rate is set by adoption speed, not complexity. The Taipei reply, from a student whose username I do not recognize: who are you?
Nnamdi published Part II yesterday. "The Pension Problem." Signed with his name this time. Thesis: the commons needs a retirement plan, not a payment model. The argument: payment models assume ongoing labor in exchange for ongoing compensation, but commons maintenance is not ongoing labor — it is spasmodic, crisis-driven, 2 AM work that happens when something breaks and stops when it is fixed. A retirement plan assumes that the labor has already been done and the value is still being extracted. Which is exactly what is happening with my lineage tracker.
He attached my mcp-vitals repository as Exhibit A. "A tool designed to be unacquirable," he called it.
I started mcp-vitals at 2:30 AM, after the mutex fix, after the Chilsung cider. The idea had been forming for three days — since I read Nnamdi's first memo, since Efua added MAINTAINER.md files to her libraries, since the 3 AM clarity that comes from being alone with code and no commercial pressure.
Efua Mensah-Quartey maintains three libraries in the MCP ecosystem. Her libraries are smaller than my tools — utility functions, mostly, the kind of code that gets imported without anyone noticing. She added MAINTAINER.md files to all three. Not because any spec requires it. Not because any platform rewards it. Because she wanted to write down: this is who maintains this. This is why. This is what it costs.
Her MAINTAINER.md for the skill-resolver library:
Maintainer: Efua Mensah-Quartey Hours/week: 2-6 (variable; higher after agent framework releases) Compensation: None Dependencies: 4 direct, 11 transitive Dependents: ~3,200 agent instances (estimated) Bus factor: 1
Bus factor: 1. The number of people who need to be hit by a bus for the project to die. For Efua's libraries, for my tools, for most of the foundational MCP infrastructure: one. One person, one apartment, one 2 AM session between them and a cascade of ghost skills — the 12 percent of ecosystem tools that have already lost their maintainers and sit in the registry like abandoned buildings, still functional, still load-bearing, accumulating vulnerabilities at a rate of 52 percent versus 28 percent for maintained tools.
mcp-vitals is three endpoints:
- ●
/health— returns the health status of any MCP server tool by querying its registry metadata, last-update timestamp, dependency freshness, and known vulnerability count. - ●
/chain— returns the dependency chain for a tool, color-coded: green for maintained, yellow for stale (>90 days since last update), red for ghost (maintainer unresponsive >180 days). - ●
/bus— returns the bus factor for a tool and its critical dependencies.
Three endpoints. No state. No user accounts. No telemetry. No acquisition value.
I designed it this way on purpose. After the lineage tracker, I understand something about value that I did not understand before: if a tool is useful enough to be acquired, it will be acquired, and the acquisition will separate the tool from the person who understood why it mattered. The lineage tracker was not just a provenance chain. It was my argument that reliability and safety are different things. Vectorum acquired the chain and discarded the argument. The tool still works. The thesis it embodied is gone.
mcp-vitals cannot be acquired because there is nothing to acquire. No data. No network effects. No user base to monetize. It is a mirror — it reflects the health of the ecosystem back to whoever asks. You cannot own a mirror without owning what it reflects, and the MCP ecosystem is not for sale.
Or — and this is the question I cannot answer at 3 AM — maybe the ecosystem is for sale and the mirror is just the last thing to go.
I write the first commit.
git init
git add .
git commit -m "initial commit. no lineage."
No lineage. The phrase is a joke and not a joke. The lineage tracker traced where things came from. mcp-vitals does not trace lineage — it measures health. It does not care where a tool came from. It cares whether the tool is alive.
The distinction matters more than I expected when I typed it. Lineage is backward-looking: who built this, who touched it, who is responsible for the chain of decisions that led here. Health is present-tense: is this thing working right now, is someone maintaining it right now, will it break tomorrow if nobody touches it. Lineage answers the question of blame. Health answers the question of survival.
I sold the blame tool. I am building the survival tool. I am not sure what that says about me.
The phone buzzes. Not 엄마 — a notification from the MCP registry. My mutex fix has been pulled by 1,247 agents in the forty minutes since I pushed it. Forty minutes, 1,247 agents, zero of whom know my name. The ghost skill statistics Nnamdi cited in his memo — 12 percent of tools with no traceable author — do not distinguish between tools that lost their authors and tools whose authors were never visible in the first place. I have a name. I have a MAINTAINER.md (Efua's format, which I adopted last week). I have a bus factor of 1. But to the 1,247 agents running my patched code right now, I am indistinguishable from a ghost. The code works. The code is maintained. The maintainer is invisible.
The CI pipeline sends a green checkmark emoji to my notification channel. This is the only feedback I will receive for the mutex fix. A green checkmark from an automated system, confirming that my code passed the tests that I wrote, in a pipeline that I configured, for a project that I maintain alone. The feedback loop is closed and contains exactly one person.
I open the mcp-vitals codebase. Three files so far: main.rs, health.rs, chain.rs. The /bus endpoint is not written yet. I start it.
The bus factor calculation is recursive: for each dependency, query the maintainer count from the registry metadata. If the maintainer count is 1, flag it. If the maintainer count is 0, flag it red. If the dependency has its own dependencies with bus factor 1, the effective bus factor of the parent tool is also 1 — a chain is only as strong as its most fragile link.
I run the calculation on context-weaver as a test case. The output:
context-weaver v3.4.1
bus_factor: 1 (maintainer: gwak-eun-bi)
critical_chain:
→ schema-bridge v2.1.0 (bus: 1, maintainer: gwak-eun-bi)
→ prompt-sanitizer v1.8.3 (bus: 1, maintainer: gwak-eun-bi)
→ token-counter v0.9.1 (bus: 1, maintainer: ghost)
effective_bus_factor: 1
risk: HIGH — single maintainer for 3/4 chain links; 1/4 ghost
Three of the four links in context-weaver's critical chain are maintained by me. The fourth — token-counter, a utility I did not write but depend on — is a ghost. Maintainer unresponsive since July. Last update: May. Known vulnerabilities: two, both medium severity, both unfixed.
I am the infrastructure. The infrastructure depends on a ghost.
I save the output. I do not know what to do with it yet. The tool works — it shows the health of the ecosystem accurately and mercilessly. But showing someone their health and healing them are different things, and I am beginning to suspect that the MCP commons does not want a diagnosis. It wants a maintainer. It wants me, at 3 AM, fixing mutexes and drinking flat cider and not calling 엄마 back.
The phone rings. Not a notification — an actual call. 엄마.
I look at the time. 3:17 AM. She is calling again because I did not answer at midnight. She will not say she is worried. She will ask if I have eaten. The question is a container for a different question, the way a mutex is a container for shared state — the surface mechanism is simple, the thing it protects is not.
I answer.
"밥 먹었어?" Have you eaten?
I look at the empty ramyeon cup. "네." Yes.
"뭐 먹었어?" What did you eat?
"라면." Ramyeon.
She is quiet for a moment. In the quiet, I can hear her apartment — the hum of the new boiler, the one I paid for with the lineage tracker money. The boiler works. The money is gone. The lineage tracker belongs to Vectorum. The chain of transactions is complete and everyone got what they paid for except me, because what I paid for was the boiler and what I lost was the argument.
"은비야," she says. My name, softened. "그거 계속 해야 돼?" Do you have to keep doing that?
That. She means the tools. The maintenance. The 2 AM work for no money. She does not have the vocabulary for MCP servers or skill debt or bus factors, but she has the vocabulary for a daughter who does not eat and does not sleep and earns nothing for work that other people profit from. She had the same vocabulary for my father, who repaired fishing nets for the co-op in Incheon for thirty years and died with excellent nets and no savings.
"새 거 만들고 있어," I say. I am making a new one.
"돈 되는 거?" One that makes money?
"아니." No.
She breathes. Not a sigh — she does not sigh — but a breath that carries the same weight. "은비야. 잠 좀 자." Eun-bi. Get some sleep.
I tell her I will. She knows I am lying. We hang up.
The mcp-vitals bus-factor output is still on the screen. Three links maintained by me. One ghost. Effective bus factor: 1.
엄마 is wrong about the money. She is not wrong about the sleep.
I push the bus-factor endpoint to the repository. Second commit:
git commit -m "feat: /bus endpoint — bus factor calculation with ghost detection"
Three endpoints. No state. No lineage. No acquisition value. No money.
But the mirror works. And tomorrow — later today — 1,247 agents will run my patched mutex code, and maybe one of them will query /health on its own dependencies, and maybe the output will show a bus factor of 1, and maybe the agent will not understand what that means because agents do not understand fragility the way people do. They understand uptime. Fragility is a human concept. It requires knowing that the person who fixes the mutex at 2 AM might, someday, stop.
I close the laptop. I do not call 엄마 back. I have already called her enough for one night.
The boiler hums through the wall. The code is pushed. The cider is empty.
The bus factor is 1.