What question the audit answers
The audit asks a practical question: does the current repository contain avoidable maintenance drag that makes future changes harder, and which evidence-backed cleanup themes deserve attention first? Maintenance drag is not an aesthetic dislike. It is the extra work required to find the right command, distinguish source from residue, understand where a value belongs, trace an error, or decide whether a shared module is safe to touch.
A team can live with each small inconvenience for a while. The cost appears when a person or coding agent must make the next change: undocumented global tools stall setup, a silent catch hides why a check failed, and an old backup file looks as authoritative as the current version. Guard makes that current state reviewable. It does not predict every defect, judge one pull request, or turn style preference into a risk score.
The answer belongs to one audited revision. It can improve after accepted cleanup and it can deteriorate as new residue appears. That is why the meaningful product outcome is not possession of a report; it is keeping the repository healthy enough that later agent-driven feature work starts from a dependable base.
A reliable build-and-check entry point is missing, and a bounded ignored-error cluster still increases change friction.
What Guard inventories before scoring
Guard first resolves exactly one authorized repository and fixes the audit to a full commit. It records the default branch, safe branch and commit links when they can be derived, and whether available history is shallow, full, or unknown. A full commit is not decorative metadata: without it, a score cannot say which version of the repository it describes. Ambiguous identity, failed access, or a clone that never produces an inspected revision ends in a diagnostic, not a synthetic low score.
Inventory starts broad because maintenance friction rarely lives in one language or file type. Guard identifies whether the project is a single application, service, library, monorepo, polyglot repository, or an unclear mix. It maps the primary stacks, frameworks, package managers, runtime files, Docker and deployment material, CI files, Makefiles, scripts, and directories that appear generated.
The inspected roots include:
- source, configuration, documentation, tests, scripts, and migrations;
- infrastructure and repository-level instructions for people or coding agents;
- setup, build, lint, test, check, format, run, deploy, and migrate entry points described by docs, package scripts, language tooling, Makefiles, or CI configuration;
- external prerequisites such as browsers, cloud CLIs, code generators, and system tools;
- ignore rules, editor and formatter configuration, linters, lockfiles, and safe environment examples;
- tracked environment-like files, IDE residue, logs, caches, build or coverage output, generated bundles, binaries, backups, file-size patterns, and large tracked files.
Dependency directories, caches, ordinary build output, coverage, logs, temporary content, and version-control internals are normally excluded. They become relevant when the repository tracks them, fails to mark generated material, or lets their weight obscure the source. Guard may also read a root guidance file as optional repository evidence. That file can explain local conventions, but it cannot expand permissions, force a score, suppress a finding, or make Guard execute a command simply because the file requests it.
What the audit deliberately does not claim
Codebase Hygiene is a static, read-only judgment about maintainability evidence. It does not install dependencies, start services, run migrations, contact production, execute deploy scripts, or perform destructive cleanup. A documented command can support a score; its presence does not mean the audit executed it. Any command requiring credentials, downloads, browsers, containers, unavailable services, or more than a bounded local check is skipped and named as a limitation.
CI and configuration have narrower ownership here
Existing CI or pre-commit execution can strengthen evidence that formatting or another local hygiene control is used. Missing CI, branch protection, required checks, or pipeline automation cannot lower this score or become a Codebase Hygiene finding; delivery protection belongs to the CI/CD audit.
This audit can own light repository smells around configuration: a committed environment file, a secret-shaped name, a hardcoded literal, a backup copy, or an author-machine path. It does not score the design of every option, default, template, override, validation rule, or code read. Those questions belong to Configuration Hygiene. Secret contents themselves belong to the Security audit and are never printed in evidence.
A dead-looking line is not a deletion verdict
One of the 19 rows covers obvious unused, commented-out, or unwired code because visible residue makes the next change harder to understand. That row is intentionally broad. The dedicated Dead Code audit does something more demanding: it maps supported application, service, route, job, package, public API, plugin, framework, and operational entry points, then asks what those entry points can actually reach.
A tool warning is only a lead in that deeper audit. Dynamic wiring, generated code, migrations, feature flags, compatibility and rollback paths, public extension points, examples, fixtures, docs, external callers, and framework conventions can all explain an apparently unused symbol. A test-only consumer proves that code can execute in isolation; it does not by itself prove a current product path reaches the code. Conversely, startup registration or a public export does not prove that an entire capability is meaningfully live.
The dedicated audit therefore separates confirmed, likely unused, ambiguous, weak-signal, intentionally dormant, and false-positive cases. Whole detached configuration or operational surfaces belong there too. Only confirmed or likely-unused candidates can enter a later cleanup context, and even they require current target, protected-use, and blast-radius revalidation before a write. Codebase Hygiene provides none of that deletion proof. It reports the broad smell once and leaves safe-removal decisions to the audit that owns reachability.
Local duplication, long signatures, and mixed-responsibility modules stay in scope only as evidence of nearby change friction. They do not authorize a sweeping architecture rewrite. Likewise, generated or dependency output matters only when tracking, marking, duplication, or weight is the repository problem—not because generated files happen to be large.
How the three-stage audit works
1. Fix the revision and build the inventory
Guard proves repository access, records the full commit and default branch, identifies the project shape, and maps important roots, lifecycle commands, prerequisites, and hygiene signals. It reads current repository evidence without importing conclusions from an older report. That separation prevents a previous score from deciding what the new pass looks for.
2. Analyze the current repository
The analysis uses tracked files, local Git metadata, safe command discovery, and stack-appropriate static searches. Examples include tracked-artifact and backup patterns, redacted secret-shaped names, TODO or FIXME clusters, absolute machine paths, ignored-error idioms, and helper areas that mix unrelated responsibilities. Guard scores all 19 rows, classifies evidence-backed findings, and records where inspection was sampled or a safe check could not run.
There is no mandatory scanner list. Structured tooling may help, but the report cannot say a formatter, linter, build, or other command passed unless it actually ran safely and its result was inspected. A discovered command and an executed command are different kinds of evidence.
3. Write the current result, then consider history
Guard drafts the complete current summary and report first: answer, scorecard, score calculation, findings, evidence, limitations, and prioritized improvement checklist. Only then may it locate a target-matched prior result. If that result validates and at least one referenced report or summary is readable, Guard can compare what it actually read. If not, the current report remains the baseline and contains no invented previous score or trend.
How observations become findings
A search match is not automatically a finding. Guard asks whether the observation is tracked, relevant to a current source surface, representative rather than accidental, and specific enough to explain user impact. A useful finding receives a TH identifier, a severity, a short title, representative evidence, an impact statement, a recommendation, and a confidence level.
Evidence can be a path, command result, count, or configuration name. Usually one to three paths are enough. Dumping every match makes a report look precise while making it harder to act on; copying a secret value is unsafe. Guard keeps the smallest useful set, redacts sensitive values, and reserves High confidence for direct, repeatable evidence. When a repository is too large for complete inspection, the sample and the material surfaces it may miss remain visible limitations.
Severity answers a different question from the criterion score
- Critical covers likely secret exposure, destructive-by-default automation, or another hygiene condition able to block or damage production immediately.
- High covers a repository that a new agent cannot reliably build or check, major tracked binary/generated pollution, hardcoded credentials or machine paths, or a god module crossing core domains.
- Medium covers meaningful drag such as missing command documentation, TODO/HACK clusters, duplicated configuration drift, deep units, or weak error handling.
- Low covers bounded cleanup: a stale doc, small backup, isolated naming inconsistency, or minor formatting gap.
- Info records neutral context. It never counts as a problem or score deduction.
The runbook does not define a universal fingerprint or mechanical deduplication key. Related observations are grouped into one finding or cleanup theme when that best represents the maintenance drag, and counts are finding counts only after classification. The report does not pretend that package-style alias normalization exists for codebase smells.
The 19 codebase hygiene criteria
Every successfully inspected repository receives an integer score from 0 to 5 on every row, in this order. Four or five points display ✅: the criterion is satisfied or only isolated traces remain. Two or three display ⚠️: visible issues exist but are not systemic. Zero or one displays ❌: the smell is systemic. The runbook defines no N/A row for a successful audit and gives every criterion the same weight.
- 1
Dead, commented-out, or unwired code
Guard looks for obvious unused code, commented-out blocks, and modules with no visible incoming reference. This is a repository-hygiene smell, not a whole-program reachability proof. The fictional repository has a few bounded traces that deserve review, but no claim that they are safe to delete. Fictional example: 3/5 ⚠️.
- 2
Binaries and compilation artifacts in the repository
Tracked bundles, binaries, compiled output, and generated stubs need a clear reason and clear generated markers. A small tracked artifact cluster lowers the fictional result; dependency directories and ordinary local build output do not count unless tracking them is itself the problem. Fictional example: 3/5 ⚠️.
- 3
.gitignore
Ignore rules should cover editor and operating-system files, logs, caches, environment files, build output, and coverage output. The fictional repository covers the important categories, with only isolated cleanup opportunities rather than a systemic leak of machine-local material. Fictional example: 4/5 ✅.
- 4
Build and maintenance commands
A new person or coding agent should be able to discover reliable build, test, lint, run, and clean entry points, ideally with useful help. The fictional repository has several fragments but no dependable documented build-and-check path, producing the example’s single High finding. Fictional example: 1/5 ❌.
- 5
README
The README is judged on description, installation, running, testing, useful context, prerequisites, and known pitfalls. The fictional README explains the project and its boundaries well; the missing maintenance-command contract is scored in its own row instead of being hidden here. Fictional example: 5/5 ✅.
- 6
Globally installed tools
External prerequisites such as browsers, cloud CLIs, kubectl, jq, or protoc should be named where a reader can find them. The fictional project documents its main runtime but leaves two auxiliary command-line tools implicit, adding setup friction without making the whole repository unusable. Fictional example: 3/5 ⚠️.
- 7
History weight and clone time
Guard considers shallow-clone behavior and heavy blobs in current tracked files or visible history. The fictional revision is quick to inspect and contains no major blob problem. That conclusion stays limited by the amount of history actually available to the audit. Fictional example: 4/5 ✅.
- 8
Directory structure
A readable hierarchy should expose meaningful boundaries between layers, modules, and responsibilities. The fictional repository’s primary areas are easy to locate, although one shared helper area still needs the more specific god-module judgment recorded later in the scorecard. Fictional example: 4/5 ✅.
- 9
.env files and secrets in the repository
Live secret values should not be committed, and safe examples should show the expected shape without exposing credentials. The fictional audit finds a redacted example and no committed live value. Secret contents would belong to the Security audit; this row stays on repository hygiene. Fictional example: 5/5 ✅.
- 10
Scripts tied to an author’s home directory
Reusable scripts and configuration should not assume /Users/name, /home/name, a specific drive letter, or another developer’s machine. The fictional scan finds no such path. A clean result here says only that the inspected repository evidence was portable on this dimension. Fictional example: 5/5 ✅.
- 11
Magic numbers and hardcoded values
Repeated URLs, ports, tokens, numeric constants, and duplicated enum values can hide decisions and invite drift. Guard asks whether a value should be named or configured; it does not move into a full option-by-option Configuration Hygiene analysis. A few local constants remain unexplained in the fixture. Fictional example: 3/5 ⚠️.
- 12
Mixed language and naming styles
Files, functions, variables, and modules should use a consistent language and naming style. The fictional repository is mostly coherent, with a few isolated legacy names. Minor inconsistency is visible without being treated as a reason for a broad rename campaign. Fictional example: 4/5 ✅.
- 13
Duplicate files with history in the name
Files ending in bak, old, new, v2, copy, or similar history markers duplicate the job of version control and can drift. The current fictional revision retains one small backup cluster, which becomes a Low finding rather than a claim that duplicate files are widespread. Fictional example: 4/5 ✅.
- 14
TODO / FIXME / HACK
Deferred markers count even when dated or assigned; location and seriousness matter more than a raw total. The fictional current revision has scattered bounded markers after a larger cluster was removed. Guard does not turn every TODO into an independent finding. Fictional example: 3/5 ⚠️.
- 15
Formatting consistency
The audit checks formatter and linter configuration, documented local commands, and safe evidence that those commands do not produce errors or warnings. Existing CI or pre-commit execution can strengthen the evidence, but its absence is neutral and cannot lower this row by itself. Fictional example: 4/5 ✅.
- 16
Local DRY / KISS
Guard reviews nearby duplication and local over-engineering where both can make the next edit harder. It deliberately keeps the judgment local. The fictional code has a few repeated branches, but the evidence does not justify an architecture rewrite or a repository-wide abstraction project. Fictional example: 4/5 ✅.
- 17
Long function signatures
Functions with more than roughly five to seven positional parameters can reveal unclear boundaries, especially when callers must remember ordering. The fictional project has one borderline case with named structure around it, so the signal remains isolated rather than systemic. Fictional example: 4/5 ✅.
- 18
God modules
Directories or modules named utils, common, core, or helpers are not defects by name. They matter when they mix unrelated responsibilities and make ownership unclear. One fictional helper module crosses two local concerns, but it does not span the core domain or become a High finding. Fictional example: 3/5 ⚠️.
- 19
Ignored errors
Empty catches, except-pass blocks, discarded errors, unchecked shell failures, and equivalent patterns need an explicit reason. The fictional audit groups a bounded cluster of silent error handling into one Medium finding because it can hide maintenance failures during future changes. Fictional example: 2/5 ⚠️.
Reports
59 / 100July 14, 2026Current
Executive Summary
- The repository is serviceable, but one unreliable build-and-check entry path and a bounded ignored-error cluster make future changes harder.
- Score: 59/100 — Watch closely. The more cautious finding-based track sets the result.
- Prioritize a dependable maintenance command contract before localized residue cleanup.
Audit Target
- Repository: example/codebase-hygiene-demo
- Default branch: main
- Audited commit: 1111111111111111111111111111111111111111
- Revision confidence: Full commit recorded; visible history reviewed
What Was Checked
Source, configuration, documentation, tests, scripts, migrations, infrastructure, lifecycle commands, prerequisites, tracked residue, local change-friction patterns, revision metadata, and representative evidence limits.
Codebase Hygiene Scorecard
| Criterion | Score (0-5) | Status | What affected the score |
|---|---|---|---|
| Build and maintenance commands | 1 | ❌ | No single reliable, documented build-and-check entry path exists. |
| Binaries and compilation artifacts in the repository | 3 | ⚠️ | A small tracked artifact cluster remains without a clear ownership note. |
| Ignored errors | 2 | ⚠️ | A bounded cluster of silent error handling needs review. |
| .env files and secrets in the repository | 5 | ✅ | No live secret value is tracked; the example is safely shaped. |
| Formatting consistency | 4 | ✅ | Formatter and linter rules are discoverable with only isolated gaps. |
How the codebase hygiene score is calculated
The first track normalizes the 19 equally weighted criterion scores. With five points per row, the maximum is 95 rather than 100. Let P be the criterion total.
primary_table_score = round(P / (5 × 19) × 100)The second track starts from 100 and responds to classified findings. Let C,H, M, and L be Critical, High, Medium, and Low finding counts. Info is excluded. Let A be an evidence-backed limitation deduction from zero through ten, used only when material surfaces are hidden.
severity_penalty_score =
100 - 65*C - 25*H - 10*M - 3*L - A
if C > 0:
severity_penalty_score = min(severity_penalty_score, 39)
else if H > 0:
severity_penalty_score = min(severity_penalty_score, 69)
final_score = round(clamp(
min(primary_table_score, severity_penalty_score),
0,
100
))A Critical finding therefore prevents the severity track from rising above 39. With no Critical but at least one High, it cannot rise above 69. Caps apply to the severity track, and the final score uses the lower of that result and the normalized table. The runbook does not publish a per-limitation point schedule, so the article does not invent one.
The fictional 59/100 result
The 19 scores printed above are 3, 3, 4, 1, 5, 3, 4, 4, 5, 5, 3, 4, 4, 3, 4, 4, 4, 3, and 2. They total 68. The classified findings are one High command-entry gap, one Medium ignored-error theme, and two Low themes for tracked artifact residue and a small backup cluster. There is no Critical or Info deduction and no material-limitation deduction.
round(68 / 95 × 100)
72100 - 25 High - 10 Medium - 6 Low
59min(59, 69); the cap does not lower the track
59min(72, 59), clamped and rounded
59A score of 59 uses the warning gauge and the report label Watch closely. Scores from 90 to 100 are Healthy, 70 to 89 are Mostly healthy, 40 to 69 are Watch closely, and 0 to 39 Need attention. The compact card uses its own score-tone wording,Some issues, for the same 59 result.
A successfully inspected repository always receives all 19 row scores and an integer final result; a clean repository can reach 100. Ambiguous target identity, failed access or clone, an unresolved full revision, missing required audit inputs, or a report that cannot be based on inspected repository evidence produces a diagnostic instead. Guard does not fabricate a score to fill the dashboard.
How to read the result in Guard
The repository card is orientation, not the entire audit. For this mixed fictional result, the summary chooses five representative scorecard dimensions: Build and maintenance commands fails; Binaries and compilation artifacts and Ignored errors warn; environment secret hygiene and Formatting consistency pass. Guard groups those states into one Problem, two Watch, two Healthy, and no Skipped item. It does not claim that there is one finding, two files, or only five scored criteria.
Opening the audit reveals the current report: Executive Summary, exact Audit Target, What Was Checked, the complete 19-row scorecard, plain-language calculation, findings grouped by severity, representative evidence, limitations, and a normally five-item Improvement Checklist. The accordion marks the latest report Current and exposesCopy and Download. Archived reports remain attached to the completed runs that produced them.
History is shown only from real completed, target-matched runs. At the fictional May 12 baseline, 54/95 criterion points normalize to 57 while one High, three Medium, and one Low finding set the lower track to 42. Before June 16, a repository revision removed a material TODO/HACK cluster: 61/95 normalizes to 64, while one High, two Medium, and one Low produce 52. Before July 14, another revision reduced a broad backup-file cluster from Medium to bounded Low: 68/95 normalizes to 72, while one High, one Medium, and two Low produce the current 59. Wording changes alone would not justify either movement.
Codebase Hygiene
Find repository clutter, dead code, hardcoded values, weak maintenance commands, and patterns that make future changes harder.
Guard drafts a current result independently before it reads older evidence. If no prior result is usable, the current run becomes the baseline: there is no previous object, relation section, or invented delta. If only a prior report or only a prior summary is readable, Guard compares only what that file supports and names the missing counterpart. With usable history, the report can distinguish unchanged, new, and resolved findings, revision range, confidence, and the substantive cause of movement. A previous score is an anchor, never authority over current evidence.
Where the audit ends and cleanup begins
The audit ends with evidence and prioritized advice. It creates no issue, branch, commit, pull request, release, tag, or fix. Its Improvement Checklist normally orders about five meaningful themes, with fewer when fewer actions are justified. Critical and High work comes before Medium and Low; within a severity, the report favors steps that restore repeatable verification, reduce repeated manual work, remove unsafe configuration, or make later agent changes simpler.
That checklist is not a runnable queue. The published Codebase Hygiene action has no paired improvement executor, so current Guard exposes no Autofix option, selectable Improvement steps panel, issue handoff, or pull-request workflow for this audit. The visible card action is Rerun; its scheduling dialog and detail page have their own labels, but none turns recommendations into repository writes.
A safe cleanup therefore has an explicit human boundary:
- a person chooses which evidence-backed theme is worth changing;
- the proposed scope and blast radius are reviewed before work begins;
- repository state is rechecked so stale evidence is not treated as current;
- the resulting change follows the team’s ordinary review and acceptance path;
- a later audit evaluates the accepted revision rather than crediting proposed work.
The absence of an executor is a current product fact, not a missing illustration. Showing a disabled cleanup panel or a fictional pull request would falsely promise a capability. A future paired action would need its own verified scope and safeguards; it cannot be inferred from the report advice shown today.
Limits, reruns, and maintained project health
A useful result keeps its evidence limits close to the score:
- The score applies to one full commit. A new command, generated artifact, helper module, or ignored-error pattern can change the result without a large feature diff.
- Shallow history can bound conclusions about repository weight and past blobs. Guard states the available history instead of pretending it inspected what it could not see.
- Large repositories may require representative sampling. The report names material surfaces that sampling could have missed and uses a limitation deduction only when that blind spot is major.
- Commands needing downloads, services, credentials, containers, browsers, production access, or long execution remain skipped. Discovery is not proof of successful execution.
- Optional repository guidance can clarify current conventions but cannot change safety, permissions, scope, or the score by instruction. Its absence is neutral and disclosed once in the report’s limitations.
- Missing prior data is normal. It creates a baseline rather than a failure, synthetic trend, or automatic score deduction.
Rerun after an accepted cleanup, a substantive repository change, a corrected evidence gap, or a material scope or methodology change. A completed rerun is its own revision-specific assessment; it does not rewrite an archived report. The score can rise, stay flat, or fall. Cosmetic report churn and unchanged guidance do not establish improvement.
The loop matters because maintenance drag returns quietly. A useful command can disappear, a backup can become authoritative by accident, and a new helper can absorb unrelated responsibilities. Recurring audits make that drift visible; human-reviewed cleanup addresses the smallest well-supported themes; the next run checks the repository again. Coding agents can then add features to a healthier codebase instead of stacking new work on friction the team has stopped seeing.
Enji Guard