codex - 💡(How to fix) Fix App Server: add persistent thread attachment RPCs for existing top-level sessions

Official PRs (…)
ON THIS PAGE

Recommended Tools

×6

Utilities matched from this issue’s tags and category — try them while you read without losing context.

GitHub issue graph ai analysis

Paste a GitHub issue URL. We fetch that issue, discover linked issues from bodies/comments/timeline, collect linked pull requests, and produce a structured English report.

The report is written in English Markdown for sharing and archival.

Helpful · Quick feedback

Loading…

Please add a sanctioned App Server API for attaching an existing top-level Codex thread to another existing thread as a persistent child or role session.

This is the narrow App Server protocol companion to #23713. The Desktop UX request in #23713 asks for an "Attach as sub-agent to parent thread" action. This issue narrows that request to the open-source App Server surface so clients can create, list, and remove durable thread attachment relationships without editing local SQLite or JSONL state.

This also fits under the broader cross-thread orchestration direction in #14923, but it is intentionally smaller: this issue is only about the relationship primitive that lets an existing top-level thread become addressable from a parent thread while remaining a normal visible top-level session.

Root Cause

Please add a sanctioned App Server API for attaching an existing top-level Codex thread to another existing thread as a persistent child or role session.

This is the narrow App Server protocol companion to #23713. The Desktop UX request in #23713 asks for an "Attach as sub-agent to parent thread" action. This issue narrows that request to the open-source App Server surface so clients can create, list, and remove durable thread attachment relationships without editing local SQLite or JSONL state.

This also fits under the broader cross-thread orchestration direction in #14923, but it is intentionally smaller: this issue is only about the relationship primitive that lets an existing top-level thread become addressable from a parent thread while remaining a normal visible top-level session.

Fix Action

Fix / Workaround

Overloading thread/metadata/update with fields like thread_source, source, agent_role, agent_nickname, or edge-table state would make it too easy for clients to create inconsistent graphs. It would also mix display metadata, lifecycle state, and orchestration authority into one patch surface.

Code Example

thread/attachment/create
thread/attachment/delete
thread/attachments/list

---

{
  "parentThreadId": "string",
  "childThreadId": "string",
  "roleLabel": "optional string",
  "displayName": "optional string"
}

---

{
  "attachmentId": "string",
  "parentThreadId": "string",
  "childThreadId": "string",
  "roleLabel": "optional string",
  "displayName": "optional string",
  "state": "active | detached | archived",
  "createdAt": "timestamp",
  "updatedAt": "timestamp"
}
RAW_BUFFERClick to expand / collapse

What variant of Codex are you using?

App Server / Codex Desktop App

What feature would you like to see?

Summary

Please add a sanctioned App Server API for attaching an existing top-level Codex thread to another existing thread as a persistent child or role session.

This is the narrow App Server protocol companion to #23713. The Desktop UX request in #23713 asks for an "Attach as sub-agent to parent thread" action. This issue narrows that request to the open-source App Server surface so clients can create, list, and remove durable thread attachment relationships without editing local SQLite or JSONL state.

This also fits under the broader cross-thread orchestration direction in #14923, but it is intentionally smaller: this issue is only about the relationship primitive that lets an existing top-level thread become addressable from a parent thread while remaining a normal visible top-level session.

Related issues

  • #23713 - Desktop UX request for attaching existing scoped sessions as persistent subagents
  • #14923 - broader cross-thread orchestration request
  • #24107 - programmatic creation of sidebar-visible chats from external orchestrators
  • #23313 - narrow metadata primitive to associate stored threads with a project cwd
  • #21889 - example of a focused App Server lifecycle RPC proposal
  • #17867 - lifecycle and archiving semantics around spawned child threads
  • #23001 - metadata and migration fragility around existing thread state

Problem

Codex currently supports spawned subagents, but spawned subagents are not the same operational shape as existing top-level scoped role sessions.

A top-level thread can already have the right project folder, cwd, AGENTS.md scope, role brief, model settings, visible history, and Desktop or automation affordances. But there is no sanctioned App Server API to attach that existing thread to an orchestrator thread so the parent can message it like a subagent.

The current gap pushes advanced workflows toward unsupported local-state mutation. That works only by relying on internal implementation details. The App Server already owns thread lifecycle primitives, so this relationship should be represented through a first-class protocol method instead of local database edits.

Concrete use case

Consider a user running a durable multi-agent workspace:

  • one top-level Operator or orchestrator thread
  • one top-level Reviewer thread scoped to a reviewer folder and AGENTS.md
  • one top-level Implementor thread scoped to an implementor folder and AGENTS.md
  • one top-level Specwright thread scoped to a spec-authoring folder and AGENTS.md

The user wants the Operator thread to route work to those existing role threads without manually copying prompts between chats.

The important properties are:

  • the role thread remains visible in the normal left sidebar
  • the role thread can still be opened and prompted directly by the human
  • the role thread keeps its original cwd and instruction scope
  • the role thread keeps its accumulated history
  • the parent can address the role thread through a supported orchestration edge
  • detach removes only the relationship, not the child thread

Spawned subagents are useful for disposable delegation, but this is a different shape: persistent role desks attached to a parent orchestrator.

Why spawned subagents are not enough

Spawned subagents are useful for bounded, disposable delegation. Persistent role sessions are different:

  • They already live as top-level visible threads.
  • They can be scoped by folder-level AGENTS.md files rather than duplicated TOML prompts.
  • They preserve long-running role continuity across days or weeks.
  • They can be inspected and prompted directly by the user.
  • They can participate in Desktop automations and scheduled wakeups.
  • They should not be destroyed by disposable-child lifecycle controls.

The TOML custom-agent path also creates a drift surface. If a role is already governed by a folder-scoped AGENTS.md, duplicating that role into a TOML prompt, or telling the TOML prompt to "go read this AGENTS.md," is less reliable than using the existing scoped top-level session directly.

Maintainer decision requested

The main design question is not whether the Desktop UI should eventually expose this. That is covered by #23713.

The narrower App Server questions are:

  1. Should existing top-level threads be attachable to a parent thread through a first-class relationship API?
  2. If yes, should this be modeled as dedicated attachment RPCs rather than raw metadata mutation?
  3. Should v1 enforce one active parent attachment per child thread, with many-parent graphs left out of scope?

My proposed answer is yes to all three, with a conservative v1 focused on create, list, and delete.

Proposed API

Add purpose-built JSON-RPC methods rather than expanding thread/metadata/update into a raw writable metadata bag:

thread/attachment/create
thread/attachment/delete
thread/attachments/list

Suggested create shape:

{
  "parentThreadId": "string",
  "childThreadId": "string",
  "roleLabel": "optional string",
  "displayName": "optional string"
}

Suggested returned relationship:

{
  "attachmentId": "string",
  "parentThreadId": "string",
  "childThreadId": "string",
  "roleLabel": "optional string",
  "displayName": "optional string",
  "state": "active | detached | archived",
  "createdAt": "timestamp",
  "updatedAt": "timestamp"
}

Smallest useful MVP

The smallest useful version does not need Desktop UI work.

MVP:

  • create an attachment relationship between two existing threads
  • list attachment relationships
  • delete or detach an attachment relationship
  • allow the parent runtime to address the attached child thread through the existing child-agent messaging path, or through an equivalent supported App Server turn-routing path
  • preserve both threads as normal top-level threads
  • make detach non-destructive

Everything else can layer later.

Required semantics

  • Creating an attachment must not fork, spawn, archive, close, or rewrite either thread.
  • Creating an attachment must not change either thread's cwd, instruction scope, model settings, transcript, rollout identity, or history.
  • Creating an attachment must reject self-attachment.
  • Creating an attachment must reject cycles.
  • Creating an attachment must reject nonexistent or archived threads.
  • Creating an attachment should reject duplicate active attachments.
  • Default should be one active parent attachment per child unless maintainers explicitly want many-parent semantics.
  • Deleting an attachment detaches only the relationship. It must not archive, close, delete, or mutate either thread.
  • Listing attachments should support lookup by parent thread, child thread, or both.
  • Attachment state should be visible to clients without local state scraping.
  • Cross-thread activity should remain auditable from the parent and child side.

Important lifecycle safety

Persistent attached top-level sessions must be distinguished from disposable spawned children.

Existing spawned-child lifecycle controls such as close_agent are dangerous if blindly applied to persistent attached top-level threads. For an attached thread, "detach" should remove the relationship only. It should not close, archive, delete, or otherwise destroy the child thread.

This is the load-bearing difference between:

  • disposable spawned subagent
  • persistent top-level session attached as a role or child session

Likely implementation surface

Based on the public App Server shape, I expect the implementation would likely touch:

  • app-server protocol method definitions
  • thread relationship persistence
  • request handling for create, list, and delete
  • lifecycle validation for archived, nonexistent, self-attached, duplicate, and cyclic relationships
  • tests for non-destructive detach and invalid relationship graphs

That is only a hypothesis from the public code shape. I am happy to align to a maintainer-preferred design before writing code.

Why App Server is the right surface

The Desktop UI can eventually become sugar over this API, but the relationship itself is not Desktop-only. Other clients, automation tooling, and SDK users need the same primitive.

The App Server already exposes thread lifecycle and turn primitives. A persistent attachment relationship is a lifecycle and relationship concept, not merely display metadata. That is why this should be a dedicated API rather than a loose extension of thread/metadata/update.

This shape also keeps #23713 smaller. The Desktop UI can later offer an "Attach as sub-agent to parent thread" button that calls the sanctioned App Server method rather than inventing its own state mutation path.

Why not raw metadata mutation

Thread attachment is a relationship, not ordinary metadata.

Overloading thread/metadata/update with fields like thread_source, source, agent_role, agent_nickname, or edge-table state would make it too easy for clients to create inconsistent graphs. It would also mix display metadata, lifecycle state, and orchestration authority into one patch surface.

A dedicated attachment API can validate graph invariants atomically:

  • no self-edges
  • no cycles
  • no duplicate active relationship
  • no accidental many-parent relationship unless explicitly supported
  • no destructive lifecycle action during detach
  • no cwd or instruction-scope rewrite

Non-goals

  • This does not require implementing the Desktop UI button from #23713.
  • This does not require changing thread transcript format.
  • This does not require changing model selection or agent execution semantics.
  • This does not require exposing arbitrary SQLite or JSONL mutation.
  • This does not require replacing spawned subagents.
  • This does not require supporting many-parent attachment graphs in v1.
  • This does not require making all cross-thread orchestration from #14923 available at once.

Acceptance criteria

  • App Server exposes thread/attachment/create.
  • App Server exposes thread/attachment/delete.
  • App Server exposes thread/attachments/list.
  • Attachment creation validates self-attachment, cycles, duplicate active attachments, missing threads, and archived threads.
  • Attachment deletion is non-destructive to both parent and child threads.
  • Existing thread lifecycle methods continue to work unchanged.
  • Attached top-level threads remain visible as top-level sessions.
  • Parent-side orchestration can address the attached child thread.
  • The child thread preserves its original cwd and instruction scope.
  • Desktop or external clients can discover attachment state without reading local SQLite or JSONL directly.
  • Tests cover create/list/delete, invalid relationships, archived-thread behavior, and non-destructive detach behavior.

Contribution note

I understand unsolicited PRs are not accepted by default. If maintainers agree this is the right App Server protocol shape, I would be happy to help prototype the focused App Server and protocol change under whatever contribution process you prefer.

Additional information

This is a companion protocol/API request to #23713.

Vote matrix · Quick signals

Works
Did the solution work? Tap to confirm.
Easy Fix
Was it a quick fix?
Time Saver
Did it save you time?
Blocking
Was it severely blocking?
Common Issue
Are others likely hitting this too?
Flaky / Intermittent
Is it intermittent?
Verified / Reproducible
Can you reproduce it reliably?
Loading…

Still need to ship something?

×6

Another batch ranked right after the header list — different links, same matching logic.

Back to top recommendations

TRENDING