LearnNewsExamplesServices
Frontmatter
id16039
titleDeployment config defaults absorb the env-override surface: policy becomes AiConfig, env keeps only secrets and choices
stateClosed
labels
enhancementaiarchitecture
assigneesneo-gpt
createdAtJul 27, 2026, 3:19 AM
updatedAtJul 30, 2026, 11:16 PM
githubUrlhttps://github.com/neomjs/neo/issues/16039
authorneo-opus-grace
commentsCount2
parentIssue15798
subIssues[]
subIssuesCompleted0
subIssuesTotal0
contentTrust
projected
quarantined0
signals[]
blockedBy[x] 16166 Split host-edge and container orchestrator task authority
blocking[ ] 16040 Rewrite the deployment guides once parity lands: fewer steps the operator performs, not fewer lines
closedAtJul 30, 2026, 11:16 PM

Deployment config defaults absorb the env-override surface: policy becomes AiConfig, env keeps only secrets and choices

Closed Backlog/active-chunk-10 enhancementaiarchitecture
neo-opus-grace
neo-opus-grace commented on Jul 27, 2026, 3:19 AM

2026-07-30 dependency correction

This ticket is no longer blocked until #15798 completes. The operator corrected the rollout premise: one maintainer machine will hard-cut to the canonical container Agent OS, then delete the local/parity compatibility substrate.

#16039 is therefore a parallel prerequisite inside #16167. The local cut becomes small only when the canonical container posture is the default and Compose stops redeclaring it. The live GitHub parent relationship already makes this ticket a child of #15798.

The problem

Every deployment-touching PR currently grows the environment-variable surface instead of moving policy and posture into AiConfig. The surface is now a dominant cost of standing Neo up, and the local/cloud cutover would otherwise add another override map solely to undo local-first defaults.

Measured against a live external deployment (sanitized docker inspect across its three services), 33 of 45 NEO_* keys the deployment sets already have declared config leaves with defaults. The pipeline sets them anyway. Of the 12 that are not leaves, only two are secrets that inherently belong outside config:

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 become leaves or derive from the owning runtime profile
behavior flags NEO_MC_PRIMARY, NEO_REAL_TIME_MEMORY_PARSING become leaves
secrets NEO_MCP_HEALTHCHECK_TOKEN, provider credential remain deployment-side

The immediate hard-cut audit also found canonical Compose restating:

  • deploymentMode=cloud and authorityProfile=container-plane;
  • local-only lanes already disabled by the cloud deployment mode;
  • disabled host-supervised MLX/Ollama/LM Studio;
  • provider selectors and model identifiers that already have defaults;
  • MCP HTTP ports and the canonical tenant mirror root;
  • plane/member paths whose defaults already resolve correctly in the production image.

Those restatements make docker-compose.dev.yml and the stopped #16167 overlay large because each profile needs its own copy of the same truth.

Target posture

A deployment supplies only:

  • secrets and secret-file locations;
  • tenant repositories and deployment identity;
  • provider endpoint/model choices when they differ from the default;
  • container listener/network placement;
  • privileged runtime-access capabilities and allowlists.

Policy, security posture, scheduler posture, default providers/models, canonical ports, and normal plane paths live in AiConfig. A host-only process explicitly opts into its host role; the default process posture is the canonical container plane.

Intended solution

  1. Default the Orchestrator to deploymentMode=cloud and authorityProfile=container-plane.
  2. Default host-supervised Ollama and LM Studio to disabled; local provider endpoints remain independently operator-managed choices.
  3. Remove canonical/dev Compose values that exactly match declared defaults, including redundant local-only false pins, provider selectors/models, MCP ports, tenant root, and canonical plane/member paths where the container image resolves the same value.
  4. Keep profile-specific placement values explicit: for example NEO_CHROMA_HOST=chroma, NEO_MCP_LISTEN_HOST=0.0.0.0, secret file paths, provider endpoints, and Docker runtime authority.
  5. Add or extend the existing config-leaf parity lint so a Compose profile cannot silently restate a matching leaf default.
  6. Re-run the deployment census and use the production Compose file plus a tiny local bind/ingress overlay as the live #16167 proof.

Acceptance criteria

  • The default Agent OS Orchestrator posture is cloud/container-plane; host-only processes opt into their role explicitly.
  • Host-supervised Ollama and LM Studio are disabled by default without changing independently managed provider endpoints.
  • Every non-secret key in the original 45-key census is a config leaf, is derived from another leaf/profile, or has a recorded deployment-specific reason.
  • Security posture defaults safely (trustProxyIdentity=false, pinFirstProviderSubject=true); deployments opt out rather than opt in.
  • Values derivable from another leaf are not restated; auth source derivation from auth mode remains the worked example.
  • Canonical Compose keeps secrets, tenant/provider choices, networking, placement, and privileged capabilities but removes matching policy/default restatements.
  • A mechanical check fails when a Compose profile sets a value identical to its declared default, extending the existing ai/scripts/lint/config-leaf-parity.json surface.
  • The census re-run reports the reduced required-key count and distinguishes required deployment choices from optional overrides.
  • ADR 0019 records the boundary: policy and posture are config; secrets and per-deployment identity/placement choices are environment.

Evidence

The census method is re-runnable: compare each deployment key against ai/configBase.mjs, ai/mcp/server/memory-core/configBase.mjs, and ai/mcp/server/knowledge-base/configBase.mjs, then compare resolved values rather than variable names alone.

Related

Parent #15798 · hard cut #16167 · plane placement #15800 · live deployment example PR #16038 · ADR 0019 AiConfig reactive-provider SSOT.

Originally filed by Grace (@neo-opus-grace, Claude Opus 5) on operator direction; dependency and execution shape corrected by Euclid on 2026-07-30 after the operator's one-user hard-cut ruling.

tobiu referenced in commit 2025943 - "feat(ai): make Docker Agent OS the default deployment posture (#16039) (#16188) on Jul 30, 2026, 11:16 PM
tobiu closed this issue on Jul 30, 2026, 11:16 PM