---
title: "I Asked a Model to Trim Code Comments and It Rewrote the Code"
canonical: https://dxdev.com/blog/2026-09-14_comment-trim-tool-rewrote-the-code/
datePublished: 2026-09-14
---
The trim tool wrote the phrase `(empty response)` over the include lines that assemble two of our page layouts. I caught it in a diff review, fixed that case, and kept going. By the early hours of the next morning I was fixing live pages the same tool had broken.

## What the tool was for

We had a legacy web codebase full of long, chatty code comments, and I had a writing standard that said they should be short. So I built a four step tool: scan, draft, review, apply. For every long comment it asked a model for a shorter one, or for nothing if the comment should go, and apply wrote the reply back into the file.

On one clone the scan flagged about 2,037 blocks. 349 of them sat in vendored third party code, license headers from libraries we did not write, so I excluded that folder. That left 1,688 blocks to draft.

## Three fixes, each aimed at the last bad reply

I reviewed that batch by hand before committing anything, and the tool did not catch what I found.

The first bug was in classification. Server-side include directives, `<!--#include virtual=... -->`, look like HTML comments. 61 of the 1,688 blocks were real include lines, sent to the model as prose to trim. Its confused answer, the literal text `(empty response)`, was written into the file in place of working includes. Both layout files lost their include chain. Separately, 51 blocks got that same phrase echoed back instead of true empty output.

I fixed the classifier and normalized the phrase. Then the first commit attempt was blocked by the repo's own pre-commit hook, which runs a JavaScript syntax check on changed files. A fresh phrasing, `(no output - delete this block)`, had slipped past my phrase match and was about to land inside a compiled bundle. That hook caught it, and my tool had not. I replaced the phrase match with a shape check: every non-answer in the corpus was the model talking about the block, wrapped in one outer pair of brackets. It matched 75 of 1,626 proposals, up from 51.

The third bug was replies with no comment markers at all. 87 of 100 of those were fine content that the model had wrapped in a markdown fence despite being told not to, and stripping the fence fixed them. The other 13 were bare prose, and I made apply refuse to write anything that did not look like a comment. After the fixes, the batch had 0 fences, 0 bracket-wrapped noise, and 0 JavaScript syntax failures. It had been 5.

All three fixes had the same shape. The model said something wrong, and I taught the tool to recognize that particular wrong thing.

## What production showed

The next round of breakage did not match any of those patterns.

- One page had single-quoted JavaScript object entries. My comment detection treated a leading `'` as a VBScript comment marker because the file extension said classic ASP, and it deleted the entries. That marker is only a comment when the file's own language directive says VBScript. Exactly one file in the whole repo declares that.
- A reply that started with `//` replaced a `/* */` block in a stylesheet. Double slashes are not a comment in CSS, so that broke the stylesheet.
- A reply wrapped in a markdown fence was written into a shell script that held a database guard, and the guard stopped blocking. A plain `bash -n` check does not catch that.

By the time the session ended, the marketing page, the transaction edit popup and seven other pages were restored, and three API migrations could be re-run.

## The check I should have started with

The tool decided what to write by looking at what the model said. The safer question is what the tool is about to overwrite. So apply now refuses to touch a span unless every line in it is a comment or blank, regardless of what the draft step decided. Before any write it validates the whole result for that language: no markdown fence at all, a syntax check for JavaScript, including the JavaScript blocks inside server pages, a syntax check for shell scripts, and no `//` outside a `/* */` block in CSS. Nothing is written until every check has passed.

I ran the new validators against the actual broken files from production. All of them were rejected, and their repaired versions were accepted. 36 tests cover it.

I checked the two worst pages live that morning. The other restored pages and the API after its redeploy I filed as follow-ups instead of verifying, so as of this post I have not seen them load.
