refactor(store/pg): error-propagate parseUUID in remaining kg + memory files

Five files, targeted CRITICAL-site migrations:

- knowledge_graph_temporal.go: SupersedeEntity (line 71 — C1 from red-team,
  UPDATE + INSERT in transaction). ListEntitiesTemporal remains on
  mustParseUUID (WARN-acceptable SELECT WHERE).
- memory_admin.go: ListAllDocuments, GetDocumentDetail, ListChunks (3 sites,
  all return errors). Adds fmt import.
- memory_search.go: Search (1 site, agent_id resolves hybrid FTS+vector).
- knowledge_graph_traversal.go: Traverse (2 sites — agent + startEntity).
- vault_documents_enrichment.go: UpdateSummaryAndReembed (2 sites — tenant,
  doc). FindSimilarDocs was migrated earlier with optAgentUUID wrapper fix.

Phase 4 Steps 4b.6, 4b.8, 4b.9, 4b.11, 4b.12 of agent identity hardening.

Still pending:
- vault_links.go (16 sites — next commit)
- knowledge_graph_embedding.go line 124 (SAFE per scout — audit only)
- agents_export_queries.go lines 312,354 (SAFE cursor per scout — audit only)
This commit is contained in:
viettranx committed 2026-04-11 21:22:23 +07:00
1 parent 63dc84f7e8
commit 2aa3ca31ae
5 files changed
+38 -10

No files matched your search

@@ -68,7 +68,10 @@ func (s *PGKnowledgeGraphStore) ListEntitiesTemporal(ctx context.Context, agentI
// SupersedeEntity atomically expires the old entity and inserts a replacement.
func (s *PGKnowledgeGraphStore) SupersedeEntity(ctx context.Context, old *store.Entity, replacement *store.Entity) error {
aid := mustParseUUID(old.AgentID)
aid, err := parseUUID(old.AgentID)
if err != nil {
return fmt.Errorf("kg supersede entity: %w", err)
}
tx, err := s.db.BeginTx(ctx, nil)
if err != nil {
return fmt.Errorf("supersede begin tx: %w", err)
@@ -15,8 +15,14 @@ func (s *PGKnowledgeGraphStore) Traverse(ctx context.Context, agentID, userID, s
maxDepth = 3
}
aid := mustParseUUID(agentID)
startID := mustParseUUID(startEntityID)
aid, err := parseUUID(agentID)
if err != nil {
return nil, fmt.Errorf("kg traverse: agent: %w", err)
}
startID, err := parseUUID(startEntityID)
if err != nil {
return nil, fmt.Errorf("kg traverse: start: %w", err)
}
tx, err := s.db.BeginTx(ctx, nil)
if err != nil {
+13 -3
View File
@@ -2,6 +2,7 @@ package pg
import (
"context"
"fmt"
"github.com/nextlevelbuilder/goclaw/internal/store"
)
@@ -35,7 +36,10 @@ func (s *PGMemoryStore) ListAllDocumentsGlobal(ctx context.Context) ([]store.Doc
// ListAllDocuments returns all documents for an agent across all users (global + personal).
func (s *PGMemoryStore) ListAllDocuments(ctx context.Context, agentID string) ([]store.DocumentInfo, error) {
aid := mustParseUUID(agentID)
aid, err := parseUUID(agentID)
if err != nil {
return nil, fmt.Errorf("memory list all documents: %w", err)
}
tc, tcArgs, _, err := scopeClause(ctx, 2)
if err != nil {
return nil, err
@@ -57,7 +61,10 @@ func (s *PGMemoryStore) ListAllDocuments(ctx context.Context, agentID string) ([
// GetDocumentDetail returns full document info with chunk and embedding counts.
func (s *PGMemoryStore) GetDocumentDetail(ctx context.Context, agentID, userID, path string) (*store.DocumentDetail, error) {
aid := mustParseUUID(agentID)
aid, err := parseUUID(agentID)
if err != nil {
return nil, fmt.Errorf("memory get document detail: %w", err)
}
var q string
var args []any
@@ -99,7 +106,10 @@ func (s *PGMemoryStore) GetDocumentDetail(ctx context.Context, agentID, userID,
// ListChunks returns chunks for a document identified by agent, user, and path.
func (s *PGMemoryStore) ListChunks(ctx context.Context, agentID, userID, path string) ([]store.ChunkInfo, error) {
aid := mustParseUUID(agentID)
aid, err := parseUUID(agentID)
if err != nil {
return nil, fmt.Errorf("memory list chunks: %w", err)
}
var q string
var args []any
+4 -1
View File
@@ -16,7 +16,10 @@ func (s *PGMemoryStore) Search(ctx context.Context, query string, agentID, userI
maxResults = s.cfg.MaxResults
}
aid := mustParseUUID(agentID)
aid, err := parseUUID(agentID)
if err != nil {
return nil, fmt.Errorf("memory search: %w", err)
}
// FTS search using tsvector
ftsResults, err := s.ftsSearch(ctx, query, aid, userID, maxResults*2)
@@ -10,12 +10,18 @@ import (
// UpdateSummaryAndReembed updates the document summary and re-embeds the combined text.
func (s *PGVaultStore) UpdateSummaryAndReembed(ctx context.Context, tenantID, docID, summary string) error {
tid := mustParseUUID(tenantID)
did := mustParseUUID(docID)
tid, err := parseUUID(tenantID)
if err != nil {
return fmt.Errorf("vault update summary: tenant: %w", err)
}
did, err := parseUUID(docID)
if err != nil {
return fmt.Errorf("vault update summary: doc: %w", err)
}
// Fetch title+path to build embed text.
var title, path string
err := s.db.QueryRowContext(ctx,
err = s.db.QueryRowContext(ctx,
`SELECT title, path FROM vault_documents WHERE id = $1 AND tenant_id = $2`,
did, tid,
).Scan(&title, &path)