Skip to content

Feat/acp hub delegated sessions#91093

Open
scotthuang wants to merge 40 commits into
openclaw:mainfrom
scotthuang:feat/acp-hub-delegated-sessions
Open

Feat/acp hub delegated sessions#91093
scotthuang wants to merge 40 commits into
openclaw:mainfrom
scotthuang:feat/acp-hub-delegated-sessions

Conversation

@scotthuang

@scotthuang scotthuang commented Jun 7, 2026

Copy link
Copy Markdown
Contributor

Summary

  • Problem: Hub sessions (WebChat, WeChat, and other main chat surfaces) need persistent external ACP harness workers without binding a Discord/Telegram thread. The existing ACP persistent path requires mode: "session" plus thread: true, which is unavailable or awkward on many hub channels.
  • Why it matters now: Dogfooding hub → Codex/Claude Code delegation from a single visible chat requires a named worker that stays alive across turns, accepts follow-ups by label, and does not echo A2A ping-pong back into the hub.
  • Intended outcome: A hub agent can sessions_spawn({ runtime: "acp", delegate: true, label?, task }), follow up with sessions_send(label=...), list owned workers via sessions_list({ delegated: true }), and operators inspect or close workers with /acp delegate list|status|close <label>. Persistent harness teardown for hub-delegated workers is operator-facing (/acp delegate close) plus maintenance idle/max-age sweeps — the same lifecycle model documented in docs/tools/acp-agents.md.
  • Success looks like: Hub-delegated workers spawn without thread binding, survive after the first task, honor follow-ups without A2A echo loops, auto-close on idle/max-age policy, and remain discoverable by label for both agents and operators.
  • Reviewers should focus on: Owner-boundary correctness for hubDelegated metadata and label follow-up, A2A skip conditions for parent-owned delegates, lifecycle maintenance/close ordering (acp.delegate.*), fail-closed ACP metadata/session-id/repair boundaries, owner-scoped label uniqueness (spawn pre-check and sessions.patch), and JSON-store vs sqlite discovery parity for operator /acp delegate vs maintenance.

ACP spawn shapes (scope boundary)

Three sessions_spawn({ runtime: "acp", ... }) paths — this PR delivers row 3 only:

Shape Persistent Thread Follow-up Close
mode: "run" No Not required Parent task announce; optional parent sessions_send Automatic after task
mode: "session" + thread: true Yes Required Messages in the bound channel thread/topic /acp close
delegate: true Yes Forbidden sessions_send(label=...) from owning hub session /acp delegate close + acp.delegate.* maintenance

This PR delivers: hub-delegated persistent workers (row 3) for WebChat/WeChat and other non-thread hub surfaces.

Does not change: row 1 (mode: "run") and row 2 (thread-bound persistent ACP). Broader decoupled-session / global session-management work stays out of scope — see Linked context.

Full product docs: docs/tools/acp-agents.md (Hub-delegated persistent workers).

Design rationale: why delegate instead of relaxing mode: "session"?

Short answer: persistence alone is under-specified. mode: "session" today means thread-visible persistent ACP (follow-up in the bound thread, close via /acp close). Hub orchestration needs a different contract: parent-owned background worker, label-routed follow-up via sessions_send, skip A2A for owner sends, and operator/maintenance close — not “same persistent session, minus thread.”

Why not { mode: "session" } without thread: true?

  • Runtime would not know follow-up surface (thread message vs hub label), visibility (channel thread vs internal worker), close owner (/acp close vs /acp delegate close + acp.delegate.*), or label rules (global vs owner-scoped).
  • That conflates at least three persistent shapes: thread-bound session, hub-delegated worker (this PR), and cron/hook affinity — each with different owner and lifecycle invariants.
  • Today mode: "session" without thread fail-closes on purpose; silently allowing it would create persistent workers without an explicit product contract.

What delegate: true buys:

  • Explicit opt-in to the hub worker bundle: hubDelegated ownership, owner-scoped labels, parent relay semantics, /acp delegate operator surface, and maintenance policy — without changing row 1 (run) or row 2 (thread session) behavior.

Relationship to #53548: this PR delivers the hub/orchestrator slice only; it does not generalize decoupled mode: "session" for all channels or requesters.

Architecture (hub → ACP worker)

Hub-delegated workers are parent-owned background ACP sessions. The hub session stays the only user-visible chat surface; the harness worker stays alive off-channel and is addressed by label, not by opening a Discord/Telegram thread.

Component map

flowchart LR
  subgraph Visible["User-visible hub surface"]
    U[User]
    CH["Channel adapter WebChat WeChat etc"]
    HUB["Hub session agent main webchat main"]
  end

  subgraph Worker["Parent-owned ACP worker background"]
    ACP["Persistent ACP session agent codex acp"]
    HX["External harness Codex Claude Code etc"]
  end

  subgraph Meta["Ownership and naming"]
    HD["hubDelegated ownerSessionKey plus label per owner"]
  end

  subgraph Lifecycle["Operator and maintenance"]
    OPS["acp delegate list status close"]
    SWP["Idle and max-age maintenance"]
  end

  U --> CH --> HUB
  HUB -->|sessions_spawn delegate true| ACP
  HUB -->|sessions_send by label| ACP
  ACP --> HX
  HUB --- HD
  ACP --- HD
  OPS --> HD
  SWP --> HD
  HUB -->|summarize or relay| CH --> U
Loading

Key invariant: the worker does not bind a channel thread/topic. Follow-ups reuse the same harness session via label; the hub agent decides what (if anything) to publish back to the visible channel.

1) Initial spawn (first task)

sequenceDiagram
  autonumber
  actor User
  participant Channel
  participant Hub as Hub session
  participant Spawn as sessions_spawn
  participant GW as Gateway
  participant Worker as ACP worker
  participant Harness as Harness runtime

  User->>Channel: task or message
  Channel->>Hub: inbound dispatch
  Hub->>Spawn: delegate true plus task and optional label
  Spawn->>GW: sessions patch hubDelegated label spawnedBy
  Spawn->>GW: initialize persistent ACP runtime
  GW->>Worker: create worker and store marker
  Worker->>Harness: run initial task
  Harness-->>Worker: progress and result
  Worker-->>Hub: optional progress stream silent notify
  Hub-->>Channel: hub agent reply
  Channel-->>User: response
Loading

Notes for reviewers:

  • No thread: true and no channel binding record is required.
  • delegate: true implies persistent mode: "session"; one-shot mode: "run" is rejected.
  • Label is optional; when omitted OpenClaw assigns delegate-YYYYMMDD-HHMMSS (UTC) and returns it in the spawn result.

2) Follow-up turns (send by label)

sequenceDiagram
  autonumber
  actor User
  participant Channel
  participant Hub as Hub session
  participant Send as sessions_send
  participant GW as Gateway
  participant Worker as ACP worker
  participant Harness as Harness runtime

  User->>Channel: follow-up message
  Channel->>Hub: inbound dispatch
  Hub->>Send: label plus message and timeout
  Send->>GW: sessions resolve label owner scoped
  GW-->>Send: worker session key
  Send->>GW: agent run and agent wait
  Note over Send,Worker: Parent-owned delegate skips A2A loop
  Worker->>Harness: continue persistent session
  Harness-->>Worker: assistant reply
  Worker-->>Send: waited reply snapshot
  Send-->>Hub: tool result
  Hub-->>Channel: hub agent relays or summarizes
  Channel-->>User: response
Loading

Notes for reviewers:

  • sessions.resolve uses owner-scoped label matching for hub-delegated workers (not global label uniqueness across owners).
  • Parent sessions_send into its own hub-delegated worker skips the A2A announce loop because the hub already owns the visible reply channel.
  • Waited sessions_send reads the worker reply from canonical chat.history; hub-delegated turns stay off visible delivery surfaces but still persist assistant/user turns to the session transcript.
  • Hub-delegated worker teardown is via /acp delegate close <label> (operator commands) and maintenance idle/max-age policy; thread-bound ACP sessions continue to use /acp close.

3) How this differs from thread-bound persistent ACP

Hub-delegated (delegate: true) Thread-bound persistent (thread: true, mode: "session")
Visible surface Hub chat only
Follow-up sessions_send(label=…) from hub
Close /acp delegate close <label>
Typical channels WebChat, WeChat, other hub surfaces

Also bundled from live dogfood on this branch:

  • P0: Fail-closed ACP runtime handle reuse after idle; force re-ensure before turn when TTL exceeded.
  • P1: When agent.wait race returns null, abort both waiters immediately so sessions_send honors timeoutSeconds (default 30s) instead of blocking for minutes.

Linked context

Which issues, PRs, or discussions are related?

Does not address:

  • Thread-bound persistent ACP (thread: true, /acp close) — unchanged.
  • Generalized decoupled mode: "session" without delegate: true.
  • Global session-management CLI/UI, cron/hook affinity reuse, channel spawn policy, and agent-tool sessions_close for hub-delegated workers (close is /acp delegate close + maintenance by design).

Was this requested by a maintainer or owner?

Local maintainer dogfood for hub → ACP delegation from WebChat/stable gateway (port 18789).

Real behavior proof (required for external PRs)

  • Behavior or issue addressed: Hub-delegated persistent ACP workers from a main chat surface; follow-up via label; no thread binding; no A2A echo loop; operator lifecycle via /acp delegate.
  • Real environment tested: macOS local source-built OpenClaw gateway on port 18789 (~/.openclaw), WeChat hub session + WebChat delegated ACP worker session, Codex ACP harness via acpx. Close-path proof recorded against current head after the delegate label-routing close fix.
  • Exact steps or command run after this patch:
  1. From hub session: sessions_spawn({ runtime: "acp", delegate: true, agentId: "codex", task: "..." }) (with and without explicit label).
  2. Follow up: sessions_send({ label: "<label>", message: "..." }).
  3. List: sessions_list({ delegated: true }).
  4. Operator: /acp delegate list, /acp delegate status <label>.
  5. Close path (current head): /acp delegate close <label>, then /acp delegate list (expect empty), then sessions_send({ label: "<label>", message: "..." }) (expect rejected / no resolve).
  6. Regression checks for idle reconnect (>10 min) and sessions_send timeout honoring (~30s default).
  • Evidence after fix (screenshot, recording, terminal capture, console output, redacted runtime log, linked artifact, or copied live output): Maintainer dogfood verified manually on stable gateway (port 18789). All proof uses screenshots (not video).

Screenshot 1 — hub-delegated ACP subagent spawn (sessions_spawn({ runtime: "acp", delegate: true, ... }); persistent mode: "session" worker created without thread: true):

acp1

Screenshot 2 — follow-up via sessions_send (hub session sends to the spawned worker by label):

acp2

Screenshot 3 — /acp delegate list empty after close (after /acp delegate close <label> on current head):

p1

Screenshot 4 — sessions_send rejected after close (follow-up with the same closed delegate label):

P3
  • Observed result after fix:

  • Hub-delegated spawn accepted without thread: true.

  • Follow-ups by label work from the same hub session.

  • sessions_list({ delegated: true }) returns owned workers.

  • A2A follow-up skipped for parent-owned hub-delegated targets (delivery.status="skipped" path).

  • Idle stale-handle reconnect and sessions_send timeout fixes verified after long-idle and short-wait scenarios.

  • Spawn/follow-up (screenshots 1–2): hub-delegated spawn succeeds without thread: true; sessions_send({ label: "<label>", ... }) reaches the persistent worker and returns a reply.

  • Close path (screenshots 3–4): /acp delegate close <label> succeeds; /acp delegate list and sessions_list({ delegated: true }) are empty afterward; follow-up sessions_send({ label: "<label>", ... }) is rejected and does not reopen the closed worker.

  • What was not tested:

  • timeoutSeconds: 0 fire-and-forget on hub-delegated follow-up.

  • Remote Crabbox/Testbox or GitHub Actions CI (local CI only; see Tests section).

  • Proof limitations or environment constraints: Proof is from a maintainer local environment, not Crabbox. Four screenshots above cover spawn, sessions_send follow-up, close, and post-close rejection; list/status and edge cases remain covered by unit tests. Duplicate-label conflict, owner-scoped label resolve, expired-delegate reactivation, and close-ordering edge cases remain covered by unit tests.

  • Before evidence (optional but encouraged): Prior dogfood without P0/P1 fixes showed long idle turns hanging until ~900s and sessions_send waits exceeding configured timeout when race waiters stacked.

Tests and validation

Which commands did you run?

# Local changed CI (Crabbox unavailable on host; remote child disabled)
env OPENCLAW_CHECK_CHANGED_REMOTE_CHILD=1 OPENCLAW_CHANGED_LANES_RAW_SYNC=1 pnpm check:changed

pnpm test:changed

# Targeted proof during development
pnpm test packages/acp-core/src/hub-delegated.test.ts
pnpm test src/acp/hub-delegated-lifecycle.test.ts
pnpm test src/agents/acp-spawn.test.ts -t "hub-delegated|auto-generates|duplicate hub-delegated"
pnpm test src/acp/control-plane/manager.runtime-handles.test.ts
pnpm test src/acp/control-plane/manager.repair-missing-metadata.test.ts
pnpm test src/acp/runtime/session-meta.test.ts
pnpm test src/tasks/task-registry.maintenance.hub-delegated.test.ts
pnpm test src/agents/openclaw-tools.sessions.test.ts -t "hub-delegated|label resolve"
pnpm test src/config/schema.test.ts -t "hub-delegated ACP lifecycle"
pnpm test src/gateway/server.chat.gateway-server-chat.test.ts

What regression coverage was added or updated?

  • packages/acp-core/src/hub-delegated.test.ts — policy, ownership, expiry, auto-label generation/conflict suffix.
  • packages/acp-core/src/session-interaction-mode.test.ts — hub-delegated parent-owned background classification.
  • src/acp/hub-delegated-lifecycle.test.ts — JSON-store sweep without sqlite metadata, close ordering, expired-candidate resolution.
  • src/commands/agent.acp.test.ts — hub-delegated ACP turns persist to canonical transcript for waited sessions_send.
  • src/agents/acp-spawn.test.ts — delegate spawn, auto-label, delegate/thread conflict, duplicate label across ACP harness stores; concurrent auto-label suffix allocation under label lock.
  • src/agents/openclaw-tools.sessions.test.tssessions_send skip-A2A for hub-delegated targets; owner-scoped label resolve via spawnedBy.
  • src/acp/control-plane/manager.repair-missing-metadata.test.ts — hub-delegated persistent repair, one-shot repair, thread-bound binding-key repair, fail-closed with no evidence.
  • src/acp/runtime/session-meta.test.ts — fail-closed session_id drift; explicit rebind only.
  • src/tasks/task-registry.maintenance.hub-delegated.test.ts — expired delegate maintenance via JSON-store sweep and marker-first close.
  • src/config/schema.test.tsacp.delegate.* accepted by strict schema.
  • Gateway/agent tests, ACP manager runtime-handle tests, sessions patch/resolve tests, command tests — hub-delegated metadata, list filter, delegate slash commands, idle reconnect, timeout race.
  • User docs: docs/tools/acp-agents.md, docs/concepts/session-tool.md, docs/gateway/configuration-reference.md.

What failed before this fix, if known?

  • check:changed initially failed on src/agents/tools/sessions-spawn-tool.ts TS5076 (??/|| mixing); fixed with parentheses before CI green.
  • Pre-P0: reused stale ACP socket after idle caused turns to hang until long timeout.
  • Pre-P1: sessions_send could block far longer than timeoutSeconds when agent.wait race returned null but left a waiter alive.

If no test was added, why not?

Targeted unit/integration coverage was added for the main contracts above. Full channel-matrix live proof remains manual dogfood.

Risk checklist

Did user-visible behavior change? (Yes)

Yes. New hub-delegated ACP worker shape, new /acp delegate operator commands, optional auto-generated delegate labels, owner-scoped label follow-up, and user-facing docs for the flow. Existing thread-bound and one-shot ACP paths are unchanged unless the caller opts into delegate: true.

Did config, environment, or migration behavior change? (Yes)

Yes, additive only: acp.delegate.idleHours (default 72) and acp.delegate.maxAgeHours (default 168). Keys are now schema-valid with label/help metadata. No doctor migration required; defaults apply to new hub-delegated workers.

Did security, auth, secrets, network, or tool execution behavior change? (No)

No new auth surfaces. Hub-delegated workers remain parent-owned with internal delivery/control-ui session effects and silent notify policy; waited sessions_send still reads canonical session transcript via chat.history. Visibility stays scoped to the owning requester for list/close/status and label-based follow-up.

What is the highest-risk area?

Parent/child session ownership and sessions_send delivery semantics (skipping A2A while still allowing intentional parent follow-up), plus ACP runtime handle reuse after idle (P0 touch) and lifecycle closure/repair boundaries for expired or partially lost delegates.

How is that risk mitigated?

  • hubDelegated.ownerSessionKey stored in session metadata; list/close/status filter by owner.
  • Label follow-up resolves within the requester owner scope (spawnedBy / hubDelegated.ownerSessionKey).
  • A2A skip uses the same parent-owned-background classification as one-shot ACP children, extended for hub-delegated persistent workers.
  • Explicit label uniqueness enforced per owner across ACP harness stores; auto-label uses UTC timestamp + suffix on collision under the shared hub-delegated label patch lock.
  • Hub-delegated close clears hubDelegated before runtime teardown so missing-metadata repair cannot resurrect closed workers.
  • Maintenance sweeps JSON-store hubDelegated rows even when sqlite metadata is absent or drifted.
  • Missing-metadata repair requires explicit persistent evidence (hubDelegated, binding key shape, or active bindings); session_id drift is fail-closed until explicit metadata rebind.
  • P0 fail-closed on empty/missing runtime status and force re-ensure after idle TTL.
  • Tests cover spawn, send, list, delegate commands, idle handle reuse, wait timeout race, repair mode, session_id drift, label scan/ownership, maintenance expiry, close ordering, and config schema.

@openclaw-barnacle openclaw-barnacle Bot added docs Improvements or additions to documentation app: web-ui App: web-ui gateway Gateway runtime commands Command implementations agents Agent runtime and tooling size: XL proof: supplied External PR includes structured after-fix real behavior proof. labels Jun 7, 2026
@clawsweeper

clawsweeper Bot commented Jun 7, 2026

Copy link
Copy Markdown
Contributor

Codex review: needs maintainer review before merge. Reviewed June 11, 2026, 8:55 AM ET / 12:55 UTC.

Summary
Adds hub-delegated persistent ACP workers via sessions_spawn(delegate: true), label follow-up/list/close/status, owner-scoped session metadata, lifecycle expiry defaults, gateway protocol/config/docs, and tests.

PR surface: Source +1466, Tests +900, Docs +51, Config 0, Other +18. Total +2435 across 56 files.

Reproducibility: not applicable. as a bug reproduction; the PR body provides after-patch screenshots for spawn, label follow-up, close, and post-close rejection in a real local gateway setup.

Review metrics: 2 noteworthy metrics.

  • Config/default surfaces: 2 added defaults. acp.delegate.idleHours and acp.delegate.maxAgeHours control when persistent hub-delegated ACP workers are auto-closed.
  • PR size: 56 files, +2784/-349. The feature spans ACP runtime, gateway protocol, session tools, commands, docs, generated fixtures, and tests, so maintainer review should stay product-boundary focused.

Merge readiness
Overall: 🐚 platinum hermit
Proof: 🦞 diamond lobster ✨ media proof bonus
Patch quality: 🐚 platinum hermit
Result: ready for maintainer review.

Overall follows the weaker of proof and patch quality, so missing proof can cap an otherwise strong patch.

Rank-up moves:

  • [P2] Maintainer should explicitly accept the acp.delegate lifecycle defaults and protocol surface before merge.

Risk before merge

  • [P1] Merging creates additive acp.delegate.idleHours and acp.delegate.maxAgeHours defaults that automatically close hub-delegated ACP workers after 72 idle hours or 168 max-age hours; maintainers should accept those lifecycle semantics explicitly.
  • [P1] Owner-scoped delegate labels and A2A skipping change session-state and message-delivery behavior for opt-in delegates, and the supplied real proof covers the main hub flow rather than the full channel/client matrix.
  • [P1] Gateway protocol and session patch additions are additive but compatibility-sensitive for generated clients and strict session-model consumers.

Maintainer options:

  1. Accept The Delegate Contract (recommended)
    A maintainer can accept the additive delegate:true feature with its documented lifecycle defaults and owner-scoped routing, then rely on the supplied proof and CI before merge.
  2. Require Broader Live Proof
    If maintainers want more confidence, ask for one additional live proof pass on another non-thread hub/channel client plus current-head CI before merge.
  3. Defer To The Broader Threadless Session Issue
    If the product direction should solve Decouple mode="session" from thread binding requirement #53548 directly instead of adding a new delegate mode, pause or close this PR and keep the canonical issue open.

Next step before merge

  • [P2] Human maintainer review should decide product and upgrade acceptance of the new ACP delegate contract; no narrow automated repair remains from this review.

Security
Cleared: No concrete security or supply-chain regression was found; the PR does not change dependencies, lockfiles, workflows, credentials, or secret handling, and the new delegate routing remains owner-scoped.

Review details

Best possible solution:

Land the explicit opt-in delegate feature only after maintainer acceptance of the lifecycle defaults and protocol surface; keep broader threadless mode=session decoupling tracked by issue #53548.

Do we have a high-confidence way to reproduce the issue?

Not applicable as a bug reproduction; the PR body provides after-patch screenshots for spawn, label follow-up, close, and post-close rejection in a real local gateway setup.

Is this the best way to solve the issue?

Yes, as an explicit opt-in delegate contract this is a better-scoped path than relaxing every mode=session call; the remaining decision is whether maintainers want these lifecycle defaults and routing semantics in core.

AGENTS.md: found and applied where relevant.

Codex review notes: model internal, reasoning high; reviewed against 68ec783e74b5.

Label changes

Label changes:

  • add proof: sufficient: Contributor real behavior proof is sufficient. The PR body includes current-head screenshots from a real local gateway showing the changed delegate spawn, follow-up, close, and rejected post-close follow-up path.

Label justifications:

  • P2: This is a normal-priority opt-in ACP feature with nontrivial but bounded session routing and lifecycle impact.
  • merge-risk: 🚨 compatibility: The PR adds config defaults plus gateway/session protocol fields that existing generated clients and operators must tolerate.
  • merge-risk: 🚨 session-state: The PR introduces hubDelegated ownership metadata, expiry, close, and maintenance paths for persistent ACP sessions.
  • merge-risk: 🚨 message-delivery: The PR changes delegate follow-up delivery through owner-scoped labels and skips A2A for parent-owned delegate replies.
  • rating: 🐚 platinum hermit: Overall readiness is 🐚 platinum hermit; proof is 🦞 diamond lobster and patch quality is 🐚 platinum hermit.
  • feature: ✨ showcase: ClawSweeper spotlight: unusually compelling feature idea for maintainer attention. The opt-in delegate flow unlocks persistent external ACP workers from hub channels without requiring native message threads while keeping follow-up and close ownership explicit.
  • status: 👀 ready for maintainer look: ClawSweeper has no concrete contributor-facing blocker left for this PR. Sufficient (screenshot): The PR body includes current-head screenshots from a real local gateway showing the changed delegate spawn, follow-up, close, and rejected post-close follow-up path.
  • proof: sufficient: Contributor real behavior proof is sufficient. The PR body includes current-head screenshots from a real local gateway showing the changed delegate spawn, follow-up, close, and rejected post-close follow-up path.
  • proof: 📸 screenshot: Contributor real behavior proof includes screenshot evidence. The PR body includes current-head screenshots from a real local gateway showing the changed delegate spawn, follow-up, close, and rejected post-close follow-up path.
Evidence reviewed

PR surface:

Source +1466, Tests +900, Docs +51, Config 0, Other +18. Total +2435 across 56 files.

View PR surface stats
Area Files Added Removed Net
Source 28 1581 115 +1466
Tests 22 1090 190 +900
Docs 3 93 42 +51
Config 1 1 1 0
Generated 0 0 0 0
Other 2 19 1 +18
Total 56 2784 349 +2435

What I checked:

  • Live PR state: this PR is open at head 327f49a with 56 changed files, +2784/-349, and existing proof plus merge-risk labels. (327f49a99988)
  • Current main still lacks delegate support: Current main still rejects sessions_spawn(runtime="acp", mode="session") without thread=true, and searching current main found no central hubDelegated delegate implementation in the ACP spawn/list/send surfaces. (src/agents/acp-spawn.ts:1334, 68ec783e74b5)
  • Delegate spawn contract: The PR rejects delegate/thread and delegate/run conflicts, keeps normal mode=session thread-gated unless delegate=true, persists hubDelegated metadata, marks delegate turns as internal effects, and returns accepted delegate details. (src/agents/acp-spawn.ts:1339, 327f49a99988)
  • Core delegate policy: The new ACP core helper defines 72-hour idle and 168-hour max-age defaults, strict owner equality, lineage mismatch rejection, owner-scoped label conflicts, exact label lookup, and expiry calculations. (packages/acp-core/src/hub-delegated.ts:14, 327f49a99988)
  • Follow-up delivery path: sessions_send resolves owner-scoped delegate labels before global labels, forbids another owner, and skips A2A delivery for parent-owned background ACP targets to avoid echo loops. (src/agents/tools/sessions-send-tool.ts:216, 327f49a99988)
  • Lifecycle close and maintenance: The lifecycle helper clears delegate identity before runtime close, restores the marker if close fails, scans discovered ACP session stores, filters by owner, and resolves expired delegates for maintenance cleanup. (src/acp/hub-delegated-lifecycle.ts:120, 327f49a99988)

Likely related people:

  • steipete: Path history shows repeated recent work across ACP spawn, session send, sessions patch, ACP metadata persistence, task maintenance, and gateway/session refactors. (role: recent area contributor; confidence: high; commits: db40fde88c6b, 7dea2837565e, 00d8d7ead059; files: src/agents/acp-spawn.ts, src/agents/tools/sessions-send-tool.ts, src/gateway/sessions-patch.ts)
  • vincentkoc: Recent history includes ACP spawn cleanup, explicit sessions_send key resolution, plugin import-cycle fixes touching ACP paths, and local blame on the current-main ACP spawn surface. (role: recent adjacent contributor; confidence: medium; commits: e2524e043865, 3659ff8bbf71, 43c53174c56e; files: src/agents/acp-spawn.ts, src/agents/tools/sessions-send-tool.ts)
  • obviyus: Recent commits touched ACP progress commentary and gateway session bootstrap paths that share the session-send and ACP runtime boundary used by this PR. (role: adjacent owner; confidence: medium; commits: 2bf886b7ddbc, 2d3f3de23549; files: src/agents/acp-spawn.ts, src/agents/tools/sessions-send-tool.ts)
  • openperf: Recent task-maintenance work on reclaiming ACP zombie runs is directly adjacent to the PR's hub-delegated maintenance cleanup path. (role: adjacent maintenance contributor; confidence: medium; commits: 02c7b5b82fc5; files: src/tasks/task-registry.maintenance.ts)
What the crustacean ranks mean
  • 🦀 challenger crab: rare, exceptional readiness with strong proof, clean implementation, and convincing validation.
  • 🦞 diamond lobster: very strong readiness with only minor maintainer review expected.
  • 🐚 platinum hermit: good normal PR, likely mergeable with ordinary maintainer review.
  • 🦐 gold shrimp: useful signal, but proof or patch confidence is still limited.
  • 🦪 silver shellfish: thin signal; proof, validation, or implementation needs work.
  • 🧂 unranked krab: not merge-ready because proof is missing/unusable or there are serious correctness or safety concerns.
  • 🌊 off-meta tidepool: rating does not apply to this item.

Shiny media proof means a screenshot, video, or linked artifact directly shows the changed behavior. Runtime, network, CSP, and security claims still need visible diagnostics.

How this review workflow works
  • ClawSweeper keeps one durable marker-backed review comment per issue or PR.
  • Re-runs edit this comment so the latest verdict, findings, and automation markers stay together instead of adding duplicate bot comments.
  • A fresh review can be triggered by eligible @clawsweeper re-review comments, exact-item GitHub events, scheduled/background review runs, or manual workflow dispatch.
  • PR/issue authors and users with repository write access can comment @clawsweeper re-review or @clawsweeper re-run on an open PR or issue to request a fresh review only.
  • Maintainers can also comment @clawsweeper review to request a fresh review only.
  • Fresh-review commands do not start repair, autofix, rebase, CI repair, or automerge.
  • Maintainer-only repair and merge flows require explicit commands such as @clawsweeper autofix, @clawsweeper automerge, @clawsweeper fix ci, or @clawsweeper address review.
  • Maintainers can comment @clawsweeper explain to ask for more context, or @clawsweeper stop to stop active automation.

@clawsweeper clawsweeper Bot added proof: 🎥 video Contributor real behavior proof includes video or recording evidence. rating: 🧂 unranked krab Not merge-ready due to missing proof or serious correctness/safety concerns. status: 📣 needs proof The PR needs real behavior proof before ClawSweeper can clear the contributor ask. P2 Normal backlog priority with limited blast radius. merge-risk: 🚨 compatibility 🚨 May break existing users, config, migrations, defaults, or upgrade paths. merge-risk: 🚨 session-state 🚨 May lose, corrupt, stale, or mis-associate session, agent, or context state. merge-risk: 🚨 security-boundary 🚨 May affect sandboxing, authorization, credentials, or sensitive data. labels Jun 7, 2026
@scotthuang

Copy link
Copy Markdown
Contributor Author

@clawsweeper re-review

Updated Real behavior proof on the latest head:

  • Moved the split-screen recording URL into the Evidence after fix field (not only under the Video proof subsection), so proof parsing and reviewers see the artifact link in the required evidence slot.
  • Pushed latest code fixes on 410ca3d460f (parentSessionKey patch guard + delegated list expiry uses ACP activity).

Video: https://github.com/user-attachments/assets/226ddef2-22d1-44b2-9709-4cb2c44deb1f

Please re-check real behavior proof and the P1/P2 review items against current head.

@clawsweeper

clawsweeper Bot commented Jun 7, 2026

Copy link
Copy Markdown
Contributor

🦞🧹
ClawSweeper re-review requested.

I asked ClawSweeper to review this item again.
Action: item re-review queued (workflow sweep.yml, event repository_dispatch).
Result: the existing ClawSweeper review comment will be edited in place when the review finishes.

Re-review progress:

@clawsweeper clawsweeper Bot added rating: 🌊 off-meta tidepool PR readiness rating does not apply to this item. and removed proof: 🎥 video Contributor real behavior proof includes video or recording evidence. rating: 🧂 unranked krab Not merge-ready due to missing proof or serious correctness/safety concerns. status: 📣 needs proof The PR needs real behavior proof before ClawSweeper can clear the contributor ask. labels Jun 7, 2026
@scotthuang

Copy link
Copy Markdown
Contributor Author

@clawsweeper re-review

Latest head 534093077e6 includes:

  • ClawSweeper P1/P2 fixes (parentSessionKey patch guard; delegated list expiry uses ACP activity).
  • Real behavior proof video URL moved into Evidence after fix (see prior comment).
  • Test follow-ups: hub-delegate label resolve retry expectations (sessions.test.ts) + overflow mock typing for MiniMax reasoning field.

Please re-review proof + merge risk on current head.

@clawsweeper

clawsweeper Bot commented Jun 7, 2026

Copy link
Copy Markdown
Contributor

🦞🧹
ClawSweeper re-review requested.

I asked ClawSweeper to review this item again.
Action: item re-review queued (workflow sweep.yml, event repository_dispatch).
Result: the existing ClawSweeper review comment will be edited in place when the review finishes.

Re-review progress:

@clawsweeper clawsweeper Bot added proof: sufficient ClawSweeper judged the real behavior proof convincing. proof: 🎥 video Contributor real behavior proof includes video or recording evidence. rating: 🦐 gold shrimp Decent PR readiness signal, but merge confidence is limited. status: 👀 ready for maintainer look ClawSweeper has no concrete contributor-facing blocker left for this PR. and removed rating: 🌊 off-meta tidepool PR readiness rating does not apply to this item. labels Jun 7, 2026
@openclaw-barnacle openclaw-barnacle Bot removed the proof: sufficient ClawSweeper judged the real behavior proof convincing. label Jun 7, 2026
@scotthuang

Copy link
Copy Markdown
Contributor Author

@clawsweeper re-review

Updates on current head e4db52fa069:

  • PR body trimmed: related issues reduced to the key Decouple mode="session" from thread binding requirement #53548 link; out-of-scope list consolidated (no long issue-number laundry list).
  • CI fixes pushed: synced hub-delegate gateway protocol Swift models (pnpm protocol:gen:swift) and refreshed codex-runtime prompt snapshots for the sessions tool surface drift.

Please re-review scope wording, proof, and merge readiness on this head.

scotthuang and others added 29 commits June 11, 2026 20:44
…gent registry

Validate hub-delegated lineage before persisting session-store mutations so
rejected patches cannot leave mismatched spawnedBy rows on disk. Skip
registerSubagentRun for delegate ACP spawns that already create a silent task.

Co-authored-by: Cursor <cursoragent@cursor.com>
Align selectAcpSessionRowForEntry with sessionId-only entry picks, skip deleted-agent
rejection for hub-delegated workers, and pass ACP metadata scope through label resolve.

Co-authored-by: Cursor <cursoragent@cursor.com>
Share delegate/store fixtures, table-drive acp-core pure helpers, split lifecycle
tests by close vs maintenance, and move sessions_send boundaries into a focused
suite while removing cross-layer label/owner/expiry duplicates.

Co-authored-by: Cursor <cursoragent@cursor.com>
Drop cross-layer duplicates for label reuse, resolve wiring, activity projection,
and concurrent auto-label suffixes; consolidate lifecycle into one file with only
close/lock/repair and a single maintenance scan test.

Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
@batmanscode

Copy link
Copy Markdown

love the demo/tutorial, very nice :D

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

agents Agent runtime and tooling app: web-ui App: web-ui commands Command implementations docs Improvements or additions to documentation feature: ✨ showcase ClawSweeper spotlight: unusually compelling feature idea for maintainer attention. gateway Gateway runtime merge-risk: 🚨 compatibility 🚨 May break existing users, config, migrations, defaults, or upgrade paths. merge-risk: 🚨 message-delivery 🚨 May drop, duplicate, misroute, suppress, or wrongly target messages. merge-risk: 🚨 session-state 🚨 May lose, corrupt, stale, or mis-associate session, agent, or context state. P2 Normal backlog priority with limited blast radius. proof: 📸 screenshot Contributor real behavior proof includes screenshot evidence. proof: sufficient ClawSweeper judged the real behavior proof convincing. proof: supplied External PR includes structured after-fix real behavior proof. rating: 🐚 platinum hermit Good normal PR readiness with ordinary maintainer review expected. scripts Repository scripts size: XL status: 👀 ready for maintainer look ClawSweeper has no concrete contributor-facing blocker left for this PR.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants