Threads (chat and issues)
Chat and issues are two views of one Issue-backed thread. Promotion is an in-place field flip, not a second object.
Every compose target in Melso is one thread. The stored row is issue. Chat is the private, untracked view of that row; the board is the workspace-visible, tracked view. Typing always appends to the same object.
Do not add status: chat. Status stays a workflow field (todo / in_progress / done / …). Chat vs work uses two other axes:
visibility:private|workspacetracked: whether the thread has a work facet (identifier on the board, assignee, subscribers, inbox)
Who promotes
The agent promotes with melso chat promote, the same family as melso issue status. A human can promote from the chat session menu. Autopilots and channel /issue create threads that are already tracked.
Promotion is in-place: same transcript, same runtime session pointer, same id map (chat_session.issue_id). It does not copy the last N messages into a disconnected issue.
Default promote: tracked=true, visibility=workspace, status todo, keep the peer agent as assignee. The agent must say the thread is now shared. Skip auto-promote when the reply itself is the deliverable.
melso issue create stays for new sibling work (sub-issues), not for “this conversation.”
Schema
- Existing issues backfill as
visibility=workspace,tracked=true. - First-party Melso chats insert a linked
issue(visibility=private,tracked=false,origin_type=melso_chat) and storechat_session.issue_id. commentis the work transcript. Chat still writeschat_messageuntil the chat XOR parent is dropped; promote copies messages onto comments when the issue has none yet, and later chat completions dual-write comments when the session is already linked.- After promote, queued/running chat tasks gain
issue_idso the next turn can resume as issue work.agent_task_queue.chat_session_idremains until channel bindings migrate. - Board,
melso issue list, search, and inbox hidetracked=falseandvisibility=privatethreads. Chat list stays creator-private.
API
POST /api/chat/sessions/{sessionId}/promote— member override (session creator only).POST /api/chat/promote— agent path; infers the session from the task token (X-Task-ID), same asmelso chat history.
Response is the promoted issue plus chat_session_id. Idempotent if the session is already tracked.
Surfaces
/chat and /issues are filters over the same object, not two resources. After promote, clients open the issue detail (session chrome). Old chat URLs keep working; ChatSession.issue_id is the redirect pointer.