Skip to content

consult: legible Gatekeeper error message when codex vendor binary is XProtect-killed #1152

Description

@amrmelsayed

Problem

When consult -m codex ... invokes the codex vendor binary and gets SIGKILL (XProtect-killed at exec time) or ENOENT (binary auto-Trashed by the OS after XProtect flagged it), the user sees a raw spawn failure with no context. There's no signal that macOS Gatekeeper / XProtect is the cause, no pointer to the workaround, no hint that they should update or file an issue.

Original observation from #1128 (2026-07-01): "the first invocation is killed with SIGKILL and the OS shows the dialog: 'codex was not opened because it contains malware. This action did not harm your Mac.' The default action in that dialog is Move to Trash, which deletes the vendor binary. All subsequent runs then fail with ENOENT because the file no longer exists."

Complements the SDK bump shipped in PR #1141 by making residual / future failures diagnosable rather than silent.

Origin

Follow-on from #1128 option (c). Deferred from the primary #1128 fix to keep that PR scoped to the SDK bump.

Fix sketch

In packages/codev/src/commands/consult/index.ts's codex invocation path (roughly the SDK spawn error handling):

  1. Detect SIGKILL on first exec of the codex binary — the child process exits with signal === 'SIGKILL' and no output before it dies.
  2. Detect ENOENT on subsequent invocations — the child process rejects immediately with code: 'ENOENT' at spawn time.
  3. In either case, run a quick verification: spctl -a -vv <resolved binary path> and check for CSSMERR_TP_CERT_REVOKED or file-not-found.
  4. Emit a legible error to stderr:
    Codex CLI blocked by macOS Gatekeeper (XProtect).
    The vendored binary at <path> has a revoked certificate and cannot be executed.
    To restore the codex consult lane:
      • Update Codev: npm install -g @cluesmith/codev@latest
      • Or install the standalone codex CLI: npm install -g @openai/codex
    Details: https://github.com/cluesmith/codev/issues/1128
    
  5. Exit with a distinctive code (e.g. 137 preserved for SIGKILL, custom code for the diagnostic path).

Behavior on other platforms

  • Linux, Windows: XProtect doesn't apply; the fallback error path is a generic spawn failed message with the resolved path and errno. Same location, different branch.
  • Non-codex models: unchanged.

Scope

  • packages/codev/src/commands/consult/index.ts — codex invocation error handler
  • Test: mock SDK spawn to emit SIGKILL / ENOENT, verify diagnostic message + exit code
  • No changes to gemini / claude / hermes lanes

Related

Metadata

Metadata

Assignees

No one assigned

    Labels

    area/consultArea: Consult CLI / consultation tooling

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions