Skip to content

feature: SIGUSR1 handler for mid-task instruction injection via inbox file #16060

@langdon

Description

@langdon

Summary

There is currently no way for an external process to send instructions to a running Codex agent without interrupting it. A SIGUSR1 handler that reads from a well-known inbox file would enable lightweight orchestrator-to-agent communication without a process restart.

Use case

When Codex runs unattended as a background agent (launched by a control plane, CI pipeline, or automation script), the orchestrator may need to:

  • Send a course correction or priority update mid-task
  • Notify the agent that new context is available
  • Ask it to check an external resource before the next step

There is currently no way to do this without killing the process (losing all context) or waiting for the session to end.

Proposed behavior

  1. Codex registers a SIGUSR1 handler in the Node wrapper (codex-cli/bin/codex.js) alongside the existing SIGINT/SIGTERM/SIGHUP handlers.
  2. On receipt, Codex reads a well-known inbox file. Suggested default: /tmp/codex-inbox-<pid>.md, overridable via CODEX_INBOX_FILE.
  3. The file contents are injected as a user/operator turn at the next safe point in the agent loop (between tool calls, not mid-LLM-call).
  4. The inbox file is deleted after reading.
  5. If no inbox file exists when the signal arrives, Codex logs a debug message and continues.

Why SIGUSR1

SIGUSR1 and SIGUSR2 are the two POSIX signals reserved for application-defined use with no default meaning. SIGHUP, SIGINT, and SIGTERM are already handled (all three forwarded to the child process). SIGUSR1 is the natural fit for "check your inbox."

Implementation sketch

The existing pattern in codex-cli/bin/codex.js:

["SIGINT", "SIGTERM", "SIGHUP"].forEach((sig) => {
  process.on(sig, () => forwardSignal(sig));
});

A SIGUSR1 handler alongside it:

process.on("SIGUSR1", () => {
  const inboxPath = process.env.CODEX_INBOX_FILE ?? `/tmp/codex-inbox-${process.pid}.md`;
  try {
    const msg = fs.readFileSync(inboxPath, "utf8").trim();
    if (msg) {
      fs.unlinkSync(inboxPath);
      injectMessage(msg); // inject into agent loop at next safe point
    }
  } catch {
    // no inbox file -- ignore
  }
});

The file-based approach is intentionally composable: any external process (a Telegram bot daemon, a cron job, another agent) can write to the inbox file and then send the signal. Codex does not need to know about the external transport.

Prior art

A similar proposal was filed for Claude Code: anthropics/claude-code#36847.


This issue was drafted collaboratively by a human operator and an AI assistant (AI-C per ai-attribution).

Metadata

Metadata

Assignees

No one assigned

    Labels

    CLIIssues related to the Codex CLIenhancementNew feature or request

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions