By: Michael Lynch <git@mtlynch.io>
Reject invalid startup configuration before side effects Application and importer configuration was spread across global flags, raw environment lookups, build-tagged helpers, and late startup code. Invalid ports, URLs, SMTP settings, or proxy values could be discovered only after directories were created, clients initialized, or SQLite opened; any nonempty BEHIND_PROXY value also enabled trusted forwarding behavior, including false-like strings. Litestream constructs a typed Config from defaults, overlays external values, validates field and cross-field constraints, and only then starts operational components in reference/litestream/cmd/litestream/main.go. Adopt that parse-then-validate boundary while keeping this application's configuration much smaller and immutable. Add startupconfig plans for the app and importer, inject environment lookup for deterministic tests, and parse all command inputs before resource initialization. Strictly validate ports, booleans, time zones, media mode, S3 and public URLs, SMTP settings, sender addresses, and production HTTPS requirements. Build-tagged login policies retain the existing development and production behavior, and Fly now supplies the canonical BEHIND_PROXY=true value. S3 configuration owns typed URL validation without exposing credentials in errors. The implementation had to preserve build-tag symmetry and secret bytes while eliminating process-global reads. Development must not require production SMTP values, production must validate them before opening SQLite, and passwords or keys must not be trimmed, formatted, or logged. Litestream-specific credentials remain Litestream's responsibility; this app validates only the LITESTREAM_BUCKET presence signal that selects SQLite pragmas rather than duplicating litestream.yml policy. No external blockers were encountered. Production and development focused tests, the full Go checks, and every flake target passed before the amendment.
| Time to Start | Worker time | Duration | Time to finish | Idle | |
| Config | 10s | 2s | 2s | 13s | 10s |
| Eval | 50s | 17s | 17s | 1m07s | 36s |
| Build | 1m06s | 5m07s | 7m35s | 8m42s | 5m01s |
| Suite | 10s | 5m27s | 8m32s | 8m42s | 5m48s |