By the time the application was ready, small changes had stopped being small. A fix in one service meant checking several similar implementations. Functions had grown into long sequences of conditions, and imports had begun to join parts of the application that were meant to stay separate. The software still worked, but each new change required more reading and more caution.
The application started with a frontend design from Vercel. Claude Code handled later frontend changes and implemented the Node.js backend. The finished Next.js and Node.js repository contained roughly 400 source files and 33,759 non-comment lines.
Most changes made sense on their own. Copying a working block was safer than changing shared code. Adding a condition was quicker than reorganising a function. The maintenance problem came from hundreds of reasonable local decisions, not one bad change.
A check that remembers
Claude Code had already been told to avoid duplication and keep functions short. Those instructions helped only when the relevant code was in context. They could not find a matching block in an unopened file or show that a function had become more complex than it was in the previous commit.
lumioguard CC was created to make that comparison. It parses the source and records complexity, nesting, function size, exact duplication and the import graph. It also checks dependency cycles and declared boundaries between layers. Existing findings remain visible, but a change fails only when it adds a blocking finding or makes one worse. If a required file cannot be analysed, the result is incomplete rather than clean.
The checks cover the common ways a codebase becomes harder to change:
| Check | What it shows |
|---|---|
| Cyclomatic and cognitive complexity | Functions with too many paths or control flow that is difficult to follow |
| Nesting depth | Conditions and loops buried inside other conditions and loops |
| Function length and parameters | Functions that may be doing too many jobs |
| File tokens | Files that require a large amount of source to be read |
| Exact duplication | Blocks copied into more than one place |
| Fan-in and fan-out | Files with too many incoming or outgoing dependencies |
| Dependency cycles | Files connected through an import loop |
| Architecture boundaries | Imports that cross layers the project has declared separate |
| Coverage | Line and branch coverage read from an existing LCOV report |
The coverage check reads a report produced by the project's test tools. lumioguard CC never runs the tests or the application itself.
The technical advantage is simple: the whole repository is checked every time. The same code and settings produce the same result. The check runs offline, does not change any files, and can find problems outside the files currently open in the coding agent's context. This includes copied code, dependency cycles and imports that cross architecture boundaries. Old problems remain visible, but only new or worsened problems can fail the current change. If some code cannot be checked, the result is marked incomplete instead of showing a false zero.
The token advantage is that the coding agent has less code to read. lumioguard CC counts the source tokens in each file and in the whole project. This count represents the amount of code an AI agent may need to load into its context. It is not the exact token count used for billing by a model provider, but it is a consistent estimate: more source code usually means more agent tokens, more context and more cost. Large files can be found and split, while the project total shows whether each change added or removed code. In this cleanup, the source count fell by 29,659 tokens.
The check runs when the coding agent tries to finish a task. It compares the working tree with the last commit and classifies every finding as new, worsened, existing or resolved. A failed check returns the file, line, measured value and reason while the relevant code is still in context. The agent changes the code, runs the same comparison again and continues until nothing blocking is new or worse. The check then runs again in CI.
lumioguard CC does not rewrite the code. It measures the change, the coding agent improves the implementation, and the next run verifies the new values. A structural problem is handled as part of the task that introduced it instead of becoming another cleanup job for later.
Cleaning the existing code
The first complete scan found 165 findings in 127 places. Existing code was cleaned in small batches. Each refactor began with behavior checks that ran fixed cases and compared results and side effects before and after the change. A lower complexity number does not prove that behavior has been preserved.
The checks also caught a regular-expression rewrite that looked safe during review but altered an error path. The change was corrected before it was accepted.
The first batch alone kept all 619 behavior cases unchanged. Further backend and frontend batches continued the same process, with the frontend work checked against 294 jsdom snapshots. The main cleanup results can be compared side by side:
| lumioguard CC measure | Before | After |
|---|---|---|
| Active findings | 165 | 68 |
| Places with findings | 127 | 53 |
| Exact clone density | 5.36% | 1.71% |
At the end, lumioguard CC reported 113 resolved findings and no new or worsened blocking finding against the branch base.
To avoid grading the cleanup with the same tool that guided it, the starting and ending commits were also scanned with SonarQube. SonarQube stayed outside the coding-agent loop; it was used only for this before-and-after check.
| Measure | Before | After |
|---|---|---|
| Non-comment lines | 33,759 | 27,847 |
| Maintainability issues | 382 | 21 |
| Duplicated lines | 1.3% | 0.4% |
| Test coverage | Not measured | 71.5% |
The two tools count differently, so their totals were not expected to match. SonarQube still showed the same broad result: less code, fewer maintainability issues and much less duplication. Behavior checks were still needed because neither static tool can tell whether the application behaves the same after a refactor.
After the cleanup, the check remained in the coding-agent loop: existing findings could be handled later, while each new change was compared with the previous commit and corrected if it added complexity, duplication or unwanted dependencies. lumioguard CC is open source; the repository contains the code, and the documentation explains the checks and setup.