Files
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

84 lines
3.6 KiB
Go

package pg
import (
"fmt"
"github.com/nextlevelbuilder/goclaw/internal/config"
"github.com/nextlevelbuilder/goclaw/internal/store"
)
// NewPGStores creates all stores backed by Postgres.
func NewPGStores(cfg store.StoreConfig) (*store.Stores, error) {
db, err := OpenDB(cfg.PostgresDSN)
if err != nil {
return nil, fmt.Errorf("open postgres: %w", err)
}
initSqlx(db)
memCfg := DefaultPGMemoryConfig()
skillsDir := cfg.SkillsStorageDir
if skillsDir == "" {
skillsDir = config.ResolvedDataDirFromEnv() + "/skills-store"
}
subagentTasks := NewPGSubagentTaskStore(db)
pgStores := &store.Stores{
DB: db,
Sessions: NewPGSessionStore(db),
Memory: NewPGMemoryStore(db, memCfg),
Cron: NewPGCronStore(db),
Pairing: NewPGPairingStore(db),
Skills: NewPGSkillStore(db, skillsDir),
Agents: NewPGAgentStore(db),
Providers: NewPGProviderStore(db, cfg.EncryptionKey),
Tracing: NewPGTracingStore(db),
RunTimeline: NewPGRunTimelineStore(db),
MCP: NewPGMCPServerStore(db, cfg.EncryptionKey),
MCPOAuthTokens: NewPGMCPOAuthTokenStore(db, cfg.EncryptionKey),
ChannelInstances: NewPGChannelInstanceStore(db, cfg.EncryptionKey),
ConfigSecrets: NewPGConfigSecretsStore(db, cfg.EncryptionKey),
AgentLinks: NewPGAgentLinkStore(db),
Teams: NewPGTeamStore(db),
BuiltinTools: NewPGBuiltinToolStore(db),
PendingMessages: NewPGPendingMessageStore(db),
ChannelMemory: NewPGChannelMemoryExtractionStore(db),
KnowledgeGraph: NewPGKnowledgeGraphStore(db),
Contacts: NewPGContactStore(db),
Activity: NewPGActivityStore(db),
Snapshots: NewPGSnapshotStore(db),
UsageEvents: NewPGUsageEventStore(db),
BrowserCookies: NewPGBrowserCookieStore(db, cfg.EncryptionKey),
SecureCLI: NewPGSecureCLIStore(db, cfg.EncryptionKey),
SecureCLIGrants: NewPGSecureCLIAgentGrantStore(db, cfg.EncryptionKey),
APIKeys: NewPGAPIKeyStore(db),
Heartbeats: NewPGHeartbeatStore(db),
ConfigPermissions: NewPGConfigPermissionStore(db),
Tenants: NewPGTenantStore(db),
BuiltinToolTenantCfgs: NewPGBuiltinToolTenantConfigStore(db),
SkillTenantCfgs: NewPGSkillTenantConfigStore(db),
SkillEvolution: NewPGSkillEvolutionStore(db),
SystemConfigs: NewPGSystemConfigStore(db),
SubagentTasks: subagentTasks,
SubagentTaskRecovery: subagentTasks,
Vault: NewPGVaultStore(db),
Episodic: NewPGEpisodicStore(db),
EvolutionMetrics: NewPGEvolutionMetricsStore(db),
EvolutionSuggestions: NewPGEvolutionSuggestionStore(db),
BitrixPortals: NewPGBitrixPortalStore(db, cfg.EncryptionKey),
Hooks: NewPGHookStore(db),
Webhooks: NewPGWebhookStore(db),
WebhookCalls: NewPGWebhookCallStore(db),
Workstations: NewPGWorkstationStore(db, cfg.EncryptionKey),
WorkstationLinks: NewPGAgentWorkstationLinkStore(db),
WorkstationPermissions: NewPGWorkstationPermissionStore(db),
WorkstationActivity: NewPGWorkstationActivityStore(db),
UsageCaps: NewPGUsageCapStore(db),
}
// Wire permStore into WorkstationStore so Create seeds allowlist atomically (H5 fix).
// Must happen after both stores are constructed.
pgStores.Workstations.(*PGWorkstationStore).SetPermStore(pgStores.WorkstationPermissions)
return pgStores, nil
}