An account redirect landed in the wrong place, and I treated it as a one-line routing configuration mistake. I opened the production application’s long-lived clone set and traced the legacy routing path because that model made the fastest fix look obvious.

The file that actually contained the problem was routing-260420.js. Its date-like name showed when it was compiled. It said nothing about whether the compile output was correct. Redirect destinations inside the file had been truncated. The file did not throw a script error, and the logs did not show a failure. It held wrong strings in a minified artifact, so accounts were redirected to the wrong destination until the support report arrived five days after the commit.

I recompiled with corrected settings, restored the redirect, and moved the hotfix through the branch stack. That work took most of an afternoon. Then I counted 14 dated script artifacts in the same folder.

The minified artifact hid its own origin

The production application follows an older pattern. Source is compiled and minified into a dated artifact, then the artifact is committed. The artifact name carries a date, but the commit did not record the invocation that produced it. For routing-260420.js, the repository did not say which tool or options had produced the output.

I asked Claude to reconstruct that invocation from the repository context. Claude could not do it because there was no build script, recorded target, or note that named the command. Its best reading was that the artifact had been created by an ad-hoc process and committed directly. That might have made the truncation a one-time mistake, or it might have been true of the 14 neighboring files. The repository could not decide between those explanations without opening each artifact.

This failure mode produced no direct signal. There was no compile error to search for. The broken output sat in the repository for five days before the report surfaced it. During that interval, the redirect used truncated destinations, and monitoring had no expected artifact content against which it could compare the output.

The new build path recorded the process

I added two checks for future compilations. The first uses an explicit configuration file for the minifier so the output comes from one repeatable configuration instead of an ad-hoc command. The second runs a syntax check on the output immediately after compilation. If either step fails, no artifact is produced for commit.

That process protects new artifacts. It does not stop a developer or an agent from committing a file created through another path. I added a pre-commit hook for that case. A dated script staged for commit receives the syntax check before the commit is accepted. A broken file fails the hook and the commit stops.

The production application has multiple clones on one host, each used for a separate development track. The shared hook directory is registered through a per-clone version-control setting. A fresh clone does not inherit that setting. The validation hook therefore remained absent until someone performed a configuration step, which repeated the same fragile reliance on memory that had allowed the artifact through.

The hook registers at session start

I added the hook-path registration to the session-start script that Claude runs when it opens a working directory. Each clone session now registers the shared hook path when it is missing. The compile gate is present before the first edit in that clone.

That change removes the remembered setup step from the normal Claude workflow. A clone opened outside that workflow can still commit directly without the session-start registration. In the present setup, active development sessions pass through Claude, so that path remains a known assumption rather than a solved problem.

The older artifacts remain unaudited

The original redirect is corrected. routing-260420.js now contains the intended output, and the account redirect works. The 14 other dated artifacts in the same folder are still unaudited. The pre-commit hook will block the next broken artifact, but it says nothing about an artifact already committed. The audit is separate work that remains on the stack.

The hook stops the next bad dated artifact before commit, but the 14 artifacts that predate it still need their own audit.