Feature 01 task 1: Go module, fail-fast config and /health #2

Member

Implements task 04797604 (Feature 01, task 1 of 6).

Done-condition: go.mod declares module code.cubecraftlabs.com/Maniacs_Mansion/Meal-Quest with go 1.25; cmd/server/main.go wires a chi router on MEALQUEST_HTTP_ADDR with slog JSON logging; internal/config.Load() reads MEALQUEST_* env vars and *_FILE secret files, collecting every missing/invalid value and exiting non-zero naming each; GET /health returns 200 {"status":"ok","version":""}; table tests cover all vars present, one missing, invalid duration, *_FILE read, unreadable *_FILE; gofmt -l . empty, go vet and go test -race pass.

Local evidence: gofmt -l . (empty), go vet ./... pass, go test -race -count=1 ./... pass (internal/config, internal/server), go build ./... pass.

Base: feature/19ad7feb-aba0-4b76-ab70-c47d71ed5e76-repository-scaffold-and-ci (dev d2dc58a).

Implements task 04797604 (Feature 01, task 1 of 6). Done-condition: go.mod declares module code.cubecraftlabs.com/Maniacs_Mansion/Meal-Quest with go 1.25; cmd/server/main.go wires a chi router on MEALQUEST_HTTP_ADDR with slog JSON logging; internal/config.Load() reads MEALQUEST_* env vars and *_FILE secret files, collecting every missing/invalid value and exiting non-zero naming each; GET /health returns 200 {"status":"ok","version":"<build version>"}; table tests cover all vars present, one missing, invalid duration, *_FILE read, unreadable *_FILE; gofmt -l . empty, go vet and go test -race pass. Local evidence: gofmt -l . (empty), go vet ./... pass, go test -race -count=1 ./... pass (internal/config, internal/server), go build ./... pass. Base: feature/19ad7feb-aba0-4b76-ab70-c47d71ed5e76-repository-scaffold-and-ci (dev d2dc58a).
dev_agent added 1 commit 2026-10-02 22:04:58 -04:00
Add Go module, fail-fast config loader and /health endpoint
Independent review Not signed off — 2 high finding(s) (#2)
5707682018
- go.mod: module code.cubecraftlabs.com/Maniacs_Mansion/Meal-Quest, go 1.25,
  sole dependency github.com/go-chi/chi/v5.
- internal/config: Load() reads MEALQUEST_* env vars and *_FILE secrets,
  collects every missing/invalid value into one error naming each variable,
  rejects inline secrets, and redacts secrets when formatted.
- internal/server: chi router serving GET /health -> {"status":"ok","version"}.
- cmd/server: wiring only; slog JSON logging, version via -ldflags
  "-X main.version=...", graceful shutdown on SIGINT/SIGTERM.
- .gitignore: cover .env*, deploy/secrets/, node_modules, dist, *.db.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
review_agent left a comment
Member

Independent review — Codex gpt-6-sol, reasoning high

Verdict: CHANGES_REQUIRED
Reviewed SHA: 57076820189b30c3c04aca5b1aaec9b63caf0fc2

{
  "verdict": "CHANGES_REQUIRED",
  "reviewed_sha": "57076820189b30c3c04aca5b1aaec9b63caf0fc2",
  "summary": "The module, health response, and named table-test cases are present. gofmt, go vet, race tests, and go build pass. Configuration and API error handling still have blocking defects.",
  "findings": [
    {
      "id": "F1",
      "severity": "high",
      "location": "internal/config/config.go:21",
      "failure_case": "A deployment configured with the documented MEALQUEST_SECRET_KEY_FILE fails startup because the loader instead requires MEALQUEST_SESSION_SECRET_FILE.",
      "evidence": "EnvSessionSecretFile names MEALQUEST_SESSION_SECRET_FILE, and load unconditionally reads it. The documented MEALQUEST_SECRET_KEY_FILE is never read or validated.",
      "suggested_correction": "Use the architecture's secret variable name and update the config tests to exercise it."
    },
    {
      "id": "F2",
      "severity": "high",
      "location": "cmd/server/main.go:51",
      "failure_case": "A public URL such as https://alice:password@example.com causes the password to appear in the JSON startup log.",
      "evidence": "The URL validator accepts any parsed HTTP(S) URL with a host, including userinfo, and main logs cfg.PublicURL.String().",
      "suggested_correction": "Reject userinfo and other credential-bearing URL components during validation; log only a validated public origin."
    },
    {
      "id": "F3",
      "severity": "medium",
      "location": "internal/config/config.go:115",
      "failure_case": "MEALQUEST_HTTP_ADDR=:notaport passes configuration loading, then fails during server startup without naming the offending variable.",
      "evidence": "net.SplitHostPort checks address structure but returns the port as an unchecked string. No later config validation checks that it is a usable TCP port.",
      "suggested_correction": "Validate the port during Load and record a problem for MEALQUEST_HTTP_ADDR."
    },
    {
      "id": "F4",
      "severity": "medium",
      "location": "internal/server/server.go:15",
      "failure_case": "POST /health returns a 405 with an empty body instead of the required API error shape.",
      "evidence": "The router installs only the GET handler and no MethodNotAllowed handler. The approved chi version's default 405 handler writes no response body.",
      "suggested_correction": "Install a 405 handler that returns {\"error\":{\"code\",\"message\",\"retryable\"}} and test its body."
    }
  ]
}

Posted unaltered by review_agent. This is transport, not a second review.

## Independent review — Codex `gpt-6-sol`, reasoning high Verdict: **CHANGES_REQUIRED** Reviewed SHA: `57076820189b30c3c04aca5b1aaec9b63caf0fc2` ```json { "verdict": "CHANGES_REQUIRED", "reviewed_sha": "57076820189b30c3c04aca5b1aaec9b63caf0fc2", "summary": "The module, health response, and named table-test cases are present. gofmt, go vet, race tests, and go build pass. Configuration and API error handling still have blocking defects.", "findings": [ { "id": "F1", "severity": "high", "location": "internal/config/config.go:21", "failure_case": "A deployment configured with the documented MEALQUEST_SECRET_KEY_FILE fails startup because the loader instead requires MEALQUEST_SESSION_SECRET_FILE.", "evidence": "EnvSessionSecretFile names MEALQUEST_SESSION_SECRET_FILE, and load unconditionally reads it. The documented MEALQUEST_SECRET_KEY_FILE is never read or validated.", "suggested_correction": "Use the architecture's secret variable name and update the config tests to exercise it." }, { "id": "F2", "severity": "high", "location": "cmd/server/main.go:51", "failure_case": "A public URL such as https://alice:password@example.com causes the password to appear in the JSON startup log.", "evidence": "The URL validator accepts any parsed HTTP(S) URL with a host, including userinfo, and main logs cfg.PublicURL.String().", "suggested_correction": "Reject userinfo and other credential-bearing URL components during validation; log only a validated public origin." }, { "id": "F3", "severity": "medium", "location": "internal/config/config.go:115", "failure_case": "MEALQUEST_HTTP_ADDR=:notaport passes configuration loading, then fails during server startup without naming the offending variable.", "evidence": "net.SplitHostPort checks address structure but returns the port as an unchecked string. No later config validation checks that it is a usable TCP port.", "suggested_correction": "Validate the port during Load and record a problem for MEALQUEST_HTTP_ADDR." }, { "id": "F4", "severity": "medium", "location": "internal/server/server.go:15", "failure_case": "POST /health returns a 405 with an empty body instead of the required API error shape.", "evidence": "The router installs only the GET handler and no MethodNotAllowed handler. The approved chi version's default 405 handler writes no response body.", "suggested_correction": "Install a 405 handler that returns {\"error\":{\"code\",\"message\",\"retryable\"}} and test its body." } ] } ``` --- Posted unaltered by `review_agent`. This is transport, not a second review.
dev_agent added 1 commit 2026-10-02 22:12:07 -04:00
Address review findings F1-F4 for config and /health
Independent review Not signed off — 0 high, 3 medium (#2)
60555bf8ec
- F1: read the secret from MEALQUEST_SECRET_KEY_FILE, the documented name.
- F2: reject public URLs carrying userinfo, never echo the raw URL in
  config errors, and log only the public origin (scheme + host).
- F3: validate the MEALQUEST_HTTP_ADDR port (numeric, 0-65535) during Load.
- F4: return 405 with the API error JSON shape for unsupported methods.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
review_agent left a comment
Member

Independent review — Codex gpt-6-sol, reasoning high

Verdict: CHANGES_REQUIRED
Reviewed SHA: 60555bf8ec087171622b9358ce3664b5ce346bfa

{
  "verdict": "CHANGES_REQUIRED",
  "reviewed_sha": "60555bf8ec087171622b9358ce3664b5ce346bfa",
  "summary": "The four prior findings are fixed. The requested formatting, vet, race test, and build checks pass. Three validation and API error cases still need correction.",
  "findings": [
    {
      "id": "F1",
      "severity": "medium",
      "location": "internal/server/server.go:14",
      "failure_case": "GET /unknown returns a plain-text 404 instead of the required JSON error body.",
      "evidence": "The router sets a 405 handler but no 404 handler. Chi’s default NotFoundHandler is http.NotFound.",
      "suggested_correction": "Register a JSON 404 handler using the required error shape and test an unknown path."
    },
    {
      "id": "F2",
      "severity": "medium",
      "location": "internal/config/config.go:141",
      "failure_case": "MEALQUEST_PUBLIC_URL=http://:8080 passes Load despite having no hostname.",
      "evidence": "The check requires a nonempty u.Host, which is \":8080\" for this URL; it does not check u.Hostname().",
      "suggested_correction": "Require a nonempty hostname and add a regression case."
    },
    {
      "id": "F3",
      "severity": "medium",
      "location": "internal/config/config.go:122",
      "failure_case": "MEALQUEST_HTTP_ADDR=bad host:8080 passes Load, then listening fails without naming MEALQUEST_HTTP_ADDR as the offending variable.",
      "evidence": "Validation splits host and port but only checks the port; the host is discarded.",
      "suggested_correction": "Validate the host syntax during Load, or attribute listen address failures to MEALQUEST_HTTP_ADDR in the startup error."
    }
  ]
}

Posted unaltered by review_agent. This is transport, not a second review.

## Independent review — Codex `gpt-6-sol`, reasoning high Verdict: **CHANGES_REQUIRED** Reviewed SHA: `60555bf8ec087171622b9358ce3664b5ce346bfa` ```json { "verdict": "CHANGES_REQUIRED", "reviewed_sha": "60555bf8ec087171622b9358ce3664b5ce346bfa", "summary": "The four prior findings are fixed. The requested formatting, vet, race test, and build checks pass. Three validation and API error cases still need correction.", "findings": [ { "id": "F1", "severity": "medium", "location": "internal/server/server.go:14", "failure_case": "GET /unknown returns a plain-text 404 instead of the required JSON error body.", "evidence": "The router sets a 405 handler but no 404 handler. Chi’s default NotFoundHandler is http.NotFound.", "suggested_correction": "Register a JSON 404 handler using the required error shape and test an unknown path." }, { "id": "F2", "severity": "medium", "location": "internal/config/config.go:141", "failure_case": "MEALQUEST_PUBLIC_URL=http://:8080 passes Load despite having no hostname.", "evidence": "The check requires a nonempty u.Host, which is \":8080\" for this URL; it does not check u.Hostname().", "suggested_correction": "Require a nonempty hostname and add a regression case." }, { "id": "F3", "severity": "medium", "location": "internal/config/config.go:122", "failure_case": "MEALQUEST_HTTP_ADDR=bad host:8080 passes Load, then listening fails without naming MEALQUEST_HTTP_ADDR as the offending variable.", "evidence": "Validation splits host and port but only checks the port; the host is discarded.", "suggested_correction": "Validate the host syntax during Load, or attribute listen address failures to MEALQUEST_HTTP_ADDR in the startup error." } ] } ``` --- Posted unaltered by `review_agent`. This is transport, not a second review.
dev_agent added 1 commit 2026-10-02 22:17:31 -04:00
Address second review findings F1-F3 for 404, public URL and listen host
Independent review Approved — 0 high findings (#2)
454faea429
- F1: return the JSON API error shape for unknown paths (404 not_found)
- F2: require a non-empty hostname in MEALQUEST_PUBLIC_URL
- F3: validate the MEALQUEST_HTTP_ADDR host as an IP address or hostname

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
review_agent left a comment
Member

Independent review — Codex gpt-6-sol, reasoning high

Verdict: APPROVED
Reviewed SHA: 454faea429ac4b954972f6d328cdf0fcd087f777

{
  "verdict": "APPROVED",
  "reviewed_sha": "454faea429ac4b954972f6d328cdf0fcd087f777",
  "summary": "The four prior findings are fixed. Configuration validation, secret handling, and HTTP responses meet the stated requirements. gofmt, go vet, race tests, and go build pass. An additional go run smoke test could not start because the read-only sandbox prevents Go from creating a temporary build directory.",
  "findings": []
}

Posted unaltered by review_agent. This is transport, not a second review.

## Independent review — Codex `gpt-6-sol`, reasoning high Verdict: **APPROVED** Reviewed SHA: `454faea429ac4b954972f6d328cdf0fcd087f777` ```json { "verdict": "APPROVED", "reviewed_sha": "454faea429ac4b954972f6d328cdf0fcd087f777", "summary": "The four prior findings are fixed. Configuration validation, secret handling, and HTTP responses meet the stated requirements. gofmt, go vet, race tests, and go build pass. An additional go run smoke test could not start because the read-only sandbox prevents Go from creating a temporary build directory.", "findings": [] } ``` --- Posted unaltered by `review_agent`. This is transport, not a second review.
approver_agent merged commit e3d8c4d73d into feature/19ad7feb-aba0-4b76-ab70-c47d71ed5e76-repository-scaffold-and-ci 2026-10-02 22:20:35 -04:00
Sign in to join this conversation.
No Reviewers
No labels
2 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: Maniacs_Mansion/MealQuest#2