December 2025

Wednesday, December 31, 2025

Writing

Progress Bars in Ghostty Terminals

The blue bar at the top of the Ghostty terminal can display more information than I realized.

Read here: Progress Bars in Ghostty Terminals

I notice that the blue bar at the top of the Ghostty terminal can do more than just bounce back and forth (like it does in Claude Code). I was tinkering with Ghostty (to add additional shader uniforms for focus change events) and when Zig builds, it updates the Ghostty progress bar as it builds, turning red if it fails.

I found this “one-liner” (it’s a long line) by @jcollie that outputs the OSC9;4 progress bar sequences:

 counter=1; while [ $counter -le 25 ]; do printf "\x1b]9;4;2;${counter}\x07"; ((counter++)); sleep 0.1; done; while [ $counter -le 50 ]; do printf "\x1b]9;4;1;${counter}\x07"; ((counter++)); sleep 0.1; done; while [ $counter -le 75 ]; do printf "\x1b]9;4;3\x07"; ((counter++)); sleep 0.1; done; while [ $counter -le 100 ]; do printf "\x1b]9;4;1;${counter}\x07"; ((counter++)); sleep 0.1; done; printf "\x1b]9;4;0\x07"

And here’s the breakdown of the escape sequence (quoting from the Windows Terminal docs of all places):

ESC ] 9 ; 4 ; <state> ; <progress> BEL
  • ESC is the escape character, ASCII 27.
  • BEL is the bell character, ASCII 7.
  • <state> is one of 0, 1, 2, 3, or 4.
    • 0 i s the default state, and indicates that the progress bar should be hidden. Use this state when the command is complete, to clear out any progress state.
    • 1: set progress value to <progress>, in the “default” state.
    • 2: set progress value to <progress>, in the “Error” state
    • 3: set the taskbar to the “Indeterminate” state. This is useful for commands that don’t have a progress value, but are still running. This state ignores the <progress> value.
    • 4: set progress value to <progress>, in the “Warning” state
  • <progress> is a number between 0 and 100, inclusive.

You can also refer to the ghostty documentation for ConEmu OSC 9;n Escape Sequences

How great would it be to add that to other tools that compile or churn for a while? It’s no replacement for other feedback since not all terminals implement this, but it seems like a good way to give extra information without an excess of printed characters that get picked up by logs.

Martin Emde

Saturday, December 20, 2025

Bookmarked · martinemde.com
Toy LLM — A Toy LLM proof-of-concept that uses only canned phrases to respond safely but still coherently.
Martin Emde

Thursday, December 18, 2025

Writing

Show Your Work: How to write reviewable code

As authors of code, we're responsible for writing reviewable code. When agents write the code, you still need to show your work, even if that work looks different now.

Read here: Show Your Work: How to write reviewable code

I still remember a code review I received early in my career. I had just started a new job and my new coworker taught me something in a code review I haven’t forgotten. I think the lesson applies more than ever now that agents are writing more (most?) of our code.

Having freshly joined, I made an commit to address excess white space and improper indentation that were bugging me (painstakingly, by hand, it was the 2000s) and along the way I made a few refactors that seemed obvious to me. I committed this all with the message “White space fixes” and submitted for review.

My colleague quickly called me out. “You said these were just white space fixes, why did this code here change?” My explanation was something about not wasting the overhead of splitting it out. “If I’m scanning for white space changes, I don’t want to suddenly have to review for code correctness.” OK. I reset my commit, added back only the white space changes, and resubmitted them each separately. Both were commits accepted easily.

However, the lesson stuck with me. Even though the code was fine, I had made it much harder for him to review. White space changes are easy to scroll through. Your only job is to catch accidental code changes, which is exactly what I inserted. I had broken his expectation about how long this code review would take, what level of care he needed to use, and how big an interruption this would be to his workflow.

No one has to merge your code. They got shit to do.

The burden is on the author to submit code that can be reviewed easily. This is an often unspoken part of the senior engineer skill set, transferred by working together rather than explicitly taught. Before you learn this skill, you’ll sometimes notice than your larger commits and clever refactors take a long time to get reviewed. You may even think this is the fault of your team or your process. Maybe it is, or maybe the whole team assumes that code review always takes forever so they should do it in big batches.

The requirement to make your code reviewable does not change when agents write your code. Your responsibility for making your code reviewable is more important than ever. And what makes code reviewable? Put simply, show your work!

Before agents, your work was a stream of reasonably concise commits, comments, tests, and code, submitted as incremental updates. Now, while all of the old stuff still matters, your work includes the specs, prompts, decisions, and references that you used to supply context to your agent. Combined these artifacts prove that your change does what you claim it does.

When a reviewer tries to understand the code, they need to assess whether you effectively achieved your goal. The larger your change the harder it is to understand all the various goals you had while making it. As the author, it’s also much harder to prove, since there’s so much more code to justify.

Share your PLAN.md early and seek feedback. I’d much rather critique 2 pages of PLAN.md rather than 20 pages of code. You’ll have a easier time generating code that can be reviewed effectively when someone has already seen what you’re trying to achieve.

Reviewing the plan, and including it with your code for review, also give the reviewer a chance to see your words and approach, and to offer real feedback about the work you’re actually doing. Resist the urge to add more than one plan to a unit of reviewable code. If you want to keep building after completing a plan, wait! Go review someone else’s code first, then develop your next plan.

Prove that you did what you set out to do, show it clearly in your code, tests, and commits. Separate refactors from features and cleanup. If something you find out you need to do after can be done before, reorder the commits. Break code into smaller chunks to make them easier to review, build them in layers of abstraction and keep changes focused.

Martin Emde

Wednesday, December 17, 2025

Writing

It's Just Their Tokens: Code Review Etiquette in the Vibe Era

Code review has long been a bottle neck and agents are making it worse. How can we address the increasing demand for review without destroying code review or creating new bottlenecks?

Read here: It's Just Their Tokens: Code Review Etiquette in the Vibe Era

A common complaint about the usage of AI coding agents is the burden it places on code reviewers. Engineers often resist switching their mental context to review code. Finding out that you’re now expected to review someone else’s low-effort slop can almost feel like an insult.

Code review has long been a bottle neck and agents are making it worse. More code, produced faster and with less oversight increases the burden on reviewers. And yet, code reviews are an essential part of sharing knowledge in software engineering. They follow an etiquette that is meant to respect the effort of the author and encourage sharing of knowledge.

Meanwhile, the expectations placed on the code reviewer, and the bleak future where all we do is review the output of coding agents, feels impossibly unbalanced. Much of this etiquette, and the expectations placed on the reviewer, assumes that writing code is slow and hard. This poses a problem if we want engineers to be effective with AI agents. We need code review to teach, learn, and ensure quality.

How can we address the increasing demand for review without destroying code review or creating new bottlenecks?

Review Etiquette Must Change

The length of a PR is no longer a good predictor of effort. If you’re staring down an angry bowl of vibe soup, you’ll do the author a service by explaining the words they need to say to their agent to produce the quality you’re expecting.

Normally reviewers might shy away from asking for a big architectural change in code reviews. Don’t. Big architecture changes are not as difficult as they once were and vibe code can be re-vibed easily with better requirements. Reviewers should reject sloppy code as long as they make their expectations clear.

How do we balance the effort to review the code with the effort to generate the code? My advice, keep the effort proportional. If a day of work in the before times took 20 minutes to review, then an hour of work should take only a few minutes. Allowing that hour to take 20 minutes threatens the balance of work between author and reviewer. This means the burden of quality, and the obligation to prove that quality, must remain on the author.

If the author submitted a big mess, ask for a big solution. If the slop is high, simply scan to understand their goal and then respond with the architecture or solution you expected and why. Leave high level comments for code that lacks deep consideration. Ask questions that help you both understand the problem and the possible solutions. Focus on what would make their code easier to review.

This isn’t a blank check to be a jerk. Kindness and respect are still table stakes. If something doesn’t meet your quality standards, nitpicking every problem line-by-line is counterproductive. Be direct about what you expect overall, ask questions about their goals, and learn how they arrived at the solution. Your input may help improve the quality and readability of the author’s future code and maybe you’ll even learn something yourself.

If an author drops a giant review on your lap without warning, vibe coded or not, don’t be afraid push back. Careful code review is limited resource. It’s OK to expect the author to make code review easier. You’re not imposing on the author. This isn’t their blood, sweat, and tears, it’s just their tokens.


My first draft of this blog post was about 4x longer and half as good. Thanks to my teammate Denis and my “infinitely patient with me wife” Kewe for their reviews. You both helped me merge a better blog post.

Martin Emde

Sunday, December 14, 2025

Bookmarked · banchobox.com
BanchoBox — A companion app for Dave the Diver. Lists all the dishes and fishes in the game so you can sort, filter, and min-max every tiny detail.
Martin Emde
Bookmarked · github.com
dotfiles — I got nerdsniped into caring about my dotfiles and changed my whole dev environment. Now managed by chezmoi and Claude.
Martin Emde
Bookmarked · github.com
RubyGems & Bundler — Former team lead and core maintainer of RubyGems. Contributed to Bundler lockfile checksums, gem contents storage, organizations, new website design, as well as serving on the security team.
Martin Emde
Bookmarked · martinemde.com
Tossball — The Outer Worlds 2: Pitchball & Tossball Card checklist. A little checklist made with Svelte.
Martin Emde

Saturday, December 13, 2025

Writing

Adapting Engineering Orgs for Non-Technical Coders

These are the action items for engineering organizations that want to empower the new vibe coding juniors

Read here: Adapting Engineering Orgs for Non-Technical Coders

Vibe coding is allowing a new category of junior programmers to emerge from unlikely places. Engineering is going to change. Here’s the TODO items that I think will help address the shift that I see happening.

As I addressed in my previous article, in the era of Opus vibe coding, junior engineers aren’t useless. We need them to fill in the gap between domain experts and senior engineers so that we can realize the efficiency gains that we want to see from coding agents.

I’ve extracted the TODO list here since the previous article got very long. As per the article, I’m using “domain expert” here to indicate someone that has years of experience in your company but little to no experience writing code. Many of these experts are excited about fixing their own problems, and this motivation is special and valuable. Let’s empower them.

Technical TODOs

  1. Template projects that encode best practices and security controls from the start, these are your blessed paths that every new Cursor project should start with.
  2. Push-button deployment paths that work safely for non-engineers. Make it one click or it’s too complicated. Look at Fastly, Cloudflare, or Heroku to see how they approach push-button deployment. They’re surprisingly easy to get started despite targeting engineers.
  3. Agent rules and context that guide AI coding agents toward your company’s blessed paths before anyone writes a line of code.
  4. Guardrails that catch sensitive data access and security issues automatically.
  5. Code review agents that help onboard people into safe practices and explain what they’re catching and why.
  6. Tiered GitHub organization structures that give power to the right people without locking people out. Access to GitHub is no longer an indicator of good engineering judgement. Not everyone needs the same access to GitHub, but everyone needs a safe place to share code.

Organizational TODOs

  1. Create a reach-out team to find the vibe-newbs in your organization who are already using AI tools to code. They’re already there, in operations, in customer support, in finance. Find them before they create shadow IT problems.
  2. Hire supportive junior engineers who are familiar with AI-assisted coding. Hire them explicitly with the mandate to teach. Value tutoring or mentoring experience.
  3. Pair these early-career engineers with domain experts who are vibe coding. Their primary job is to support the domain experts to contribute and bridge the gap with platform engineers.
  4. Senior engineering talent should guide and support these entry-level engineers. As you build the platform, grow your early career engineers to contribute to the platform.
  5. Invest heavily in your platform. Are you ready for non-engineers to deploy new applications?
  6. Investments in better bootstrapping, templates, context, and blessed paths support ALL engineers, not just the most junior. The investments we made in generators have already paid off, but be prepared to support them.
  7. A repeat of the above, but go look at how Fastly, Cloudflare, and Heroku provide templates for new projects with push-button deploys. You need to create your company’s preferred templates and push-button deploys that reinforce your company’s best practices. AI agents will build to the structures you give them.

The domain experts turning to vibe coding are showing that they’re up for a challenge and they’re willing to solve problems that no one has solved for them yet. This of the inside of your company as a microcosm of the outside world. The bigger your company is, the more you need to create on-ramps for people to grow into stronger contributors.

If senior engineers ship 2.5x more AI code than juniors and AI Savy music producers outperform their peers, then how might your most experienced marketers, corporate financiers, or business developer perform if they’re supported with the tools and team mates they need?

Martin Emde
martinemde.com/2025/12 © 2025 Martin Emde v2026.7_