fix(announce): propagate sender + role through team-task announce re-ingress#1128
Open
mozaa-solana wants to merge 1 commit intonextlevelbuilder:devfrom
Open
Conversation
…ingress
When a member calls team_tasks(action="complete"), goclaw fans the result
back to the Lead's session via the team-task announce queue. The Lead
resumes a turn whose initial user message is the synthesized
"[System Message] Team member ... completed task. Result: ..." string.
Inside that resumed turn, the Lead is a regular agent — it can call any
tool, including write_file and cron mutations. Those tools route through
CheckFileWriterPermission / CheckCronPermission, which in group-scope
sessions deny when the resumed RunRequest carries no SenderID:
permission denied: system context cannot write files in group chats.
If this is a legitimate user action, ensure the acting sender is
preserved through the tool chain.
team_tool_dispatch.go already stamps MetaOriginSenderID and MetaOriginRole
into the dispatch metadata. consumer_handlers.go already reads inMeta on
the completion-side teammate message. The gap was in between:
- announceRouting (cmd/gateway_announce_queue.go) had no field for
OriginSenderID / OriginRole
- The RunRequest it built had no SenderID / Role set
- loop_context.injectContext skips WithSenderID when req.SenderID is
empty — so the Lead's resumed ctx had no sender attribution, and
every group-scope permission check then tripped the deny path.
Subagent path (subagentAnnounceRouting in gateway_subagent_announce_queue.go)
already had these fields wired since nextlevelbuilder#915. This brings the team-task
path to parity. No security relaxation: empty upstream → still empty
downstream (still denies, as intended for genuine system-initiated
turns); only legitimately-attributed dispatches now flow through.
- cmd/gateway_announce_queue.go: add OriginSenderID + OriginRole to
announceRouting; pass them into the RunRequest.
- cmd/gateway_consumer_handlers.go: read MetaOriginSenderID +
MetaOriginRole from inMeta when building the routing struct.
- cmd/gateway_announce_routing_test.go: 2 unit tests guarding both
"real human propagates through" and "empty stays empty" cases so
this regression can't re-land silently.
Tests: existing cmd/ + internal/tools/ suites pass; new tests pass.
3 tasks
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
When a member completes a team task, goclaw fans the result back to the Lead's session via the team-task announce queue. The Lead resumes a turn whose initial user message is the synthesized
[System Message] Team member ... completed task. Result: ...string.Inside that resumed turn, the Lead can call any tool, including `write_file` and `cron` mutations. In group-scope sessions, those tools route through `CheckFileWriterPermission` / `CheckCronPermission`, which deny when the resumed RunRequest carries no SenderID:
`team_tool_dispatch.go` already stamps `MetaOriginSenderID` + `MetaOriginRole` into the dispatch metadata. `consumer_handlers.go` already reads inMeta on the completion-side teammate message. The gap was in between:
The subagent announce path (`subagentAnnounceRouting`) already had these fields wired since #915. This brings the team-task path to parity.
Failure repro
Changes
No security relaxation
Empty upstream → still empty downstream (still denies, as intended for genuine system-initiated turns). Only legitimately-attributed dispatches now flow through.
Test plan
Related
Follow-up to #915 / #1105 (sender propagation through MCP bridge + delegate). Same class of bug, last remaining code path that lost attribution. The c02-choros team had a Lead agent (Neo) consistently failing to log cycle results because of this — diagnostic message in `config_permission_store` was the trail.