Skip to content

Improve ocx init compatibility and recovery guidance when hard-link publication is unavailable #3893

Description

@parkjs101

Area

CLI

What are you trying to accomplish?

Complete first-run setup with ocx init when the configuration filesystem refuses hard-link publication, while preserving the existing confidentiality and complete-file publication guarantees. If those guarantees cannot be provided on that filesystem, users need actionable guidance for choosing a supported configuration location.

What prevents this today?

Reviewed at dev commit 76436a3ee221d577cc94d6c10544c03bb1f9d9db.

publishInitialConfigNoReplace hardens a private temporary file, writes the complete configuration, then publishes it with one hard-link operation. Unsupported or denied links fail explicitly; this is intentional behavior introduced by #3796 and documented in the quickstart, rather than an unhandled exception.

The error identifies the hard-link requirement and warns that configuration may already exist, but does not explain how to select a supported location or distinguish a link restriction from a permission-hardening failure.

The temporary file is a sibling of the target. Merely placing OPENCODEX_HOME on another drive does not create a cross-device link.

What should OpenCodex do?

Provide a documented recovery path when initial publication is unavailable:

  • Explain the filesystem/permission requirements and how to select a configuration location that satisfies them.
  • Preserve the warning to inspect the destination before retrying when publication is uncertain.
  • Distinguish a failure to secure the temporary file from a failure to publish it.
  • Consider an alternative publication strategy only if it preserves all existing guarantees: permission hardening before secret bytes are written, complete-file visibility, no replacement of any existing destination, and cleanup that cannot damage an existing or concurrently published file.

An actionable diagnostic/documentation improvement is a useful first step. Alternative filesystem support should require evidence that these guarantees hold; this proposal does not require an unconditional fallback.

Example usage or interface

For a fresh installation whose current location rejects publication:

  1. Run ocx init.
  2. Receive an explanation of the failed prerequisite and instructions to inspect any existing config or temporary residue.
  3. Select a supported OPENCODEX_HOME location and retry setup, without hand-writing a configuration containing credentials.

Existing configuration must remain preserved throughout this workflow.

Alternatives or workarounds

Opening the destination with O_CREAT | O_EXCL prevents replacement, but writing its contents afterward exposes an empty or partial config. It is not equivalent to publishing a fully written private file.

Ordinary rename/replacement is also not an acceptable fallback if it can replace a concurrent winner. On Windows, a fallback must account for required ACL hardening as well as hard-link support.

Additional context

Verification used Windows with Bun 1.4.0 and the implementation's injected I/O seam. For each of EOPNOTSUPP, ENOTSUP, ENOSYS, EXDEV, and EPERM, an injected link failure produced:

{
  "name": "InitialConfigPublicationError",
  "publication": "uncertain",
  "hardLinkUnavailable": true,
  "residualTemp": false,
  "targetExists": false
}

The isolated probe used nonsensitive fixture bytes and bypassed ACL hardening solely to reach the link fault boundary. This verifies error handling, not successful operation on an actual non-NTFS/FUSE/network filesystem. No physical-filesystem reproduction is claimed.

Existing regression coverage includes partial-write cleanup and denied-link behavior in tests/config/config-mutation-lock.test.ts. That whole test file could not run in this fresh checkout because zod/v4 was unavailable; the standalone publication probe did run.

Checks

  • I searched existing issues and documentation.
  • This request describes a concrete OpenCodex workflow rather than merely naming a desired technology.
  • I removed secrets and personal data.

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