How ai-Memory Ensures Session Continuity Across Different Harnesses

ai-memory ensures session continuity across different harnesses by injecting native session selectors through a unified launch-plan builder, detecting existing user-specified selectors to avoid conflicts, and maintaining a managed-workstream ledger that preserves logical session IDs across harness boundaries.

Switching between AI coding assistants like Claude Code and Codex typically fragments session context, forcing developers to manually rebuild state when changing tools. The ai-memory project eliminates this friction by implementing a hardware abstraction layer that maintains session continuity across different harnesses through runtime argument injection and persistent transcript storage. This architecture allows developers to start a task in Claude Code and seamlessly continue it in Codex—or any other supported harness—without losing conversation history or context.

Unified Launch-Plan Builder for Native Session Injection

The core mechanism for cross-harness continuity resides in crates/ai-memory-workstream/src/harness.rs, specifically the build_launch_plan function. This builder generates native command lines that inject session selectors only when the harness operates in session mode and the user has not supplied their own native selector.

For Claude Code, the builder creates a fresh UUID and appends either --session-id for new sessions or --resume <id> when continuing a linked session (lines 17-27). The implementation checks the harness type and constructs the appropriate argument vector:

// Example: building a launch plan for Claude Code
let plan = build_launch_plan(
    ManagedHarness::Claude,
    None,
    vec![OsString::from("--model"), OsString::from("opus")],
    Some("a1b2c3d4")    // linked session ID supplied by ai-memory
)?;
// `plan.args` now contains "… --resume a1b2c3d4" and `plan.expected_session_id` is Some("a1b2c3d4")

For Codex, the builder handles both interactive and non-interactive modes. When executing commands via exec, it rewrites the argument list to insert resume <id> immediately after the subcommand (lines 28-44). This ensures Codex receives the session directive in the correct position within the argument hierarchy:

// Example: building a launch plan for Codex (non-interactive)
let plan = build_launch_plan(
    ManagedHarness::Codex,
    None,
    vec![OsString::from("exec"), OsString::from("some-script")],
    Some("deadbeef")
)?;
// `plan.args` becomes ["exec","resume","deadbeef","some-script"]

The LaunchPlan struct returned by this function includes an expected_session_id field that records the UUID the harness will use. This allows the CLI—specifically crates/ai-memory-cli/src/commands/run.rs—to correlate later observations with the same logical session, regardless of which native tool generated them.

Guarding Against Conflicting Session Selectors

Before injecting any automatic selectors, ai-memory verifies whether the user has already specified native resume or continue flags. The has_native_session_selector function (lines 85-95 in crates/ai-memory-workstream/src/harness.rs) scans the CLI arguments for harness-specific patterns like --resume, --continue, or --fork.

This detection prevents the automatic selector from overriding explicit user choices and guarantees idempotency when a linked session is requested. If the function returns true, build_launch_plan skips injection entirely:

// Detect whether the user already provided a native selector
if has_native_session_selector(ManagedHarness::Codex, &cli_args) {
    // Do not inject our own `resume` flag – the user is in full control
}

This guard clause ensures that power users retain full control over native session management while casual users benefit from automatic continuity.

Cross-Harness Persistence via the Managed-Workstream Ledger

Session continuity extends beyond individual process lifecycles through the managed-workstream ledger, documented in docs/ARCHITECTURE.md (lines 58-66). This ledger stores portable transcripts that can attach to any later harness invocation, effectively decoupling the logical session from the native tool implementing it.

When ai-memory run executes, it resolves the most recent usable native session—or creates a fresh one—and injects the stored transcript tail into the new harness. The implementation in crates/ai-memory-workstream/src/transcript.rs handles reading and writing these portable records, while crates/ai-memory-store/src/writer.rs persists observations tied to a SessionId in SQLite.

The workflow operates as follows:

  1. CLI Parsing: Arguments are scanned for existing session selectors via has_native_session_selector
  2. Launch Plan Construction: build_launch_plan generates or reuses a UUID and injects the appropriate selector
  3. Native Execution: The harness receives the selector and creates a native session (e.g., Claude Code emits a session-id page)
  4. Event Hooking: Lifecycle events (SessionStart, SessionEnd) are sanitized and written to SQLite, with transcripts appended to the workstream ledger
  5. Cross-Harness Continuation: Later harnesses read the ledger, discover previous native sessions, and resume using stored selectors

Because the logical session ID persists in both the LaunchPlan.expected_session_id field and the workstream ledger, every observation and LLM-driven consolidation links back to the same abstract session, regardless of which native tool the user invokes.

Summary

  • Unified launch-plan builder: The build_launch_plan function in crates/ai-memory-workstream/src/harness.rs injects native-specific session selectors (e.g., --session-id for Claude Code, resume for Codex) while tracking the expected session ID.
  • Conflict prevention: has_native_session_selector guards against overriding user-specified flags, ensuring explicit session choices take precedence over automatic injection.
  • Persistent ledger: The managed-workstream ledger stores portable transcripts in SQLite via crates/ai-memory-store/src/writer.rs, enabling logical sessions to survive across different native harness invocations.
  • Cross-harness compatibility: The architecture supports Claude Code, Codex, OpenCode, and Kiro through harness-specific argument rewriting without requiring changes to the underlying session storage model.

Frequently Asked Questions

How does ai-memory prevent duplicate session IDs when users specify their own resume flags?

The has_native_session_selector function scans incoming CLI arguments for harness-specific resume, continue, or fork flags before injection occurs. If it detects an existing selector, build_launch_plan skips automatic injection, ensuring user-specified session IDs take precedence and preventing duplicate or conflicting identifiers.

What happens to session data when switching from Claude Code to Codex?

Session data persists in the managed-workstream ledger as portable transcripts. When switching harnesses, ai-memory run reads the ledger to discover the most recent native session, generates the appropriate selector for the new harness (e.g., converting a Claude Code session ID to a Codex resume argument), and injects it into the new command line. The logical session ID remains constant while the native representation adapts to the target harness.

Where does ai-memory store the logical session transcripts?

Transcripts are stored in a SQLite database through crates/ai-memory-store/src/writer.rs, which persists observations tied to a SessionId. Additionally, crates/ai-memory-workstream/src/transcript.rs manages the portable transcript format that allows later harnesses to read and resume from previous session states, effectively creating a hardware abstraction layer for session storage.

How does the LaunchPlan structure track the expected session ID?

The LaunchPlan struct returned by build_launch_plan contains an expected_session_id field of type Option<String>. When the builder generates a new UUID or receives a linked session ID, it populates this field with the identifier that will be passed to the native harness. The CLI uses this field to correlate subsequent observations and lifecycle events with the correct logical session, ensuring continuity even when the underlying native session identifier format differs between harnesses.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →