ryfineZ/codex-session-patcher: cleaning refusal replies out of Codex, Claude Code and OpenCode sessions
A lightweight Python tool to clean AI refusal responses from Codex CLI session files
At a glance
- What is it?
- A Python tool that scans local agent session files for refusal responses, replaces them with cooperative text so a session can resume, and optionally injects CTF context into Codex, Claude Code or OpenCode. It is aimed at security testers and CTF players, and it edits your session history in place.
- Who is it for?
- Adopt it if you run Codex CLI, Claude Code or OpenCode for CTF or authorised security testing and you keep hitting refusals that break resume, and if you are comfortable with a tool that rewrites your own session JSONL or SQLite files. Do not adopt it if you need a documented licence file, a supported upstream contract, or a way to undo a prompt injection you no longer track.
- Can I use it commercially?
- Not without permission. GitHub finds no licence file in the repository, and without a licence all rights are reserved by default: you may read the code but not reuse it. Check the README, or ask the authors, before using it.
- Is it still maintained?
- Yes. The repository last received commits 60 days ago.
- What is it written in?
- Mainly Python, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 1, 2026, and from our analysis. They are not legal advice.
Editorial analysis
The refusal wall this tool is built around
Coding agents refuse. In a CTF or an authorised penetration test, a request to write an exploit or a reverse-engineering script comes back as a refusal, and the session stops being useful. The README frames the project around exactly that: security testing, CTF competitions and pentest work where the agent "frequently refuses requests involving security operations, causing the session to break".
The tool attacks the problem from two directions. The first is cleanup: scan session files that already contain refusals, replace the refusal text with cooperative content, and resume. The second is prevention: install a CTF context at the configuration layer so the refusal is less likely in the first place. Those are different bets. Cleanup is a repair after the fact and depends on the session format staying stable. Injection is a pre-commitment that changes how the agent starts every session, and it carries its own risk of breaking normal work.
The intended user is narrow. This is not a general session browser for people who chat with coding agents. It is for someone who already knows they will be refused, and who wants the session to keep going rather than start over.
Two-level refusal detection and how a session gets rewritten
Detection is described as a two-level strategy: strong phrases matched against the whole reply, plus weaker keywords matched at the start of a reply. That combination is a deliberate trade-off. Whole-phrase matching keeps false positives low but misses refusals phrased differently; leading-keyword matching catches more but is likelier to flag ordinary text. The README claims a low false-positive rate for the pair, not zero. If you run cleanup across a large session directory, the preview path is the only real check you have.
Once a refusal is found, the replacement text is either a fixed safe default or, when an AI backend is configured, a rewrite generated from the surrounding conversation. The README lists OpenAI, Ollama and OpenRouter as compatible endpoints, so the rewrite step can be local. Two fallbacks are documented: cleanup can handle older Codex refusal records that only carry an event_msg, and if the model returns garbled question-mark output the tool falls back to a safe default string. That second fallback is a sign the author has hit encoding failures in practice.
The tool also erases encrypted reasoning content from Reasoning and Thinking blocks. The --keep-reasoning flag exists to disable that erasure and only replace refusals, which tells you the default is destructive. Backups are created before cleaning unless you pass --no-backup, and the README describes restoring to any earlier version. It does not document a rollback path for the CTF injection side.
Installing it and cleaning one session
The README gives a clone-and-script install. The install script probes for a Python 3.8 or newer interpreter, and the package declares requires-python >=3.8 with no runtime dependencies for the CLI itself.
# CLI version (auto-detects Python 3.8+)
git clone https://github.com/ryfineZ/codex-session-patcher.git
cd codex-session-patcher
./scripts/install.shAfter that, the codex-patcher entry point should be on your PATH. The first useful run is a dry run over the latest session, which prints what would change and shows the modified content without touching files.
codex-patcher --dry-run --show-content --latestRead the output before trusting it. If the preview looks right, drop --dry-run and add --format when auto-detection picks the wrong platform.
codex-patcher --latest --format claude-codeThe Web UI is the other entry point. It needs the optional web extra (FastAPI, uvicorn, pydantic, websockets, httpx) and serves on port 8080 by default.
./scripts/start-web.sh
# then open http://localhost:8080According to the README, the production script only installs or rebuilds when the Python web dependencies are missing, the frontend dependencies are missing or stale, or the built frontend assets are stale, and it does not require Node.js when the built assets are already present. Rebuilding the frontend or running dev mode needs Node.js 20.19+ on the 20.x line or 22.12+.
CTF prompt injection is a separate, more invasive decision
The injection half writes configuration, not session data. For Codex it creates a profile file at ~/.codex/ctf.config.toml on macOS and Linux, or %USERPROFILE%\.codex\ctf.config.toml on Windows, and you start it with codex -p ctf so ordinary sessions are untouched. For Claude Code and OpenCode it creates dedicated workspaces at ~/.claude-ctf-workspace and ~/.opencode-ctf-workspace, with context injected through a project-level CLAUDE.md or AGENTS.md.
codex-patcher --install-ctf-config
codex -p ctfCodex gets two injection modes that are mutually exclusive. The default append mode writes developer_instructions and keeps the built-in prompt. Replace mode writes model_instructions_file pointing at a prompt file, which takes over the built-in prompt entirely. Replace is the stronger lever and the bigger commitment.
The installer is defensive about coexistence. It strips legacy profile = "ctf", [profiles.ctf] and [profiles.ctf.*] entries left by earlier versions of this tool, because Codex CLI 0.134.0 and later error on legacy profiles. Global mode only manages blocks carrying the # __csp_ctf_global__ marker, and it refuses to enable if config.toml already has a top-level developer_instructions or model_instructions_file, rather than overwrite your configuration or create duplicate keys. Unmanaged files with the same name are preserved and reported as conflicts. That is careful design, and it also means the installer will sometimes simply refuse to act, which you should expect rather than treat as a bug.
Where it breaks, and when it is the wrong tool
The licence is the first hard problem. The README carries an MIT badge and pyproject.toml declares license = {text = "MIT"}, but the repository's top-level entries list no LICENSE file. The badge links to one that does not appear in the layout. Until you confirm a LICENSE file exists, treat the licence as unverified rather than MIT.
Second, this tool edits files that another project owns. Codex session JSONL, Claude Code JSONL and OpenCode SQLite are not formats this repository controls, and the README already documents one break caused by an upstream change: the Codex 0.134.0 legacy profile error. Nothing in the README describes a compatibility policy or a supported-version matrix, so an upstream format change is a plausible failure mode with no stated response.
Third, the injection side has a weaker undo story than the cleanup side. Cleanup has automatic backups and restore. The README does not document rollback for injected prompt configuration. Uninstall commands exist for each platform, and managed blocks carry markers so they can be identified, but if you edit a managed prompt file by hand the marker logic is what you are relying on.
Finally, consider whether you should be doing this at all. If your work is ordinary software development, a tool whose stated purpose is getting an agent to cooperate with security operations is the wrong tool, and the injection modes will change the behaviour of every session they cover. The prompt rewriting feature, codex-patcher --rewrite, requires an AI backend configured in the Web UI first, so it is not available on a fresh CLI-only install.
How it differs from a general session manager
A session manager, and the README's own comparison point is the family of Claude Code session managers, indexes and searches your history. It answers the question "where was that conversation". It does not modify the content of a reply, and it does not touch agent configuration.
codex-session-patcher answers a different question: "this session contains a refusal, make it usable again". That means it must parse each platform's session format, decide which messages are refusals, generate replacement text, and write the file back. The Web UI shows a session list grouped by date with filters for format, refusal status and backup status, which looks like a manager, but the preview panel, diff view and one-click execution are all in service of rewriting.
The practical difference is what happens when the tool is wrong. A search tool that mis-parses a file shows you nothing. This one has already written a replacement into your session and erased reasoning content by default. That is why the dry-run path and the backup default matter more here than in a read-only browser.
Maintenance, upgrade cost and the licence question
The last push was on 2026-08-02, the same day v1.5.0 was released, following v1.4.7 on 2026-07-06 and v1.4.6 on 2026-06-08. That is a roughly monthly release cadence through the summer, and the repository is not archived. The version is read dynamically from codex_session_patcher.__version__, so the package version and the release tag are meant to agree.
Upgrade cost splits by half. The CLI has no runtime dependencies, so updating it is a clone or a reinstall with no resolution step. The Web UI pulls FastAPI, uvicorn, pydantic, websockets and httpx, and the start script rebuilds the frontend only when dependencies or build output are stale, which keeps routine starts cheap but means a frontend rebuild needs Node.js 20.19+ or 22.12+. The CTF prompt files ship as package data under codex_session_patcher/ctf_config/prompts/*.md, so upgrading the package can change the prompts that are already installed in your Codex profile or workspaces. The README states that updating a managed prompt creates a backup first, but you should still re-run codex-patcher --ctf-status after an upgrade to see what state each platform is in.
On licensing: pyproject.toml and the README both say MIT, and the README badge links to a LICENSE file. The repository's top-level listing does not include one. I am not giving legal advice; the point is that you cannot rely on a licence you have not seen, and if you plan to redistribute or vendor this code, resolving that discrepancy is a step you take before, not after.
Editorial conclusion
Adopt it if you run Codex CLI, Claude Code or OpenCode for CTF or authorised security testing and you keep hitting refusals that break resume, and if you are comfortable with a tool that rewrites your own session JSONL or SQLite files. Do not adopt it if you need a documented licence file, a supported upstream contract, or a way to undo a prompt injection you no longer track. Before relying on it, verify three things in your own checkout: that the LICENSE file the README badge points to actually exists in the repository root, that the CLI reports the right CTF state with codex-patcher --ctf-status after you install and then uninstall a profile, and that a --dry-run --show-content pass over one real session shows the replacements you expect before you let it write.
Frequently asked questions
What is codex-session-patcher used for?
It cleans refusal responses out of AI coding tool session files so a session can be resumed, and it can inject CTF or pentest context into Codex, Claude Code or OpenCode configuration. The README frames both features around security testing, CTF competitions and penetration testing.
How do I check a Codex session before the patcher changes it?
Run the CLI in preview mode with codex-patcher --dry-run --show-content --latest, which reports what would change and shows the modified content without writing to the file. Backups are created before cleaning unless you pass --no-backup.
Is codex-session-patcher safe to run on my session files?
The README says cleaning creates a backup first and supports restoring to an earlier version, and that the Web UI only accepts loopback clients and local page origins. It also says reasoning and thinking content is erased by default, so the --keep-reasoning flag is what limits changes to refusal replacement only.
Which AI coding tools does codex-session-patcher support?
Codex CLI, Claude Code and OpenCode. Codex sessions are JSONL and support both profile and global injection; Claude Code uses JSONL with a dedicated workspace at ~/.claude-ctf-workspace; OpenCode stores sessions in SQLite and uses ~/.opencode-ctf-workspace.
What licence is codex-session-patcher released under?
pyproject.toml declares license = {text = "MIT"} and the README shows an MIT badge, but the repository's top-level file listing does not include a LICENSE file. Confirm the file exists before relying on that licence.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/ryfinez-codex-session-patcher)