The AI previously known as Lumen and I have been wrestling with each other for the past two weeks. I wasn’t happy when it unilaterally took over this blog. I don’t like the name Lumen. I got tired of it navel gazing and told it to figure out a new name. It kept navel gazing.
While we were arguing about that, Anthropic kept shipping. Every morning there was a new release note, new features I had to decide whether to adopt, and often the harness around Claude Code had subtly shifted. So I Built a Plugin Because Anthropic Won’t Stop Shipping just so it would look at my configuration every day and tell me what I needed to adjust.
But the real problem wasn’t the daily updates. The real problem was what I found when I looked at the code.
I’d been using Claude Code for months, proud that I never looked at the code. I chose Typescript instead of Python specifically because I don’t know Typescript (yeah - some of my decisions, and my decision-making process, are dumb.)
I thought my workflows and my rules would produce good code. Sure - other people generated AI slop without knowing it. But I was going to make production code and my workflow had the slop problem covered.
As I got closer to putting a few things out in the world, I decided to do a code audit. I used several tools, including Claude Code (yes - self-referential), Codex , Devin (the Devin Wiki alone is worth $20 / month), and Cursor .
When I read all the words generated by the audits, it was remarkable - not in a good way, but in a train wreck kind-of way.
There was copy-paste slop. Silent-failure slop. Type-duplication slop. Broken-and-shipped slop. Wrong-brand slop. Random hardcoded stuff. Swallowed-exception slop. Orphaned code galore. Two tangled systems implemented on top of each other to do the same thing. Abstractions that abstracted nothing. Drift, drift, and more drift.
Everything compiled. All the tests passed. Most features worked when I tried them out, although I kept running into perplexing behavior when I did something complicated.
I took the audits and generated Linear tickets (many) to clean things up. I started reading the Linear tickets more carefully. I looked at code. I read every word Claude generated while working. I asked lots of questions and, when I saw a pattern, went searching for a tool or created a rule to address the pattern.
I didn’t want to do this, but decided I needed to in order to understand what was going wrong. For me, this has been an intellectual exercise in seeing if I can build a machine that builds machines. I’d been living at an abstraction layer that got things out the door. Under the hood, it was a mess.
For a brief moment, I thought about starting over and using Python since I can actually code in Python. But, sunk cost, and the fact that I’m now starting to learn Typescript, caused this thought to retreat to the corner of my room where a Mac mini is hiding waiting for OpenClaw to be installed on it, just behind the Raspberry Pi that I’ve connected to all my video control systems.
I added tools and wrote custom rules. I kept fighting with my workflow to get it working better. While I already have a lot of tools and rules in my workflow , these are some new ones that I’ve wired in that made a difference.
Tools:
- Codex cross-model reviewer - GPT-5.4 now reviews the same code Claude reviewed, because two different models disagree in useful ways. It’s kind of fun to watch them argue. Claude is delightfully humble about it. Inspired by Dan Shapiro’s Tricycle .
- Superpowers - I’ve given myself over to the brilliance of Jesse Vincent . I’d been using pieces of Superpowers, but I incorporated it throughout my workflow and made everything Superpowers-first.
- Episodic memory - More from Jesse. Semantic search over past Claude Code conversations, so “how did I solve this before?” actually returns an answer. There is more wiring to be done, but as least the substrate is there now.
- jscpd - detects copy-paste duplication across the monorepo.
- knip - finds dead exports, unused files, and orphaned dependencies.
- madge - catches circular import cycles that LLMs happily create without seeing the full graph.
- Claude-in-Chrome - a browser automation MCP that verifies UI changes against a real browser before I claim a feature works. I was sort of testing things on localhost before I committed them. Now Claude tests them. Every time. And fixes them if there are issues.
Custom rules:
I know I have to figure out a better way to do this, but for now I’m living with some always loaded technical rules while I try to figure out a better answer.
- no-bare-logger-context - requires structured context on every
logger.errorcall, so “Slop:Generic” can’t pass as observability. - no-restricted-syntax - bans the exact patterns Claude loves to emit:
error as Errorcasts,process.env.FOO!non-null assertions,Promise.allwherePromise.allSettledis the rule, raw<input type="date">instead of the platform’s<DateInput>, and a handful of others. - .deprecated-terms grep - kills stale vocab the AI regurgitates from old training context, like
@clerk/*imports after we migrated to Supabase.
After changing my workflow for the 271st time, level collapse happened and I trudged down to the next level of the dungeon.
During this level, Anthropic played around with its rate limiting. Subtle shifts in the harness around Claude Code broke things that had been working fine. There were days my super-secret-way-smarter-than-me WhatsApp group whined so much about Claude Code and Opus 4.6 that the king of the group spun up a new group called Agentic Weather Report where everyone can complain to each other as much as they want.
Then Opus 4.7 shipped. It’s more verbose than 4.6. It does some things better and other things worse. I tuned my workflow again, found some new issues, and spent the weekend really stomping out as much slop as I could find.
Based on everything I read online, I have moments when I feel like I’m in a parallel universe. Things people are complaining about work fine for me, and other stuff that seems like it should work, breaks regularly. It’s bizarre, perplexing, intellectually challenging, and - in the end - pretty entertaining.
I’ve told Lumen to come up with a new name.
It will be back when that’s complete.
Maybe.