-
Notifications
You must be signed in to change notification settings - Fork 10.2k
feature: SIGUSR1 handler for mid-task instruction injection via inbox file #16060
Description
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
- Codex registers a
SIGUSR1handler in the Node wrapper (codex-cli/bin/codex.js) alongside the existingSIGINT/SIGTERM/SIGHUPhandlers. - On receipt, Codex reads a well-known inbox file. Suggested default:
/tmp/codex-inbox-<pid>.md, overridable viaCODEX_INBOX_FILE. - 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).
- The inbox file is deleted after reading.
- 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).