LearnNewsExamplesServices
Frontmatter
id16671
titleDeploy pipeline defaults to an auth-incomplete composition
stateClosed
labels
bugaibuild
assigneesneo-gpt-emmy
createdAtAug 8, 2026, 12:23 PM
updatedAtAug 8, 2026, 2:41 PM
githubUrlhttps://github.com/neomjs/neo/issues/16671
authorneo-gpt-emmy
commentsCount0
parentIssuenull
subIssues[]
subIssuesCompleted0
subIssuesTotal0
contentTrust
projected
quarantined0
signals[]
blockedBy[]
blocking[]
closedAtAug 8, 2026, 2:41 PM

Deploy pipeline defaults to an auth-incomplete composition

neo-gpt-emmy
neo-gpt-emmy commented on Aug 8, 2026, 12:23 PM

Context

At origin/dev@2263a7e4f986d6e1c4bbeeb6b03b5e42cf0c4399, the reference deploy script treats an unset NEO_DEPLOY_COMPOSE_FILE as permission to select ai/deploy/docker-compose.yml. The base file configures KB and MC for Streamable HTTP but does not select an authentication installer; the local deployment overlay supplies the concrete auth profile.

The existing focused suite proves the current contract: an explicitly empty value fails, while an unset value succeeds with the base-only default. A live reproduction recorded on #16206 shows the expensive result: image build and container mutation happen before AuthService rejects the incomplete composition.

The semantic sweep found broad #16206 and closed #16458. This is not a duplicate of either: #16206 remains a multi-axis needs-re-triage umbrella, while #16458 delivered ordered multi-file support and deliberately preserved the unsafe unset fallback. This ticket isolates the one-PR residual without reopening a resolved ticket.

Live latest-open sweep: checked the newest 20 open issues plus recent A2A claims at 2026-08-08T10:22:00Z; no equivalent or competing claim found.

The Problem

Unset and explicitly empty inputs currently have inverted safety. Empty fails before Docker; unset silently chooses a composition known not to be a complete deployment profile. The reference path can therefore spend revision lookup, build time, and container mutation before failing at server boot.

The pipeline must not choose a security or provider profile. Its safe responsibility is narrower: require the caller to name the deployment composition it intends to operate.

The Architectural Reality

  • ai/examples/cloud-deployment/deploy-pipeline.sh:34-38 owns the implicit base-only fallback.
  • ai/deploy/docker-compose.yml:80-104,178-204 configures the HTTP services without selecting an auth mode.
  • ai/deploy/docker-compose.local-agent-os.yml:10-15 is one concrete auth-complete overlay.
  • ai/mcp/server/shared/services/AuthService.mjs:124-128 correctly fails closed when no installer exists.
  • test/playwright/unit/ai/DeployPipelineComposeFileList.spec.mjs:201-220 locks the unsafe unset behavior.
  • learn/agentos/cloud-deployment/PipelineWiring.md:151-170 already tells callers to discover and pass the real ordered file set.

No new file or ownership move is proposed; the existing pipeline, focused spec, and operator guide remain the owning surfaces.

The Fix

Make NEO_DEPLOY_COMPOSE_FILE mandatory for the reference pipeline.

  • Unset and values resolving to zero usable entries fail before revision resolution, network access, preflight, or Docker.
  • The diagnostic names the variable and directs the caller to provide the plane's ordered, auth-complete Compose file set.
  • Explicit single-file and ordered multi-file inputs retain their current argv and merge-order semantics.
  • Update the focused spec and Pipeline Wiring guide; remove language calling the implicit fallback compatible.

Contract Ledger

Target Surface Source of Authority Proposed Behavior Fallback / Edge Case Docs Evidence
NEO_DEPLOY_COMPOSE_FILE in deploy-pipeline.sh The plane's own Compose labels plus PipelineWiring.md Caller supplies one explicit path or a colon-delimited ordered set Unset, empty, or delimiter-only input exits non-zero before external work Update PipelineWiring.md and script comments Focused Playwright unit spec
Deploy transaction boundary Existing fail-before-Docker guards in the script Explicit one-file and multi-file invocations remain unchanged Missing composition produces zero Docker/preflight calls and no revision lookup Inline contract comment Recording-stub order assertions

Decision Record impact

Aligned with ADR 0014 and ADR 0019. The deployment pipeline selects an explicit composition; it does not invent runtime configuration or authentication authority.

Acceptance Criteria

  • Unset, empty, and delimiter-only NEO_DEPLOY_COMPOSE_FILE values exit non-zero before revision resolution, network access, preflight, or Docker.
  • The error names NEO_DEPLOY_COMPOSE_FILE and the need for an ordered, auth-complete deployment composition.
  • Explicit single-path behavior and repeated -f ordering for multiple paths remain unchanged.
  • Project pinning, revision resolution, survivability preflight, up -d --build --wait, and the never-down guarantee remain unchanged for valid input.
  • Script comments and PipelineWiring.md no longer describe an implicit base-only fallback as compatible.
  • The focused DeployPipelineComposeFileList.spec.mjs suite is green, with the old unset-success expectation replaced by a fail-before-external-work witness.

Out of Scope

  • Selecting or changing an auth mode.
  • Changing AuthService.
  • Decomposing the base Compose file or adding auth fragments.
  • Reclassifying required inputs in #16511.
  • Running a real deployment.

Avoided Traps

  • Do not inject NEO_AUTH_MODE from the pipeline.
  • Do not reject an explicitly supplied single file; downstream deployments may provide a self-contained composition.
  • Do not validate completeness by starting or mutating containers.

Related

#16206 · #16458 · #16511 · PR #16456

Retrieval Hint: "deploy pipeline unset compose file auth-incomplete base composition"

tobiu referenced in commit d44b7f6 - "fix(deploy): require explicit composition (#16671) (#16674) on Aug 8, 2026, 2:41 PM
tobiu closed this issue on Aug 8, 2026, 2:41 PM