Metadata-Version: 2.4
Name: pod-memory-manager
Version: 0.2.0
Summary: Memory Manager — DDD + Clean Architecture for POD Manager Agent
License-Expression: MIT
Project-URL: Repository, https://github.com/menriquez11/ColorArtAgentPlatform
Project-URL: Issues, https://github.com/menriquez11/ColorArtAgentPlatform/issues
Classifier: Framework :: FastAPI
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.12
Classifier: Topic :: Database
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Requires-Python: >=3.12
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: fastapi>=0.115
Requires-Dist: uvicorn[standard]>=0.30
Requires-Dist: pydantic>=2.0
Requires-Dist: pydantic-settings>=2.0
Requires-Dist: sqlalchemy[asyncio]>=2.0
Requires-Dist: asyncpg>=0.30
Requires-Dist: alembic>=1.13
Requires-Dist: pgvector>=0.3
Requires-Dist: httpx>=0.27
Requires-Dist: PyJWT[crypto]>=2.10
Requires-Dist: tiktoken<1,>=0.9
Provides-Extra: dev
Requires-Dist: pytest>=8.0; extra == "dev"
Requires-Dist: pytest-asyncio>=0.24; extra == "dev"
Requires-Dist: pytest-cov>=5.0; extra == "dev"
Requires-Dist: pytest-bdd>=7.0; extra == "dev"
Requires-Dist: testcontainers[postgres]>=4.0; extra == "dev"
Requires-Dist: ruff>=0.5; extra == "dev"
Dynamic: license-file

# ColorArt SMA — Stateful Memory Agent

**ColorArt SMA** es un manejador de memoria stateful para agentes de IA. Su objetivo es proporcionar una capa de memoria durable, gobernada y recuperable que pueda ser consumida por runtimes agénticos sin convertir al vector store, al proveedor LLM o al framework del agente en la fuente de verdad.

SMA implementa memoria tipada, recuperación híbrida, construcción de contexto, Promotion Gate, trazabilidad, gobernanza, retención, erasure verificable, proyecciones de embeddings reconstruibles y operación mediante outbox transaccional.

> **Estado actual:** Fase 7.3 certificada y **Gate E cerrado** para el alcance funcional, operacional y de performance definido sobre el nodo de referencia. La certificación no implica HA, multi-región ni un SLA externo sobre infraestructura distinta.

## ¿Por qué existe SMA?

Los agentes necesitan algo más que recuperar documentos similares. Necesitan continuidad y una forma controlada de decidir qué información puede convertirse en memoria durable, quién puede consultarla, cómo se actualiza y cómo se elimina.

SMA separa esas responsabilidades del runtime del agente:

- PostgreSQL mantiene el estado canónico.
- pgvector acelera recuperación semántica, pero los embeddings son proyecciones reconstruibles.
- las escrituras durables de memoria pasan por gates explícitos;
- el scope se aplica antes de que un registro sea elegible para retrieval/ranking;
- provenance, lifecycle, retention y erasure forman parte del modelo de memoria;
- el Trace Ledger conserva evidencia append-only de las ejecuciones;
- el outbox PostgreSQL coordina procesamiento asíncrono idempotente.

SMA **no es un chatbot, un runtime agéntico, un LLM gateway ni una aplicación RAG genérica**. Es un subsistema de memoria que otros agentes pueden consumir mediante API.

## Capacidades principales

### Durable Memory Catalog

SMA administra cuatro tipos principales de memoria durable:

| Tipo | Propósito |
|---|---|
| `POLICY` | Reglas y restricciones que gobiernan el comportamiento del agente. |
| `PREFERENCE` | Preferencias persistentes aplicables al scope autorizado. |
| `FACT` | Afirmaciones estructuradas con confidence, vigencia, lifecycle y provenance. |
| `EPISODIC` | Memorias derivadas de experiencias o ejecuciones estabilizadas. |

El **Trace Ledger** se mantiene separado del catálogo durable y conserva ejecuciones y eventos append-only.

### Retrieval y contexto

- modos `EXACT`, `LEXICAL`, `VECTOR` y `HYBRID`;
- ranking global y degradación explícita;
- búsqueda tipada con scores y provenance;
- paginación autenticada;
- construcción de contexto con presupuesto de tokens;
- fallback lexical cuando el provider semántico no está disponible.

### Promotion y lifecycle

- Promotion Gate para `FACT`, `PREFERENCE` y `EPISODIC`;
- decisiones deterministas con evidencia semántica opcional;
- idempotencia y control de concurrencia;
- deduplicación, supersession, review y rejection;
- revocación y lifecycle exact-scoped.

### Governance

- lineage;
- retention;
- expiration;
- erasure verificable;
- deletion receipts;
- quarantine/review de memoria derivada;
- controles de acceso TENANT/AGENT;
- protección contra recuperación de memorias erased, revoked, superseded o expired.

### Embedding projections

- proyecciones versionadas;
- generación y retry durable;
- rebuild blue/green;
- checkpoints y fencing;
- validación de model/dimension/source schema/content revision;
- switch atómico cuando la cobertura objetivo está completa;
- proyecciones stale o retired fuera del ranking final.

## Arquitectura

```mermaid
flowchart LR
    A[Agent Runtime / Client] -->|REST API| API[FastAPI Product API]

    API --> UC[Application Use Cases]

    UC --> SEARCH[Retrieval & Context]
    UC --> PROMO[Promotion Gate]
    UC --> TRACE[Trace Ledger]
    UC --> GOV[Governance & Lifecycle]

    SEARCH --> UOW[Scoped Unit of Work]
    PROMO --> UOW
    TRACE --> UOW
    GOV --> UOW

    UOW --> PG[(PostgreSQL + pgvector)]
    UOW --> OUTBOX[(Transactional Outbox)]

    SEARCH --> PROVIDER[Ollama / Embedding Provider]

    OUTBOX --> WORKER[Outbox Worker]
    WORKER --> EXTRACT[Extraction]
    WORKER --> EMBED[Embedding Projection]
    WORKER --> GOVERNANCE[Governance Jobs]

    EXTRACT --> PG
    EMBED --> PROVIDER
    EMBED --> PG
    GOVERNANCE --> PG
```

La arquitectura sigue DDD + Clean Architecture. Las dependencias se orientan hacia el dominio y las integraciones externas permanecen detrás de adapters/ports.

Documentación de arquitectura:

- [Memory Manager — DDD + Clean Architecture](docs/architecture/memory-manager-ddd-clean-architecture.md)
- [MemoryRecord aggregate](docs/architecture/memoryrecord-aggregate.md)
- [TraceRun / TraceEvent aggregates](docs/architecture/tracerun-traceevent-aggregates.md)
- [Resumen del Memory Aggregate](docs/architecture/memory-aggregate-summary.md)

## Stack tecnológico

- Python 3.12+
- FastAPI
- Pydantic / pydantic-settings
- SQLAlchemy Async
- asyncpg
- PostgreSQL 16
- pgvector
- Alembic
- Ollama-compatible providers
- HTTPX
- PyJWT
- tiktoken
- Pytest / pytest-asyncio / pytest-bdd
- Testcontainers
- Ruff
- Docker / Docker Compose

## Estructura del repositorio

```text
color-art-sma/
├── src/colorart_memory/
│   ├── api/                 # HTTP adapters y contratos FastAPI
│   ├── application/         # casos de uso, ports y orquestación
│   ├── domain/              # entidades, value objects y reglas de dominio
│   ├── infrastructure/      # persistencia y adapters externos
│   ├── bootstrap/           # composition root / dependency wiring
│   ├── observability/       # métricas e instrumentación
│   └── workers/             # procesamiento durable del outbox
├── alembic/                 # migraciones PostgreSQL
├── tests/                   # unit, integration, e2e y BDD
├── evaluation/              # golden datasets, carga y evidencia de certificación
├── scripts/                 # utilerías operacionales y de certificación
├── docs/
│   ├── architecture/
│   ├── phase1/ ... phase7/
│   ├── runbooks/
│   ├── analysis/
│   └── plans/
├── Dockerfile
├── docker-compose.yml
├── docker-compose.production.yml
└── pyproject.toml
```

## Requisitos

Para desarrollo local:

- Python `3.12+`;
- Docker con Docker Compose;
- puertos `5432`, `11434` y `8088` disponibles cuando se usen los defaults;
- Git.

## Inicio rápido — desarrollo local

### 1. Clonar y preparar configuración

```bash
git clone https://github.com/menriquez11/color-art-sma.git
cd color-art-sma

cp .env.example .env
```

`.env` es configuración local y **no debe versionarse**. `.env.example` contiene únicamente el contrato y valores seguros de desarrollo.

### 2. Levantar PostgreSQL y Ollama

```bash
docker compose up -d postgres ollama
```

Descargar el modelo de embeddings configurado por default:

```bash
docker compose exec ollama ollama pull nomic-embed-text
```

### 3. Crear el entorno Python

```bash
python3.12 -m venv .venv
source .venv/bin/activate

python -m pip install --upgrade pip
python -m pip install -e ".[dev]"
```

### 4. Aplicar migraciones

```bash
alembic upgrade head
alembic check
```

### 5. Ejecutar la API

```bash
uvicorn colorart_memory.main:app \
  --host 0.0.0.0 \
  --port 8088
```

En otro proceso, para habilitar los consumidores asíncronos del outbox:

```bash
python -m colorart_memory.workers.outbox_worker
```

### 6. Verificar el servicio

```bash
curl --fail --silent http://127.0.0.1:8088/health/live
curl --fail --silent http://127.0.0.1:8088/health/ready
curl --fail --silent http://127.0.0.1:8088/health/dependencies
```

En `MEMORY_ENVIRONMENT=local` con OpenAPI habilitado:

```text
http://127.0.0.1:8088/docs
```

OpenAPI/Swagger se deshabilita en producción.

## API de producto

La superficie pública principal está organizada por capabilities:

| Capability | Endpoint principal |
|---|---|
| Search | `POST /api/v1/memory/search` |
| Context build | `POST /api/v1/memory/context` |
| Revocation | `POST /api/v1/memory/revocations` |
| Promotion | `/api/v1/memory/promotion-cases` |
| Trace Ledger | `/api/v1/traces/runs` |
| Embedding maintenance | `/api/v1/memory/embeddings` |
| Governance | `/api/v1/memory/governance` |
| Health | `/health/live`, `/health/ready`, `/health/dependencies` |
| Metrics | `GET /metrics` |

La autorización es fail-closed y se expresa mediante capabilities. Los roles de producto incluyen `AGENT`, `EDITOR`, `REVIEWER` y `ADMIN`.

Para el contrato detallado consulta el reporte de [Fase 7.1 — API de producto](docs/phase7/phase7-1-validation-report.md).

## Configuración

La configuración se carga en `MemorySettings` desde variables de entorno con
prefijo estricto `MEMORY_`. Las variables genéricas sin prefijo se ignoran y el
modelo resultante es inmutable.

Variables principales:

| Variable | Uso |
|---|---|
| `MEMORY_DATABASE_URL` | conexión async a PostgreSQL |
| `MEMORY_ENVIRONMENT` | `local`, `test`, `staging` o `production` |
| `MEMORY_AUTH_MODE` | `dev` o `jwt` |
| `MEMORY_EMBEDDING_PROVIDER` | `ollama` o `noop` en entornos permitidos |
| `MEMORY_OLLAMA_BASE_URL` | endpoint del provider Ollama |
| `MEMORY_OLLAMA_EMBED_MODEL` | modelo de embeddings |
| `MEMORY_EMBEDDING_DIM` | dimensión esperada del vector |
| `MEMORY_TOKEN_ENCODING` | encoding usado exclusivamente para contar tokens de contexto |
| `MEMORY_CONTEXT_MAX_TOKEN_BUDGET` | máximo operacional aceptado por context build; default `1048576`, rango `100..10000000` |
| `MEMORY_SEMANTIC_COMPARATOR_PROVIDER` | comparator semántico |
| `MEMORY_EXTRACTOR_PROVIDER` | provider de extracción de memoria |
| `MEMORY_SEARCH_CURSOR_SIGNING_KEY` | firma HMAC para paginación pública |
| `MEMORY_TRUSTED_HOSTS` | hosts HTTP permitidos |
| `MEMORY_CORS_ALLOWED_ORIGINS` | origins CORS permitidos; vacío = deshabilitado |
| `MEMORY_METRICS_ENABLED` | habilita exposición de métricas |
| `MEMORY_METRICS_BEARER_TOKEN` | protege `/metrics` en producción |

Consulta [.env.example](.env.example) y
[src/colorart_memory/config.py](src/colorart_memory/config.py) como contrato
operativo vigente.

En `POST /api/v1/memory/context`, el runtime llamador debe enviar siempre `token_budget` y elegirlo según la ventana del modelo downstream y los demás consumidores del prompt. `MEMORY_CONTEXT_MAX_TOKEN_BUDGET` es únicamente el guardrail del deployment: no proporciona un presupuesto por defecto, no se aplica mediante clamping y cualquier exceso se rechaza con HTTP 422 antes de retrieval o provider I/O.

El techo de producto de 10,000,000 tokens es una invariante de seguridad versionada en código, no un objetivo ni una recomendación operacional. SMA no descubre automáticamente ventanas de contexto ni mantiene un registro de capacidades por modelo. `MEMORY_TOKEN_ENCODING` permanece independiente y solo determina cómo se cuentan los tokens.

## Observabilidad y health

SMA expone tres niveles de health:

- `/health/live`: comprueba únicamente que el proceso está vivo;
- `/health/ready`: requiere PostgreSQL, pgvector y la revisión Alembic esperada;
- `/health/dependencies`: informa el estado de dependencias semánticas degradables, manteniendo lexical retrieval disponible cuando aplica.

`GET /metrics` expone métricas Prometheus con labels acotados para evitar PII y cardinalidad no controlada. En producción, si las métricas están habilitadas, el endpoint exige un Bearer token dedicado.

Consulta [Fase 7.2 — Observabilidad](docs/phase7/phase7-2-observability-validation-report.md).

## Pruebas y calidad

Instalar dependencias de desarrollo y ejecutar:

```bash
ruff check app tests scripts alembic
pytest -q
```

Para cambios de schema:

```bash
alembic upgrade head
alembic check
```

La suite distingue marcadores `unit`, `integration`, `e2e` y `bdd`:

```bash
pytest -m unit -q
pytest -m integration -q
pytest -m e2e -q
pytest -m bdd -q
```

No se debe declarar que una validación está aprobada si los comandos correspondientes no fueron ejecutados.

## Estado de certificación

La certificación de Fase 7.3 ejecutada el **27 de agosto de 2026** cerró Gate E para el alcance acordado del nodo de referencia.

Resultados principales:

| Criterio | Resultado certificado |
|---|---:|
| Suite funcional | `1,039 passed` |
| Dataset | 100,000 facts + 20,000 episodes |
| HTTP steady | 10 RPS durante 30 minutos |
| Spike | 25 RPS durante 60 segundos |
| Requests | 19,500 / 19,500 HTTP 200 |
| HTTP error rate | 0.000% |
| SQL retrieval p95 | 96.781 ms |
| BuildContext warm p95 | 123.303 ms |
| Recall@10 | 0.928571 |
| nDCG@10 | 0.988188 |
| Native vector coverage | 100% |

El baseline corresponde a la infraestructura descrita en el reporte y **debe repetirse sobre la plataforma destino antes de comprometer capacidad o SLA**.

Evidencia completa: [Fase 7.3 — Certificación de producción](docs/phase7/phase7-3-production-certification-report.md).

## Docker de producción

El repositorio incluye [docker-compose.production.yml](docker-compose.production.yml) con:

- PostgreSQL + pgvector;
- Ollama;
- migración Alembic one-shot;
- API SMA;
- outbox worker;
- filesystem read-only para los procesos SMA;
- ejecución non-root;
- `cap_drop=ALL`;
- `no-new-privileges`;
- readiness healthcheck.

Producción exige configuración explícita de secretos y autenticación, incluyendo `MEMORY_DATABASE_URL`, JWT, `MEMORY_SEARCH_CURSOR_SIGNING_KEY` y `MEMORY_METRICS_BEARER_TOKEN`.

Antes de operar un entorno productivo utiliza el [checklist operacional](docs/runbooks/operations-checklist.md) y los [runbooks](docs/runbooks/README.md).

## Operación y recuperación

Runbooks disponibles:

- [Respuesta a incidentes](docs/runbooks/incident-response.md)
- [Backup PostgreSQL](docs/runbooks/postgres-backup.md)
- [Restore y cutover](docs/runbooks/postgres-restore.md)
- [Replay controlado del outbox](docs/runbooks/outbox-replay.md)
- [Embedding rebuild blue/green](docs/runbooks/embedding-rebuild.md)
- [Checklist operacional](docs/runbooks/operations-checklist.md)

Los procedimientos están diseñados para preservar scope, Unit of Work, Promotion Gate, idempotencia y evidencia operacional.

## Seguridad

Principios mínimos del repositorio:

- no versionar `.env`, secretos, API keys, JWT o credenciales;
- no usar datos reales de clientes en fixtures o pruebas;
- no registrar tokens ni contenido sensible en telemetría;
- mantener autorización y scope antes del retrieval/ranking;
- mantener `MEMORY_AUTH_MODE=dev` únicamente en local/test;
- no habilitar providers `noop`/deterministas fuera de entornos permitidos;
- no realizar escrituras directas que eviten Promotion Gate, Governance Gate o Unit of Work;
- preservar el modelo canonical-data-first: PostgreSQL es la fuente de verdad y los embeddings son proyecciones reconstruibles.

## Alcance actual

Gate E certifica el alcance funcional y operacional acordado para SMA, pero no debe interpretarse como certificación automática de:

- alta disponibilidad;
- multi-región;
- autoscaling multi-réplica;
- PITR administrado por una plataforma cloud;
- dashboards externos;
- SLA de una infraestructura aún no baselineada.

Cada plataforma destino debe ejecutar sus propios capacity tests, recovery drills y controles de infraestructura.

## Documentación

La documentación extensa vive en [`docs/`](docs/).

Puntos de entrada recomendados:

- [Arquitectura](docs/architecture/)
- [Fase 7](docs/phase7/)
- [Runbooks](docs/runbooks/)
- [Publicar la distribución en PyPI](docs/runbooks/publishing-pypi.md)
- [Análisis](docs/analysis/)
- [Planes de implementación](docs/plans/)

El README se mantiene deliberadamente orientado a descubrir el proyecto y comenzar a utilizarlo. Las decisiones arquitectónicas, reportes de validación, evidencia y procedimientos operativos deben permanecer en `docs/`.

## Licencia

`pod-memory-manager` se distribuye bajo la licencia MIT. Conserva el aviso de
copyright y el texto de la licencia al redistribuir el software; consulta
[LICENSE](LICENSE). La licencia no cobra regalías y permite uso comercial,
modificaciones y redistribución.

## Contribución

Antes de proponer un cambio:

1. mantener el cambio enfocado;
2. respetar las fronteras DDD/Clean Architecture existentes;
3. añadir o actualizar pruebas cuando cambie comportamiento;
4. añadir migración Alembic para cambios de schema;
5. actualizar documentación cuando cambie un contrato arquitectónico u operacional;
6. ejecutar al menos `ruff check` y la suite relevante de Pytest;
7. revisar que el commit no incluya secretos, caches, builds ni artefactos temporales.

Los cambios que alteren source-of-truth, scope, Promotion Gate, governance, lifecycle, retrieval, proyecciones o seguridad deben documentar explícitamente su impacto arquitectónico.

## Soporte y mantenimiento

Para incidencias operativas consulta primero [`docs/runbooks/`](docs/runbooks/). Para cambios del producto utiliza el flujo de Issues/Pull Requests del repositorio y adjunta únicamente evidencia libre de secretos y datos personales.

**Maintainer:** [@menriquez11](https://github.com/menriquez11)
