Skip to content

[Feature]: Make detached longwork final delivery ownership explicit #80450

Description

@anyech

Summary

Detached or migrated long-running work needs an explicit final-delivery owner when origin, work, and update threads are not the same surface.

Today it is possible for a child/subagent completion to be surfaced through more than one legitimate path, for example:

  1. a source/origin thread owns the child request and receives the native child completion, and
  2. an orchestrator also bridges the same full completion summary into a dedicated work thread.

That cross-thread visibility is useful when it is intentional, but duplicate full final summaries are confusing when there is no explicit dual-delivery contract.

Why this is separate from related duplicate-delivery work

This is not the same class as same-response duplicate delivery where a single assistant response both calls message.send and emits matching normal assistant text. That path is being addressed separately in #80445.

This issue is about multi-surface longwork orchestration: source/origin thread, work thread, update thread, and child completion delivery may all be valid concepts, but there is no first-class owner for the final user-visible summary.

It is also adjacent to #75973, which exposes final metadata for hooks without raw text or routing behavior. This request is about the delivery/ownership policy that can use such metadata safely.

Expected behavior

For detached/migrated work, OpenClaw should have one explicit final-summary owner. Example modes:

  • work-thread-final: the complete final summary is delivered only to the work thread; the origin thread may receive at most a short pointer/status note.
  • origin-bridge-final: the complete final summary is delivered only to the origin/update thread through a validated bridge-back path; the work thread may receive at most a short pointer/status note.

The runtime or helper contract should make it difficult to accidentally publish the same full final summary to both threads.

Actual behavior / risk

A longwork migration can produce two full final summaries across different Discord threads when both of these happen:

  • the original child completion is delivered to the requester/source thread, and
  • a parent/orchestrator manually bridges the same completion summary into the new work thread.

A second related risk is that requester-scoped child discovery can make a newer work thread appear to have no relevant worker, even though an older/source thread already has a matching child still running or about to complete. That can lead to duplicate worker launches unless the migration packet carries the exact child session identity or the operator checks visible session lineage.

Proposed shape

Add a first-class contract field or API concept for final ownership, for example:

{
  "originThread": "<origin/update surface>",
  "workThread": "<work surface>",
  "updateThread": "<single explicit update target>",
  "deliveryMode": "same-thread | bridge-back",
  "completionOwner": "work-thread-final | origin-bridge-final",
  "childSessionKey": "<exact child session identity>"
}

The important invariant is:

one child completion may have multiple observers, but only one owner is allowed to publish the full final user-visible summary.

Possible implementation directions:

  • extend detached/session spawn metadata so final-delivery ownership is explicit at launch time;
  • make reporter/final-delivery helpers derive their target from that persisted contract instead of free-form thread selection;
  • suppress or downgrade non-owner final delivery to a short pointer/status note;
  • expose enough child identity in migration packets or completion events to prevent duplicate worker launches after cross-thread migration.

Evidence level

This was observed in a real Discord longwork migration, then locally mitigated by adding an explicit completionOwner field to a deployment-side detach/admission contract and regression tests for the contract helper.

I do not have a minimal upstream runtime test case yet. The current request is to decide the intended first-class ownership model before turning it into a runtime-level PR.

Acceptance criteria

  • A detached/migrated child completion has exactly one full-final delivery owner.
  • Bridge-back remains possible when explicitly requested.
  • Same-thread detached continuity remains the default.
  • Non-owner surfaces can receive short pointer/status notes without duplicating the full final summary.
  • Duplicate worker launches are harder after cross-thread migration because the exact child identity is carried or discoverable.

Metadata

Metadata

Assignees

No one assigned

    Labels

    P2Normal backlog priority with limited blast radius.clawsweeper:needs-live-reproClawSweeper needs live local, crabbox, or manual validation to confirm this issue.clawsweeper:needs-maintainer-reviewClawSweeper marked this issue as needing maintainer review before automation.clawsweeper:needs-product-decisionClawSweeper marked this issue as needing a product or behavior decision.clawsweeper:no-new-fix-prClawSweeper does not recommend queueing a new automated fix PR for this issue.impact:message-lossChannel message delivery can be lost, duplicated, or misrouted.impact:session-stateSession, memory, transcript, context, or agent state can drift or corrupt.issue-rating: 🐚 platinum hermitGood issue quality with a plausible reproduction path needing some confirmation.maturity:stableIssue affects a taxonomy feature currently scored M4/M5.staleMarked as stale due to inactivity

    Type

    No type

    Fields

    Priority

    None yet

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions