Files
openclaw/qa/scenarios/channels/subagent-thread-spawn.yaml
Dallin Romney c1b9e36221 test(qa): migrate channel thread and DM isolation scenarios (#101112)
* test(qa): migrate channel thread isolation scenarios

* test(qa): remove stale Matrix scenario fixture

* test(qa): use canonical coverage taxonomy ids

* test(qa): preserve Matrix flow runtime identities

* test(qa): expose Slack thread polling helper

* test(qa): select Matrix for native thread smoke

* test(qa): keep Matrix subagent spawn opt-in

* test(qa): target selected live account in scenario patches
2026-07-06 17:52:38 -07:00

96 lines
3.5 KiB
YAML

title: Matrix subagent thread spawn
scenario:
id: subagent-thread-spawn
surface: channels
coverage:
primary:
- channels.threads
- agents.subagents
objective: Verify sessions_spawn(thread=true, mode=session) creates a persistent Matrix child thread and delivers the child result there.
gatewayConfigPatch:
tools:
profile: coding
channels:
matrix:
accounts:
$selectedAccount:
threadBindings:
enabled: true
spawnSessions: true
groups:
"*":
tools:
allow:
- sessions_spawn
- sessions_yield
successCriteria:
- The parent calls sessions_spawn with thread=true and mode=session.
- Matrix emits the child-session introduction.
- The child completion carries the introduction message as its normalized thread id.
docsRefs:
- docs/channels/matrix.md
- docs/tools/subagents.md
codeRefs:
- src/agents/tools/sessions-spawn-tool.ts
- extensions/qa-matrix/src/adapter.runtime.ts
execution:
kind: flow
channel: matrix
summary: Spawn a bound Matrix child session and require native thread relation evidence on completion.
config:
requiredChannelDriver: live
conversationId: main
childMarker: QA-MATRIX-SUBAGENT-THREAD-OK
prompt: 'Use sessions_spawn for this QA check. task="Finish with exactly QA-MATRIX-SUBAGENT-THREAD-OK." label=qa-thread-subagent thread=true mode=session. After spawn returns status="accepted", wait for the child session reply in the spawned Matrix thread. Do not write QA-MATRIX-SUBAGENT-THREAD-OK in the parent response.'
flow:
steps:
- name: delivers the child result in the spawned Matrix thread
actions:
- assert:
expr: transport.id === 'matrix'
message: subagent thread spawn requires the live Matrix adapter
- resetTransport: true
- sendInbound:
conversation:
id:
ref: config.conversationId
kind: channel
senderId: "@driver:matrix.test"
senderName: QA Driver
text:
expr: "`@openclaw ${config.prompt}`"
- waitForOutbound:
conversation:
id:
ref: config.conversationId
kind: channel
textIncludes: Messages here go directly to this session
timeoutMs:
expr: liveTurnTimeoutMs(env, 120000)
saveAs: intro
- waitForOutbound:
conversation:
id:
ref: config.conversationId
kind: channel
textIncludes:
ref: config.childMarker
threadId:
expr: intro.id
timeoutMs:
expr: liveTurnTimeoutMs(env, 180000)
saveAs: completion
- assert:
expr: completion.threadId === intro.id
message:
expr: "`expected subagent completion in thread ${intro.id}, got ${completion.threadId ?? '<none>'}`"
- set: debugRequests
value:
expr: "env.mock ? [...(await fetchJson(`${env.mock.baseUrl}/debug/requests`))] : []"
- assert:
expr: "!env.mock || debugRequests.some((request) => request.plannedToolName === 'sessions_spawn' && /thread=true mode=session/i.test(String(request.allInputText ?? '')))"
message: expected sessions_spawn(thread=true, mode=session) tool call
detailsExpr: "`${completion.threadId}: ${completion.text}`"