How to Keep Codex Running Indefinitely

I’ve been using OpenAI’s Codex for programmatically verifible tasks that can take a long time to complete, such as formalizing a proof in Lean, or using autoresearch to iteratively improve ML models. Codex tends to stop at reasonable-looking milestones even when the next step is obvious, which can be a pain when I want it to run unattended. A Stop hook that injects a continuation prompt fixes it.

You register the hook once in ~/.codex and opt in per run, so there’s nothing to add to individual projects. The setup is three files, and the hook stays off unless you set CODEX_KEEPALIVE=1.

Step 1: Enable hooks

In ~/.codex/config.toml:

[features]
codex_hooks = true

Step 2: Register the Stop hook

In ~/.codex/hooks.json:

{
  "hooks": {
    "Stop": [
      {
        "hooks": [
          {
            "type": "command",
            "command": "python3 /home/your-user/.codex/hooks/keep_session_alive.py",
            "timeout": 5,
            "statusMessage": "Evaluating keep-alive hook"
          }
        ]
      }
    ]
  }
}

Replace /home/your-user with your home directory.

Step 3: The hook script

In ~/.codex/hooks/keep_session_alive.py:

#!/usr/bin/env python3

import json
import os
import subprocess
import sys

ENABLE_ENV = "CODEX_KEEPALIVE"
PROMPT_ENV = "CODEX_KEEPALIVE_PROMPT"
SCRIPT_ENV = "CODEX_KEEPALIVE_SCRIPT"
DEFAULT_PROMPT = (
    "Continue working in this session without waiting for the user. "
    "Do another pass: verify the latest result, look for the next "
    "concrete action, and keep going."
)


def main() -> int:
    if not os.getenv(ENABLE_ENV):
        return 0

    json.load(sys.stdin)

    script = os.getenv(SCRIPT_ENV)
    if script:
        result = subprocess.run(script, shell=True)
        if result.returncode == 0:
            return 0

    json.dump(
        {
            "decision": "block",
            "reason": os.getenv(PROMPT_ENV, DEFAULT_PROMPT),
        },
        sys.stdout,
    )
    sys.stdout.write("\n")
    return 0


if __name__ == "__main__":
    raise SystemExit(main())

When CODEX_KEEPALIVE is set, the hook writes a block decision back to Codex with a continuation prompt, and Codex treats it as a new user turn instead of ending the session. If CODEX_KEEPALIVE_SCRIPT is also set, the hook runs that command first; a zero exit lets the session end naturally, giving you an exit condition.

Usage

Nothing changes by default — plain codex runs as before. To run unattended:

CODEX_KEEPALIVE=1 codex --yolo

--yolo auto-approves every action, so only do this inside a sandbox (Docker, VM, etc.). An unattended agent with auto-approval on your host can quietly wreck things.

With a task-specific prompt and exit condition:

CODEX_KEEPALIVE=1 \
CODEX_KEEPALIVE_PROMPT="Keep iterating until tests pass." \
CODEX_KEEPALIVE_SCRIPT="python3 check_tests.py" \
codex --yolo

The hook runs check_tests.py on every stop; as soon as it exits 0, Codex stops for real.