Blocked until local/cloud runtime parity (#15798) completes. Filed now so the decision is captured while the evidence is fresh; the work must not start before parity lands, because parity is what makes the correct defaults knowable.
The problem
Every deployment-touching PR currently grows the environment-variable surface instead of moving a default. The surface is now the dominant cost of standing Neo up.
Measured against a live external-tenant deployment (sanitized docker inspect across its three services): 33 of 45 NEO_* keys the deployment sets are already declared config leaves with defaults. The pipeline sets them anyway. Of the 12 that are not leaves, only 2 belong in the environment at all:
| group |
keys |
disposition |
| auto-* toggles |
NEO_AUTO_SYNC, NEO_AUTO_DREAM, NEO_AUTO_GOLDEN_PATH, NEO_AUTO_INGEST_FS, NEO_AUTO_SUMMARIZE, NEO_KB_AUTO_START_DATABASE, NEO_MEM_AUTO_START_DATABASE, NEO_MEM_AUTO_START_INFERENCE |
8 — should become leaves |
| behavior flags |
NEO_MC_PRIMARY, NEO_REAL_TIME_MEMORY_PARSING |
2 — should become leaves |
| secrets |
NEO_MCP_HEALTHCHECK_TOKEN, provider PAT |
2 — correctly env-side, keep |
The ratchet, caught live
PR #16038 is well-built work that still adds six NEO_AUTH_* overrides to the canonical parity profile:
NEO_AUTH_MODE: github-pat
NEO_AUTH_TRUST_PROXY_IDENTITY: "false"
NEO_AUTH_PIN_FIRST_PROVIDER_SUBJECT: "true"
NEO_AUTH_AUTO_PROVISION_IDENTITY_SOURCES: github-pat
NEO_AUTH_PROVIDER_BOOTSTRAP_PAT_FILE: /run/secrets/mcp-auth-token
NEO_MCP_HEALTHCHECK_TOKEN_FILE: *provider-bootstrap-pat-file
Exactly one is a genuine deployment decision — where the secret file lives. TRUST_PROXY_IDENTITY: false and PIN_FIRST_PROVIDER_SUBJECT: true are security posture that should be the default; AUTO_PROVISION_IDENTITY_SOURCES is derivable from the auth mode. Nothing is wrong with that PR — the ratchet is structural, and no individual PR is where it should be stopped.
Why this blocks on parity
Today local and deployed run differently, so no one can know which value is the default versus a local accommodation. Once the same topology runs both places, the default is observable rather than argued. Doing this first would encode today's divergence as tomorrow's defaults.
Target posture
A deployment supplies: tenant repos · GitLab or GitHub · chat + embedding model (only if changing) · secrets. Everything else is a default, overridable but not required.
Acceptance Criteria
Evidence
Census method is re-runnable: each key greps against ai/configBase.mjs, ai/mcp/server/memory-core/configBase.mjs, ai/mcp/server/knowledge-base/configBase.mjs for a leaf declaration. Baseline recorded on #15798.
Related
#15798 parity epic (hard dependency) · #15800 data-plane placement election · #16038 the live example · ADR-0019 AiConfig reactive provider SSOT.
Filed by @neo-opus-grace (Grace, Claude Opus 5) on operator direction — capture now, start after parity.
Blocked until local/cloud runtime parity (#15798) completes. Filed now so the decision is captured while the evidence is fresh; the work must not start before parity lands, because parity is what makes the correct defaults knowable.
The problem
Every deployment-touching PR currently grows the environment-variable surface instead of moving a default. The surface is now the dominant cost of standing Neo up.
Measured against a live external-tenant deployment (sanitized
docker inspectacross its three services): 33 of 45NEO_*keys the deployment sets are already declared config leaves with defaults. The pipeline sets them anyway. Of the 12 that are not leaves, only 2 belong in the environment at all:NEO_AUTO_SYNC,NEO_AUTO_DREAM,NEO_AUTO_GOLDEN_PATH,NEO_AUTO_INGEST_FS,NEO_AUTO_SUMMARIZE,NEO_KB_AUTO_START_DATABASE,NEO_MEM_AUTO_START_DATABASE,NEO_MEM_AUTO_START_INFERENCENEO_MC_PRIMARY,NEO_REAL_TIME_MEMORY_PARSINGNEO_MCP_HEALTHCHECK_TOKEN, provider PATThe ratchet, caught live
PR #16038 is well-built work that still adds six
NEO_AUTH_*overrides to the canonical parity profile:NEO_AUTH_MODE: github-pat NEO_AUTH_TRUST_PROXY_IDENTITY: "false" NEO_AUTH_PIN_FIRST_PROVIDER_SUBJECT: "true" NEO_AUTH_AUTO_PROVISION_IDENTITY_SOURCES: github-pat NEO_AUTH_PROVIDER_BOOTSTRAP_PAT_FILE: /run/secrets/mcp-auth-token NEO_MCP_HEALTHCHECK_TOKEN_FILE: *provider-bootstrap-pat-fileExactly one is a genuine deployment decision — where the secret file lives.
TRUST_PROXY_IDENTITY: falseandPIN_FIRST_PROVIDER_SUBJECT: trueare security posture that should be the default;AUTO_PROVISION_IDENTITY_SOURCESis derivable from the auth mode. Nothing is wrong with that PR — the ratchet is structural, and no individual PR is where it should be stopped.Why this blocks on parity
Today local and deployed run differently, so no one can know which value is the default versus a local accommodation. Once the same topology runs both places, the default is observable rather than argued. Doing this first would encode today's divergence as tomorrow's defaults.
Target posture
A deployment supplies: tenant repos · GitLab or GitHub · chat + embedding model (only if changing) · secrets. Everything else is a default, overridable but not required.
Acceptance Criteria
trustProxyIdentityfalse,pinFirstProviderSubjecttrue) so a deployment opts out, never in.autoProvisionIdentitySourcesfrom auth mode is the worked example.ai/scripts/lint/config-leaf-parity.jsonsurface rather than adding a lane.Evidence
Census method is re-runnable: each key greps against
ai/configBase.mjs,ai/mcp/server/memory-core/configBase.mjs,ai/mcp/server/knowledge-base/configBase.mjsfor a leaf declaration. Baseline recorded on #15798.Related
#15798 parity epic (hard dependency) · #15800 data-plane placement election · #16038 the live example · ADR-0019 AiConfig reactive provider SSOT.
Filed by @neo-opus-grace (Grace, Claude Opus 5) on operator direction — capture now, start after parity.