What question does the configuration hygiene audit answer?
A configuration file can look tidy while the configuration contract is broken. A template may advertise an option that code no longer reads. Code may require a value that no sample mentions. Two environment files may define the same setting differently, with no clear rule for which one wins. Each defect turns a routine adjustment into an investigation, and the failure can remain silent because every individual file still parses.
The audit therefore asks a deliberately broad question: How manageable, practical, clean, and understandable is the project's configuration: is every option consciously chosen, wired, and explained—or has the configuration swollen with decisions deferred “for later,” so that any adjustment takes extra effort and can silently break something?
An option is a value someone is expected to choose. Its declaration is where that choice is exposed; a read is where code consumes it; an override deliberately replaces a base value for a narrower environment or instance; and validation rejects a value that cannot be used safely. Guard follows that chain in both directions instead of counting files or praising a schema merely because it exists.
“Configuration drift” here is repository-visible disagreement among declarations, defaults, templates, documentation, override layers, validation, and code reads. The audit does not inspect a live environment or prove that the fictional score below can start a production service. It describes the evidence at one audited commit and the amount of guesswork that evidence leaves.
Repository evidence shows a setup path, but templates, deferred values, and option context still require manual reconciliation.
What Guard maps across the repository
The audit begins by fixing the target. Guard records a provider-neutral repository identity, full path, default branch, exact commit, safe links when they can be derived, and whether available history is shallow, full, or unknown. That precision matters: configuration can change between adjacent commits, and a report without a revision cannot tell a reader which template and which code read were compared.
Discovery is based on configuration's role, not its extension. Guard looks across the following surfaces before deciding whether the contract is coherent:
- environment files and safe templates, plus declarative YAML, JSON, TOML, INI, XML,
.properties, and equivalent data formats; - framework-required JavaScript or TypeScript config, Python settings modules, Ruby or Rails configuration, Java or Spring configuration, Go config packages, and other ecosystem-specific code-form settings;
- package-manager configuration, runtime declaration files, source and test roots, Dockerfiles, compose and deployment manifests, Makefile variables, package-manifest fields, CLI flag defaults, settings classes, and constants that act as configuration;
- generated configuration that is tracked as a source, documentation that defines supported settings, schemas and validators, examples and demos, package scripts, and framework conventions that imply a configuration surface;
- CI files only as places where configuration values may be duplicated or checked—not as evidence that the pipeline itself is healthy.
Each surface keeps more than a path. The inventory records format, owner area, whether it is declarative or code-form, visible complexity, option names, redacted default shapes, placeholders, environment-specific values, documentation, validation, and duplication. Each option then links its declaration and default to code read points, evidence that the value takes effect, and concerns such as a later overwrite or a cache created before the expected override is loaded.
Repository type controls applicability. Applications, services, frontends, backends, CLIs, workers, mobile apps, infrastructure projects, and mixed deployable repositories normally use the full model when configuration exists or is reasonably expected. Discovery can classify a repository as an application, service, frontend, backend, CLI, worker, mobile app, library, SDK, plugin, monorepo, polyglot project, docs/config project, infrastructure project, mixed repository, or unclear case. Monorepos and polyglot repositories are mapped surface by surface; a root template for one package cannot represent every deployable unit.
Libraries, SDKs, and plugins are judged only on configuration they actually own, such as development, demo, example, integration-test, package-tooling, or documented settings. Public API parameters and constructors are outside this audit's first version. Docs-only repositories, samples, and small libraries with no configuration surface and no reasonable need for one may be successful domain no-ops. Their non-applicable criteria are skipped rather than awarded perfect points.
Generated dependency or build output, vendored packages, virtual environments, caches, coverage output, and Git internals are excluded unless a tracked file there is itself configuration evidence. Guard also does not browse arbitrary external documentation to fill a repository-evidence gap: if the configuration contract is not discoverable from the authorized evidence, that limitation remains visible.
What the audit deliberately does not do
Configuration hygiene is a read-only analysis. Guard does not install project dependencies, launch the application, start a service, run a migration, execute a lifecycle hook, build or test the project, deploy a release, or contact production. It does not modify a template, choose a value, create an issue or branch, commit a fix, or open a pull request. Static parser output and repository metadata can support a finding; executing untrusted project behavior merely to prove one cannot. Execution remains outside the boundary.
Repository guidance can describe intended settings, ownership, or a safe place to inspect. It remains lower-priority contextual evidence. It cannot expand access, weaken verification, suppress a finding, force a score, authorize a write, or make Guard run a command. Missing or unusable guidance is neutral and never subtracts points.
Shared files do not make every concern part of this audit:
- Configuration hygiene may report a template design that invites secrets, but the Security audit owns secret content and exposure. Values are never printed; evidence stops at a redacted path and key name.
- It may notice duplicated settings in a workflow or credit the presence of a validator, but the CI/CD audit owns pipeline validity, branch protection, and delivery quality.
- Package-manager and registry settings are inventory context; acquisition rules and lockfile discipline belong to the Dependency hygiene audit.
- Per-option truth is relevant on a live surface. Proving that an entire config file or operational surface is detached belongs to the Dead code audit.
- Configuration design belongs here; broad repository clutter and general cleanliness remain with the Codebase hygiene audit.
How the audit works from revision to report
Resolve the revision and build the option catalog
Guard first establishes one unambiguous repository and commit. It detects repository type, stacks, frameworks, config roots, docs, examples, deployment surfaces, and conventions that imply configuration. Structured parsers are preferred when they can read a format safely; text inspection remains valid when a format is unusual or setting up a parser would mutate the project. The output of this pass is a map from surfaces to options, reads, docs, validators, and override layers—not a score guessed from filenames.
Test the contract before judging its shape
The next pass works in a fixed order. It asks whether the inventory is complete, whether declarations and code reads agree, whether defaults and required decisions are coherent, whether the number and organization of knobs are justified, and finally whether invalid input fails loudly and context is discoverable. A broken declaration-to-effect contract outranks a stylistic complaint about bloat on the same surface.
This analysis assigns each applicable criterion an evidence-backed score or an explicit skip. It separates penalized findings from positive credit-only signals and from non-scoring observations, derives launch readiness, applies deductions and caps, and orders bounded next steps. It still uses only the current revision; previous reports do not influence collection or initial scoring.
Draft the current result before comparing history
Guard completes the current summary and report from current evidence before it reads a previous result. Only then may a validated, readable earlier report or summary support a comparison. If nothing usable exists, the new result remains unchanged and becomes the baseline. This order prevents an old score, old wording, or old blind spot from becoming the premise of the current audit.
No universal configuration scanner is implied. A structured parser, a safe static reference check, a tool's version or help output, local revision metadata, and repository documentation have different evidentiary roles. A safely reproduced parser error tied to an audited configuration file can be evidence; an unavailable optional parser is only a limitation. A proven read/declaration mismatch is evidence as well.
How an option becomes evidence instead of guesswork
Consider an optional endpoint declared in an example environment file. The declaration is only the first link. Guard looks for its default shape, the loader or settings class that reads it, the place where the resulting value affects behavior, the validator that rejects an invalid form, and the documentation that tells a person when to override it. If code reads a sibling setting that the template never declares, the mapping must also expose that reverse mismatch.
- Declared and effective: the option is exposed, consumed, and changes the intended behavior at the expected time.
- Declared but inert: it is never read, is overwritten later, is cached before the relevant override, or is read only for diagnostics.
- Read but undiscoverable: code expects a value that no template, schema, manifest, example, or documentation explains.
- Layered override: one base value has a clear narrower override with understandable precedence.
- Parallel copy: several full files repeat the same values and can drift independently, leaving authority unclear.
Placeholders require context. An intentionally empty optional example can be honest. An empty mandatory value or a “decide later” marker with no owner decision is a stronger defect. The same care applies to code-form configuration: framework-mandated code may be perfectly proportional, while a custom settings program with hidden branches can be difficult to understand even if it is syntactically valid.
Evidence is consolidated around the option contract, but the scoring contract does not define a formal finding-level deduplication key. The article therefore does not promise that repeated rows are mechanically merged before deductions. Each confirmed finding needs concrete evidence and an observable consequence; the worked example states exactly which Medium and Low findings are counted.
Positive evidence that is credit-only
Four signals can strengthen positive reasoning or confidence, but their absence is neutral and cannot create a finding, deduction, cap, or required improvement item:
- visible environment or instance divergence that proves a configuration option earns its keep;
- dynamic defaults derived from environment or system properties rather than static guesses;
- process maturity such as schemas, configuration validators in CI, reviewed config changes, or canary and rollback hints;
- a typed or schema-backed single declaration point.
Non-scoring observations follow the same discipline. They need a path or key, an observable consequence, and a clear statement that they do not alter criterion scores, deductions, caps, final score, or severity.
Reports
56 / 100July 17, 2026Current
Executive Summary
- Configuration is manageable, practical only with manual reconciliation, not yet clean, and not fully understandable: the repository exposes a setup path, but templates, deferred values, and option context do not yet form a coherent contract.
- Launch readiness: Runnable with manual effort.
- Score: 56/100. A stale parallel template and weak unknown-key validation are the main confirmed concern; a localized context gap also reduces the result.
Audit Target
- Repository: github.com/example-org/config-sandbox
- Default branch: main
- Checked commit: 00000000000000000000000000000000c0ffee42
- Revision confidence: Full commit and tracked repository configuration available
What Was Checked
- Environment templates, declarative and framework configuration, CLI defaults, code reads, docs and schemas, override layers, validators, and redacted secret-shaped key locations at the audited revision.
Configuration hygiene scorecard
| Criterion | Score (0-5) | Status | What affected the score |
|---|---|---|---|
| Config/code boundary | 4 | ✅ | Deploy-varying values are externalized; code-form settings follow framework conventions. |
| Deferred decision residue | 2 | ⚠️ | Two optional example values still use placeholder text without a recorded owner decision. |
| Declared options wired and take effect | 3 | ⚠️ | One optional framework-managed value has only indirect static take-effect evidence. |
| Template presence and sync | 2 | ⚠️ | One stale key persists in a duplicated environment template. |
The eleven criteria behind the score
Every applicable criterion receives an integer from 0 to 5. Scores of 4–5 carry a ✅ pass signal, 2–3 carry a ⚠️ warning, and 0–1 carry a ❌ failure signal. A genuinely non-applicable criterion is skipped with ⏭️, a null score, and an explanation; it leaves the denominator rather than becoming zero or perfect.
The scoring model does not publish separate universal anchors for 4 versus 5, 2 versus 3, or 0 versus 1. Guard must support each integer with repository evidence against the criterion's decision. The four credit-only signals above and any observations remain outside this list.
- 1
Config/code boundary
Guard asks whether values that genuinely vary by deployment, environment, or instance live outside ordinary code, and whether values that never vary have been kept as constants rather than exported as knobs. Code-form configuration is not automatically a problem: framework conventions and proportional complexity matter.
- 2
Knob justification
Every exposed option should correspond to a plausible decision. A useful setting has a real variation scenario and the right granularity; a switch that nobody can explain, or several controls for the same decision, make configuration harder to reason about.
- 3
Scale manageability
The number of surfaces, options, and override layers should stay proportional to the project. Guard looks for a configuration contract that a new maintainer can map without treating configuration as an undocumented program or domain-specific language.
- 4
Defaults quality
Mandatory inputs should be limited, safe defaults should exist where they are reasonable, and templates or documentation should make the remaining choices understandable. A default is judged as repository evidence, not as proof that it is safe for every production environment.
- 5
Deferred decision residue
Placeholder text, empty required values, TODOs, FIXMEs, and settings that merely postpone an owner decision weaken this criterion. Guard distinguishes a deliberately optional example value from an undecided mandatory value, which is a more serious contract failure.
- 6
Declared options wired and take effect
A declared option must be read and must influence the intended behavior at the expected time. Decorative reads, values overwritten later, settings cached before an override is loaded, and values used only for logs do not prove that the option works.
- 7
Code reads declared
The mapping also runs in reverse. Every configuration value read by code should be discoverable in a template, example, schema, manifest, or documentation, so a required setting cannot remain a shadow dependency known only to the implementation.
- 8
Template presence and sync
A discoverable sample should cover real reads, omit stale keys, and contain no real secret values. Multiple environment examples can be useful, but parallel full copies that drift independently are not the same as a clear base with intentional overrides.
- 9
Loud validation
Invalid, unknown, or missing configuration should fail early with a useful error. Guard looks for evidence that misspelled keys, wrong value shapes, and nonexistent paths cannot pass silently and leave the project running in an unintended state.
- 10
Option context
A first-time reader should be able to learn what an option controls, what behavior it changes, and when to change it. That context may live in comments, a README, generated reference material, or another discoverable source; it need not be duplicated everywhere.
- 11
Single source per value
One source should be authoritative for each value. Environment and instance layers may override a shared base, but copied values spread across unrelated templates, manifests, and constants make precedence unclear and allow fixes to land in only one place.
How the final score is calculated, reduced, and capped
The criteria are equally scaled. Only scored criteria enter the denominator, so a library with a genuinely irrelevant surface is not penalized for skipping it.
max_sum = number_of_scored_criteria * 5
criteria_score = round((criteria_sum / max_sum) * 100)Confirmed penalized findings reduce the rounded base. The impacts describe configuration manageability risk, not vulnerability severity. Critical means repository evidence cannot support correct configuration or a defect can silently make deployment unusable; High covers a broken contract, no-effect setting, shadow required read, or undecided mandatory value; Medium covers bloat, duplication, stale templates, weak validation, or recurring silent-failure risk; Low covers a localized organization, naming, granularity, or context gap. Info, credit signals, and observations deduct nothing.
finding_reduction = min(
critical * 20 + high * 8 + medium * 3 + low * 1,
35
)
risk_adjusted_score = criteria_score - finding_reductionThe scoring contract calls these “confirmed penalized findings” without specifying a mechanical confidence cutoff, and it does not define a finding-deduplication algorithm. The article does not invent either rule. The fictional findings below use explicit evidence and are counted exactly once in the shown arithmetic.
Caps preserve stop conditions
After deductions, Guard applies every supported cap and keeps the lowest ceiling:
- 59: the project cannot start or be configured from documented or template values, and no discoverable documentation explains what must be set.
- 69: a large share of declared options are unwired or ineffective, or code reads have no declaration anywhere.
- 69: a configuration-heavy project has neither a discoverable template nor option-context documentation.
- 39: a Critical configuration condition makes correct deployment impossible or silently unsafe from repository evidence.
final_score = min(risk_adjusted_score, every_applicable_cap)
final_score = clamp(final_score, 0, 100)A final score of 70–100 is good, 40–69 is warning, and 0–39 is bad. The formula specifies round(...) but not how a language should resolve an exact half tie. Guard's article therefore preserves the formula without naming a half-up, half-even, or other convention, and the example uses an exact integer before rounding.
Launch readiness remains separate
Launch readiness summarizes effort; it is not another score, deduction, cap, or runtime test. Needs investigation means the evidence does not reveal a reliable setup path. Runnable with manual effort means a path exists but a person must reconcile files, values, or docs. Ready without guesswork means templates, defaults, required values, context, and validation form a coherent path. Not applicable is reserved for a genuine domain no-op with no expected configuration surface.
A worked example: 56 out of 100
In the fictional example-org/config-sandbox repository, all eleven criteria apply. Their scores are 4, 3, 4, 3, 2, 3, 4, 2, 2, 3, and 3, for a total of 33 out of 55.
33 out of 55, scaled to 100
60One Medium at 3 points and one Low at 1 point
-4No 59, 69, or 39 trigger is present
—round((33 / 55) × 100) - 4
56The Medium finding is a stale key repeated across parallel example templates together with weak unknown-key validation. The Low finding is localized option-context ambiguity. There is no shadow required read, no mandatory undecided value, and no proven no-effect setting, so the example contains no High finding. The reduction is 4, below the 35-point maximum, and no cap changes the result.
A successful ordinary run publishes an integer score. A library with some skipped criteria has a defined applicable-only denominator. A completely all-skipped no-op exposes a source ambiguity: the audit is explicitly successful and non-punitive, but the scoring contract does not define a numeric result when max_sum is zero while the summary still expects a number. Guard's article does not manufacture 100, zero, or a numeric N/A for that case.
Configuration hygiene
Check whether project configuration is manageable, practical, clean, and understandable, and identify the next steps to reduce setup effort and improve maintainability.
How to read the result in Guard
The repository metric card is an orientation surface. Its ring shows the 0–100 score, and the score itself determines the badge: the fictional 56 produces Some issues. Seven decision-level checklist items are then grouped into the generic Problems, Watch, Healthy, and Skipped buckets. For this fixture, six items warn, one passes, none fail, and none skip. Those counts summarize checklist states; they are not finding totals and they are not the eleven criterion scores.
Opening the result reveals the answer-first report. It identifies the repository, default branch, full audited commit, and what was checked. Findings begin with the explicit audit question and a direct answer across manageability, practicality, cleanliness, and understandability. Launch readiness follows that answer, then the complete eleven-row scorecard, plain-language score calculation, compact top findings with separate impact and confidence, present credit-only signals, evidence, limitations, and an ordered improvement checklist.
The report archive labels the newest completed entry Current and offers Copy and Download for its Markdown. The history card uses the report-provided text Needs config work in the fictional example; that phrase is not the fixed metric-card taxonomy. A delta appears only when a usable previous summary supplies its score and date.
History points are completed audit scores ordered oldest to newest on one 0–100 line. They are not forecasts. Selecting a point in the live product opens its corresponding report; the static article figure keeps only the visual anatomy. The fictional increase is a coherent example of comparison, not a promise that running an audit makes configuration improve.
Guard can mark an old result Out of date after it has not been refreshed recently. That badge communicates evidence freshness. It does not decay or recompute the stored score with time; a Rerun evaluates a new or current repository revision.
Where the audit ends and improvement begins
The audit can turn strong evidence into bounded improvement candidates, but it remains read-only. A candidate needs a specific scope, priority, maturity step, evidence, reason, ordered next actions, completion signal, medium or high confidence, blast radius, and a note about what must be revalidated. Low-confidence speculation, observations, and absent credit-only practices do not enter the candidate list. An empty list is valid.
The sequence follows the configuration contract rather than cosmetic convenience:
- Make declaration and effect agree. Wire a supported option or remove it; declare a shadow code read in a discoverable source.
- Resolve deferred decisions. Fill or remove placeholders only after the owner chooses the intended value. A deferred product or operational decision is issue-only by default; an agent must not silently decide it.
- Synchronize templates. Add missing supported keys, remove stale ones, and preserve redacted examples.
- Document option context. Explain meaning, effect, and when a reader should change the setting.
- Extract deploy-varying hard-coded values. Move a real environment or instance decision across the config/code boundary.
- Slim and single-source the model. Turn never-varying knobs into constants, deduplicate parallel values, and convert unjustified custom code config to a proportional data form when evidence supports it.
- Harden validation. Add loud configuration validation and, where useful, optional maturity signals such as a schema-backed declaration point.
Those steps account for the audit's supported candidate shapes: wire or remove an option, declare a shadow read, sync a template, fill a deferred decision, document an option, extract a hard-coded value, constantize an option, deduplicate a value, add validation, and convert unjustified code configuration to data.
Configuration hygiene currently has no paired improvement executor in the product. Its metric card therefore shows Rerun, not Autofix, and there is no Improvement steps panel, automatic issue, branch, pull request, or configuration edit to depict. A future or manual improvement must revalidate the repository identity, current revision, evidence, permissions, and blast radius before any write. The handoff is context—not permission—and a person remains responsible for decisions the repository cannot make on their behalf.
Limits, reruns, and maintained configuration health
A useful Configuration hygiene result keeps its evidence boundary visible:
- It applies to one audited commit. A later template, code read, default, or override can change the result.
- Static evidence can prove declarations, read paths, overwrite structure, docs, and validators; it cannot prove that a real production launch succeeds.
- Secret-shaped values remain redacted. Exposure belongs to the Security audit, not to a Configuration hygiene example.
- Unavailable optional parser tooling and inaccessible evidence are limitations on what Guard can establish. A safely reproduced parser error tied to an audited configuration file may support evidence, as can a proven contract mismatch.
- A genuine all-skipped domain no-op is successful, non-punitive, and has Not applicable launch readiness, but the current source does not define its numeric zero-denominator result. This article assigns none.
- Ambiguous identity, inaccessible repository, unresolved revision, or missing required inputs produces a diagnostic failure rather than a synthetic low score and report.
- Repository guidance can clarify intent but cannot change scope, safety, evidence, or permissions; absence is neutral.
Previous evidence is optional and read last
With no valid prior context, the independent current result stays unchanged, no previous comparison or relation section appears, and the run becomes the baseline. A locator whose report and summary cannot be read follows the same path with a limitation. If only one counterpart is readable, Guard compares only what that file proves and discloses the missing half. A relation section can use a readable report or summary, while the compact previous score and delta require the prior summary itself.
Substantive repository changes, corrected earlier evidence, material changes in verified scope or limitations, relevant repository-guidance changes, and meaningful methodology changes can explain movement. Reworded prose, out-of-scope edits, and cosmetic churn cannot. When movement is merely assessment noise, the prior score is an anchor for alignment rather than an unquestionable truth.
Rerun means re-establish the current state
Rerun audits the changed or current repository state; it does not edit an old report or replay a live application launch. Automatic audits may be scheduled to react to changed commits, but they remain audits, not Autofix. A later score may rise, stay flat, or fall as the evidence changes.
This recurrence is what makes configuration hygiene useful to ongoing agent-driven development. Coding agents inherit every stale template, shadow read, ambiguous override, and deferred choice already in the project. Rechecking the contract after changes helps keep new features from being layered onto settings that no person—or agent—can confidently explain.
Enji Guard