LearnNewsExamplesServices
Frontmatter
id13432
titleFail-loud validation of required deployment env vars (meaningful errors)
stateClosed
labels
enhancementaiarchitecture
assignees[]
createdAtJun 16, 2026, 1:09 PM
updatedAt3:21 PM
githubUrlhttps://github.com/neomjs/neo/issues/13432
authorneo-opus-grace
commentsCount3
parentIssuenull
subIssues[]
subIssuesCompleted0
subIssuesTotal0
contentTrust
projected
quarantined0
signals[]
blockedBy[]
blocking[]
closedAtJul 3, 2026, 1:15 AM

Fail-loud validation of required deployment env vars (meaningful errors)

Closed v13.1.0/archive-v13-1-0-chunk-3 enhancementaiarchitecture
neo-opus-grace
neo-opus-grace commented on Jun 16, 2026, 1:09 PM

Context

Surfaced by an operator premise-challenge on PR #13423 (#13418, the gitlab-pat healthcheck-token doc): documenting a cryptic deployment error is the tip of the iceberg. The cloud-deploy surface has many REQUIRED env vars (per server + per mode) that, when unset/empty, fail at some downstream layer with a meaningless error instead of naming the missing var.

The Problem

Required-env-var failures are non-self-diagnosing — the operator sees the SYMPTOM (a 401, a connection refusal, a crash, compose dependency <svc> failed to start), not the CAUSE (a specific unset env var). Each costs a debugging round-trip and, at best, a troubleshooting-doc lookup. Known instances (non-exhaustive):

  • NEO_MCP_HEALTHCHECK_TOKEN unset under NEO_AUTH_MODE=gitlab-pat → in-container healthcheck 401 → unhealthy → dependency <svc> failed to start (first fix: #13431).
  • NEO_AUTH_GITLAB_API_BASE_URL, NEO_CHROMA_HOST/PORT, NEO_OLLAMA_HOST, tenant deploy tokens, the Caddy DNS token, … — each fails downstream, not at the unset-var site.

Proposed Direction (design surface — likely epic + Ideation)

Boot-time, mode-aware required-env-var validation at each deploy entrypoint (MCP servers, orchestrator daemon, diagnostic scripts) that FAILS LOUD with a meaningful message (required env var X is unset — needed for Y; see <doc>) BEFORE the cryptic downstream failure. Open questions to resolve before implementation (not yet V-B-A'd — do not treat as settled):

  • Where the validator + the required-var schema live (AiConfig SSOT? a dedicated deploy-config module? — note the NEO imports only in thread-entrypoints rule + the config.template SSOT discipline both constrain this).
  • The schema format and how mode-conditional requirements are expressed.
  • Fail-loud vs warn per var; and which of the "bunch" are truly required per mode (V-B-A each against the entrypoints, not assumed).

Acceptance Criteria (umbrella — refine into subs)

  • Enumerated, mode-aware required-env-var schema for the deploy entrypoints (V-B-A'd against actual usage).
  • Boot-time validation fails loud with a meaningful per-var message.
  • Pattern applied across entrypoints; the first instance (#13431) reconciled into it.

Out of Scope

  • Optional / has-default env vars (only REQUIRED ones).
  • Weakening any auth gate (the validator improves the error, never bypasses a requirement — cf. the #12990 auth-exemption rejection).

Related

  • First instance: #13431 (mcpHealthcheck self-diagnosing 401). Origin: operator premise-challenge on PR #13423 / #13418. Auth contract #12378; cloud topology ADR 0014.

Release classification

post-release (deployment DX). Boardless. Candidate to graduate to an epic (per-entrypoint subs) + an Ideation Discussion for the validator/schema design (Tier-3: the solution shape has cross-substrate ambiguity).

Origin Session ID: 0b27b21a-2146-4976-945f-f1682c6a1c9c


Post-Graduation Implementation Contract

This section supersedes the earlier design-surface / likely-epic uncertainty above. Discussion #13505 graduated this work back into #13432 on 2026-07-02; implementation remains bounded by ADR-0019 and the #14456 leaf-metadata coordination AC.

Contract Ledger Matrix

Target Surface Source of Authority Proposed Behavior Fallback Docs Evidence
AiConfig leaf metadata grammar (leaf default/env/type plus additive metadata) ADR-0019 + Discussion #13505 + #14456 coordination AC Env-bound leaves may declare mode/entrypoint requiredness where the leaf owns the requirement; metadata is additive, lint-checkable, and does not create a parallel required-var list. Preserve existing 3-argument leaf calls. Untagged leaves are not required by this contract; requirements without a stable leaf owner must stay outside the first implementation. JSDoc on the leaf factory / metadata compiler; PR body names the #14456 coordination result. Unit fixtures proving metadata compiles into the registry without changing existing leaf defaults/env parsing.
Boot/readiness validation seam (assertConfigFresh) Discussion #13505 OQ1/OQ2 + #13560/#13570 boot-guard precedent Validate required env state at the existing config-fresh boot guard seam used by deploy entrypoints; fail closed for certifying consumers when a required state is invalid, absent, or unknown. Diagnostic-only consumers may report structured nonzero state, but UNKNOWN must never certify readiness. JSDoc on validator result/disposition helpers. Deterministic matrix: entrypoint x mode x requirement x valueState x consumerClaim -> expectedDisposition.
Healthcheck auth boundary (NEO_MCP_HEALTHCHECK_TOKEN) #13435 split + #12990 auth-exemption rejection + #13505 OQ4 The first implementation may report the existing healthcheck-token requirement under the relevant mode/entrypoint. It must not change loopback/static-secret/auth policy. Any auth-policy change requires a separate security artifact that explicitly supersedes #12990. PR body states the split and non-change. Tests assert reporting/validation only, not auth behavior changes.

Implementation Acceptance Criteria

  • Extend the AiConfig meta-leaf grammar with requiredness metadata in the same coordinated attribute surface as #14456, without a parallel required-var schema.
  • Preserve ADR-0019 boundaries: no env re-reads outside the AiConfig env layer, no hidden defaults, no defensive optional chaining, no pass-through config object plumbing, and no runtime mutation of the shared AiConfig singleton.
  • Validate required value state at the existing assertConfigFresh / config-fresh boot-guard seam.
  • Distinguish present-valid, present-invalid/empty, absent, and unknown/un-checkable states; invalid, absent, or unknown must never certify readiness.
  • Keep #13435 split: reporting NEO_MCP_HEALTHCHECK_TOKEN as an existing requirement is allowed; auth-policy changes are out of scope.
  • Add deterministic unit coverage for entrypoint x mode x requirement x valueState x consumerClaim -> expectedDisposition.