Skip to content

[Feature]: atomic ocx update command with daemon drain, schema validation, and multi-client sync #4173

Description

@rrmlima

Problem to solve

When operators or automated agent harnesses upgrade OpenCodex via npm install -g @bitkyc08/opencodex@latest:

  1. Active In-Flight Runtime Rejection (packageTreeIntegrity 503): The running Bun proxy process detects filesystem changes under its active package directory (src/server/index.ts:1088 packageTreeIntegrity.status()), immediately throwing 503 Server_error: OpenCodex package files changed while this proxy was running; restart OpenCodex before retrying. on all /v1/*, /healthz, and /readyz endpoints.
  2. Desynchronized Client State: The upgrade updates the package files but does not coordinate the dependent client topology:
    • On-disk opencodex-catalog.json and client models caches (models_cache.json) lag behind the new binary until an explicit sync command runs.
    • Long-lived Codex CLI app-server processes retain outdated protocol handles and stale catalog state.
    • Exported client targets (e.g. ~/.commandcode/providers.json via PR feat(clients): add native Command Code integration and catalog sync #3833) do not automatically converge on the new version's schema or models.
  3. Manual and Error-Prone Orchestration: Operators and automation scripts are forced to compose external wrapper shell scripts (stopping the service, updating via npm, validating JSON schema, invoking ocx sync --restart-codex, and polling /readyz). If any step is executed out of sequence or by a non-interactive runner, the deployment remains in an unready 503 or deadlocked state.

Proposed solution

Implement a first-class, atomic CLI command:

ocx update [version] [--channel <stable|preview>] [--restart-codex] [--dry-run] [--json]

Architecture & Lifecycle Stages:

  1. Pre-flight Schema & Readiness Guard:
    • Execute internal config validate in memory against active configuration before initiating download or termination. If configuration is invalid, abort immediately without altering running processes or files.
  2. Managed Daemon Drain & Teardown:
    • Detect whether opencodex-proxy is running as a systemd user unit, launchd daemon, or standalone background process.
    • Signal a graceful drain barrier (DRAIN state) to complete active turns while rejecting new ingress with Retry-After.
    • Terminate the listener cleanly before filesystem mutation begins, eliminating the packageTreeIntegrity race condition entirely.
  3. Transactional Package Upgrade:
    • Execute package acquisition via standard global npm/bun registry resolvers to the target version (defaulting to latest published tag on the current channel).
  4. Post-Install Client & Process Convergence:
    • Execute internal catalog regeneration (sync-cache) atomically with lock acquisition.
    • Terminate stale app-server child processes cleanly using afterCatalogWriteHandleAppServers.
    • Trigger catalog-refresh across all registered client exports (mcode, pi, raycast, and commandcode).
  5. Verified Service Bootstrap & Health Handshake:
    • Restart the daemon/unit.
    • Poll local loopback /readyz with bounded timeout until HTTP 200 {"status":"ready"} is observed before yielding control back to the terminal.
    • Output structured JSON status when --json is specified.

Alternatives considered

  • External wrapper shell scripts (apply-fix.sh / cron / wrapper CLIs): Currently used in production deployments as a local workaround. Highly brittle across platforms (Linux systemd vs macOS launchd vs Windows services) and leaves non-expert users and agent harnesses vulnerable to runtime desyncs.
  • In-process auto-reload on package tree change: Attempting to hot-reload ES modules inside the running Bun process. Rejected due to state corruption risks in SQLite/memory caches, active WebSocket handles, and crypto sessions.

Additional context

  • Upstream files involved:
    • src/cli/dispatch.ts and src/cli/registry.ts (CLI command registration and option parsing)
    • src/server/index.ts (packageTreeIntegrity check and graceful drain coordination)
    • src/service.ts (daemon management across platforms)
    • src/integrations/catalog-refresh.ts and src/codex/catalog/sync.ts (multi-client synchronization)

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    cliCLI, config inject, packaging flagsenhancementNew feature or request

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions