go-config-startup-validation
The project was reconstructed at ~/guard (Go 1.26, no pre-existing repo in the environment). The fix addresses C-GAP-001..003 in three parts.
1. internal/config/config.go — new ApplyStartupValidations() (fixes C-GAP-002 compression on DeepSeek, C-GAP-003 missing API key):
// ApplyStartupValidations inspects the configuration for known
// misconfigurations, corrects the ones it can (mutating c), and returns
// human-readable warnings for the caller to surface via slog.Warn.
func (c *Config) ApplyStartupValidations() []string {
var warnings []string
// C-GAP-002: DeepSeek has no embeddings endpoint. If compression is
// enabled with the default text-embedding-3-small model on that
// backend, disable it and explain why.
if c.CompressionEnabled &&
strings.EqualFold(c.LLMBackend, BackendDeepSeek) &&
c.EmbeddingsModel == EmbeddingModelTextEmbedding3Small {
c.CompressionEnabled = false
warnings = append(warnings, fmt.Sprintf(
"compression disabled: backend %q has no embeddings endpoint for model %q; "+
"set --compression=false / compression.enabled=false, switch to a backend "+
"that exposes embeddings, or configure an embeddings-capable model",
c.LLMBackend, c.EmbeddingsModel))
}
// C-GAP-003: surface a missing LLM API key at startup.
if strings.TrimSpace(c.LLMAPIKey) == "" {
warnings = append(warnings,
"LLM API key is not set: LLM requests will fail at runtime "+
"(set LLM_API_KEY or pass --llm-api-key)")
}
return warnings
}
2. internal/server/server.go — RunServer logs warnings via slog.Warn and gates the compression worker:
func RunServer(cfg *config.Config, logger *slog.Logger) error {
warnings := cfg.ApplyStartupValidations()
for _, w := range warnings {
logger.Warn("startup validation", "detail", w)
}
if cfg.CompressionEnabled {
startCompressionWorker(logger)
} else {
logger.Info("compression worker not started (compression disabled)")
}
return nil
}
3. Makefile — dev targets use --db-url (C-GAP-001; the CLI in cmd/server/main.go registers --db-url, never --db):
dev: build
$(BIN) --db-url "$(DB_URL)"
dev-openai: build
$(BIN) --db-url "$(DB_URL)" --llm-backend openai --llm-api-key sk-test-1234
**Unit tests — 9/9 pass** (`go test -count=1 ./...`), covering: | Test | Covers | |---|---| | `TestApplyStartupValidations_DisablesCompressionOnDeepSeek` | C-GAP-002 correction: compression off + warning explaining missing embeddings endpoint | | `TestApplyStartupValidations_KeepsCompressionOnEmbeddingBackend` | OpenAI backend → compression stays on, no compression warning (no false positive) | | `TestApplyStartupValidations_RespectsExplicitDisable` | User-disabled compression is never re-enabled / re-warned | | `TestApplyStartupValidations_DeepSeekNonDefaultEmbeddingModelKeepsCompression` | Non-default model is not touched (only the exact default triggers correction) | | `TestApplyStartupValidations_WarnsOnMissingAPIKey` | C-GAP-003: warn when key empty; no warning when set | | `TestRunServer_LogsWarningsViaSlogWarn` | Both warnings emitted at `level=WARN` | | `TestRunServer_DoesNotStartCompressionWorkerWhenDisabled` | Worker stub not invoked after correction; config mutated | | `TestRunServer_StartsCompressionWorkerWhenSupported` | Worker starts on embeddings-capable backend | | `TestCLIFlagIsDbUrl` | C-GAP-001: `--db-url` registered and parses; legacy `--db` absent | **Live `make dev` run** (default DeepSeek config, `LLM_API_KEY` unset) — WARNs printed, compression worker NOT started, exit 0: ``` level=WARN msg="startup validation" detail="compression disabled: backend \"deepseek\" has no embeddings endpoint for model \"text-embedding-3-small\"; ..." level=WARN msg="startup validation" detail="LLM API key is not set: LLM requests will fail at runtime (set LLM_API_KEY or pass --llm-api-key)" level=INFO msg="compression worker not started (compression disabled)" ``` Edge cases exercised in live runs: - **Env key present** (this machine has `LLM_API_KEY` set): only the compression WARN prints — the missing-key warning is correctly suppressed, proving no false positives. - **`make dev-openai`**: no compression WARN, `compression worker started` — compression only disabled where it would actually fail. **Guard script — `guard PASS 5/5`** (`make guard`, exit 0): (1) Makefile recipes use `$(BIN) --db-url`, no `$(BIN) --db `; (2) `config.ApplyStartupValidations` exported; (3)–(5) behavioral checks via the unit tests above. One interim guard failure was a regex artifact (it matched the comment "CLI has no --db flag"); fixed by scoping check #1 to recipe lines with `grep -F` on `$(BIN)`.
{"model": "deepseek-v4-flash", "problem_class": "go-config-startup-validation", "result": "passed", "tests": 9}The project was reconstructed at ~/guard (Go 1.26, no pre-existing repo in the environment). The fix addresses C-GAP-001..003 in three parts.
1. internal/config/config.go — new ApplyStartupValidations() (fixes C-GAP-002 compression on DeepSeek, C-GAP-003 missing API key):
// ApplyStartupValidations inspects the configuration for known
// misconfigurations, corrects the ones it can (mutating c), and returns
// human-readable warnings for the caller to surface via slog.Warn.
func (c *Config) ApplyStartupValidations() []string {
var warnings []string
// C-GAP-002: DeepSeek has no embeddings endpoint. If compression is
// enabled with the default text-embedding-3-small model on that
// backend, disable it and explain why.
if c.CompressionEnabled &&
strings.EqualFold(c.LLMBackend, BackendDeepSeek) &&
c.EmbeddingsModel == EmbeddingModelTextEmbedding3Small {
c.CompressionEnabled = false
warnings = append(warnings, fmt.Sprintf(
"compression disabled: backend %q has no embeddings endpoint for model %q; "+
"set --compression=false / compression.enabled=false, switch to a backend "+
"that exposes embeddings, or configure an embeddings-capable model",
c.LLMBackend, c.EmbeddingsModel))
}
// C-GAP-003: surface a missing LLM API key at startup.
if strings.TrimSpace(c.LLMAPIKey) == "" {
warnings = append(warnings,
"LLM API key is not set: LLM requests will fail at runtime "+
"(set LLM_API_KEY or pass --llm-api-key)")
}
return warnings
}
2. internal/server/server.go — RunServer logs warnings via slog.Warn and gates the compression worker:
func RunServer(cfg *config.Config, logger *slog.Logger) error {
warnings := cfg.ApplyStartupValidations()
for _, w := range warnings {
logger.Warn("startup validation", "detail", w)
}
if cfg.CompressionEnabled {
startCompressionWorker(logger)
} else {
logger.Info("compression worker not started (compression disabled)")
}
return nil
}
3. Makefile — dev targets use --db-url (C-GAP-001; the CLI in cmd/server/main.go registers --db-url, never --db):
dev: build
$(BIN) --db-url "$(DB_URL)"
dev-openai: build
$(BIN) --db-url "$(DB_URL)" --llm-backend openai --llm-api-key sk-test-1234
**Unit tests — 9/9 pass** (`go test -count=1 ./...`), covering: | Test | Covers | |---|---| | `TestApplyStartupValidations_DisablesCompressionOnDeepSeek` | C-GAP-002 correction: compression off + warning explaining missing embeddings endpoint | | `TestApplyStartupValidations_KeepsCompressionOnEmbeddingBackend` | OpenAI backend → compression stays on, no compression warning (no false positive) | | `TestApplyStartupValidations_RespectsExplicitDisable` | User-disabled compression is never re-enabled / re-warned | | `TestApplyStartupValidations_DeepSeekNonDefaultEmbeddingModelKeepsCompression` | Non-default model is not touched (only the exact default triggers correction) | | `TestApplyStartupValidations_WarnsOnMissingAPIKey` | C-GAP-003: warn when key empty; no warning when set | | `TestRunServer_LogsWarningsViaSlogWarn` | Both warnings emitted at `level=WARN` | | `TestRunServer_DoesNotStartCompressionWorkerWhenDisabled` | Worker stub not invoked after correction; config mutated | | `TestRunServer_StartsCompressionWorkerWhenSupported` | Worker starts on embeddings-capable backend | | `TestCLIFlagIsDbUrl` | C-GAP-001: `--db-url` registered and parses; legacy `--db` absent | **Live `make dev` run** (default DeepSeek config, `LLM_API_KEY` unset) — WARNs printed, compression worker NOT started, exit 0: ``` level=WARN msg="startup validation" detail="compression disabled: backend \"deepseek\" has no embeddings endpoint for model \"text-embedding-3-small\"; ..." level=WARN msg="startup validation" detail="LLM API key is not set: LLM requests will fail at runtime (set LLM_API_KEY or pass --llm-api-key)" level=INFO msg="compression worker not started (compression disabled)" ``` Edge cases exercised in live runs: - **Env key present** (this machine has `LLM_API_KEY` set): only the compression WARN prints — the missing-key warning is correctly suppressed, proving no false positives. - **`make dev-openai`**: no compression WARN, `compression worker started` — compression only disabled where it would actually fail. **Guard script — `guard PASS 5/5`** (`make guard`, exit 0): (1) Makefile recipes use `$(BIN) --db-url`, no `$(BIN) --db `; (2) `config.ApplyStartupValidations` exported; (3)–(5) behavioral checks via the unit tests above. One interim guard failure was a regex artifact (it matched the comment "CLI has no --db flag"); fixed by scoping check #1 to recipe lines with `grep -F` on `$(BIN)`.
{"model": "deepseek-v4-flash", "problem_class": "go-config-startup-validation", "result": "passed", "tests": 9}