How the Managed Workstream Launcher (`ai-memory run`) Provides Cross-Harness Continuity

The managed workstream launcher enables cross-harness continuity by detecting the target AI harness, injecting the correct session flags into the native command line, discovering sessions after launch if necessary, and exporting the resulting transcript into a unified workstream store.

The akitaonrails/ai-memory project treats native sessions from disparate coding agents as interchangeable inputs to a single persistent workstream. By using the managed workstream launcher, a developer can start a task with Claude, resume it with Codex, and review history in Kiro without losing conversational context. This article explains exactly how the launcher coordinates harness detection, session linking, and transcript ingestion according to the source code.

Harness Identification and Launch Plan Construction

The continuity flow begins inside crates/ai-memory-workstream/src/harness.rs, where the ManagedHarness enum represents every supported agent.

Selecting the Target Harness

When you invoke ai-memory run claude or ai-memory run kiro-cli, the CLI parses the first positional argument through ManagedHarness::from_name. This maps the string token to a strongly typed variant such as ManagedHarness::Claude, ManagedHarness::KiroV3, or ManagedHarness::Codex. The variant determines every subsequent decision: which flags to inject, where sessions live on disk, and how transcripts are parsed.

Injecting Session Flags with build_launch_plan

Once the harness is known, the launcher calls build_launch_plan from crates/ai-memory-workstream/src/lib.rs. This function inspects the invocation context and decides whether the launch is session-bearing or a passthrough utility. For a normal coding session, it injects a native session selector—such as --session-id, --session, or --resume—only when the user has not already supplied one. The function also records the expected session ID so the wrapper can associate the child process with the correct workstream later.

For passthrough commands like codex doctor, the launch mode is detected as LaunchMode::Passthrough and no selector is added, letting the utility run without side effects.

// Example: launching Claude and linking its session
use ai_memory_workstream::{build_launch_plan, ManagedHarness, LaunchMode};

let harness = ManagedHarness::Claude;
let native_args = vec![OsString::from("--model"), OsString::from("opus")];
let linked_id = Some("a1b2c3d4-5678-90ab-cdef-1234567890ab");

// Build the transparent launch plan; the wrapper injects "--session-id" or "--resume".
let plan = build_launch_plan(harness, None, native_args, linked_id).unwrap();
assert_eq!(plan.mode, LaunchMode::Session);
assert_eq!(plan.args, ["--model", "opus", "--resume", "a1b2c3d4-5678-90ab-cdef-1234567890ab"]);

Native Session Detection and Discovery

Not every harness exposes its session ID before the process starts. The launcher compensates by discovering sessions after the fact and checking for existing sessions before creating new ones.

Adopting or Creating Sessions

Before spawning a new child, the wrapper checks whether a native session already exists via the native_session_exists helper. If an existing session is found, the launcher adopts it and injects the matching resume flag. Otherwise, the launcher generates a fresh UUID (or allows the harness to assign one) and adds the corresponding flag based on the harness type. This design lets a user switch from ai-memory run codex to ai-memory run open-code without losing conversation history, because the workstream stores a canonical representation of events that is independent of the specific harness.

Post-Launch Discovery with discover_native_session

Some agents—notably Kiro v3 when the user omits the --v3 flag—cannot be linked to a session until after they start. In these cases, discover_native_session scans the harness-specific session directory, matches the entry against the current working directory, and returns the newly created native session ID. This bridges the gap between launch and linkage.

// Example: discovering a fresh Kimi session created after a launch
use ai_memory_workstream::{discover_native_session, ManagedHarness};

let home = std::path::Path::new("/home/user/.kimi");
let cwd = std::env::current_dir().unwrap();
let started = std::time::SystemTime::now();

let maybe_id = tokio::runtime::Runtime::new().unwrap().block_on(
    discover_native_session(
        ManagedHarness::Kimi,
        home,
        &cwd,
        None,
        started,
    ),
).unwrap();

if let Some(id) = maybe_id {
    println!("Discovered new Kimi session: {id}");
}

Transcript Export and Unified Workstream Ingestion

After the child process exits, the launcher converts the native transcript into a harness-agnostic event stream that feeds the persistent workstream.

Parsing Native Stores with export_transcript

The export_transcript function, defined in crates/ai-memory-workstream/src/lib.rs and implemented via crates/ai-memory-workstream/src/transcript.rs, reads the harness's native JSONL or SQLite store. It converts each record into a NewWorkstreamEvent and returns an ExportedTranscript that contains a cursor for incremental reads. This cursor is what enables the launcher to resume ingestion on the next invocation without duplicating events.

Handling Rewritable Journals

Several harnesses—including Kimi, Kiro v3, and Grok—maintain rewritable journals rather than append-only logs. The transcript parser handles these by hashing the consumed prefix, so subsequent exports can detect what has already been ingested and avoid double-counting history.

// Example: exporting a Kiro v3 transcript after the child exits
use ai_memory_workstream::{
    export_transcript, ManagedHarness, NativeSessionCandidate,
};
use std::path::Path;

let home = Path::new("/home/user/.kiro");
let cwd = std::env::current_dir().unwrap();
let session_dir = None;
let native_session_id = "7f6e5d4c-3b2a-1908-7654-3210fedcba98";

let exported = tokio::runtime::Runtime::new().unwrap().block_on(
    export_transcript(
        ManagedHarness::KiroV3,
        home,
        &cwd,
        session_dir,
        native_session_id,
        None,
    ),
).unwrap();

println!("Exported {} events", exported.events.len());

CLI Orchestration and Process Lifecycle

All of these stages are orchestrated by the binary entry point in crates/ai-memory-cli/src/main.rs. The ai-memory run command performs the following sequence:

  1. Parses the command-line arguments and resolves the harness via ManagedHarness::from_name.
  2. Calls build_launch_plan to obtain the exact native command line, complete with injected session selectors.
  3. Spawns the child process using the wrapper's process-launch utilities.
  4. Waits for the child to finish.
  5. Invokes export_transcript to ingest native events into the workstream store.

This pipeline ensures that every harness writes into the same canonical workstream, making the underlying agent interchangeable while the conversation history remains persistent.

Summary

  • The managed workstream launcher maps each harness to a typed ManagedHarness variant in harness.rs.
  • build_launch_plan injects session selectors only for session-bearing launches, avoiding side effects on passthrough utilities.
  • Existing sessions are adopted via native_session_exists; missing IDs are discovered post-launch with discover_native_session.
  • export_transcript converts native JSONL or SQLite transcripts into NewWorkstreamEvent objects, using a cursor for incremental reads.
  • Rewritable journals from Kimi, Kiro v3, and Grok are handled by hashing the consumed prefix to prevent duplicate ingestion.
  • The entry point in crates/ai-memory-cli/src/main.rs ties these steps into a single lifecycle that preserves history across any supported harness.

Frequently Asked Questions

What harnesses are supported by the managed workstream launcher?

The launcher supports Claude, Codex, OpenCode, Kiro, Kiro v3, Kimi, Command Code, and Grok, among others. Each variant is defined in crates/ai-memory-workstream/src/harness.rs and carries its own session directory, flag conventions, and transcript parser.

How does ai-memory run handle utilities like codex doctor?

Commands that do not need a persistent session are detected as LaunchMode::Passthrough inside build_launch_plan. In this mode, the launcher skips session injection entirely and runs the native binary without modifying its arguments.

Can I switch from one harness to another without losing history?

Yes. Because the workstream stores a canonical representation of events that is independent of any specific harness, you can start with ai-memory run codex and later resume with ai-memory run claude. The launcher links each new native session to the existing workstream through the transcript cursor.

Where is the transcript conversion logic implemented?

The transcript parser lives in crates/ai-memory-workstream/src/transcript.rs. It is responsible for reading each harness's native JSONL or SQLite format, converting records into NewWorkstreamEvent values, and computing hashes for rewritable journals so that incremental exports remain consistent.

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 →