From e50097e7c9f2142db7f47bf9998e39dcd0eb8e88 Mon Sep 17 00:00:00 2001 From: Daniel Sateler Date: Tue, 23 Jun 2026 00:49:05 -0400 Subject: [PATCH 1/2] docs(codex): teleport-for-Codex design note (NOT implemented, blocked) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Plan only — no code. Codex teleport needs the real session format + resume semantics confirmed against an actual session before implementing; shipping inferred-format code would repeat the Claude encoding bug. Blocked now: no codex on the mini, MacBook powered off (no real session to package, no env to resume on). Documents the grounding step + implementation sketch for the next session. Co-Authored-By: Claude Opus 4.8 Claude-Session: https://claude.ai/code/session_01Y1zMeQM7WsMbT5eK8eR8mH --- docs/teleport-codex.md | 72 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 72 insertions(+) create mode 100644 docs/teleport-codex.md diff --git a/docs/teleport-codex.md b/docs/teleport-codex.md new file mode 100644 index 0000000..394ffe0 --- /dev/null +++ b/docs/teleport-codex.md @@ -0,0 +1,72 @@ +# Teleport for Codex — design note + +> **Status: NOT IMPLEMENTED. Blocked on validation.** This is a plan, not working +> code. Do not ship an implementation built only from the notes below — the Codex +> session format and resume semantics must be confirmed against a **real session** +> first. (We just learned this the hard way: Claude Code's project-dir encoding +> wasn't what anyone would have guessed, and a 33-check suite that assumed the rule +> stayed green while real resume broke.) + +## Goal + +`dotai tp` already moves a live **Claude Code** conversation between machines. Do the +same for **Codex** (OpenAI's CLI): package the current Codex session + repo state, +ship it, and resume it on the target. + +The engine is mostly harness-agnostic already — `teleport.sh send` takes +`--harness`, and today it prints a friendly "Codex isn't supported yet". The repo +handling (URL match → clone or worktree, uncommitted patch, untracked, local-commit +bundle) is reusable as-is. What's Codex-specific is **finding, packaging, placing, +and resuming the session transcript**. + +## Why this is blocked right now + +To build and validate this we need, at minimum: +1. A machine with `codex` installed to **generate a real session** (inspect the + actual on-disk format), and +2. A reachable Codex environment on the **target** to confirm resume works. + +At the time of writing: `codex` is **not installed on the mini**, and the MacBook +(where Codex is used) was **powered off**. So there is neither a real session to +package nor an environment to resume on. Inferring the format and shipping code +would be guessing — exactly the failure mode we just fixed for Claude. + +## What to confirm first (the grounding step) + +On a machine with Codex: + +```bash +command -v codex && codex --version +# run one throwaway session, then inspect what it wrote: +find ~/.codex/sessions -name '*.jsonl' | tail -1 | xargs -I{} sh -c 'echo {}; head -5 {}' +``` + +Answer these against the **real file**, do not assume: +- **Where** sessions live (expected `~/.codex/sessions/YYYY/MM/DD/rollout-*.jsonl`, to confirm). +- The **line/event schema**, and **where the cwd / working dir lives** (the field name). +- How a session is **identified** (a UUID? the filename?) and how it's **resumed** + (`codex resume ` / `--last` / a flag — confirm the exact command). +- Whether the target needs any **index/registry** updated (like Claude's + `~/.claude/projects//` dir name) for `codex resume` to find a + dropped-in transcript — this is precisely what bit us on the Claude side. + +## Implementation sketch (once grounded) + +1. **send:** with `--harness codex`, find the latest (or `--session`) rollout file + for the current cwd, stage it alongside the repo payload (reuse existing repo + bundling untouched), ship via the existing rsync path. +2. **receive:** land the repo (existing clone/worktree logic, no change), then place + the rollout file where Codex expects it on the target — rewriting any cwd field + the way `cmd_receive` already rewrites Claude's, and creating whatever + index/dir Codex needs. Print the real `codex resume …` command. +3. **skill:** the `teleport` skill currently asserts Claude Code via + `$CLAUDE_CODE_SESSION_ID`. Add a Codex detection path. +4. **tests:** add a Codex scenario to the Docker suite using a **captured real + rollout fixture** — and assert placement against where `codex resume` actually + looks, not against our own placement function (the non-circular lesson). + +## Out of scope for this note + +No code is included on purpose. The next session should start from the grounding +step above on a Codex-capable machine, then implement + validate end-to-end (a real +laptop→mini Codex teleport that actually resumes), the same bar Claude teleport met. From d801110ec4effb7e9cc60498e75cc530937adb29 Mon Sep 17 00:00:00 2001 From: Daniel Sateler Date: Tue, 23 Jun 2026 14:26:48 -0400 Subject: [PATCH 2/2] docs(codex): grounded the Codex session format (ready to implement) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Inspected real Codex rollouts on the MacBook. Confirmed: sessions at ~/.codex/sessions/YYYY/MM/DD/rollout--.jsonl; lines are {timestamp,type,payload}; cwd is in the first line's payload.cwd (single place); session keyed by UUID in the filename (no encoded-cwd dir → no path-encoding trap). One open question for impl: how `codex resume` locates a session. Test plan: codex+auth on the mini (copy auth.json), real e2e resume. Start here next. Co-Authored-By: Claude Opus 4.8 Claude-Session: https://claude.ai/code/session_01Y1zMeQM7WsMbT5eK8eR8mH --- docs/teleport-codex.md | 117 ++++++++++++++++++----------------------- 1 file changed, 51 insertions(+), 66 deletions(-) diff --git a/docs/teleport-codex.md b/docs/teleport-codex.md index 394ffe0..3ce4ecf 100644 --- a/docs/teleport-codex.md +++ b/docs/teleport-codex.md @@ -1,72 +1,57 @@ # Teleport for Codex — design note -> **Status: NOT IMPLEMENTED. Blocked on validation.** This is a plan, not working -> code. Do not ship an implementation built only from the notes below — the Codex -> session format and resume semantics must be confirmed against a **real session** -> first. (We just learned this the hard way: Claude Code's project-dir encoding -> wasn't what anyone would have guessed, and a 33-check suite that assumed the rule -> stayed green while real resume broke.) +> **Status: GROUNDED, ready to implement (2026-06-23).** The session format was +> confirmed against real Codex sessions on the MacBook. Implementation + a real +> end-to-end test are the next-session task. The bar is the same Claude teleport +> met: a real laptop→mini run that actually resumes. ## Goal `dotai tp` already moves a live **Claude Code** conversation between machines. Do the -same for **Codex** (OpenAI's CLI): package the current Codex session + repo state, -ship it, and resume it on the target. - -The engine is mostly harness-agnostic already — `teleport.sh send` takes -`--harness`, and today it prints a friendly "Codex isn't supported yet". The repo -handling (URL match → clone or worktree, uncommitted patch, untracked, local-commit -bundle) is reusable as-is. What's Codex-specific is **finding, packaging, placing, -and resuming the session transcript**. - -## Why this is blocked right now - -To build and validate this we need, at minimum: -1. A machine with `codex` installed to **generate a real session** (inspect the - actual on-disk format), and -2. A reachable Codex environment on the **target** to confirm resume works. - -At the time of writing: `codex` is **not installed on the mini**, and the MacBook -(where Codex is used) was **powered off**. So there is neither a real session to -package nor an environment to resume on. Inferring the format and shipping code -would be guessing — exactly the failure mode we just fixed for Claude. - -## What to confirm first (the grounding step) - -On a machine with Codex: - -```bash -command -v codex && codex --version -# run one throwaway session, then inspect what it wrote: -find ~/.codex/sessions -name '*.jsonl' | tail -1 | xargs -I{} sh -c 'echo {}; head -5 {}' -``` - -Answer these against the **real file**, do not assume: -- **Where** sessions live (expected `~/.codex/sessions/YYYY/MM/DD/rollout-*.jsonl`, to confirm). -- The **line/event schema**, and **where the cwd / working dir lives** (the field name). -- How a session is **identified** (a UUID? the filename?) and how it's **resumed** - (`codex resume ` / `--last` / a flag — confirm the exact command). -- Whether the target needs any **index/registry** updated (like Claude's - `~/.claude/projects//` dir name) for `codex resume` to find a - dropped-in transcript — this is precisely what bit us on the Claude side. - -## Implementation sketch (once grounded) - -1. **send:** with `--harness codex`, find the latest (or `--session`) rollout file - for the current cwd, stage it alongside the repo payload (reuse existing repo - bundling untouched), ship via the existing rsync path. -2. **receive:** land the repo (existing clone/worktree logic, no change), then place - the rollout file where Codex expects it on the target — rewriting any cwd field - the way `cmd_receive` already rewrites Claude's, and creating whatever - index/dir Codex needs. Print the real `codex resume …` command. -3. **skill:** the `teleport` skill currently asserts Claude Code via - `$CLAUDE_CODE_SESSION_ID`. Add a Codex detection path. -4. **tests:** add a Codex scenario to the Docker suite using a **captured real - rollout fixture** — and assert placement against where `codex resume` actually - looks, not against our own placement function (the non-circular lesson). - -## Out of scope for this note - -No code is included on purpose. The next session should start from the grounding -step above on a Codex-capable machine, then implement + validate end-to-end (a real -laptop→mini Codex teleport that actually resumes), the same bar Claude teleport met. +same for **Codex** (OpenAI's CLI). The repo handling (URL match → clone/worktree, +uncommitted patch, untracked, local-commit bundle, `--into`) is reused **unchanged**; +only finding / packaging / placing / resuming the session is Codex-specific. + +## Confirmed format (real sessions, 2026-06-23) + +- **Rollouts:** `~/.codex/sessions/YYYY/MM/DD/rollout--.jsonl` +- Each line is `{ "timestamp", "type", "payload" }`. Types seen: `session_meta` + (first line), then `event_msg` / `response_item` (the turns). +- **The cwd lives in ONE place:** the first line's `payload.cwd` + (e.g. `/Users/sat/code/Pump Up`). `payload.id` == the UUID == the filename's uuid. +- Contrast with Claude: there is **no per-line cwd**, and the session is keyed by + **UUID in the filename**, not by an encoded-cwd project dir. So there's no + path-encoding trap like the one that bit Claude — likely simpler. + +## The one open question (confirm FIRST when implementing) + +How does `codex resume` locate a session — by UUID globally (scans +`~/.codex/sessions/`) or tied to the cwd? This decides whether dropping the rollout +file in place is enough, or whether an index/registry must be touched. Confirm with +`codex resume --help` (needs `node` on PATH — the bun shim failed over headless SSH; +run it in a login shell or via `/opt/homebrew/bin/codex`). + +## Implementation sketch + +1. **send** (`--harness codex`): find the rollout for the current cwd (newest, or + `--session `), stage it with the existing repo payload, ship. +2. **receive**: place the rollout under `~/.codex/sessions/YYYY/MM/DD/` on the + target, rewrite **only** `payload.cwd` on the first line to the worktree path, + then print the real `codex resume ` command. Reuse clone/worktree as-is. +3. **skill**: add a Codex detection path (today it asserts `$CLAUDE_CODE_SESSION_ID`). +4. **tests**: add a Codex scenario using a captured real rollout fixture; assert + placement against where `codex resume` actually looks — **not** against our own + placement function (the non-circular lesson from the Claude encoding bug). + +## Test plan (real, end-to-end) + +- **codex + auth on the mini:** install codex on the mini and **copy + `~/.codex/auth.json` from the MacBook** (decided 2026-06-23) so resume can run. +- Teleport a throwaway Codex session MacBook→mini with a secret token; run + `codex resume ` on the mini; confirm it resumes carrying the token. Same bar + Claude teleport met. + +## Where to start next session + +Grounding is done (format, cwd location, session id, rollout path). Pending: the +resume-lookup mechanism (above), then implement + validate end-to-end. Start here.