Files
goclaw/docs/24-knowledge-vault.md

16 KiB
Raw Permalink Blame History

24 - Knowledge Vault

The Knowledge Vault is a query layer above existing memory systems (episodic memory, knowledge graph, memory files). It provides document registration, bidirectional wikilinks, filesystem sync, and unified search across all knowledge sources.

Not a replacement — extends capability. The vault sits between agents and episodic/KG stores, enabling agents to curate workspace documents with explicit relationships.


1. Architecture Overview

Components

Component Role
VaultStore Interface: document CRUD, link management, hybrid search (FTS+vector)
VaultService Search coordinator: fan-out across vault, episodic, KG; parallel queries with weighted ranking
VaultSyncWorker Filesystem watcher: detects file changes (create/write/delete), syncs content hashes back to registry
VaultRetriever Retrieval adapter: bridges vault search into agent L0 memory system
HTTP Handlers REST endpoints: list, get, search, links

Data Flow

Agent writes document → Workspace FS
                    ↓
              VaultSyncWorker detects change
                    ↓
         Update vault_documents (hash, metadata)
                    ↓
         On agent query: vault_search tool
                    ↓
    VaultSearchService (parallel fan-out)
         ↙        ↓        ↘
    Vault    Episodic    Knowledge Graph
         ↘        ↓        ↙
      Normalize & Weight Scores
         ↓
   Return Top Results

Tenant & Scope Isolation

Documents are scoped by tenant (isolation), agent (per-agent namespace), and document scope (personal/team/shared):

  • personal: Agent-specific documents (agent_context_files, per-user work)
  • team: Team workspace documents (team_context_files)
  • shared: Cross-tenant shared knowledge (future)

Document Scope & Ownership

scope agent_id team_id Visibility
personal set NULL Owning agent only (within tenant)
team NULL set Members of the team (within tenant)
shared NULL NULL All agents within the tenant
custom any any User-defined via custom_scope

DB Invariant (migration 000055)

A CHECK constraint enforces the above table: vault_documents_scope_consistency. Rejects inserts/updates that violate the scope × ownership relationship. scope='custom' is unconstrained (user-defined scopes).

Agent Read Semantics

vault_search, ListDocuments, CountDocuments return:

  • Docs owned by the agent (agent_id = <agent>)
  • PLUS shared docs (agent_id IS NULL)

Within a team context (RunContext with TeamID set), results also include team-scoped docs for that team. Tenant isolation (tenant_id = <tenant>) is always enforced.


2. Data Model

vault_documents

Document registry: metadata pointers. Content lives on filesystem; registry holds path, hash, embeddings, and links.

Column Type Notes
id UUID Primary key
tenant_id UUID Multi-tenant isolation
agent_id UUID Per-agent namespace
scope TEXT personal | team | shared
path TEXT Workspace-relative path (workspace/notes/foo.md)
title TEXT Display name
doc_type TEXT context, memory, note, skill, episodic
content_hash TEXT SHA-256 of file content (detects changes)
embedding vector(1536) pgvector: semantic similarity
tsv tsvector Generated: FTS index on title+path
metadata JSONB Optional custom fields
created_at, updated_at TIMESTAMPTZ Timestamps
Unique constraint (agent_id, scope, path) One doc per path per scope

Indices:

  • idx_vault_docs_tenant — tenant_id (multi-tenant queries)
  • idx_vault_docs_agent_scope — agent_id, scope (agent-scoped filters)
  • idx_vault_docs_type — agent_id, doc_type (type filters)
  • idx_vault_docs_hash — content_hash (change detection)
  • idx_vault_docs_embedding — HNSW vector (semantic search)
  • idx_vault_docs_tsv — GIN FTS index (keyword search)

Bidirectional links between documents (wikilinks, explicit references).

Column Type Notes
id UUID Primary key
from_doc_id UUID Source document
to_doc_id UUID Target document
link_type TEXT wikilink, reference, etc.
context TEXT ~50 chars: surrounding text snippet
created_at TIMESTAMPTZ Creation timestamp
Unique constraint (from_doc_id, to_doc_id, link_type) No duplicate links

Indices:

  • idx_vault_links_from — from_doc_id (outgoing links)
  • idx_vault_links_to — to_doc_id (backlinks)

vault_versions

Version history (v3.1+ preparation; empty in v3.0).

Column Type Notes
id UUID Primary key
doc_id UUID Document reference
version INT Version number
content TEXT Snapshot of document content
changed_by TEXT User/agent identifier
created_at TIMESTAMPTZ Snapshot timestamp

Bidirectional markdown links in the [[target]] format.

Parsing & Extraction

ExtractWikilinks(content string) parses all [[...]] patterns:

  • Format: [[path/to/file.md]] or [[name|display text]] (display text ignored)
  • Returns: []WikilinkMatch with target, context (~50 chars), and byte offset

Examples:

See [[architecture/components]] for details.
Reference [[SOUL.md|agent persona]] here.
Link [[../parent-project]] up.

Edge cases:

  • Empty target [[]] → skipped
  • Whitespace-only targets → trimmed and skipped
  • Paths with spaces: [[foo bar]] → preserved
  • File extensions: .md auto-appended if missing

Resolution Strategy

ResolveWikilinkTarget() finds the document matching a wikilink target:

  1. Exact path matchGetDocument(tenantID, agentID, "path/to/file.md")
  2. With .md suffix — If target lacks .md, retry with suffix
  3. Basename search — Linear search through all agent docs; match by basename (case-insensitive)
  4. Unresolved — Return nil (not an error; backlinks can be incomplete)

Example: [[SOUL.md]] → lookup SOUL.md → fallback to lookup SOUL → scan for any doc with basename SOUL

SyncDocLinks(ctx, vaultStore, doc, content, tenantID, agentID) keeps wikilinks in vault_links in sync with document content:

  1. Extract [[...]] patterns from content
  2. Delete all outgoing links for the document (replace strategy)
  3. For each match:
    • Resolve target via strategy above
    • Create vault_link row if resolved
  4. Return (errors logged, not thrown)

Called during:

  • Document upsert (agent writing to workspace)
  • VaultSyncWorker processing file changes

Hybrid search integrates vault FTS, vector embeddings, episodic memory, and knowledge graph.

Vault Search (Store-Level)

VaultStore.Search(ctx, opts VaultSearchOptions) on single vault:

  • FTS: PostgreSQL plainto_tsquery() on tsv (title+path keywords)
  • Vector: pgvector cosine similarity on embedding (semantic)
  • Combined scoring: Normalize each method's scores (01), then apply query-time weights
  • Results: Top N documents with score

Unified Search (Cross-Store)

VaultSearchService.Search(ctx, opts UnifiedSearchOptions):

Parallel fan-out:

Query → ├─ VaultStore.Search()      [0.4 weight]
        ├─ EpisodicStore.Search()   [0.3 weight]
        └─ KGStore.SearchEntities() [0.3 weight]
                ↓
         Normalize each source
         (max score = 1.0, then * weight)
                ↓
         Merge & deduplicate by ID
                ↓
         Sort by final score DESC
                ↓
         Return top N

Score normalization: Each source's scores scaled to 01 (max_score / weight), then weighted:

  • Vault: 0.4 (keyword + semantic)
  • Episodic: 0.3 (session summaries)
  • KG: 0.3 (entity relationships)

Default max results per source: maxResults * 2 (then deduplicate + cap to maxResults).

Parameters

Param Type Default Notes
Query string Required: natural language
AgentID string Scope to agent
TenantID string Scope to tenant
Scope string all personal, team, shared
DocTypes []string all context, memory, note, skill, episodic
MaxResults int 10 Results per final result set
MinScore float64 0.0 Filter by minimum score

5. Filesystem Sync

VaultSyncWorker watches workspace directories for changes and keeps vault_documents hashes in sync.

Watcher Loop

Uses fsnotify to detect Write, Create, Remove events:

  1. Debounce: 500ms (multiple rapid changes → one batch)
  2. For each file change:
    • Compute SHA-256 hash of file content
    • Compare to vault_documents.content_hash
    • If different: update hash in DB
    • If file deleted: mark metadata["deleted"] = true

Constraints

  • Only syncs registered documents (files already in vault_documents)
  • New files must be registered by agent (via agent write) first
  • Unreadable files → marked as deleted

Setup

syncer := vault.NewVaultSyncWorker(vaultStore)
go syncer.Watch(ctx, workspaceDir, tenantID, agentID)

6. HTTP API

RESTful endpoints for vault operations.

List Documents

Endpoint: GET /v1/agents/{agentID}/vault/documents

Query params:

  • scope — personal, team, or shared (optional)
  • doc_type — comma-separated types (optional)
  • limit — default 20, max 500
  • offset — pagination

Response:

[
  {
    "id": "uuid",
    "agent_id": "uuid",
    "path": "workspace/notes/foo.md",
    "title": "Foo Notes",
    "doc_type": "note",
    "content_hash": "sha256hex",
    "created_at": "2026-04-07T00:00:00Z"
  }
]

Get Document

Endpoint: GET /v1/agents/{agentID}/vault/documents/{docID}

Response: Single VaultDocument object

Endpoint: POST /v1/agents/{agentID}/vault/search

Request body:

{
  "query": "authentication flow",
  "scope": "team",
  "doc_types": ["context", "note"],
  "max_results": 10
}

Response:

[
  {
    "document": { /* VaultDocument */ },
    "score": 0.87,
    "source": "vault"
  },
  {
    "document": { /* episodic record */ },
    "score": 0.65,
    "source": "episodic"
  }
]

Endpoint: GET /v1/agents/{agentID}/vault/documents/{docID}/links

Response:

{
  "outlinks": [
    {
      "id": "uuid",
      "to_doc_id": "uuid",
      "link_type": "wikilink",
      "context": "See [[target]] for details."
    }
  ],
  "backlinks": [
    {
      "id": "uuid",
      "from_doc_id": "uuid",
      "link_type": "wikilink",
      "context": "Reference [[SOUL.md]] here."
    }
  ]
}

List (Cross-Agent)

Endpoint: GET /v1/vault/documents

Query params:

  • agent_id — optional filter to specific agent (otherwise all tenant agents)
  • scope, doc_type, limit, offset — same as per-agent endpoint

7. Tools

Agents access vault via two tools.

Primary discovery tool: Search across all knowledge sources (vault, episodic, KG) with unified ranking.

Parameters:

{
  "query": "string (required)",
  "scope": "string (optional: personal|team|shared)",
  "types": "string (optional: comma-separated doc types)",
  "maxResults": "number (optional: default 10)"
}

Example:

Agent: "Find documents about authentication"
Tool call: vault_search(query="authentication", types="context,note")
Result: Top 10 results from vault + episodic + KG

Create explicit link: Connect two documents (similar to wikilink).

Parameters:

{
  "from": "string (source document path, required)",
  "to": "string (target document path, required)",
  "context": "string (optional: relationship description)"
}

Example:

Agent: "Link the authentication guide to the SOUL file"
Tool call: vault_link(from="docs/auth.md", to="SOUL.md", context="Persona reference")
Result: Explicit link created in vault_links

8. Retriever Integration

VaultRetriever bridges vault search into agent L0 memory system.

Usage

retriever := vault.NewVaultRetriever(searchService)
summaries, err := retriever.RetrieveL0(ctx, agentID, userID, query, config)
// Returns []memory.L0Summary with highest-ranked results

Configuration

type RetrieverConfig struct {
  RelevanceThreshold float64  // default 0.3
  MaxL0Items         int      // default 5
  TenantID           string
}

Used by agent to retrieve relevant documents during think phase (before plan/act).


9. Web UI (v3)

Vault page in dashboard displays:

  • Document list — workspace documents filtered by scope/type
  • Graph visualization — nodes = documents, edges = wikilinks, interactive pan/zoom
  • Search interface — unified cross-store search with source badges
  • Link editor — create/remove links between documents

10. Feature Flags & Configuration

Knowledge Vault is v3-only feature.

  • Edition: Standard and Lite (full support)
  • Prerequisite: PostgreSQL with pgvector extension
  • Storage: vault_* tables created by migration 000038
  • Workspace: Documents organized in agent-level workspace directory (e.g., ~/.goclaw/workspace/agent_name/)

No explicit feature flag; vault is enabled if:

  1. Migration 000038 ran successfully
  2. VaultStore initialized during gateway startup
  3. VaultSyncWorker started

11. Examples

Adding a Document

Agent writes to workspace:

~/.goclaw/workspace/myagent/notes/architecture.md

On next sync (or immediate write):

  1. VaultSyncWorker detects file creation
  2. Computes SHA-256 hash
  3. Vault document auto-registered with metadata

Markdown content:

See [[architecture.md]] for system design.
See [[SOUL.md|persona]] for agent personality.

Agent calls vault_search("system design"):

  1. ExtractWikilinks finds [[architecture.md]] and [[SOUL.md]]
  2. ResolveWikilinkTarget matches to registered documents
  3. SyncDocLinks creates vault_link rows
  4. Backlinks available via /links endpoint

Search Example

Agent: "Find notes about authentication"

Request:

POST /v1/agents/agent-123/vault/search
{
  "query": "authentication flow",
  "scope": "personal",
  "max_results": 5
}

Response (parallel results from vault + episodic + KG):

[
  {
    "document": {
      "id": "doc-456",
      "path": "notes/auth.md",
      "title": "Authentication Flow",
      "doc_type": "note"
    },
    "score": 0.92,
    "source": "vault"
  },
  {
    "id": "episodic-789",
    "title": "Session-2026-04-06",
    "source": "episodic",
    "score": 0.68
  }
]

12. Limitations

  • Vault docs do not auto-embed in system prompt — Must be retrieved via agent tools
  • No full-text indexing on document content — Only title+path FTS; content requires embeddings
  • Sync is one-way — Filesystem changes sync to vault; vault does not write back to FS
  • No conflict resolution — Concurrent edits not detected; last write wins
  • Version history empty — vault_versions table prepared for v3.1

File Reference

Module Path Purpose
Vault service & sync internal/vault/ VaultStore, VaultService, VaultSyncWorker, VaultRetriever, wikilink parsing
Store & HTTP internal/store/vault_store.go, internal/http/vault_handlers.go Store interface, REST endpoints (list, get, search, links)
Tools & migration internal/tools/vault_*.go, migrations/000038_vault_tables.up.sql vault_search and vault_link tools, schema migration

Use grep or your editor's symbol search for specific files.