Files
goclaw/internal/tools/delegation_artifacts_secure.go
Duc Nguyenandntduc bb7712a9ff 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>
2026-07-30 14:17:40 +07:00

49 lines
946 B
Go

package tools
import (
"errors"
"io/fs"
"os"
)
const (
artifactSecureReadBatchSize = 64
artifactSecureMaxDirectoryEntries = 4096
artifactSecureMaxDepth = 64
artifactSecureCleanupEntryBudget = 4096
)
var (
errArtifactSymlink = errors.New("symlink rejected")
errArtifactReparsePoint = errors.New("reparse point rejected")
)
type artifactEntryKind uint8
const (
artifactEntryOther artifactEntryKind = iota
artifactEntryRegular
artifactEntryDirectory
)
type artifactSecureEntry struct {
file *os.File
kind artifactEntryKind
size int64
links uint64
}
func (e *artifactSecureEntry) close() error {
if e == nil || e.file == nil {
return nil
}
return e.file.Close()
}
func (e *artifactSecureEntry) readDirBatch() ([]fs.DirEntry, error) {
if e == nil || e.file == nil || e.kind != artifactEntryDirectory {
return nil, ErrArtifactNonRegular
}
return e.file.ReadDir(artifactSecureReadBatchSize)
}