mirror of
https://github.com/tiennm99/goclaw.git
synced 2026-10-20 00:15:16 +00:00
fix(collaboration): harden delegated task isolation (#1486)
* feat(collaboration): isolate delegated artifacts and child runs Isolate delegated inputs and outputs behind secure artifact exchange lifecycles. Scope Agent Link tasks by tenant and root agent, and enforce delegation spawn-tree boundaries. Add process-wide child-run admission and preserve logical media paths across native, MCP, and sandbox execution. * fix(collaboration): harden delegated task isolation Enforce tenant and root-agent task scope across migrations and stores. Add exactly-once async completion delivery, delegated sandbox boundaries, and confined artifact and media recovery across runtime surfaces. * fix(collaboration): recover interrupted async tasks * fix(collaboration): normalize persisted child-run status --------- Co-authored-by: ntduc <ntduc@cpp.ai.vn>
This commit is contained in:
1 parent
496b7ffce6
commit
bb7712a9ff
186 files changed
+18858
-1233
No files matched your search
@@ -0,0 +1,50 @@
|
||||
package tools
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"testing"
|
||||
"time"
|
||||
)
|
||||
|
||||
func TestAnnounceQueueCloseDropsPendingDebounce(t *testing.T) {
|
||||
drained := make(chan struct{}, 1)
|
||||
queue := NewAnnounceQueue(20, 20, func(string, []AnnounceQueueItem, AnnounceMetadata) {
|
||||
drained <- struct{}{}
|
||||
})
|
||||
queue.Enqueue("session", AnnounceQueueItem{SubagentID: "task"}, AnnounceMetadata{})
|
||||
if err := queue.CloseContext(context.Background()); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
select {
|
||||
case <-drained:
|
||||
t.Fatal("pending announce drained after queue close")
|
||||
case <-time.After(50 * time.Millisecond):
|
||||
}
|
||||
}
|
||||
|
||||
func TestAnnounceQueueCloseContextBoundsActiveDrain(t *testing.T) {
|
||||
started := make(chan struct{})
|
||||
release := make(chan struct{})
|
||||
queue := NewAnnounceQueue(1, 1, func(string, []AnnounceQueueItem, AnnounceMetadata) {
|
||||
close(started)
|
||||
<-release
|
||||
})
|
||||
queue.Enqueue("session", AnnounceQueueItem{SubagentID: "task"}, AnnounceMetadata{})
|
||||
select {
|
||||
case <-started:
|
||||
case <-time.After(time.Second):
|
||||
t.Fatal("announce drain did not start")
|
||||
}
|
||||
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 20*time.Millisecond)
|
||||
defer cancel()
|
||||
err := queue.CloseContext(ctx)
|
||||
if !errors.Is(err, ErrAnnounceQueueDrainTimeout) {
|
||||
t.Fatalf("CloseContext error = %v, want typed drain timeout", err)
|
||||
}
|
||||
close(release)
|
||||
if err := queue.CloseContext(context.Background()); err != nil {
|
||||
t.Fatalf("CloseContext retry: %v", err)
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user