# Configuration Validation

## Objective

Fail at startup with a clear message instead of at 3am with a null.

A startup check that every required setting is present, well-formed, and consistent — reporting all problems at once, in plain language.

## Before You Begin

This feature is being added to an application that already exists and already
works. Do not scaffold a new project, and do not assume a blank slate.

Inspect the codebase first and establish:

- The existing application structure and where code of this kind already lives.
- The framework and version in use.
- The existing design system — colours, spacing, typography, and component conventions.
- Existing UI components you can reuse instead of writing new ones.
- The existing database structure, if this feature needs to persist anything.
- The existing authentication and authorization system, if this feature is user-scoped.
- Dependencies already installed, so you don't add a library that duplicates one.
- The existing test setup and conventions.

Only start writing code once you understand the above. If the application
already implements part of this feature, extend it rather than replacing it.

## Implementation Instructions

1. Declare every setting the app reads in one place: its name, whether it is required, which environments require it, its expected format, and a one-line description of what it does.
2. Validate at startup, before the app accepts traffic. Report every problem in a single pass — an operator fixing one missing variable per deploy cycle is a bad afternoon.
3. Say what is wrong and what to do. 'DATABASE_URL is missing; expected a postgres:// connection string' beats a nil error six frames deep.
4. Validate relationships as well as individual values. A setting that is required only when a feature flag is on, or a pair that must both be set or both be absent, is where the real breakage lives.
5. Fail closed in production for anything unsafe to omit, but allow sensible local defaults in development so a new contributor can boot the app.
6. Do NOT print, log, or include secret values in validation errors. Report the name, the expected shape, and whether it is present — never the value, not even truncated.
7. Classify settings as required, optional, deprecated, or environment-specific, and warn on deprecated ones with the replacement name.

## UI and UX Requirements

Match the application's existing design system exactly. Reuse its components,
spacing, and typography. This feature should look like it was always there.

## Responsive Requirements

Works on mobile, tablet, and desktop. Touch targets are large enough to hit on a
phone, and nothing overflows horizontally at 320px.

## Accessibility Requirements

- Fully keyboard navigable.
- Correct semantic elements and ARIA roles.
- Visible focus states.
- Meets WCAG AA contrast.
- Dynamic changes are announced to screen readers.
- Respects prefers-reduced-motion.

## Edge Cases

- An empty string is not the same as unset, and the difference is usually a bug. Decide explicitly which one counts as missing.
- Type coercion is a silent failure mode. The string 'false' is truthy in most languages, and 'no' is not a number.
- Settings that point at external services should be checked for shape at startup but not necessarily connected to — a strict connectivity check turns a slow dependency into a boot failure.
- Validation must run identically in every environment that boots the app, including migration containers, one-off consoles, and scheduled tasks, or a missing value surfaces only in the path nobody tested.
- Deployment templates and the documented example file must be generated from the same declaration, or the list drifts within a month.
- A validation failure must exit with a non-zero status and a readable message on stderr, so the deploy fails visibly rather than crash-looping quietly.
- Do not require production-only settings in a test run, or the test suite becomes a place where secrets have to exist.

## Testing

Exercise the feature end to end in the running application. Cover every edge case
above, then run the existing test suite and confirm nothing regressed.

## Acceptance Criteria

- [ ] Every setting the app reads is declared in one place with its requirement level and format.
- [ ] Startup validation reports all failures at once and refuses to serve traffic on failure.
- [ ] Error messages name the setting, the expected shape, and the fix, and never contain the value.
- [ ] Cross-setting relationships and conditionally required settings are validated.
- [ ] Development boots with defaults while production fails closed on unsafe omissions.
- [ ] Deprecated settings warn and name their replacement.
- [ ] The documented example configuration is generated from the declaration.
- [ ] The feature matches the existing design system.
- [ ] No existing functionality is broken.

## Adaptation Rules

- Match the existing design system. Do not introduce a new colour palette,
  spacing scale, or component library.
- Reuse existing components and utilities wherever they fit.
- Follow the naming, file layout, and code style already present.
- Do not upgrade, replace, or remove existing dependencies to make this
  feature fit. Adapt the feature to the app, not the app to the feature.
- Do not break existing functionality. If a change is genuinely required in
  existing code, make the smallest one that works and say so.
- If something in these instructions conflicts with how the application is
  built, follow the application and explain the deviation.

## Final Verification

Before you report the work as done:

1. Re-read the acceptance criteria above and check each one against what you
   actually built.
2. Run the application and exercise the feature end to end.
3. Run the existing test suite and confirm you have broken nothing.
4. Check the feature on mobile, tablet, and desktop widths.
5. Check keyboard navigation and focus handling.
6. Summarize what changed: files added, files modified, and anything you
   deliberately did differently because of how this application is built.

If any acceptance criterion is unmet, fix it before reporting completion.
