# 018 — Shared Knowledge: base de conocimiento compartida entre agentes

## Objetivo

Crear un sistema de conocimiento compartido (`knowledges/` en la raiz del proyecto) donde multiples agentes pueden leer, escribir y buscar documentos en comun. Esto permite colaboracion entre agentes: uno puede registrar informacion que otros consultan.

## Contexto

- Cada agente ya tiene su **knowledge privado** en `agents/<id>/knowledge/` con SQLite FTS5 index (`shell/knowledge/store.go`).
- Los tipos puros ya existen: `pkg/knowledge.Document`, `SearchResult`, `Store` interface.
- Las tools de knowledge ya existen: `tools/knowledgetools/` (search, read, write, list).
- El `FileStore` en `shell/knowledge/` ya implementa todo el CRUD + FTS5.
- Lo que falta es una **instancia compartida** de `FileStore` apuntando a `knowledges/` con tools dedicadas que multiples agentes puedan usar.

## Arquitectura

```
knowledges/                      ← carpeta raiz, documentos .md compartidos
knowledges/data/knowledge.db     ← SQLite FTS5 index compartido (en .gitignore)

pkg/knowledge/                   ← sin cambios, los tipos puros ya cubren
shell/knowledge/store.go         ← sin cambios, FileStore ya es reutilizable
tools/knowledgetools/shared.go   ← NEW: tools prefijadas shared_knowledge_*
agents/runtime.go                ← instanciar shared store + registrar tools
internal/config/schema.go        ← config para habilitar shared knowledge
```

### Patron pure core / impure shell

- `pkg/` — sin cambios, `knowledge.Store` interface ya sirve
- `shell/knowledge/` — sin cambios, `FileStore` ya funciona con cualquier directorio
- `tools/knowledgetools/` — nuevas tools que wrappean el store compartido
- `agents/runtime.go` — composicion: crea shared store y registra tools

## Tareas

### Fase 1: Config

- [ ] **1.1** Agregar seccion `shared_knowledge` al config en `internal/config/schema.go`:
  ```go
  type SharedKnowledgeCfg struct {
      Enabled bool   `yaml:"enabled"` // default false
      Dir     string `yaml:"dir"`     // default "knowledges"
      DBPath  string `yaml:"db_path"` // default "knowledges/data/knowledge.db"
  }
  ```
- [ ] **1.2** Agregar campo `SharedKnowledge SharedKnowledgeCfg` al `ToolsCfg` (o al `AgentConfig` directamente).

### Fase 2: Tools compartidas en `tools/knowledgetools/`

- [ ] **2.1** Crear `tools/knowledgetools/shared.go` con tools prefijadas `shared_knowledge_*`:
  - `shared_knowledge_search` — buscar en la base compartida
  - `shared_knowledge_read` — leer un documento compartido por slug
  - `shared_knowledge_write` — crear/actualizar un documento compartido
  - `shared_knowledge_list` — listar todos los documentos compartidos
  - Reutilizar `KnowledgeStore` interface y la misma logica de las tools privadas pero con nombres y descripciones que indican "shared across all agents"

- [ ] **2.2** Cada tool debe incluir en su descripcion que es conocimiento **compartido** entre agentes:
  ```
  "Search the shared knowledge base accessible by all agents. Use this to find information other agents have recorded."
  ```

- [ ] **2.3** Funcion constructora:
  ```go
  // NewSharedKnowledgeTools creates all shared knowledge tools backed by the given store.
  func NewSharedKnowledgeTools(store KnowledgeStore) []tools.Tool
  ```

### Fase 3: Integracion en runtime

- [ ] **3.1** En `agents/runtime.go`, si `cfg.Tools.SharedKnowledge.Enabled` (o donde se ponga en config):
  - Crear un `shellknowledge.New(dir, dbPath, logger)` con la ruta compartida
  - Llamar `Sync(ctx)` al arrancar
  - Registrar las tools de `NewSharedKnowledgeTools(sharedStore)` en el registry
  - Guardar referencia para cerrar en defer

- [ ] **3.2** El shared store debe ser **una instancia por agente** (cada proceso abre su propia conexion SQLite al mismo archivo DB). SQLite soporta lecturas concurrentes y escrituras serializadas con WAL mode.

- [ ] **3.3** Habilitar WAL mode en el shared store para mejor concurrencia entre procesos:
  ```go
  db.Exec("PRAGMA journal_mode=WAL")
  ```
  Esto puede ir en `shell/knowledge/store.go` `New()` para beneficiar tambien al store privado.

### Fase 4: Carpeta `knowledges/`

- [ ] **4.1** Crear `knowledges/` en la raiz del proyecto con un `README.md` explicando su proposito.
- [ ] **4.2** Agregar `knowledges/data/` a `.gitignore` (la DB no se commitea, los .md si).

### Fase 5: Coexistencia con knowledge privado

- [ ] **5.1** Un agente puede tener **ambos** habilitados: knowledge privado (`agents/<id>/knowledge/`) y shared (`knowledges/`). Las tools se distinguen por nombre:
  - `knowledge_search` / `knowledge_read` / `knowledge_write` / `knowledge_list` → privado
  - `shared_knowledge_search` / `shared_knowledge_read` / `shared_knowledge_write` / `shared_knowledge_list` → compartido

- [ ] **5.2** Documentar en el system prompt de los agentes la diferencia:
  - Knowledge privado: "tu base de conocimiento personal, solo tu puedes ver"
  - Knowledge compartido: "base compartida entre todos los agentes, usa para colaborar"

### Fase 6: Tests

- [ ] **6.1** Test de `NewSharedKnowledgeTools` — verificar que genera 4 tools con nombres `shared_knowledge_*`.
- [ ] **6.2** Test de integracion: dos stores apuntando al mismo directorio pueden leer lo que el otro escribe (simula dos agentes).
- [ ] **6.3** Test de concurrencia basico con WAL mode.

### Fase 7: Cleanup y docs

- [ ] **7.1** Actualizar `CLAUDE.md` — agregar `knowledges/` a la estructura de directorios.
- [ ] **7.2** Actualizar `.gitignore` con `knowledges/data/`.
- [ ] **7.3** Ejemplo de config habilitando shared knowledge en un agente existente.

---

## Ejemplo de config

```yaml
tools:
  knowledge:
    enabled: true          # knowledge privado del agente
    dir: "knowledge"       # relativo a agents/<id>/

  shared_knowledge:
    enabled: true          # knowledge compartido
    dir: "knowledges"      # relativo a la raiz del proyecto
    db_path: "knowledges/data/knowledge.db"
```

## Ejemplo de flujo

```
1. agente-A recibe: "investiga X y guarda lo que encuentres"
   → LLM usa shared_knowledge_write(slug: "investigacion-x", content: "...")
   → Se escribe knowledges/investigacion-x.md + actualiza FTS5

2. agente-B recibe: "que sabemos sobre X?"
   → LLM usa shared_knowledge_search(query: "X")
   → Encuentra el documento que escribio agente-A
   → shared_knowledge_read(slug: "investigacion-x")
   → Responde con la informacion

3. Agentes colaboran acumulando conocimiento en la misma base
```

## Decisiones de diseno

- **Reusar FileStore**: no crear un store nuevo. `shell/knowledge.FileStore` ya tiene todo (CRUD, FTS5, Sync). Solo se instancia con una ruta diferente.
- **WAL mode**: permite que multiples procesos lean/escriban concurrentemente. Es la forma estandar de compartir SQLite entre procesos.
- **Prefix `shared_knowledge_`**: diferencia claramente las tools compartidas de las privadas. El LLM sabe cual usar segun contexto.
- **Los .md se commitean, la DB no**: los documentos compartidos forman parte del repo (versionados). La DB FTS5 se reconstruye con `Sync()` al arrancar.
- **Sin control de acceso por agente**: cualquier agente con shared_knowledge habilitado puede leer y escribir. Simplicidad primero; RBAC se puede agregar despues si hace falta.

## Prerequisitos

- Knowledge privado ya funcional (pkg/knowledge, shell/knowledge, tools/knowledgetools) — ya implementado.
- No tiene dependencias externas nuevas.

## Riesgos

- **Contention en escritura**: si muchos agentes escriben simultaneamente, SQLite serializa las escrituras. Con WAL mode esto es manejable para el volumen esperado.
- **Sync al arrancar**: si hay muchos documentos, el Sync inicial puede tardar. No deberia ser problema con volumenes pequenos.
- **Conflictos de slug**: dos agentes podrian sobreescribir el mismo documento. Esto es intencional (ultimo gana), pero el LLM debe ser consciente via el system prompt.
