codex-rescue 0.1.0a1__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- codex_rescue-0.1.0a1/CHANGELOG.md +27 -0
- codex_rescue-0.1.0a1/LICENSE +21 -0
- codex_rescue-0.1.0a1/MANIFEST.in +21 -0
- codex_rescue-0.1.0a1/PKG-INFO +200 -0
- codex_rescue-0.1.0a1/README.md +175 -0
- codex_rescue-0.1.0a1/pyproject.toml +42 -0
- codex_rescue-0.1.0a1/setup.cfg +4 -0
- codex_rescue-0.1.0a1/src/codex_rescue/__init__.py +3 -0
- codex_rescue-0.1.0a1/src/codex_rescue/artifacts.py +51 -0
- codex_rescue-0.1.0a1/src/codex_rescue/cli.py +178 -0
- codex_rescue-0.1.0a1/src/codex_rescue/discovery.py +473 -0
- codex_rescue-0.1.0a1/src/codex_rescue/doctor.py +67 -0
- codex_rescue-0.1.0a1/src/codex_rescue/fixtures.py +163 -0
- codex_rescue-0.1.0a1/src/codex_rescue/gitstate.py +132 -0
- codex_rescue-0.1.0a1/src/codex_rescue/harness.py +75 -0
- codex_rescue-0.1.0a1/src/codex_rescue/hooks.py +125 -0
- codex_rescue-0.1.0a1/src/codex_rescue/journal.py +83 -0
- codex_rescue-0.1.0a1/src/codex_rescue/reconstruct.py +260 -0
- codex_rescue-0.1.0a1/src/codex_rescue/salvage.py +90 -0
- codex_rescue-0.1.0a1/src/codex_rescue/transcript.py +216 -0
- codex_rescue-0.1.0a1/src/codex_rescue/verify.py +162 -0
- codex_rescue-0.1.0a1/src/codex_rescue.egg-info/PKG-INFO +200 -0
- codex_rescue-0.1.0a1/src/codex_rescue.egg-info/SOURCES.txt +24 -0
- codex_rescue-0.1.0a1/src/codex_rescue.egg-info/dependency_links.txt +1 -0
- codex_rescue-0.1.0a1/src/codex_rescue.egg-info/entry_points.txt +2 -0
- codex_rescue-0.1.0a1/src/codex_rescue.egg-info/top_level.txt +1 -0
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to Codex Rescue will be documented in this file.
|
|
4
|
+
|
|
5
|
+
## v0.1.0-alpha
|
|
6
|
+
|
|
7
|
+
Initial experimental alpha release.
|
|
8
|
+
|
|
9
|
+
### Included
|
|
10
|
+
|
|
11
|
+
- Recent Codex session discovery (`sessions` command)
|
|
12
|
+
- Interrupted and damaged session diagnosis (`doctor` command)
|
|
13
|
+
- Immutable evidence-backed recovery salvage (`salvage` command)
|
|
14
|
+
- Git repository state verification (`verify` command)
|
|
15
|
+
- Confidence-labeled recovery handoff (VERIFIED / RECONSTRUCTED / UNKNOWN)
|
|
16
|
+
- Sanitized synthetic regression corpus (5 fixture types)
|
|
17
|
+
- Sanitized real-origin regression corpus (3 cases)
|
|
18
|
+
- Crash-safe append-only journal
|
|
19
|
+
- Bounded recovery brief generation
|
|
20
|
+
- Secret redaction in handoff artifacts
|
|
21
|
+
|
|
22
|
+
### Known limitations
|
|
23
|
+
|
|
24
|
+
- Broad real compaction recovery not yet validated
|
|
25
|
+
- Interactive continuation depends on terminal/TTY environment
|
|
26
|
+
- Previous Codex version recovery coverage is limited
|
|
27
|
+
- Not every arbitrary corruption type is supported
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 shleder
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
include LICENSE
|
|
2
|
+
include README.md
|
|
3
|
+
include CHANGELOG.md
|
|
4
|
+
include pyproject.toml
|
|
5
|
+
|
|
6
|
+
prune fixtures
|
|
7
|
+
prune real-corpus
|
|
8
|
+
prune tests
|
|
9
|
+
prune .github
|
|
10
|
+
prune .validation-output
|
|
11
|
+
prune .pypi-release-venv
|
|
12
|
+
prune .release-venv
|
|
13
|
+
prune .validation-baseline
|
|
14
|
+
prune .validation-runtime
|
|
15
|
+
prune .cli-smoke
|
|
16
|
+
prune .codex-rescue-poc
|
|
17
|
+
prune .codex-rescue-final
|
|
18
|
+
prune .codex-rescue-final-3
|
|
19
|
+
prune .review-output
|
|
20
|
+
|
|
21
|
+
global-exclude *.pyc *.pyo __pycache__
|
|
@@ -0,0 +1,200 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: codex-rescue
|
|
3
|
+
Version: 0.1.0a1
|
|
4
|
+
Summary: Local-first recovery tool for interrupted and damaged OpenAI Codex sessions
|
|
5
|
+
Author: shleder
|
|
6
|
+
License: MIT
|
|
7
|
+
Project-URL: Homepage, https://github.com/shleder/codex-rescue
|
|
8
|
+
Project-URL: Repository, https://github.com/shleder/codex-rescue
|
|
9
|
+
Project-URL: Issues, https://github.com/shleder/codex-rescue/issues
|
|
10
|
+
Classifier: Development Status :: 3 - Alpha
|
|
11
|
+
Classifier: Environment :: Console
|
|
12
|
+
Classifier: Intended Audience :: Developers
|
|
13
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
14
|
+
Classifier: Operating System :: OS Independent
|
|
15
|
+
Classifier: Programming Language :: Python :: 3
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
19
|
+
Classifier: Topic :: Software Development :: Quality Assurance
|
|
20
|
+
Classifier: Topic :: System :: Recovery Tools
|
|
21
|
+
Requires-Python: >=3.11
|
|
22
|
+
Description-Content-Type: text/markdown
|
|
23
|
+
License-File: LICENSE
|
|
24
|
+
Dynamic: license-file
|
|
25
|
+
|
|
26
|
+
<p align="center">
|
|
27
|
+
<a href="https://github.com/shleder/codex-rescue/actions/workflows/ci.yml"><img src="https://img.shields.io/github/actions/workflow/status/shleder/codex-rescue/ci.yml?branch=main&style=flat-square&label=CI&logo=github" alt="CI Status"></a>
|
|
28
|
+
<a href="https://github.com/shleder/codex-rescue/releases/tag/v0.1.0-alpha"><img src="https://img.shields.io/badge/version-v0.1.0--alpha-3fb950?style=flat-square" alt="Version"></a>
|
|
29
|
+
<a href="LICENSE"><img src="https://img.shields.io/badge/license-MIT-blue?style=flat-square" alt="License"></a>
|
|
30
|
+
<a href="https://www.python.org/"><img src="https://img.shields.io/badge/python-3.11%20%7C%203.12%20%7C%203.13-1f6feb?style=flat-square&logo=python&logoColor=white" alt="Python"></a>
|
|
31
|
+
<a href="#privacy"><img src="https://img.shields.io/badge/privacy-100%25%20local--first-238636?style=flat-square" alt="Privacy"></a>
|
|
32
|
+
</p>
|
|
33
|
+
|
|
34
|
+
---
|
|
35
|
+
|
|
36
|
+
## Overview
|
|
37
|
+
|
|
38
|
+
When **OpenAI Codex CLI** can't resume safely, **Rescue** tells you what actually happened and gets you back to work.
|
|
39
|
+
|
|
40
|
+
Codex Rescue is a local-first fsck and crash-recovery tool for OpenAI Codex sessions. It diagnoses interrupted or damaged sessions, verifies repository working tree state, and reconstructs a bounded evidence-backed continuation **without modifying the original Codex rollout**.
|
|
41
|
+
|
|
42
|
+
> [!WARNING]
|
|
43
|
+
> **Codex Rescue is experimental alpha software.**
|
|
44
|
+
> It is an evidence-gathering release designed to collect real failure cases.
|
|
45
|
+
> See [Alpha Limitations](#alpha-limitations) below.
|
|
46
|
+
|
|
47
|
+
---
|
|
48
|
+
|
|
49
|
+
## Core Commands
|
|
50
|
+
|
|
51
|
+
Rescue provides four narrow, read-only diagnostic and recovery entry points:
|
|
52
|
+
|
|
53
|
+
| Command | Usage | Description |
|
|
54
|
+
|---|---|---|
|
|
55
|
+
| **`sessions`** | `codex-rescue sessions` | Discover and list recent local Codex rollout sessions |
|
|
56
|
+
| **`doctor`** | `codex-rescue doctor --latest` | Inspect and diagnose a damaged session (**read-only**) |
|
|
57
|
+
| **`salvage`** | `codex-rescue salvage --latest --fork` | Create an immutable, content-addressed recovery handoff |
|
|
58
|
+
| **`verify`** | `codex-rescue verify <rescue-id>` | Detect repository divergence before executing continuation |
|
|
59
|
+
|
|
60
|
+
---
|
|
61
|
+
|
|
62
|
+
## Confidence Model
|
|
63
|
+
|
|
64
|
+
Rescue reconstructs facts with explicit, uncompromised confidence levels. Model prose alone is **never** accepted as source of truth.
|
|
65
|
+
|
|
66
|
+
| Level | Badge | Meaning & Source of Truth |
|
|
67
|
+
|---|---|---|
|
|
68
|
+
| **VERIFIED** | `VERIFIED` | Directly proven by durable evidence: Git HEAD SHA, working tree diff, tool execution exit code, or durable output record |
|
|
69
|
+
| **RECONSTRUCTED** | `RECONSTRUCTED` | Strongly inferred from available evidence with no unresolved contradictions |
|
|
70
|
+
| **UNKNOWN** | `UNKNOWN` | Cannot be proven safely. **UNKNOWN is deliberate.** Rescue refuses to guess when execution state is uncertain |
|
|
71
|
+
|
|
72
|
+
> [!NOTE]
|
|
73
|
+
> **Safety Invariants:**
|
|
74
|
+
> 1. Source rollouts are **immutable** (`doctor`, `salvage`, and `verify` never write to the original `.jsonl` file).
|
|
75
|
+
> 2. **No automatic replay** — an action whose execution status is `UNKNOWN` is never automatically re-executed.
|
|
76
|
+
|
|
77
|
+
---
|
|
78
|
+
|
|
79
|
+
## Quick Start
|
|
80
|
+
|
|
81
|
+
### 1. Installation
|
|
82
|
+
|
|
83
|
+
Install directly from the GitHub release tag:
|
|
84
|
+
|
|
85
|
+
```bash
|
|
86
|
+
# Recommended global installation via pipx
|
|
87
|
+
pipx install git+https://github.com/shleder/codex-rescue.git@v0.1.0-alpha
|
|
88
|
+
|
|
89
|
+
# Or via standard pip
|
|
90
|
+
pip install git+https://github.com/shleder/codex-rescue.git@v0.1.0-alpha
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
### 2. Workflow Example
|
|
94
|
+
|
|
95
|
+
```bash
|
|
96
|
+
# 1. Discover recent Codex sessions
|
|
97
|
+
codex-rescue sessions
|
|
98
|
+
|
|
99
|
+
# 2. Diagnose the latest session
|
|
100
|
+
codex-rescue doctor --latest
|
|
101
|
+
|
|
102
|
+
# 3. Generate an immutable recovery handoff
|
|
103
|
+
codex-rescue salvage --latest --fork
|
|
104
|
+
|
|
105
|
+
# 4. Verify repository state before continuing
|
|
106
|
+
codex-rescue verify <rescue-id>
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
### Sample Output
|
|
110
|
+
|
|
111
|
+
```text
|
|
112
|
+
$ codex-rescue doctor --latest
|
|
113
|
+
|
|
114
|
+
Doctor: UNFINISHED_TOOL_CALL
|
|
115
|
+
Findings: UNFINISHED_TOOL_CALL
|
|
116
|
+
Repository: /path/to/repo (HEAD a6cfe48)
|
|
117
|
+
|
|
118
|
+
$ codex-rescue salvage --latest --fork
|
|
119
|
+
|
|
120
|
+
Salvage: 8f8f4e822c9ce353ed584c5f
|
|
121
|
+
Original session untouched: yes
|
|
122
|
+
Rescue directory: .codex-rescue/rescues/8f8f4e822c9ce353ed584c5f
|
|
123
|
+
|
|
124
|
+
$ codex-rescue verify 8f8f4e822c9ce353ed584c5f
|
|
125
|
+
|
|
126
|
+
Verify: REVIEW_REQUIRED
|
|
127
|
+
Review: unfinished action requires inspection before replay
|
|
128
|
+
Review: handoff contains load-bearing unknowns
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
---
|
|
132
|
+
|
|
133
|
+
## Proven Compatibility & Evidence
|
|
134
|
+
|
|
135
|
+
| Version / Scope | Status | Proven Real-World Evidence |
|
|
136
|
+
|---|---|---|
|
|
137
|
+
| **Codex CLI 0.147.0** | **Validated** | Genuine interrupted session diagnosed (`UNFINISHED_TOOL_CALL`), source rollout preserved, repo state verified |
|
|
138
|
+
| **Codex CLI 0.146.1** | **Smoke-tested** | Isolated authentication & basic rollout parser validation |
|
|
139
|
+
| **Codex 0.145.0-alpha.18** | **Observed** | Legacy envelope format compatibility observed |
|
|
140
|
+
| **Synthetic Fixtures** | **5/5 PASS** | `kill_apply_patch`, `kill_shell_before_result`, `lost_tail_after_compaction`, `malformed_jsonl`, `oversized_payload` |
|
|
141
|
+
|
|
142
|
+
---
|
|
143
|
+
|
|
144
|
+
## Alpha Limitations
|
|
145
|
+
|
|
146
|
+
> [!IMPORTANT]
|
|
147
|
+
> The following limitations are documented honestly. Do not claim recovery guarantees that have not been validated.
|
|
148
|
+
|
|
149
|
+
- **Compaction recovery** — broad real compaction-related recovery is not yet validated; only synthetic fixtures exist.
|
|
150
|
+
- **Interactive continuation** — automatic fresh continuation depends on terminal/TTY environment (Windows ConPTY limitations noted).
|
|
151
|
+
- **Previous versions** — validation is focused on Codex CLI 0.147.0; earlier versions are smoke-tested or observed.
|
|
152
|
+
- **Side-effect replay** — Rescue does not automatically replay unknown side effects; it reports them as `REVIEW_REQUIRED`.
|
|
153
|
+
|
|
154
|
+
---
|
|
155
|
+
|
|
156
|
+
## Privacy & Security
|
|
157
|
+
|
|
158
|
+
- **100% Local-First** — zero telemetry, zero analytics, zero network uploads, zero cloud dependencies.
|
|
159
|
+
- **No private DB mutation** — Rescue never modifies `state_*.sqlite` or internal Codex databases.
|
|
160
|
+
- **Secret Redaction** — built-in secret redaction automatically filters common API key patterns (`sk-*`, `ghp_*`, `AKIA*`, Bearer tokens).
|
|
161
|
+
- **Sanitization Notice** — Codex rollouts can contain secrets; sanitize all session files before attaching to public issues.
|
|
162
|
+
|
|
163
|
+
---
|
|
164
|
+
|
|
165
|
+
## Development & Verification
|
|
166
|
+
|
|
167
|
+
```bash
|
|
168
|
+
# Clone the repository
|
|
169
|
+
git clone https://github.com/shleder/codex-rescue.git
|
|
170
|
+
cd codex-rescue
|
|
171
|
+
|
|
172
|
+
# Install in editable mode
|
|
173
|
+
pip install -e .
|
|
174
|
+
|
|
175
|
+
# Run full unit test suite (43 passed, 1 skipped)
|
|
176
|
+
python -m unittest discover -s tests -v
|
|
177
|
+
|
|
178
|
+
# Run synthetic fixture harness (5/5 PASS)
|
|
179
|
+
python -m codex_rescue.harness fixtures --output .validation-output/test
|
|
180
|
+
|
|
181
|
+
# Run deterministic alpha demo
|
|
182
|
+
python scripts/demo_alpha.py
|
|
183
|
+
```
|
|
184
|
+
|
|
185
|
+
---
|
|
186
|
+
|
|
187
|
+
## Submit a Recovery Report
|
|
188
|
+
|
|
189
|
+
The primary goal of this public alpha is collecting real broken Codex sessions to expand our sanitized regression corpus.
|
|
190
|
+
|
|
191
|
+
[**Open a Recovery Report →**](https://github.com/shleder/codex-rescue/issues/new?template=recovery-report.yml)
|
|
192
|
+
|
|
193
|
+
> [!CAUTION]
|
|
194
|
+
> **Do NOT upload raw rollout files containing secrets or credentials.** Always sanitize session data before attaching.
|
|
195
|
+
|
|
196
|
+
---
|
|
197
|
+
|
|
198
|
+
## License
|
|
199
|
+
|
|
200
|
+
Distributed under the [MIT License](LICENSE). Copyright (c) 2026 shleder.
|
|
@@ -0,0 +1,175 @@
|
|
|
1
|
+
<p align="center">
|
|
2
|
+
<a href="https://github.com/shleder/codex-rescue/actions/workflows/ci.yml"><img src="https://img.shields.io/github/actions/workflow/status/shleder/codex-rescue/ci.yml?branch=main&style=flat-square&label=CI&logo=github" alt="CI Status"></a>
|
|
3
|
+
<a href="https://github.com/shleder/codex-rescue/releases/tag/v0.1.0-alpha"><img src="https://img.shields.io/badge/version-v0.1.0--alpha-3fb950?style=flat-square" alt="Version"></a>
|
|
4
|
+
<a href="LICENSE"><img src="https://img.shields.io/badge/license-MIT-blue?style=flat-square" alt="License"></a>
|
|
5
|
+
<a href="https://www.python.org/"><img src="https://img.shields.io/badge/python-3.11%20%7C%203.12%20%7C%203.13-1f6feb?style=flat-square&logo=python&logoColor=white" alt="Python"></a>
|
|
6
|
+
<a href="#privacy"><img src="https://img.shields.io/badge/privacy-100%25%20local--first-238636?style=flat-square" alt="Privacy"></a>
|
|
7
|
+
</p>
|
|
8
|
+
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
## Overview
|
|
12
|
+
|
|
13
|
+
When **OpenAI Codex CLI** can't resume safely, **Rescue** tells you what actually happened and gets you back to work.
|
|
14
|
+
|
|
15
|
+
Codex Rescue is a local-first fsck and crash-recovery tool for OpenAI Codex sessions. It diagnoses interrupted or damaged sessions, verifies repository working tree state, and reconstructs a bounded evidence-backed continuation **without modifying the original Codex rollout**.
|
|
16
|
+
|
|
17
|
+
> [!WARNING]
|
|
18
|
+
> **Codex Rescue is experimental alpha software.**
|
|
19
|
+
> It is an evidence-gathering release designed to collect real failure cases.
|
|
20
|
+
> See [Alpha Limitations](#alpha-limitations) below.
|
|
21
|
+
|
|
22
|
+
---
|
|
23
|
+
|
|
24
|
+
## Core Commands
|
|
25
|
+
|
|
26
|
+
Rescue provides four narrow, read-only diagnostic and recovery entry points:
|
|
27
|
+
|
|
28
|
+
| Command | Usage | Description |
|
|
29
|
+
|---|---|---|
|
|
30
|
+
| **`sessions`** | `codex-rescue sessions` | Discover and list recent local Codex rollout sessions |
|
|
31
|
+
| **`doctor`** | `codex-rescue doctor --latest` | Inspect and diagnose a damaged session (**read-only**) |
|
|
32
|
+
| **`salvage`** | `codex-rescue salvage --latest --fork` | Create an immutable, content-addressed recovery handoff |
|
|
33
|
+
| **`verify`** | `codex-rescue verify <rescue-id>` | Detect repository divergence before executing continuation |
|
|
34
|
+
|
|
35
|
+
---
|
|
36
|
+
|
|
37
|
+
## Confidence Model
|
|
38
|
+
|
|
39
|
+
Rescue reconstructs facts with explicit, uncompromised confidence levels. Model prose alone is **never** accepted as source of truth.
|
|
40
|
+
|
|
41
|
+
| Level | Badge | Meaning & Source of Truth |
|
|
42
|
+
|---|---|---|
|
|
43
|
+
| **VERIFIED** | `VERIFIED` | Directly proven by durable evidence: Git HEAD SHA, working tree diff, tool execution exit code, or durable output record |
|
|
44
|
+
| **RECONSTRUCTED** | `RECONSTRUCTED` | Strongly inferred from available evidence with no unresolved contradictions |
|
|
45
|
+
| **UNKNOWN** | `UNKNOWN` | Cannot be proven safely. **UNKNOWN is deliberate.** Rescue refuses to guess when execution state is uncertain |
|
|
46
|
+
|
|
47
|
+
> [!NOTE]
|
|
48
|
+
> **Safety Invariants:**
|
|
49
|
+
> 1. Source rollouts are **immutable** (`doctor`, `salvage`, and `verify` never write to the original `.jsonl` file).
|
|
50
|
+
> 2. **No automatic replay** — an action whose execution status is `UNKNOWN` is never automatically re-executed.
|
|
51
|
+
|
|
52
|
+
---
|
|
53
|
+
|
|
54
|
+
## Quick Start
|
|
55
|
+
|
|
56
|
+
### 1. Installation
|
|
57
|
+
|
|
58
|
+
Install directly from the GitHub release tag:
|
|
59
|
+
|
|
60
|
+
```bash
|
|
61
|
+
# Recommended global installation via pipx
|
|
62
|
+
pipx install git+https://github.com/shleder/codex-rescue.git@v0.1.0-alpha
|
|
63
|
+
|
|
64
|
+
# Or via standard pip
|
|
65
|
+
pip install git+https://github.com/shleder/codex-rescue.git@v0.1.0-alpha
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
### 2. Workflow Example
|
|
69
|
+
|
|
70
|
+
```bash
|
|
71
|
+
# 1. Discover recent Codex sessions
|
|
72
|
+
codex-rescue sessions
|
|
73
|
+
|
|
74
|
+
# 2. Diagnose the latest session
|
|
75
|
+
codex-rescue doctor --latest
|
|
76
|
+
|
|
77
|
+
# 3. Generate an immutable recovery handoff
|
|
78
|
+
codex-rescue salvage --latest --fork
|
|
79
|
+
|
|
80
|
+
# 4. Verify repository state before continuing
|
|
81
|
+
codex-rescue verify <rescue-id>
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
### Sample Output
|
|
85
|
+
|
|
86
|
+
```text
|
|
87
|
+
$ codex-rescue doctor --latest
|
|
88
|
+
|
|
89
|
+
Doctor: UNFINISHED_TOOL_CALL
|
|
90
|
+
Findings: UNFINISHED_TOOL_CALL
|
|
91
|
+
Repository: /path/to/repo (HEAD a6cfe48)
|
|
92
|
+
|
|
93
|
+
$ codex-rescue salvage --latest --fork
|
|
94
|
+
|
|
95
|
+
Salvage: 8f8f4e822c9ce353ed584c5f
|
|
96
|
+
Original session untouched: yes
|
|
97
|
+
Rescue directory: .codex-rescue/rescues/8f8f4e822c9ce353ed584c5f
|
|
98
|
+
|
|
99
|
+
$ codex-rescue verify 8f8f4e822c9ce353ed584c5f
|
|
100
|
+
|
|
101
|
+
Verify: REVIEW_REQUIRED
|
|
102
|
+
Review: unfinished action requires inspection before replay
|
|
103
|
+
Review: handoff contains load-bearing unknowns
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
---
|
|
107
|
+
|
|
108
|
+
## Proven Compatibility & Evidence
|
|
109
|
+
|
|
110
|
+
| Version / Scope | Status | Proven Real-World Evidence |
|
|
111
|
+
|---|---|---|
|
|
112
|
+
| **Codex CLI 0.147.0** | **Validated** | Genuine interrupted session diagnosed (`UNFINISHED_TOOL_CALL`), source rollout preserved, repo state verified |
|
|
113
|
+
| **Codex CLI 0.146.1** | **Smoke-tested** | Isolated authentication & basic rollout parser validation |
|
|
114
|
+
| **Codex 0.145.0-alpha.18** | **Observed** | Legacy envelope format compatibility observed |
|
|
115
|
+
| **Synthetic Fixtures** | **5/5 PASS** | `kill_apply_patch`, `kill_shell_before_result`, `lost_tail_after_compaction`, `malformed_jsonl`, `oversized_payload` |
|
|
116
|
+
|
|
117
|
+
---
|
|
118
|
+
|
|
119
|
+
## Alpha Limitations
|
|
120
|
+
|
|
121
|
+
> [!IMPORTANT]
|
|
122
|
+
> The following limitations are documented honestly. Do not claim recovery guarantees that have not been validated.
|
|
123
|
+
|
|
124
|
+
- **Compaction recovery** — broad real compaction-related recovery is not yet validated; only synthetic fixtures exist.
|
|
125
|
+
- **Interactive continuation** — automatic fresh continuation depends on terminal/TTY environment (Windows ConPTY limitations noted).
|
|
126
|
+
- **Previous versions** — validation is focused on Codex CLI 0.147.0; earlier versions are smoke-tested or observed.
|
|
127
|
+
- **Side-effect replay** — Rescue does not automatically replay unknown side effects; it reports them as `REVIEW_REQUIRED`.
|
|
128
|
+
|
|
129
|
+
---
|
|
130
|
+
|
|
131
|
+
## Privacy & Security
|
|
132
|
+
|
|
133
|
+
- **100% Local-First** — zero telemetry, zero analytics, zero network uploads, zero cloud dependencies.
|
|
134
|
+
- **No private DB mutation** — Rescue never modifies `state_*.sqlite` or internal Codex databases.
|
|
135
|
+
- **Secret Redaction** — built-in secret redaction automatically filters common API key patterns (`sk-*`, `ghp_*`, `AKIA*`, Bearer tokens).
|
|
136
|
+
- **Sanitization Notice** — Codex rollouts can contain secrets; sanitize all session files before attaching to public issues.
|
|
137
|
+
|
|
138
|
+
---
|
|
139
|
+
|
|
140
|
+
## Development & Verification
|
|
141
|
+
|
|
142
|
+
```bash
|
|
143
|
+
# Clone the repository
|
|
144
|
+
git clone https://github.com/shleder/codex-rescue.git
|
|
145
|
+
cd codex-rescue
|
|
146
|
+
|
|
147
|
+
# Install in editable mode
|
|
148
|
+
pip install -e .
|
|
149
|
+
|
|
150
|
+
# Run full unit test suite (43 passed, 1 skipped)
|
|
151
|
+
python -m unittest discover -s tests -v
|
|
152
|
+
|
|
153
|
+
# Run synthetic fixture harness (5/5 PASS)
|
|
154
|
+
python -m codex_rescue.harness fixtures --output .validation-output/test
|
|
155
|
+
|
|
156
|
+
# Run deterministic alpha demo
|
|
157
|
+
python scripts/demo_alpha.py
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
---
|
|
161
|
+
|
|
162
|
+
## Submit a Recovery Report
|
|
163
|
+
|
|
164
|
+
The primary goal of this public alpha is collecting real broken Codex sessions to expand our sanitized regression corpus.
|
|
165
|
+
|
|
166
|
+
[**Open a Recovery Report →**](https://github.com/shleder/codex-rescue/issues/new?template=recovery-report.yml)
|
|
167
|
+
|
|
168
|
+
> [!CAUTION]
|
|
169
|
+
> **Do NOT upload raw rollout files containing secrets or credentials.** Always sanitize session data before attaching.
|
|
170
|
+
|
|
171
|
+
---
|
|
172
|
+
|
|
173
|
+
## License
|
|
174
|
+
|
|
175
|
+
Distributed under the [MIT License](LICENSE). Copyright (c) 2026 shleder.
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["setuptools>=68"]
|
|
3
|
+
build-backend = "setuptools.build_meta"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "codex-rescue"
|
|
7
|
+
dynamic = ["version"]
|
|
8
|
+
description = "Local-first recovery tool for interrupted and damaged OpenAI Codex sessions"
|
|
9
|
+
readme = "README.md"
|
|
10
|
+
license = {text = "MIT"}
|
|
11
|
+
requires-python = ">=3.11"
|
|
12
|
+
dependencies = []
|
|
13
|
+
authors = [
|
|
14
|
+
{name = "shleder"},
|
|
15
|
+
]
|
|
16
|
+
classifiers = [
|
|
17
|
+
"Development Status :: 3 - Alpha",
|
|
18
|
+
"Environment :: Console",
|
|
19
|
+
"Intended Audience :: Developers",
|
|
20
|
+
"License :: OSI Approved :: MIT License",
|
|
21
|
+
"Operating System :: OS Independent",
|
|
22
|
+
"Programming Language :: Python :: 3",
|
|
23
|
+
"Programming Language :: Python :: 3.11",
|
|
24
|
+
"Programming Language :: Python :: 3.12",
|
|
25
|
+
"Programming Language :: Python :: 3.13",
|
|
26
|
+
"Topic :: Software Development :: Quality Assurance",
|
|
27
|
+
"Topic :: System :: Recovery Tools",
|
|
28
|
+
]
|
|
29
|
+
|
|
30
|
+
[project.urls]
|
|
31
|
+
Homepage = "https://github.com/shleder/codex-rescue"
|
|
32
|
+
Repository = "https://github.com/shleder/codex-rescue"
|
|
33
|
+
Issues = "https://github.com/shleder/codex-rescue/issues"
|
|
34
|
+
|
|
35
|
+
[project.scripts]
|
|
36
|
+
codex-rescue = "codex_rescue.cli:main"
|
|
37
|
+
|
|
38
|
+
[tool.setuptools.dynamic]
|
|
39
|
+
version = {attr = "codex_rescue.__version__"}
|
|
40
|
+
|
|
41
|
+
[tool.setuptools.packages.find]
|
|
42
|
+
where = ["src"]
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
import hashlib
|
|
4
|
+
import json
|
|
5
|
+
import os
|
|
6
|
+
from pathlib import Path
|
|
7
|
+
from typing import Any
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
def canonical_json(data: Any) -> bytes:
|
|
11
|
+
return json.dumps(data, sort_keys=True, separators=(",", ":"), ensure_ascii=False).encode("utf-8")
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
def atomic_write(path: Path, data: bytes) -> None:
|
|
15
|
+
path.parent.mkdir(parents=True, exist_ok=True)
|
|
16
|
+
temp = path.with_name(f".{path.name}.{os.getpid()}.tmp")
|
|
17
|
+
fd = os.open(temp, os.O_CREAT | os.O_EXCL | os.O_WRONLY, 0o600)
|
|
18
|
+
try:
|
|
19
|
+
offset = 0
|
|
20
|
+
while offset < len(data):
|
|
21
|
+
offset += os.write(fd, data[offset:])
|
|
22
|
+
os.fsync(fd)
|
|
23
|
+
finally:
|
|
24
|
+
os.close(fd)
|
|
25
|
+
os.replace(temp, path)
|
|
26
|
+
if os.name != "nt":
|
|
27
|
+
dir_fd = os.open(path.parent, os.O_RDONLY)
|
|
28
|
+
try:
|
|
29
|
+
os.fsync(dir_fd)
|
|
30
|
+
finally:
|
|
31
|
+
os.close(dir_fd)
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
def write_rescue(root: Path, handoff: dict[str, Any], brief: str, continuation: str) -> tuple[str, Path]:
|
|
35
|
+
handoff_bytes = canonical_json(handoff)
|
|
36
|
+
rescue_id = hashlib.sha256(handoff_bytes).hexdigest()[:24]
|
|
37
|
+
rescue_dir = root / "rescues" / rescue_id
|
|
38
|
+
atomic_write(rescue_dir / "handoff.v1.json", handoff_bytes + b"\n")
|
|
39
|
+
atomic_write(rescue_dir / "RECOVERY_BRIEF.md", brief.encode("utf-8"))
|
|
40
|
+
atomic_write(rescue_dir / "CONTINUATION_PROMPT.md", continuation.encode("utf-8"))
|
|
41
|
+
return rescue_id, rescue_dir
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
def load_handoff(root: Path, rescue_id: str) -> dict[str, Any]:
|
|
45
|
+
path = root / "rescues" / rescue_id / "handoff.v1.json"
|
|
46
|
+
data = json.loads(path.read_text(encoding="utf-8"))
|
|
47
|
+
actual_id = hashlib.sha256(canonical_json(data)).hexdigest()[:24]
|
|
48
|
+
if actual_id != rescue_id:
|
|
49
|
+
raise ValueError(f"handoff hash mismatch: expected {rescue_id}, actual {actual_id}")
|
|
50
|
+
return data
|
|
51
|
+
|