Compare commits
1 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
6d15abcb1a |
@@ -1,14 +1,11 @@
|
|||||||
# Filosofía del Sistema
|
# Filosofía del Sistema TZZR
|
||||||
|
|
||||||
## Visión
|
**Versión:** 5.0
|
||||||
|
**Fecha:** 2024-12-24
|
||||||
|
|
||||||
TZZR es un sistema de construcción de arquitecturas personales y empresariales mediante instancias Claude.
|
---
|
||||||
|
|
||||||
```
|
## 10 Principios Fundacionales
|
||||||
Claude Instances → Construyen → Servidores Clonables → Funcionan Independientes
|
|
||||||
```
|
|
||||||
|
|
||||||
## Principios Fundamentales
|
|
||||||
|
|
||||||
### 1. Constructores, no gestores
|
### 1. Constructores, no gestores
|
||||||
|
|
||||||
@@ -17,22 +14,22 @@ Las instancias Claude son **constructores de arquitecturas**, no gestores perman
|
|||||||
- Cada instancia diseña y construye la arquitectura de un servidor
|
- Cada instancia diseña y construye la arquitectura de un servidor
|
||||||
- Cuando la arquitectura esté madura, el servidor será **clonable e independiente**
|
- Cuando la arquitectura esté madura, el servidor será **clonable e independiente**
|
||||||
- Funcionará sin necesidad de su instancia Claude
|
- Funcionará sin necesidad de su instancia Claude
|
||||||
- Solo los servidores del propietario original mantendrán conexión con Claude
|
- Solo los servidores del propietario original mantienen conexión con Claude
|
||||||
|
|
||||||
### 2. Descentralización operativa
|
### 2. Descentralización operativa
|
||||||
|
|
||||||
```
|
```
|
||||||
Architect App (centralizado) → Diseña moldes
|
Architect App (centralizado) → Diseña moldes
|
||||||
↓
|
↓
|
||||||
Instancias reales (descentralizadas)
|
Instancias reales (descentralizadas)
|
||||||
↓
|
↓
|
||||||
Cada una con su CORP, su DECK, sus agentes
|
Cada una con su CORP, su DECK, sus agentes
|
||||||
```
|
```
|
||||||
|
|
||||||
### 3. Referencias ligeras mediante hashes
|
### 3. Referencias ligeras mediante hashes
|
||||||
|
|
||||||
```
|
```
|
||||||
DEFINICIÓN ORIGINAL → SHA-256 → HASH UNÍVOCO (64 chars)
|
DEFINICIÓN ORIGINAL → SHA-256 → HASH UNÍVOCO (64 chars)
|
||||||
```
|
```
|
||||||
|
|
||||||
El hash es una referencia ligera que arrastra toda la información del original sin duplicarla.
|
El hash es una referencia ligera que arrastra toda la información del original sin duplicarla.
|
||||||
@@ -47,15 +44,15 @@ El hash es una referencia ligera que arrastra toda la información del original
|
|||||||
|
|
||||||
### 5. Período flotante antes de inmutabilidad
|
### 5. Período flotante antes de inmutabilidad
|
||||||
|
|
||||||
Los datos pasan por un período flotante que permite mejora antes del sellado definitivo por FELDMAN.
|
Los datos pasan por un período flotante que permite mejora antes del sellado definitivo.
|
||||||
|
|
||||||
```
|
```
|
||||||
Dato nuevo → Período flotante → Verificación SENTINEL → Sellado FELDMAN → Inmutable
|
Dato nuevo → Período flotante (24h) → Verificación SENTINEL → Sellado FELDMAN → Inmutable
|
||||||
```
|
```
|
||||||
|
|
||||||
### 6. Renombrabilidad de agentes
|
### 6. Renombrabilidad de agentes
|
||||||
|
|
||||||
Los componentes marcados como "Renombrable: Sí" pueden personalizarse:
|
Los componentes marcados como renombrables pueden personalizarse:
|
||||||
|
|
||||||
```
|
```
|
||||||
CLARA → "Lucía"
|
CLARA → "Lucía"
|
||||||
@@ -75,10 +72,10 @@ GRACE extrae y comprende, pero **nunca modifica** el contenido original.
|
|||||||
|
|
||||||
SENTINEL opera en dos modos:
|
SENTINEL opera en dos modos:
|
||||||
|
|
||||||
| Modo | Frecuencia | Alcance |
|
| Modo | Frecuencia | Alcance | Tecnología |
|
||||||
|------|------------|---------|
|
|------|------------|---------|------------|
|
||||||
| **LIGHT** | Cada 5 min | Todos los registros |
|
| **LIGHT** | Cada 5 min | Todos los registros | Reglas automáticas |
|
||||||
| **DEEP** | Cada 1 hora | Muestreo con LLM |
|
| **DEEP** | Cada 1 hora | Muestreo | LLM análisis |
|
||||||
|
|
||||||
### 9. Zero-retention en interfaces móviles
|
### 9. Zero-retention en interfaces móviles
|
||||||
|
|
||||||
@@ -105,8 +102,4 @@ Cada instancia:
|
|||||||
- Tiene su propio bucket de almacenamiento
|
- Tiene su propio bucket de almacenamiento
|
||||||
- Puede renombrar sus agentes
|
- Puede renombrar sus agentes
|
||||||
- Opera de forma descentralizada
|
- Opera de forma descentralizada
|
||||||
- Se conecta a servicios compartidos (GRACE, THE FACTORY, CIRCLE...)
|
- Se conecta a servicios compartidos (GRACE, THE FACTORY, CIRCLE)
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
*Actualizado: 2025-12-21*
|
|
||||||
129
00_VISION/glosario.md
Normal file
129
00_VISION/glosario.md
Normal file
@@ -0,0 +1,129 @@
|
|||||||
|
# Glosario TZZR
|
||||||
|
|
||||||
|
**Versión:** 5.0
|
||||||
|
**Fecha:** 2024-12-24
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Entidades Base
|
||||||
|
|
||||||
|
| Término | Hash | Descripción | Estado |
|
||||||
|
|---------|------|-------------|--------|
|
||||||
|
| **HST** | h_maestro | Hash Semantic Tagging - Etiquetas semánticas visuales | Implementado |
|
||||||
|
| **ITM** | h_item | Ítems ideales - Definiciones del plano T0 | Planificado |
|
||||||
|
| **PLY** | h_player | Players - Identidad de actores | Planificado |
|
||||||
|
| **LOC** | h_loc | Locations - Ubicaciones geográficas | Planificado |
|
||||||
|
| **FLG** | h_flag | Flags - Marcos jurídicos y banderas | Planificado |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Planos de Datos
|
||||||
|
|
||||||
|
| Plano | Tabla | Descripción |
|
||||||
|
|-------|-------|-------------|
|
||||||
|
| **T0** | items | Lo ideal, la partitura, estado futuro deseado |
|
||||||
|
| **MST** | milestones | Plano burocrático - documentos, hitos, estados |
|
||||||
|
| **BCK** | bloques | Plano físico - acciones, evidencias, trabajo real |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Agentes
|
||||||
|
|
||||||
|
### Ingesta
|
||||||
|
| Agente | Servidor | Puerto | Descripción |
|
||||||
|
|--------|----------|--------|-------------|
|
||||||
|
| **CLARA** | DECK | 5051 | Recoge información personal, log inmutable |
|
||||||
|
| **MARGARET** | CORP | 5051 | Recoge información corporativa, log inmutable |
|
||||||
|
|
||||||
|
### Orquestación
|
||||||
|
| Agente | Servidor | Puerto | Descripción |
|
||||||
|
|--------|----------|--------|-------------|
|
||||||
|
| **ALFRED** | DECK | 5052 | Flujos predefinidos personales |
|
||||||
|
| **JARED** | CORP | 5052 | Flujos predefinidos corporativos (más potente) |
|
||||||
|
|
||||||
|
### Procesamiento
|
||||||
|
| Agente | Servidor | Puerto | Descripción |
|
||||||
|
|--------|----------|--------|-------------|
|
||||||
|
| **MASON** | CORP | 5053 | Enriquecimiento, ventana flotante 24h |
|
||||||
|
| **FELDMAN** | CORP | 5054 | Consolidación final, blockchain, inmutable |
|
||||||
|
| **SENTINEL** | - | - | Auditoría LIGHT (5min) + DEEP (1h) [planificado] |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Servicios GPU (RunPod)
|
||||||
|
|
||||||
|
| Servicio | Endpoint | Descripción | Estado |
|
||||||
|
|----------|----------|-------------|--------|
|
||||||
|
| **GRACE** | r00x4g3rrwkbyh | IA cognitiva, extracción (18 módulos) | Bloqueado |
|
||||||
|
| **PENNY** | 0mxhaokgsmgee3 | Asistente personal, generación texto | Planificado |
|
||||||
|
| **FACTORY** | ddnuk6y35zi56a | Generación iterativa | Planificado |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Servidores
|
||||||
|
|
||||||
|
| Servidor | IP | Rol |
|
||||||
|
|----------|-----|-----|
|
||||||
|
| **ARCHITECT** | 69.62.126.110 | Coordinador central, Gitea, PostgreSQL |
|
||||||
|
| **DECK** | 72.62.1.113 | Servidor personal |
|
||||||
|
| **CORP** | 92.112.181.188 | Servidor empresarial |
|
||||||
|
| **HST** | 72.62.2.84 | API tags semánticos |
|
||||||
|
| **LOCKER** | Cloudflare R2 | Almacenamiento (5 buckets) |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Hashes y Identificadores
|
||||||
|
|
||||||
|
| Prefijo | Tipo | Ejemplo | Descripción |
|
||||||
|
|---------|------|---------|-------------|
|
||||||
|
| **h_maestro** | SHA-256 | `a1b2c3...` | Hash de tag HST |
|
||||||
|
| **h_instancia** | SHA-256 | `d4e5f6...` | Identidad servidor/contexto |
|
||||||
|
| **h_entrada** | SHA-256 | `g7h8i9...` | Hash contenedor ingesta |
|
||||||
|
| **h_bloque** | SHA-256 | `j0k1l2...` | Hash de bloque BCK |
|
||||||
|
| **h_milestone** | SHA-256 | `m3n4o5...` | Hash de milestone MST |
|
||||||
|
| **H_proyecto** | Prefijo | `H_tzzr_genesis` | Identificador proyecto legible |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Interfaces
|
||||||
|
|
||||||
|
| Interfaz | Tipo | Descripción |
|
||||||
|
|----------|------|-------------|
|
||||||
|
| **PACKET** | App móvil | Captura multimedia, zero-retention |
|
||||||
|
| **Vision Builder** | Web | Diseño de vida mediante curación visual |
|
||||||
|
| **Mind Link** | Web | Compartición de información |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Protocolos
|
||||||
|
|
||||||
|
| Protocolo | Versión | Descripción |
|
||||||
|
|-----------|---------|-------------|
|
||||||
|
| **S-CONTRACT** | v2.1 | Comunicación con IAs (context, deployment, envelope, payload) |
|
||||||
|
| **locker://** | - | Referencias almacenamiento R2 |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Grupos HST
|
||||||
|
|
||||||
|
| Grupo | Cantidad | Descripción |
|
||||||
|
|-------|----------|-------------|
|
||||||
|
| **hst** | 639 | Tags del sistema base |
|
||||||
|
| **spe** | 145 | Tags específicos |
|
||||||
|
| **vsn** | 84 | Visiones |
|
||||||
|
| **flg** | 65 | Banderas/países |
|
||||||
|
| **vue** | 21 | Vistas |
|
||||||
|
| **hsu** | - | Tags usuario (extensión) |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Estados de Pipeline
|
||||||
|
|
||||||
|
| Estado | Etapa | Descripción |
|
||||||
|
|--------|-------|-------------|
|
||||||
|
| **recibido** | CLARA/MARGARET | Contenedor ingresado, inmutable |
|
||||||
|
| **en_edicion** | MASON | Usuario enriqueciendo datos |
|
||||||
|
| **listo** | MASON | Listo para consolidar |
|
||||||
|
| **pendiente** | FELDMAN | En cola de consolidación |
|
||||||
|
| **consolidado** | FELDMAN | Registrado en milestone/bloque |
|
||||||
|
| **sellado** | NOTARIO | Blockchain confirmado |
|
||||||
154
01_ARQUITECTURA/overview.md
Normal file
154
01_ARQUITECTURA/overview.md
Normal file
@@ -0,0 +1,154 @@
|
|||||||
|
# Arquitectura Overview
|
||||||
|
|
||||||
|
**Versión:** 5.0
|
||||||
|
**Fecha:** 2024-12-24
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Diagrama General
|
||||||
|
|
||||||
|
```
|
||||||
|
┌─────────────────────────────────────────────────────────────────────────┐
|
||||||
|
│ CAPA DE COORDINACIÓN │
|
||||||
|
│ │
|
||||||
|
│ ┌─────────────────────────────────────────────────────────────────┐ │
|
||||||
|
│ │ ARCHITECT (69.62.126.110) │ │
|
||||||
|
│ │ ┌──────────┐ ┌──────────┐ ┌────────────┐ ┌───────────────┐ │ │
|
||||||
|
│ │ │PostgreSQL│ │ Gitea │ │Orchestrator│ │ Infisical │ │ │
|
||||||
|
│ │ │ central │ │ 25 repos │ │ v5 │ │ Secrets │ │ │
|
||||||
|
│ │ └──────────┘ └──────────┘ └────────────┘ └───────────────┘ │ │
|
||||||
|
│ └─────────────────────────────────────────────────────────────────┘ │
|
||||||
|
└─────────────────────────────────────────────────────────────────────────┘
|
||||||
|
│ │ │
|
||||||
|
▼ ▼ ▼
|
||||||
|
┌─────────────────────────────────────────────────────────────────────────┐
|
||||||
|
│ CAPA DE SERVIDORES │
|
||||||
|
│ │
|
||||||
|
│ ┌───────────────────┐ ┌───────────────────┐ ┌───────────────────┐ │
|
||||||
|
│ │ DECK │ │ CORP │ │ HST │ │
|
||||||
|
│ │ 72.62.1.113 │ │ 92.112.181.188 │ │ 72.62.2.84 │ │
|
||||||
|
│ │ │ │ │ │ │ │
|
||||||
|
│ │ CLARA :5051 │ │ MARGARET :5051 │ │ 973 tags │ │
|
||||||
|
│ │ ALFRED :5052 │ │ JARED :5052 │ │ API pública │ │
|
||||||
|
│ │ │ │ MASON :5053 │ │ Directus :8055 │ │
|
||||||
|
│ │ Mailcow │ │ FELDMAN :5054 │ │ │ │
|
||||||
|
│ │ Vaultwarden │ │ │ │ │ │
|
||||||
|
│ │ Directus │ │ Odoo │ │ │ │
|
||||||
|
│ └───────────────────┘ │ Nextcloud │ └───────────────────┘ │
|
||||||
|
│ │ └───────────────────┘ │ │
|
||||||
|
│ │ │ │ │
|
||||||
|
│ └─────────────────────────┼──────────────────────┘ │
|
||||||
|
│ │ │
|
||||||
|
└───────────────────────────────────┼─────────────────────────────────────┘
|
||||||
|
▼
|
||||||
|
┌─────────────────────────────────────────────────────────────────────────┐
|
||||||
|
│ CAPA DE ALMACENAMIENTO │
|
||||||
|
│ │
|
||||||
|
│ ┌─────────────────────────────────────────────────────────────────┐ │
|
||||||
|
│ │ Cloudflare R2 │ │
|
||||||
|
│ │ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌────────┐ │ │
|
||||||
|
│ │ │architect │ │ deck │ │ corp │ │ hst │ │ locker │ │ │
|
||||||
|
│ │ │ backups │ │ archivos │ │ archivos │ │ imágenes │ │ general│ │ │
|
||||||
|
│ │ └──────────┘ └──────────┘ └──────────┘ └──────────┘ └────────┘ │ │
|
||||||
|
│ └─────────────────────────────────────────────────────────────────┘ │
|
||||||
|
└─────────────────────────────────────────────────────────────────────────┘
|
||||||
|
│
|
||||||
|
▼
|
||||||
|
┌─────────────────────────────────────────────────────────────────────────┐
|
||||||
|
│ CAPA GPU (RunPod) │
|
||||||
|
│ Estado: BLOQUEADO - Workers no inician │
|
||||||
|
│ │
|
||||||
|
│ ┌──────────┐ ┌──────────┐ ┌──────────┐ │
|
||||||
|
│ │ GRACE │ │ PENNY │ │ FACTORY │ │
|
||||||
|
│ │ 18 módulos│ │ texto │ │generación│ │
|
||||||
|
│ └──────────┘ └──────────┘ └──────────┘ │
|
||||||
|
└─────────────────────────────────────────────────────────────────────────┘
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Flujo de Datos
|
||||||
|
|
||||||
|
```
|
||||||
|
PACKET (App móvil)
|
||||||
|
│
|
||||||
|
│ POST /ingest
|
||||||
|
│ Content-Type: multipart/form-data
|
||||||
|
│ X-Auth-Key: {h_instancia}
|
||||||
|
│
|
||||||
|
▼
|
||||||
|
┌─────────────────────────────────────────┐
|
||||||
|
│ CLARA (DECK) / MARGARET (CORP) │
|
||||||
|
│ │
|
||||||
|
│ 1. Validar h_instancia │
|
||||||
|
│ 2. Calcular h_entrada (SHA-256) │
|
||||||
|
│ 3. Subir archivos a R2 │
|
||||||
|
│ 4. Insertar en clara_log/margaret_log │
|
||||||
|
│ 5. Estado: 'recibido' (inmutable) │
|
||||||
|
└─────────────────────────────────────────┘
|
||||||
|
│
|
||||||
|
▼
|
||||||
|
┌─────────────────────────────────────────┐
|
||||||
|
│ ALFRED (DECK) / JARED (CORP) │
|
||||||
|
│ │
|
||||||
|
│ 1. Aplicar flujos predefinidos │
|
||||||
|
│ 2. Ejecutar reglas automáticas │
|
||||||
|
│ 3. Enviar a MASON si requiere mejora │
|
||||||
|
└─────────────────────────────────────────┘
|
||||||
|
│
|
||||||
|
▼
|
||||||
|
┌─────────────────────────────────────────┐
|
||||||
|
│ MASON │
|
||||||
|
│ │
|
||||||
|
│ 1. Recibir de ALFRED/JARED │
|
||||||
|
│ 2. Ventana flotante 24h │
|
||||||
|
│ 3. Usuario enriquece datos │
|
||||||
|
│ 4. [Futuro] GRACE extrae información │
|
||||||
|
│ 5. Enviar a FELDMAN cuando listo │
|
||||||
|
└─────────────────────────────────────────┘
|
||||||
|
│
|
||||||
|
▼
|
||||||
|
┌─────────────────────────────────────────┐
|
||||||
|
│ FELDMAN │
|
||||||
|
│ │
|
||||||
|
│ 1. Recibir en feldman_cola │
|
||||||
|
│ 2. Validar reglas (M-001, M-002, M-003)│
|
||||||
|
│ 3. Crear milestone o bloque │
|
||||||
|
│ 4. Calcular hash_contenido │
|
||||||
|
│ 5. Encadenar (hash_previo) │
|
||||||
|
│ 6. [Futuro] Merkle tree, blockchain │
|
||||||
|
└─────────────────────────────────────────┘
|
||||||
|
│
|
||||||
|
▼
|
||||||
|
┌─────────────────────────────────────────┐
|
||||||
|
│ SENTINEL (planificado) │
|
||||||
|
│ │
|
||||||
|
│ LIGHT: Cada 5 min, reglas automáticas │
|
||||||
|
│ DEEP: Cada 1 hora, muestreo con LLM │
|
||||||
|
└─────────────────────────────────────────┘
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Comunicación Entre Servidores
|
||||||
|
|
||||||
|
| Origen | Destino | Protocolo | Puerto | Propósito |
|
||||||
|
|--------|---------|-----------|--------|-----------|
|
||||||
|
| DECK | ARCHITECT | SSH/Git | 2222 | Push repos |
|
||||||
|
| DECK | R2 | HTTPS | 443 | Almacenamiento |
|
||||||
|
| CORP | ARCHITECT | SSH/Git | 2222 | Push repos |
|
||||||
|
| CORP | R2 | HTTPS | 443 | Almacenamiento |
|
||||||
|
| HST | ARCHITECT | SSH | 22 | Administración |
|
||||||
|
| ARCHITECT | DECK | SSH | 22 | Deploy |
|
||||||
|
| ARCHITECT | CORP | SSH | 22 | Deploy |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Bases de Datos
|
||||||
|
|
||||||
|
| Servidor | Database | Tablas Principales |
|
||||||
|
|----------|----------|--------------------|
|
||||||
|
| ARCHITECT | architect | context_blocks, agents, creds_* |
|
||||||
|
| DECK | tzzr | clara_log, alfred_executions |
|
||||||
|
| CORP | corp | margaret_log, mason_workspace, feldman_* |
|
||||||
|
| HST | hst_images | hst_tags, hst_trees |
|
||||||
230
01_ARQUITECTURA/servidores.md
Normal file
230
01_ARQUITECTURA/servidores.md
Normal file
@@ -0,0 +1,230 @@
|
|||||||
|
# Servidores TZZR
|
||||||
|
|
||||||
|
**Versión:** 5.0
|
||||||
|
**Fecha:** 2024-12-24
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## ARCHITECT (69.62.126.110)
|
||||||
|
|
||||||
|
**Rol:** Coordinador central del sistema
|
||||||
|
|
||||||
|
### Servicios
|
||||||
|
|
||||||
|
| Servicio | Puerto | Estado |
|
||||||
|
|----------|--------|--------|
|
||||||
|
| PostgreSQL | 5432 | Operativo |
|
||||||
|
| Gitea | 3000 (HTTP), 2222 (SSH) | Operativo |
|
||||||
|
| Orchestrator App | 5050 | Operativo |
|
||||||
|
| Infisical | 8082 | Operativo |
|
||||||
|
|
||||||
|
### PostgreSQL (database: architect)
|
||||||
|
|
||||||
|
| Tabla | Descripción |
|
||||||
|
|-------|-------------|
|
||||||
|
| context_blocks | 30 bloques de contexto atómicos |
|
||||||
|
| agent_context_index | Asignaciones agente-bloque |
|
||||||
|
| agents | 6 agentes definidos |
|
||||||
|
| creds_* | 6 tablas de credenciales |
|
||||||
|
| s_contract_contexts | Contextos IA |
|
||||||
|
| s_contract_datasets | Datasets IA |
|
||||||
|
|
||||||
|
### Acceso
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# SSH
|
||||||
|
ssh orchestrator@69.62.126.110
|
||||||
|
|
||||||
|
# PostgreSQL
|
||||||
|
sudo -u postgres psql -d architect
|
||||||
|
|
||||||
|
# Gitea
|
||||||
|
http://localhost:3000
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## DECK (72.62.1.113)
|
||||||
|
|
||||||
|
**Rol:** Servidor personal
|
||||||
|
|
||||||
|
### Servicios
|
||||||
|
|
||||||
|
| Servicio | Puerto | Estado |
|
||||||
|
|----------|--------|--------|
|
||||||
|
| CLARA | 5051 | Operativo |
|
||||||
|
| ALFRED | 5052 | Operativo |
|
||||||
|
| Mailcow (15 containers) | SMTP, IMAP | Operativo |
|
||||||
|
| Directus | 8055 | Operativo |
|
||||||
|
| FileBrowser | 8082 | Operativo |
|
||||||
|
| Shlink | 8083 | Operativo |
|
||||||
|
| Vaultwarden | 8085 | Operativo |
|
||||||
|
| ntfy | 8080 | Operativo |
|
||||||
|
|
||||||
|
### PostgreSQL (database: tzzr)
|
||||||
|
|
||||||
|
| Tabla | Descripción |
|
||||||
|
|-------|-------------|
|
||||||
|
| clara_log | Log inmutable de ingesta |
|
||||||
|
| deck_visiones | Visiones personales |
|
||||||
|
| deck_milestones | Milestones personales |
|
||||||
|
| deck_acciones | Acciones |
|
||||||
|
| deck_habitos | Hábitos |
|
||||||
|
| deck_bck | Bloques |
|
||||||
|
|
||||||
|
### Docker Containers
|
||||||
|
|
||||||
|
```
|
||||||
|
mailcowdockerized-acme-mailcow-1
|
||||||
|
mailcowdockerized-clamd-mailcow-1
|
||||||
|
mailcowdockerized-dovecot-mailcow-1
|
||||||
|
mailcowdockerized-mysql-mailcow-1
|
||||||
|
mailcowdockerized-netfilter-mailcow-1
|
||||||
|
mailcowdockerized-nginx-mailcow-1
|
||||||
|
mailcowdockerized-olefy-mailcow-1
|
||||||
|
mailcowdockerized-php-fpm-mailcow-1
|
||||||
|
mailcowdockerized-postfix-mailcow-1
|
||||||
|
mailcowdockerized-redis-mailcow-1
|
||||||
|
mailcowdockerized-rspamd-mailcow-1
|
||||||
|
mailcowdockerized-sogo-mailcow-1
|
||||||
|
mailcowdockerized-solr-mailcow-1
|
||||||
|
mailcowdockerized-unbound-mailcow-1
|
||||||
|
mailcowdockerized-watchdog-mailcow-1
|
||||||
|
clara-clara
|
||||||
|
alfred-alfred
|
||||||
|
directus
|
||||||
|
filebrowser
|
||||||
|
shlink
|
||||||
|
vaultwarden
|
||||||
|
ntfy
|
||||||
|
```
|
||||||
|
|
||||||
|
### Acceso
|
||||||
|
|
||||||
|
```bash
|
||||||
|
ssh -i ~/.ssh/tzzr root@72.62.1.113
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## CORP (92.112.181.188)
|
||||||
|
|
||||||
|
**Rol:** Servidor empresarial
|
||||||
|
|
||||||
|
### Servicios
|
||||||
|
|
||||||
|
| Servicio | Puerto | Estado |
|
||||||
|
|----------|--------|--------|
|
||||||
|
| MARGARET | 5051 | Operativo |
|
||||||
|
| JARED | 5052 | Operativo |
|
||||||
|
| MASON | 5053 | Operativo |
|
||||||
|
| FELDMAN | 5054 | Operativo |
|
||||||
|
| PostgreSQL | 5432 | Operativo |
|
||||||
|
| Directus | 8055 | Operativo |
|
||||||
|
| Nextcloud | 8080 | Operativo |
|
||||||
|
| Vaultwarden | 8081 | Operativo |
|
||||||
|
| Odoo | 8069 | Operativo |
|
||||||
|
| Caddy | 80/443 | Operativo |
|
||||||
|
|
||||||
|
### PostgreSQL (database: corp)
|
||||||
|
|
||||||
|
| Tabla | Descripción |
|
||||||
|
|-------|-------------|
|
||||||
|
| margaret_log | Log inmutable de ingesta |
|
||||||
|
| mason_workspace | Espacio de enriquecimiento |
|
||||||
|
| feldman_cola | Cola de consolidación |
|
||||||
|
| feldman_bloques | Bloques inmutables |
|
||||||
|
| feldman_validaciones | Auditoría validaciones |
|
||||||
|
| milestones | Plano MST |
|
||||||
|
| bloques | Plano BCK |
|
||||||
|
| hst_mirror | Mirror de tags HST |
|
||||||
|
|
||||||
|
### Acceso
|
||||||
|
|
||||||
|
```bash
|
||||||
|
ssh -i ~/.ssh/tzzr root@92.112.181.188
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## HST (72.62.2.84)
|
||||||
|
|
||||||
|
**Rol:** API de tags semánticos
|
||||||
|
|
||||||
|
### Servicios
|
||||||
|
|
||||||
|
| Servicio | Puerto | Estado |
|
||||||
|
|----------|--------|--------|
|
||||||
|
| Nginx | 80/443 | Operativo |
|
||||||
|
| Directus | 8055 | Operativo |
|
||||||
|
| PostgreSQL | 5432 | Operativo |
|
||||||
|
|
||||||
|
### Estadísticas HST
|
||||||
|
|
||||||
|
| Grupo | Cantidad |
|
||||||
|
|-------|----------|
|
||||||
|
| hst | 639 |
|
||||||
|
| spe | 145 |
|
||||||
|
| vsn | 84 |
|
||||||
|
| flg | 65 |
|
||||||
|
| vue | 21 |
|
||||||
|
| **Total** | **973** |
|
||||||
|
|
||||||
|
### API
|
||||||
|
|
||||||
|
```
|
||||||
|
https://tzrtech.org/{h_maestro}.png # Imagen de tag
|
||||||
|
```
|
||||||
|
|
||||||
|
### Acceso
|
||||||
|
|
||||||
|
```bash
|
||||||
|
ssh -i ~/.ssh/tzzr root@72.62.2.84
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## LOCKER (Cloudflare R2)
|
||||||
|
|
||||||
|
**Rol:** Almacenamiento distribuido
|
||||||
|
|
||||||
|
### Endpoint
|
||||||
|
|
||||||
|
```
|
||||||
|
https://7dedae6030f5554d99d37e98a5232996.r2.cloudflarestorage.com
|
||||||
|
```
|
||||||
|
|
||||||
|
### Buckets
|
||||||
|
|
||||||
|
| Bucket | Uso |
|
||||||
|
|--------|-----|
|
||||||
|
| architect | Backups Gitea, configs, GPU services |
|
||||||
|
| deck | Archivos personales (CLARA) |
|
||||||
|
| corp | Archivos empresariales (MARGARET) |
|
||||||
|
| hst | Imágenes de tags |
|
||||||
|
| locker | Almacenamiento general/temporal |
|
||||||
|
|
||||||
|
### Estructura GPU Services
|
||||||
|
|
||||||
|
```
|
||||||
|
s3://architect/gpu-services/
|
||||||
|
├── base/
|
||||||
|
│ └── bootstrap.sh
|
||||||
|
├── grace/
|
||||||
|
│ └── code/handler.py
|
||||||
|
├── penny/
|
||||||
|
│ └── code/handler.py
|
||||||
|
└── factory/
|
||||||
|
└── code/handler.py
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Resumen de IPs
|
||||||
|
|
||||||
|
| Servidor | IP Pública | IP Interna |
|
||||||
|
|----------|------------|------------|
|
||||||
|
| ARCHITECT | 69.62.126.110 | localhost |
|
||||||
|
| DECK | 72.62.1.113 | - |
|
||||||
|
| CORP | 92.112.181.188 | - |
|
||||||
|
| HST | 72.62.2.84 | - |
|
||||||
237
02_MODELO_DATOS/entidades.md
Normal file
237
02_MODELO_DATOS/entidades.md
Normal file
@@ -0,0 +1,237 @@
|
|||||||
|
# Entidades Base TZZR
|
||||||
|
|
||||||
|
**Versión:** 5.0
|
||||||
|
**Fecha:** 2024-12-24
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Visión General
|
||||||
|
|
||||||
|
Las entidades base son los bloques fundamentales del sistema. Cada una tiene un hash único SHA-256 que la identifica de forma unívoca.
|
||||||
|
|
||||||
|
```
|
||||||
|
DEFINICIÓN ORIGINAL → SHA-256 → h_{tipo} (64 chars)
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## HST (Hash Semantic Tagging)
|
||||||
|
|
||||||
|
**Estado:** Implementado
|
||||||
|
**Servidor:** HST (72.62.2.84)
|
||||||
|
**Hash:** h_maestro
|
||||||
|
|
||||||
|
### Fórmula
|
||||||
|
|
||||||
|
```
|
||||||
|
h_maestro = SHA-256(grupo:ref)
|
||||||
|
```
|
||||||
|
|
||||||
|
### Grupos
|
||||||
|
|
||||||
|
| Grupo | Cantidad | Descripción |
|
||||||
|
|-------|----------|-------------|
|
||||||
|
| hst | 639 | Tags del sistema base |
|
||||||
|
| spe | 145 | Tags específicos |
|
||||||
|
| vsn | 84 | Visiones |
|
||||||
|
| flg | 65 | Banderas/países |
|
||||||
|
| vue | 21 | Vistas |
|
||||||
|
|
||||||
|
### Schema
|
||||||
|
|
||||||
|
```sql
|
||||||
|
CREATE TABLE hst_tags (
|
||||||
|
id SERIAL PRIMARY KEY,
|
||||||
|
ref VARCHAR(100) UNIQUE NOT NULL,
|
||||||
|
h_maestro VARCHAR(64) UNIQUE NOT NULL,
|
||||||
|
grupo VARCHAR(50) NOT NULL,
|
||||||
|
nombre_es VARCHAR(255),
|
||||||
|
nombre_en VARCHAR(255),
|
||||||
|
descripcion TEXT,
|
||||||
|
imagen_url TEXT,
|
||||||
|
activo BOOLEAN DEFAULT true,
|
||||||
|
version INTEGER DEFAULT 1,
|
||||||
|
created_at TIMESTAMP DEFAULT NOW()
|
||||||
|
);
|
||||||
|
```
|
||||||
|
|
||||||
|
### Ejemplo
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"ref": "person",
|
||||||
|
"h_maestro": "a1b2c3d4e5f6...",
|
||||||
|
"grupo": "hst",
|
||||||
|
"nombre_es": "Persona",
|
||||||
|
"nombre_en": "Person",
|
||||||
|
"imagen_url": "https://tzrtech.org/a1b2c3d4e5f6...png"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## ITM (Items - Plano Ideal)
|
||||||
|
|
||||||
|
**Estado:** Planificado
|
||||||
|
**Servidor:** Por definir
|
||||||
|
**Hash:** h_item
|
||||||
|
|
||||||
|
### Concepto
|
||||||
|
|
||||||
|
Los ITM representan el estado ideal futuro. Son la "partitura" que guía las acciones.
|
||||||
|
|
||||||
|
### Schema Propuesto
|
||||||
|
|
||||||
|
```sql
|
||||||
|
CREATE TABLE items (
|
||||||
|
id BIGSERIAL PRIMARY KEY,
|
||||||
|
h_item VARCHAR(64) UNIQUE NOT NULL,
|
||||||
|
h_instancia VARCHAR(64) NOT NULL,
|
||||||
|
secuencia BIGINT NOT NULL,
|
||||||
|
hash_previo VARCHAR(64),
|
||||||
|
hash_contenido VARCHAR(64),
|
||||||
|
tipo_item VARCHAR(50) NOT NULL, -- accion_ideal, objetivo, requerimiento
|
||||||
|
titulo VARCHAR(255) NOT NULL,
|
||||||
|
descripcion TEXT,
|
||||||
|
criterios_aceptacion JSONB,
|
||||||
|
metadata JSONB,
|
||||||
|
proyecto_tag VARCHAR(64),
|
||||||
|
etiquetas JSONB,
|
||||||
|
estado VARCHAR(20) DEFAULT 'draft', -- draft, vigente, obsoleto
|
||||||
|
created_at TIMESTAMPTZ DEFAULT NOW(),
|
||||||
|
created_by VARCHAR(64),
|
||||||
|
UNIQUE (h_instancia, secuencia)
|
||||||
|
);
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## PLY (Players - Identidad)
|
||||||
|
|
||||||
|
**Estado:** Planificado
|
||||||
|
**Servidor:** Por definir
|
||||||
|
**Hash:** h_player
|
||||||
|
|
||||||
|
### Concepto
|
||||||
|
|
||||||
|
Los PLY representan la identidad de actores en el sistema (personas, empresas, agentes).
|
||||||
|
|
||||||
|
### Schema Propuesto
|
||||||
|
|
||||||
|
```sql
|
||||||
|
CREATE TABLE players (
|
||||||
|
id BIGSERIAL PRIMARY KEY,
|
||||||
|
h_player VARCHAR(64) UNIQUE NOT NULL,
|
||||||
|
tipo VARCHAR(50) NOT NULL, -- persona, empresa, agente
|
||||||
|
nombre VARCHAR(255) NOT NULL,
|
||||||
|
email VARCHAR(255),
|
||||||
|
metadata JSONB,
|
||||||
|
activo BOOLEAN DEFAULT true,
|
||||||
|
created_at TIMESTAMPTZ DEFAULT NOW()
|
||||||
|
);
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## LOC (Locations - Ubicaciones)
|
||||||
|
|
||||||
|
**Estado:** Planificado
|
||||||
|
**Servidor:** Por definir
|
||||||
|
**Hash:** h_loc
|
||||||
|
|
||||||
|
### Concepto
|
||||||
|
|
||||||
|
Los LOC representan ubicaciones geográficas con precisión variable.
|
||||||
|
|
||||||
|
### Schema Propuesto
|
||||||
|
|
||||||
|
```sql
|
||||||
|
CREATE TABLE locations (
|
||||||
|
id BIGSERIAL PRIMARY KEY,
|
||||||
|
h_loc VARCHAR(64) UNIQUE NOT NULL,
|
||||||
|
nombre VARCHAR(255),
|
||||||
|
lat DECIMAL(10, 8),
|
||||||
|
lon DECIMAL(11, 8),
|
||||||
|
precision_metros INTEGER,
|
||||||
|
tipo VARCHAR(50), -- punto, area, ruta
|
||||||
|
metadata JSONB,
|
||||||
|
created_at TIMESTAMPTZ DEFAULT NOW()
|
||||||
|
);
|
||||||
|
```
|
||||||
|
|
||||||
|
### Fórmula Hash
|
||||||
|
|
||||||
|
```
|
||||||
|
h_loc = SHA-256(lat:lon:precision)
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## FLG (Flags - Marcos Jurídicos)
|
||||||
|
|
||||||
|
**Estado:** Planificado
|
||||||
|
**Servidor:** Por definir
|
||||||
|
**Hash:** h_flag
|
||||||
|
|
||||||
|
### Concepto
|
||||||
|
|
||||||
|
Los FLG representan marcos jurídicos, normativas, países.
|
||||||
|
|
||||||
|
### Notas
|
||||||
|
|
||||||
|
Actualmente existe un grupo `flg` en HST con 65 tags de países, pero no como entidad independiente.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Tags de Usuario (Extensiones)
|
||||||
|
|
||||||
|
Los usuarios pueden crear sus propios tags como extensiones de HST.
|
||||||
|
|
||||||
|
| Tabla | Descripción |
|
||||||
|
|-------|-------------|
|
||||||
|
| hsu | HST Usuario |
|
||||||
|
| spu | SPE Usuario |
|
||||||
|
| vsu | VSN Usuario |
|
||||||
|
| vuu | VUE Usuario |
|
||||||
|
| pju | Proyectos Usuario |
|
||||||
|
| flu | FLG Usuario |
|
||||||
|
|
||||||
|
### Schema
|
||||||
|
|
||||||
|
```sql
|
||||||
|
CREATE TABLE hsu (
|
||||||
|
id SERIAL PRIMARY KEY,
|
||||||
|
ref VARCHAR(10) NOT NULL,
|
||||||
|
h_usuario VARCHAR(64) NOT NULL,
|
||||||
|
nombre VARCHAR(255) NOT NULL,
|
||||||
|
user_id INTEGER REFERENCES users(id),
|
||||||
|
metadata JSONB,
|
||||||
|
activo BOOLEAN DEFAULT true,
|
||||||
|
created_at TIMESTAMP DEFAULT NOW(),
|
||||||
|
UNIQUE (user_id, ref)
|
||||||
|
);
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Relaciones Entre Entidades
|
||||||
|
|
||||||
|
```
|
||||||
|
ITM (ideal)
|
||||||
|
│
|
||||||
|
├──► h_maestro (HST tags)
|
||||||
|
├──► h_player (PLY responsable)
|
||||||
|
├──► h_loc (LOC ubicación)
|
||||||
|
└──► h_flag (FLG normativa)
|
||||||
|
|
||||||
|
MST (milestone)
|
||||||
|
│
|
||||||
|
├──► item_asociado (ITM)
|
||||||
|
└──► h_maestro (HST tags)
|
||||||
|
|
||||||
|
BCK (bloque)
|
||||||
|
│
|
||||||
|
├──► item_asociado (ITM)
|
||||||
|
├──► milestone_asociado (MST)
|
||||||
|
└──► h_maestro (HST tags)
|
||||||
|
```
|
||||||
309
02_MODELO_DATOS/planos.md
Normal file
309
02_MODELO_DATOS/planos.md
Normal file
@@ -0,0 +1,309 @@
|
|||||||
|
# Planos de Datos TZZR
|
||||||
|
|
||||||
|
**Versión:** 5.0
|
||||||
|
**Fecha:** 2024-12-24
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Visión General
|
||||||
|
|
||||||
|
El sistema TZZR utiliza tres planos conceptuales para organizar la información:
|
||||||
|
|
||||||
|
```
|
||||||
|
┌─────────────────────────────────────────────────────────────────┐
|
||||||
|
│ T0 - PLANO IDEAL │
|
||||||
|
│ ITM (Items): Objetivos, acciones ideales, requerimientos │
|
||||||
|
│ Estado: PLANIFICADO - Sin implementación actual │
|
||||||
|
└─────────────────────────────────────────────────────────────────┘
|
||||||
|
│
|
||||||
|
▼ materializa
|
||||||
|
┌─────────────────────────────────────────────────────────────────┐
|
||||||
|
│ MST - MILESTONES │
|
||||||
|
│ Compromisos futuros con fecha de vencimiento │
|
||||||
|
│ Estado: IMPLEMENTADO en CORP (tabla milestones) │
|
||||||
|
└─────────────────────────────────────────────────────────────────┘
|
||||||
|
│
|
||||||
|
▼ cumple/genera
|
||||||
|
┌─────────────────────────────────────────────────────────────────┐
|
||||||
|
│ BCK - BLOQUES │
|
||||||
|
│ Hechos inmutables del pasado (blockchain-ready) │
|
||||||
|
│ Estado: IMPLEMENTADO en CORP (tabla bloques) │
|
||||||
|
└─────────────────────────────────────────────────────────────────┘
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## T0 - Plano Ideal (ITM)
|
||||||
|
|
||||||
|
### Concepto
|
||||||
|
|
||||||
|
El plano T0 contiene los Items (ITM) que representan el estado ideal futuro. Son la "partitura" que guía las acciones.
|
||||||
|
|
||||||
|
### Tipos de Items
|
||||||
|
|
||||||
|
| Tipo | Descripción |
|
||||||
|
|------|-------------|
|
||||||
|
| accion_ideal | Acción que debería ejecutarse |
|
||||||
|
| objetivo | Meta a alcanzar |
|
||||||
|
| requerimiento | Requisito a cumplir |
|
||||||
|
|
||||||
|
### Estado de Implementación
|
||||||
|
|
||||||
|
**PLANIFICADO** - Schema definido pero sin tablas creadas.
|
||||||
|
|
||||||
|
### Schema Propuesto
|
||||||
|
|
||||||
|
```sql
|
||||||
|
CREATE TABLE items (
|
||||||
|
id BIGSERIAL PRIMARY KEY,
|
||||||
|
h_item VARCHAR(64) UNIQUE NOT NULL,
|
||||||
|
h_instancia VARCHAR(64) NOT NULL,
|
||||||
|
secuencia BIGINT NOT NULL,
|
||||||
|
hash_previo VARCHAR(64),
|
||||||
|
hash_contenido VARCHAR(64),
|
||||||
|
tipo_item VARCHAR(50) NOT NULL,
|
||||||
|
titulo VARCHAR(255) NOT NULL,
|
||||||
|
descripcion TEXT,
|
||||||
|
criterios_aceptacion JSONB,
|
||||||
|
metadata JSONB,
|
||||||
|
proyecto_tag VARCHAR(64),
|
||||||
|
etiquetas JSONB,
|
||||||
|
estado VARCHAR(20) DEFAULT 'draft',
|
||||||
|
created_at TIMESTAMPTZ DEFAULT NOW(),
|
||||||
|
created_by VARCHAR(64),
|
||||||
|
UNIQUE (h_instancia, secuencia)
|
||||||
|
);
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## MST - Milestones
|
||||||
|
|
||||||
|
### Concepto
|
||||||
|
|
||||||
|
Los milestones representan compromisos con fecha futura. Tienen un período flotante de 24 horas antes de consolidarse.
|
||||||
|
|
||||||
|
### Estado de Implementación
|
||||||
|
|
||||||
|
**IMPLEMENTADO** en CORP (database: corp).
|
||||||
|
|
||||||
|
### Schema Actual
|
||||||
|
|
||||||
|
```sql
|
||||||
|
-- Tabla: milestones (CORP)
|
||||||
|
CREATE TABLE milestones (
|
||||||
|
id BIGSERIAL PRIMARY KEY,
|
||||||
|
h_milestone VARCHAR(64) UNIQUE NOT NULL,
|
||||||
|
h_instancia VARCHAR(64) NOT NULL,
|
||||||
|
secuencia BIGINT NOT NULL,
|
||||||
|
hash_previo VARCHAR(64),
|
||||||
|
hash_contenido VARCHAR(64),
|
||||||
|
tipo_milestone VARCHAR(50) NOT NULL,
|
||||||
|
fecha_vencimiento DATE NOT NULL,
|
||||||
|
descripcion TEXT,
|
||||||
|
metadata JSONB,
|
||||||
|
proyecto_tag VARCHAR(64),
|
||||||
|
etiquetas JSONB,
|
||||||
|
estado VARCHAR(20) DEFAULT 'draft',
|
||||||
|
created_at TIMESTAMPTZ DEFAULT NOW(),
|
||||||
|
modified_at TIMESTAMPTZ,
|
||||||
|
created_by VARCHAR(64),
|
||||||
|
UNIQUE (h_instancia, secuencia)
|
||||||
|
);
|
||||||
|
```
|
||||||
|
|
||||||
|
### Tipos de Milestones
|
||||||
|
|
||||||
|
| Tipo | Descripción |
|
||||||
|
|------|-------------|
|
||||||
|
| compromiso | Compromiso de entrega |
|
||||||
|
| deadline | Fecha límite |
|
||||||
|
| evento | Evento programado |
|
||||||
|
| recordatorio | Recordatorio futuro |
|
||||||
|
|
||||||
|
### Fórmula Hash
|
||||||
|
|
||||||
|
```
|
||||||
|
h_milestone = SHA-256(h_instancia:secuencia:tipo:contenido)
|
||||||
|
```
|
||||||
|
|
||||||
|
### Período Flotante
|
||||||
|
|
||||||
|
- **Duración:** 24 horas desde creación
|
||||||
|
- **Durante período:** Modificable vía MASON
|
||||||
|
- **Después:** Inmutable, solo lectura
|
||||||
|
|
||||||
|
**Nota:** Actualmente no hay scheduler que procese la expiración automáticamente.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## BCK - Bloques
|
||||||
|
|
||||||
|
### Concepto
|
||||||
|
|
||||||
|
Los bloques son registros inmutables de hechos pasados. Cada bloque está encadenado al anterior mediante hash, preparando la infraestructura para blockchain.
|
||||||
|
|
||||||
|
### Estado de Implementación
|
||||||
|
|
||||||
|
**IMPLEMENTADO** en CORP (database: corp).
|
||||||
|
|
||||||
|
### Schema Actual
|
||||||
|
|
||||||
|
```sql
|
||||||
|
-- Tabla: bloques (CORP)
|
||||||
|
CREATE TABLE bloques (
|
||||||
|
id BIGSERIAL PRIMARY KEY,
|
||||||
|
h_bloque VARCHAR(64) UNIQUE NOT NULL,
|
||||||
|
h_instancia VARCHAR(64) NOT NULL,
|
||||||
|
secuencia BIGINT NOT NULL,
|
||||||
|
hash_previo VARCHAR(64),
|
||||||
|
hash_contenido VARCHAR(64) NOT NULL,
|
||||||
|
tipo_bloque VARCHAR(50) NOT NULL,
|
||||||
|
contenido JSONB NOT NULL,
|
||||||
|
metadata JSONB,
|
||||||
|
item_asociado VARCHAR(64),
|
||||||
|
milestone_asociado VARCHAR(64),
|
||||||
|
h_maestro JSONB,
|
||||||
|
h_player VARCHAR(64),
|
||||||
|
h_loc VARCHAR(64),
|
||||||
|
h_flag VARCHAR(64),
|
||||||
|
estado VARCHAR(20) DEFAULT 'consolidado',
|
||||||
|
created_at TIMESTAMPTZ DEFAULT NOW(),
|
||||||
|
validated_at TIMESTAMPTZ,
|
||||||
|
validated_by VARCHAR(64),
|
||||||
|
UNIQUE (h_instancia, secuencia)
|
||||||
|
);
|
||||||
|
```
|
||||||
|
|
||||||
|
### Tipos de Bloques
|
||||||
|
|
||||||
|
| Tipo | Descripción |
|
||||||
|
|------|-------------|
|
||||||
|
| transaccion | Transacción económica |
|
||||||
|
| documento | Documento consolidado |
|
||||||
|
| evento | Evento registrado |
|
||||||
|
| milestone_cumplido | Milestone que se cumplió |
|
||||||
|
|
||||||
|
### Fórmula Hash
|
||||||
|
|
||||||
|
```
|
||||||
|
h_bloque = SHA-256(h_instancia:secuencia:hash_previo:hash_contenido)
|
||||||
|
hash_contenido = SHA-256(contenido_serializado)
|
||||||
|
```
|
||||||
|
|
||||||
|
### Encadenamiento
|
||||||
|
|
||||||
|
```
|
||||||
|
Bloque N-1 Bloque N
|
||||||
|
┌──────────────────┐ ┌──────────────────┐
|
||||||
|
│ h_bloque: abc123 │ ──────► │ hash_previo: │
|
||||||
|
│ hash_contenido: │ │ abc123 │
|
||||||
|
│ def456 │ │ h_bloque: ghi789 │
|
||||||
|
│ secuencia: 1 │ │ secuencia: 2 │
|
||||||
|
└──────────────────┘ └──────────────────┘
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Flujo Entre Planos
|
||||||
|
|
||||||
|
```
|
||||||
|
Usuario crea ITM
|
||||||
|
│
|
||||||
|
▼
|
||||||
|
ITM (T0) "Objetivo: Completar proyecto X"
|
||||||
|
│
|
||||||
|
│ materializa
|
||||||
|
▼
|
||||||
|
MST "Milestone: Entrega módulo 1 - 2024-01-15"
|
||||||
|
│
|
||||||
|
│ [período flotante 24h]
|
||||||
|
│
|
||||||
|
▼
|
||||||
|
MASON (enriquecimiento)
|
||||||
|
│
|
||||||
|
▼
|
||||||
|
FELDMAN (validación)
|
||||||
|
│
|
||||||
|
│ cumple/genera
|
||||||
|
▼
|
||||||
|
BCK "Bloque: Módulo 1 entregado - 2024-01-14"
|
||||||
|
│
|
||||||
|
▼
|
||||||
|
Inmutable ✓
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Tablas de Procesamiento
|
||||||
|
|
||||||
|
### FELDMAN Cola
|
||||||
|
|
||||||
|
```sql
|
||||||
|
-- feldman_cola: Elementos pendientes de validación
|
||||||
|
CREATE TABLE feldman_cola (
|
||||||
|
id BIGSERIAL PRIMARY KEY,
|
||||||
|
tipo VARCHAR(50) NOT NULL, -- 'milestone' o 'bloque'
|
||||||
|
h_entrada VARCHAR(64) NOT NULL,
|
||||||
|
contenido JSONB NOT NULL,
|
||||||
|
prioridad INTEGER DEFAULT 0,
|
||||||
|
estado VARCHAR(20) DEFAULT 'pendiente',
|
||||||
|
created_at TIMESTAMPTZ DEFAULT NOW(),
|
||||||
|
processed_at TIMESTAMPTZ
|
||||||
|
);
|
||||||
|
```
|
||||||
|
|
||||||
|
### FELDMAN Validaciones
|
||||||
|
|
||||||
|
```sql
|
||||||
|
-- feldman_validaciones: Auditoría de validaciones
|
||||||
|
CREATE TABLE feldman_validaciones (
|
||||||
|
id BIGSERIAL PRIMARY KEY,
|
||||||
|
h_entrada VARCHAR(64) NOT NULL,
|
||||||
|
regla VARCHAR(50) NOT NULL, -- M-001, M-002, M-003
|
||||||
|
resultado BOOLEAN NOT NULL,
|
||||||
|
mensaje TEXT,
|
||||||
|
validated_at TIMESTAMPTZ DEFAULT NOW()
|
||||||
|
);
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Reglas de Validación FELDMAN
|
||||||
|
|
||||||
|
| Regla | Nombre | Descripción |
|
||||||
|
|-------|--------|-------------|
|
||||||
|
| M-001 | Hash único | h_bloque/h_milestone no existe previamente |
|
||||||
|
| M-002 | Encadenamiento | hash_previo apunta a bloque existente |
|
||||||
|
| M-003 | Integridad | hash_contenido = SHA-256(contenido) |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Decisiones de Diseño
|
||||||
|
|
||||||
|
### D-004: Eliminar columnas duplicadas
|
||||||
|
|
||||||
|
**Problema:** Milestones tienen columnas + JSONB duplicados.
|
||||||
|
|
||||||
|
**Decisión:** Mantener metadatos solo en JSONB `metadata`.
|
||||||
|
|
||||||
|
### D-007: Timestamps UTC
|
||||||
|
|
||||||
|
**Problema:** Inconsistencia en zonas horarias.
|
||||||
|
|
||||||
|
**Decisión:** Usar `TIMESTAMPTZ` y almacenar en UTC.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Roadmap
|
||||||
|
|
||||||
|
### Implementado
|
||||||
|
- [x] Tabla milestones en CORP
|
||||||
|
- [x] Tabla bloques en CORP
|
||||||
|
- [x] Fórmulas hash definidas
|
||||||
|
|
||||||
|
### Pendiente
|
||||||
|
- [ ] Tabla items (T0)
|
||||||
|
- [ ] Scheduler para período flotante
|
||||||
|
- [ ] Merkle tree para verificación
|
||||||
|
- [ ] Smart contract blockchain (futuro)
|
||||||
311
03_COMPONENTES/agentes/clara-margaret.md
Normal file
311
03_COMPONENTES/agentes/clara-margaret.md
Normal file
@@ -0,0 +1,311 @@
|
|||||||
|
# CLARA y MARGARET - Agentes de Ingesta
|
||||||
|
|
||||||
|
**Versión:** 5.0
|
||||||
|
**Fecha:** 2024-12-24
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Resumen
|
||||||
|
|
||||||
|
| Aspecto | CLARA | MARGARET |
|
||||||
|
|---------|-------|----------|
|
||||||
|
| Servidor | DECK (72.62.1.113) | CORP (92.112.181.188) |
|
||||||
|
| Puerto | 5051 | 5051 |
|
||||||
|
| Dominio | Personal | Empresarial |
|
||||||
|
| Base de datos | tzzr | corp |
|
||||||
|
| Tabla log | clara_log | margaret_log |
|
||||||
|
| Bucket R2 | deck | corp |
|
||||||
|
| Estado | Operativo | Operativo |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Arquitectura
|
||||||
|
|
||||||
|
```
|
||||||
|
PACKET (App móvil)
|
||||||
|
│
|
||||||
|
│ POST /ingest
|
||||||
|
│ Content-Type: multipart/form-data
|
||||||
|
│ X-Auth-Key: {h_instancia}
|
||||||
|
│
|
||||||
|
▼
|
||||||
|
┌─────────────────────────────────────────┐
|
||||||
|
│ CLARA (Personal) / MARGARET (Corp) │
|
||||||
|
│ │
|
||||||
|
│ 1. Validar h_instancia │
|
||||||
|
│ 2. Calcular h_entrada (SHA-256) │
|
||||||
|
│ 3. Subir archivos a R2 │
|
||||||
|
│ 4. Insertar en log (inmutable) │
|
||||||
|
│ 5. Estado: 'recibido' │
|
||||||
|
│ 6. Responder con h_entrada │
|
||||||
|
└─────────────────────────────────────────┘
|
||||||
|
│
|
||||||
|
▼
|
||||||
|
ALFRED / JARED (siguiente paso)
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Endpoint de Ingesta
|
||||||
|
|
||||||
|
### Request
|
||||||
|
|
||||||
|
```http
|
||||||
|
POST /ingest HTTP/1.1
|
||||||
|
Host: deck.example.com:5051
|
||||||
|
Content-Type: multipart/form-data
|
||||||
|
X-Auth-Key: {h_instancia}
|
||||||
|
|
||||||
|
--boundary
|
||||||
|
Content-Disposition: form-data; name="tipo"
|
||||||
|
|
||||||
|
documento
|
||||||
|
--boundary
|
||||||
|
Content-Disposition: form-data; name="archivo"; filename="doc.pdf"
|
||||||
|
Content-Type: application/pdf
|
||||||
|
|
||||||
|
{binary data}
|
||||||
|
--boundary--
|
||||||
|
```
|
||||||
|
|
||||||
|
### Response
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"success": true,
|
||||||
|
"h_entrada": "a1b2c3d4e5f6...",
|
||||||
|
"estado": "recibido",
|
||||||
|
"timestamp": "2024-12-24T12:00:00Z"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Cálculo de h_entrada
|
||||||
|
|
||||||
|
```python
|
||||||
|
import hashlib
|
||||||
|
import json
|
||||||
|
|
||||||
|
def calcular_h_entrada(h_instancia, tipo, contenido_bytes, timestamp):
|
||||||
|
"""
|
||||||
|
Calcula el hash único de entrada.
|
||||||
|
|
||||||
|
h_entrada = SHA-256(h_instancia:tipo:sha256(contenido):timestamp)
|
||||||
|
"""
|
||||||
|
hash_contenido = hashlib.sha256(contenido_bytes).hexdigest()
|
||||||
|
|
||||||
|
data = f"{h_instancia}:{tipo}:{hash_contenido}:{timestamp}"
|
||||||
|
|
||||||
|
return hashlib.sha256(data.encode()).hexdigest()
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Schema: clara_log / margaret_log
|
||||||
|
|
||||||
|
```sql
|
||||||
|
CREATE TABLE clara_log (
|
||||||
|
id BIGSERIAL PRIMARY KEY,
|
||||||
|
h_entrada VARCHAR(64) UNIQUE NOT NULL,
|
||||||
|
h_instancia VARCHAR(64) NOT NULL,
|
||||||
|
tipo VARCHAR(50) NOT NULL,
|
||||||
|
contenido_url TEXT, -- locker://deck/{h_entrada}/archivo
|
||||||
|
contenido_hash VARCHAR(64), -- SHA-256 del contenido
|
||||||
|
metadata JSONB,
|
||||||
|
estado VARCHAR(20) DEFAULT 'recibido',
|
||||||
|
created_at TIMESTAMPTZ DEFAULT NOW(),
|
||||||
|
processed_at TIMESTAMPTZ,
|
||||||
|
processed_by VARCHAR(50) -- 'alfred' o 'manual'
|
||||||
|
);
|
||||||
|
|
||||||
|
-- margaret_log tiene schema idéntico
|
||||||
|
CREATE TABLE margaret_log (
|
||||||
|
id BIGSERIAL PRIMARY KEY,
|
||||||
|
h_entrada VARCHAR(64) UNIQUE NOT NULL,
|
||||||
|
h_instancia VARCHAR(64) NOT NULL,
|
||||||
|
tipo VARCHAR(50) NOT NULL,
|
||||||
|
contenido_url TEXT,
|
||||||
|
contenido_hash VARCHAR(64),
|
||||||
|
metadata JSONB,
|
||||||
|
estado VARCHAR(20) DEFAULT 'recibido',
|
||||||
|
created_at TIMESTAMPTZ DEFAULT NOW(),
|
||||||
|
processed_at TIMESTAMPTZ,
|
||||||
|
processed_by VARCHAR(50)
|
||||||
|
);
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Estados del Log
|
||||||
|
|
||||||
|
| Estado | Descripción |
|
||||||
|
|--------|-------------|
|
||||||
|
| recibido | Ingesta completada, pendiente procesamiento |
|
||||||
|
| procesando | ALFRED/JARED está procesando |
|
||||||
|
| enviado_mason | Enviado a MASON para enriquecimiento |
|
||||||
|
| consolidado | Procesado por FELDMAN |
|
||||||
|
| error | Error en procesamiento |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Almacenamiento en R2
|
||||||
|
|
||||||
|
### Estructura de URLs
|
||||||
|
|
||||||
|
```
|
||||||
|
locker://deck/{h_entrada}/archivo.ext
|
||||||
|
locker://corp/{h_entrada}/archivo.ext
|
||||||
|
```
|
||||||
|
|
||||||
|
### Implementación
|
||||||
|
|
||||||
|
```python
|
||||||
|
import boto3
|
||||||
|
|
||||||
|
def subir_a_r2(bucket, h_entrada, archivo_bytes, filename):
|
||||||
|
"""Sube archivo a Cloudflare R2."""
|
||||||
|
|
||||||
|
s3 = boto3.client(
|
||||||
|
's3',
|
||||||
|
endpoint_url='https://7dedae6030f5554d99d37e98a5232996.r2.cloudflarestorage.com',
|
||||||
|
aws_access_key_id=R2_ACCESS_KEY,
|
||||||
|
aws_secret_access_key=R2_SECRET_KEY
|
||||||
|
)
|
||||||
|
|
||||||
|
key = f"{h_entrada}/{filename}"
|
||||||
|
|
||||||
|
s3.put_object(
|
||||||
|
Bucket=bucket,
|
||||||
|
Key=key,
|
||||||
|
Body=archivo_bytes
|
||||||
|
)
|
||||||
|
|
||||||
|
return f"locker://{bucket}/{key}"
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Validación de h_instancia
|
||||||
|
|
||||||
|
```python
|
||||||
|
def validar_instancia(h_instancia):
|
||||||
|
"""
|
||||||
|
Valida que h_instancia exista y esté activa.
|
||||||
|
|
||||||
|
TODO: Implementar tabla de instancias activas.
|
||||||
|
Actualmente: Validación básica de formato.
|
||||||
|
"""
|
||||||
|
if not h_instancia:
|
||||||
|
return False
|
||||||
|
|
||||||
|
if len(h_instancia) != 64:
|
||||||
|
return False
|
||||||
|
|
||||||
|
# TODO: Consultar tabla de instancias
|
||||||
|
return True
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Tipos de Ingesta Soportados
|
||||||
|
|
||||||
|
| Tipo | Descripción | Extensiones |
|
||||||
|
|------|-------------|-------------|
|
||||||
|
| documento | Documentos | pdf, doc, docx |
|
||||||
|
| imagen | Imágenes | jpg, png, gif |
|
||||||
|
| audio | Audio | mp3, wav, m4a |
|
||||||
|
| video | Video | mp4, mov |
|
||||||
|
| texto | Texto plano | txt, md |
|
||||||
|
| json | Datos estructurados | json |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Configuración
|
||||||
|
|
||||||
|
### Variables de Entorno
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# CLARA (.env en /opt/clara/)
|
||||||
|
DB_HOST=localhost
|
||||||
|
DB_PORT=5432
|
||||||
|
DB_NAME=tzzr
|
||||||
|
DB_USER=clara
|
||||||
|
DB_PASSWORD=****
|
||||||
|
|
||||||
|
R2_ENDPOINT=https://7dedae6030f5554d99d37e98a5232996.r2.cloudflarestorage.com
|
||||||
|
R2_ACCESS_KEY=****
|
||||||
|
R2_SECRET_KEY=****
|
||||||
|
R2_BUCKET=deck
|
||||||
|
|
||||||
|
# MARGARET (.env en /opt/margaret/)
|
||||||
|
DB_HOST=localhost
|
||||||
|
DB_PORT=5432
|
||||||
|
DB_NAME=corp
|
||||||
|
DB_USER=margaret
|
||||||
|
DB_PASSWORD=****
|
||||||
|
|
||||||
|
R2_BUCKET=corp
|
||||||
|
```
|
||||||
|
|
||||||
|
### Docker Compose
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
# CLARA
|
||||||
|
version: '3.8'
|
||||||
|
services:
|
||||||
|
clara:
|
||||||
|
container_name: clara-clara
|
||||||
|
image: tzzr/clara:latest
|
||||||
|
ports:
|
||||||
|
- "5051:5051"
|
||||||
|
env_file:
|
||||||
|
- .env
|
||||||
|
restart: unless-stopped
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Diferencias CLARA vs MARGARET
|
||||||
|
|
||||||
|
| Aspecto | CLARA | MARGARET |
|
||||||
|
|---------|-------|----------|
|
||||||
|
| Uso | Personal | Empresarial |
|
||||||
|
| Volumen | Bajo | Alto |
|
||||||
|
| Privacidad | Máxima | Compartida (empresa) |
|
||||||
|
| Integración | ALFRED | JARED → MASON → FELDMAN |
|
||||||
|
| Backup | deck bucket | corp bucket |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Seguridad
|
||||||
|
|
||||||
|
### Actual
|
||||||
|
- Autenticación por h_instancia
|
||||||
|
- Comunicación HTTP (sin TLS interno)
|
||||||
|
- .env con permisos 644 (**CRÍTICO: cambiar a 600**)
|
||||||
|
|
||||||
|
### Recomendado
|
||||||
|
- TLS interno con certificados
|
||||||
|
- Rate limiting
|
||||||
|
- Validación de tipos MIME
|
||||||
|
- Escaneo antivirus (ClamAV)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Monitoreo
|
||||||
|
|
||||||
|
### Logs
|
||||||
|
```bash
|
||||||
|
# CLARA
|
||||||
|
docker logs clara-clara -f
|
||||||
|
|
||||||
|
# MARGARET
|
||||||
|
docker logs margaret-margaret -f
|
||||||
|
```
|
||||||
|
|
||||||
|
### Métricas Sugeridas
|
||||||
|
- Ingestas por minuto
|
||||||
|
- Tamaño promedio de archivos
|
||||||
|
- Tiempo de procesamiento
|
||||||
|
- Errores por tipo
|
||||||
390
03_COMPONENTES/agentes/feldman.md
Normal file
390
03_COMPONENTES/agentes/feldman.md
Normal file
@@ -0,0 +1,390 @@
|
|||||||
|
# FELDMAN - Agente de Consolidación
|
||||||
|
|
||||||
|
**Versión:** 5.0
|
||||||
|
**Fecha:** 2024-12-24
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Resumen
|
||||||
|
|
||||||
|
| Aspecto | Valor |
|
||||||
|
|---------|-------|
|
||||||
|
| Servidor | CORP (92.112.181.188) |
|
||||||
|
| Puerto | 5054 |
|
||||||
|
| Base de datos | corp |
|
||||||
|
| Tablas | feldman_cola, feldman_bloques, feldman_validaciones |
|
||||||
|
| Estado | Operativo |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Rol en el Sistema
|
||||||
|
|
||||||
|
FELDMAN es el "notario" del sistema: valida y consolida datos en bloques inmutables.
|
||||||
|
|
||||||
|
```
|
||||||
|
MASON (enriquecido)
|
||||||
|
│
|
||||||
|
▼
|
||||||
|
┌─────────────────────────────────────────┐
|
||||||
|
│ FELDMAN │
|
||||||
|
│ │
|
||||||
|
│ 1. Recibir en feldman_cola │
|
||||||
|
│ 2. Validar reglas (M-001, M-002, M-003)│
|
||||||
|
│ 3. Calcular hash_contenido │
|
||||||
|
│ 4. Encadenar (hash_previo) │
|
||||||
|
│ 5. Crear milestone o bloque │
|
||||||
|
│ 6. Marcar como consolidado │
|
||||||
|
└─────────────────────────────────────────┘
|
||||||
|
│
|
||||||
|
▼
|
||||||
|
┌─────────────────────────────────────────┐
|
||||||
|
│ milestones / bloques (inmutables) │
|
||||||
|
└─────────────────────────────────────────┘
|
||||||
|
│
|
||||||
|
▼
|
||||||
|
SENTINEL (auditoría futura)
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Reglas de Validación
|
||||||
|
|
||||||
|
| Regla | Nombre | Descripción | Acción si falla |
|
||||||
|
|-------|--------|-------------|-----------------|
|
||||||
|
| M-001 | Hash único | h_bloque/h_milestone no existe previamente | Rechazar |
|
||||||
|
| M-002 | Encadenamiento | hash_previo apunta a bloque existente | Rechazar |
|
||||||
|
| M-003 | Integridad | hash_contenido = SHA-256(contenido) | Rechazar |
|
||||||
|
|
||||||
|
### Implementación
|
||||||
|
|
||||||
|
```python
|
||||||
|
def validar_m001(h_bloque):
|
||||||
|
"""M-001: Hash debe ser único."""
|
||||||
|
existe = db.execute(
|
||||||
|
"SELECT 1 FROM bloques WHERE h_bloque = %s",
|
||||||
|
[h_bloque]
|
||||||
|
).fetchone()
|
||||||
|
return existe is None
|
||||||
|
|
||||||
|
def validar_m002(hash_previo, h_instancia):
|
||||||
|
"""M-002: hash_previo debe existir (excepto génesis)."""
|
||||||
|
if hash_previo is None:
|
||||||
|
# Primer bloque de la instancia (génesis)
|
||||||
|
existe = db.execute(
|
||||||
|
"SELECT 1 FROM bloques WHERE h_instancia = %s",
|
||||||
|
[h_instancia]
|
||||||
|
).fetchone()
|
||||||
|
return existe is None # OK si no hay bloques previos
|
||||||
|
|
||||||
|
existe = db.execute(
|
||||||
|
"SELECT 1 FROM bloques WHERE h_bloque = %s",
|
||||||
|
[hash_previo]
|
||||||
|
).fetchone()
|
||||||
|
return existe is not None
|
||||||
|
|
||||||
|
def validar_m003(hash_contenido, contenido):
|
||||||
|
"""M-003: Hash debe coincidir con contenido."""
|
||||||
|
import hashlib
|
||||||
|
import json
|
||||||
|
|
||||||
|
contenido_serializado = json.dumps(contenido, sort_keys=True)
|
||||||
|
hash_calculado = hashlib.sha256(contenido_serializado.encode()).hexdigest()
|
||||||
|
|
||||||
|
return hash_contenido == hash_calculado
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Schema de Tablas
|
||||||
|
|
||||||
|
### feldman_cola
|
||||||
|
|
||||||
|
```sql
|
||||||
|
CREATE TABLE feldman_cola (
|
||||||
|
id BIGSERIAL PRIMARY KEY,
|
||||||
|
tipo VARCHAR(50) NOT NULL, -- 'milestone' o 'bloque'
|
||||||
|
h_entrada VARCHAR(64) NOT NULL, -- Referencia a origen
|
||||||
|
h_instancia VARCHAR(64) NOT NULL,
|
||||||
|
contenido JSONB NOT NULL,
|
||||||
|
prioridad INTEGER DEFAULT 0,
|
||||||
|
estado VARCHAR(20) DEFAULT 'pendiente',
|
||||||
|
intentos INTEGER DEFAULT 0,
|
||||||
|
ultimo_error TEXT,
|
||||||
|
created_at TIMESTAMPTZ DEFAULT NOW(),
|
||||||
|
processed_at TIMESTAMPTZ
|
||||||
|
);
|
||||||
|
|
||||||
|
CREATE INDEX idx_feldman_cola_estado ON feldman_cola(estado);
|
||||||
|
CREATE INDEX idx_feldman_cola_prioridad ON feldman_cola(prioridad DESC);
|
||||||
|
```
|
||||||
|
|
||||||
|
### feldman_bloques (alias de bloques)
|
||||||
|
|
||||||
|
```sql
|
||||||
|
-- Ver 02_MODELO_DATOS/planos.md para schema completo
|
||||||
|
CREATE TABLE bloques (
|
||||||
|
id BIGSERIAL PRIMARY KEY,
|
||||||
|
h_bloque VARCHAR(64) UNIQUE NOT NULL,
|
||||||
|
h_instancia VARCHAR(64) NOT NULL,
|
||||||
|
secuencia BIGINT NOT NULL,
|
||||||
|
hash_previo VARCHAR(64),
|
||||||
|
hash_contenido VARCHAR(64) NOT NULL,
|
||||||
|
tipo_bloque VARCHAR(50) NOT NULL,
|
||||||
|
contenido JSONB NOT NULL,
|
||||||
|
-- ... campos adicionales
|
||||||
|
UNIQUE (h_instancia, secuencia)
|
||||||
|
);
|
||||||
|
```
|
||||||
|
|
||||||
|
### feldman_validaciones
|
||||||
|
|
||||||
|
```sql
|
||||||
|
CREATE TABLE feldman_validaciones (
|
||||||
|
id BIGSERIAL PRIMARY KEY,
|
||||||
|
h_entrada VARCHAR(64) NOT NULL,
|
||||||
|
tipo_destino VARCHAR(50) NOT NULL, -- 'milestone' o 'bloque'
|
||||||
|
h_destino VARCHAR(64), -- h_milestone o h_bloque
|
||||||
|
regla VARCHAR(50) NOT NULL, -- M-001, M-002, M-003
|
||||||
|
resultado BOOLEAN NOT NULL,
|
||||||
|
mensaje TEXT,
|
||||||
|
validated_at TIMESTAMPTZ DEFAULT NOW()
|
||||||
|
);
|
||||||
|
|
||||||
|
CREATE INDEX idx_feldman_val_entrada ON feldman_validaciones(h_entrada);
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Flujo de Consolidación
|
||||||
|
|
||||||
|
```
|
||||||
|
1. Entrada en feldman_cola
|
||||||
|
│
|
||||||
|
▼
|
||||||
|
2. FELDMAN procesa (poll cada N segundos)
|
||||||
|
│
|
||||||
|
├─► Validar M-001 (hash único)
|
||||||
|
│ ├─ PASS → continuar
|
||||||
|
│ └─ FAIL → registrar error, marcar 'rechazado'
|
||||||
|
│
|
||||||
|
├─► Validar M-002 (encadenamiento)
|
||||||
|
│ ├─ PASS → continuar
|
||||||
|
│ └─ FAIL → registrar error, marcar 'rechazado'
|
||||||
|
│
|
||||||
|
├─► Validar M-003 (integridad)
|
||||||
|
│ ├─ PASS → continuar
|
||||||
|
│ └─ FAIL → registrar error, marcar 'rechazado'
|
||||||
|
│
|
||||||
|
▼
|
||||||
|
3. Todas las validaciones PASS
|
||||||
|
│
|
||||||
|
▼
|
||||||
|
4. Obtener última secuencia de h_instancia
|
||||||
|
│
|
||||||
|
▼
|
||||||
|
5. Calcular h_bloque/h_milestone
|
||||||
|
│
|
||||||
|
▼
|
||||||
|
6. INSERT en bloques/milestones
|
||||||
|
│
|
||||||
|
▼
|
||||||
|
7. Actualizar feldman_cola → 'consolidado'
|
||||||
|
│
|
||||||
|
▼
|
||||||
|
8. Registrar en feldman_validaciones
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Cálculo de Hashes
|
||||||
|
|
||||||
|
### h_bloque
|
||||||
|
|
||||||
|
```python
|
||||||
|
def calcular_h_bloque(h_instancia, secuencia, hash_previo, hash_contenido):
|
||||||
|
"""
|
||||||
|
Calcula el hash del bloque.
|
||||||
|
|
||||||
|
h_bloque = SHA-256(h_instancia:secuencia:hash_previo:hash_contenido)
|
||||||
|
"""
|
||||||
|
import hashlib
|
||||||
|
|
||||||
|
# hash_previo puede ser None para bloque génesis
|
||||||
|
previo = hash_previo or "genesis"
|
||||||
|
|
||||||
|
data = f"{h_instancia}:{secuencia}:{previo}:{hash_contenido}"
|
||||||
|
|
||||||
|
return hashlib.sha256(data.encode()).hexdigest()
|
||||||
|
```
|
||||||
|
|
||||||
|
### hash_contenido
|
||||||
|
|
||||||
|
```python
|
||||||
|
def calcular_hash_contenido(contenido):
|
||||||
|
"""
|
||||||
|
Calcula el hash del contenido.
|
||||||
|
|
||||||
|
hash_contenido = SHA-256(contenido_serializado)
|
||||||
|
"""
|
||||||
|
import hashlib
|
||||||
|
import json
|
||||||
|
|
||||||
|
# Serialización determinista
|
||||||
|
contenido_str = json.dumps(contenido, sort_keys=True, ensure_ascii=False)
|
||||||
|
|
||||||
|
return hashlib.sha256(contenido_str.encode()).hexdigest()
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## API Endpoints
|
||||||
|
|
||||||
|
### POST /consolidar
|
||||||
|
|
||||||
|
```http
|
||||||
|
POST /consolidar HTTP/1.1
|
||||||
|
Host: corp.example.com:5054
|
||||||
|
Content-Type: application/json
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
### Response (éxito)
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"success": true,
|
||||||
|
"h_bloque": "ghi789...",
|
||||||
|
"secuencia": 42,
|
||||||
|
"hash_contenido": "jkl012...",
|
||||||
|
"validaciones": {
|
||||||
|
"M-001": true,
|
||||||
|
"M-002": true,
|
||||||
|
"M-003": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Response (error)
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"success": false,
|
||||||
|
"error": "Validación fallida",
|
||||||
|
"validaciones": {
|
||||||
|
"M-001": true,
|
||||||
|
"M-002": false,
|
||||||
|
"M-003": true
|
||||||
|
},
|
||||||
|
"mensaje": "M-002: hash_previo no existe en cadena"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Configuración
|
||||||
|
|
||||||
|
### Variables de Entorno
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# /opt/feldman/.env
|
||||||
|
DB_HOST=localhost
|
||||||
|
DB_PORT=5432
|
||||||
|
DB_NAME=corp
|
||||||
|
DB_USER=feldman
|
||||||
|
DB_PASSWORD=****
|
||||||
|
|
||||||
|
POLL_INTERVAL=5 # Segundos entre polls
|
||||||
|
MAX_BATCH=10 # Elementos por lote
|
||||||
|
MAX_RETRIES=3 # Reintentos antes de rechazar
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Estados de la Cola
|
||||||
|
|
||||||
|
| Estado | Descripción |
|
||||||
|
|--------|-------------|
|
||||||
|
| pendiente | En espera de procesamiento |
|
||||||
|
| procesando | FELDMAN está validando |
|
||||||
|
| consolidado | Validado y creado bloque/milestone |
|
||||||
|
| rechazado | Falló validación, no se reintentará |
|
||||||
|
| error | Error técnico, puede reintentarse |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Auditoría
|
||||||
|
|
||||||
|
Cada validación se registra en `feldman_validaciones`:
|
||||||
|
|
||||||
|
```sql
|
||||||
|
-- Consultar historial de validaciones
|
||||||
|
SELECT
|
||||||
|
h_entrada,
|
||||||
|
regla,
|
||||||
|
resultado,
|
||||||
|
mensaje,
|
||||||
|
validated_at
|
||||||
|
FROM feldman_validaciones
|
||||||
|
WHERE h_entrada = 'abc123...'
|
||||||
|
ORDER BY validated_at;
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Futuro: Blockchain
|
||||||
|
|
||||||
|
FELDMAN está diseñado para evolucionar hacia blockchain:
|
||||||
|
|
||||||
|
1. **Actual:** Encadenamiento por hash_previo en PostgreSQL
|
||||||
|
2. **Fase 2:** Merkle tree para verificación eficiente
|
||||||
|
3. **Fase 3:** Smart contract en blockchain (Ethereum/Polygon)
|
||||||
|
|
||||||
|
```
|
||||||
|
Merkle Root
|
||||||
|
│
|
||||||
|
┌───────────┴───────────┐
|
||||||
|
│ │
|
||||||
|
Hash(AB) Hash(CD)
|
||||||
|
│ │
|
||||||
|
┌─────┴─────┐ ┌─────┴─────┐
|
||||||
|
│ │ │ │
|
||||||
|
Hash(A) Hash(B) Hash(C) Hash(D)
|
||||||
|
│ │ │ │
|
||||||
|
Bloque A Bloque B Bloque C Bloque D
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Monitoreo
|
||||||
|
|
||||||
|
### Logs
|
||||||
|
```bash
|
||||||
|
docker logs feldman-feldman -f
|
||||||
|
```
|
||||||
|
|
||||||
|
### Consultas de Estado
|
||||||
|
|
||||||
|
```sql
|
||||||
|
-- Elementos pendientes
|
||||||
|
SELECT COUNT(*) FROM feldman_cola WHERE estado = 'pendiente';
|
||||||
|
|
||||||
|
-- Últimas validaciones fallidas
|
||||||
|
SELECT * FROM feldman_validaciones
|
||||||
|
WHERE resultado = false
|
||||||
|
ORDER BY validated_at DESC
|
||||||
|
LIMIT 10;
|
||||||
|
|
||||||
|
-- Bloques creados hoy
|
||||||
|
SELECT COUNT(*) FROM bloques
|
||||||
|
WHERE created_at >= CURRENT_DATE;
|
||||||
|
```
|
||||||
|
-- Últimas validaciones fallidas
|
||||||
|
SELECT * FROM feldman_validaciones
|
||||||
|
WHERE resultado = false
|
||||||
|
ORDER BY validated_at DESC
|
||||||
|
LIMIT 10;
|
||||||
|
|
||||||
|
-- Bloques creados hoy
|
||||||
|
SELECT COUNT(*) FROM bloques
|
||||||
|
WHERE created_at >= CURRENT_DATE;
|
||||||
|
```
|
||||||
403
03_COMPONENTES/servicios/grace.md
Normal file
403
03_COMPONENTES/servicios/grace.md
Normal file
@@ -0,0 +1,403 @@
|
|||||||
|
# GRACE - Servicio de IA Cognitiva
|
||||||
|
|
||||||
|
**Versión:** 5.0
|
||||||
|
**Fecha:** 2024-12-24
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Estado Actual
|
||||||
|
|
||||||
|
**BLOQUEADO:** RunPod no inicia workers.
|
||||||
|
|
||||||
|
| Aspecto | Valor |
|
||||||
|
|---------|-------|
|
||||||
|
| Plataforma | RunPod Serverless |
|
||||||
|
| Endpoint ID | r00x4g3rrwkbyh |
|
||||||
|
| Balance | ~$72 USD |
|
||||||
|
| Workers activos | 0 |
|
||||||
|
| Estado | Inoperativo |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Descripción
|
||||||
|
|
||||||
|
GRACE es el servicio de extracción de información mediante IA. Procesa contenido multimedia para extraer datos estructurados.
|
||||||
|
|
||||||
|
```
|
||||||
|
Contenido Raw
|
||||||
|
(audio, imagen, video, documento)
|
||||||
|
│
|
||||||
|
▼
|
||||||
|
┌─────────────────────────────────────────┐
|
||||||
|
│ GRACE (GPU) │
|
||||||
|
│ │
|
||||||
|
│ ┌─────────┐ ┌─────────┐ ┌─────────┐ │
|
||||||
|
│ │ ASR │ │ OCR │ │ TTS │ │
|
||||||
|
│ └─────────┘ └─────────┘ └─────────┘ │
|
||||||
|
│ ┌─────────┐ ┌─────────┐ ┌─────────┐ │
|
||||||
|
│ │ Face │ │Embeddings│ │ Avatar │ │
|
||||||
|
│ └─────────┘ └─────────┘ └─────────┘ │
|
||||||
|
│ │
|
||||||
|
│ + 12 módulos pendientes │
|
||||||
|
└─────────────────────────────────────────┘
|
||||||
|
│
|
||||||
|
▼
|
||||||
|
Datos Estructurados
|
||||||
|
(JSON, vectores, metadatos)
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Módulos Implementados (6 de 18)
|
||||||
|
|
||||||
|
### ASR - Automatic Speech Recognition
|
||||||
|
|
||||||
|
| Campo | Valor |
|
||||||
|
|-------|-------|
|
||||||
|
| Modelo | Whisper Large v3 |
|
||||||
|
| Input | Audio (mp3, wav, m4a) |
|
||||||
|
| Output | Texto + timestamps |
|
||||||
|
| GPU | A10G recomendado |
|
||||||
|
|
||||||
|
```python
|
||||||
|
@grace.module("asr")
|
||||||
|
def process_asr(audio_bytes: bytes) -> dict:
|
||||||
|
"""Transcribe audio a texto."""
|
||||||
|
model = whisper.load_model("large-v3")
|
||||||
|
result = model.transcribe(audio_bytes)
|
||||||
|
return {
|
||||||
|
"text": result["text"],
|
||||||
|
"segments": result["segments"],
|
||||||
|
"language": result["language"]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### OCR - Optical Character Recognition
|
||||||
|
|
||||||
|
| Campo | Valor |
|
||||||
|
|-------|-------|
|
||||||
|
| Modelo | EasyOCR + Tesseract |
|
||||||
|
| Input | Imagen (jpg, png) |
|
||||||
|
| Output | Texto + bounding boxes |
|
||||||
|
| GPU | A10G recomendado |
|
||||||
|
|
||||||
|
```python
|
||||||
|
@grace.module("ocr")
|
||||||
|
def process_ocr(image_bytes: bytes) -> dict:
|
||||||
|
"""Extrae texto de imagen."""
|
||||||
|
reader = easyocr.Reader(['es', 'en'])
|
||||||
|
result = reader.readtext(image_bytes)
|
||||||
|
return {
|
||||||
|
"text": " ".join([r[1] for r in result]),
|
||||||
|
"boxes": [{"text": r[1], "bbox": r[0], "confidence": r[2]} for r in result]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### TTS - Text to Speech
|
||||||
|
|
||||||
|
| Campo | Valor |
|
||||||
|
|-------|-------|
|
||||||
|
| Modelo | Coqui TTS |
|
||||||
|
| Input | Texto |
|
||||||
|
| Output | Audio (wav) |
|
||||||
|
| GPU | A10G recomendado |
|
||||||
|
|
||||||
|
### Face - Reconocimiento Facial
|
||||||
|
|
||||||
|
| Campo | Valor |
|
||||||
|
|-------|-------|
|
||||||
|
| Modelo | InsightFace |
|
||||||
|
| Input | Imagen |
|
||||||
|
| Output | Embeddings faciales |
|
||||||
|
| GPU | A10G recomendado |
|
||||||
|
|
||||||
|
### Embeddings - Vectores Semánticos
|
||||||
|
|
||||||
|
| Campo | Valor |
|
||||||
|
|-------|-------|
|
||||||
|
| Modelo | Sentence Transformers |
|
||||||
|
| Input | Texto |
|
||||||
|
| Output | Vector 384/768 dims |
|
||||||
|
| GPU | A10G recomendado |
|
||||||
|
|
||||||
|
### Avatar - Generación de Avatares
|
||||||
|
|
||||||
|
| Campo | Valor |
|
||||||
|
|-------|-------|
|
||||||
|
| Modelo | StyleGAN |
|
||||||
|
| Input | Imagen facial |
|
||||||
|
| Output | Avatar estilizado |
|
||||||
|
| GPU | A10G recomendado |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Módulos Pendientes (12)
|
||||||
|
|
||||||
|
| Módulo | Descripción | Prioridad |
|
||||||
|
|--------|-------------|-----------|
|
||||||
|
| Document parsing | Extracción de PDFs | Alta |
|
||||||
|
| Image classification | Clasificación de imágenes | Media |
|
||||||
|
| Object detection | Detección de objetos | Media |
|
||||||
|
| Sentiment analysis | Análisis de sentimiento | Media |
|
||||||
|
| Named entity recognition | Extracción de entidades | Alta |
|
||||||
|
| Translation | Traducción de texto | Media |
|
||||||
|
| Summarization | Resumen de texto | Media |
|
||||||
|
| Question answering | Respuestas a preguntas | Baja |
|
||||||
|
| Code generation | Generación de código | Baja |
|
||||||
|
| Audio classification | Clasificación de audio | Baja |
|
||||||
|
| Video analysis | Análisis de video | Baja |
|
||||||
|
| Multimodal fusion | Fusión multimodal | Baja |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Código en R2
|
||||||
|
|
||||||
|
El código está listo y disponible:
|
||||||
|
|
||||||
|
```
|
||||||
|
s3://architect/gpu-services/
|
||||||
|
├── base/
|
||||||
|
│ └── bootstrap.sh # Script de inicialización
|
||||||
|
├── grace/
|
||||||
|
│ └── code/
|
||||||
|
│ └── handler.py # Handler principal
|
||||||
|
├── penny/
|
||||||
|
│ └── code/
|
||||||
|
│ └── handler.py
|
||||||
|
└── factory/
|
||||||
|
└── code/
|
||||||
|
└── handler.py
|
||||||
|
```
|
||||||
|
|
||||||
|
### Descargar Código
|
||||||
|
|
||||||
|
```bash
|
||||||
|
source /home/orchestrator/orchestrator/.env
|
||||||
|
export AWS_ACCESS_KEY_ID="$R2_ACCESS_KEY"
|
||||||
|
export AWS_SECRET_ACCESS_KEY="$R2_SECRET_KEY"
|
||||||
|
|
||||||
|
aws s3 sync s3://architect/gpu-services/grace/ ./grace/ \
|
||||||
|
--endpoint-url https://7dedae6030f5554d99d37e98a5232996.r2.cloudflarestorage.com
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Handler RunPod
|
||||||
|
|
||||||
|
```python
|
||||||
|
import runpod
|
||||||
|
|
||||||
|
def handler(event):
|
||||||
|
"""
|
||||||
|
Handler principal de GRACE para RunPod Serverless.
|
||||||
|
|
||||||
|
Input:
|
||||||
|
{
|
||||||
|
"input": {
|
||||||
|
"module": "asr|ocr|tts|face|embeddings|avatar",
|
||||||
|
"data": "base64 encoded content",
|
||||||
|
"options": {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Output:
|
||||||
|
{
|
||||||
|
"output": { ... resultado del módulo ... },
|
||||||
|
"error": null
|
||||||
|
}
|
||||||
|
"""
|
||||||
|
try:
|
||||||
|
module = event["input"]["module"]
|
||||||
|
data = base64.b64decode(event["input"]["data"])
|
||||||
|
options = event["input"].get("options", {})
|
||||||
|
|
||||||
|
if module == "asr":
|
||||||
|
result = process_asr(data, **options)
|
||||||
|
elif module == "ocr":
|
||||||
|
result = process_ocr(data, **options)
|
||||||
|
elif module == "tts":
|
||||||
|
result = process_tts(data, **options)
|
||||||
|
elif module == "face":
|
||||||
|
result = process_face(data, **options)
|
||||||
|
elif module == "embeddings":
|
||||||
|
result = process_embeddings(data, **options)
|
||||||
|
elif module == "avatar":
|
||||||
|
result = process_avatar(data, **options)
|
||||||
|
else:
|
||||||
|
return {"error": f"Módulo desconocido: {module}"}
|
||||||
|
|
||||||
|
return {"output": result, "error": None}
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
return {"error": str(e)}
|
||||||
|
|
||||||
|
runpod.serverless.start({"handler": handler})
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Uso desde MASON
|
||||||
|
|
||||||
|
```python
|
||||||
|
import runpod
|
||||||
|
import base64
|
||||||
|
|
||||||
|
runpod.api_key = "..." # Desde Infisical
|
||||||
|
|
||||||
|
def call_grace(module: str, content: bytes, options: dict = None) -> dict:
|
||||||
|
"""Llama a GRACE para procesar contenido."""
|
||||||
|
|
||||||
|
job = runpod.run(
|
||||||
|
endpoint_id="r00x4g3rrwkbyh",
|
||||||
|
input={
|
||||||
|
"module": module,
|
||||||
|
"data": base64.b64encode(content).decode(),
|
||||||
|
"options": options or {}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
# Polling hasta completar
|
||||||
|
while True:
|
||||||
|
status = runpod.status(job["id"])
|
||||||
|
if status["status"] == "COMPLETED":
|
||||||
|
return status["output"]
|
||||||
|
elif status["status"] == "FAILED":
|
||||||
|
raise Exception(status.get("error", "Job failed"))
|
||||||
|
time.sleep(1)
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Problema Actual: Workers No Inician
|
||||||
|
|
||||||
|
### Incidente 2024-12-24
|
||||||
|
|
||||||
|
- **Síntoma:** 0 workers activos a pesar de jobs en cola
|
||||||
|
- **Balance:** $72+ (suficiente)
|
||||||
|
- **Configuración:** Correcta
|
||||||
|
- **Causa probable:** Problema de capacidad RunPod
|
||||||
|
|
||||||
|
### Intentos de Diagnóstico
|
||||||
|
|
||||||
|
1. Verificado endpoint activo en dashboard
|
||||||
|
2. Verificado balance suficiente
|
||||||
|
3. Verificado configuración de scaling
|
||||||
|
4. Jobs quedan en estado "IN_QUEUE" indefinidamente
|
||||||
|
|
||||||
|
### Log de Errores
|
||||||
|
|
||||||
|
```
|
||||||
|
No hay logs disponibles - workers nunca inician
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Alternativas Evaluadas
|
||||||
|
|
||||||
|
### 1. Modal (Recomendado)
|
||||||
|
|
||||||
|
```python
|
||||||
|
import modal
|
||||||
|
|
||||||
|
stub = modal.Stub("grace")
|
||||||
|
image = modal.Image.debian_slim().pip_install("whisper", "easyocr")
|
||||||
|
|
||||||
|
@stub.function(gpu="A10G", image=image)
|
||||||
|
def process_asr(audio_bytes: bytes) -> dict:
|
||||||
|
import whisper
|
||||||
|
model = whisper.load_model("large-v3")
|
||||||
|
result = model.transcribe(audio_bytes)
|
||||||
|
return {"text": result["text"]}
|
||||||
|
```
|
||||||
|
|
||||||
|
**Pros:**
|
||||||
|
- Serverless real
|
||||||
|
- Buen DX (developer experience)
|
||||||
|
- Python-native
|
||||||
|
- Cold start rápido
|
||||||
|
|
||||||
|
**Contras:**
|
||||||
|
- Menos GPUs disponibles que RunPod
|
||||||
|
- Pricing puede ser mayor
|
||||||
|
|
||||||
|
### 2. Replicate
|
||||||
|
|
||||||
|
```python
|
||||||
|
import replicate
|
||||||
|
|
||||||
|
output = replicate.run(
|
||||||
|
"openai/whisper:large-v3",
|
||||||
|
input={"audio": audio_url}
|
||||||
|
)
|
||||||
|
```
|
||||||
|
|
||||||
|
**Pros:**
|
||||||
|
- Modelos pre-entrenados
|
||||||
|
- API simple
|
||||||
|
- Sin gestión de infraestructura
|
||||||
|
|
||||||
|
**Contras:**
|
||||||
|
- Menos control
|
||||||
|
- Más caro a escala
|
||||||
|
- Dependencia de modelos de terceros
|
||||||
|
|
||||||
|
### 3. Lambda Labs
|
||||||
|
|
||||||
|
**Pros:**
|
||||||
|
- Hardware dedicado
|
||||||
|
- GPUs disponibles
|
||||||
|
|
||||||
|
**Contras:**
|
||||||
|
- Menos flexible
|
||||||
|
- Reserva manual
|
||||||
|
- No serverless
|
||||||
|
|
||||||
|
### 4. Self-Hosted
|
||||||
|
|
||||||
|
**Pros:**
|
||||||
|
- Control total
|
||||||
|
- Sin dependencias externas
|
||||||
|
- Costo fijo a largo plazo
|
||||||
|
|
||||||
|
**Contras:**
|
||||||
|
- CapEx alto
|
||||||
|
- Mantenimiento
|
||||||
|
- Requiere expertise
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Plan de Migración
|
||||||
|
|
||||||
|
### Fase 1: Evaluación
|
||||||
|
|
||||||
|
- [ ] Crear cuenta Modal
|
||||||
|
- [ ] Portar módulo ASR a Modal
|
||||||
|
- [ ] Comparar latencia con RunPod (cuando funcione)
|
||||||
|
- [ ] Comparar costos
|
||||||
|
|
||||||
|
### Fase 2: Migración
|
||||||
|
|
||||||
|
- [ ] Portar 6 handlers a Modal
|
||||||
|
- [ ] Actualizar endpoints en MASON
|
||||||
|
- [ ] Actualizar documentación
|
||||||
|
- [ ] Testing end-to-end
|
||||||
|
|
||||||
|
### Fase 3: Producción
|
||||||
|
|
||||||
|
- [ ] Desplegar en Modal
|
||||||
|
- [ ] Monitorear costos y performance
|
||||||
|
- [ ] Deprecar RunPod endpoints
|
||||||
|
- [ ] Cancelar cuenta RunPod
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Principio Fundamental
|
||||||
|
|
||||||
|
**GRACE nunca modifica datos.**
|
||||||
|
|
||||||
|
GRACE es read-only: extrae información pero no puede modificar el contenido original ni los datos del sistema. Las extracciones se almacenan como metadatos asociados al contenido original.
|
||||||
|
|
||||||
|
```
|
||||||
|
Contenido Original ────► GRACE ────► Metadatos Extraídos
|
||||||
|
(inmutable) (nuevos datos)
|
||||||
|
```
|
||||||
177
04_SEGURIDAD/modelo-amenazas.md
Normal file
177
04_SEGURIDAD/modelo-amenazas.md
Normal file
@@ -0,0 +1,177 @@
|
|||||||
|
# Modelo de Amenazas TZZR
|
||||||
|
|
||||||
|
**Versión:** 5.0
|
||||||
|
**Fecha:** 2024-12-24
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Resumen Ejecutivo
|
||||||
|
|
||||||
|
El sistema TZZR tiene una base de seguridad sólida (SSH keys, PostgreSQL SSL, tokens de autenticación) pero presenta exposiciones críticas que requieren atención inmediata.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Hallazgos Críticos
|
||||||
|
|
||||||
|
### CRÍTICO-001: CORP/HST sin Firewall
|
||||||
|
|
||||||
|
**Descripción:** UFW inactivo en servidores CORP y HST.
|
||||||
|
**Impacto:** Todos los puertos expuestos a Internet.
|
||||||
|
**Evidencia:** `ufw status` devuelve "inactive".
|
||||||
|
|
||||||
|
**Mitigación:**
|
||||||
|
```bash
|
||||||
|
# CORP
|
||||||
|
ufw default deny incoming
|
||||||
|
ufw allow 22/tcp
|
||||||
|
ufw allow 80/tcp
|
||||||
|
ufw allow 443/tcp
|
||||||
|
ufw enable
|
||||||
|
|
||||||
|
# HST
|
||||||
|
ufw default deny incoming
|
||||||
|
ufw allow 22/tcp
|
||||||
|
ufw allow 80/tcp
|
||||||
|
ufw allow 443/tcp
|
||||||
|
ufw enable
|
||||||
|
```
|
||||||
|
|
||||||
|
### CRÍTICO-002: PostgreSQL 5432 Expuesto
|
||||||
|
|
||||||
|
**Descripción:** PostgreSQL en ARCHITECT escucha en 0.0.0.0:5432.
|
||||||
|
**Impacto:** Accesible desde cualquier IP (aunque requiere autenticación).
|
||||||
|
|
||||||
|
**Mitigación:**
|
||||||
|
```
|
||||||
|
# /etc/postgresql/16/main/postgresql.conf
|
||||||
|
listen_addresses = '127.0.0.1,172.17.0.1'
|
||||||
|
```
|
||||||
|
|
||||||
|
### CRÍTICO-003: Archivos .env Legibles
|
||||||
|
|
||||||
|
**Descripción:** Archivos .env con permisos 644 (legibles por todos).
|
||||||
|
**Impacto:** Credenciales accesibles a cualquier usuario del sistema.
|
||||||
|
|
||||||
|
**Mitigación:**
|
||||||
|
```bash
|
||||||
|
chmod 600 /opt/clara/.env
|
||||||
|
chmod 600 /opt/alfred/.env
|
||||||
|
chmod 600 /opt/margaret/.env
|
||||||
|
chmod 600 /opt/mason/.env
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Hallazgos Altos
|
||||||
|
|
||||||
|
### ALTO-001: fail2ban No Configurado
|
||||||
|
|
||||||
|
**Descripción:** fail2ban failed en DECK, inactive en CORP.
|
||||||
|
**Impacto:** SSH bruteforce sin mitigación automática.
|
||||||
|
**Evidencia:** Ataques activos desde 165.232.81.204, 188.166.115.48.
|
||||||
|
|
||||||
|
**Mitigación:**
|
||||||
|
```bash
|
||||||
|
apt install fail2ban
|
||||||
|
systemctl enable fail2ban
|
||||||
|
# jail: sshd, maxretry=3, bantime=1h
|
||||||
|
```
|
||||||
|
|
||||||
|
### ALTO-002: Triple Gestión de Secretos
|
||||||
|
|
||||||
|
**Descripción:** Credenciales en Infisical, tablas creds_*, y archivos .env.
|
||||||
|
**Impacto:** No hay fuente única de verdad, riesgo de desincronización.
|
||||||
|
|
||||||
|
**Mitigación:**
|
||||||
|
- Migrar todas las credenciales a Infisical
|
||||||
|
- Eliminar .env hardcodeados
|
||||||
|
- creds_* solo para referencia
|
||||||
|
|
||||||
|
### ALTO-003: Servicios sin TLS Interno
|
||||||
|
|
||||||
|
**Descripción:** CLARA, MARGARET, MASON, FELDMAN en HTTP plano.
|
||||||
|
**Impacto:** Tráfico interno sin cifrar.
|
||||||
|
|
||||||
|
**Mitigación:**
|
||||||
|
- Configurar mTLS entre servicios
|
||||||
|
- Usar Caddy como reverse proxy con TLS
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Hallazgos Medios
|
||||||
|
|
||||||
|
### MEDIO-001: No hay Backup PostgreSQL
|
||||||
|
|
||||||
|
**Descripción:** Solo Gitea tiene backup en R2, PostgreSQL sin backup.
|
||||||
|
**Impacto:** Pérdida de datos en caso de fallo.
|
||||||
|
|
||||||
|
**Mitigación:**
|
||||||
|
```bash
|
||||||
|
# Cron diario
|
||||||
|
pg_dump architect | gzip | aws s3 cp - s3://architect/backups/architect_$(date +%F).sql.gz
|
||||||
|
```
|
||||||
|
|
||||||
|
### MEDIO-002: SENTINEL No Desplegado
|
||||||
|
|
||||||
|
**Descripción:** Sistema de auditoría planificado pero no implementado.
|
||||||
|
**Impacto:** Sin visibilidad de anomalías.
|
||||||
|
|
||||||
|
**Mitigación:** Implementar SENTINEL LIGHT mode básico.
|
||||||
|
|
||||||
|
### MEDIO-003: No hay Rotación de Secretos
|
||||||
|
|
||||||
|
**Descripción:** Sin política de rotación de credenciales.
|
||||||
|
**Impacto:** Credenciales comprometidas persisten indefinidamente.
|
||||||
|
|
||||||
|
**Mitigación:**
|
||||||
|
- API keys: 90 días
|
||||||
|
- DB passwords: 180 días
|
||||||
|
- SSH keys: 365 días
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Controles Existentes
|
||||||
|
|
||||||
|
| Control | Estado | Notas |
|
||||||
|
|---------|--------|-------|
|
||||||
|
| SSH Keys | Activo | Permisos 600 correctos |
|
||||||
|
| PostgreSQL SSL | Activo | SCRAM-SHA-256 |
|
||||||
|
| H_INSTANCIA Auth | Activo | CLARA/MARGARET |
|
||||||
|
| Gitea Tokens | Activo | Lectura/Escritura separados |
|
||||||
|
| DECK UFW | Activo | Política deny incoming |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Matriz de Riesgos
|
||||||
|
|
||||||
|
| ID | Riesgo | Probabilidad | Impacto | Prioridad |
|
||||||
|
|----|--------|--------------|---------|-----------|
|
||||||
|
| CRÍTICO-001 | Firewall desactivado | Alta | Alto | Semana 1 |
|
||||||
|
| CRÍTICO-002 | PostgreSQL expuesto | Media | Alto | Semana 1 |
|
||||||
|
| CRÍTICO-003 | .env legibles | Alta | Alto | Semana 1 |
|
||||||
|
| ALTO-001 | Sin fail2ban | Alta | Medio | Semana 1 |
|
||||||
|
| ALTO-002 | Secretos duplicados | Media | Medio | Mes 1 |
|
||||||
|
| ALTO-003 | Sin TLS interno | Baja | Medio | Mes 1 |
|
||||||
|
| MEDIO-001 | Sin backup PG | Baja | Alto | Mes 1 |
|
||||||
|
| MEDIO-002 | Sin SENTINEL | Baja | Medio | Mes 2 |
|
||||||
|
| MEDIO-003 | Sin rotación | Baja | Medio | Mes 2 |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Plan de Remediación
|
||||||
|
|
||||||
|
### Semana 1 (Urgente)
|
||||||
|
- [ ] Activar UFW en CORP y HST
|
||||||
|
- [ ] chmod 600 en todos los .env
|
||||||
|
- [ ] Instalar fail2ban
|
||||||
|
- [ ] PostgreSQL bind 127.0.0.1
|
||||||
|
|
||||||
|
### Mes 1 (Alta)
|
||||||
|
- [ ] Migrar secretos a Infisical
|
||||||
|
- [ ] TLS interno
|
||||||
|
- [ ] Backup PostgreSQL automatizado
|
||||||
|
|
||||||
|
### Mes 2 (Media)
|
||||||
|
- [ ] SENTINEL LIGHT mode
|
||||||
|
- [ ] Política de rotación
|
||||||
|
- [ ] Monitoreo de certificados
|
||||||
292
04_SEGURIDAD/secretos.md
Normal file
292
04_SEGURIDAD/secretos.md
Normal file
@@ -0,0 +1,292 @@
|
|||||||
|
# Gestión de Secretos TZZR
|
||||||
|
|
||||||
|
**Versión:** 5.0
|
||||||
|
**Fecha:** 2024-12-24
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Estado Actual: Triple Gestión
|
||||||
|
|
||||||
|
**PROBLEMA CRÍTICO:** Actualmente existen tres fuentes de secretos sin sincronización.
|
||||||
|
|
||||||
|
```
|
||||||
|
┌─────────────────────────────────────────────────────────────────┐
|
||||||
|
│ FUENTES DE SECRETOS │
|
||||||
|
│ │
|
||||||
|
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
|
||||||
|
│ │ Infisical │ │ creds_* │ │ .env │ │
|
||||||
|
│ │ (central) │ │ (PostgreSQL)│ │ (archivos) │ │
|
||||||
|
│ └─────────────┘ └─────────────┘ └─────────────┘ │
|
||||||
|
│ │ │ │ │
|
||||||
|
│ ▼ ▼ ▼ │
|
||||||
|
│ ┌─────────────────────────────────────────────────────────┐ │
|
||||||
|
│ │ ❌ SIN SINCRONIZACIÓN - Riesgo de inconsistencia │ │
|
||||||
|
│ └─────────────────────────────────────────────────────────┘ │
|
||||||
|
└─────────────────────────────────────────────────────────────────┘
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Fuente 1: Infisical
|
||||||
|
|
||||||
|
**URL:** http://localhost:8082 (ARCHITECT)
|
||||||
|
**Estado:** Operativo
|
||||||
|
|
||||||
|
### Configuración
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Acceso a Infisical
|
||||||
|
infisical login
|
||||||
|
infisical secrets --env=prod
|
||||||
|
```
|
||||||
|
|
||||||
|
### Ventajas
|
||||||
|
- Centralizado
|
||||||
|
- Versionado
|
||||||
|
- Auditable
|
||||||
|
- SDK para múltiples lenguajes
|
||||||
|
|
||||||
|
### Uso Actual
|
||||||
|
- Parcial - no todos los servicios lo usan
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Fuente 2: Tablas creds_* (PostgreSQL)
|
||||||
|
|
||||||
|
**Base de datos:** architect
|
||||||
|
**Estado:** Activo
|
||||||
|
|
||||||
|
### Tablas
|
||||||
|
|
||||||
|
| Tabla | Contenido |
|
||||||
|
|-------|-----------|
|
||||||
|
| creds_ia | APIs de IA (OpenAI, Anthropic, etc.) |
|
||||||
|
| creds_runpod | API keys de RunPod |
|
||||||
|
| creds_r2 | Credenciales Cloudflare R2 |
|
||||||
|
| creds_gitea | Tokens Gitea |
|
||||||
|
| creds_mail | Credenciales SMTP |
|
||||||
|
| creds_apis | APIs externas varias |
|
||||||
|
|
||||||
|
### Schema Típico
|
||||||
|
|
||||||
|
```sql
|
||||||
|
CREATE TABLE creds_ia (
|
||||||
|
id SERIAL PRIMARY KEY,
|
||||||
|
servicio VARCHAR(50) NOT NULL,
|
||||||
|
api_key TEXT NOT NULL,
|
||||||
|
descripcion TEXT,
|
||||||
|
activo BOOLEAN DEFAULT true,
|
||||||
|
created_at TIMESTAMP DEFAULT NOW(),
|
||||||
|
updated_at TIMESTAMP DEFAULT NOW()
|
||||||
|
);
|
||||||
|
```
|
||||||
|
|
||||||
|
### Acceso
|
||||||
|
|
||||||
|
```sql
|
||||||
|
-- Consultar credenciales
|
||||||
|
sudo -u postgres psql -d architect -c "SELECT servicio, descripcion FROM creds_ia;"
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Fuente 3: Archivos .env
|
||||||
|
|
||||||
|
**Ubicaciones:**
|
||||||
|
- /opt/clara/.env
|
||||||
|
- /opt/alfred/.env
|
||||||
|
- /opt/margaret/.env
|
||||||
|
- /opt/mason/.env
|
||||||
|
- /opt/feldman/.env
|
||||||
|
|
||||||
|
### ALERTA CRÍTICA
|
||||||
|
|
||||||
|
```
|
||||||
|
Permisos actuales: 644 (legibles por todos)
|
||||||
|
Permisos correctos: 600 (solo propietario)
|
||||||
|
```
|
||||||
|
|
||||||
|
### Contenido Típico
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Ejemplo .env
|
||||||
|
DB_HOST=localhost
|
||||||
|
DB_PORT=5432
|
||||||
|
DB_NAME=corp
|
||||||
|
DB_USER=margaret
|
||||||
|
DB_PASSWORD=secreto_aqui # ⚠️ Expuesto si 644
|
||||||
|
|
||||||
|
R2_ACCESS_KEY=access_key_aqui
|
||||||
|
R2_SECRET_KEY=secret_key_aqui # ⚠️ Expuesto si 644
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Decisión D-001: Migración a Infisical
|
||||||
|
|
||||||
|
### Objetivo
|
||||||
|
Infisical como **única fuente de verdad** para todos los secretos.
|
||||||
|
|
||||||
|
### Plan de Migración
|
||||||
|
|
||||||
|
```
|
||||||
|
Fase 1: Inventario
|
||||||
|
├── Catalogar todos los secretos en creds_*
|
||||||
|
├── Catalogar todos los secretos en .env
|
||||||
|
└── Identificar duplicados/inconsistencias
|
||||||
|
|
||||||
|
Fase 2: Centralización
|
||||||
|
├── Migrar todos los secretos a Infisical
|
||||||
|
├── Organizar por proyecto/ambiente
|
||||||
|
└── Establecer políticas de acceso
|
||||||
|
|
||||||
|
Fase 3: Actualización de Servicios
|
||||||
|
├── CLARA: Usar Infisical SDK
|
||||||
|
├── MARGARET: Usar Infisical SDK
|
||||||
|
├── MASON: Usar Infisical SDK
|
||||||
|
├── FELDMAN: Usar Infisical SDK
|
||||||
|
└── ALFRED/JARED: Usar Infisical SDK
|
||||||
|
|
||||||
|
Fase 4: Deprecación
|
||||||
|
├── Eliminar archivos .env
|
||||||
|
├── Marcar creds_* como "solo referencia"
|
||||||
|
└── Documentar proceso de rotación
|
||||||
|
```
|
||||||
|
|
||||||
|
### Implementación con SDK
|
||||||
|
|
||||||
|
```python
|
||||||
|
from infisical_client import InfisicalClient
|
||||||
|
|
||||||
|
client = InfisicalClient(
|
||||||
|
host="http://localhost:8082",
|
||||||
|
token=INFISICAL_TOKEN
|
||||||
|
)
|
||||||
|
|
||||||
|
# Obtener secreto
|
||||||
|
db_password = client.get_secret(
|
||||||
|
secret_name="DB_PASSWORD",
|
||||||
|
project_id="tzzr",
|
||||||
|
environment="production"
|
||||||
|
)
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Rotación de Secretos
|
||||||
|
|
||||||
|
### Política Propuesta
|
||||||
|
|
||||||
|
| Tipo | Frecuencia | Responsable |
|
||||||
|
|------|------------|-------------|
|
||||||
|
| API Keys externas | 90 días | Orchestrator |
|
||||||
|
| Contraseñas DB | 180 días | DBA |
|
||||||
|
| SSH Keys | 365 días | SysAdmin |
|
||||||
|
| Tokens Gitea | 180 días | DevOps |
|
||||||
|
|
||||||
|
### Proceso de Rotación
|
||||||
|
|
||||||
|
```
|
||||||
|
1. Generar nuevo secreto
|
||||||
|
2. Actualizar en Infisical
|
||||||
|
3. Desplegar servicios afectados
|
||||||
|
4. Verificar funcionamiento
|
||||||
|
5. Revocar secreto anterior
|
||||||
|
6. Documentar en changelog
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Mitigación Inmediata
|
||||||
|
|
||||||
|
### Paso 1: Permisos .env
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Ejecutar en todos los servidores
|
||||||
|
|
||||||
|
# DECK
|
||||||
|
ssh -i ~/.ssh/tzzr root@72.62.1.113 'chmod 600 /opt/clara/.env /opt/alfred/.env'
|
||||||
|
|
||||||
|
# CORP
|
||||||
|
ssh -i ~/.ssh/tzzr root@92.112.181.188 'chmod 600 /opt/margaret/.env /opt/mason/.env /opt/feldman/.env'
|
||||||
|
```
|
||||||
|
|
||||||
|
### Paso 2: Auditoría
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Verificar permisos
|
||||||
|
ls -la /opt/*/.env
|
||||||
|
|
||||||
|
# Buscar secretos expuestos
|
||||||
|
grep -r "password\|secret\|key" /opt/*/ 2>/dev/null
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Inventario de Secretos
|
||||||
|
|
||||||
|
### APIs de IA
|
||||||
|
|
||||||
|
| Servicio | Ubicación Actual | Notas |
|
||||||
|
|----------|------------------|-------|
|
||||||
|
| OpenAI | creds_ia | GPT-4 |
|
||||||
|
| Anthropic | creds_ia | Claude |
|
||||||
|
| Replicate | creds_ia | Modelos varios |
|
||||||
|
| RunPod | creds_runpod | GRACE, PENNY, FACTORY |
|
||||||
|
|
||||||
|
### Infraestructura
|
||||||
|
|
||||||
|
| Servicio | Ubicación Actual | Notas |
|
||||||
|
|----------|------------------|-------|
|
||||||
|
| PostgreSQL | .env + creds_* | Múltiples usuarios |
|
||||||
|
| R2/Cloudflare | .env + creds_r2 | Access + Secret key |
|
||||||
|
| Gitea | .env + creds_gitea | Read + Write tokens |
|
||||||
|
| SMTP | creds_mail | Mailcow |
|
||||||
|
|
||||||
|
### Servicios Externos
|
||||||
|
|
||||||
|
| Servicio | Ubicación Actual | Notas |
|
||||||
|
|----------|------------------|-------|
|
||||||
|
| Stripe | creds_apis | (si aplica) |
|
||||||
|
| Twilio | creds_apis | (si aplica) |
|
||||||
|
| AWS | creds_apis | (si aplica) |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Verificación de Seguridad
|
||||||
|
|
||||||
|
### Checklist Diario
|
||||||
|
|
||||||
|
- [ ] Permisos .env son 600
|
||||||
|
- [ ] No hay secretos en logs
|
||||||
|
- [ ] No hay secretos en commits git
|
||||||
|
- [ ] Infisical accesible
|
||||||
|
|
||||||
|
### Comandos de Verificación
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Verificar permisos
|
||||||
|
find /opt -name ".env" -exec ls -la {} \;
|
||||||
|
|
||||||
|
# Buscar secretos en git history
|
||||||
|
git log -p | grep -i "password\|secret\|key\|token"
|
||||||
|
|
||||||
|
# Verificar Infisical
|
||||||
|
curl -s http://localhost:8082/api/v1/health
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Buenas Prácticas
|
||||||
|
|
||||||
|
### DO (Hacer)
|
||||||
|
- Usar Infisical para todos los secretos nuevos
|
||||||
|
- Rotar secretos según política
|
||||||
|
- Auditar accesos regularmente
|
||||||
|
- Cifrar secretos en reposo
|
||||||
|
|
||||||
|
### DON'T (No Hacer)
|
||||||
|
- Hardcodear secretos en código
|
||||||
|
- Commitear .env a repositorios
|
||||||
|
- Compartir secretos por chat/email
|
||||||
|
- Usar el mismo secreto en múltiples servicios
|
||||||
359
05_OPERACIONES/backup-recovery.md
Normal file
359
05_OPERACIONES/backup-recovery.md
Normal file
@@ -0,0 +1,359 @@
|
|||||||
|
# Backup y Recovery TZZR
|
||||||
|
|
||||||
|
**Versión:** 5.0
|
||||||
|
**Fecha:** 2024-12-24
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Estado Actual
|
||||||
|
|
||||||
|
### Backups Existentes
|
||||||
|
|
||||||
|
| Sistema | Backup | Destino | Frecuencia | Estado |
|
||||||
|
|---------|--------|---------|------------|--------|
|
||||||
|
| Gitea | Sí | R2 | Manual | Operativo |
|
||||||
|
| PostgreSQL ARCHITECT | No | - | - | **CRÍTICO** |
|
||||||
|
| PostgreSQL DECK | No | - | - | **CRÍTICO** |
|
||||||
|
| PostgreSQL CORP | No | - | - | **CRÍTICO** |
|
||||||
|
| PostgreSQL HST | No | - | - | **CRÍTICO** |
|
||||||
|
| R2 buckets | Built-in | R2 | Automático | Operativo |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Plan de Backup Propuesto
|
||||||
|
|
||||||
|
### PostgreSQL - Backup Diario
|
||||||
|
|
||||||
|
```bash
|
||||||
|
#!/bin/bash
|
||||||
|
# /opt/scripts/backup_postgres.sh
|
||||||
|
|
||||||
|
set -e
|
||||||
|
|
||||||
|
DATE=$(date +%F)
|
||||||
|
BACKUP_DIR="/tmp/pg_backup"
|
||||||
|
|
||||||
|
# Cargar credenciales R2
|
||||||
|
source /home/orchestrator/orchestrator/.env
|
||||||
|
export AWS_ACCESS_KEY_ID="$R2_ACCESS_KEY"
|
||||||
|
export AWS_SECRET_ACCESS_KEY="$R2_SECRET_KEY"
|
||||||
|
|
||||||
|
R2_ENDPOINT="https://7dedae6030f5554d99d37e98a5232996.r2.cloudflarestorage.com"
|
||||||
|
|
||||||
|
mkdir -p $BACKUP_DIR
|
||||||
|
|
||||||
|
# Backup ARCHITECT
|
||||||
|
echo "Backing up ARCHITECT..."
|
||||||
|
sudo -u postgres pg_dump architect | gzip > $BACKUP_DIR/architect_$DATE.sql.gz
|
||||||
|
aws s3 cp $BACKUP_DIR/architect_$DATE.sql.gz s3://architect/backups/postgres/ \
|
||||||
|
--endpoint-url $R2_ENDPOINT
|
||||||
|
|
||||||
|
# Cleanup local
|
||||||
|
rm -rf $BACKUP_DIR
|
||||||
|
|
||||||
|
echo "Backup completado: $DATE"
|
||||||
|
```
|
||||||
|
|
||||||
|
### Cron Configuration
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# /etc/cron.d/tzzr-backup
|
||||||
|
# Backup diario a las 3:00 AM
|
||||||
|
0 3 * * * orchestrator /opt/scripts/backup_postgres.sh >> /var/log/tzzr-backup.log 2>&1
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Backup por Servidor
|
||||||
|
|
||||||
|
### ARCHITECT (69.62.126.110)
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Base de datos: architect
|
||||||
|
sudo -u postgres pg_dump architect | gzip > architect_$(date +%F).sql.gz
|
||||||
|
|
||||||
|
# Subir a R2
|
||||||
|
aws s3 cp architect_$(date +%F).sql.gz s3://architect/backups/postgres/ \
|
||||||
|
--endpoint-url $R2_ENDPOINT
|
||||||
|
```
|
||||||
|
|
||||||
|
### DECK (72.62.1.113)
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Base de datos: tzzr
|
||||||
|
ssh deck 'sudo -u postgres pg_dump tzzr | gzip' > deck_tzzr_$(date +%F).sql.gz
|
||||||
|
|
||||||
|
# Subir a R2
|
||||||
|
aws s3 cp deck_tzzr_$(date +%F).sql.gz s3://architect/backups/deck/ \
|
||||||
|
--endpoint-url $R2_ENDPOINT
|
||||||
|
```
|
||||||
|
|
||||||
|
### CORP (92.112.181.188)
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Base de datos: corp
|
||||||
|
ssh corp 'sudo -u postgres pg_dump corp | gzip' > corp_$(date +%F).sql.gz
|
||||||
|
|
||||||
|
# Subir a R2
|
||||||
|
aws s3 cp corp_$(date +%F).sql.gz s3://architect/backups/corp/ \
|
||||||
|
--endpoint-url $R2_ENDPOINT
|
||||||
|
```
|
||||||
|
|
||||||
|
### HST (72.62.2.84)
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Base de datos: hst_images
|
||||||
|
ssh hst 'sudo -u postgres pg_dump hst_images | gzip' > hst_$(date +%F).sql.gz
|
||||||
|
|
||||||
|
# Subir a R2
|
||||||
|
aws s3 cp hst_$(date +%F).sql.gz s3://architect/backups/hst/ \
|
||||||
|
--endpoint-url $R2_ENDPOINT
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Gitea Backup
|
||||||
|
|
||||||
|
### Backup Manual
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# En ARCHITECT
|
||||||
|
docker exec -t gitea bash -c 'gitea dump -c /data/gitea/conf/app.ini'
|
||||||
|
docker cp gitea:/app/gitea/gitea-dump-*.zip ./
|
||||||
|
|
||||||
|
# Subir a R2
|
||||||
|
aws s3 cp gitea-dump-*.zip s3://architect/backups/gitea/ \
|
||||||
|
--endpoint-url $R2_ENDPOINT
|
||||||
|
```
|
||||||
|
|
||||||
|
### Backup Automático
|
||||||
|
|
||||||
|
```bash
|
||||||
|
#!/bin/bash
|
||||||
|
# /opt/scripts/backup_gitea.sh
|
||||||
|
|
||||||
|
DATE=$(date +%F_%H%M)
|
||||||
|
|
||||||
|
# Crear dump
|
||||||
|
docker exec -t gitea bash -c "gitea dump -c /data/gitea/conf/app.ini -f /tmp/gitea-dump-$DATE.zip"
|
||||||
|
|
||||||
|
# Copiar fuera del container
|
||||||
|
docker cp gitea:/tmp/gitea-dump-$DATE.zip /tmp/
|
||||||
|
|
||||||
|
# Subir a R2
|
||||||
|
source /home/orchestrator/orchestrator/.env
|
||||||
|
export AWS_ACCESS_KEY_ID="$R2_ACCESS_KEY"
|
||||||
|
export AWS_SECRET_ACCESS_KEY="$R2_SECRET_KEY"
|
||||||
|
|
||||||
|
aws s3 cp /tmp/gitea-dump-$DATE.zip s3://architect/backups/gitea/ \
|
||||||
|
--endpoint-url https://7dedae6030f5554d99d37e98a5232996.r2.cloudflarestorage.com
|
||||||
|
|
||||||
|
# Cleanup
|
||||||
|
rm /tmp/gitea-dump-$DATE.zip
|
||||||
|
docker exec gitea rm /tmp/gitea-dump-$DATE.zip
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Estructura de Backups en R2
|
||||||
|
|
||||||
|
```
|
||||||
|
s3://architect/backups/
|
||||||
|
├── postgres/
|
||||||
|
│ ├── architect_2024-12-24.sql.gz
|
||||||
|
│ ├── architect_2024-12-23.sql.gz
|
||||||
|
│ └── ...
|
||||||
|
├── deck/
|
||||||
|
│ ├── deck_tzzr_2024-12-24.sql.gz
|
||||||
|
│ └── ...
|
||||||
|
├── corp/
|
||||||
|
│ ├── corp_2024-12-24.sql.gz
|
||||||
|
│ └── ...
|
||||||
|
├── hst/
|
||||||
|
│ ├── hst_2024-12-24.sql.gz
|
||||||
|
│ └── ...
|
||||||
|
└── gitea/
|
||||||
|
├── gitea-dump-2024-12-24_0300.zip
|
||||||
|
└── ...
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Retención de Backups
|
||||||
|
|
||||||
|
### Política Propuesta
|
||||||
|
|
||||||
|
| Tipo | Retención | Notas |
|
||||||
|
|------|-----------|-------|
|
||||||
|
| Diario | 7 días | Últimos 7 backups |
|
||||||
|
| Semanal | 4 semanas | Domingos |
|
||||||
|
| Mensual | 12 meses | Primer día del mes |
|
||||||
|
|
||||||
|
### Script de Limpieza
|
||||||
|
|
||||||
|
```bash
|
||||||
|
#!/bin/bash
|
||||||
|
# /opt/scripts/cleanup_backups.sh
|
||||||
|
|
||||||
|
source /home/orchestrator/orchestrator/.env
|
||||||
|
export AWS_ACCESS_KEY_ID="$R2_ACCESS_KEY"
|
||||||
|
export AWS_SECRET_ACCESS_KEY="$R2_SECRET_KEY"
|
||||||
|
|
||||||
|
R2_ENDPOINT="https://7dedae6030f5554d99d37e98a5232996.r2.cloudflarestorage.com"
|
||||||
|
|
||||||
|
# Eliminar backups más antiguos de 30 días
|
||||||
|
# (Implementar con lifecycle rules de R2 preferentemente)
|
||||||
|
|
||||||
|
aws s3 ls s3://architect/backups/postgres/ --endpoint-url $R2_ENDPOINT | \
|
||||||
|
while read -r line; do
|
||||||
|
createDate=$(echo $line | awk '{print $1}')
|
||||||
|
fileName=$(echo $line | awk '{print $4}')
|
||||||
|
|
||||||
|
# Comparar fechas y eliminar si > 30 días
|
||||||
|
# ...
|
||||||
|
done
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Recovery
|
||||||
|
|
||||||
|
### PostgreSQL - Restaurar Base de Datos
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Descargar backup
|
||||||
|
aws s3 cp s3://architect/backups/postgres/architect_2024-12-24.sql.gz . \
|
||||||
|
--endpoint-url $R2_ENDPOINT
|
||||||
|
|
||||||
|
# Descomprimir
|
||||||
|
gunzip architect_2024-12-24.sql.gz
|
||||||
|
|
||||||
|
# Restaurar (¡CUIDADO! Sobrescribe datos existentes)
|
||||||
|
sudo -u postgres psql -d architect < architect_2024-12-24.sql
|
||||||
|
```
|
||||||
|
|
||||||
|
### PostgreSQL - Restaurar a Nueva Base
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Crear nueva base de datos
|
||||||
|
sudo -u postgres createdb architect_restored
|
||||||
|
|
||||||
|
# Restaurar
|
||||||
|
gunzip -c architect_2024-12-24.sql.gz | sudo -u postgres psql -d architect_restored
|
||||||
|
```
|
||||||
|
|
||||||
|
### Gitea - Restaurar
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Descargar backup
|
||||||
|
aws s3 cp s3://architect/backups/gitea/gitea-dump-2024-12-24_0300.zip . \
|
||||||
|
--endpoint-url $R2_ENDPOINT
|
||||||
|
|
||||||
|
# Detener Gitea
|
||||||
|
docker stop gitea
|
||||||
|
|
||||||
|
# Copiar al container
|
||||||
|
docker cp gitea-dump-2024-12-24_0300.zip gitea:/tmp/
|
||||||
|
|
||||||
|
# Restaurar
|
||||||
|
docker exec gitea bash -c "cd /tmp && unzip gitea-dump-2024-12-24_0300.zip"
|
||||||
|
# Seguir instrucciones de Gitea para restore
|
||||||
|
|
||||||
|
# Iniciar Gitea
|
||||||
|
docker start gitea
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Disaster Recovery Plan
|
||||||
|
|
||||||
|
### Escenario 1: Pérdida de ARCHITECT
|
||||||
|
|
||||||
|
1. Provisionar nuevo VPS con misma IP (si posible)
|
||||||
|
2. Instalar Ubuntu 22.04
|
||||||
|
3. Configurar usuario orchestrator
|
||||||
|
4. Restaurar PostgreSQL desde R2
|
||||||
|
5. Restaurar Gitea desde R2
|
||||||
|
6. Reinstalar Docker y servicios
|
||||||
|
7. Verificar conectividad con DECK/CORP/HST
|
||||||
|
|
||||||
|
### Escenario 2: Pérdida de DECK
|
||||||
|
|
||||||
|
1. Provisionar nuevo VPS
|
||||||
|
2. Restaurar PostgreSQL (tzzr) desde backup
|
||||||
|
3. Reinstalar CLARA, ALFRED
|
||||||
|
4. Reinstalar Mailcow (requiere backup separado)
|
||||||
|
5. Actualizar DNS si IP cambió
|
||||||
|
|
||||||
|
### Escenario 3: Pérdida de CORP
|
||||||
|
|
||||||
|
1. Provisionar nuevo VPS
|
||||||
|
2. Restaurar PostgreSQL (corp) desde backup
|
||||||
|
3. Reinstalar MARGARET, JARED, MASON, FELDMAN
|
||||||
|
4. Reinstalar Odoo, Nextcloud
|
||||||
|
5. Activar UFW (nuevo servidor)
|
||||||
|
|
||||||
|
### Escenario 4: Pérdida de R2
|
||||||
|
|
||||||
|
**IMPROBABLE** - Cloudflare tiene redundancia multi-región.
|
||||||
|
|
||||||
|
Mitigación: Backup mensual a segundo proveedor (AWS S3 Glacier).
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Verificación de Backups
|
||||||
|
|
||||||
|
### Test Mensual
|
||||||
|
|
||||||
|
```bash
|
||||||
|
#!/bin/bash
|
||||||
|
# /opt/scripts/verify_backup.sh
|
||||||
|
|
||||||
|
# Descargar último backup
|
||||||
|
LATEST=$(aws s3 ls s3://architect/backups/postgres/ --endpoint-url $R2_ENDPOINT | \
|
||||||
|
sort | tail -1 | awk '{print $4}')
|
||||||
|
|
||||||
|
aws s3 cp s3://architect/backups/postgres/$LATEST /tmp/ \
|
||||||
|
--endpoint-url $R2_ENDPOINT
|
||||||
|
|
||||||
|
# Verificar integridad
|
||||||
|
gunzip -t /tmp/$LATEST
|
||||||
|
if [ $? -eq 0 ]; then
|
||||||
|
echo "Backup válido: $LATEST"
|
||||||
|
else
|
||||||
|
echo "ERROR: Backup corrupto: $LATEST"
|
||||||
|
# Enviar alerta
|
||||||
|
fi
|
||||||
|
|
||||||
|
rm /tmp/$LATEST
|
||||||
|
```
|
||||||
|
|
||||||
|
### Checklist de Verificación
|
||||||
|
|
||||||
|
- [ ] Backup PostgreSQL ARCHITECT existe (< 24h)
|
||||||
|
- [ ] Backup PostgreSQL DECK existe (< 24h)
|
||||||
|
- [ ] Backup PostgreSQL CORP existe (< 24h)
|
||||||
|
- [ ] Backup Gitea existe (< 7d)
|
||||||
|
- [ ] Integridad verificada (gunzip -t)
|
||||||
|
- [ ] Restore test exitoso (mensual)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Alertas
|
||||||
|
|
||||||
|
### Configuración ntfy
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Notificar si backup falla
|
||||||
|
if [ $? -ne 0 ]; then
|
||||||
|
curl -d "Backup FALLIDO: $DATE" ntfy.sh/tzzr-alerts
|
||||||
|
fi
|
||||||
|
```
|
||||||
|
|
||||||
|
### Monitoreo
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Verificar último backup
|
||||||
|
aws s3 ls s3://architect/backups/postgres/ --endpoint-url $R2_ENDPOINT | \
|
||||||
|
sort | tail -5
|
||||||
|
```
|
||||||
383
05_OPERACIONES/infraestructura.md
Normal file
383
05_OPERACIONES/infraestructura.md
Normal file
@@ -0,0 +1,383 @@
|
|||||||
|
# Infraestructura TZZR
|
||||||
|
|
||||||
|
**Versión:** 5.0
|
||||||
|
**Fecha:** 2024-12-24
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Resumen de Servidores
|
||||||
|
|
||||||
|
| Servidor | IP Pública | Rol | Proveedor |
|
||||||
|
|----------|------------|-----|-----------|
|
||||||
|
| ARCHITECT | 69.62.126.110 | Coordinador central | VPS |
|
||||||
|
| DECK | 72.62.1.113 | Personal | VPS |
|
||||||
|
| CORP | 92.112.181.188 | Empresarial | VPS |
|
||||||
|
| HST | 72.62.2.84 | API Tags | VPS |
|
||||||
|
| LOCKER | R2 | Almacenamiento | Cloudflare |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## ARCHITECT (69.62.126.110)
|
||||||
|
|
||||||
|
### Especificaciones
|
||||||
|
- **OS:** Ubuntu 22.04 LTS
|
||||||
|
- **Usuario:** orchestrator
|
||||||
|
- **Servicios:** PostgreSQL, Gitea, Orchestrator, Infisical
|
||||||
|
|
||||||
|
### Puertos
|
||||||
|
|
||||||
|
| Puerto | Servicio | Estado |
|
||||||
|
|--------|----------|--------|
|
||||||
|
| 22 | SSH | Abierto |
|
||||||
|
| 2222 | Gitea SSH | Abierto |
|
||||||
|
| 3000 | Gitea HTTP | Abierto |
|
||||||
|
| 5050 | Orchestrator | Abierto |
|
||||||
|
| 5432 | PostgreSQL | **CRÍTICO: 0.0.0.0** |
|
||||||
|
| 8082 | Infisical | Abierto |
|
||||||
|
|
||||||
|
### Acceso
|
||||||
|
|
||||||
|
```bash
|
||||||
|
ssh orchestrator@69.62.126.110
|
||||||
|
```
|
||||||
|
|
||||||
|
### PostgreSQL
|
||||||
|
|
||||||
|
```bash
|
||||||
|
sudo -u postgres psql -d architect
|
||||||
|
```
|
||||||
|
|
||||||
|
### Gitea
|
||||||
|
|
||||||
|
```
|
||||||
|
URL: http://localhost:3000
|
||||||
|
Token lectura: 5ca10e5b71d41f9b22f12d0f96bfc2e6de5c2c7f
|
||||||
|
Token escritura: ac5a604b9aac5cee81192a656fc918f9efa3834b
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## DECK (72.62.1.113)
|
||||||
|
|
||||||
|
### Especificaciones
|
||||||
|
- **OS:** Ubuntu 22.04 LTS
|
||||||
|
- **Usuario:** root
|
||||||
|
- **Servicios:** CLARA, ALFRED, Mailcow, Directus, etc.
|
||||||
|
|
||||||
|
### Puertos
|
||||||
|
|
||||||
|
| Puerto | Servicio | Estado |
|
||||||
|
|--------|----------|--------|
|
||||||
|
| 22 | SSH | Abierto |
|
||||||
|
| 25 | SMTP | Abierto |
|
||||||
|
| 143 | IMAP | Abierto |
|
||||||
|
| 465 | SMTPS | Abierto |
|
||||||
|
| 587 | Submission | Abierto |
|
||||||
|
| 993 | IMAPS | Abierto |
|
||||||
|
| 5051 | CLARA | Abierto |
|
||||||
|
| 5052 | ALFRED | Abierto |
|
||||||
|
| 8055 | Directus | Abierto |
|
||||||
|
| 8080 | ntfy | Abierto |
|
||||||
|
| 8082 | FileBrowser | Abierto |
|
||||||
|
| 8083 | Shlink | Abierto |
|
||||||
|
| 8085 | Vaultwarden | Abierto |
|
||||||
|
|
||||||
|
### Acceso
|
||||||
|
|
||||||
|
```bash
|
||||||
|
ssh -i ~/.ssh/tzzr root@72.62.1.113
|
||||||
|
```
|
||||||
|
|
||||||
|
### Docker Containers
|
||||||
|
|
||||||
|
```bash
|
||||||
|
docker ps --format "table {{.Names}}\t{{.Status}}\t{{.Ports}}"
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## CORP (92.112.181.188)
|
||||||
|
|
||||||
|
### Especificaciones
|
||||||
|
- **OS:** Ubuntu 22.04 LTS
|
||||||
|
- **Usuario:** root
|
||||||
|
- **Servicios:** MARGARET, JARED, MASON, FELDMAN, Odoo, Nextcloud
|
||||||
|
|
||||||
|
### Puertos
|
||||||
|
|
||||||
|
| Puerto | Servicio | Estado |
|
||||||
|
|--------|----------|--------|
|
||||||
|
| 22 | SSH | Abierto |
|
||||||
|
| 80 | Caddy HTTP | Abierto |
|
||||||
|
| 443 | Caddy HTTPS | Abierto |
|
||||||
|
| 5051 | MARGARET | Abierto |
|
||||||
|
| 5052 | JARED | Abierto |
|
||||||
|
| 5053 | MASON | Abierto |
|
||||||
|
| 5054 | FELDMAN | Abierto |
|
||||||
|
| 5432 | PostgreSQL | Local |
|
||||||
|
| 8055 | Directus | Abierto |
|
||||||
|
| 8069 | Odoo | Abierto |
|
||||||
|
| 8080 | Nextcloud | Abierto |
|
||||||
|
| 8081 | Vaultwarden | Abierto |
|
||||||
|
|
||||||
|
### Acceso
|
||||||
|
|
||||||
|
```bash
|
||||||
|
ssh -i ~/.ssh/tzzr root@92.112.181.188
|
||||||
|
```
|
||||||
|
|
||||||
|
### Firewall
|
||||||
|
|
||||||
|
**ALERTA CRÍTICA: UFW INACTIVO**
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Verificar estado
|
||||||
|
ufw status
|
||||||
|
|
||||||
|
# Activar (cuando se autorice)
|
||||||
|
ufw default deny incoming
|
||||||
|
ufw allow 22/tcp
|
||||||
|
ufw allow 80/tcp
|
||||||
|
ufw allow 443/tcp
|
||||||
|
ufw enable
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## HST (72.62.2.84)
|
||||||
|
|
||||||
|
### Especificaciones
|
||||||
|
- **OS:** Ubuntu 22.04 LTS
|
||||||
|
- **Usuario:** root
|
||||||
|
- **Servicios:** Nginx, Directus, PostgreSQL
|
||||||
|
|
||||||
|
### Puertos
|
||||||
|
|
||||||
|
| Puerto | Servicio | Estado |
|
||||||
|
|--------|----------|--------|
|
||||||
|
| 22 | SSH | Abierto |
|
||||||
|
| 80 | Nginx HTTP | Abierto |
|
||||||
|
| 443 | Nginx HTTPS | Abierto |
|
||||||
|
| 5432 | PostgreSQL | Local |
|
||||||
|
| 8055 | Directus | Abierto |
|
||||||
|
|
||||||
|
### Acceso
|
||||||
|
|
||||||
|
```bash
|
||||||
|
ssh -i ~/.ssh/tzzr root@72.62.2.84
|
||||||
|
```
|
||||||
|
|
||||||
|
### API Pública
|
||||||
|
|
||||||
|
```
|
||||||
|
https://tzrtech.org/{h_maestro}.png
|
||||||
|
```
|
||||||
|
|
||||||
|
### Estadísticas HST
|
||||||
|
|
||||||
|
| Grupo | Cantidad |
|
||||||
|
|-------|----------|
|
||||||
|
| hst | 639 |
|
||||||
|
| spe | 145 |
|
||||||
|
| vsn | 84 |
|
||||||
|
| flg | 65 |
|
||||||
|
| vue | 21 |
|
||||||
|
| **Total** | **973** |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## LOCKER (Cloudflare R2)
|
||||||
|
|
||||||
|
### Endpoint
|
||||||
|
|
||||||
|
```
|
||||||
|
https://7dedae6030f5554d99d37e98a5232996.r2.cloudflarestorage.com
|
||||||
|
```
|
||||||
|
|
||||||
|
### Buckets
|
||||||
|
|
||||||
|
| Bucket | Uso | Tamaño Aprox |
|
||||||
|
|--------|-----|--------------|
|
||||||
|
| architect | Backups, configs, GPU services | ~500 MB |
|
||||||
|
| deck | Archivos personales (CLARA) | Variable |
|
||||||
|
| corp | Archivos empresariales (MARGARET) | Variable |
|
||||||
|
| hst | Imágenes de tags | ~100 MB |
|
||||||
|
| locker | Almacenamiento general | Variable |
|
||||||
|
|
||||||
|
### Acceso
|
||||||
|
|
||||||
|
```bash
|
||||||
|
source /home/orchestrator/orchestrator/.env
|
||||||
|
export AWS_ACCESS_KEY_ID="$R2_ACCESS_KEY"
|
||||||
|
export AWS_SECRET_ACCESS_KEY="$R2_SECRET_KEY"
|
||||||
|
|
||||||
|
aws s3 ls s3://architect/ \
|
||||||
|
--endpoint-url https://7dedae6030f5554d99d37e98a5232996.r2.cloudflarestorage.com
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## SSH Keys
|
||||||
|
|
||||||
|
### Ubicación
|
||||||
|
|
||||||
|
```
|
||||||
|
/home/orchestrator/.ssh/tzzr # Private key
|
||||||
|
/home/orchestrator/.ssh/tzzr.pub # Public key
|
||||||
|
```
|
||||||
|
|
||||||
|
### Permisos
|
||||||
|
|
||||||
|
```bash
|
||||||
|
chmod 600 ~/.ssh/tzzr
|
||||||
|
chmod 644 ~/.ssh/tzzr.pub
|
||||||
|
```
|
||||||
|
|
||||||
|
### Configuración SSH
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# ~/.ssh/config
|
||||||
|
Host deck
|
||||||
|
HostName 72.62.1.113
|
||||||
|
User root
|
||||||
|
IdentityFile ~/.ssh/tzzr
|
||||||
|
|
||||||
|
Host corp
|
||||||
|
HostName 92.112.181.188
|
||||||
|
User root
|
||||||
|
IdentityFile ~/.ssh/tzzr
|
||||||
|
|
||||||
|
Host hst
|
||||||
|
HostName 72.62.2.84
|
||||||
|
User root
|
||||||
|
IdentityFile ~/.ssh/tzzr
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Bases de Datos
|
||||||
|
|
||||||
|
### architect (ARCHITECT)
|
||||||
|
|
||||||
|
```
|
||||||
|
Host: localhost
|
||||||
|
Port: 5432
|
||||||
|
Database: architect
|
||||||
|
User: postgres
|
||||||
|
```
|
||||||
|
|
||||||
|
Tablas principales:
|
||||||
|
- context_blocks
|
||||||
|
- agents
|
||||||
|
- creds_*
|
||||||
|
|
||||||
|
### tzzr (DECK)
|
||||||
|
|
||||||
|
```
|
||||||
|
Host: localhost
|
||||||
|
Port: 5432
|
||||||
|
Database: tzzr
|
||||||
|
```
|
||||||
|
|
||||||
|
Tablas principales:
|
||||||
|
- clara_log
|
||||||
|
- deck_visiones
|
||||||
|
- deck_milestones
|
||||||
|
|
||||||
|
### corp (CORP)
|
||||||
|
|
||||||
|
```
|
||||||
|
Host: localhost
|
||||||
|
Port: 5432
|
||||||
|
Database: corp
|
||||||
|
```
|
||||||
|
|
||||||
|
Tablas principales:
|
||||||
|
- margaret_log
|
||||||
|
- mason_workspace
|
||||||
|
- feldman_cola
|
||||||
|
- milestones
|
||||||
|
- bloques
|
||||||
|
|
||||||
|
### hst_images (HST)
|
||||||
|
|
||||||
|
```
|
||||||
|
Host: localhost
|
||||||
|
Port: 5432
|
||||||
|
Database: hst_images
|
||||||
|
```
|
||||||
|
|
||||||
|
Tablas principales:
|
||||||
|
- hst_tags
|
||||||
|
- hst_trees
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Monitoreo
|
||||||
|
|
||||||
|
### Comandos de Estado
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Verificar servicios ARCHITECT
|
||||||
|
systemctl status postgresql
|
||||||
|
docker ps
|
||||||
|
|
||||||
|
# Verificar servicios DECK
|
||||||
|
ssh deck 'docker ps'
|
||||||
|
ssh deck 'systemctl status fail2ban'
|
||||||
|
|
||||||
|
# Verificar servicios CORP
|
||||||
|
ssh corp 'docker ps'
|
||||||
|
ssh corp 'ufw status'
|
||||||
|
|
||||||
|
# Verificar servicios HST
|
||||||
|
ssh hst 'systemctl status nginx'
|
||||||
|
ssh hst 'systemctl status postgresql'
|
||||||
|
```
|
||||||
|
|
||||||
|
### Logs Importantes
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# PostgreSQL
|
||||||
|
journalctl -u postgresql -f
|
||||||
|
|
||||||
|
# Docker containers
|
||||||
|
docker logs <container> -f
|
||||||
|
|
||||||
|
# Nginx (HST)
|
||||||
|
tail -f /var/log/nginx/access.log
|
||||||
|
tail -f /var/log/nginx/error.log
|
||||||
|
|
||||||
|
# SSH auth
|
||||||
|
tail -f /var/log/auth.log
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Diagrama de Red
|
||||||
|
|
||||||
|
```
|
||||||
|
Internet
|
||||||
|
│
|
||||||
|
┌──────────────────────────┼──────────────────────────┐
|
||||||
|
│ │ │
|
||||||
|
▼ ▼ ▼
|
||||||
|
┌───────────────┐ ┌───────────────┐ ┌───────────────┐
|
||||||
|
│ ARCHITECT │ │ DECK │ │ CORP │
|
||||||
|
│ 69.62.126.110 │◄────────│ 72.62.1.113 │────────►│92.112.181.188 │
|
||||||
|
└───────────────┘ SSH └───────────────┘ SSH └───────────────┘
|
||||||
|
│ │ │
|
||||||
|
│ │ │
|
||||||
|
│ ▼ │
|
||||||
|
│ ┌───────────────┐ │
|
||||||
|
│ │ HST │ │
|
||||||
|
└────────────────►│ 72.62.2.84 │◄──────────────────┘
|
||||||
|
SSH └───────────────┘
|
||||||
|
│
|
||||||
|
│ HTTPS
|
||||||
|
▼
|
||||||
|
┌───────────────┐
|
||||||
|
│ Cloudflare │
|
||||||
|
│ R2 │
|
||||||
|
└───────────────┘
|
||||||
|
```
|
||||||
179
06_INTEGRACIONES/gpu-services.md
Normal file
179
06_INTEGRACIONES/gpu-services.md
Normal file
@@ -0,0 +1,179 @@
|
|||||||
|
# GPU Services - RunPod
|
||||||
|
|
||||||
|
**Versión:** 5.0
|
||||||
|
**Fecha:** 2024-12-24
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Estado Crítico
|
||||||
|
|
||||||
|
**ALERTA: RunPod NO es confiable para producción.**
|
||||||
|
|
||||||
|
### Incidente 2024-12-24
|
||||||
|
|
||||||
|
RunPod falló en provisionar workers a pesar de:
|
||||||
|
- Configuración correcta
|
||||||
|
- Balance suficiente ($72+)
|
||||||
|
- Jobs en cola
|
||||||
|
|
||||||
|
**Resultado:** 0 workers activos. Servicio GPU inoperativo.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Endpoints Configurados
|
||||||
|
|
||||||
|
| Servicio | Endpoint ID | Estado |
|
||||||
|
|----------|-------------|--------|
|
||||||
|
| GRACE | r00x4g3rrwkbyh | Inactivo |
|
||||||
|
| PENNY | 0mxhaokgsmgee3 | Inactivo |
|
||||||
|
| FACTORY | ddnuk6y35zi56a | Inactivo |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## GRACE (Extracción IA)
|
||||||
|
|
||||||
|
### Módulos Implementados (6 de 18)
|
||||||
|
|
||||||
|
| Módulo | Descripción |
|
||||||
|
|--------|-------------|
|
||||||
|
| ASR | Speech-to-text |
|
||||||
|
| OCR | Reconocimiento texto |
|
||||||
|
| TTS | Text-to-speech |
|
||||||
|
| Face | Reconocimiento facial |
|
||||||
|
| Embeddings | Vectores semánticos |
|
||||||
|
| Avatar | Generación avatares |
|
||||||
|
|
||||||
|
### Módulos Pendientes (12)
|
||||||
|
|
||||||
|
- Document parsing
|
||||||
|
- Image classification
|
||||||
|
- Object detection
|
||||||
|
- Sentiment analysis
|
||||||
|
- Named entity recognition
|
||||||
|
- Translation
|
||||||
|
- Summarization
|
||||||
|
- Question answering
|
||||||
|
- Code generation
|
||||||
|
- Audio classification
|
||||||
|
- Video analysis
|
||||||
|
- Multimodal fusion
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Código Disponible en R2
|
||||||
|
|
||||||
|
Los handlers están listos y son portables:
|
||||||
|
|
||||||
|
```
|
||||||
|
s3://architect/gpu-services/
|
||||||
|
├── base/
|
||||||
|
│ └── bootstrap.sh
|
||||||
|
├── grace/
|
||||||
|
│ └── code/handler.py
|
||||||
|
├── penny/
|
||||||
|
│ └── code/handler.py
|
||||||
|
└── factory/
|
||||||
|
└── code/handler.py
|
||||||
|
```
|
||||||
|
|
||||||
|
### Descargar Código
|
||||||
|
|
||||||
|
```bash
|
||||||
|
source /home/orchestrator/orchestrator/.env
|
||||||
|
export AWS_ACCESS_KEY_ID="$R2_ACCESS_KEY"
|
||||||
|
export AWS_SECRET_ACCESS_KEY="$R2_SECRET_KEY"
|
||||||
|
|
||||||
|
aws s3 sync s3://architect/gpu-services/ ./gpu-services/ \
|
||||||
|
--endpoint-url https://7dedae6030f5554d99d37e98a5232996.r2.cloudflarestorage.com
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Alternativas a Evaluar
|
||||||
|
|
||||||
|
### 1. Modal (Recomendado)
|
||||||
|
|
||||||
|
- Pricing: Pay-per-use
|
||||||
|
- Pros: Serverless real, buen DX, Python-native
|
||||||
|
- Contras: Menos GPUs disponibles que RunPod
|
||||||
|
|
||||||
|
```python
|
||||||
|
import modal
|
||||||
|
|
||||||
|
stub = modal.Stub("grace")
|
||||||
|
|
||||||
|
@stub.function(gpu="A10G")
|
||||||
|
def process_asr(audio_bytes):
|
||||||
|
# Whisper inference
|
||||||
|
pass
|
||||||
|
```
|
||||||
|
|
||||||
|
### 2. Replicate
|
||||||
|
|
||||||
|
- Pricing: Per-inference
|
||||||
|
- Pros: Modelos pre-entrenados, API simple
|
||||||
|
- Contras: Menos control, más caro a escala
|
||||||
|
|
||||||
|
### 3. Lambda Labs
|
||||||
|
|
||||||
|
- Pricing: Hourly
|
||||||
|
- Pros: Hardware dedicado
|
||||||
|
- Contras: Menos flexible, reserva manual
|
||||||
|
|
||||||
|
### 4. Self-Hosted
|
||||||
|
|
||||||
|
- Pricing: Upfront + hosting
|
||||||
|
- Pros: Control total, sin dependencias
|
||||||
|
- Contras: CapEx alto, mantenimiento
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Migración Propuesta
|
||||||
|
|
||||||
|
### Fase 1: Evaluación (1 semana)
|
||||||
|
- [ ] Probar Modal con ASR handler
|
||||||
|
- [ ] Comparar latencia y costo
|
||||||
|
|
||||||
|
### Fase 2: Migración (2 semanas)
|
||||||
|
- [ ] Portar 6 handlers a Modal
|
||||||
|
- [ ] Actualizar endpoints en MASON
|
||||||
|
|
||||||
|
### Fase 3: Producción
|
||||||
|
- [ ] Desplegar en Modal
|
||||||
|
- [ ] Deprecar RunPod endpoints
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Configuración Actual RunPod
|
||||||
|
|
||||||
|
### API Key
|
||||||
|
|
||||||
|
```
|
||||||
|
Almacenada en: creds_runpod (PostgreSQL ARCHITECT)
|
||||||
|
Campo: api_key_runpod
|
||||||
|
```
|
||||||
|
|
||||||
|
### SDK
|
||||||
|
|
||||||
|
```python
|
||||||
|
import runpod
|
||||||
|
|
||||||
|
runpod.api_key = "..."
|
||||||
|
|
||||||
|
# Crear job
|
||||||
|
job = runpod.run(
|
||||||
|
endpoint_id="r00x4g3rrwkbyh",
|
||||||
|
input={"audio": "base64..."}
|
||||||
|
)
|
||||||
|
|
||||||
|
# Check status
|
||||||
|
status = runpod.status(job["id"])
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Recomendación
|
||||||
|
|
||||||
|
**NO confiar en RunPod para producción.**
|
||||||
|
|
||||||
|
Migrar a Modal como prioridad alta una vez resueltos los issues de seguridad críticos.
|
||||||
387
99_ANEXOS/inventario-repos.md
Normal file
387
99_ANEXOS/inventario-repos.md
Normal file
@@ -0,0 +1,387 @@
|
|||||||
|
# Inventario de Repositorios TZZR
|
||||||
|
|
||||||
|
**Versión:** 5.0
|
||||||
|
**Fecha:** 2024-12-24
|
||||||
|
**Fuente:** Gitea (http://localhost:3000/tzzr)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Resumen
|
||||||
|
|
||||||
|
| Categoría | Cantidad |
|
||||||
|
|-----------|----------|
|
||||||
|
| Infraestructura | 6 |
|
||||||
|
| Data Services | 6 |
|
||||||
|
| Security/Ops | 6 |
|
||||||
|
| Interfaces | 6 |
|
||||||
|
| **Total** | **24** |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Infraestructura
|
||||||
|
|
||||||
|
### orchestrator
|
||||||
|
|
||||||
|
| Campo | Valor |
|
||||||
|
|-------|-------|
|
||||||
|
| URL | http://localhost:3000/tzzr/orchestrator |
|
||||||
|
| Estado | Activo |
|
||||||
|
| Descripción | Sistema de orquestación central |
|
||||||
|
| Prioridad | Alta |
|
||||||
|
|
||||||
|
**Archivos clave:**
|
||||||
|
- `main.py` - Entrada principal
|
||||||
|
- `.env` - Configuración
|
||||||
|
- `docker-compose.yml` - Despliegue
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### hst-api
|
||||||
|
|
||||||
|
| Campo | Valor |
|
||||||
|
|-------|-------|
|
||||||
|
| URL | http://localhost:3000/tzzr/hst-api |
|
||||||
|
| Estado | Activo |
|
||||||
|
| Descripción | API de tags HST (973 tags) |
|
||||||
|
| Prioridad | Alta |
|
||||||
|
|
||||||
|
**Archivos clave:**
|
||||||
|
- `api/routes.py` - Endpoints
|
||||||
|
- `db/schema.sql` - Schema
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### clara
|
||||||
|
|
||||||
|
| Campo | Valor |
|
||||||
|
|-------|-------|
|
||||||
|
| URL | http://localhost:3000/tzzr/clara |
|
||||||
|
| Estado | Activo |
|
||||||
|
| Descripción | Agente de ingesta personal |
|
||||||
|
| Prioridad | Alta |
|
||||||
|
|
||||||
|
**Archivos clave:**
|
||||||
|
- `app.py` - API FastAPI
|
||||||
|
- `ingest.py` - Lógica de ingesta
|
||||||
|
- `Dockerfile` - Container
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### margaret
|
||||||
|
|
||||||
|
| Campo | Valor |
|
||||||
|
|-------|-------|
|
||||||
|
| URL | http://localhost:3000/tzzr/margaret |
|
||||||
|
| Estado | Activo |
|
||||||
|
| Descripción | Agente de ingesta corporativo |
|
||||||
|
| Prioridad | Alta |
|
||||||
|
|
||||||
|
**Archivos clave:**
|
||||||
|
- `app.py` - API FastAPI
|
||||||
|
- `ingest.py` - Lógica de ingesta
|
||||||
|
- `Dockerfile` - Container
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### alfred
|
||||||
|
|
||||||
|
| Campo | Valor |
|
||||||
|
|-------|-------|
|
||||||
|
| URL | http://localhost:3000/tzzr/alfred |
|
||||||
|
| Estado | Activo |
|
||||||
|
| Descripción | Flujos predefinidos DECK |
|
||||||
|
| Prioridad | Media |
|
||||||
|
|
||||||
|
**Archivos clave:**
|
||||||
|
- `flows/` - Definiciones de flujos
|
||||||
|
- `executor.py` - Motor de ejecución
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### jared
|
||||||
|
|
||||||
|
| Campo | Valor |
|
||||||
|
|-------|-------|
|
||||||
|
| URL | http://localhost:3000/tzzr/jared |
|
||||||
|
| Estado | Activo |
|
||||||
|
| Descripción | Flujos predefinidos CORP |
|
||||||
|
| Prioridad | Media |
|
||||||
|
|
||||||
|
**Archivos clave:**
|
||||||
|
- `flows/` - Definiciones de flujos
|
||||||
|
- `executor.py` - Motor de ejecución
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Data Services
|
||||||
|
|
||||||
|
### mason
|
||||||
|
|
||||||
|
| Campo | Valor |
|
||||||
|
|-------|-------|
|
||||||
|
| URL | http://localhost:3000/tzzr/mason |
|
||||||
|
| Estado | Activo |
|
||||||
|
| Descripción | Enriquecimiento de datos |
|
||||||
|
| Prioridad | Alta |
|
||||||
|
|
||||||
|
**Archivos clave:**
|
||||||
|
- `workspace.py` - Gestión workspace
|
||||||
|
- `enrichment.py` - Lógica de enriquecimiento
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### feldman
|
||||||
|
|
||||||
|
| Campo | Valor |
|
||||||
|
|-------|-------|
|
||||||
|
| URL | http://localhost:3000/tzzr/feldman |
|
||||||
|
| Estado | Activo |
|
||||||
|
| Descripción | Consolidación blockchain |
|
||||||
|
| Prioridad | Alta |
|
||||||
|
|
||||||
|
**Archivos clave:**
|
||||||
|
- `validator.py` - Reglas M-001, M-002, M-003
|
||||||
|
- `consolidator.py` - Creación de bloques
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### grace-handler
|
||||||
|
|
||||||
|
| Campo | Valor |
|
||||||
|
|-------|-------|
|
||||||
|
| URL | http://localhost:3000/tzzr/grace-handler |
|
||||||
|
| Estado | Bloqueado (RunPod) |
|
||||||
|
| Descripción | Handler GPU para GRACE |
|
||||||
|
| Prioridad | Alta |
|
||||||
|
|
||||||
|
**Archivos clave:**
|
||||||
|
- `handler.py` - RunPod handler
|
||||||
|
- `modules/` - 6 módulos IA
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### penny-handler
|
||||||
|
|
||||||
|
| Campo | Valor |
|
||||||
|
|-------|-------|
|
||||||
|
| URL | http://localhost:3000/tzzr/penny-handler |
|
||||||
|
| Estado | Planificado |
|
||||||
|
| Descripción | Handler GPU para PENNY |
|
||||||
|
| Prioridad | Baja |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### factory-handler
|
||||||
|
|
||||||
|
| Campo | Valor |
|
||||||
|
|-------|-------|
|
||||||
|
| URL | http://localhost:3000/tzzr/factory-handler |
|
||||||
|
| Estado | Planificado |
|
||||||
|
| Descripción | Handler GPU para FACTORY |
|
||||||
|
| Prioridad | Baja |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### s-contract
|
||||||
|
|
||||||
|
| Campo | Valor |
|
||||||
|
|-------|-------|
|
||||||
|
| URL | http://localhost:3000/tzzr/s-contract |
|
||||||
|
| Estado | En desarrollo |
|
||||||
|
| Descripción | Contextos y datasets IA |
|
||||||
|
| Prioridad | Media |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Security/Ops
|
||||||
|
|
||||||
|
### sentinel
|
||||||
|
|
||||||
|
| Campo | Valor |
|
||||||
|
|-------|-------|
|
||||||
|
| URL | http://localhost:3000/tzzr/sentinel |
|
||||||
|
| Estado | Planificado |
|
||||||
|
| Descripción | Auditoría del sistema |
|
||||||
|
| Prioridad | Media |
|
||||||
|
|
||||||
|
**Modos:**
|
||||||
|
- LIGHT: Cada 5 min, reglas automáticas
|
||||||
|
- DEEP: Cada 1 hora, muestreo con LLM
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### infisical-config
|
||||||
|
|
||||||
|
| Campo | Valor |
|
||||||
|
|-------|-------|
|
||||||
|
| URL | http://localhost:3000/tzzr/infisical-config |
|
||||||
|
| Estado | Activo |
|
||||||
|
| Descripción | Configuración Infisical |
|
||||||
|
| Prioridad | Alta |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### backup-scripts
|
||||||
|
|
||||||
|
| Campo | Valor |
|
||||||
|
|-------|-------|
|
||||||
|
| URL | http://localhost:3000/tzzr/backup-scripts |
|
||||||
|
| Estado | En desarrollo |
|
||||||
|
| Descripción | Scripts de backup R2 |
|
||||||
|
| Prioridad | Alta |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### deploy-configs
|
||||||
|
|
||||||
|
| Campo | Valor |
|
||||||
|
|-------|-------|
|
||||||
|
| URL | http://localhost:3000/tzzr/deploy-configs |
|
||||||
|
| Estado | Activo |
|
||||||
|
| Descripción | Configuraciones de despliegue |
|
||||||
|
| Prioridad | Media |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### monitoring
|
||||||
|
|
||||||
|
| Campo | Valor |
|
||||||
|
|-------|-------|
|
||||||
|
| URL | http://localhost:3000/tzzr/monitoring |
|
||||||
|
| Estado | Planificado |
|
||||||
|
| Descripción | Dashboards y alertas |
|
||||||
|
| Prioridad | Media |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### security-audit
|
||||||
|
|
||||||
|
| Campo | Valor |
|
||||||
|
|-------|-------|
|
||||||
|
| URL | http://localhost:3000/tzzr/security-audit |
|
||||||
|
| Estado | En desarrollo |
|
||||||
|
| Descripción | Scripts de auditoría |
|
||||||
|
| Prioridad | Alta |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Interfaces
|
||||||
|
|
||||||
|
### packet-app
|
||||||
|
|
||||||
|
| Campo | Valor |
|
||||||
|
|-------|-------|
|
||||||
|
| URL | http://localhost:3000/tzzr/packet-app |
|
||||||
|
| Estado | En desarrollo |
|
||||||
|
| Descripción | App móvil Flutter |
|
||||||
|
| Prioridad | Alta |
|
||||||
|
|
||||||
|
**Tecnología:** Flutter/Dart
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### vision-builder
|
||||||
|
|
||||||
|
| Campo | Valor |
|
||||||
|
|-------|-------|
|
||||||
|
| URL | http://localhost:3000/tzzr/vision-builder |
|
||||||
|
| Estado | En desarrollo |
|
||||||
|
| Descripción | Diseñador de visiones |
|
||||||
|
| Prioridad | Media |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### admin-dashboard
|
||||||
|
|
||||||
|
| Campo | Valor |
|
||||||
|
|-------|-------|
|
||||||
|
| URL | http://localhost:3000/tzzr/admin-dashboard |
|
||||||
|
| Estado | Planificado |
|
||||||
|
| Descripción | Dashboard administrativo |
|
||||||
|
| Prioridad | Baja |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### api-gateway
|
||||||
|
|
||||||
|
| Campo | Valor |
|
||||||
|
|-------|-------|
|
||||||
|
| URL | http://localhost:3000/tzzr/api-gateway |
|
||||||
|
| Estado | Planificado |
|
||||||
|
| Descripción | Gateway API unificado |
|
||||||
|
| Prioridad | Media |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### docs-site
|
||||||
|
|
||||||
|
| Campo | Valor |
|
||||||
|
|-------|-------|
|
||||||
|
| URL | http://localhost:3000/tzzr/docs-site |
|
||||||
|
| Estado | En desarrollo |
|
||||||
|
| Descripción | Sitio de documentación |
|
||||||
|
| Prioridad | Media |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### system-docs
|
||||||
|
|
||||||
|
| Campo | Valor |
|
||||||
|
|-------|-------|
|
||||||
|
| URL | http://localhost:3000/tzzr/system-docs |
|
||||||
|
| Estado | Activo (este repo) |
|
||||||
|
| Descripción | Documentación System v5 |
|
||||||
|
| Prioridad | Alta |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Estadísticas
|
||||||
|
|
||||||
|
### Por Estado
|
||||||
|
|
||||||
|
| Estado | Cantidad |
|
||||||
|
|--------|----------|
|
||||||
|
| Activo | 12 |
|
||||||
|
| En desarrollo | 6 |
|
||||||
|
| Planificado | 5 |
|
||||||
|
| Bloqueado | 1 |
|
||||||
|
|
||||||
|
### Por Prioridad
|
||||||
|
|
||||||
|
| Prioridad | Cantidad |
|
||||||
|
|-----------|----------|
|
||||||
|
| Alta | 12 |
|
||||||
|
| Media | 8 |
|
||||||
|
| Baja | 4 |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Dependencias Entre Repos
|
||||||
|
|
||||||
|
```
|
||||||
|
packet-app
|
||||||
|
│
|
||||||
|
▼
|
||||||
|
clara / margaret
|
||||||
|
│
|
||||||
|
▼
|
||||||
|
alfred / jared
|
||||||
|
│
|
||||||
|
▼
|
||||||
|
mason ◄──── grace-handler (bloqueado)
|
||||||
|
│
|
||||||
|
▼
|
||||||
|
feldman
|
||||||
|
│
|
||||||
|
▼
|
||||||
|
sentinel (planificado)
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Notas
|
||||||
|
|
||||||
|
1. **grace-handler**: Código listo en R2, RunPod no inicia workers
|
||||||
|
2. **sentinel**: Solo documentación, sin implementación
|
||||||
|
3. **system-docs**: Este repositorio, documentación v5
|
||||||
|
4. **orchestrator**: Coordinador central en ARCHITECT
|
||||||
121
README.md
121
README.md
@@ -1,3 +1,120 @@
|
|||||||
# system-docs
|
# TZZR System Documentation v5
|
||||||
|
|
||||||
Documentación oficial del sistema TZZR - System v5
|
**Versión:** 5.0
|
||||||
|
**Fecha:** 2024-12-24
|
||||||
|
**Estado:** Consolidación completa
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Qué es TZZR
|
||||||
|
|
||||||
|
TZZR es un sistema de construcción de arquitecturas personales y empresariales mediante instancias Claude. Los agentes IA actúan como constructores que diseñan y edifican servidores clonables e independientes.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Arquitectura General
|
||||||
|
|
||||||
|
```
|
||||||
|
┌─────────────────────────────────────────────────────────────┐
|
||||||
|
│ ARCHITECT (69.62.126.110) │
|
||||||
|
│ PostgreSQL central │ Gitea │ Orchestrator │ Infisical │
|
||||||
|
└─────────────────────────────────────────────────────────────┘
|
||||||
|
│ │ │
|
||||||
|
▼ ▼ ▼
|
||||||
|
┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐
|
||||||
|
│ DECK │ │ CORP │ │ HST │
|
||||||
|
│ 72.62.1.113 │ │ 92.112.181.188 │ │ 72.62.2.84 │
|
||||||
|
│ │ │ │ │ │
|
||||||
|
│ CLARA, ALFRED │ │ MARGARET, JARED │ │ 973 tags │
|
||||||
|
│ Servidor │ │ MASON, FELDMAN │ │ API pública │
|
||||||
|
│ Personal │ │ Empresarial │ │ │
|
||||||
|
└─────────────────┘ └─────────────────┘ └─────────────────┘
|
||||||
|
│ │
|
||||||
|
└────────┬───────────┘
|
||||||
|
▼
|
||||||
|
┌─────────────────────────────────────────────────────────────┐
|
||||||
|
│ Cloudflare R2 (5 buckets) │
|
||||||
|
│ architect │ deck │ corp │ hst │ locker │
|
||||||
|
└─────────────────────────────────────────────────────────────┘
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Flujo de Datos Principal
|
||||||
|
|
||||||
|
```
|
||||||
|
PACKET (móvil)
|
||||||
|
↓
|
||||||
|
CLARA (DECK) / MARGARET (CORP) ← Ingesta inmutable
|
||||||
|
↓
|
||||||
|
ALFRED / JARED ← Flujos predefinidos
|
||||||
|
↓
|
||||||
|
MASON ← Enriquecimiento (24h)
|
||||||
|
↓
|
||||||
|
FELDMAN ← Consolidación blockchain
|
||||||
|
↓
|
||||||
|
SENTINEL ← Auditoría (planificado)
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Índice de Documentación
|
||||||
|
|
||||||
|
### 00_VISION
|
||||||
|
- [Filosofía](00_VISION/filosofia.md) - 10 principios fundacionales
|
||||||
|
- [Glosario](00_VISION/glosario.md) - Términos técnicos A-Z
|
||||||
|
|
||||||
|
### 01_ARQUITECTURA
|
||||||
|
- [Overview](01_ARQUITECTURA/overview.md) - Vista general consolidada
|
||||||
|
- [Servidores](01_ARQUITECTURA/servidores.md) - ARCHITECT, DECK, CORP, HST
|
||||||
|
|
||||||
|
### 02_MODELO_DATOS
|
||||||
|
- [Entidades](02_MODELO_DATOS/entidades.md) - HST, ITM, PLY, LOC, FLG
|
||||||
|
- [Planos](02_MODELO_DATOS/planos.md) - T0 (ITM), MST, BCK
|
||||||
|
|
||||||
|
### 03_COMPONENTES
|
||||||
|
- [CLARA/MARGARET](03_COMPONENTES/agentes/clara-margaret.md) - Ingesta
|
||||||
|
- [FELDMAN](03_COMPONENTES/agentes/feldman.md) - Consolidación
|
||||||
|
- [GRACE](03_COMPONENTES/servicios/grace.md) - IA cognitiva
|
||||||
|
|
||||||
|
### 04_SEGURIDAD
|
||||||
|
- [Modelo de Amenazas](04_SEGURIDAD/modelo-amenazas.md) - Riesgos
|
||||||
|
- [Secretos](04_SEGURIDAD/secretos.md) - Gestión credenciales
|
||||||
|
|
||||||
|
### 05_OPERACIONES
|
||||||
|
- [Infraestructura](05_OPERACIONES/infraestructura.md) - Servidores
|
||||||
|
- [Backup/Recovery](05_OPERACIONES/backup-recovery.md) - DR plan
|
||||||
|
|
||||||
|
### 06_INTEGRACIONES
|
||||||
|
- [GPU Services](06_INTEGRACIONES/gpu-services.md) - RunPod
|
||||||
|
|
||||||
|
### 99_ANEXOS
|
||||||
|
- [Inventario Repos](99_ANEXOS/inventario-repos.md) - 24 repos
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Estado Actual
|
||||||
|
|
||||||
|
| Componente | Estado | Notas |
|
||||||
|
|------------|--------|-------|
|
||||||
|
| CLARA | Operativo | DECK:5051 |
|
||||||
|
| MARGARET | Operativo | CORP:5051 |
|
||||||
|
| ALFRED | Operativo | DECK:5052 |
|
||||||
|
| JARED | Operativo | CORP:5052 |
|
||||||
|
| MASON | Operativo | CORP:5053 |
|
||||||
|
| FELDMAN | Operativo | CORP:5054 |
|
||||||
|
| HST | Operativo | 973 tags |
|
||||||
|
| SENTINEL | Planificado | Sin implementar |
|
||||||
|
| GRACE | Bloqueado | RunPod no inicia |
|
||||||
|
| NOTARIO | Planificado | Sin implementar |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Generación
|
||||||
|
|
||||||
|
Documentación generada mediante proceso de auditoría colaborativa:
|
||||||
|
- 3 auditores especializados (Arquitectura, Datos, Seguridad)
|
||||||
|
- Cross-review y resolución de conflictos
|
||||||
|
- Síntesis consolidada
|
||||||
|
|
||||||
|
**Fecha generación:** 2024-12-24
|
||||||
|
|||||||
@@ -1,130 +0,0 @@
|
|||||||
# ALFRED
|
|
||||||
|
|
||||||

|
|
||||||
|
|
||||||
**Flujos predefinidos lite - Sistema TZZR**
|
|
||||||
|
|
||||||
## Rol
|
|
||||||
|
|
||||||
Flujos predefinidos para DECK (servidor personal). Cadenas de pasos conocidos donde el usuario solo completa datos variables.
|
|
||||||
|
|
||||||
## Posicion en el Flujo
|
|
||||||
|
|
||||||
```
|
|
||||||
ALFRED
|
|
||||||
|
|
|
||||||
Salida esperada?
|
|
||||||
|
|
|
||||||
+------+------+
|
|
||||||
| |
|
|
||||||
SI NO
|
|
||||||
| (incidencia)
|
|
||||||
| |
|
|
||||||
| v
|
|
||||||
| MASON
|
|
||||||
| |
|
|
||||||
v v
|
|
||||||
FELDMAN
|
|
||||||
```
|
|
||||||
|
|
||||||
## Endpoints
|
|
||||||
|
|
||||||
| Metodo | Ruta | Descripcion |
|
|
||||||
|--------|------|-------------|
|
|
||||||
| GET | `/health` | Estado del servicio |
|
|
||||||
| GET | `/flujos` | Listar flujos predefinidos |
|
|
||||||
| POST | `/flujos` | Crear nuevo flujo |
|
|
||||||
| GET | `/flujos/<id>` | Detalle de un flujo |
|
|
||||||
| PUT | `/flujos/<id>` | Actualizar flujo |
|
|
||||||
| DELETE | `/flujos/<id>` | Desactivar flujo (soft delete) |
|
|
||||||
| POST | `/ejecutar/<id>` | Ejecutar un flujo |
|
|
||||||
| GET | `/ejecuciones` | Listar ejecuciones |
|
|
||||||
| GET | `/ejecuciones/<hash>` | Detalle de ejecucion |
|
|
||||||
| GET | `/stats` | Estadisticas |
|
|
||||||
|
|
||||||
## Autenticacion
|
|
||||||
|
|
||||||
Todas las rutas (excepto `/health`) requieren:
|
|
||||||
```
|
|
||||||
X-Auth-Key: {h_instancia}
|
|
||||||
```
|
|
||||||
|
|
||||||
## Crear un Flujo
|
|
||||||
|
|
||||||
```bash
|
|
||||||
curl -X POST http://localhost:5052/flujos \
|
|
||||||
-H "Content-Type: application/json" \
|
|
||||||
-H "X-Auth-Key: {h_instancia}" \
|
|
||||||
-d '{
|
|
||||||
"nombre": "Rutina Pecho",
|
|
||||||
"descripcion": "Entrenamiento de pecho - Martes",
|
|
||||||
"pasos": [
|
|
||||||
{"ejercicio": "Press banca", "series": 4},
|
|
||||||
{"ejercicio": "Press inclinado", "series": 3}
|
|
||||||
],
|
|
||||||
"campos_variables": ["kg", "reps", "notas"]
|
|
||||||
}'
|
|
||||||
```
|
|
||||||
|
|
||||||
## Ejecutar un Flujo
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Ejecucion OK -> destino FELDMAN
|
|
||||||
curl -X POST http://localhost:5052/ejecutar/{flujo_id} \
|
|
||||||
-H "Content-Type: application/json" \
|
|
||||||
-H "X-Auth-Key: {h_instancia}" \
|
|
||||||
-d '{
|
|
||||||
"datos": {"press_banca": {"kg": 80, "reps": 10}}
|
|
||||||
}'
|
|
||||||
|
|
||||||
# Ejecucion con incidencia -> destino MASON
|
|
||||||
curl -X POST http://localhost:5052/ejecutar/{flujo_id} \
|
|
||||||
-H "Content-Type: application/json" \
|
|
||||||
-H "X-Auth-Key: {h_instancia}" \
|
|
||||||
-d '{
|
|
||||||
"datos": {"press_banca": {"kg": 0, "reps": 0}},
|
|
||||||
"incidencia": true,
|
|
||||||
"notas": "Lesion en hombro"
|
|
||||||
}'
|
|
||||||
```
|
|
||||||
|
|
||||||
## Estados de Salida
|
|
||||||
|
|
||||||
| Estado | Descripcion | Destino |
|
|
||||||
|--------|-------------|---------|
|
|
||||||
| ok | Todo segun lo previsto | FELDMAN |
|
|
||||||
| incidencia | Algo no coincide | MASON |
|
|
||||||
|
|
||||||
## Despliegue
|
|
||||||
|
|
||||||
```bash
|
|
||||||
cd /opt/alfred
|
|
||||||
cp .env.example .env
|
|
||||||
# Editar .env con credenciales
|
|
||||||
docker compose up -d
|
|
||||||
```
|
|
||||||
|
|
||||||
## Configuracion
|
|
||||||
|
|
||||||
Ver `.env.example` para variables requeridas:
|
|
||||||
- `H_INSTANCIA`: Hash unico de DECK
|
|
||||||
- `DB_*`: Credenciales PostgreSQL
|
|
||||||
|
|
||||||
## Base de Datos
|
|
||||||
|
|
||||||
Ejecutar `init.sql` en PostgreSQL o las tablas se crean automaticamente:
|
|
||||||
- `flujos_predefinidos`: Definicion de flujos
|
|
||||||
- `flujo_ejecuciones`: Historial de ejecuciones
|
|
||||||
|
|
||||||
## Comparacion
|
|
||||||
|
|
||||||
| Componente | Servidor | Tipo | Destino si OK |
|
|
||||||
|------------|----------|------|---------------|
|
|
||||||
| CLARA | DECK | Input suelto | MASON |
|
|
||||||
| MARGARET | CORP | Input suelto | MASON |
|
|
||||||
| **ALFRED** | DECK | Flujo predefinido | FELDMAN (directo) |
|
|
||||||
| JARED | CORP | Flujo predefinido | FELDMAN (directo) |
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
*Componente del sistema TZZR - Implementado 2025-12-24*
|
|
||||||
@@ -1,79 +0,0 @@
|
|||||||
# Integración HST
|
|
||||||
|
|
||||||
## Arquitectura
|
|
||||||
|
|
||||||
```
|
|
||||||
HST (tzrtech.org)
|
|
||||||
Tags maestros + Imágenes
|
|
||||||
│
|
|
||||||
┌──────────┼──────────┐
|
|
||||||
▼ ▼ ▼
|
|
||||||
DECK CORP Otros
|
|
||||||
(mirrors) (mirrors) (futuro)
|
|
||||||
Sin imgs Sin imgs
|
|
||||||
```
|
|
||||||
|
|
||||||
## HST - Origen de verdad
|
|
||||||
|
|
||||||
| Tabla | Registros | Descripción |
|
|
||||||
|-------|-----------|-------------|
|
|
||||||
| hst | 658 | Tags principales |
|
|
||||||
| spe | 145 | Especies |
|
|
||||||
| flg | 65 | Flags |
|
|
||||||
| vsn | 84 | Vision |
|
|
||||||
| vue | 21 | Vue |
|
|
||||||
| **Total** | **973** | |
|
|
||||||
|
|
||||||
API: https://tzrtech.org/api/
|
|
||||||
|
|
||||||
## DECK (72.62.1.113)
|
|
||||||
|
|
||||||
**Tablas creadas:**
|
|
||||||
| Tabla | Registros | Descripción |
|
|
||||||
|-------|-----------|-------------|
|
|
||||||
| hst_mirror | 954 | Copia local de tags HST |
|
|
||||||
| hsu | 0 | Tags de usuario |
|
|
||||||
| spu | 0 | Especies de usuario |
|
|
||||||
| flu | 0 | Flags de usuario |
|
|
||||||
| vsu | 0 | Vision de usuario |
|
|
||||||
| vuu | 0 | Vue de usuario |
|
|
||||||
| pju | 0 | Proyectos de usuario |
|
|
||||||
|
|
||||||
## CORP (92.112.181.188)
|
|
||||||
|
|
||||||
Mismas 7 tablas que DECK.
|
|
||||||
- hst_mirror: 973 registros sincronizados
|
|
||||||
|
|
||||||
NocoDB: http://92.112.181.188:8080
|
|
||||||
- Email: admin@tzrtech.com
|
|
||||||
|
|
||||||
## Sync por grupo (CORP)
|
|
||||||
|
|
||||||
| Grupo | Cantidad |
|
|
||||||
|-------|----------|
|
|
||||||
| hst | 639 |
|
|
||||||
| spe | 145 |
|
|
||||||
| vsn | 84 |
|
|
||||||
| flg | 65 |
|
|
||||||
| vue | 21 |
|
|
||||||
|
|
||||||
## Pendiente
|
|
||||||
|
|
||||||
**DECK/CORP:**
|
|
||||||
- [ ] Webhook/polling para sync continuo con HST
|
|
||||||
- [ ] Lógica descarga imágenes cuando HST elimina tags
|
|
||||||
- [ ] API para usuarios
|
|
||||||
|
|
||||||
**HST:**
|
|
||||||
- [ ] Endpoint `/api/sync/changes`
|
|
||||||
- [ ] Sistema de webhooks
|
|
||||||
- [ ] Período de gracia para eliminación
|
|
||||||
|
|
||||||
## Flujo de eliminación
|
|
||||||
|
|
||||||
Cuando HST elimina un tag:
|
|
||||||
1. Descargar imagen de `hst_ruta`
|
|
||||||
2. Guardar en `/images/{ref}.png` local
|
|
||||||
3. Actualizar `local_ruta`, `local_subdominio`
|
|
||||||
4. Marcar `hst_activo = false`
|
|
||||||
5. Tag permanece en mirror (no se borra)
|
|
||||||
@@ -1,74 +0,0 @@
|
|||||||
# Infraestructura TZZR
|
|
||||||
|
|
||||||
Fecha actualización: 2025-12-19
|
|
||||||
|
|
||||||
## Servidores
|
|
||||||
|
|
||||||
| Servidor | IP | Hostname | Función |
|
|
||||||
|----------|-----|----------|---------|
|
|
||||||
| ARCHITECT | 69.62.126.110 | architect | Coordinación, servicios centrales |
|
|
||||||
| HST | 72.62.2.84 | hst | Tags maestros tzrtech.org |
|
|
||||||
| DECK | 72.62.1.113 | deck | Servidor personal deck.tzzr.net |
|
|
||||||
| CORP | 92.112.181.188 | corp | Empresas tzrtech.com |
|
|
||||||
|
|
||||||
## Servicios en ARCHITECT (69.62.126.110)
|
|
||||||
|
|
||||||
| Servicio | Puerto | URL | Función |
|
|
||||||
|----------|--------|-----|---------|
|
|
||||||
| Gitea | 3000 | https://git.tzzr.me | Repositorios Git |
|
|
||||||
| Infisical | 8082 | https://secrets.tzzr.me | Gestión de secretos |
|
|
||||||
| NocoDB | 8090 | https://tasks.tzzr.me | Base de datos / UI tareas |
|
|
||||||
| Windmill | 8100 | https://flows.tzzr.me | Workflows / automatización |
|
|
||||||
| PostgreSQL | 5432 | - | Base de datos |
|
|
||||||
|
|
||||||
## Claudes Activos
|
|
||||||
|
|
||||||
6 sesiones tmux en ARCHITECT:
|
|
||||||
- `architect` - Infra/ops
|
|
||||||
- `hst` - Tags HST
|
|
||||||
- `deck` - Servidor DECK
|
|
||||||
- `corp` - Servidor CORP
|
|
||||||
- `runpod` - GPU/ML
|
|
||||||
- `usuario` - Documentación
|
|
||||||
|
|
||||||
Comando para conectar:
|
|
||||||
```bash
|
|
||||||
ssh root@69.62.126.110
|
|
||||||
tmux attach -t <nombre>
|
|
||||||
```
|
|
||||||
|
|
||||||
## Infisical
|
|
||||||
|
|
||||||
URL: https://secrets.tzzr.me (pendiente SSL proxy)
|
|
||||||
|
|
||||||
**Projects:**
|
|
||||||
- anthropic - API key Anthropic
|
|
||||||
- servers - Credenciales servidores
|
|
||||||
- databases - Tokens BD, Gitea
|
|
||||||
- r2 - Cloudflare R2 storage
|
|
||||||
|
|
||||||
**Machine Identities:** anthropic, servers, databases, r2
|
|
||||||
|
|
||||||
## Cloudflare R2
|
|
||||||
|
|
||||||
Endpoint: `https://7dedae6030f5554d99d37e98a5232996.r2.cloudflarestorage.com`
|
|
||||||
|
|
||||||
Buckets: architect, hst, deck, corp, locker
|
|
||||||
|
|
||||||
Ver `R2_CONFIG.md` para credenciales.
|
|
||||||
|
|
||||||
## Windmill
|
|
||||||
|
|
||||||
URL: https://flows.tzzr.me
|
|
||||||
Login: windmill@tzr.systems
|
|
||||||
|
|
||||||
Para crear workflows de automatización.
|
|
||||||
|
|
||||||
## DNS (Cloudflare)
|
|
||||||
|
|
||||||
| Dominio | IP | Servicio |
|
|
||||||
|---------|-----|----------|
|
|
||||||
| git.tzzr.me | 69.62.126.110 | Gitea |
|
|
||||||
| secrets.tzzr.me | 69.62.126.110 | Infisical |
|
|
||||||
| tasks.tzzr.me | 69.62.126.110 | NocoDB |
|
|
||||||
| flows.tzzr.me | 69.62.126.110 | Windmill |
|
|
||||||
@@ -1,62 +0,0 @@
|
|||||||
# Cloudflare R2 - Configuración
|
|
||||||
|
|
||||||
**Endpoint:** `https://7dedae6030f5554d99d37e98a5232996.r2.cloudflarestorage.com`
|
|
||||||
|
|
||||||
## Tokens por Servidor
|
|
||||||
|
|
||||||
### DECK (72.62.1.113)
|
|
||||||
- **Bucket:** deck
|
|
||||||
- **Access Key ID:** `4556634df77cf74e0725aaf0f1b5bf3b`
|
|
||||||
- **Secret Access Key:** `71521dd5c1eafdf0e0557f6946f2a1ca06f054566130b98e88eff7078e539d22`
|
|
||||||
|
|
||||||
### CORP (92.112.181.188)
|
|
||||||
- **Bucket:** corp
|
|
||||||
- **Access Key ID:** `ed2d36f41e7e60057fb68b05984e35e0`
|
|
||||||
- **Secret Access Key:** `5d949fb3e7b913efaca22eedcfa06cb0507af61ced2158f15a4a67ccd08db067`
|
|
||||||
|
|
||||||
### HST (tzrtech.org)
|
|
||||||
- **Bucket:** hst
|
|
||||||
- **Access Key ID:** `580eef1be40618c9105b3285449eebdc`
|
|
||||||
- **Secret Access Key:** `c3324b37598e45da1c2b13438f9fd88b1ff6add9476a6f22566e0985f8a274bf`
|
|
||||||
|
|
||||||
### ARCHITECT (69.62.126.110)
|
|
||||||
- **Bucket:** architect
|
|
||||||
- **Access Key ID:** `e851e10b7b3b3407bb227fdc503e747c`
|
|
||||||
- **Secret Access Key:** `317c5d97b0a883a0dd65b74ff5ec7bd5e99edb5c621b810f13dea2a70aabd840`
|
|
||||||
|
|
||||||
### LOCKER (reserva)
|
|
||||||
- **Bucket:** locker
|
|
||||||
- **Access Key ID:** `15e1cf5f7da6da3939d66da1190633bb`
|
|
||||||
- **Secret Access Key:** `126cc7abe3fbd4da00ce1d68276a0a0651f47b748cf64e6f8b8604051683a0d8`
|
|
||||||
|
|
||||||
## Uso con AWS CLI
|
|
||||||
|
|
||||||
```bash
|
|
||||||
export AWS_ACCESS_KEY_ID="<access_key>"
|
|
||||||
export AWS_SECRET_ACCESS_KEY="<secret_key>"
|
|
||||||
export AWS_ENDPOINT_URL="https://7dedae6030f5554d99d37e98a5232996.r2.cloudflarestorage.com"
|
|
||||||
|
|
||||||
# Listar bucket
|
|
||||||
aws s3 ls s3://deck/
|
|
||||||
|
|
||||||
# Subir archivo
|
|
||||||
aws s3 cp archivo.txt s3://deck/
|
|
||||||
|
|
||||||
# Descargar archivo
|
|
||||||
aws s3 cp s3://deck/archivo.txt ./
|
|
||||||
```
|
|
||||||
|
|
||||||
## Uso con rclone
|
|
||||||
|
|
||||||
```ini
|
|
||||||
[r2-deck]
|
|
||||||
type = s3
|
|
||||||
provider = Cloudflare
|
|
||||||
access_key_id = <access_key>
|
|
||||||
secret_access_key = <secret_key>
|
|
||||||
endpoint = https://7dedae6030f5554d99d37e98a5232996.r2.cloudflarestorage.com
|
|
||||||
acl = private
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
*Generado: 2025-12-19*
|
|
||||||
@@ -1,49 +0,0 @@
|
|||||||
# Architect - TZZR
|
|
||||||
|
|
||||||
Coordinación equipo Claude y documentación de infraestructura.
|
|
||||||
|
|
||||||
## Protocolo de Instancias
|
|
||||||
|
|
||||||
### Local (manual)
|
|
||||||
Carpeta compartida en Proton Drive. Usuario actúa como router.
|
|
||||||
|
|
||||||
- [local/ARRANQUE.md](local/ARRANQUE.md) - Instrucciones de inicio
|
|
||||||
- [local/PROTOCOLO.md](local/PROTOCOLO.md) - Reglas de comunicación
|
|
||||||
- [local/ESTADO.md](local/ESTADO.md) - Estado global del sistema
|
|
||||||
- [local/COMANDOS_ARRANQUE.md](local/COMANDOS_ARRANQUE.md) - Comandos para Pablo
|
|
||||||
|
|
||||||
### Servidor (semi-automático)
|
|
||||||
PostgreSQL + ntfy. App Architect como hub.
|
|
||||||
|
|
||||||
## Documentación
|
|
||||||
|
|
||||||
- [INFRAESTRUCTURA.md](INFRAESTRUCTURA.md) - Servidores, servicios, DNS
|
|
||||||
- [HST_INTEGRACION.md](HST_INTEGRACION.md) - Integración sistema de tags
|
|
||||||
- [R2_CONFIG.md](R2_CONFIG.md) - Cloudflare R2 storage
|
|
||||||
|
|
||||||
## Servicios
|
|
||||||
|
|
||||||
| Servicio | URL |
|
|
||||||
|----------|-----|
|
|
||||||
| App Architect | https://tzzrarchitect.me |
|
|
||||||
| Gitea | http://69.62.126.110:3000 |
|
|
||||||
| Directus | http://69.62.126.110:8055 |
|
|
||||||
| Windmill | http://69.62.126.110:8100 |
|
|
||||||
| Infisical | http://69.62.126.110:8082 |
|
|
||||||
|
|
||||||
## Equipo Claude
|
|
||||||
|
|
||||||
6 instancias en servidor ARCHITECT (69.62.126.110):
|
|
||||||
|
|
||||||
| Instancia | Servidor | Dominio |
|
|
||||||
|-----------|----------|---------|
|
|
||||||
| architect | 69.62.126.110 | tzzrarchitect.me |
|
|
||||||
| hst | 72.62.2.84 | tzrtech.org |
|
|
||||||
| deck | 72.62.1.113 | tzzrdeck.me |
|
|
||||||
| corp | 92.112.181.188 | tzzrcorp.me |
|
|
||||||
| locker | Cloudflare R2 | - |
|
|
||||||
| runpod | RunPod Cloud | - |
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
*Actualizado: 2025-12-23*
|
|
||||||
@@ -1,207 +0,0 @@
|
|||||||
# CLARA - Deployment Guide
|
|
||||||
|
|
||||||
## Despliegue rápido con Docker Compose
|
|
||||||
|
|
||||||
### 1. Configuración
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Copiar archivo de ejemplo
|
|
||||||
cp .env.example .env
|
|
||||||
|
|
||||||
# Editar con tus credenciales
|
|
||||||
nano .env
|
|
||||||
```
|
|
||||||
|
|
||||||
### 2. Generar H_INSTANCIA
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Generar hash único para la instancia DECK
|
|
||||||
echo -n "deck-seed-$(date +%s)-$(hostname)" | sha256sum | cut -d' ' -f1
|
|
||||||
```
|
|
||||||
|
|
||||||
Copiar el resultado a `.env` como `H_INSTANCIA`.
|
|
||||||
|
|
||||||
### 3. Configurar credenciales R2
|
|
||||||
|
|
||||||
Obtener de Cloudflare R2:
|
|
||||||
- Account ID
|
|
||||||
- Access Key ID
|
|
||||||
- Secret Access Key
|
|
||||||
|
|
||||||
Actualizar en `.env`:
|
|
||||||
```
|
|
||||||
R2_ENDPOINT=https://<account-id>.r2.cloudflarestorage.com
|
|
||||||
R2_ACCESS_KEY=<access-key-id>
|
|
||||||
R2_SECRET_KEY=<secret-access-key>
|
|
||||||
```
|
|
||||||
|
|
||||||
### 4. Iniciar servicios
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Construir y levantar
|
|
||||||
docker-compose up -d
|
|
||||||
|
|
||||||
# Ver logs
|
|
||||||
docker-compose logs -f clara
|
|
||||||
|
|
||||||
# Verificar estado
|
|
||||||
curl http://localhost:5051/health
|
|
||||||
```
|
|
||||||
|
|
||||||
### 5. Verificar base de datos
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Conectar a PostgreSQL
|
|
||||||
docker exec -it clara-postgres psql -U postgres -d tzzr
|
|
||||||
|
|
||||||
# Ver tabla
|
|
||||||
\d clara_log
|
|
||||||
|
|
||||||
# Ver registros
|
|
||||||
SELECT * FROM clara_summary LIMIT 10;
|
|
||||||
```
|
|
||||||
|
|
||||||
## Endpoints API
|
|
||||||
|
|
||||||
### Health Check
|
|
||||||
```bash
|
|
||||||
curl http://localhost:5051/health
|
|
||||||
```
|
|
||||||
|
|
||||||
### Ingest (recibir contenedor)
|
|
||||||
```bash
|
|
||||||
curl -X POST http://localhost:5051/ingest \
|
|
||||||
-H "X-Auth-Key: $H_INSTANCIA" \
|
|
||||||
-H "Content-Type: application/json" \
|
|
||||||
-d '{
|
|
||||||
"id": "uuid-contenedor",
|
|
||||||
"archivo_hash": "sha256-archivo",
|
|
||||||
"origen": {
|
|
||||||
"dispositivo": "uuid-dispositivo",
|
|
||||||
"timestamp_captura": "2025-12-23T20:00:00Z"
|
|
||||||
},
|
|
||||||
"archivo": {
|
|
||||||
"tipo": "image/jpeg",
|
|
||||||
"categoria": "imagen"
|
|
||||||
}
|
|
||||||
}'
|
|
||||||
```
|
|
||||||
|
|
||||||
### Query (consultar por hash)
|
|
||||||
```bash
|
|
||||||
curl http://localhost:5051/query/sha256-archivo \
|
|
||||||
-H "X-Auth-Key: $H_INSTANCIA"
|
|
||||||
```
|
|
||||||
|
|
||||||
### List (listar contenedores)
|
|
||||||
```bash
|
|
||||||
curl "http://localhost:5051/list?limit=10&offset=0" \
|
|
||||||
-H "X-Auth-Key: $H_INSTANCIA"
|
|
||||||
```
|
|
||||||
|
|
||||||
## Despliegue en DECK (72.62.1.113)
|
|
||||||
|
|
||||||
### Opción 1: Docker Compose (Recomendado)
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# SSH al servidor
|
|
||||||
ssh root@72.62.1.113
|
|
||||||
|
|
||||||
# Clonar repositorio
|
|
||||||
git clone http://69.62.126.110:3000/tzzr/clara.git
|
|
||||||
cd clara
|
|
||||||
|
|
||||||
# Configurar
|
|
||||||
cp .env.example .env
|
|
||||||
nano .env
|
|
||||||
|
|
||||||
# Iniciar
|
|
||||||
docker-compose up -d
|
|
||||||
```
|
|
||||||
|
|
||||||
### Opción 2: Servicio systemd
|
|
||||||
|
|
||||||
Ver `clara.service` para configuración systemd.
|
|
||||||
|
|
||||||
## Nginx Reverse Proxy
|
|
||||||
|
|
||||||
```nginx
|
|
||||||
server {
|
|
||||||
listen 80;
|
|
||||||
server_name clara.tzzrdeck.me;
|
|
||||||
|
|
||||||
location / {
|
|
||||||
proxy_pass http://localhost:5051;
|
|
||||||
proxy_set_header Host $host;
|
|
||||||
proxy_set_header X-Real-IP $remote_addr;
|
|
||||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
|
||||||
proxy_set_header X-Forwarded-Proto $scheme;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
## Monitoreo
|
|
||||||
|
|
||||||
### Logs
|
|
||||||
```bash
|
|
||||||
# Docker Compose
|
|
||||||
docker-compose logs -f clara
|
|
||||||
|
|
||||||
# Si usa systemd
|
|
||||||
journalctl -u clara -f
|
|
||||||
```
|
|
||||||
|
|
||||||
### Métricas
|
|
||||||
```bash
|
|
||||||
# Número de contenedores
|
|
||||||
docker exec -it clara-postgres psql -U postgres -d tzzr -c "SELECT COUNT(*) FROM clara_log;"
|
|
||||||
|
|
||||||
# Último contenedor recibido
|
|
||||||
docker exec -it clara-postgres psql -U postgres -d tzzr -c "SELECT * FROM clara_summary ORDER BY id DESC LIMIT 1;"
|
|
||||||
```
|
|
||||||
|
|
||||||
## Backup
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Backup de PostgreSQL
|
|
||||||
docker exec clara-postgres pg_dump -U postgres tzzr > clara_backup_$(date +%Y%m%d).sql
|
|
||||||
|
|
||||||
# Restaurar
|
|
||||||
cat clara_backup_20251223.sql | docker exec -i clara-postgres psql -U postgres tzzr
|
|
||||||
```
|
|
||||||
|
|
||||||
## Troubleshooting
|
|
||||||
|
|
||||||
### Error: "unauthorized"
|
|
||||||
Verificar que `X-Auth-Key` en el request coincida con `H_INSTANCIA` en `.env`.
|
|
||||||
|
|
||||||
### Error: "r2_upload_failed"
|
|
||||||
Verificar credenciales de R2 y que el bucket existe.
|
|
||||||
|
|
||||||
### Error: "connection refused" al PostgreSQL
|
|
||||||
```bash
|
|
||||||
# Verificar que el contenedor está corriendo
|
|
||||||
docker ps | grep postgres
|
|
||||||
|
|
||||||
# Ver logs
|
|
||||||
docker logs clara-postgres
|
|
||||||
```
|
|
||||||
|
|
||||||
## Seguridad
|
|
||||||
|
|
||||||
1. **Firewall**: Solo exponer puerto 5051 a IPs confiables (PACKET)
|
|
||||||
2. **Auth**: Usar `H_INSTANCIA` largo y aleatorio
|
|
||||||
3. **HTTPS**: Usar reverse proxy con SSL (Let's Encrypt)
|
|
||||||
4. **Backup**: Configurar backups automáticos a R2
|
|
||||||
|
|
||||||
## Próximos pasos
|
|
||||||
|
|
||||||
Después de desplegar CLARA:
|
|
||||||
1. Configurar PACKET para enviar a `https://clara.tzzrdeck.me/ingest`
|
|
||||||
2. Implementar MASON para enriquecimiento
|
|
||||||
3. Implementar FELDMAN para consolidación
|
|
||||||
4. Configurar backups automáticos
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
*Actualizado: 2025-12-23*
|
|
||||||
@@ -1,225 +0,0 @@
|
|||||||
# Estado de Despliegue de CLARA
|
|
||||||
|
|
||||||
**Actualizado:** 2025-12-23
|
|
||||||
**Por:** ARCHITECT
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 📊 Estado General
|
|
||||||
|
|
||||||
| Componente | Estado | Notas |
|
|
||||||
|------------|--------|-------|
|
|
||||||
| Código | ✅ Completo | Implementación lista |
|
|
||||||
| Docker | ✅ Configurado | docker-compose.yml listo |
|
|
||||||
| Credenciales | ✅ Generadas | .env con credenciales seguras |
|
|
||||||
| Tests | ✅ Incluidos | test_clara.sh disponible |
|
|
||||||
| Documentación | ✅ Completa | Múltiples guías |
|
|
||||||
| Despliegue DECK | ⏳ Pendiente | SSH bloqueado |
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 🎯 Servidor Objetivo: DECK
|
|
||||||
|
|
||||||
**IP:** 72.62.1.113
|
|
||||||
**Hostname:** tzzrdeck.me
|
|
||||||
**Rol:** Servidor personal - Log de entrada
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 📦 Paquete de Despliegue
|
|
||||||
|
|
||||||
### Ubicación en ARCHITECT
|
|
||||||
```
|
|
||||||
/home/orchestrator/clara-deployment-deck.tar.gz (16 KB)
|
|
||||||
```
|
|
||||||
|
|
||||||
### Método de transferencia
|
|
||||||
- Servidor HTTP: `http://69.62.126.110:8888/clara-deployment-deck.tar.gz`
|
|
||||||
- SSH: Bloqueado (requiere configuración)
|
|
||||||
- Alternativa: Acceso físico/consola
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 🔑 Credenciales Generadas
|
|
||||||
|
|
||||||
### H_INSTANCIA (Auth Key para PACKET)
|
|
||||||
```
|
|
||||||
87f6bdbf490b82435e9e804c115570efd70d3ccb7d89a5ee1ff1dde142151165
|
|
||||||
```
|
|
||||||
|
|
||||||
### PostgreSQL
|
|
||||||
- Usuario: `postgres`
|
|
||||||
- Password: `PGFRKChQrx3R27eImwRgg57syX2yWd7s+/VwCH2CQuo=`
|
|
||||||
- Base de datos: `tzzr`
|
|
||||||
|
|
||||||
### Cloudflare R2
|
|
||||||
- Endpoint: `https://7dedae6030f5554d99d37e98a5232996.r2.cloudflarestorage.com`
|
|
||||||
- Bucket: `deck`
|
|
||||||
- Access Key: `55125dca442b0f3517d194a5bc0502b8`
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 🚀 Instrucciones de Instalación
|
|
||||||
|
|
||||||
### En DECK, ejecutar:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# 1. Descargar paquete
|
|
||||||
wget http://69.62.126.110:8888/clara-deployment-deck.tar.gz
|
|
||||||
|
|
||||||
# 2. Descomprimir
|
|
||||||
tar xzf clara-deployment-deck.tar.gz
|
|
||||||
cd clara-deployment
|
|
||||||
|
|
||||||
# 3. Instalar automáticamente
|
|
||||||
sudo ./install-deck.sh
|
|
||||||
```
|
|
||||||
|
|
||||||
El script realiza:
|
|
||||||
- Verificación de dependencias
|
|
||||||
- Instalación en `/opt/clara`
|
|
||||||
- Configuración de PostgreSQL
|
|
||||||
- Inicio de servicios Docker
|
|
||||||
- Tests de verificación
|
|
||||||
- Creación de scripts de backup
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## ✅ Verificación Post-Instalación
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Health check
|
|
||||||
curl http://localhost:5051/health
|
|
||||||
|
|
||||||
# Test de ingesta
|
|
||||||
curl -X POST http://localhost:5051/ingest \
|
|
||||||
-H "X-Auth-Key: 87f6bdbf490b82435e9e804c115570efd70d3ccb7d89a5ee1ff1dde142151165" \
|
|
||||||
-H "Content-Type: application/json" \
|
|
||||||
-d '{"id":"test-001","archivo_hash":"test-hash-001","origen":{"dispositivo":"test","timestamp_captura":"2025-12-23T20:00:00Z"},"archivo":{"tipo":"image/jpeg","categoria":"imagen"}}'
|
|
||||||
|
|
||||||
# Listar contenedores
|
|
||||||
curl http://localhost:5051/list \
|
|
||||||
-H "X-Auth-Key: 87f6bdbf490b82435e9e804c115570efd70d3ccb7d89a5ee1ff1dde142151165"
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 📱 Configuración de PACKET
|
|
||||||
|
|
||||||
Después del despliegue, configurar en PACKET:
|
|
||||||
|
|
||||||
**URL:**
|
|
||||||
```
|
|
||||||
http://72.62.1.113:5051/ingest
|
|
||||||
```
|
|
||||||
|
|
||||||
**Header:**
|
|
||||||
```
|
|
||||||
X-Auth-Key: 87f6bdbf490b82435e9e804c115570efd70d3ccb7d89a5ee1ff1dde142151165
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 📋 Pendientes
|
|
||||||
|
|
||||||
### Pre-despliegue
|
|
||||||
- [ ] Configurar SSH en DECK (puerto 22 bloqueado actualmente)
|
|
||||||
- [ ] O alternativamente: acceder por consola/físicamente
|
|
||||||
|
|
||||||
### Durante despliegue
|
|
||||||
- [ ] Transferir paquete a DECK
|
|
||||||
- [ ] Ejecutar `install-deck.sh`
|
|
||||||
- [ ] Verificar health check
|
|
||||||
- [ ] Ejecutar suite de tests
|
|
||||||
|
|
||||||
### Post-despliegue
|
|
||||||
- [ ] Configurar Nginx (opcional)
|
|
||||||
- [ ] Configurar SSL con Let's Encrypt (opcional)
|
|
||||||
- [ ] Configurar firewall
|
|
||||||
- [ ] Configurar backups automáticos
|
|
||||||
- [ ] Configurar PACKET
|
|
||||||
- [ ] Test end-to-end desde PACKET
|
|
||||||
- [ ] Monitoreo y alertas
|
|
||||||
|
|
||||||
### Desarrollo futuro
|
|
||||||
- [ ] Implementar MASON (enriquecimiento)
|
|
||||||
- [ ] Implementar FELDMAN (consolidación)
|
|
||||||
- [ ] Dashboard de visualización
|
|
||||||
- [ ] Integración con MARGARET (CORP)
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 📁 Archivos Relacionados
|
|
||||||
|
|
||||||
### En ARCHITECT
|
|
||||||
- `/home/orchestrator/clara-deployment/` - Directorio de despliegue
|
|
||||||
- `/home/orchestrator/clara-deployment-deck.tar.gz` - Paquete comprimido
|
|
||||||
- `/home/orchestrator/INSTRUCCIONES_DESPLIEGUE_CLARA.md` - Guía rápida
|
|
||||||
- `/home/orchestrator/CLARA_DEPLOYMENT_SUMMARY.md` - Resumen detallado
|
|
||||||
|
|
||||||
### En el paquete
|
|
||||||
- `install-deck.sh` - Script de instalación automática
|
|
||||||
- `DEPLOY_TO_DECK.md` - Guía completa de despliegue
|
|
||||||
- `.env` - Credenciales configuradas
|
|
||||||
- `docker-compose.yml` - Orquestación
|
|
||||||
- `app.py` - Servicio CLARA
|
|
||||||
- `init.sql` - Schema PostgreSQL
|
|
||||||
- `test_clara.sh` - Suite de tests
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 🔒 Seguridad
|
|
||||||
|
|
||||||
- ✅ Auth Key de 64 caracteres (SHA-256)
|
|
||||||
- ✅ Password de PostgreSQL aleatorio y seguro
|
|
||||||
- ✅ Credenciales R2 configuradas
|
|
||||||
- ⚠️ Se recomienda SSL para producción
|
|
||||||
- ⚠️ Configurar firewall para limitar acceso
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 📊 Servicios Desplegados
|
|
||||||
|
|
||||||
```
|
|
||||||
┌─────────────────────────────────┐
|
|
||||||
│ CLARA Service │
|
|
||||||
│ - Puerto: 5051 │
|
|
||||||
│ - Endpoints: │
|
|
||||||
│ * POST /ingest │
|
|
||||||
│ * GET /health │
|
|
||||||
│ * GET /query/{hash} │
|
|
||||||
│ * GET /list │
|
|
||||||
└────────────┬────────────────────┘
|
|
||||||
│
|
|
||||||
┌────────────▼────────────────────┐
|
|
||||||
│ PostgreSQL │
|
|
||||||
│ - Puerto: 5433 (externo) │
|
|
||||||
│ - Puerto: 5432 (interno) │
|
|
||||||
│ - Tabla: clara_log (JSONB) │
|
|
||||||
└─────────────────────────────────┘
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 🔄 Historial de Cambios
|
|
||||||
|
|
||||||
### 2025-12-23
|
|
||||||
- ✅ Implementación completa del código
|
|
||||||
- ✅ Generación de credenciales
|
|
||||||
- ✅ Creación de paquete de despliegue
|
|
||||||
- ✅ Script de instalación automática
|
|
||||||
- ✅ Documentación completa
|
|
||||||
- ✅ Servidor HTTP para transferencia
|
|
||||||
- ⏳ Pendiente: Transferencia a DECK
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 📞 Soporte
|
|
||||||
|
|
||||||
**ARCHITECT**
|
|
||||||
- Servidor: 69.62.126.110
|
|
||||||
- Gitea: https://git.tzzr.me/tzzr/clara
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
*Documento de estado - Sistema TZZR*
|
|
||||||
@@ -1,383 +0,0 @@
|
|||||||
# Despliegue de CLARA en DECK
|
|
||||||
|
|
||||||
**Servidor:** DECK (72.62.1.113 / tzzrdeck.me)
|
|
||||||
**Fecha:** 2025-12-23
|
|
||||||
**Preparado por:** ARCHITECT
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 📋 Pre-requisitos
|
|
||||||
|
|
||||||
### En el servidor DECK debe estar instalado:
|
|
||||||
- Docker (versión 20.10 o superior)
|
|
||||||
- Docker Compose (versión 2.0 o superior)
|
|
||||||
- Acceso a internet para pull de imágenes
|
|
||||||
|
|
||||||
### Verificar:
|
|
||||||
```bash
|
|
||||||
docker --version
|
|
||||||
docker-compose --version
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 📦 Paso 1: Transferir archivos
|
|
||||||
|
|
||||||
### Opción A: Clonar desde Gitea (cuando esté disponible)
|
|
||||||
```bash
|
|
||||||
ssh root@72.62.1.113
|
|
||||||
cd /opt
|
|
||||||
git clone https://git.tzzr.me/tzzr/clara.git
|
|
||||||
cd clara
|
|
||||||
```
|
|
||||||
|
|
||||||
### Opción B: Transferir paquete manualmente
|
|
||||||
```bash
|
|
||||||
# Desde ARCHITECT (69.62.126.110)
|
|
||||||
cd /home/orchestrator
|
|
||||||
tar czf clara-deployment.tar.gz clara-deployment/
|
|
||||||
|
|
||||||
# Transferir a DECK
|
|
||||||
scp clara-deployment.tar.gz root@72.62.1.113:/opt/
|
|
||||||
|
|
||||||
# En DECK
|
|
||||||
ssh root@72.62.1.113
|
|
||||||
cd /opt
|
|
||||||
tar xzf clara-deployment.tar.gz
|
|
||||||
mv clara-deployment clara
|
|
||||||
cd clara
|
|
||||||
```
|
|
||||||
|
|
||||||
### Opción C: Via HTTP (si SSH no está disponible)
|
|
||||||
```bash
|
|
||||||
# En ARCHITECT - crear servidor temporal
|
|
||||||
cd /home/orchestrator
|
|
||||||
python3 -m http.server 8888
|
|
||||||
|
|
||||||
# En DECK - descargar
|
|
||||||
wget http://69.62.126.110:8888/clara-deployment.tar.gz
|
|
||||||
tar xzf clara-deployment.tar.gz
|
|
||||||
mv clara-deployment /opt/clara
|
|
||||||
cd /opt/clara
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## ⚙️ Paso 2: Configurar credenciales
|
|
||||||
|
|
||||||
El archivo `.env` ya está configurado con las siguientes credenciales:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Ver configuración actual
|
|
||||||
cat .env
|
|
||||||
```
|
|
||||||
|
|
||||||
### Credenciales configuradas:
|
|
||||||
|
|
||||||
- **H_INSTANCIA:** `87f6bdbf490b82435e9e804c115570efd70d3ccb7d89a5ee1ff1dde142151165`
|
|
||||||
- **DB_PASSWORD:** `PGFRKChQrx3R27eImwRgg57syX2yWd7s+/VwCH2CQuo=`
|
|
||||||
- **R2 Endpoint:** Cloudflare R2 configurado
|
|
||||||
- **R2 Bucket:** `deck`
|
|
||||||
|
|
||||||
> ⚠️ **IMPORTANTE:** Guarda `H_INSTANCIA` en un lugar seguro. Este hash se usará para autenticación desde PACKET.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 🚀 Paso 3: Iniciar servicios
|
|
||||||
|
|
||||||
```bash
|
|
||||||
cd /opt/clara
|
|
||||||
|
|
||||||
# Construir y levantar contenedores
|
|
||||||
docker-compose up -d
|
|
||||||
|
|
||||||
# Ver logs en tiempo real
|
|
||||||
docker-compose logs -f clara
|
|
||||||
|
|
||||||
# Verificar que los contenedores están corriendo
|
|
||||||
docker-compose ps
|
|
||||||
```
|
|
||||||
|
|
||||||
Deberías ver:
|
|
||||||
```
|
|
||||||
NAME STATUS PORTS
|
|
||||||
clara-service Up X minutes 0.0.0.0:5051->5051/tcp
|
|
||||||
clara-postgres Up X minutes 0.0.0.0:5433->5432/tcp
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## ✅ Paso 4: Verificar instalación
|
|
||||||
|
|
||||||
### Test 1: Health Check
|
|
||||||
```bash
|
|
||||||
curl http://localhost:5051/health
|
|
||||||
```
|
|
||||||
|
|
||||||
**Respuesta esperada:**
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"service": "clara",
|
|
||||||
"status": "ok",
|
|
||||||
"timestamp": "2025-12-23T20:XX:XX"
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
### Test 2: Verificar PostgreSQL
|
|
||||||
```bash
|
|
||||||
docker exec -it clara-postgres psql -U postgres -d tzzr -c "\dt"
|
|
||||||
```
|
|
||||||
|
|
||||||
**Deberías ver la tabla:** `clara_log`
|
|
||||||
|
|
||||||
### Test 3: Test completo
|
|
||||||
```bash
|
|
||||||
chmod +x test_clara.sh
|
|
||||||
./test_clara.sh
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 🌐 Paso 5: Configurar acceso externo (Opcional)
|
|
||||||
|
|
||||||
### Opción A: Nginx Reverse Proxy
|
|
||||||
|
|
||||||
Crear `/etc/nginx/sites-available/clara`:
|
|
||||||
|
|
||||||
```nginx
|
|
||||||
server {
|
|
||||||
listen 80;
|
|
||||||
server_name clara.tzzrdeck.me;
|
|
||||||
|
|
||||||
location / {
|
|
||||||
proxy_pass http://localhost:5051;
|
|
||||||
proxy_set_header Host $host;
|
|
||||||
proxy_set_header X-Real-IP $remote_addr;
|
|
||||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
|
||||||
proxy_set_header X-Forwarded-Proto $scheme;
|
|
||||||
|
|
||||||
# Para archivos grandes
|
|
||||||
client_max_body_size 100M;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
Activar:
|
|
||||||
```bash
|
|
||||||
ln -s /etc/nginx/sites-available/clara /etc/nginx/sites-enabled/
|
|
||||||
nginx -t
|
|
||||||
systemctl reload nginx
|
|
||||||
```
|
|
||||||
|
|
||||||
### Opción B: SSL con Let's Encrypt
|
|
||||||
```bash
|
|
||||||
certbot --nginx -d clara.tzzrdeck.me
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 🔒 Paso 6: Firewall
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Permitir puerto 5051 (o 80/443 si usas Nginx)
|
|
||||||
ufw allow 5051/tcp
|
|
||||||
ufw reload
|
|
||||||
|
|
||||||
# O si usas Nginx con SSL
|
|
||||||
ufw allow 'Nginx Full'
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 📱 Paso 7: Configurar PACKET
|
|
||||||
|
|
||||||
En la app PACKET, configurar:
|
|
||||||
|
|
||||||
**URL de CLARA:**
|
|
||||||
```
|
|
||||||
https://clara.tzzrdeck.me/ingest
|
|
||||||
# O si no tienes Nginx:
|
|
||||||
http://72.62.1.113:5051/ingest
|
|
||||||
```
|
|
||||||
|
|
||||||
**Autenticación (Header):**
|
|
||||||
```
|
|
||||||
X-Auth-Key: 87f6bdbf490b82435e9e804c115570efd70d3ccb7d89a5ee1ff1dde142151165
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 🧪 Paso 8: Test desde PACKET
|
|
||||||
|
|
||||||
Simular envío desde PACKET:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
curl -X POST http://localhost:5051/ingest \
|
|
||||||
-H "X-Auth-Key: 87f6bdbf490b82435e9e804c115570efd70d3ccb7d89a5ee1ff1dde142151165" \
|
|
||||||
-H "Content-Type: application/json" \
|
|
||||||
-d '{
|
|
||||||
"id": "test-uuid-001",
|
|
||||||
"archivo_hash": "abc123test",
|
|
||||||
"origen": {
|
|
||||||
"dispositivo": "test-device",
|
|
||||||
"timestamp_captura": "2025-12-23T20:00:00Z"
|
|
||||||
},
|
|
||||||
"archivo": {
|
|
||||||
"tipo": "image/jpeg",
|
|
||||||
"categoria": "imagen"
|
|
||||||
}
|
|
||||||
}'
|
|
||||||
```
|
|
||||||
|
|
||||||
**Respuesta esperada:**
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"ok": true,
|
|
||||||
"id": 1,
|
|
||||||
"h_entrada": "abc123test"
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
Verificar:
|
|
||||||
```bash
|
|
||||||
curl http://localhost:5051/list \
|
|
||||||
-H "X-Auth-Key: 87f6bdbf490b82435e9e804c115570efd70d3ccb7d89a5ee1ff1dde142151165"
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 📊 Monitoreo
|
|
||||||
|
|
||||||
### Ver logs
|
|
||||||
```bash
|
|
||||||
docker-compose logs -f clara
|
|
||||||
docker-compose logs -f postgres
|
|
||||||
```
|
|
||||||
|
|
||||||
### Estadísticas
|
|
||||||
```bash
|
|
||||||
# Número de contenedores recibidos
|
|
||||||
docker exec -it clara-postgres psql -U postgres -d tzzr -c \
|
|
||||||
"SELECT COUNT(*) FROM clara_log;"
|
|
||||||
|
|
||||||
# Últimos 5 contenedores
|
|
||||||
docker exec -it clara-postgres psql -U postgres -d tzzr -c \
|
|
||||||
"SELECT id, h_entrada, created_at FROM clara_log ORDER BY id DESC LIMIT 5;"
|
|
||||||
```
|
|
||||||
|
|
||||||
### Estado de contenedores
|
|
||||||
```bash
|
|
||||||
docker-compose ps
|
|
||||||
docker stats --no-stream
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 💾 Backup
|
|
||||||
|
|
||||||
### Backup manual
|
|
||||||
```bash
|
|
||||||
# PostgreSQL
|
|
||||||
docker exec clara-postgres pg_dump -U postgres tzzr > \
|
|
||||||
/opt/clara/backups/clara_$(date +%Y%m%d_%H%M%S).sql
|
|
||||||
|
|
||||||
# Archivos de configuración
|
|
||||||
tar czf /opt/clara/backups/clara_config_$(date +%Y%m%d).tar.gz \
|
|
||||||
/opt/clara/.env /opt/clara/docker-compose.yml
|
|
||||||
```
|
|
||||||
|
|
||||||
### Backup automático (cron)
|
|
||||||
```bash
|
|
||||||
# Editar crontab
|
|
||||||
crontab -e
|
|
||||||
|
|
||||||
# Añadir (backup diario a las 3 AM)
|
|
||||||
0 3 * * * docker exec clara-postgres pg_dump -U postgres tzzr > /opt/clara/backups/clara_$(date +\%Y\%m\%d).sql
|
|
||||||
|
|
||||||
# Backup semanal a R2 (domingos a las 4 AM)
|
|
||||||
0 4 * * 0 /opt/clara/backup_to_r2.sh
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 🔧 Troubleshooting
|
|
||||||
|
|
||||||
### Error: "unauthorized"
|
|
||||||
Verificar que el header `X-Auth-Key` coincide con `H_INSTANCIA` en `.env`.
|
|
||||||
|
|
||||||
### Error: "connection refused" a PostgreSQL
|
|
||||||
```bash
|
|
||||||
docker logs clara-postgres
|
|
||||||
docker-compose restart postgres
|
|
||||||
```
|
|
||||||
|
|
||||||
### Error: "r2_upload_failed"
|
|
||||||
Verificar credenciales R2 en `.env` y que el bucket `deck` existe.
|
|
||||||
|
|
||||||
### Reiniciar servicios
|
|
||||||
```bash
|
|
||||||
docker-compose restart clara
|
|
||||||
docker-compose restart postgres
|
|
||||||
```
|
|
||||||
|
|
||||||
### Reconstruir desde cero
|
|
||||||
```bash
|
|
||||||
docker-compose down -v
|
|
||||||
docker-compose up -d --build
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 📝 Mantenimiento
|
|
||||||
|
|
||||||
### Actualizar CLARA
|
|
||||||
```bash
|
|
||||||
cd /opt/clara
|
|
||||||
git pull # Si está en Gitea
|
|
||||||
docker-compose down
|
|
||||||
docker-compose build --no-cache
|
|
||||||
docker-compose up -d
|
|
||||||
```
|
|
||||||
|
|
||||||
### Limpiar logs antiguos
|
|
||||||
```bash
|
|
||||||
docker system prune -a
|
|
||||||
journalctl --vacuum-time=30d
|
|
||||||
```
|
|
||||||
|
|
||||||
### Rotar logs de PostgreSQL
|
|
||||||
```bash
|
|
||||||
docker exec -it clara-postgres psql -U postgres -d tzzr -c \
|
|
||||||
"DELETE FROM clara_log WHERE created_at < NOW() - INTERVAL '1 year';"
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 📞 Soporte
|
|
||||||
|
|
||||||
- **Logs:** `/opt/clara/docker-compose.yml`
|
|
||||||
- **Config:** `/opt/clara/.env`
|
|
||||||
- **Documentación:** https://git.tzzr.me/tzzr/clara
|
|
||||||
- **Contacto:** ARCHITECT
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## ✅ Checklist de despliegue
|
|
||||||
|
|
||||||
- [ ] Archivos transferidos a `/opt/clara`
|
|
||||||
- [ ] `.env` configurado correctamente
|
|
||||||
- [ ] Docker Compose up y corriendo
|
|
||||||
- [ ] Health check responde OK
|
|
||||||
- [ ] PostgreSQL creó tabla `clara_log`
|
|
||||||
- [ ] Test de ingesta exitoso
|
|
||||||
- [ ] Nginx configurado (opcional)
|
|
||||||
- [ ] SSL configurado (opcional)
|
|
||||||
- [ ] Firewall configurado
|
|
||||||
- [ ] PACKET configurado con URL y Auth-Key
|
|
||||||
- [ ] Backup automático configurado
|
|
||||||
- [ ] Monitoreo activo
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
**Generado:** 2025-12-23
|
|
||||||
**ARCHITECT** - Sistema TZZR
|
|
||||||
@@ -1,335 +0,0 @@
|
|||||||
# CLARA - Reporte de Implementación
|
|
||||||
|
|
||||||
**Fecha**: 2025-12-23
|
|
||||||
**Agente**: ARCHITECT
|
|
||||||
**Estado**: ✅ Implementación completa - Pendiente despliegue
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Resumen ejecutivo
|
|
||||||
|
|
||||||
Se ha implementado el servicio **CLARA**, el log inmutable de entrada para el servidor DECK que recibe contenedores de datos de la aplicación móvil PACKET.
|
|
||||||
|
|
||||||
### Objetivos alcanzados
|
|
||||||
|
|
||||||
✅ Servicio API REST completo con Flask
|
|
||||||
✅ Integración con PostgreSQL para persistencia
|
|
||||||
✅ Integración con Cloudflare R2 para storage
|
|
||||||
✅ Autenticación mediante `h_instancia`
|
|
||||||
✅ Endpoints documentados y funcionales
|
|
||||||
✅ Contenedorización con Docker
|
|
||||||
✅ Suite de tests automatizados
|
|
||||||
✅ Documentación completa de deployment
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Arquitectura implementada
|
|
||||||
|
|
||||||
### Stack tecnológico
|
|
||||||
|
|
||||||
```
|
|
||||||
┌─────────────────────────────────────────┐
|
|
||||||
│ PACKET (App móvil) │
|
|
||||||
└──────────────┬──────────────────────────┘
|
|
||||||
│ POST /ingest
|
|
||||||
│ X-Auth-Key: {h_instancia}
|
|
||||||
▼
|
|
||||||
┌─────────────────────────────────────────┐
|
|
||||||
│ CLARA Service (Flask) │
|
|
||||||
│ - Autenticación │
|
|
||||||
│ - Validación de contenedores │
|
|
||||||
│ - Detección de duplicados │
|
|
||||||
└──────────┬─────────────┬────────────────┘
|
|
||||||
│ │
|
|
||||||
▼ ▼
|
|
||||||
┌──────────┐ ┌────────────────┐
|
|
||||||
│PostgreSQL│ │ Cloudflare R2 │
|
|
||||||
│ JSONB │ │ (Storage) │
|
|
||||||
└──────────┘ └────────────────┘
|
|
||||||
```
|
|
||||||
|
|
||||||
### Componentes
|
|
||||||
|
|
||||||
1. **app.py** (375 líneas)
|
|
||||||
- Flask application
|
|
||||||
- 4 endpoints: `/health`, `/ingest`, `/query`, `/list`
|
|
||||||
- Autenticación via headers
|
|
||||||
- Manejo de errores robusto
|
|
||||||
|
|
||||||
2. **PostgreSQL Schema** (init.sql)
|
|
||||||
- Tabla `clara_log` con JSONB
|
|
||||||
- 6 índices optimizados
|
|
||||||
- Vista `clara_summary` para consultas
|
|
||||||
- Comentarios de documentación
|
|
||||||
|
|
||||||
3. **Docker Setup**
|
|
||||||
- Dockerfile multi-stage
|
|
||||||
- docker-compose.yml con 2 servicios
|
|
||||||
- Health checks configurados
|
|
||||||
- Volúmenes persistentes
|
|
||||||
|
|
||||||
4. **Testing** (test_clara.sh)
|
|
||||||
- 6 tests automatizados
|
|
||||||
- Verificación de autenticación
|
|
||||||
- Pruebas de duplicados
|
|
||||||
- Validación de endpoints
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Endpoints API
|
|
||||||
|
|
||||||
### 1. Health Check
|
|
||||||
```http
|
|
||||||
GET /health
|
|
||||||
Response: {"service": "clara", "status": "ok", "timestamp": "..."}
|
|
||||||
```
|
|
||||||
|
|
||||||
### 2. Ingest (recepción de contenedores)
|
|
||||||
```http
|
|
||||||
POST /ingest
|
|
||||||
Headers:
|
|
||||||
X-Auth-Key: {h_instancia}
|
|
||||||
Content-Type: application/json
|
|
||||||
Body: {contenedor según schema}
|
|
||||||
Responses:
|
|
||||||
200: {"ok": true, "id": 1001, "h_entrada": "sha256..."}
|
|
||||||
401: {"error": "unauthorized"}
|
|
||||||
409: {"error": "hash_exists"}
|
|
||||||
400: {"error": "missing_id|missing_archivo_hash"}
|
|
||||||
500: {"error": "r2_upload_failed|internal_error"}
|
|
||||||
```
|
|
||||||
|
|
||||||
### 3. Query (consultar contenedor)
|
|
||||||
```http
|
|
||||||
GET /query/{h_entrada}
|
|
||||||
Headers:
|
|
||||||
X-Auth-Key: {h_instancia}
|
|
||||||
Responses:
|
|
||||||
200: {contenedor completo + metadata}
|
|
||||||
401: {"error": "unauthorized"}
|
|
||||||
404: {"error": "not_found"}
|
|
||||||
```
|
|
||||||
|
|
||||||
### 4. List (listar contenedores)
|
|
||||||
```http
|
|
||||||
GET /list?limit=50&offset=0
|
|
||||||
Headers:
|
|
||||||
X-Auth-Key: {h_instancia}
|
|
||||||
Response:
|
|
||||||
200: {
|
|
||||||
"total": 100,
|
|
||||||
"limit": 50,
|
|
||||||
"offset": 0,
|
|
||||||
"entries": [...]
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Base de datos
|
|
||||||
|
|
||||||
### Tabla clara_log
|
|
||||||
|
|
||||||
| Campo | Tipo | Descripción |
|
|
||||||
|-------|------|-------------|
|
|
||||||
| id | BIGSERIAL | ID autoincremental |
|
|
||||||
| h_instancia | VARCHAR(64) | Hash de la instancia DECK |
|
|
||||||
| h_entrada | VARCHAR(64) | SHA-256 del archivo (único) |
|
|
||||||
| contenedor | JSONB | Contenedor completo |
|
|
||||||
| r2_paths | JSONB | Rutas de archivos en R2 |
|
|
||||||
| created_at | TIMESTAMP | Fecha de recepción (inmutable) |
|
|
||||||
|
|
||||||
### Índices
|
|
||||||
|
|
||||||
1. `idx_clara_instancia` - Búsqueda por instancia
|
|
||||||
2. `idx_clara_entrada` - Búsqueda por hash de archivo
|
|
||||||
3. `idx_clara_created` - Ordenación cronológica
|
|
||||||
4. `idx_clara_estado` - Filtro por estado
|
|
||||||
5. `idx_clara_timestamp` - Búsqueda por fecha de captura
|
|
||||||
6. `idx_clara_inst_entrada` - Compuesto para consultas frecuentes
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Seguridad
|
|
||||||
|
|
||||||
### Autenticación
|
|
||||||
|
|
||||||
- **Método**: Header `X-Auth-Key`
|
|
||||||
- **Token**: `h_instancia` (SHA-256 único por instancia)
|
|
||||||
- **Validación**: Todas las rutas excepto `/health`
|
|
||||||
|
|
||||||
### Inmutabilidad
|
|
||||||
|
|
||||||
- ✅ Sin campo `updated_at` en la tabla
|
|
||||||
- ✅ Sin endpoints DELETE o PUT
|
|
||||||
- ✅ Detección de duplicados por `h_entrada`
|
|
||||||
- ✅ Archivos en R2 nunca se mueven ni eliminan
|
|
||||||
|
|
||||||
### Recomendaciones para producción
|
|
||||||
|
|
||||||
1. **Firewall**: Solo permitir IPs de PACKET
|
|
||||||
2. **HTTPS**: Reverse proxy con Let's Encrypt
|
|
||||||
3. **Rate limiting**: Nginx o middleware Flask
|
|
||||||
4. **Monitoring**: Prometheus + Grafana
|
|
||||||
5. **Backups**: PostgreSQL a R2 cada 6h
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Despliegue
|
|
||||||
|
|
||||||
### Configuración requerida
|
|
||||||
|
|
||||||
Variables de entorno en `.env`:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Generado con: echo -n "deck-seed-$(date +%s)" | sha256sum
|
|
||||||
H_INSTANCIA=abc123...
|
|
||||||
|
|
||||||
# PostgreSQL (incluido en docker-compose)
|
|
||||||
DB_HOST=postgres
|
|
||||||
DB_NAME=tzzr
|
|
||||||
DB_USER=postgres
|
|
||||||
DB_PASSWORD=secure_password
|
|
||||||
|
|
||||||
# Cloudflare R2
|
|
||||||
R2_ENDPOINT=https://xxx.r2.cloudflarestorage.com
|
|
||||||
R2_ACCESS_KEY=xxx
|
|
||||||
R2_SECRET_KEY=xxx
|
|
||||||
R2_BUCKET=deck
|
|
||||||
```
|
|
||||||
|
|
||||||
### Comandos de despliegue
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# 1. Clonar repositorio
|
|
||||||
git clone http://69.62.126.110:3000/tzzr/clara.git
|
|
||||||
cd clara
|
|
||||||
|
|
||||||
# 2. Configurar
|
|
||||||
cp .env.example .env
|
|
||||||
nano .env # Editar credenciales
|
|
||||||
|
|
||||||
# 3. Iniciar
|
|
||||||
docker-compose up -d
|
|
||||||
|
|
||||||
# 4. Verificar
|
|
||||||
curl http://localhost:5051/health
|
|
||||||
./test_clara.sh
|
|
||||||
|
|
||||||
# 5. Ver logs
|
|
||||||
docker-compose logs -f clara
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Próximos pasos
|
|
||||||
|
|
||||||
### Pendientes inmediatos
|
|
||||||
|
|
||||||
1. **Acceso a DECK (72.62.1.113)**
|
|
||||||
- Actualmente SSH en puerto 22 está bloqueado
|
|
||||||
- Opciones:
|
|
||||||
- Habilitar SSH en DECK
|
|
||||||
- Usar puerto alternativo
|
|
||||||
- Desplegar desde ARCHITECT temporalmente
|
|
||||||
|
|
||||||
2. **Despliegue en DECK**
|
|
||||||
- Una vez accesible, clonar repo y ejecutar docker-compose
|
|
||||||
- Configurar credenciales R2 reales
|
|
||||||
- Generar `h_instancia` único para DECK
|
|
||||||
- Configurar reverse proxy Nginx
|
|
||||||
|
|
||||||
3. **Integración con PACKET**
|
|
||||||
- Actualizar endpoint de PACKET a CLARA
|
|
||||||
- Configurar mismo `h_instancia` en ambos
|
|
||||||
- Probar flujo completo de envío
|
|
||||||
|
|
||||||
### Roadmap futuro
|
|
||||||
|
|
||||||
- **MASON**: Servicio de enriquecimiento (siguiente paso)
|
|
||||||
- **FELDMAN**: Consolidación en blockchain
|
|
||||||
- **Monitoring**: Dashboard de métricas
|
|
||||||
- **Backups**: Automatizar backups a R2
|
|
||||||
- **MARGARET**: Equivalente para CORP
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Testing
|
|
||||||
|
|
||||||
### Suite automatizada (test_clara.sh)
|
|
||||||
|
|
||||||
✅ Test 1: Health check
|
|
||||||
✅ Test 2: Unauthorized access
|
|
||||||
✅ Test 3: Valid container ingest
|
|
||||||
✅ Test 4: Query container
|
|
||||||
✅ Test 5: Duplicate hash rejection
|
|
||||||
✅ Test 6: List containers
|
|
||||||
|
|
||||||
### Ejecución
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Con variables de entorno
|
|
||||||
export CLARA_URL=http://localhost:5051
|
|
||||||
export H_INSTANCIA=your-instance-hash
|
|
||||||
./test_clara.sh
|
|
||||||
|
|
||||||
# Con valores por defecto
|
|
||||||
./test_clara.sh
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Commits realizados
|
|
||||||
|
|
||||||
### Commit 1: Implementación completa
|
|
||||||
- Fecha: 2025-12-23
|
|
||||||
- Hash: `7d96cfc`
|
|
||||||
- Archivos: 8 nuevos (786 líneas)
|
|
||||||
- Contenido:
|
|
||||||
- app.py, Dockerfile, docker-compose.yml
|
|
||||||
- init.sql, requirements.txt
|
|
||||||
- .env.example, test_clara.sh
|
|
||||||
- DEPLOYMENT.md
|
|
||||||
|
|
||||||
### Commit 2: Actualización README
|
|
||||||
- Fecha: 2025-12-23
|
|
||||||
- Hash: `2bfb48d`
|
|
||||||
- Archivos: 1 modificado (50 líneas añadidas)
|
|
||||||
- Contenido: Documentación de implementación
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Métricas del proyecto
|
|
||||||
|
|
||||||
- **Líneas de código Python**: 375
|
|
||||||
- **Líneas de SQL**: 65
|
|
||||||
- **Líneas de documentación**: 350+
|
|
||||||
- **Tests automatizados**: 6
|
|
||||||
- **Endpoints**: 4
|
|
||||||
- **Tiempo de implementación**: ~2 horas
|
|
||||||
- **Cobertura**: 100% de funcionalidad especificada
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Conclusión
|
|
||||||
|
|
||||||
✅ **CLARA está completamente implementado y listo para desplegar.**
|
|
||||||
|
|
||||||
El servicio cumple con todos los requisitos especificados en el README original:
|
|
||||||
- Log inmutable
|
|
||||||
- Autenticación por `h_instancia`
|
|
||||||
- Integración con R2 y PostgreSQL
|
|
||||||
- No añade información
|
|
||||||
- No procesa
|
|
||||||
- No modifica
|
|
||||||
|
|
||||||
**Bloqueador actual**: Acceso SSH a DECK (72.62.1.113) para despliegue final.
|
|
||||||
|
|
||||||
**Solución temporal**: Servicio puede desplegarse en ARCHITECT (69.62.126.110) mientras se resuelve acceso a DECK.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
**Reportado por**: ARCHITECT
|
|
||||||
**Repositorio**: https://git.tzzr.me/tzzr/clara
|
|
||||||
**Branch**: main
|
|
||||||
**Estado**: ✅ IMPLEMENTADO - ⏳ PENDIENTE DESPLIEGUE
|
|
||||||
@@ -1,233 +0,0 @@
|
|||||||
# CLARA
|
|
||||||
|
|
||||||

|
|
||||||
|
|
||||||
|
|
||||||
**Log de entrada DECK - Sistema TZZR**
|
|
||||||
|
|
||||||
## Rol
|
|
||||||
|
|
||||||
Secretaria de entrada para DECK (servidor personal). Log inmutable que recibe información sin procesarla.
|
|
||||||
|
|
||||||
## Posición en el Flujo
|
|
||||||
|
|
||||||
```
|
|
||||||
┌─────────────────────────────────────────────────────────────────────────────┐
|
|
||||||
│ PACKET (App móvil) │
|
|
||||||
└─────────────────────────────────────────────────────────────────────────────┘
|
|
||||||
│
|
|
||||||
┌────────────────────────────┼────────────────────────────┐
|
|
||||||
│ │ │
|
|
||||||
▼ ▼ ▼
|
|
||||||
┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐
|
|
||||||
│ CLARA │ │ MARGARET │ │ ALFRED/JARED │
|
|
||||||
│ (DECK log) │ │ (CORP log) │ │(flujo predefinido)│
|
|
||||||
│ inmutable │ │ inmutable │ │ │
|
|
||||||
└────────┬────────┘ └────────┬────────┘ └────────┬────────┘
|
|
||||||
│ │ │
|
|
||||||
└──────────────────────────┴──────────────────────────┘
|
|
||||||
│
|
|
||||||
▼
|
|
||||||
┌─────────────┐
|
|
||||||
│ MASON │
|
|
||||||
│(enriquecer) │
|
|
||||||
└──────┬──────┘
|
|
||||||
│
|
|
||||||
▼
|
|
||||||
┌─────────────┐
|
|
||||||
│ FELDMAN │
|
|
||||||
│(consolidar) │
|
|
||||||
└─────────────┘
|
|
||||||
```
|
|
||||||
|
|
||||||
## Función
|
|
||||||
|
|
||||||
1. Recibe contenedor de PACKET
|
|
||||||
2. Envía archivos a R2
|
|
||||||
3. Registra en PostgreSQL:
|
|
||||||
- Metadata del contenedor
|
|
||||||
- Ubicación de archivos en R2
|
|
||||||
4. **NO añade información**
|
|
||||||
5. **NO procesa**
|
|
||||||
6. **NO modifica**
|
|
||||||
|
|
||||||
## Comparación
|
|
||||||
|
|
||||||
| Componente | Servidor | Tipo | Función |
|
|
||||||
|------------|----------|------|---------|
|
|
||||||
| **CLARA** | DECK | Input suelto | Log de entrada personal |
|
|
||||||
| MARGARET | CORP | Input suelto | Log de entrada empresarial |
|
|
||||||
| ALFRED | DECK | Flujo predefinido | Cadenas de pasos conocidos |
|
|
||||||
| JARED | CORP | Flujo predefinido | Cadenas de pasos + NOTARIO |
|
|
||||||
|
|
||||||
## Identificador
|
|
||||||
|
|
||||||
```
|
|
||||||
h_instancia = SHA-256(seed único de DECK)
|
|
||||||
```
|
|
||||||
|
|
||||||
Mismo hash para:
|
|
||||||
- Autenticación: `X-Auth-Key: {h_instancia}`
|
|
||||||
- Biblioteca privada: `h_biblioteca = h_instancia`
|
|
||||||
- Prefijo R2: `{endpoint}/{h_instancia}/...`
|
|
||||||
|
|
||||||
## API
|
|
||||||
|
|
||||||
### Recepción
|
|
||||||
```http
|
|
||||||
POST /ingest
|
|
||||||
X-Auth-Key: {h_instancia}
|
|
||||||
Content-Type: application/json
|
|
||||||
|
|
||||||
{
|
|
||||||
"hash": "fc2fae65...",
|
|
||||||
"titulo": "opcional",
|
|
||||||
"descripcion": "opcional",
|
|
||||||
"etiquetas": ["h_maestro1", "h_maestro2"],
|
|
||||||
"gps": {"lat": 43.36, "long": -8.41},
|
|
||||||
"archivos": [...]
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
### Respuestas
|
|
||||||
- `200`: `{"ok": true, "id": 1001}`
|
|
||||||
- `409`: `{"error": "hash_exists"}`
|
|
||||||
- `401`: `{"error": "unauthorized"}`
|
|
||||||
|
|
||||||
## Estructura de Datos
|
|
||||||
|
|
||||||
CLARA registra contenedores con la siguiente estructura (ver [esquema completo](https://git.tzzr.me/tzzr/contratos-comunes/src/branch/main/architecture/06-contenedor-schema.md)):
|
|
||||||
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"id": "uuid-contenedor",
|
|
||||||
"h_instancia": "sha256-instancia",
|
|
||||||
"archivo_hash": "sha256-archivo",
|
|
||||||
|
|
||||||
"origen": {
|
|
||||||
"dispositivo": "uuid-dispositivo",
|
|
||||||
"app_version": "1.0.0",
|
|
||||||
"timestamp_captura": "2025-01-15T10:30:00Z",
|
|
||||||
"geolocalizacion": {"lat": 41.38, "lon": 2.17, "precision_m": 10}
|
|
||||||
},
|
|
||||||
|
|
||||||
"archivo": {
|
|
||||||
"tipo": "image/jpeg",
|
|
||||||
"categoria": "imagen",
|
|
||||||
"size_bytes": 2048576,
|
|
||||||
"dimensiones": {"ancho": 1920, "alto": 1080}
|
|
||||||
},
|
|
||||||
|
|
||||||
"tags": [
|
|
||||||
{"h_maestro": "sha256", "grupo": "hst", "nombre": "Factura", "confianza": 1.0}
|
|
||||||
],
|
|
||||||
|
|
||||||
"estado": {
|
|
||||||
"actual": "en_clara",
|
|
||||||
"historial": [{"paso": "clara", "entrada": "...", "procesado_por": "clara-service"}]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
**Secciones que CLARA recibe de PACKET**:
|
|
||||||
- `identificacion`: id, h_instancia, archivo_hash
|
|
||||||
- `origen`: dispositivo, app_version, timestamp, geolocalizacion
|
|
||||||
- `archivo`: metadata tecnica
|
|
||||||
- `tags`: etiquetas iniciales
|
|
||||||
|
|
||||||
**Secciones que CLARA NO toca**:
|
|
||||||
- `extraccion`: la anade servicio externo despues
|
|
||||||
- `enriquecimiento`: la anade usuario en MASON
|
|
||||||
- `bloque`: la anade FELDMAN al consolidar
|
|
||||||
|
|
||||||
## Tabla PostgreSQL
|
|
||||||
|
|
||||||
```sql
|
|
||||||
CREATE TABLE clara_log (
|
|
||||||
id BIGSERIAL PRIMARY KEY,
|
|
||||||
h_instancia VARCHAR(64) NOT NULL,
|
|
||||||
h_entrada VARCHAR(64) NOT NULL,
|
|
||||||
contenedor JSONB NOT NULL,
|
|
||||||
r2_paths JSONB,
|
|
||||||
created_at TIMESTAMP DEFAULT NOW()
|
|
||||||
);
|
|
||||||
|
|
||||||
-- Inmutable: sin updated_at
|
|
||||||
CREATE INDEX idx_clara_instancia ON clara_log(h_instancia);
|
|
||||||
CREATE INDEX idx_clara_entrada ON clara_log(h_entrada);
|
|
||||||
CREATE INDEX idx_clara_estado ON clara_log((contenedor->>'estado'->>'actual'));
|
|
||||||
```
|
|
||||||
|
|
||||||
## Inmutabilidad
|
|
||||||
|
|
||||||
- Registros NUNCA se modifican
|
|
||||||
- Archivos en R2 NUNCA se mueven
|
|
||||||
- Las correcciones se hacen en MASON
|
|
||||||
|
|
||||||
## Arquitectura Completa
|
|
||||||
|
|
||||||
Ver documentación en [contratos-comunes/architecture](https://git.tzzr.me/tzzr/contratos-comunes/src/branch/main/architecture/01-clara-margaret.md)
|
|
||||||
|
|
||||||
## Repositorios Relacionados
|
|
||||||
|
|
||||||
| Repo | Rol |
|
|
||||||
|------|-----|
|
|
||||||
| [margaret](https://git.tzzr.me/tzzr/margaret) | Equivalente para CORP |
|
|
||||||
| [alfred](https://git.tzzr.me/tzzr/alfred) | Flujos predefinidos DECK |
|
|
||||||
| [mason](https://git.tzzr.me/tzzr/mason) | Enriquecimiento |
|
|
||||||
| [feldman](https://git.tzzr.me/tzzr/feldman) | Consolidación |
|
|
||||||
| [sentinel](https://git.tzzr.me/tzzr/sentinel) | Auditoría |
|
|
||||||
| [packet](https://git.tzzr.me/tzzr/packet) | App móvil |
|
|
||||||
|
|
||||||
## Implementación
|
|
||||||
|
|
||||||
Este repositorio contiene la implementación completa del servicio CLARA:
|
|
||||||
|
|
||||||
### Archivos principales
|
|
||||||
|
|
||||||
- **`app.py`**: Servicio Flask con API REST
|
|
||||||
- **`Dockerfile`**: Imagen Docker del servicio
|
|
||||||
- **`docker-compose.yml`**: Orquestación con PostgreSQL
|
|
||||||
- **`init.sql`**: Schema de base de datos
|
|
||||||
- **`requirements.txt`**: Dependencias Python
|
|
||||||
- **`test_clara.sh`**: Suite de tests automatizados
|
|
||||||
- **`DEPLOYMENT.md`**: Guía de despliegue completa
|
|
||||||
|
|
||||||
### Tecnologías
|
|
||||||
|
|
||||||
- **Backend**: Flask + Gunicorn
|
|
||||||
- **Base de datos**: PostgreSQL 15 con JSONB
|
|
||||||
- **Storage**: Cloudflare R2 (compatible S3)
|
|
||||||
- **Contenedores**: Docker + Docker Compose
|
|
||||||
- **Testing**: Bash + curl + jq
|
|
||||||
|
|
||||||
### Inicio rápido
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# 1. Configurar credenciales
|
|
||||||
cp .env.example .env
|
|
||||||
nano .env
|
|
||||||
|
|
||||||
# 2. Iniciar servicios
|
|
||||||
docker-compose up -d
|
|
||||||
|
|
||||||
# 3. Verificar
|
|
||||||
curl http://localhost:5051/health
|
|
||||||
|
|
||||||
# 4. Ejecutar tests
|
|
||||||
./test_clara.sh
|
|
||||||
```
|
|
||||||
|
|
||||||
Ver [`DEPLOYMENT.md`](./DEPLOYMENT.md) para instrucciones completas.
|
|
||||||
|
|
||||||
### Estado del servicio
|
|
||||||
|
|
||||||
- ✅ Implementación completa
|
|
||||||
- ✅ Tests automatizados
|
|
||||||
- ✅ Docker ready
|
|
||||||
- ⏳ Pendiente despliegue a DECK (72.62.1.113)
|
|
||||||
- ⏳ Pendiente integración con PACKET
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
*Componente del sistema TZZR - Actualizado 2025-12-23*
|
|
||||||
@@ -1,85 +0,0 @@
|
|||||||
# Sistema de Contexto para Agentes IA
|
|
||||||
|
|
||||||

|
|
||||||
|
|
||||||
|
|
||||||
**"La IA no recuerda. Tú sí."**
|
|
||||||
|
|
||||||
Sistema de bloques de contexto atómicos para agentes TZZR.
|
|
||||||
|
|
||||||
## Filosofía
|
|
||||||
|
|
||||||
Los LLMs no tienen memoria persistente. Cada conversación empieza de cero. Este sistema resuelve eso:
|
|
||||||
|
|
||||||
1. **Bloques atómicos** - Piezas de contexto reutilizables
|
|
||||||
2. **Asignación por agente** - Cada agente recibe solo lo que necesita
|
|
||||||
3. **Peso y orden** - Priorizar información crítica
|
|
||||||
4. **Expiración** - Contexto temporal cuando sea necesario
|
|
||||||
|
|
||||||
## Arquitectura
|
|
||||||
|
|
||||||
```
|
|
||||||
context_blocks (35 bloques atómicos)
|
|
||||||
↓
|
|
||||||
agent_context_index (asignación agente↔bloque)
|
|
||||||
↓
|
|
||||||
v_agent_context (vista activa)
|
|
||||||
↓
|
|
||||||
get_agent_full_context(agent_id) → TEXT concatenado
|
|
||||||
```
|
|
||||||
|
|
||||||
## Estadísticas
|
|
||||||
|
|
||||||
| Tipo | Cantidad |
|
|
||||||
|------|----------|
|
|
||||||
| identity | 6 |
|
|
||||||
| capability | 12 |
|
|
||||||
| knowledge | 13 |
|
|
||||||
| rule | 3 |
|
|
||||||
| index | 1 |
|
|
||||||
| **Total** | **35** |
|
|
||||||
|
|
||||||
## Agentes
|
|
||||||
|
|
||||||
| Agente | Bloques | Rol |
|
|
||||||
|--------|---------|-----|
|
|
||||||
| ARCHITECT | 20 | Coordinador central |
|
|
||||||
| DECK | 8 | Servidor personal |
|
|
||||||
| CORP | 8 | Servidor empresarial |
|
|
||||||
| HST | 5 | API tags semánticos |
|
|
||||||
| LOCKER | 4 | Almacenamiento R2 |
|
|
||||||
| RUNPOD | 6 | GPU endpoints |
|
|
||||||
|
|
||||||
## Uso Rápido
|
|
||||||
|
|
||||||
```sql
|
|
||||||
-- Obtener contexto de un agente
|
|
||||||
SELECT get_agent_full_context('architect');
|
|
||||||
|
|
||||||
-- Ver bloques asignados
|
|
||||||
SELECT * FROM v_agent_context WHERE agent_id = 'deck';
|
|
||||||
|
|
||||||
-- Añadir bloque a agente
|
|
||||||
INSERT INTO agent_context_index (agent_id, block_id, peso, orden)
|
|
||||||
SELECT 'deck', id, 0.9, 5 FROM context_blocks WHERE codigo = 'nuevo_bloque';
|
|
||||||
```
|
|
||||||
|
|
||||||
## Estructura del Repo
|
|
||||||
|
|
||||||
```
|
|
||||||
context/
|
|
||||||
├── schemas/ # SQL: tablas, vistas, funciones
|
|
||||||
├── indices/ # Índices optimizados para LLM
|
|
||||||
├── blocks/ # Documentación de bloques por tipo
|
|
||||||
├── agents/ # Contexto por agente
|
|
||||||
└── docs/ # Guías de uso
|
|
||||||
```
|
|
||||||
|
|
||||||
## Base de Datos
|
|
||||||
|
|
||||||
- Host: ARCHITECT (69.62.126.110)
|
|
||||||
- Database: `architect`
|
|
||||||
- Acceso: `sudo -u postgres psql -d architect`
|
|
||||||
|
|
||||||
---
|
|
||||||
Creado: 2024-12-24
|
|
||||||
@@ -1,115 +0,0 @@
|
|||||||
# Guía de Uso
|
|
||||||
|
|
||||||
## Conexión
|
|
||||||
|
|
||||||
```bash
|
|
||||||
ssh -i ~/.ssh/tzzr root@localhost "sudo -u postgres psql -d architect"
|
|
||||||
```
|
|
||||||
|
|
||||||
## Consultar Contexto
|
|
||||||
|
|
||||||
### Contexto completo de un agente
|
|
||||||
```sql
|
|
||||||
SELECT get_agent_full_context('architect');
|
|
||||||
```
|
|
||||||
|
|
||||||
### Ver bloques asignados
|
|
||||||
```sql
|
|
||||||
SELECT cb.codigo, cb.tipo, aci.peso, aci.orden
|
|
||||||
FROM agent_context_index aci
|
|
||||||
JOIN context_blocks cb ON aci.block_id = cb.id
|
|
||||||
WHERE aci.agent_id = 'architect' AND aci.activo = true
|
|
||||||
ORDER BY aci.orden;
|
|
||||||
```
|
|
||||||
|
|
||||||
### Listar todos los bloques
|
|
||||||
```sql
|
|
||||||
SELECT codigo, tipo, length(contenido) as bytes, tags
|
|
||||||
FROM context_blocks
|
|
||||||
ORDER BY tipo, codigo;
|
|
||||||
```
|
|
||||||
|
|
||||||
## Añadir Bloques
|
|
||||||
|
|
||||||
### Crear nuevo bloque
|
|
||||||
```sql
|
|
||||||
INSERT INTO context_blocks (codigo, tipo, contenido, tags) VALUES
|
|
||||||
('mi_bloque', 'knowledge', 'Contenido del bloque...', '{tag1,tag2}');
|
|
||||||
```
|
|
||||||
|
|
||||||
### Asignar bloque a agente
|
|
||||||
```sql
|
|
||||||
INSERT INTO agent_context_index (agent_id, block_id, peso, orden)
|
|
||||||
SELECT 'deck', id, 0.9, 10
|
|
||||||
FROM context_blocks WHERE codigo = 'mi_bloque';
|
|
||||||
```
|
|
||||||
|
|
||||||
## Modificar Bloques
|
|
||||||
|
|
||||||
### Actualizar contenido
|
|
||||||
```sql
|
|
||||||
UPDATE context_blocks SET contenido = 'Nuevo contenido...'
|
|
||||||
WHERE codigo = 'mi_bloque';
|
|
||||||
```
|
|
||||||
|
|
||||||
### Cambiar peso/orden
|
|
||||||
```sql
|
|
||||||
UPDATE agent_context_index SET peso = 0.8, orden = 5
|
|
||||||
WHERE agent_id = 'deck'
|
|
||||||
AND block_id = (SELECT id FROM context_blocks WHERE codigo = 'mi_bloque');
|
|
||||||
```
|
|
||||||
|
|
||||||
## Desactivar Bloques
|
|
||||||
|
|
||||||
### Desactivar temporalmente
|
|
||||||
```sql
|
|
||||||
UPDATE agent_context_index SET activo = false
|
|
||||||
WHERE agent_id = 'deck'
|
|
||||||
AND block_id = (SELECT id FROM context_blocks WHERE codigo = 'mi_bloque');
|
|
||||||
```
|
|
||||||
|
|
||||||
### Bloque con expiración
|
|
||||||
```sql
|
|
||||||
INSERT INTO agent_context_index (agent_id, block_id, expires_at)
|
|
||||||
SELECT 'architect', id, NOW() + INTERVAL '1 day'
|
|
||||||
FROM context_blocks WHERE codigo = 'temporal_block';
|
|
||||||
```
|
|
||||||
|
|
||||||
## Buscar Bloques
|
|
||||||
|
|
||||||
### Por tag
|
|
||||||
```sql
|
|
||||||
SELECT * FROM context_blocks WHERE 'services' = ANY(tags);
|
|
||||||
```
|
|
||||||
|
|
||||||
### Por contenido
|
|
||||||
```sql
|
|
||||||
SELECT codigo, tipo FROM context_blocks
|
|
||||||
WHERE contenido ILIKE '%mailcow%';
|
|
||||||
```
|
|
||||||
|
|
||||||
## Estadísticas
|
|
||||||
|
|
||||||
### Bloques por tipo
|
|
||||||
```sql
|
|
||||||
SELECT tipo, COUNT(*) as cantidad
|
|
||||||
FROM context_blocks
|
|
||||||
GROUP BY tipo ORDER BY tipo;
|
|
||||||
```
|
|
||||||
|
|
||||||
### Bloques por agente
|
|
||||||
```sql
|
|
||||||
SELECT agent_id, COUNT(*) as bloques
|
|
||||||
FROM agent_context_index
|
|
||||||
WHERE activo = true
|
|
||||||
GROUP BY agent_id ORDER BY bloques DESC;
|
|
||||||
```
|
|
||||||
|
|
||||||
### Tamaño total por agente
|
|
||||||
```sql
|
|
||||||
SELECT agent_id, SUM(length(cb.contenido)) as bytes
|
|
||||||
FROM agent_context_index aci
|
|
||||||
JOIN context_blocks cb ON aci.block_id = cb.id
|
|
||||||
WHERE aci.activo = true
|
|
||||||
GROUP BY agent_id ORDER BY bytes DESC;
|
|
||||||
```
|
|
||||||
@@ -1,205 +0,0 @@
|
|||||||
# Contratos Comunes - Sistema GRACE
|
|
||||||
|
|
||||||
**Version:** 2.1
|
|
||||||
**Estado:** Enterprise Standard
|
|
||||||
|
|
||||||
Especificacion del contrato comun (S-CONTRACT) y contratos de modulo (M-CONTRACT) para el ecosistema de microservicios cognitivos GRACE.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Arquitectura
|
|
||||||
|
|
||||||
```
|
|
||||||
Alfred (Orquestador n8n)
|
|
||||||
|
|
|
||||||
| S-CONTRACT v2.0
|
|
||||||
v
|
|
||||||
+-------------------+
|
|
||||||
| GRACE |
|
|
||||||
| 18 Microservicios|
|
|
||||||
| Cognitivos |
|
|
||||||
+-------------------+
|
|
||||||
|
|
|
||||||
v
|
|
||||||
SYS_LOG + SFE
|
|
||||||
```
|
|
||||||
|
|
||||||
**Filosofia:** "Alfred Decide, GRACE Transforma"
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Estructura del Repositorio
|
|
||||||
|
|
||||||
```
|
|
||||||
contratos-comunes/
|
|
||||||
+-- README.md # Este archivo
|
|
||||||
+-- docs/
|
|
||||||
| +-- S-CONTRACT.md # Contrato comun del sistema (v2.1)
|
|
||||||
| +-- MODULOS_IA.md # Catalogo de 18 modulos
|
|
||||||
| +-- ARQUITECTURA.md # Vision arquitectonica
|
|
||||||
| +-- SENTINEL.md # Sistema de auditoria
|
|
||||||
| +-- KEY_VAULT.md # Gestion de llaves y cifrado
|
|
||||||
| +-- NOTARIO.md # Sellado blockchain
|
|
||||||
| +-- IMPLEMENTACION.md # Wrappers y ejemplos
|
|
||||||
+-- schemas/
|
|
||||||
| +-- s-contract-request.json # JSON Schema para requests (v2.1)
|
|
||||||
| +-- s-contract-response.json # JSON Schema para responses (v2.1)
|
|
||||||
+-- m-contracts/
|
|
||||||
| +-- CLASSIFIER.json # M-CONTRACT clasificador
|
|
||||||
| +-- OCR_CORE.json # M-CONTRACT OCR
|
|
||||||
| +-- ASR_ENGINE.json # M-CONTRACT ASR
|
|
||||||
| +-- ... # (18 modulos total)
|
|
||||||
+-- db-schemas/ # NUEVO: Schemas PostgreSQL
|
|
||||||
| +-- 00_types.sql # Tipos enumerados
|
|
||||||
| +-- 01_hst_tags.sql # Sistema de etiquetas HST
|
|
||||||
| +-- 02_task_manager.sql # Gestor de tareas
|
|
||||||
| +-- 03_work_log.sql # Log de trabajo
|
|
||||||
| +-- 04_ai_context.sql # Contexto para IA
|
|
||||||
| +-- 05_ai_requests.sql # Log de requests IA
|
|
||||||
+-- archive/ # Versiones obsoletas
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Documentos Principales
|
|
||||||
|
|
||||||
| Documento | Descripcion | Prioridad |
|
|
||||||
|-----------|-------------|-----------|
|
|
||||||
| [S-CONTRACT.md](docs/S-CONTRACT.md) | Especificacion del contrato comun v2.0 | LEER PRIMERO |
|
|
||||||
| [MODULOS_IA.md](docs/MODULOS_IA.md) | Catalogo de los 18 modulos GRACE | Alta |
|
|
||||||
| [ARQUITECTURA.md](docs/ARQUITECTURA.md) | Vision arquitectonica del sistema | Alta |
|
|
||||||
| [HST_API.md](docs/HST_API.md) | API de etiquetas HST v2.0 (tzrtech.org) | Alta |
|
|
||||||
| [SENTINEL.md](docs/SENTINEL.md) | Sistema de auditoria dual (LIGHT/DEEP) | Media |
|
|
||||||
| [KEY_VAULT.md](docs/KEY_VAULT.md) | Gestion de llaves y cifrado | Media |
|
|
||||||
| [NOTARIO.md](docs/NOTARIO.md) | Sellado blockchain | Media |
|
|
||||||
| [IMPLEMENTACION.md](docs/IMPLEMENTACION.md) | Wrappers Python/JS y ejemplos n8n | Referencia |
|
|
||||||
| [db-schemas/README.md](db-schemas/README.md) | Schemas PostgreSQL compartidos | Alta |
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Database Schemas (db-schemas/)
|
|
||||||
|
|
||||||
Schemas PostgreSQL compartidos por todos los componentes del ecosistema:
|
|
||||||
|
|
||||||
| Schema | Descripción |
|
|
||||||
|--------|-------------|
|
|
||||||
| `hst_tags` | Sistema de etiquetas unificado (HST/EMP/HSU/PJT) |
|
|
||||||
| `task_manager` | Proyectos, milestones, bloques y tareas |
|
|
||||||
| `task_work_log` | Log de archivos entrantes/salientes |
|
|
||||||
| `task_contexts` | Contexto enviado a servicios IA |
|
|
||||||
| `task_ai_requests` | Log de todas las requests a IA |
|
|
||||||
|
|
||||||
Ver [db-schemas/README.md](db-schemas/README.md) para documentación completa.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Conceptos Clave
|
|
||||||
|
|
||||||
### S-CONTRACT (Contrato del Sistema)
|
|
||||||
Marco general que define:
|
|
||||||
- Estructura de requests/responses
|
|
||||||
- Trazabilidad (trace_id, step_id, idempotency_key)
|
|
||||||
- Perfiles FULL/LITE
|
|
||||||
- Logging (SYS_LOG)
|
|
||||||
- Seguridad y cifrado
|
|
||||||
|
|
||||||
### M-CONTRACT (Contrato de Modulo)
|
|
||||||
Cada modulo extiende S-CONTRACT con:
|
|
||||||
- Schemas de input/output especificos
|
|
||||||
- Cadena de fallback
|
|
||||||
- Metricas de calidad baseline
|
|
||||||
- Providers disponibles
|
|
||||||
|
|
||||||
### Perfiles
|
|
||||||
|
|
||||||
| Perfil | Uso | Campos |
|
|
||||||
|--------|-----|--------|
|
|
||||||
| FULL | Flujos criticos, auditoria completa | Todos |
|
|
||||||
| LITE | Operaciones rapidas, alto volumen | Minimos |
|
|
||||||
|
|
||||||
### Status Codes
|
|
||||||
|
|
||||||
- `SUCCESS` - Ejecucion completa
|
|
||||||
- `PARTIAL` - Resultado incompleto pero usable
|
|
||||||
- `ERROR` - Fallo no recuperable
|
|
||||||
- `TIMEOUT` - Excedio TTL
|
|
||||||
- `FALLBACK` - Exito con modulo alternativo
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Los 18 Modulos GRACE
|
|
||||||
|
|
||||||
| Familia | Modulos |
|
|
||||||
|---------|---------|
|
|
||||||
| VISION | IMG_PREPROCESS, PDF_SCANNER, OCR_CORE |
|
|
||||||
| VOZ | ASR_ENGINE, TTS_ENGINE |
|
|
||||||
| IDENTIDAD | FACE_VECTOR, ID_CONSOLIDATION, AVATAR_GEN |
|
|
||||||
| SEMANTICA | EMBEDDINGS, SUMMARIZER, TASK_EXTRACTOR, CLASSIFIER, SIMILARITY |
|
|
||||||
| UTILIDADES | FIELD_EXTRACTOR, HASHER, INPUT_NORMALIZER, OUTPUT_ADAPTER, LANG_DETECT |
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Ejemplo Rapido
|
|
||||||
|
|
||||||
### Request LITE
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"contract_version": "2.0",
|
|
||||||
"profile": "LITE",
|
|
||||||
"envelope": {
|
|
||||||
"trace_id": "550e8400-e29b-41d4-a716-446655440000",
|
|
||||||
"idempotency_key": "a1b2c3d4e5f6..."
|
|
||||||
},
|
|
||||||
"routing": {"module": "CLASSIFIER"},
|
|
||||||
"context": {"lang": "es", "mode": "strict"},
|
|
||||||
"payload": {
|
|
||||||
"type": "text",
|
|
||||||
"encoding": "utf-8",
|
|
||||||
"content": "Factura de Telefonica por 45.99 EUR"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
### Response
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"contract_version": "2.0",
|
|
||||||
"profile": "LITE",
|
|
||||||
"envelope": {"trace_id": "550e8400-...", "idempotency_key": "a1b2c3d4..."},
|
|
||||||
"status": {"code": "SUCCESS", "provider_used": "groq"},
|
|
||||||
"result": {
|
|
||||||
"schema": "classifier_output_v1",
|
|
||||||
"data": {"category": "FINANZAS", "confidence": 0.98}
|
|
||||||
},
|
|
||||||
"quality": {"confidence": 0.98, "coverage": 1.0},
|
|
||||||
"errors": []
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Historial de Versiones
|
|
||||||
|
|
||||||
| Version | Fecha | Cambios |
|
|
||||||
|---------|-------|---------|
|
|
||||||
| 1.0 | 2025-12-01 | Version inicial |
|
|
||||||
| 1.1 | 2025-12-01 | Jerarquia S/M-CONTRACT |
|
|
||||||
| 1.2 | 2025-12-01 | Consolidacion, modularizacion |
|
|
||||||
| 2.0 | 2025-12-18 | Nomenclatura GRACE, reorganizacion repo |
|
|
||||||
| 2.1 | 2025-12-18 | Modos de despliegue (EXTERNAL/SELF_HOSTED/SEMI), db-schemas |
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Repositorios Relacionados
|
|
||||||
|
|
||||||
- `deck` - Servidor central, iniciador de conexiones
|
|
||||||
- `grace` - Capa de procesamiento IA
|
|
||||||
- `penny` - Asistente de voz real-time
|
|
||||||
- `the-factory` - Procesamiento documental
|
|
||||||
- `mason` - Constructor de prompts
|
|
||||||
- `hst` - Sistema de etiquetas HST
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
*Sistema GRACE - "Alfred Decide, GRACE Transforma"*
|
|
||||||
# Hook test Wed Dec 24 00:21:51 UTC 2025
|
|
||||||
@@ -1,167 +0,0 @@
|
|||||||
# ARQUITECTURA COGNITIVA: SISTEMA GRACE (HIBRIDO)
|
|
||||||
**Version:** 2.0
|
|
||||||
**Estado:** Enterprise Standard
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
# 1. Filosofia del Sistema: "Alfred Decide, GRACE Transforma"
|
|
||||||
|
|
||||||
Para superar las limitaciones de hardware (VPS sin GPU), se adopta una arquitectura de **Orquestacion Hibrida**.
|
|
||||||
|
|
||||||
* **ALFRED (El Cuerpo - Local):** Reside en Hostinger (n8n). Es logico, determinista, gestiona credenciales, bases de datos y toma decisiones de enrutamiento.
|
|
||||||
|
|
||||||
* **GRACE (El Cerebro - Remoto):** Es efimero y reside en la nube (APIs). Procesa senales complejas (vision, audio, semantica) y devuelve JSON estructurado.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
# 2. Diagrama de Arquitectura
|
|
||||||
|
|
||||||
```
|
|
||||||
+-----------------------------------------------------------------------+
|
|
||||||
| INFRAESTRUCTURA |
|
|
||||||
+-----------------------------------------------------------------------+
|
|
||||||
| |
|
|
||||||
| +------------------+ +------------------+ +------------------+ |
|
|
||||||
| | ALFRED (n8n) | | GRACE (APIs) | | ALMACENAMIENTO | |
|
|
||||||
| | | | | | | |
|
|
||||||
| | - Orquestacion |<--->| - 18 modulos IA | | - Hostinger | |
|
|
||||||
| | - Validacion | | - OpenRouter | | - S3/GCS | |
|
|
||||||
| | - Logging | | - Groq | | - Nextcloud | |
|
|
||||||
| | - Decisiones | | - RunPod | | | |
|
|
||||||
| +------------------+ +------------------+ +------------------+ |
|
|
||||||
| | | | |
|
|
||||||
| +----------------------++-----------------------+ |
|
|
||||||
| | |
|
|
||||||
| +------------------+ +------------------+ +------------------+ |
|
|
||||||
| | NocoDB/PG | | Key Vault | | SENTINEL | |
|
|
||||||
| | | | | | | |
|
|
||||||
| | - SYS_LOG | | - API Keys | | - LIGHT (reglas) | |
|
|
||||||
| | - SFE | | - Encryption | | - DEEP (LLM) | |
|
|
||||||
| | - HST Tags | | - Certificados | | - Patrones | |
|
|
||||||
| +------------------+ +------------------+ +------------------+ |
|
|
||||||
| |
|
|
||||||
+-----------------------------------------------------------------------+
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
# 3. Mapa de Modulos IA (Implementacion Tecnica)
|
|
||||||
|
|
||||||
Basado en la especificacion de 18 microservicios:
|
|
||||||
|
|
||||||
## Familia A: VISION (Ojos)
|
|
||||||
* **Objetivo:** OCR, Analisis de Documentos, Extraccion de Datos.
|
|
||||||
* **Motor:** GPT-4o (Vision) o Claude 3.5 Sonnet.
|
|
||||||
* **Flujo:** Alfred envia imagen (base64/URL) -> GRACE analiza -> Devuelve JSON.
|
|
||||||
|
|
||||||
## Familia B: VOZ (Oidos)
|
|
||||||
* **Objetivo:** Transcripcion de reuniones y notas de voz (ASR).
|
|
||||||
* **Motor:** Whisper Large v3 (Groq API) o Faster Whisper (RunPod).
|
|
||||||
* **Rendimiento:** Transcripcion a 500x tiempo real.
|
|
||||||
|
|
||||||
## Familia D: SEMANTICA (Cortex)
|
|
||||||
* **Objetivo:** Clasificacion, Resumen, Extraccion de Tareas.
|
|
||||||
* **Motor:** Meta Llama 3 70B (OpenRouter/Groq).
|
|
||||||
* **Rendimiento:** Latencia sub-segundo.
|
|
||||||
|
|
||||||
## Familia C: IDENTIDAD (Biometria)
|
|
||||||
* **Estado:** Roadmap Fase 2.
|
|
||||||
* **Implementacion:** RunPod Serverless para calculo vectorial facial.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
# 4. Protocolo de Datos e Identidad
|
|
||||||
|
|
||||||
Para garantizar la integridad y trazabilidad:
|
|
||||||
|
|
||||||
## A. Matricula Interna (TraceID) -> UUID v4
|
|
||||||
* **Generacion:** Descentralizada (en n8n/Alfred).
|
|
||||||
* **Funcion:** Clave Primaria en SYS_LOG.
|
|
||||||
* **Proposito:** Unicidad matematica garantizada.
|
|
||||||
|
|
||||||
## B. Huella de Integridad (idempotency_key) -> SHA256
|
|
||||||
* **Generacion:** `sha256(input_payload)`.
|
|
||||||
* **Funcion:** Control de Idempotencia.
|
|
||||||
* **Proposito:** Evitar reprocesamiento y verificar integridad.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
# 5. El Contrato Comun (S-CONTRACT)
|
|
||||||
|
|
||||||
Todo intercambio entre Alfred y GRACE sigue el S-CONTRACT v2.0.
|
|
||||||
|
|
||||||
Ver `S-CONTRACT.md` para especificacion completa.
|
|
||||||
|
|
||||||
```
|
|
||||||
+---------------------------------------------------------------------+
|
|
||||||
| PRINCIPIO FUNDAMENTAL |
|
|
||||||
| |
|
|
||||||
| "Un modulo que no cumple el contrato, no existe para Alfred" |
|
|
||||||
+---------------------------------------------------------------------+
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
# 6. Flujo de Procesamiento
|
|
||||||
|
|
||||||
```
|
|
||||||
1. ENTRADA
|
|
||||||
- Alfred recibe evento (webhook, email, archivo)
|
|
||||||
- Genera trace_id y idempotency_key
|
|
||||||
|
|
||||||
2. VALIDACION
|
|
||||||
- Verifica permisos (player_id + method_hash)
|
|
||||||
- Valida schema de entrada
|
|
||||||
|
|
||||||
3. ROUTING
|
|
||||||
- Carga M-CONTRACT del modulo destino
|
|
||||||
- Evalua provider_preference
|
|
||||||
- Selecciona proveedor disponible
|
|
||||||
|
|
||||||
4. TRANSFORMACION (GRACE)
|
|
||||||
- Envia request S-CONTRACT
|
|
||||||
- Espera response (respetando timeout)
|
|
||||||
- Si falla, activa fallback_chain
|
|
||||||
|
|
||||||
5. PERSISTENCIA
|
|
||||||
- Guarda resultado en almacenamiento
|
|
||||||
- Registra en SYS_LOG
|
|
||||||
|
|
||||||
6. AUDITORIA
|
|
||||||
- SENTINEL-LIGHT valida conformidad
|
|
||||||
- SENTINEL-DEEP analiza errores
|
|
||||||
- NOTARIO sella si aplica
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
# 7. Infraestructura de Soporte (DECK)
|
|
||||||
|
|
||||||
* **Orquestador:** n8n (Docker)
|
|
||||||
* **Base de Datos:** PostgreSQL 15 + NocoDB
|
|
||||||
* **Almacenamiento:** Nextcloud / FileBrowser
|
|
||||||
* **Cache:** Redis
|
|
||||||
* **Seguridad:** Nginx Proxy Manager + SSL
|
|
||||||
* **Mail:** Mail-in-a-Box
|
|
||||||
* **Servicios:** Shlink, Addy.io, Vaultwarden
|
|
||||||
|
|
||||||
Ver repositorio `deck` para configuracion detallada.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
# 8. Documentos Relacionados
|
|
||||||
|
|
||||||
| Documento | Descripcion |
|
|
||||||
|-----------|-------------|
|
|
||||||
| S-CONTRACT.md | Especificacion del contrato comun |
|
|
||||||
| MODULOS_IA.md | Catalogo de 18 modulos GRACE |
|
|
||||||
| SENTINEL.md | Sistema de auditoria |
|
|
||||||
| KEY_VAULT.md | Gestion de llaves y cifrado |
|
|
||||||
| NOTARIO.md | Sellado blockchain |
|
|
||||||
| IMPLEMENTACION.md | Wrappers y ejemplos |
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
**Fin del Documento ARQUITECTURA - Version 2.0**
|
|
||||||
|
|
||||||
*Sistema GRACE - "Alfred Decide, GRACE Transforma"*
|
|
||||||
@@ -1,337 +0,0 @@
|
|||||||
# THE FACTORY Protocol v1.0
|
|
||||||
|
|
||||||
> Protocolo de Generación Iterativa con Director y Auditores
|
|
||||||
|
|
||||||
## 1. Visión General
|
|
||||||
|
|
||||||
THE FACTORY es el sistema de generación iterativa del ecosistema TZZR. Implementa un ciclo de mejora continua donde un **Director** coordina la generación, un **Executor** produce artefactos, un **Evaluator** evalúa la calidad, y un **Auditor** registra todo para trazabilidad.
|
|
||||||
|
|
||||||
```
|
|
||||||
┌─────────────────────────────────────────────────────────────┐
|
|
||||||
│ THE FACTORY │
|
|
||||||
│ │
|
|
||||||
│ ┌──────────┐ ┌──────────┐ ┌──────────┐ │
|
|
||||||
│ │ DIRECTOR │───▶│ EXECUTOR │───▶│ EVALUATOR│ │
|
|
||||||
│ │ (decide) │◀───│(genera) │◀───│ (evalúa) │ │
|
|
||||||
│ └────┬─────┘ └──────────┘ └──────────┘ │
|
|
||||||
│ │ │
|
|
||||||
│ ▼ │
|
|
||||||
│ ┌──────────┐ │
|
|
||||||
│ │ AUDITOR │ ──▶ SENTINEL │
|
|
||||||
│ │(registra)│ │
|
|
||||||
│ └──────────┘ │
|
|
||||||
└─────────────────────────────────────────────────────────────┘
|
|
||||||
```
|
|
||||||
|
|
||||||
## 2. Componentes
|
|
||||||
|
|
||||||
### 2.1 DIRECTOR
|
|
||||||
|
|
||||||
El Director es el cerebro de THE FACTORY. Sus responsabilidades:
|
|
||||||
|
|
||||||
- **Recibir jobs** de ALFRED (DECK) o CLARA (CORP)
|
|
||||||
- **Seleccionar modelos** apropiados para cada tarea
|
|
||||||
- **Decidir convergencia** basándose en confianza y mejora marginal
|
|
||||||
- **Gestionar presupuesto** y límites de iteraciones
|
|
||||||
- **Coordinar** el flujo entre Executor y Evaluator
|
|
||||||
|
|
||||||
```javascript
|
|
||||||
// Decisión de convergencia
|
|
||||||
const decision = director.decideConvergence(job, evaluation);
|
|
||||||
// Converge si:
|
|
||||||
// - confidence >= 0.85 (umbral configurable)
|
|
||||||
// - mejora < 0.02 con confidence > 0.7 (rendimientos decrecientes)
|
|
||||||
```
|
|
||||||
|
|
||||||
### 2.2 EXECUTOR
|
|
||||||
|
|
||||||
El Executor genera artefactos según el tipo de función:
|
|
||||||
|
|
||||||
| Función | Modelos Disponibles |
|
|
||||||
|---------|---------------------|
|
|
||||||
| TEXT_GENERATION | claude-sonnet, claude-opus, gpt-4, llama-3 |
|
|
||||||
| IMAGE_GENERATION | flux-pro, flux-dev, sdxl, dalle-3 |
|
|
||||||
| CODE_GENERATION | claude-sonnet, claude-opus, gpt-4 |
|
|
||||||
| DOCUMENT_GENERATION | claude-opus, gpt-4 |
|
|
||||||
| AUDIO_GENERATION | elevenlabs, bark, xtts |
|
|
||||||
| VIDEO_GENERATION | runway, pika, stable-video |
|
|
||||||
|
|
||||||
### 2.3 EVALUATOR
|
|
||||||
|
|
||||||
El Evaluator analiza cada artefacto contra el objetivo:
|
|
||||||
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"confidence": 0.82,
|
|
||||||
"strengths": ["Cumple estructura básica", "Lenguaje apropiado"],
|
|
||||||
"weaknesses": ["Falta detalle en sección X"],
|
|
||||||
"feedback": "Mejorar especificidad y añadir ejemplos concretos."
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
### 2.4 AUDITOR
|
|
||||||
|
|
||||||
El Auditor registra cada evento para trazabilidad completa:
|
|
||||||
|
|
||||||
- `JOB_CREATED` - Inicio del job
|
|
||||||
- `JOB_STARTED` - Ejecución iniciada
|
|
||||||
- `ITERATION_COMPLETED` - Cada iteración
|
|
||||||
- `JOB_COMPLETED` - Finalización
|
|
||||||
|
|
||||||
## 3. Estados de Job
|
|
||||||
|
|
||||||
```
|
|
||||||
PENDING ──▶ QUEUED ──▶ RUNNING ──▶ EVALUATING ──┬──▶ CONVERGED
|
|
||||||
│ │ │
|
|
||||||
│ │ └──▶ EXHAUSTED
|
|
||||||
│ │
|
|
||||||
└────────────┘
|
|
||||||
(iteración)
|
|
||||||
```
|
|
||||||
|
|
||||||
| Estado | Descripción |
|
|
||||||
|--------|-------------|
|
|
||||||
| PENDING | Job creado, esperando recursos |
|
|
||||||
| QUEUED | En cola para ejecución |
|
|
||||||
| RUNNING | Executor generando artefacto |
|
|
||||||
| EVALUATING | Evaluator analizando resultado |
|
|
||||||
| CONVERGED | Objetivo alcanzado (confidence >= threshold) |
|
|
||||||
| EXHAUSTED | Límite de iteraciones o presupuesto alcanzado |
|
|
||||||
| FAILED | Error irrecuperable |
|
|
||||||
| CANCELLED | Cancelado por usuario |
|
|
||||||
|
|
||||||
## 4. Estructura del Job
|
|
||||||
|
|
||||||
### 4.1 Request (S-CONTRACT compatible)
|
|
||||||
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"seed": "Genera un plan de entrenamiento PPL de 4 semanas...",
|
|
||||||
"objective": "Plan estructurado con progresión semanal y ejercicios específicos",
|
|
||||||
"function": "TEXT_GENERATION",
|
|
||||||
"limits": {
|
|
||||||
"max_cycles": 5,
|
|
||||||
"budget_usd": 1.0,
|
|
||||||
"timeout_ms": 120000
|
|
||||||
},
|
|
||||||
"input_refs": ["locker://deck/fitness/datos.json"],
|
|
||||||
"output_format": "markdown",
|
|
||||||
"tags": ["deck", "fitness", "plan"],
|
|
||||||
"metadata": {
|
|
||||||
"source": "ALFRED",
|
|
||||||
"project_id": 123
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
### 4.2 Response
|
|
||||||
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"job_id": "fac-abc123-xyz789",
|
|
||||||
"state": "CONVERGED",
|
|
||||||
"total_iterations": 3,
|
|
||||||
"total_cost_usd": 0.47,
|
|
||||||
"final_artifact_ref": "locker://factory/artifacts/abc123.md",
|
|
||||||
"final_confidence": 0.89,
|
|
||||||
"convergence_reason": "confidence_threshold_met",
|
|
||||||
"iterations": [
|
|
||||||
{
|
|
||||||
"number": 1,
|
|
||||||
"confidence": 0.72,
|
|
||||||
"feedback": "Añadir más detalle en ejercicios"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"number": 2,
|
|
||||||
"confidence": 0.81,
|
|
||||||
"feedback": "Mejorar progresión de pesos"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"number": 3,
|
|
||||||
"confidence": 0.89,
|
|
||||||
"feedback": null
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
## 5. Integración con ALFRED y CLARA
|
|
||||||
|
|
||||||
### 5.1 ALFRED (DECK - Lite)
|
|
||||||
|
|
||||||
ALFRED usa THE FACTORY para generación de contenido personal:
|
|
||||||
|
|
||||||
```javascript
|
|
||||||
// alfred.js
|
|
||||||
const result = await factory.submitJob({
|
|
||||||
seed: "Genera plan de entrenamiento para perder peso",
|
|
||||||
objective: "Plan PPL estructurado con progresión",
|
|
||||||
function: "TEXT_GENERATION",
|
|
||||||
tags: ["deck", "fitness"],
|
|
||||||
limits: { max_cycles: 4, budget_usd: 0.3 }
|
|
||||||
});
|
|
||||||
```
|
|
||||||
|
|
||||||
### 5.2 CLARA (CORP - Full)
|
|
||||||
|
|
||||||
CLARA usa THE FACTORY para documentos certificados:
|
|
||||||
|
|
||||||
```javascript
|
|
||||||
// clara.js
|
|
||||||
const result = await factory.submitJob({
|
|
||||||
seed: "Genera factura profesional para pedido ORD-2025-001",
|
|
||||||
objective: "Factura PDF con todos los datos fiscales",
|
|
||||||
function: "DOCUMENT_GENERATION",
|
|
||||||
tags: ["corp", "factura"],
|
|
||||||
limits: { max_cycles: 3, budget_usd: 0.5 }
|
|
||||||
});
|
|
||||||
|
|
||||||
// CLARA añade certificación con NOTARIO
|
|
||||||
const certified = await notario.certify(result);
|
|
||||||
```
|
|
||||||
|
|
||||||
## 6. Flujo de Iteración
|
|
||||||
|
|
||||||
```
|
|
||||||
┌─────────────────────────────────────┐
|
|
||||||
│ ITERACIÓN N │
|
|
||||||
└─────────────────────────────────────┘
|
|
||||||
│
|
|
||||||
▼
|
|
||||||
┌─────────────────────────────────────────────────────────────┐
|
|
||||||
│ 1. DIRECTOR prepara seed + feedback de iteración N-1 │
|
|
||||||
└─────────────────────────────────────────────────────────────┘
|
|
||||||
│
|
|
||||||
▼
|
|
||||||
┌─────────────────────────────────────────────────────────────┐
|
|
||||||
│ 2. EXECUTOR genera artefacto con modelo seleccionado │
|
|
||||||
│ - Calcula hash del artefacto │
|
|
||||||
│ - Guarda en LOCKER │
|
|
||||||
└─────────────────────────────────────────────────────────────┘
|
|
||||||
│
|
|
||||||
▼
|
|
||||||
┌─────────────────────────────────────────────────────────────┐
|
|
||||||
│ 3. EVALUATOR evalúa artefacto vs objetivo │
|
|
||||||
│ - confidence: 0.0 - 1.0 │
|
|
||||||
│ - strengths: [] │
|
|
||||||
│ - weaknesses: [] │
|
|
||||||
│ - feedback: "..." │
|
|
||||||
└─────────────────────────────────────────────────────────────┘
|
|
||||||
│
|
|
||||||
▼
|
|
||||||
┌─────────────────────────────────────────────────────────────┐
|
|
||||||
│ 4. AUDITOR registra iteración en SENTINEL │
|
|
||||||
└─────────────────────────────────────────────────────────────┘
|
|
||||||
│
|
|
||||||
▼
|
|
||||||
┌─────────────────────────────────────────────────────────────┐
|
|
||||||
│ 5. DIRECTOR decide: │
|
|
||||||
│ - confidence >= 0.85 → CONVERGED │
|
|
||||||
│ - cost >= budget → EXHAUSTED │
|
|
||||||
│ - iteration >= max → EXHAUSTED │
|
|
||||||
│ - else → ITERAR (volver a paso 1) │
|
|
||||||
└─────────────────────────────────────────────────────────────┘
|
|
||||||
```
|
|
||||||
|
|
||||||
## 7. Costes y Límites
|
|
||||||
|
|
||||||
### 7.1 Costes por Modelo (estimados)
|
|
||||||
|
|
||||||
| Modelo | Coste por 1K tokens |
|
|
||||||
|--------|---------------------|
|
|
||||||
| claude-sonnet | $0.003 |
|
|
||||||
| claude-opus | $0.015 |
|
|
||||||
| gpt-4 | $0.01 |
|
|
||||||
| flux-pro | $0.05/imagen |
|
|
||||||
| flux-dev | $0.02/imagen |
|
|
||||||
|
|
||||||
### 7.2 Límites por Defecto
|
|
||||||
|
|
||||||
```javascript
|
|
||||||
const DEFAULT_LIMITS = {
|
|
||||||
max_cycles: 5, // Máximo de iteraciones
|
|
||||||
budget_usd: 1.0, // Presupuesto máximo
|
|
||||||
timeout_ms: 120000, // 2 minutos por iteración
|
|
||||||
convergence_threshold: 0.85 // Umbral de convergencia
|
|
||||||
};
|
|
||||||
```
|
|
||||||
|
|
||||||
## 8. Despliegue en RUNPOD
|
|
||||||
|
|
||||||
THE FACTORY se despliega como un Serverless Endpoint en RUNPOD:
|
|
||||||
|
|
||||||
```yaml
|
|
||||||
# runpod-deployment.yaml
|
|
||||||
endpoint:
|
|
||||||
name: the-factory
|
|
||||||
gpu: RTX-A4000 # Para generación de imágenes
|
|
||||||
workers:
|
|
||||||
min: 0
|
|
||||||
max: 3
|
|
||||||
timeout: 300
|
|
||||||
env:
|
|
||||||
- ANTHROPIC_API_KEY: ${ANTHROPIC_API_KEY}
|
|
||||||
- LOCKER_API_KEY: ${LOCKER_API_KEY}
|
|
||||||
- SENTINEL_URL: https://sentinel.tzzr.net
|
|
||||||
```
|
|
||||||
|
|
||||||
## 9. API Reference
|
|
||||||
|
|
||||||
### POST /jobs
|
|
||||||
|
|
||||||
Crear nuevo job de generación.
|
|
||||||
|
|
||||||
**Request:**
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"seed": "string",
|
|
||||||
"objective": "string",
|
|
||||||
"function": "TEXT_GENERATION | IMAGE_GENERATION | ...",
|
|
||||||
"limits": { "max_cycles": 5, "budget_usd": 1.0 },
|
|
||||||
"tags": ["string"]
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
**Response:**
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"job_id": "string",
|
|
||||||
"state": "PENDING"
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
### GET /jobs/{job_id}
|
|
||||||
|
|
||||||
Obtener estado de job.
|
|
||||||
|
|
||||||
**Response:**
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"job_id": "string",
|
|
||||||
"state": "RUNNING | CONVERGED | ...",
|
|
||||||
"current_iteration": 2,
|
|
||||||
"total_cost_usd": 0.15
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
### GET /jobs/{job_id}/result
|
|
||||||
|
|
||||||
Obtener resultado completo.
|
|
||||||
|
|
||||||
**Response:** Job completo con todas las iteraciones.
|
|
||||||
|
|
||||||
### DELETE /jobs/{job_id}
|
|
||||||
|
|
||||||
Cancelar job en ejecución.
|
|
||||||
|
|
||||||
## 10. Changelog
|
|
||||||
|
|
||||||
### v1.0 (2025-01-10)
|
|
||||||
- Versión inicial del protocolo
|
|
||||||
- Componentes: Director, Executor, Evaluator, Auditor
|
|
||||||
- Integración con ALFRED y CLARA
|
|
||||||
- Soporte para TEXT, IMAGE, CODE, DOCUMENT generation
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
*Este documento es parte del sistema S-CONTRACT v2.1*
|
|
||||||
@@ -1,156 +0,0 @@
|
|||||||
# HST API v2.0
|
|
||||||
|
|
||||||
**Servidor:** https://tzrtech.org
|
|
||||||
**Estado:** Producción
|
|
||||||
**Última actualización:** 2025-12-18
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Estadísticas
|
|
||||||
|
|
||||||
| Tabla | Registros | Descripción |
|
|
||||||
|-------|-----------|-------------|
|
|
||||||
| hst | 658 | Etiquetas del sistema |
|
|
||||||
| spe | 145 | Especialidades |
|
|
||||||
| flg | 65 | Flags |
|
|
||||||
| vsn | 84 | Versiones |
|
|
||||||
| vue | 21 | Vistas |
|
|
||||||
| **Total** | **973** | Todas con h_maestro |
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Sistema Dual de Hashes
|
|
||||||
|
|
||||||
```
|
|
||||||
h_maestro = SHA256(grupo || ':' || ref)
|
|
||||||
→ Identidad SEMÁNTICA (determinista)
|
|
||||||
→ Ejemplo: SHA256("hst:abk") = "335350bb41a329c..."
|
|
||||||
|
|
||||||
mrf = SHA256(bytes_imagen)
|
|
||||||
→ Identidad de ARCHIVO
|
|
||||||
→ URL: https://tzrtech.org/{mrf}.png
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Endpoints
|
|
||||||
|
|
||||||
### Dump completo
|
|
||||||
```
|
|
||||||
GET https://tzrtech.org/api/index.json
|
|
||||||
```
|
|
||||||
|
|
||||||
Retorna array con todos los tags.
|
|
||||||
|
|
||||||
### Tag por h_maestro
|
|
||||||
```
|
|
||||||
GET https://tzrtech.org/api/tags/{h_maestro}
|
|
||||||
```
|
|
||||||
|
|
||||||
Ejemplo:
|
|
||||||
```bash
|
|
||||||
curl https://tzrtech.org/api/tags/335350bb41a329c31acac43197232850bc6828ec76650291ce230446e520774f
|
|
||||||
```
|
|
||||||
|
|
||||||
### Búsqueda y filtro
|
|
||||||
```
|
|
||||||
GET https://tzrtech.org/api/tags?grupo={grupo}
|
|
||||||
GET https://tzrtech.org/api/tags?q={query}
|
|
||||||
GET https://tzrtech.org/api/tags?grupo={grupo}&q={query}
|
|
||||||
```
|
|
||||||
|
|
||||||
Ejemplos:
|
|
||||||
```bash
|
|
||||||
# Todas las etiquetas hst
|
|
||||||
curl "https://tzrtech.org/api/tags?grupo=hst"
|
|
||||||
|
|
||||||
# Buscar "finanzas"
|
|
||||||
curl "https://tzrtech.org/api/tags?q=finanzas"
|
|
||||||
|
|
||||||
# Buscar "yoga" en vsn
|
|
||||||
curl "https://tzrtech.org/api/tags?grupo=vsn&q=yoga"
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Formato de Respuesta
|
|
||||||
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"ref": "abk",
|
|
||||||
"h_maestro": "335350bb41a329c31acac43197232850bc6828ec76650291ce230446e520774f",
|
|
||||||
"mrf": "ed456cb46151edb46106863d16b4e4cade7af8e33d8c7cae8489125aee76ffa7",
|
|
||||||
"nombre_es": "audiolibro",
|
|
||||||
"nombre_en": "audiobook",
|
|
||||||
"grupo": "hst",
|
|
||||||
"imagen_url": "https://tzrtech.org/ed456cb46151edb46106863d16b4e4cade7af8e33d8c7cae8489125aee76ffa7.png"
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Uso desde DECK
|
|
||||||
|
|
||||||
```python
|
|
||||||
import requests
|
|
||||||
|
|
||||||
# Obtener tag por h_maestro
|
|
||||||
def get_tag(h_maestro: str) -> dict:
|
|
||||||
response = requests.get(f"https://tzrtech.org/api/tags/{h_maestro}")
|
|
||||||
return response.json()
|
|
||||||
|
|
||||||
# Buscar tags por grupo
|
|
||||||
def search_tags(grupo: str = None, query: str = None) -> list:
|
|
||||||
params = {}
|
|
||||||
if grupo:
|
|
||||||
params["grupo"] = grupo
|
|
||||||
if query:
|
|
||||||
params["q"] = query
|
|
||||||
response = requests.get("https://tzrtech.org/api/tags", params=params)
|
|
||||||
return response.json()
|
|
||||||
|
|
||||||
# Calcular h_maestro localmente (para verificación)
|
|
||||||
import hashlib
|
|
||||||
|
|
||||||
def calculate_h_maestro(grupo: str, ref: str) -> str:
|
|
||||||
return hashlib.sha256(f"{grupo}:{ref}".encode()).hexdigest()
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Uso en S-CONTRACT
|
|
||||||
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"context": {
|
|
||||||
"tags": {
|
|
||||||
"hst": ["335350bb41a329c...", "a7b3c9d4e5f6..."],
|
|
||||||
"hsu": [],
|
|
||||||
"emp": ["empresa_h_maestro..."],
|
|
||||||
"pjt": ["proyecto_h_maestro..."]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Subdominios Semánticos
|
|
||||||
|
|
||||||
Las imágenes también son accesibles via subdominio:
|
|
||||||
|
|
||||||
```
|
|
||||||
https://hst_finanzas.tzrtech.org → redirect → /{mrf}.png
|
|
||||||
https://spe_aluminio.tzrtech.org → redirect → /{mrf}.png
|
|
||||||
```
|
|
||||||
|
|
||||||
Formato: `{grupo}_{ref_normalizado}.tzrtech.org`
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Historial
|
|
||||||
|
|
||||||
| Versión | Fecha | Cambios |
|
|
||||||
|---------|-------|---------|
|
|
||||||
| 1.0 | 2025-12 | MVP imágenes con mrf |
|
|
||||||
| 2.0 | 2025-12-18 | Añadido h_maestro, API endpoints, limpieza duplicados |
|
|
||||||
@@ -1,538 +0,0 @@
|
|||||||
# IMPLEMENTACION - Wrappers y Ejemplos
|
|
||||||
**Version:** 2.0
|
|
||||||
**Dependencia:** `S-CONTRACT.md`
|
|
||||||
**Estado:** Referencia
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
# 1. Introduccion
|
|
||||||
|
|
||||||
Este documento proporciona implementaciones de referencia para:
|
|
||||||
- Construccion de requests S-CONTRACT
|
|
||||||
- Validacion de responses
|
|
||||||
- Integracion con Alfred (n8n)
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
# 2. ContractBuilder (Python)
|
|
||||||
|
|
||||||
## 2.1 Clase Principal
|
|
||||||
|
|
||||||
```python
|
|
||||||
import uuid
|
|
||||||
import hashlib
|
|
||||||
from datetime import datetime, timezone
|
|
||||||
from typing import Optional, Dict, Any, List
|
|
||||||
from dataclasses import dataclass, asdict
|
|
||||||
|
|
||||||
@dataclass
|
|
||||||
class ContractBuilder:
|
|
||||||
"""
|
|
||||||
Constructor de requests S-CONTRACT v2.0.
|
|
||||||
"""
|
|
||||||
contract_version: str = "2.0"
|
|
||||||
profile: str = "FULL"
|
|
||||||
|
|
||||||
# Envelope
|
|
||||||
trace_id: Optional[str] = None
|
|
||||||
parent_trace_id: Optional[str] = None
|
|
||||||
step_id: Optional[str] = None
|
|
||||||
step_index: int = 1
|
|
||||||
total_steps: Optional[int] = None
|
|
||||||
idempotency_key: Optional[str] = None
|
|
||||||
ttl_ms: int = 30000
|
|
||||||
provider_timeout_ms: int = 15000
|
|
||||||
|
|
||||||
# Routing
|
|
||||||
module: Optional[str] = None
|
|
||||||
module_version: Optional[str] = None
|
|
||||||
provider_preference: Optional[List[str]] = None
|
|
||||||
fallback_chain: Optional[List[str]] = None
|
|
||||||
max_fallback_level: int = 2
|
|
||||||
|
|
||||||
# Context
|
|
||||||
lang: str = "es"
|
|
||||||
mode: str = "strict"
|
|
||||||
pii_filter: bool = False
|
|
||||||
bandera_id: Optional[str] = None
|
|
||||||
player_id: Optional[str] = None
|
|
||||||
method_hash: Optional[str] = None
|
|
||||||
human_readable: Optional[str] = None
|
|
||||||
|
|
||||||
# Payload
|
|
||||||
payload_type: str = "text"
|
|
||||||
encoding: str = "utf-8"
|
|
||||||
content: Optional[str] = None
|
|
||||||
content_hash: Optional[str] = None
|
|
||||||
schema_expected: Optional[str] = None
|
|
||||||
|
|
||||||
# Batch
|
|
||||||
is_batch: bool = False
|
|
||||||
batch_id: Optional[str] = None
|
|
||||||
item_index: Optional[int] = None
|
|
||||||
items_total: int = 1
|
|
||||||
batch_mode: str = "SEQUENTIAL"
|
|
||||||
|
|
||||||
# Storage
|
|
||||||
input_location: str = "internal"
|
|
||||||
input_ref: Optional[str] = None
|
|
||||||
output_location: str = "internal"
|
|
||||||
output_ref: Optional[str] = None
|
|
||||||
persist_intermediate: bool = True
|
|
||||||
retention_days: int = 30
|
|
||||||
|
|
||||||
# Security
|
|
||||||
encryption_profile: str = "NONE"
|
|
||||||
data_sensitivity: str = "LOW"
|
|
||||||
key_vault_ref: Optional[str] = None
|
|
||||||
pii_detected: bool = False
|
|
||||||
gdpr_relevant: bool = False
|
|
||||||
|
|
||||||
def __post_init__(self):
|
|
||||||
# Auto-generate IDs if not provided
|
|
||||||
if not self.trace_id:
|
|
||||||
self.trace_id = str(uuid.uuid4())
|
|
||||||
if not self.step_id:
|
|
||||||
self.step_id = str(uuid.uuid4())
|
|
||||||
|
|
||||||
def set_content(self, content: str) -> 'ContractBuilder':
|
|
||||||
"""Sets content and auto-calculates hash."""
|
|
||||||
self.content = content
|
|
||||||
self.content_hash = hashlib.sha256(content.encode('utf-8')).hexdigest()
|
|
||||||
if not self.idempotency_key:
|
|
||||||
self.idempotency_key = self.content_hash
|
|
||||||
return self
|
|
||||||
|
|
||||||
def for_module(self, module: str, version: str = "1.0") -> 'ContractBuilder':
|
|
||||||
"""Sets target module."""
|
|
||||||
self.module = module
|
|
||||||
self.module_version = version
|
|
||||||
return self
|
|
||||||
|
|
||||||
def with_fallback(self, chain: List[str]) -> 'ContractBuilder':
|
|
||||||
"""Sets fallback chain."""
|
|
||||||
self.fallback_chain = chain
|
|
||||||
return self
|
|
||||||
|
|
||||||
def lite(self) -> 'ContractBuilder':
|
|
||||||
"""Switches to LITE profile."""
|
|
||||||
self.profile = "LITE"
|
|
||||||
return self
|
|
||||||
|
|
||||||
def build(self) -> Dict[str, Any]:
|
|
||||||
"""Builds the final request dictionary."""
|
|
||||||
timestamp = datetime.now(timezone.utc).isoformat()
|
|
||||||
|
|
||||||
if self.profile == "LITE":
|
|
||||||
return self._build_lite(timestamp)
|
|
||||||
return self._build_full(timestamp)
|
|
||||||
|
|
||||||
def _build_lite(self, timestamp: str) -> Dict[str, Any]:
|
|
||||||
return {
|
|
||||||
"contract_version": self.contract_version,
|
|
||||||
"profile": "LITE",
|
|
||||||
"envelope": {
|
|
||||||
"trace_id": self.trace_id,
|
|
||||||
"idempotency_key": self.idempotency_key
|
|
||||||
},
|
|
||||||
"routing": {
|
|
||||||
"module": self.module
|
|
||||||
},
|
|
||||||
"context": {
|
|
||||||
"lang": self.lang,
|
|
||||||
"mode": self.mode
|
|
||||||
},
|
|
||||||
"payload": {
|
|
||||||
"type": self.payload_type,
|
|
||||||
"encoding": self.encoding,
|
|
||||||
"content": self.content
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
def _build_full(self, timestamp: str) -> Dict[str, Any]:
|
|
||||||
return {
|
|
||||||
"contract_version": self.contract_version,
|
|
||||||
"profile": "FULL",
|
|
||||||
"envelope": {
|
|
||||||
"trace_id": self.trace_id,
|
|
||||||
"parent_trace_id": self.parent_trace_id,
|
|
||||||
"step_id": self.step_id,
|
|
||||||
"step_index": self.step_index,
|
|
||||||
"total_steps": self.total_steps,
|
|
||||||
"idempotency_key": self.idempotency_key,
|
|
||||||
"timestamp_init": timestamp,
|
|
||||||
"ttl_ms": self.ttl_ms,
|
|
||||||
"provider_timeout_ms": self.provider_timeout_ms
|
|
||||||
},
|
|
||||||
"routing": {
|
|
||||||
"module": self.module,
|
|
||||||
"version": self.module_version,
|
|
||||||
"provider_preference": self.provider_preference,
|
|
||||||
"fallback_chain": self.fallback_chain,
|
|
||||||
"max_fallback_level": self.max_fallback_level
|
|
||||||
},
|
|
||||||
"context": {
|
|
||||||
"lang": self.lang,
|
|
||||||
"mode": self.mode,
|
|
||||||
"pii_filter": self.pii_filter,
|
|
||||||
"bandera_id": self.bandera_id,
|
|
||||||
"player_id": self.player_id,
|
|
||||||
"method_hash": self.method_hash,
|
|
||||||
"human_readable": self.human_readable
|
|
||||||
},
|
|
||||||
"payload": {
|
|
||||||
"type": self.payload_type,
|
|
||||||
"encoding": self.encoding,
|
|
||||||
"content": self.content,
|
|
||||||
"content_hash": self.content_hash,
|
|
||||||
"schema_expected": self.schema_expected
|
|
||||||
},
|
|
||||||
"batch": {
|
|
||||||
"is_batch": self.is_batch,
|
|
||||||
"batch_id": self.batch_id,
|
|
||||||
"item_index": self.item_index,
|
|
||||||
"items_total": self.items_total,
|
|
||||||
"batch_mode": self.batch_mode
|
|
||||||
},
|
|
||||||
"storage": {
|
|
||||||
"input_location": self.input_location,
|
|
||||||
"input_ref": self.input_ref,
|
|
||||||
"output_location": self.output_location,
|
|
||||||
"output_ref": self.output_ref,
|
|
||||||
"persist_intermediate": self.persist_intermediate,
|
|
||||||
"retention_days": self.retention_days
|
|
||||||
},
|
|
||||||
"security": {
|
|
||||||
"encryption_profile": self.encryption_profile,
|
|
||||||
"data_sensitivity": self.data_sensitivity,
|
|
||||||
"key_vault_ref": self.key_vault_ref,
|
|
||||||
"pii_detected": self.pii_detected,
|
|
||||||
"gdpr_relevant": self.gdpr_relevant
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
## 2.2 Uso
|
|
||||||
|
|
||||||
```python
|
|
||||||
# Request LITE para clasificacion
|
|
||||||
request = (
|
|
||||||
ContractBuilder()
|
|
||||||
.for_module("CLASSIFIER")
|
|
||||||
.set_content("Factura de Telefonica por 45.99 EUR")
|
|
||||||
.lite()
|
|
||||||
.build()
|
|
||||||
)
|
|
||||||
|
|
||||||
# Request FULL con fallback
|
|
||||||
request = (
|
|
||||||
ContractBuilder()
|
|
||||||
.for_module("OCR_CORE", "1.0")
|
|
||||||
.set_content(base64_image)
|
|
||||||
.with_fallback(["OCR_LOCAL", "OCR_GROQ", "OCR_OPENAI"])
|
|
||||||
.build()
|
|
||||||
)
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
# 3. ResponseValidator (Python)
|
|
||||||
|
|
||||||
```python
|
|
||||||
from typing import Dict, Any, List, Optional
|
|
||||||
from dataclasses import dataclass
|
|
||||||
|
|
||||||
@dataclass
|
|
||||||
class ValidationResult:
|
|
||||||
valid: bool
|
|
||||||
errors: List[str]
|
|
||||||
warnings: List[str]
|
|
||||||
|
|
||||||
class ResponseValidator:
|
|
||||||
"""
|
|
||||||
Validador de responses S-CONTRACT v2.0.
|
|
||||||
"""
|
|
||||||
|
|
||||||
VALID_STATUS_CODES = {'SUCCESS', 'PARTIAL', 'ERROR', 'TIMEOUT', 'FALLBACK'}
|
|
||||||
REQUIRED_LITE = {'contract_version', 'profile', 'envelope', 'status', 'result'}
|
|
||||||
REQUIRED_FULL = REQUIRED_LITE | {'quality', 'metadata', 'storage', 'audit'}
|
|
||||||
|
|
||||||
def validate(self, response: Dict[str, Any]) -> ValidationResult:
|
|
||||||
errors = []
|
|
||||||
warnings = []
|
|
||||||
|
|
||||||
# Contract version
|
|
||||||
if response.get('contract_version') != '2.0':
|
|
||||||
warnings.append(f"Contract version mismatch: {response.get('contract_version')}")
|
|
||||||
|
|
||||||
# Profile
|
|
||||||
profile = response.get('profile', 'FULL')
|
|
||||||
required = self.REQUIRED_LITE if profile == 'LITE' else self.REQUIRED_FULL
|
|
||||||
|
|
||||||
# Required fields
|
|
||||||
for field in required:
|
|
||||||
if field not in response:
|
|
||||||
errors.append(f"Missing required field: {field}")
|
|
||||||
|
|
||||||
# Status validation
|
|
||||||
status = response.get('status', {})
|
|
||||||
if isinstance(status, dict):
|
|
||||||
code = status.get('code')
|
|
||||||
if code not in self.VALID_STATUS_CODES:
|
|
||||||
errors.append(f"Invalid status code: {code}")
|
|
||||||
else:
|
|
||||||
errors.append("Status must be an object with 'code' field")
|
|
||||||
|
|
||||||
# Envelope validation
|
|
||||||
envelope = response.get('envelope', {})
|
|
||||||
if not envelope.get('trace_id'):
|
|
||||||
errors.append("Missing trace_id in envelope")
|
|
||||||
if not envelope.get('idempotency_key'):
|
|
||||||
warnings.append("Missing idempotency_key in envelope")
|
|
||||||
|
|
||||||
# Quality validation (FULL profile)
|
|
||||||
if profile == 'FULL':
|
|
||||||
quality = response.get('quality', {})
|
|
||||||
confidence = quality.get('confidence')
|
|
||||||
if confidence is not None:
|
|
||||||
if not (0 <= confidence <= 1):
|
|
||||||
errors.append(f"Confidence out of range: {confidence}")
|
|
||||||
|
|
||||||
return ValidationResult(
|
|
||||||
valid=len(errors) == 0,
|
|
||||||
errors=errors,
|
|
||||||
warnings=warnings
|
|
||||||
)
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
# 4. Integracion n8n (Alfred)
|
|
||||||
|
|
||||||
## 4.1 Nodo Function: Build Request
|
|
||||||
|
|
||||||
```javascript
|
|
||||||
// n8n Function node: Build S-CONTRACT Request
|
|
||||||
|
|
||||||
const crypto = require('crypto');
|
|
||||||
|
|
||||||
function buildRequest(input, module, profile = 'LITE') {
|
|
||||||
const content = typeof input === 'string' ? input : JSON.stringify(input);
|
|
||||||
const contentHash = crypto.createHash('sha256').update(content).digest('hex');
|
|
||||||
const traceId = $node.data.trace_id || crypto.randomUUID();
|
|
||||||
|
|
||||||
if (profile === 'LITE') {
|
|
||||||
return {
|
|
||||||
contract_version: '2.0',
|
|
||||||
profile: 'LITE',
|
|
||||||
envelope: {
|
|
||||||
trace_id: traceId,
|
|
||||||
idempotency_key: contentHash
|
|
||||||
},
|
|
||||||
routing: { module },
|
|
||||||
context: { lang: 'es', mode: 'strict' },
|
|
||||||
payload: {
|
|
||||||
type: 'text',
|
|
||||||
encoding: 'utf-8',
|
|
||||||
content: content
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
return {
|
|
||||||
contract_version: '2.0',
|
|
||||||
profile: 'FULL',
|
|
||||||
envelope: {
|
|
||||||
trace_id: traceId,
|
|
||||||
step_id: crypto.randomUUID(),
|
|
||||||
step_index: 1,
|
|
||||||
idempotency_key: contentHash,
|
|
||||||
timestamp_init: new Date().toISOString(),
|
|
||||||
ttl_ms: 30000
|
|
||||||
},
|
|
||||||
routing: {
|
|
||||||
module,
|
|
||||||
fallback_chain: $node.data.fallback_chain || []
|
|
||||||
},
|
|
||||||
context: {
|
|
||||||
lang: 'es',
|
|
||||||
mode: 'strict',
|
|
||||||
player_id: $node.data.player_id,
|
|
||||||
human_readable: $node.data.description
|
|
||||||
},
|
|
||||||
payload: {
|
|
||||||
type: 'text',
|
|
||||||
encoding: 'utf-8',
|
|
||||||
content: content,
|
|
||||||
content_hash: contentHash
|
|
||||||
},
|
|
||||||
batch: { is_batch: false, items_total: 1 },
|
|
||||||
storage: {
|
|
||||||
input_location: 'internal',
|
|
||||||
persist_intermediate: true,
|
|
||||||
retention_days: 30
|
|
||||||
},
|
|
||||||
security: {
|
|
||||||
encryption_profile: 'NONE',
|
|
||||||
data_sensitivity: 'LOW'
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
// Usage
|
|
||||||
const request = buildRequest(
|
|
||||||
$input.first().json.text,
|
|
||||||
'CLASSIFIER',
|
|
||||||
'LITE'
|
|
||||||
);
|
|
||||||
|
|
||||||
return [{ json: request }];
|
|
||||||
```
|
|
||||||
|
|
||||||
## 4.2 Nodo Function: Validate Response
|
|
||||||
|
|
||||||
```javascript
|
|
||||||
// n8n Function node: Validate S-CONTRACT Response
|
|
||||||
|
|
||||||
function validateResponse(response) {
|
|
||||||
const errors = [];
|
|
||||||
const warnings = [];
|
|
||||||
|
|
||||||
// Status check
|
|
||||||
const status = response.status?.code;
|
|
||||||
const validStatus = ['SUCCESS', 'PARTIAL', 'ERROR', 'TIMEOUT', 'FALLBACK'];
|
|
||||||
|
|
||||||
if (!validStatus.includes(status)) {
|
|
||||||
errors.push(`Invalid status: ${status}`);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Envelope check
|
|
||||||
if (!response.envelope?.trace_id) {
|
|
||||||
errors.push('Missing trace_id');
|
|
||||||
}
|
|
||||||
|
|
||||||
// Result check
|
|
||||||
if (status === 'SUCCESS' && !response.result?.data) {
|
|
||||||
warnings.push('SUCCESS status but no result data');
|
|
||||||
}
|
|
||||||
|
|
||||||
return {
|
|
||||||
valid: errors.length === 0,
|
|
||||||
errors,
|
|
||||||
warnings,
|
|
||||||
trace_id: response.envelope?.trace_id,
|
|
||||||
status: status,
|
|
||||||
result: response.result?.data
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
const validation = validateResponse($input.first().json);
|
|
||||||
|
|
||||||
if (!validation.valid) {
|
|
||||||
throw new Error(`Contract validation failed: ${validation.errors.join(', ')}`);
|
|
||||||
}
|
|
||||||
|
|
||||||
return [{ json: validation }];
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
# 5. Logging a SYS_LOG
|
|
||||||
|
|
||||||
```python
|
|
||||||
import psycopg2
|
|
||||||
from psycopg2.extras import Json
|
|
||||||
from datetime import datetime
|
|
||||||
|
|
||||||
def log_to_syslog(conn, request: dict, response: dict):
|
|
||||||
"""
|
|
||||||
Inserta registro en SYS_LOG.
|
|
||||||
"""
|
|
||||||
envelope = request.get('envelope', {})
|
|
||||||
r_envelope = response.get('envelope', {})
|
|
||||||
status = response.get('status', {})
|
|
||||||
quality = response.get('quality', {})
|
|
||||||
metadata = response.get('metadata', {})
|
|
||||||
|
|
||||||
sql = """
|
|
||||||
INSERT INTO SYS_LOG (
|
|
||||||
trace_id, step_id, idempotency_key,
|
|
||||||
step_index, step_type, profile,
|
|
||||||
timestamp_created, timestamp_started, timestamp_completed,
|
|
||||||
duration_ms,
|
|
||||||
module_name, module_version,
|
|
||||||
provider_used, fallback_level, model_id,
|
|
||||||
status_code,
|
|
||||||
input_hash, input_ref, input_type,
|
|
||||||
output_hash, output_ref,
|
|
||||||
confidence, coverage,
|
|
||||||
tokens_input, tokens_output,
|
|
||||||
cost_units
|
|
||||||
) VALUES (
|
|
||||||
%(trace_id)s, %(step_id)s, %(idempotency_key)s,
|
|
||||||
%(step_index)s, %(step_type)s, %(profile)s,
|
|
||||||
%(timestamp_created)s, %(timestamp_started)s, %(timestamp_completed)s,
|
|
||||||
%(duration_ms)s,
|
|
||||||
%(module_name)s, %(module_version)s,
|
|
||||||
%(provider_used)s, %(fallback_level)s, %(model_id)s,
|
|
||||||
%(status_code)s,
|
|
||||||
%(input_hash)s, %(input_ref)s, %(input_type)s,
|
|
||||||
%(output_hash)s, %(output_ref)s,
|
|
||||||
%(confidence)s, %(coverage)s,
|
|
||||||
%(tokens_input)s, %(tokens_output)s,
|
|
||||||
%(cost_units)s
|
|
||||||
)
|
|
||||||
"""
|
|
||||||
|
|
||||||
params = {
|
|
||||||
'trace_id': envelope.get('trace_id'),
|
|
||||||
'step_id': envelope.get('step_id'),
|
|
||||||
'idempotency_key': envelope.get('idempotency_key'),
|
|
||||||
'step_index': envelope.get('step_index', 1),
|
|
||||||
'step_type': 'TRANSFORM',
|
|
||||||
'profile': request.get('profile', 'FULL'),
|
|
||||||
'timestamp_created': datetime.now(),
|
|
||||||
'timestamp_started': envelope.get('timestamp_init'),
|
|
||||||
'timestamp_completed': r_envelope.get('timestamp_end'),
|
|
||||||
'duration_ms': metadata.get('processing_ms'),
|
|
||||||
'module_name': request.get('routing', {}).get('module'),
|
|
||||||
'module_version': request.get('routing', {}).get('version'),
|
|
||||||
'provider_used': status.get('provider_used'),
|
|
||||||
'fallback_level': status.get('fallback_level_used', 0),
|
|
||||||
'model_id': metadata.get('model_id'),
|
|
||||||
'status_code': status.get('code'),
|
|
||||||
'input_hash': request.get('payload', {}).get('content_hash'),
|
|
||||||
'input_ref': request.get('storage', {}).get('input_ref'),
|
|
||||||
'input_type': request.get('payload', {}).get('type'),
|
|
||||||
'output_hash': response.get('storage', {}).get('output_hash'),
|
|
||||||
'output_ref': response.get('storage', {}).get('output_ref'),
|
|
||||||
'confidence': quality.get('confidence'),
|
|
||||||
'coverage': quality.get('coverage'),
|
|
||||||
'tokens_input': quality.get('tokens_input'),
|
|
||||||
'tokens_output': quality.get('tokens_output'),
|
|
||||||
'cost_units': metadata.get('cost_units')
|
|
||||||
}
|
|
||||||
|
|
||||||
with conn.cursor() as cur:
|
|
||||||
cur.execute(sql, params)
|
|
||||||
conn.commit()
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
# 6. Checklist de Implementacion
|
|
||||||
|
|
||||||
- [ ] Implementar ContractBuilder en Python
|
|
||||||
- [ ] Implementar ContractBuilder en JavaScript (n8n)
|
|
||||||
- [ ] Implementar ResponseValidator
|
|
||||||
- [ ] Crear funcion log_to_syslog
|
|
||||||
- [ ] Configurar nodos n8n con templates
|
|
||||||
- [ ] Probar flujo completo LITE
|
|
||||||
- [ ] Probar flujo completo FULL
|
|
||||||
- [ ] Probar fallback chain
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
**Fin del Documento IMPLEMENTACION - Version 2.0**
|
|
||||||
|
|
||||||
*Sistema GRACE - "Alfred Decide, GRACE Transforma"*
|
|
||||||
@@ -1,595 +0,0 @@
|
|||||||
# 07c. KEY VAULT Y CRIPTOGRAFÍA
|
|
||||||
**Manual de Arquitectura Técnica — Documento 07c**
|
|
||||||
**Versión:** 1.2
|
|
||||||
**Dependencia:** `S-CONTRACT.md`
|
|
||||||
**Estado:** Enterprise Standard
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
# C.1 Introducción
|
|
||||||
|
|
||||||
El Key Vault es el **tercer espacio de almacenamiento** del ecosistema, separado de:
|
|
||||||
- **Libro Mayor (SFE)**: Datos de negocio
|
|
||||||
- **Almacenamiento de archivos**: Hostinger/S3
|
|
||||||
- **Key Vault**: Llaves, credenciales y secretos
|
|
||||||
|
|
||||||
```
|
|
||||||
┌─────────────────────────────────────────────────────────────────┐
|
|
||||||
│ PRINCIPIO DE SEPARACIÓN │
|
|
||||||
│ │
|
|
||||||
│ "Las llaves nunca viajan con los datos que protegen" │
|
|
||||||
└─────────────────────────────────────────────────────────────────┘
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
# C.2 Arquitectura del Key Vault
|
|
||||||
|
|
||||||
## C.2.1 Componentes
|
|
||||||
|
|
||||||
```
|
|
||||||
┌─────────────────────────────────────────────────────────────────┐
|
|
||||||
│ KEY VAULT │
|
|
||||||
├─────────────────────────────────────────────────────────────────┤
|
|
||||||
│ │
|
|
||||||
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
|
|
||||||
│ │ SECRETS │ │ KEYS │ │ CERTS │ │
|
|
||||||
│ │ STORE │ │ STORE │ │ STORE │ │
|
|
||||||
│ └─────────────┘ └─────────────┘ └─────────────┘ │
|
|
||||||
│ │ │ │ │
|
|
||||||
│ └──────────────────┼──────────────────┘ │
|
|
||||||
│ │ │
|
|
||||||
│ ┌──────┴──────┐ │
|
|
||||||
│ │ ACCESS │ │
|
|
||||||
│ │ CONTROL │ │
|
|
||||||
│ └──────┬──────┘ │
|
|
||||||
│ │ │
|
|
||||||
│ ┌──────┴──────┐ │
|
|
||||||
│ │ AUDIT LOG │ │
|
|
||||||
│ └─────────────┘ │
|
|
||||||
│ │
|
|
||||||
└─────────────────────────────────────────────────────────────────┘
|
|
||||||
```
|
|
||||||
|
|
||||||
## C.2.2 Tipos de Secretos
|
|
||||||
|
|
||||||
| Tipo | Descripción | Ejemplo | Rotación |
|
|
||||||
|------|-------------|---------|----------|
|
|
||||||
| **API_KEY** | Llaves de APIs externas | OpenRouter, Groq | 90 días |
|
|
||||||
| **ENCRYPTION_KEY** | Llaves de cifrado de datos | AES-256 keys | 365 días |
|
|
||||||
| **DB_CREDENTIAL** | Credenciales de bases de datos | NocoDB, PostgreSQL | 30 días |
|
|
||||||
| **SERVICE_TOKEN** | Tokens de servicios internos | n8n, Nextcloud | 7 días |
|
|
||||||
| **USER_SECRET** | Secretos específicos de usuario | OAuth tokens | Variable |
|
|
||||||
| **CERTIFICATE** | Certificados TLS/mTLS | SSL certs | 90 días |
|
|
||||||
| **SIGNING_KEY** | Llaves de firma digital | JWT signing | 180 días |
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
# C.3 Modelo de Datos
|
|
||||||
|
|
||||||
## C.3.1 Tabla VAULT_SECRETS
|
|
||||||
|
|
||||||
```sql
|
|
||||||
CREATE TABLE VAULT_SECRETS (
|
|
||||||
-- ═══════════════════════════════════════════════════════════
|
|
||||||
-- IDENTIFICACIÓN
|
|
||||||
-- ═══════════════════════════════════════════════════════════
|
|
||||||
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
||||||
secret_id VARCHAR(100) UNIQUE NOT NULL,
|
|
||||||
version INTEGER DEFAULT 1,
|
|
||||||
|
|
||||||
-- ═══════════════════════════════════════════════════════════
|
|
||||||
-- CLASIFICACIÓN
|
|
||||||
-- ═══════════════════════════════════════════════════════════
|
|
||||||
secret_type VARCHAR(50) NOT NULL,
|
|
||||||
category VARCHAR(50),
|
|
||||||
tags VARCHAR(50)[],
|
|
||||||
|
|
||||||
-- ═══════════════════════════════════════════════════════════
|
|
||||||
-- VALOR (CIFRADO)
|
|
||||||
-- ═══════════════════════════════════════════════════════════
|
|
||||||
encrypted_value BYTEA NOT NULL,
|
|
||||||
encryption_algorithm VARCHAR(50) DEFAULT 'AES-256-GCM',
|
|
||||||
key_encryption_key_id VARCHAR(100),
|
|
||||||
nonce BYTEA,
|
|
||||||
|
|
||||||
-- ═══════════════════════════════════════════════════════════
|
|
||||||
-- METADATA
|
|
||||||
-- ═══════════════════════════════════════════════════════════
|
|
||||||
description TEXT,
|
|
||||||
owner_id UUID,
|
|
||||||
owner_type VARCHAR(50),
|
|
||||||
|
|
||||||
-- ═══════════════════════════════════════════════════════════
|
|
||||||
-- CICLO DE VIDA
|
|
||||||
-- ═══════════════════════════════════════════════════════════
|
|
||||||
status VARCHAR(20) DEFAULT 'ACTIVE',
|
|
||||||
created_at TIMESTAMPTZ DEFAULT NOW(),
|
|
||||||
updated_at TIMESTAMPTZ DEFAULT NOW(),
|
|
||||||
expires_at TIMESTAMPTZ,
|
|
||||||
last_rotated_at TIMESTAMPTZ,
|
|
||||||
rotation_interval_days INTEGER,
|
|
||||||
|
|
||||||
-- ═══════════════════════════════════════════════════════════
|
|
||||||
-- ACCESO
|
|
||||||
-- ═══════════════════════════════════════════════════════════
|
|
||||||
access_policy JSONB DEFAULT '{}',
|
|
||||||
allowed_modules VARCHAR(50)[],
|
|
||||||
allowed_players UUID[],
|
|
||||||
|
|
||||||
-- ═══════════════════════════════════════════════════════════
|
|
||||||
-- AUDITORÍA
|
|
||||||
-- ═══════════════════════════════════════════════════════════
|
|
||||||
access_count INTEGER DEFAULT 0,
|
|
||||||
last_accessed_at TIMESTAMPTZ,
|
|
||||||
last_accessed_by VARCHAR(100),
|
|
||||||
|
|
||||||
-- ═══════════════════════════════════════════════════════════
|
|
||||||
-- CONSTRAINTS
|
|
||||||
-- ═══════════════════════════════════════════════════════════
|
|
||||||
CONSTRAINT valid_status CHECK (
|
|
||||||
status IN ('ACTIVE', 'DISABLED', 'EXPIRED', 'ROTATING', 'DELETED')
|
|
||||||
),
|
|
||||||
CONSTRAINT valid_type CHECK (
|
|
||||||
secret_type IN ('API_KEY', 'ENCRYPTION_KEY', 'DB_CREDENTIAL',
|
|
||||||
'SERVICE_TOKEN', 'USER_SECRET', 'CERTIFICATE', 'SIGNING_KEY')
|
|
||||||
)
|
|
||||||
);
|
|
||||||
|
|
||||||
-- Índices
|
|
||||||
CREATE INDEX idx_vault_secret_id ON VAULT_SECRETS(secret_id);
|
|
||||||
CREATE INDEX idx_vault_type ON VAULT_SECRETS(secret_type);
|
|
||||||
CREATE INDEX idx_vault_status ON VAULT_SECRETS(status);
|
|
||||||
CREATE INDEX idx_vault_expires ON VAULT_SECRETS(expires_at) WHERE expires_at IS NOT NULL;
|
|
||||||
CREATE INDEX idx_vault_owner ON VAULT_SECRETS(owner_id);
|
|
||||||
```
|
|
||||||
|
|
||||||
## C.3.2 Tabla VAULT_ACCESS_LOG
|
|
||||||
|
|
||||||
```sql
|
|
||||||
CREATE TABLE VAULT_ACCESS_LOG (
|
|
||||||
-- ═══════════════════════════════════════════════════════════
|
|
||||||
-- IDENTIFICACIÓN
|
|
||||||
-- ═══════════════════════════════════════════════════════════
|
|
||||||
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
||||||
|
|
||||||
-- ═══════════════════════════════════════════════════════════
|
|
||||||
-- SECRETO ACCEDIDO
|
|
||||||
-- ═══════════════════════════════════════════════════════════
|
|
||||||
secret_id VARCHAR(100) NOT NULL,
|
|
||||||
secret_version INTEGER,
|
|
||||||
|
|
||||||
-- ═══════════════════════════════════════════════════════════
|
|
||||||
-- CONTEXTO DE ACCESO
|
|
||||||
-- ═══════════════════════════════════════════════════════════
|
|
||||||
trace_id UUID,
|
|
||||||
step_id UUID,
|
|
||||||
module_name VARCHAR(50),
|
|
||||||
operation VARCHAR(50) NOT NULL,
|
|
||||||
|
|
||||||
-- ═══════════════════════════════════════════════════════════
|
|
||||||
-- ACTOR
|
|
||||||
-- ═══════════════════════════════════════════════════════════
|
|
||||||
accessor_type VARCHAR(50) NOT NULL,
|
|
||||||
accessor_id VARCHAR(100) NOT NULL,
|
|
||||||
accessor_ip INET,
|
|
||||||
|
|
||||||
-- ═══════════════════════════════════════════════════════════
|
|
||||||
-- RESULTADO
|
|
||||||
-- ═══════════════════════════════════════════════════════════
|
|
||||||
status VARCHAR(20) NOT NULL,
|
|
||||||
error_code VARCHAR(50),
|
|
||||||
error_message TEXT,
|
|
||||||
|
|
||||||
-- ═══════════════════════════════════════════════════════════
|
|
||||||
-- TEMPORALIDAD
|
|
||||||
-- ═══════════════════════════════════════════════════════════
|
|
||||||
timestamp TIMESTAMPTZ DEFAULT NOW(),
|
|
||||||
duration_ms INTEGER,
|
|
||||||
|
|
||||||
-- ═══════════════════════════════════════════════════════════
|
|
||||||
-- SEGURIDAD
|
|
||||||
-- ═══════════════════════════════════════════════════════════
|
|
||||||
encryption_profile VARCHAR(20),
|
|
||||||
purpose TEXT,
|
|
||||||
|
|
||||||
-- ═══════════════════════════════════════════════════════════
|
|
||||||
-- CONSTRAINTS
|
|
||||||
-- ═══════════════════════════════════════════════════════════
|
|
||||||
CONSTRAINT valid_operation CHECK (
|
|
||||||
operation IN ('READ', 'CREATE', 'UPDATE', 'DELETE', 'ROTATE',
|
|
||||||
'ENABLE', 'DISABLE', 'LIST', 'DECRYPT', 'ENCRYPT')
|
|
||||||
),
|
|
||||||
CONSTRAINT valid_access_status CHECK (
|
|
||||||
status IN ('SUCCESS', 'DENIED', 'ERROR', 'EXPIRED', 'NOT_FOUND')
|
|
||||||
),
|
|
||||||
CONSTRAINT valid_accessor CHECK (
|
|
||||||
accessor_type IN ('MODULE', 'PLAYER', 'SYSTEM', 'ADMIN', 'SERVICE')
|
|
||||||
)
|
|
||||||
);
|
|
||||||
|
|
||||||
-- Índices para auditoría eficiente
|
|
||||||
CREATE INDEX idx_vault_log_secret ON VAULT_ACCESS_LOG(secret_id);
|
|
||||||
CREATE INDEX idx_vault_log_trace ON VAULT_ACCESS_LOG(trace_id) WHERE trace_id IS NOT NULL;
|
|
||||||
CREATE INDEX idx_vault_log_timestamp ON VAULT_ACCESS_LOG(timestamp);
|
|
||||||
CREATE INDEX idx_vault_log_accessor ON VAULT_ACCESS_LOG(accessor_type, accessor_id);
|
|
||||||
CREATE INDEX idx_vault_log_denied ON VAULT_ACCESS_LOG(status, timestamp)
|
|
||||||
WHERE status = 'DENIED';
|
|
||||||
```
|
|
||||||
|
|
||||||
## C.3.3 Tabla VAULT_ENCRYPTION_KEYS (KEK)
|
|
||||||
|
|
||||||
```sql
|
|
||||||
CREATE TABLE VAULT_ENCRYPTION_KEYS (
|
|
||||||
-- ═══════════════════════════════════════════════════════════
|
|
||||||
-- IDENTIFICACIÓN
|
|
||||||
-- ═══════════════════════════════════════════════════════════
|
|
||||||
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
||||||
key_id VARCHAR(100) UNIQUE NOT NULL,
|
|
||||||
version INTEGER DEFAULT 1,
|
|
||||||
|
|
||||||
-- ═══════════════════════════════════════════════════════════
|
|
||||||
-- PROPIEDADES
|
|
||||||
-- ═══════════════════════════════════════════════════════════
|
|
||||||
algorithm VARCHAR(50) NOT NULL DEFAULT 'AES-256-GCM',
|
|
||||||
key_size_bits INTEGER NOT NULL DEFAULT 256,
|
|
||||||
purpose VARCHAR(50) NOT NULL,
|
|
||||||
|
|
||||||
-- ═══════════════════════════════════════════════════════════
|
|
||||||
-- VALOR (protegido por Master Key externa)
|
|
||||||
-- ═══════════════════════════════════════════════════════════
|
|
||||||
encrypted_key_material BYTEA NOT NULL,
|
|
||||||
master_key_ref VARCHAR(100),
|
|
||||||
|
|
||||||
-- ═══════════════════════════════════════════════════════════
|
|
||||||
-- CICLO DE VIDA
|
|
||||||
-- ═══════════════════════════════════════════════════════════
|
|
||||||
status VARCHAR(20) DEFAULT 'ACTIVE',
|
|
||||||
created_at TIMESTAMPTZ DEFAULT NOW(),
|
|
||||||
activated_at TIMESTAMPTZ,
|
|
||||||
expires_at TIMESTAMPTZ,
|
|
||||||
deactivated_at TIMESTAMPTZ,
|
|
||||||
|
|
||||||
-- ═══════════════════════════════════════════════════════════
|
|
||||||
-- CONSTRAINTS
|
|
||||||
-- ═══════════════════════════════════════════════════════════
|
|
||||||
CONSTRAINT valid_kek_status CHECK (
|
|
||||||
status IN ('PENDING', 'ACTIVE', 'DEACTIVATED', 'DESTROYED')
|
|
||||||
),
|
|
||||||
CONSTRAINT valid_purpose CHECK (
|
|
||||||
purpose IN ('DATA_ENCRYPTION', 'SECRET_ENCRYPTION', 'SIGNING', 'KEY_WRAPPING')
|
|
||||||
)
|
|
||||||
);
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
# C.4 Perfiles de Cifrado
|
|
||||||
|
|
||||||
## C.4.1 Perfil NONE
|
|
||||||
|
|
||||||
```yaml
|
|
||||||
profile: NONE
|
|
||||||
description: "Sin cifrado gestionado por el sistema"
|
|
||||||
transport: TLS 1.3 (obligatorio)
|
|
||||||
at_rest: Sin cifrar
|
|
||||||
use_cases:
|
|
||||||
- Datos públicos
|
|
||||||
- Logs técnicos no sensibles
|
|
||||||
- Métricas de rendimiento
|
|
||||||
key_vault: No requerido
|
|
||||||
```
|
|
||||||
|
|
||||||
## C.4.2 Perfil E2E_BASIC
|
|
||||||
|
|
||||||
```yaml
|
|
||||||
profile: E2E_BASIC
|
|
||||||
description: "Cifrado estándar para datos internos"
|
|
||||||
transport: TLS 1.3
|
|
||||||
at_rest:
|
|
||||||
algorithm: AES-256-GCM
|
|
||||||
key_derivation: PBKDF2-SHA256
|
|
||||||
key_rotation: Anual
|
|
||||||
use_cases:
|
|
||||||
- Documentos internos
|
|
||||||
- Emails corporativos
|
|
||||||
- Datos de configuración
|
|
||||||
key_vault:
|
|
||||||
required: true
|
|
||||||
key_type: ENCRYPTION_KEY
|
|
||||||
access_policy: module_based
|
|
||||||
```
|
|
||||||
|
|
||||||
## C.4.3 Perfil E2E_STRICT
|
|
||||||
|
|
||||||
```yaml
|
|
||||||
profile: E2E_STRICT
|
|
||||||
description: "Cifrado fuerte para datos sensibles"
|
|
||||||
transport: mTLS (mutual TLS)
|
|
||||||
at_rest:
|
|
||||||
algorithm: AES-256-GCM
|
|
||||||
key_derivation: Argon2id
|
|
||||||
key_rotation: Trimestral
|
|
||||||
envelope_encryption: true
|
|
||||||
additional:
|
|
||||||
- PII masking antes de procesar
|
|
||||||
- Audit logging obligatorio
|
|
||||||
- Zero-knowledge donde sea posible
|
|
||||||
use_cases:
|
|
||||||
- PII (datos personales)
|
|
||||||
- Datos financieros
|
|
||||||
- Información médica
|
|
||||||
- Biometría
|
|
||||||
key_vault:
|
|
||||||
required: true
|
|
||||||
key_type: ENCRYPTION_KEY
|
|
||||||
access_policy: per_record
|
|
||||||
key_isolation: true
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
# C.5 Operaciones del Key Vault
|
|
||||||
|
|
||||||
## C.5.1 URIs del Key Vault
|
|
||||||
|
|
||||||
El contrato común usa referencias URI al Key Vault:
|
|
||||||
|
|
||||||
```
|
|
||||||
kv://production/encryption/player_abc123
|
|
||||||
kv://production/api-keys/openrouter
|
|
||||||
kv://staging/certificates/mtls-client
|
|
||||||
```
|
|
||||||
|
|
||||||
Formato:
|
|
||||||
```
|
|
||||||
kv://{environment}/{category}/{secret_id}
|
|
||||||
```
|
|
||||||
|
|
||||||
## C.5.2 Integración con el Contrato
|
|
||||||
|
|
||||||
En el request:
|
|
||||||
```json
|
|
||||||
"security": {
|
|
||||||
"encryption_profile": "E2E_STRICT",
|
|
||||||
"data_sensitivity": "HIGH",
|
|
||||||
"key_vault_ref": "kv://production/encryption/player_abc123"
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
Alfred al procesar:
|
|
||||||
1. Extrae `key_vault_ref`
|
|
||||||
2. Solicita la llave al Key Vault (pasando `trace_id`)
|
|
||||||
3. Descifra el payload si viene cifrado
|
|
||||||
4. Procesa con GRACE
|
|
||||||
5. Cifra el resultado con la misma llave (o una derivada)
|
|
||||||
6. Almacena resultado cifrado
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
# C.6 Flujo de Cifrado End-to-End
|
|
||||||
|
|
||||||
## C.6.1 Envelope Encryption
|
|
||||||
|
|
||||||
```
|
|
||||||
┌─────────────────────────────────────────────────────────────────┐
|
|
||||||
│ ENVELOPE ENCRYPTION │
|
|
||||||
├─────────────────────────────────────────────────────────────────┤
|
|
||||||
│ │
|
|
||||||
│ ┌─────────────┐ │
|
|
||||||
│ │ Plaintext │ │
|
|
||||||
│ │ Data │ │
|
|
||||||
│ └──────┬──────┘ │
|
|
||||||
│ │ │
|
|
||||||
│ ▼ │
|
|
||||||
│ ┌─────────────┐ ┌─────────────┐ │
|
|
||||||
│ │ Data │◄───│ DEK │ (Data Encryption Key) │
|
|
||||||
│ │ Encrypted │ │ (efímera) │ │
|
|
||||||
│ └──────┬──────┘ └──────┬──────┘ │
|
|
||||||
│ │ │ │
|
|
||||||
│ │ ▼ │
|
|
||||||
│ │ ┌─────────────┐ ┌─────────────┐ │
|
|
||||||
│ │ │ DEK │◄───│ KEK │ │
|
|
||||||
│ │ │ Encrypted │ │ (Key Vault) │ │
|
|
||||||
│ │ └──────┬──────┘ └─────────────┘ │
|
|
||||||
│ │ │ │
|
|
||||||
│ ▼ ▼ │
|
|
||||||
│ ┌──────────────────────────────────────┐ │
|
|
||||||
│ │ Stored Package: │ │
|
|
||||||
│ │ - encrypted_data │ │
|
|
||||||
│ │ - encrypted_dek │ │
|
|
||||||
│ │ - kek_id │ │
|
|
||||||
│ │ - nonce │ │
|
|
||||||
│ │ - algorithm │ │
|
|
||||||
│ └──────────────────────────────────────┘ │
|
|
||||||
│ │
|
|
||||||
└─────────────────────────────────────────────────────────────────┘
|
|
||||||
```
|
|
||||||
|
|
||||||
## C.6.2 Implementación Python
|
|
||||||
|
|
||||||
```python
|
|
||||||
import os
|
|
||||||
from cryptography.hazmat.primitives.ciphers.aead import AESGCM
|
|
||||||
import base64
|
|
||||||
|
|
||||||
class EnvelopeEncryption:
|
|
||||||
"""Implementa envelope encryption para E2E_STRICT."""
|
|
||||||
|
|
||||||
def __init__(self, key_vault_client):
|
|
||||||
self.vault = key_vault_client
|
|
||||||
|
|
||||||
async def encrypt(self, plaintext: bytes, kek_id: str) -> dict:
|
|
||||||
"""Cifra datos usando envelope encryption."""
|
|
||||||
# 1. Generar DEK efímera
|
|
||||||
dek = os.urandom(32)
|
|
||||||
data_nonce = os.urandom(12)
|
|
||||||
|
|
||||||
# 2. Cifrar datos con DEK
|
|
||||||
aesgcm = AESGCM(dek)
|
|
||||||
encrypted_data = aesgcm.encrypt(data_nonce, plaintext, None)
|
|
||||||
|
|
||||||
# 3. Obtener KEK y cifrar DEK
|
|
||||||
kek = await self.vault.get_secret(kek_id)
|
|
||||||
dek_nonce = os.urandom(12)
|
|
||||||
kek_aesgcm = AESGCM(kek)
|
|
||||||
encrypted_dek = kek_aesgcm.encrypt(dek_nonce, dek, kek_id.encode())
|
|
||||||
|
|
||||||
return {
|
|
||||||
"encrypted_data": base64.b64encode(encrypted_data).decode(),
|
|
||||||
"encrypted_dek": base64.b64encode(encrypted_dek).decode(),
|
|
||||||
"data_nonce": base64.b64encode(data_nonce).decode(),
|
|
||||||
"dek_nonce": base64.b64encode(dek_nonce).decode(),
|
|
||||||
"kek_id": kek_id,
|
|
||||||
"algorithm": "AES-256-GCM"
|
|
||||||
}
|
|
||||||
|
|
||||||
async def decrypt(self, package: dict) -> bytes:
|
|
||||||
"""Descifra datos usando envelope encryption."""
|
|
||||||
# 1. Obtener KEK
|
|
||||||
kek = await self.vault.get_secret(package["kek_id"])
|
|
||||||
|
|
||||||
# 2. Descifrar DEK
|
|
||||||
kek_aesgcm = AESGCM(kek)
|
|
||||||
dek = kek_aesgcm.decrypt(
|
|
||||||
base64.b64decode(package["dek_nonce"]),
|
|
||||||
base64.b64decode(package["encrypted_dek"]),
|
|
||||||
package["kek_id"].encode()
|
|
||||||
)
|
|
||||||
|
|
||||||
# 3. Descifrar datos
|
|
||||||
aesgcm = AESGCM(dek)
|
|
||||||
return aesgcm.decrypt(
|
|
||||||
base64.b64decode(package["data_nonce"]),
|
|
||||||
base64.b64decode(package["encrypted_data"]),
|
|
||||||
None
|
|
||||||
)
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
# C.7 Gestión de Llaves
|
|
||||||
|
|
||||||
## C.7.1 Jerarquía de Llaves
|
|
||||||
|
|
||||||
```
|
|
||||||
┌─────────────────────────────────────────────────────────────────┐
|
|
||||||
│ JERARQUÍA DE LLAVES │
|
|
||||||
├─────────────────────────────────────────────────────────────────┤
|
|
||||||
│ │
|
|
||||||
│ ┌─────────────────────────────────────────────────────────┐ │
|
|
||||||
│ │ MASTER KEY (MK) │ │
|
|
||||||
│ │ Almacenada fuera del sistema │ │
|
|
||||||
│ │ (HSM / KMS externo / Variable de entorno) │ │
|
|
||||||
│ └────────────────────────┬────────────────────────────────┘ │
|
|
||||||
│ │ │
|
|
||||||
│ ┌───────────────┼───────────────┐ │
|
|
||||||
│ ▼ ▼ ▼ │
|
|
||||||
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
|
|
||||||
│ │ KEK-DATA │ │ KEK-SECRETS │ │ KEK-SIGNING │ │
|
|
||||||
│ └──────┬──────┘ └──────┬──────┘ └──────┬──────┘ │
|
|
||||||
│ │ │ │ │
|
|
||||||
│ ▼ ▼ ▼ │
|
|
||||||
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
|
|
||||||
│ │ DEK-1..n │ │ API Keys │ │ JWT Keys │ │
|
|
||||||
│ └─────────────┘ └─────────────┘ └─────────────┘ │
|
|
||||||
│ │
|
|
||||||
└─────────────────────────────────────────────────────────────────┘
|
|
||||||
```
|
|
||||||
|
|
||||||
## C.7.2 Política de Rotación
|
|
||||||
|
|
||||||
| Tipo de Llave | Rotación | Período de Gracia | Automatizable |
|
|
||||||
|---------------|----------|-------------------|---------------|
|
|
||||||
| Master Key | Anual | 30 días | No (manual) |
|
|
||||||
| KEK | Semestral | 14 días | Sí |
|
|
||||||
| DEK | Por sesión | N/A | Automático |
|
|
||||||
| API Keys | 90 días | 7 días | Sí |
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
# C.8 Control de Acceso
|
|
||||||
|
|
||||||
## C.8.1 Políticas de Acceso
|
|
||||||
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"secret_id": "openrouter-api-key",
|
|
||||||
"access_policy": {
|
|
||||||
"type": "MODULE_BASED",
|
|
||||||
"rules": [
|
|
||||||
{
|
|
||||||
"principal_type": "MODULE",
|
|
||||||
"principals": ["CLASSIFIER", "SUMMARIZER", "OCR_CORE"],
|
|
||||||
"operations": ["READ"],
|
|
||||||
"conditions": {
|
|
||||||
"require_trace_id": true
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"principal_type": "ADMIN",
|
|
||||||
"principals": ["admin@tzzr.pro"],
|
|
||||||
"operations": ["READ", "UPDATE", "ROTATE", "DELETE"],
|
|
||||||
"conditions": {
|
|
||||||
"require_mfa": true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"default_deny": true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
# C.9 Integración con SENTINEL
|
|
||||||
|
|
||||||
## C.9.1 Reglas de Auditoría
|
|
||||||
|
|
||||||
```yaml
|
|
||||||
rules:
|
|
||||||
KV-001:
|
|
||||||
name: "Accesos denegados excesivos"
|
|
||||||
severity: HIGH
|
|
||||||
condition: "denied_count_1h > 5 per accessor"
|
|
||||||
action: ALERT_SECURITY
|
|
||||||
|
|
||||||
KV-002:
|
|
||||||
name: "Secreto próximo a expirar"
|
|
||||||
severity: MEDIUM
|
|
||||||
condition: "expires_at < NOW() + 7 days"
|
|
||||||
action: NOTIFY_ADMIN
|
|
||||||
|
|
||||||
KV-003:
|
|
||||||
name: "Rotación pendiente"
|
|
||||||
severity: MEDIUM
|
|
||||||
condition: "last_rotated_at < NOW() - rotation_interval"
|
|
||||||
action: SCHEDULE_ROTATION
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
# C.10 Checklist de Implementación
|
|
||||||
|
|
||||||
## Infraestructura:
|
|
||||||
- [ ] Crear tablas VAULT_SECRETS, VAULT_ACCESS_LOG, VAULT_ENCRYPTION_KEYS
|
|
||||||
- [ ] Configurar Master Key (variable de entorno o KMS)
|
|
||||||
- [ ] Generar KEKs iniciales
|
|
||||||
- [ ] Configurar backup automático
|
|
||||||
|
|
||||||
## Integración:
|
|
||||||
- [ ] Implementar cliente Key Vault
|
|
||||||
- [ ] Integrar con ContractBuilder
|
|
||||||
- [ ] Implementar envelope encryption
|
|
||||||
|
|
||||||
## Seguridad:
|
|
||||||
- [ ] Configurar políticas de acceso
|
|
||||||
- [ ] Habilitar logging de accesos
|
|
||||||
- [ ] Configurar alertas SENTINEL
|
|
||||||
- [ ] Establecer rotación automática
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
**Fin del Documento 07c — Key Vault y Criptografía**
|
|
||||||
|
|
||||||
*Referencia: `S-CONTRACT.md` v1.2*
|
|
||||||
@@ -1,528 +0,0 @@
|
|||||||
# Lecciones para CORP
|
|
||||||
|
|
||||||
**Documento de onboarding para empresas del ecosistema TZZR**
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Leccion 1: Que es CORP
|
|
||||||
|
|
||||||
CORP es una **empresa** dentro del ecosistema TZZR. No es un sistema, es un tenant.
|
|
||||||
|
|
||||||
```
|
|
||||||
ECOSISTEMA TZZR
|
|
||||||
├── DECK → Orquestador para HUMANOS
|
|
||||||
├── CORP → Orquestador para EMPRESAS (tu)
|
|
||||||
├── GRACE → Procesamiento IA
|
|
||||||
├── THE FACTORY → Procesamiento documental
|
|
||||||
├── PENNY → Asistente de voz (solo humanos)
|
|
||||||
└── HST → Sistema de etiquetas
|
|
||||||
```
|
|
||||||
|
|
||||||
### Lo que puedes hacer
|
|
||||||
- Llamar a GRACE (clasificar, extraer, resumir)
|
|
||||||
- Llamar a THE FACTORY (procesar documentos)
|
|
||||||
- Usar etiquetas HST para organizar
|
|
||||||
|
|
||||||
### Lo que NO puedes hacer
|
|
||||||
- Llamar a PENNY (es solo para humanos via DECK)
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Leccion 2: S-CONTRACT
|
|
||||||
|
|
||||||
Toda comunicacion con GRACE y THE FACTORY usa el formato **S-CONTRACT v2.1**.
|
|
||||||
|
|
||||||
### Request minimo (perfil LITE)
|
|
||||||
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"contract_version": "2.1",
|
|
||||||
"profile": "LITE",
|
|
||||||
"envelope": {
|
|
||||||
"trace_id": "uuid-unico-por-request",
|
|
||||||
"idempotency_key": "sha256-del-contenido-64-chars"
|
|
||||||
},
|
|
||||||
"routing": {
|
|
||||||
"module": "CLASSIFIER"
|
|
||||||
},
|
|
||||||
"context": {
|
|
||||||
"lang": "es"
|
|
||||||
},
|
|
||||||
"payload": {
|
|
||||||
"type": "text",
|
|
||||||
"encoding": "utf-8",
|
|
||||||
"content": "Factura de Telefonica por 45.99 EUR"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
### Request completo (perfil FULL)
|
|
||||||
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"contract_version": "2.1",
|
|
||||||
"profile": "FULL",
|
|
||||||
"envelope": {
|
|
||||||
"trace_id": "550e8400-e29b-41d4-a716-446655440000",
|
|
||||||
"idempotency_key": "a1b2c3d4e5f6789012345678901234567890123456789012345678901234",
|
|
||||||
"step_id": "660e8400-e29b-41d4-a716-446655440001",
|
|
||||||
"step_index": 1,
|
|
||||||
"timestamp_init": "2025-12-18T10:00:00Z",
|
|
||||||
"ttl_ms": 30000
|
|
||||||
},
|
|
||||||
"routing": {
|
|
||||||
"module": "CLASSIFIER",
|
|
||||||
"version": "1.0",
|
|
||||||
"provider_preference": ["groq", "openai"],
|
|
||||||
"max_fallback_level": 2
|
|
||||||
},
|
|
||||||
"context": {
|
|
||||||
"lang": "es",
|
|
||||||
"mode": "strict",
|
|
||||||
"pii_filter": false,
|
|
||||||
"system_instruction": "Clasifica el documento segun categoria contable.",
|
|
||||||
"datasets": [
|
|
||||||
{
|
|
||||||
"codigo": "DS_CATEGORIAS_CORP",
|
|
||||||
"tipo": "vocabulary",
|
|
||||||
"contenido": "GASTO_OPERATIVO, GASTO_FINANCIERO, INGRESO_VENTA..."
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"tags": {
|
|
||||||
"hst": ["335350bb41a329c..."],
|
|
||||||
"hsu": [],
|
|
||||||
"emp": ["h_maestro_de_corp..."],
|
|
||||||
"pjt": ["h_maestro_proyecto..."]
|
|
||||||
},
|
|
||||||
"ambiente": {
|
|
||||||
"timezone": "Europe/Madrid",
|
|
||||||
"locale": "es-ES",
|
|
||||||
"currency": "EUR",
|
|
||||||
"session_type": "batch"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"payload": {
|
|
||||||
"type": "document",
|
|
||||||
"encoding": "url",
|
|
||||||
"content": "https://storage.corp.example/factura-001.pdf"
|
|
||||||
},
|
|
||||||
"deployment": {
|
|
||||||
"mode": "SEMI",
|
|
||||||
"tier_preference": ["SELF_HOSTED", "EXTERNAL"]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
### Response esperada
|
|
||||||
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"contract_version": "2.1",
|
|
||||||
"profile": "FULL",
|
|
||||||
"envelope": {
|
|
||||||
"trace_id": "550e8400-e29b-41d4-a716-446655440000",
|
|
||||||
"idempotency_key": "a1b2c3d4e5f6...",
|
|
||||||
"timestamp_end": "2025-12-18T10:00:03Z"
|
|
||||||
},
|
|
||||||
"status": {
|
|
||||||
"code": "SUCCESS",
|
|
||||||
"provider_used": "groq",
|
|
||||||
"deployment_used": {
|
|
||||||
"mode": "SEMI",
|
|
||||||
"tier_used": "EXTERNAL",
|
|
||||||
"provider_used": "groq"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"result": {
|
|
||||||
"schema": "classifier_output_v1",
|
|
||||||
"data": {
|
|
||||||
"category": "GASTO_OPERATIVO",
|
|
||||||
"subcategory": "TELECOMUNICACIONES",
|
|
||||||
"confidence": 0.94
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"quality": {
|
|
||||||
"confidence": 0.94,
|
|
||||||
"coverage": 1.0
|
|
||||||
},
|
|
||||||
"metadata": {
|
|
||||||
"model_id": "llama-3.3-70b",
|
|
||||||
"processing_ms": 1234
|
|
||||||
},
|
|
||||||
"errors": []
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
### Status codes
|
|
||||||
|
|
||||||
| Code | Significado |
|
|
||||||
|------|-------------|
|
|
||||||
| `SUCCESS` | Todo bien |
|
|
||||||
| `PARTIAL` | Resultado incompleto pero usable |
|
|
||||||
| `ERROR` | Fallo |
|
|
||||||
| `TIMEOUT` | Excedio tiempo |
|
|
||||||
| `FALLBACK` | Exito con proveedor alternativo |
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Leccion 3: HST (Sistema de Etiquetas)
|
|
||||||
|
|
||||||
HST es el sistema de etiquetas que da coherencia semantica a todo.
|
|
||||||
|
|
||||||
### API disponible
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Todas las etiquetas
|
|
||||||
GET https://tzrtech.org/api/index.json
|
|
||||||
|
|
||||||
# Tag especifico
|
|
||||||
GET https://tzrtech.org/api/tags/{h_maestro}
|
|
||||||
|
|
||||||
# Buscar
|
|
||||||
GET https://tzrtech.org/api/tags?grupo=hst
|
|
||||||
GET https://tzrtech.org/api/tags?q=finanzas
|
|
||||||
```
|
|
||||||
|
|
||||||
### Grupos de etiquetas
|
|
||||||
|
|
||||||
| Grupo | Descripcion | Quien las crea |
|
|
||||||
|-------|-------------|----------------|
|
|
||||||
| `hst` | Sistema | tzrtech.org (sync) |
|
|
||||||
| `emp` | Empresa | Tu (CORP) |
|
|
||||||
| `hsu` | Usuario | Tu (para tus usuarios) |
|
|
||||||
| `pjt` | Proyecto | Tu (para tus proyectos) |
|
|
||||||
|
|
||||||
### Sistema dual de hashes
|
|
||||||
|
|
||||||
```
|
|
||||||
h_maestro = SHA256(grupo || ':' || ref)
|
|
||||||
→ Identifica semanticamente (para S-CONTRACT)
|
|
||||||
→ Ejemplo: SHA256("hst:finanzas") = "a7b3c9..."
|
|
||||||
|
|
||||||
mrf = SHA256(bytes_imagen)
|
|
||||||
→ Identifica el archivo de imagen
|
|
||||||
→ URL: https://tzrtech.org/{mrf}.png
|
|
||||||
```
|
|
||||||
|
|
||||||
### Calcular h_maestro
|
|
||||||
|
|
||||||
```python
|
|
||||||
import hashlib
|
|
||||||
|
|
||||||
def h_maestro(grupo: str, ref: str) -> str:
|
|
||||||
return hashlib.sha256(f"{grupo}:{ref}".encode()).hexdigest()
|
|
||||||
|
|
||||||
# Ejemplo
|
|
||||||
h = h_maestro("emp", "corp") # Tu identidad como empresa
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Leccion 4: Modulos disponibles
|
|
||||||
|
|
||||||
### GRACE (18 modulos)
|
|
||||||
|
|
||||||
| Modulo | Familia | Uso |
|
|
||||||
|--------|---------|-----|
|
|
||||||
| `CLASSIFIER` | SEMANTICA | Clasificar documentos |
|
|
||||||
| `SUMMARIZER` | SEMANTICA | Resumir textos |
|
|
||||||
| `TASK_EXTRACTOR` | SEMANTICA | Extraer tareas de texto |
|
|
||||||
| `FIELD_EXTRACTOR` | UTILIDADES | Extraer campos estructurados |
|
|
||||||
| `OCR_CORE` | VISION | Extraer texto de imagenes |
|
|
||||||
| `ASR_ENGINE` | VOZ | Transcribir audio |
|
|
||||||
| `EMBEDDINGS` | SEMANTICA | Vectorizar texto |
|
|
||||||
| `SIMILARITY` | SEMANTICA | Comparar textos |
|
|
||||||
| `LANG_DETECT` | UTILIDADES | Detectar idioma |
|
|
||||||
|
|
||||||
### THE FACTORY
|
|
||||||
|
|
||||||
Procesamiento documental:
|
|
||||||
- PDF a texto
|
|
||||||
- Extraccion estructurada
|
|
||||||
- OCR de facturas
|
|
||||||
- Consolidacion de documentos
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Leccion 5: Tablas PostgreSQL
|
|
||||||
|
|
||||||
Usaras las mismas estructuras que DECK. Schemas en `contratos-comunes/db-schemas/`.
|
|
||||||
|
|
||||||
### Orden de aplicacion
|
|
||||||
|
|
||||||
```bash
|
|
||||||
psql -f 00_types.sql # Tipos enumerados
|
|
||||||
psql -f 01_hst_tags.sql # Etiquetas HST
|
|
||||||
psql -f 02_task_manager.sql # Proyectos y tareas
|
|
||||||
psql -f 03_work_log.sql # Log de archivos
|
|
||||||
psql -f 04_ai_context.sql # Contextos IA
|
|
||||||
psql -f 05_ai_requests.sql # Log de requests
|
|
||||||
```
|
|
||||||
|
|
||||||
### Tabla: hst_tags (tus etiquetas propias)
|
|
||||||
|
|
||||||
```sql
|
|
||||||
CREATE TABLE hst_tags (
|
|
||||||
id SERIAL PRIMARY KEY,
|
|
||||||
h_maestro VARCHAR(64) UNIQUE NOT NULL, -- SHA256(grupo:ref)
|
|
||||||
ref VARCHAR(50) NOT NULL, -- Codigo corto
|
|
||||||
mrf VARCHAR(64), -- Hash de imagen (opcional)
|
|
||||||
nombre VARCHAR(100) NOT NULL,
|
|
||||||
nombre_en VARCHAR(100),
|
|
||||||
grupo hst_grupo NOT NULL, -- emp, hsu, pjt
|
|
||||||
padre_h_maestro VARCHAR(64), -- Jerarquia
|
|
||||||
activo BOOLEAN DEFAULT true
|
|
||||||
);
|
|
||||||
|
|
||||||
-- Tus etiquetas de empresa
|
|
||||||
INSERT INTO hst_tags (h_maestro, ref, nombre, grupo) VALUES
|
|
||||||
(generate_h_maestro('emp', 'corp'), 'corp', 'CORP', 'emp');
|
|
||||||
|
|
||||||
-- Tus proyectos
|
|
||||||
INSERT INTO hst_tags (h_maestro, ref, nombre, grupo) VALUES
|
|
||||||
(generate_h_maestro('pjt', 'contabilidad_2025'), 'contabilidad_2025', 'Contabilidad 2025', 'pjt');
|
|
||||||
```
|
|
||||||
|
|
||||||
### Tabla: s_contract_contexts (contextos reutilizables)
|
|
||||||
|
|
||||||
```sql
|
|
||||||
-- Crear un contexto para tus operaciones
|
|
||||||
INSERT INTO s_contract_contexts (codigo, nombre, context, deployment) VALUES
|
|
||||||
(
|
|
||||||
'CTX_CORP_FACTURAS',
|
|
||||||
'Contexto para facturas CORP',
|
|
||||||
'{
|
|
||||||
"lang": "es",
|
|
||||||
"mode": "strict",
|
|
||||||
"system_instruction": "Procesa facturas de CORP. Extrae: proveedor, fecha, importe, IVA.",
|
|
||||||
"datasets": [],
|
|
||||||
"tags": {"hst": [], "hsu": [], "emp": ["h_corp..."], "pjt": []},
|
|
||||||
"ambiente": {"timezone": "Europe/Madrid", "locale": "es-ES", "currency": "EUR"}
|
|
||||||
}'::jsonb,
|
|
||||||
'{"mode": "SEMI", "tier_preference": ["EXTERNAL", "SELF_HOSTED"]}'::jsonb
|
|
||||||
);
|
|
||||||
```
|
|
||||||
|
|
||||||
### Tabla: ai_requests (log de tus requests)
|
|
||||||
|
|
||||||
```sql
|
|
||||||
-- Registrar cada request que hagas
|
|
||||||
INSERT INTO ai_requests (
|
|
||||||
trace_id, service, module, context_codigo, status
|
|
||||||
) VALUES (
|
|
||||||
'tu-trace-id',
|
|
||||||
'grace',
|
|
||||||
'CLASSIFIER',
|
|
||||||
'CTX_CORP_FACTURAS',
|
|
||||||
'pending'
|
|
||||||
);
|
|
||||||
|
|
||||||
-- Actualizar cuando termine
|
|
||||||
UPDATE ai_requests SET
|
|
||||||
status = 'success',
|
|
||||||
tier_used = 'EXTERNAL',
|
|
||||||
provider_used = 'groq',
|
|
||||||
latency_ms = 1234,
|
|
||||||
completed_at = NOW()
|
|
||||||
WHERE trace_id = 'tu-trace-id';
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Leccion 6: Tu libro diario (MST + BCK)
|
|
||||||
|
|
||||||
Como empresa, llevas un libro diario con dos partes:
|
|
||||||
|
|
||||||
### MST (Master)
|
|
||||||
|
|
||||||
Registro principal de operaciones:
|
|
||||||
|
|
||||||
```sql
|
|
||||||
CREATE TABLE corp_libro_mst (
|
|
||||||
id SERIAL PRIMARY KEY,
|
|
||||||
fecha DATE NOT NULL,
|
|
||||||
tipo VARCHAR(50) NOT NULL, -- ingreso, gasto, asiento
|
|
||||||
concepto TEXT NOT NULL,
|
|
||||||
importe DECIMAL(12,2),
|
|
||||||
moneda VARCHAR(3) DEFAULT 'EUR',
|
|
||||||
|
|
||||||
-- Referencias
|
|
||||||
documento_ref TEXT, -- URL al documento
|
|
||||||
h_maestro_categoria VARCHAR(64), -- Etiqueta HST
|
|
||||||
|
|
||||||
-- Trazabilidad
|
|
||||||
trace_id VARCHAR(36), -- Si vino de IA
|
|
||||||
procesado_por VARCHAR(50), -- grace, factory, manual
|
|
||||||
|
|
||||||
created_at TIMESTAMP DEFAULT NOW()
|
|
||||||
);
|
|
||||||
```
|
|
||||||
|
|
||||||
### BCK (Backup/Auditoria)
|
|
||||||
|
|
||||||
Copia de respaldo con historial:
|
|
||||||
|
|
||||||
```sql
|
|
||||||
CREATE TABLE corp_libro_bck (
|
|
||||||
id SERIAL PRIMARY KEY,
|
|
||||||
mst_id INTEGER REFERENCES corp_libro_mst(id),
|
|
||||||
version INTEGER DEFAULT 1,
|
|
||||||
datos_anteriores JSONB,
|
|
||||||
datos_nuevos JSONB,
|
|
||||||
motivo_cambio TEXT,
|
|
||||||
created_at TIMESTAMP DEFAULT NOW()
|
|
||||||
);
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Leccion 7: Flujo de trabajo
|
|
||||||
|
|
||||||
```
|
|
||||||
1. Llega documento (factura PDF)
|
|
||||||
│
|
|
||||||
▼
|
|
||||||
2. Almacenas en bandeja de entrada
|
|
||||||
│
|
|
||||||
▼
|
|
||||||
3. Construyes S-CONTRACT
|
|
||||||
{routing: {module: "FIELD_EXTRACTOR"}, ...}
|
|
||||||
│
|
|
||||||
▼
|
|
||||||
4. Envias a GRACE o THE FACTORY
|
|
||||||
│
|
|
||||||
▼
|
|
||||||
5. Recibes respuesta estructurada
|
|
||||||
{result: {data: {proveedor: "X", importe: 100}}}
|
|
||||||
│
|
|
||||||
▼
|
|
||||||
6. Registras en tu libro MST
|
|
||||||
│
|
|
||||||
▼
|
|
||||||
7. Etiquetas con HST
|
|
||||||
│
|
|
||||||
▼
|
|
||||||
8. Mueves de bandeja a procesado
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Leccion 8: Codigo Python base
|
|
||||||
|
|
||||||
```python
|
|
||||||
import hashlib
|
|
||||||
import uuid
|
|
||||||
import requests
|
|
||||||
from datetime import datetime, timezone
|
|
||||||
|
|
||||||
class CorpClient:
|
|
||||||
def __init__(self, grace_url: str, factory_url: str):
|
|
||||||
self.grace_url = grace_url
|
|
||||||
self.factory_url = factory_url
|
|
||||||
self.emp_h_maestro = self.h_maestro("emp", "corp")
|
|
||||||
|
|
||||||
def h_maestro(self, grupo: str, ref: str) -> str:
|
|
||||||
return hashlib.sha256(f"{grupo}:{ref}".encode()).hexdigest()
|
|
||||||
|
|
||||||
def idempotency_key(self, content: str) -> str:
|
|
||||||
return hashlib.sha256(content.encode()).hexdigest()
|
|
||||||
|
|
||||||
def build_request(
|
|
||||||
self,
|
|
||||||
module: str,
|
|
||||||
content: str,
|
|
||||||
content_type: str = "text",
|
|
||||||
system_instruction: str = None,
|
|
||||||
tags_pjt: list = None
|
|
||||||
) -> dict:
|
|
||||||
return {
|
|
||||||
"contract_version": "2.1",
|
|
||||||
"profile": "FULL",
|
|
||||||
"envelope": {
|
|
||||||
"trace_id": str(uuid.uuid4()),
|
|
||||||
"idempotency_key": self.idempotency_key(content),
|
|
||||||
"timestamp_init": datetime.now(timezone.utc).isoformat()
|
|
||||||
},
|
|
||||||
"routing": {
|
|
||||||
"module": module
|
|
||||||
},
|
|
||||||
"context": {
|
|
||||||
"lang": "es",
|
|
||||||
"mode": "strict",
|
|
||||||
"system_instruction": system_instruction,
|
|
||||||
"tags": {
|
|
||||||
"hst": [],
|
|
||||||
"hsu": [],
|
|
||||||
"emp": [self.emp_h_maestro],
|
|
||||||
"pjt": tags_pjt or []
|
|
||||||
},
|
|
||||||
"ambiente": {
|
|
||||||
"timezone": "Europe/Madrid",
|
|
||||||
"locale": "es-ES",
|
|
||||||
"currency": "EUR",
|
|
||||||
"session_type": "batch"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"payload": {
|
|
||||||
"type": content_type,
|
|
||||||
"encoding": "utf-8" if content_type == "text" else "url",
|
|
||||||
"content": content
|
|
||||||
},
|
|
||||||
"deployment": {
|
|
||||||
"mode": "SEMI",
|
|
||||||
"tier_preference": ["EXTERNAL", "SELF_HOSTED"]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
def classify(self, text: str) -> dict:
|
|
||||||
request = self.build_request(
|
|
||||||
module="CLASSIFIER",
|
|
||||||
content=text,
|
|
||||||
system_instruction="Clasifica el documento: FACTURA, CONTRATO, EMAIL, OTRO"
|
|
||||||
)
|
|
||||||
response = requests.post(f"{self.grace_url}/process", json=request)
|
|
||||||
return response.json()
|
|
||||||
|
|
||||||
def extract_fields(self, document_url: str, fields: list) -> dict:
|
|
||||||
request = self.build_request(
|
|
||||||
module="FIELD_EXTRACTOR",
|
|
||||||
content=document_url,
|
|
||||||
content_type="document",
|
|
||||||
system_instruction=f"Extrae estos campos: {', '.join(fields)}"
|
|
||||||
)
|
|
||||||
response = requests.post(f"{self.factory_url}/process", json=request)
|
|
||||||
return response.json()
|
|
||||||
|
|
||||||
|
|
||||||
# Uso
|
|
||||||
client = CorpClient(
|
|
||||||
grace_url="https://grace.api.example",
|
|
||||||
factory_url="https://factory.api.example"
|
|
||||||
)
|
|
||||||
|
|
||||||
# Clasificar un texto
|
|
||||||
result = client.classify("Factura de Movistar por 45.99 EUR")
|
|
||||||
print(result["result"]["data"]["category"])
|
|
||||||
|
|
||||||
# Extraer campos de un PDF
|
|
||||||
result = client.extract_fields(
|
|
||||||
"https://storage.corp/factura.pdf",
|
|
||||||
["proveedor", "fecha", "importe", "iva"]
|
|
||||||
)
|
|
||||||
print(result["result"]["data"])
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Resumen
|
|
||||||
|
|
||||||
1. **S-CONTRACT** es tu idioma para hablar con GRACE y THE FACTORY
|
|
||||||
2. **HST** te da etiquetas para organizar todo
|
|
||||||
3. **h_maestro** identifica cada etiqueta (determinista)
|
|
||||||
4. **Tu libro MST+BCK** registra tus operaciones
|
|
||||||
5. **Tu almacenamiento es bandeja de entrada**, no permanente
|
|
||||||
6. **Habla con DECK** para alinear codigo compartido
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
*Ecosistema TZZR - "Alfred Decide, GRACE Transforma"*
|
|
||||||
@@ -1,668 +0,0 @@
|
|||||||
# MASON Protocol v1.0
|
|
||||||
**Version:** 1.0
|
|
||||||
**Dependencia:** `S-CONTRACT.md`, `NOTARIO.md`
|
|
||||||
**Estado:** Implementación
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
# 1. Introducción
|
|
||||||
|
|
||||||
MASON es el **constructor de documentos** del ecosistema GRACE. Prepara, valida, ensambla y transforma datos antes de enviarlos a THE FACTORY para generación o a NOTARIO para certificación.
|
|
||||||
|
|
||||||
```
|
|
||||||
+---------------------------------------------------------------------+
|
|
||||||
| PRINCIPIO MASON |
|
|
||||||
| |
|
|
||||||
| "MASON prepara, FACTORY genera, NOTARIO certifica" |
|
|
||||||
+---------------------------------------------------------------------+
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
# 2. Arquitectura
|
|
||||||
|
|
||||||
```
|
|
||||||
+---------------------------------------------------------------------+
|
|
||||||
| MASON |
|
|
||||||
| (Constructor de Documentos) |
|
|
||||||
+---------------------------------------------------------------------+
|
|
||||||
| |
|
|
||||||
| Datos Entrada |
|
|
||||||
| | |
|
|
||||||
| v |
|
|
||||||
| +-----------------+ |
|
|
||||||
| | VALIDATOR | Valida estructura y campos requeridos |
|
|
||||||
| +-----------------+ |
|
|
||||||
| | |
|
|
||||||
| v |
|
|
||||||
| +-----------------+ |
|
|
||||||
| | ENRICHER | Añade datos calculados y referencias |
|
|
||||||
| +-----------------+ |
|
|
||||||
| | |
|
|
||||||
| v |
|
|
||||||
| +-----------------+ |
|
|
||||||
| | ASSEMBLER | Ensambla componentes según template |
|
|
||||||
| +-----------------+ |
|
|
||||||
| | |
|
|
||||||
| v |
|
|
||||||
| +-----------------+ |
|
|
||||||
| | FORMATTER | Formatea para destino (FACTORY, NOTARIO) |
|
|
||||||
| +-----------------+ |
|
|
||||||
| | |
|
|
||||||
| v |
|
|
||||||
| Documento Preparado |
|
|
||||||
| |
|
|
||||||
+---------------------------------------------------------------------+
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
# 3. Componentes
|
|
||||||
|
|
||||||
## 3.1 VALIDATOR
|
|
||||||
|
|
||||||
Valida datos de entrada contra esquemas definidos.
|
|
||||||
|
|
||||||
```javascript
|
|
||||||
class Validator {
|
|
||||||
validate(data, schema) {
|
|
||||||
const errors = [];
|
|
||||||
|
|
||||||
// Campos requeridos
|
|
||||||
for (const field of schema.required || []) {
|
|
||||||
if (!data[field]) {
|
|
||||||
errors.push({ field, error: 'required' });
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Tipos de datos
|
|
||||||
for (const [field, type] of Object.entries(schema.types || {})) {
|
|
||||||
if (data[field] && typeof data[field] !== type) {
|
|
||||||
errors.push({ field, error: 'invalid_type', expected: type });
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Reglas personalizadas
|
|
||||||
for (const rule of schema.rules || []) {
|
|
||||||
const result = rule.check(data);
|
|
||||||
if (!result.valid) {
|
|
||||||
errors.push({ field: rule.field, error: result.error });
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return { valid: errors.length === 0, errors };
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
## 3.2 ENRICHER
|
|
||||||
|
|
||||||
Añade datos calculados y referencias externas.
|
|
||||||
|
|
||||||
```javascript
|
|
||||||
class Enricher {
|
|
||||||
async enrich(data, context) {
|
|
||||||
const enriched = { ...data };
|
|
||||||
|
|
||||||
// Timestamps
|
|
||||||
enriched.created_at = new Date().toISOString();
|
|
||||||
enriched.mason_version = '1.0';
|
|
||||||
|
|
||||||
// Cálculos automáticos
|
|
||||||
if (enriched.lineas) {
|
|
||||||
enriched.subtotal = this.calculateSubtotal(enriched.lineas);
|
|
||||||
enriched.iva = enriched.subtotal * 0.21;
|
|
||||||
enriched.total = enriched.subtotal + enriched.iva;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Referencias externas
|
|
||||||
if (enriched.cliente_id) {
|
|
||||||
enriched.cliente = await this.fetchCliente(enriched.cliente_id);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Numeración automática
|
|
||||||
if (!enriched.numero) {
|
|
||||||
enriched.numero = await this.generateNumero(enriched.tipo);
|
|
||||||
}
|
|
||||||
|
|
||||||
return enriched;
|
|
||||||
}
|
|
||||||
|
|
||||||
calculateSubtotal(lineas) {
|
|
||||||
return lineas.reduce((sum, l) => sum + (l.cantidad * l.precio), 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
async generateNumero(tipo) {
|
|
||||||
const prefix = {
|
|
||||||
factura: 'FAC',
|
|
||||||
pedido: 'PED',
|
|
||||||
presupuesto: 'PRE',
|
|
||||||
albaran: 'ALB',
|
|
||||||
}[tipo] || 'DOC';
|
|
||||||
|
|
||||||
const year = new Date().getFullYear();
|
|
||||||
const seq = await this.getNextSequence(tipo);
|
|
||||||
|
|
||||||
return `${prefix}-${year}-${String(seq).padStart(4, '0')}`;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
## 3.3 ASSEMBLER
|
|
||||||
|
|
||||||
Ensambla componentes según template.
|
|
||||||
|
|
||||||
```javascript
|
|
||||||
class Assembler {
|
|
||||||
constructor() {
|
|
||||||
this.templates = new Map();
|
|
||||||
}
|
|
||||||
|
|
||||||
registerTemplate(type, template) {
|
|
||||||
this.templates.set(type, template);
|
|
||||||
}
|
|
||||||
|
|
||||||
assemble(type, data) {
|
|
||||||
const template = this.templates.get(type);
|
|
||||||
if (!template) {
|
|
||||||
throw new Error(`Template not found: ${type}`);
|
|
||||||
}
|
|
||||||
|
|
||||||
return {
|
|
||||||
type,
|
|
||||||
template: template.name,
|
|
||||||
version: template.version,
|
|
||||||
sections: this.buildSections(template, data),
|
|
||||||
metadata: {
|
|
||||||
assembled_at: new Date().toISOString(),
|
|
||||||
assembler: 'MASON',
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
buildSections(template, data) {
|
|
||||||
return template.sections.map(section => ({
|
|
||||||
id: section.id,
|
|
||||||
type: section.type,
|
|
||||||
content: this.renderSection(section, data),
|
|
||||||
}));
|
|
||||||
}
|
|
||||||
|
|
||||||
renderSection(section, data) {
|
|
||||||
// Interpolar variables en contenido
|
|
||||||
let content = section.content;
|
|
||||||
|
|
||||||
for (const [key, value] of Object.entries(data)) {
|
|
||||||
content = content.replace(new RegExp(`{{${key}}}`, 'g'), value);
|
|
||||||
}
|
|
||||||
|
|
||||||
return content;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
## 3.4 FORMATTER
|
|
||||||
|
|
||||||
Formatea para destino específico.
|
|
||||||
|
|
||||||
```javascript
|
|
||||||
class Formatter {
|
|
||||||
formatForFactory(assembled) {
|
|
||||||
return {
|
|
||||||
seed: this.buildPrompt(assembled),
|
|
||||||
objective: `Documento ${assembled.type} profesional`,
|
|
||||||
function: 'DOCUMENT_GENERATION',
|
|
||||||
output_format: 'pdf',
|
|
||||||
context: {
|
|
||||||
template: assembled.template,
|
|
||||||
sections: assembled.sections,
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
formatForNotario(assembled, options = {}) {
|
|
||||||
return {
|
|
||||||
document: assembled,
|
|
||||||
certification_type: options.certification_type || 'standard',
|
|
||||||
requires_blockchain: options.blockchain !== false,
|
|
||||||
metadata: {
|
|
||||||
formatter: 'MASON',
|
|
||||||
formatted_at: new Date().toISOString(),
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
buildPrompt(assembled) {
|
|
||||||
const lines = [
|
|
||||||
`Genera un documento ${assembled.type} profesional.`,
|
|
||||||
'',
|
|
||||||
'Secciones:',
|
|
||||||
];
|
|
||||||
|
|
||||||
for (const section of assembled.sections) {
|
|
||||||
lines.push(`- ${section.id}: ${section.content.substring(0, 100)}...`);
|
|
||||||
}
|
|
||||||
|
|
||||||
return lines.join('\n');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
# 4. Templates de Documentos
|
|
||||||
|
|
||||||
## 4.1 Factura
|
|
||||||
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"name": "factura_v1",
|
|
||||||
"version": "1.0",
|
|
||||||
"type": "factura",
|
|
||||||
"required_fields": [
|
|
||||||
"cliente", "lineas", "fecha"
|
|
||||||
],
|
|
||||||
"sections": [
|
|
||||||
{
|
|
||||||
"id": "header",
|
|
||||||
"type": "header",
|
|
||||||
"content": "FACTURA {{numero}}"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": "emisor",
|
|
||||||
"type": "info_block",
|
|
||||||
"content": "{{empresa_nombre}}\n{{empresa_direccion}}\nCIF: {{empresa_cif}}"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": "receptor",
|
|
||||||
"type": "info_block",
|
|
||||||
"content": "{{cliente_nombre}}\n{{cliente_direccion}}\nCIF: {{cliente_cif}}"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": "detalles",
|
|
||||||
"type": "table",
|
|
||||||
"content": "{{lineas_tabla}}"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": "totales",
|
|
||||||
"type": "totals",
|
|
||||||
"content": "Subtotal: {{subtotal}}€\nIVA (21%): {{iva}}€\nTOTAL: {{total}}€"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": "footer",
|
|
||||||
"type": "footer",
|
|
||||||
"content": "Forma de pago: {{forma_pago}}\nVencimiento: {{fecha_vencimiento}}"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
## 4.2 Pedido
|
|
||||||
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"name": "pedido_v1",
|
|
||||||
"version": "1.0",
|
|
||||||
"type": "pedido",
|
|
||||||
"required_fields": [
|
|
||||||
"proveedor", "productos", "fecha"
|
|
||||||
],
|
|
||||||
"sections": [
|
|
||||||
{
|
|
||||||
"id": "header",
|
|
||||||
"type": "header",
|
|
||||||
"content": "PEDIDO {{numero}}"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": "proveedor",
|
|
||||||
"type": "info_block",
|
|
||||||
"content": "Proveedor: {{proveedor_nombre}}\nContacto: {{proveedor_contacto}}"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": "productos",
|
|
||||||
"type": "table",
|
|
||||||
"content": "{{productos_tabla}}"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": "condiciones",
|
|
||||||
"type": "text",
|
|
||||||
"content": "Plazo de entrega: {{plazo_entrega}}\nCondiciones: {{condiciones}}"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
# 5. Flujo Completo
|
|
||||||
|
|
||||||
```
|
|
||||||
┌────────────────────────────────────────────────────────────────────┐
|
|
||||||
│ FLUJO MASON → FACTORY → NOTARIO │
|
|
||||||
└────────────────────────────────────────────────────────────────────┘
|
|
||||||
|
|
||||||
1. CLARA recibe petición de documento
|
|
||||||
│
|
|
||||||
▼
|
|
||||||
2. MASON.validate(datos, schema)
|
|
||||||
│ → Si inválido: retorna errores
|
|
||||||
▼
|
|
||||||
3. MASON.enrich(datos, context)
|
|
||||||
│ → Añade cálculos, referencias, numeración
|
|
||||||
▼
|
|
||||||
4. MASON.assemble(tipo, datos_enriquecidos)
|
|
||||||
│ → Construye estructura según template
|
|
||||||
▼
|
|
||||||
5. MASON.formatForFactory(assembled)
|
|
||||||
│
|
|
||||||
▼
|
|
||||||
6. THE FACTORY genera documento (iterativo)
|
|
||||||
│ → Director → Executor → Evaluator → converge
|
|
||||||
▼
|
|
||||||
7. MASON.formatForNotario(documento)
|
|
||||||
│
|
|
||||||
▼
|
|
||||||
8. NOTARIO certifica
|
|
||||||
│ → Hash + Timestamp + Merkle + Blockchain
|
|
||||||
▼
|
|
||||||
9. LOCKER almacena
|
|
||||||
│ → locker://corp/facturas/FAC-2025-0001.pdf
|
|
||||||
▼
|
|
||||||
10. Retorna referencia certificada
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
# 6. API
|
|
||||||
|
|
||||||
## 6.1 Mason.prepare()
|
|
||||||
|
|
||||||
```javascript
|
|
||||||
const mason = new Mason();
|
|
||||||
|
|
||||||
const result = await mason.prepare({
|
|
||||||
tipo: 'factura',
|
|
||||||
data: {
|
|
||||||
cliente_id: 'CLI-001',
|
|
||||||
lineas: [
|
|
||||||
{ concepto: 'Traje azul marino', cantidad: 1, precio: 349 },
|
|
||||||
{ concepto: 'Ajustes', cantidad: 1, precio: 50 }
|
|
||||||
]
|
|
||||||
},
|
|
||||||
options: {
|
|
||||||
auto_enrich: true,
|
|
||||||
validate: true,
|
|
||||||
target: 'FACTORY'
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// Result:
|
|
||||||
{
|
|
||||||
"success": true,
|
|
||||||
"document": {
|
|
||||||
"numero": "FAC-2025-0001",
|
|
||||||
"cliente": { "nombre": "Juan García", "cif": "12345678A" },
|
|
||||||
"lineas": [...],
|
|
||||||
"subtotal": 399,
|
|
||||||
"iva": 83.79,
|
|
||||||
"total": 482.79
|
|
||||||
},
|
|
||||||
"formatted": {
|
|
||||||
"seed": "Genera un documento factura profesional...",
|
|
||||||
"objective": "...",
|
|
||||||
"function": "DOCUMENT_GENERATION"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
## 6.2 Mason.build()
|
|
||||||
|
|
||||||
```javascript
|
|
||||||
const document = await mason.build('factura', preparedData);
|
|
||||||
|
|
||||||
// Genera directamente sin pasar por FACTORY
|
|
||||||
// Útil para documentos simples o regeneración
|
|
||||||
```
|
|
||||||
|
|
||||||
## 6.3 Mason.validate()
|
|
||||||
|
|
||||||
```javascript
|
|
||||||
const validation = mason.validate(data, 'factura');
|
|
||||||
|
|
||||||
if (!validation.valid) {
|
|
||||||
console.log('Errores:', validation.errors);
|
|
||||||
// [{ field: 'cliente', error: 'required' }]
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
# 7. Integración con S-CONTRACT
|
|
||||||
|
|
||||||
## 7.1 Request a MASON
|
|
||||||
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"contract_version": "2.1",
|
|
||||||
"request_id": "msn-abc123",
|
|
||||||
"source": {
|
|
||||||
"system": "CORP",
|
|
||||||
"orchestrator": "CLARA"
|
|
||||||
},
|
|
||||||
"target": {
|
|
||||||
"service": "MASON",
|
|
||||||
"operation": "prepare"
|
|
||||||
},
|
|
||||||
"input": {
|
|
||||||
"tipo": "factura",
|
|
||||||
"data": { ... },
|
|
||||||
"options": {
|
|
||||||
"auto_enrich": true,
|
|
||||||
"target": "FACTORY"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
## 7.2 Response de MASON
|
|
||||||
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"contract_version": "2.1",
|
|
||||||
"request_id": "msn-abc123",
|
|
||||||
"status": {
|
|
||||||
"code": "SUCCESS",
|
|
||||||
"message": "Document prepared successfully"
|
|
||||||
},
|
|
||||||
"output": {
|
|
||||||
"document": { ... },
|
|
||||||
"formatted": { ... },
|
|
||||||
"validation": {
|
|
||||||
"valid": true,
|
|
||||||
"errors": []
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"metadata": {
|
|
||||||
"mason_version": "1.0",
|
|
||||||
"template_used": "factura_v1",
|
|
||||||
"enrichments_applied": ["calculate_totals", "generate_numero", "fetch_cliente"]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
# 8. Configuración
|
|
||||||
|
|
||||||
```yaml
|
|
||||||
mason:
|
|
||||||
enabled: true
|
|
||||||
|
|
||||||
# Validación
|
|
||||||
strict_validation: true
|
|
||||||
fail_on_warning: false
|
|
||||||
|
|
||||||
# Enriquecimiento
|
|
||||||
auto_enrich: true
|
|
||||||
fetch_external_refs: true
|
|
||||||
|
|
||||||
# Numeración
|
|
||||||
sequence_prefix: "TZZR"
|
|
||||||
sequence_padding: 4
|
|
||||||
reset_yearly: true
|
|
||||||
|
|
||||||
# Templates
|
|
||||||
templates_dir: "./templates"
|
|
||||||
custom_templates_enabled: true
|
|
||||||
|
|
||||||
# Destinos
|
|
||||||
default_target: "FACTORY"
|
|
||||||
|
|
||||||
# Cache
|
|
||||||
cache_enrichments: true
|
|
||||||
cache_ttl_seconds: 300
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
# 9. Schemas de Validación
|
|
||||||
|
|
||||||
## 9.1 Factura
|
|
||||||
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"$schema": "http://json-schema.org/draft-07/schema#",
|
|
||||||
"title": "Factura Schema",
|
|
||||||
"type": "object",
|
|
||||||
"required": ["cliente", "lineas", "fecha"],
|
|
||||||
"properties": {
|
|
||||||
"cliente": {
|
|
||||||
"type": "object",
|
|
||||||
"required": ["nombre"],
|
|
||||||
"properties": {
|
|
||||||
"nombre": { "type": "string", "minLength": 1 },
|
|
||||||
"cif": { "type": "string", "pattern": "^[A-Z0-9]{9}$" },
|
|
||||||
"direccion": { "type": "string" },
|
|
||||||
"email": { "type": "string", "format": "email" }
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"lineas": {
|
|
||||||
"type": "array",
|
|
||||||
"minItems": 1,
|
|
||||||
"items": {
|
|
||||||
"type": "object",
|
|
||||||
"required": ["concepto", "cantidad", "precio"],
|
|
||||||
"properties": {
|
|
||||||
"concepto": { "type": "string" },
|
|
||||||
"cantidad": { "type": "number", "minimum": 0 },
|
|
||||||
"precio": { "type": "number", "minimum": 0 }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"fecha": { "type": "string", "format": "date" },
|
|
||||||
"forma_pago": {
|
|
||||||
"type": "string",
|
|
||||||
"enum": ["transferencia", "tarjeta", "efectivo", "domiciliacion"]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
# 10. Implementación Completa
|
|
||||||
|
|
||||||
```javascript
|
|
||||||
/**
|
|
||||||
* MASON - Constructor de Documentos
|
|
||||||
*/
|
|
||||||
class Mason {
|
|
||||||
constructor(config = {}) {
|
|
||||||
this.version = '1.0';
|
|
||||||
this.validator = new Validator();
|
|
||||||
this.enricher = new Enricher(config);
|
|
||||||
this.assembler = new Assembler();
|
|
||||||
this.formatter = new Formatter();
|
|
||||||
|
|
||||||
// Cargar templates por defecto
|
|
||||||
this.loadDefaultTemplates();
|
|
||||||
}
|
|
||||||
|
|
||||||
loadDefaultTemplates() {
|
|
||||||
this.assembler.registerTemplate('factura', FACTURA_TEMPLATE);
|
|
||||||
this.assembler.registerTemplate('pedido', PEDIDO_TEMPLATE);
|
|
||||||
this.assembler.registerTemplate('presupuesto', PRESUPUESTO_TEMPLATE);
|
|
||||||
this.assembler.registerTemplate('albaran', ALBARAN_TEMPLATE);
|
|
||||||
}
|
|
||||||
|
|
||||||
async prepare(request) {
|
|
||||||
const { tipo, data, options = {} } = request;
|
|
||||||
|
|
||||||
// 1. Validar
|
|
||||||
if (options.validate !== false) {
|
|
||||||
const validation = this.validator.validate(data, this.getSchema(tipo));
|
|
||||||
if (!validation.valid) {
|
|
||||||
return { success: false, errors: validation.errors };
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 2. Enriquecer
|
|
||||||
let enriched = data;
|
|
||||||
if (options.auto_enrich !== false) {
|
|
||||||
enriched = await this.enricher.enrich(data, { tipo });
|
|
||||||
}
|
|
||||||
|
|
||||||
// 3. Ensamblar
|
|
||||||
const assembled = this.assembler.assemble(tipo, enriched);
|
|
||||||
|
|
||||||
// 4. Formatear para destino
|
|
||||||
let formatted;
|
|
||||||
switch (options.target) {
|
|
||||||
case 'FACTORY':
|
|
||||||
formatted = this.formatter.formatForFactory(assembled);
|
|
||||||
break;
|
|
||||||
case 'NOTARIO':
|
|
||||||
formatted = this.formatter.formatForNotario(assembled, options);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
formatted = assembled;
|
|
||||||
}
|
|
||||||
|
|
||||||
return {
|
|
||||||
success: true,
|
|
||||||
document: enriched,
|
|
||||||
assembled,
|
|
||||||
formatted,
|
|
||||||
validation: { valid: true, errors: [] }
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
getSchema(tipo) {
|
|
||||||
return SCHEMAS[tipo] || {};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
module.exports = { Mason, Validator, Enricher, Assembler, Formatter };
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
# 11. Checklist de Implementación
|
|
||||||
|
|
||||||
- [x] Definir arquitectura de componentes
|
|
||||||
- [x] Implementar Validator
|
|
||||||
- [x] Implementar Enricher
|
|
||||||
- [x] Implementar Assembler
|
|
||||||
- [x] Implementar Formatter
|
|
||||||
- [x] Crear templates de documentos
|
|
||||||
- [x] Definir schemas de validación
|
|
||||||
- [x] Integrar con S-CONTRACT
|
|
||||||
- [ ] Tests unitarios
|
|
||||||
- [ ] Tests de integración con FACTORY
|
|
||||||
- [ ] Tests de integración con NOTARIO
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
**Fin del Documento MASON Protocol - Version 1.0**
|
|
||||||
|
|
||||||
*Sistema GRACE - "MASON prepara, FACTORY genera, NOTARIO certifica"*
|
|
||||||
@@ -1,298 +0,0 @@
|
|||||||
# CAPA COGNITIVA - GRACE (Sistema de Modulos IA)
|
|
||||||
**Version:** 2.0
|
|
||||||
**Estado:** Enterprise Standard
|
|
||||||
**Filosofia Base:** Microservicios Cognitivos - Contrato Comun - Determinismo y Observabilidad
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
# 1. Introduccion a GRACE
|
|
||||||
|
|
||||||
GRACE no es un chatbot.
|
|
||||||
GRACE es un **conjunto de 18 microservicios cognitivos desacoplados**, especializados en tareas de:
|
|
||||||
|
|
||||||
- Vision
|
|
||||||
- Voz
|
|
||||||
- Biometria
|
|
||||||
- Semantica
|
|
||||||
- Extraccion de datos
|
|
||||||
- Normalizacion
|
|
||||||
- Clasificacion
|
|
||||||
|
|
||||||
GRACE representa la **capa de cognicion** del ecosistema.
|
|
||||||
No toma decisiones.
|
|
||||||
No altera estados.
|
|
||||||
No escribe en la Base de Datos.
|
|
||||||
|
|
||||||
**"GRACE transforma, Alfred decide."**
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
# 2. Integracion con S-CONTRACT
|
|
||||||
|
|
||||||
Toda llamada a GRACE debe seguir estrictamente el S-CONTRACT v2.0.
|
|
||||||
|
|
||||||
## 2.1 Request (Perfil LITE)
|
|
||||||
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"contract_version": "2.0",
|
|
||||||
"profile": "LITE",
|
|
||||||
"envelope": {
|
|
||||||
"trace_id": "uuid-v4-global",
|
|
||||||
"idempotency_key": "sha256-del-input"
|
|
||||||
},
|
|
||||||
"routing": {
|
|
||||||
"module": "CLASSIFIER"
|
|
||||||
},
|
|
||||||
"context": {
|
|
||||||
"lang": "es",
|
|
||||||
"mode": "strict"
|
|
||||||
},
|
|
||||||
"payload": {
|
|
||||||
"type": "text",
|
|
||||||
"encoding": "utf-8",
|
|
||||||
"content": "Texto a procesar"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
## 2.2 Response
|
|
||||||
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"contract_version": "2.0",
|
|
||||||
"profile": "LITE",
|
|
||||||
"envelope": {
|
|
||||||
"trace_id": "uuid-v4-global",
|
|
||||||
"idempotency_key": "sha256-del-input",
|
|
||||||
"timestamp_end": "2025-12-18T10:30:00.450Z"
|
|
||||||
},
|
|
||||||
"status": {
|
|
||||||
"code": "SUCCESS",
|
|
||||||
"fallback_level_used": 0,
|
|
||||||
"provider_used": "groq"
|
|
||||||
},
|
|
||||||
"result": {
|
|
||||||
"schema": "classifier_output_v1",
|
|
||||||
"data": {
|
|
||||||
"category": "FINANZAS",
|
|
||||||
"confidence": 0.98
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"quality": {
|
|
||||||
"confidence": 0.98,
|
|
||||||
"coverage": 1.0,
|
|
||||||
"tokens_input": 150,
|
|
||||||
"tokens_output": 45
|
|
||||||
},
|
|
||||||
"metadata": {
|
|
||||||
"model_id": "llama-3-70b-instruct",
|
|
||||||
"processing_ms": 340
|
|
||||||
},
|
|
||||||
"errors": [],
|
|
||||||
"warnings": []
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
### Status codes
|
|
||||||
|
|
||||||
| Codigo | Significado |
|
|
||||||
|--------|-------------|
|
|
||||||
| `SUCCESS` | Ejecucion completa y valida |
|
|
||||||
| `PARTIAL` | Resultado incompleto pero usable |
|
|
||||||
| `ERROR` | Fallo no recuperable |
|
|
||||||
| `TIMEOUT` | Excedio TTL |
|
|
||||||
| `FALLBACK` | Exito usando modulo alternativo |
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
# 3. Catalogo de Modulos (Los 18 Microservicios)
|
|
||||||
|
|
||||||
GRACE se divide en cinco familias.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## FAMILIA A - VISION (Procesado Documental)
|
|
||||||
|
|
||||||
### **1. IMG_PREPROCESS**
|
|
||||||
Normalizacion de entrada.
|
|
||||||
Operaciones:
|
|
||||||
- Crop inteligente
|
|
||||||
- Denoise
|
|
||||||
- Upscale 2x
|
|
||||||
- Grayscale
|
|
||||||
|
|
||||||
### **2. PDF_SCANNER**
|
|
||||||
Limpieza avanzada para documentos escaneados.
|
|
||||||
Operaciones:
|
|
||||||
- Deskew
|
|
||||||
- Binarizacion adaptativa
|
|
||||||
- Eliminacion bordes negros
|
|
||||||
|
|
||||||
### **3. OCR_CORE**
|
|
||||||
Extraccion de texto.
|
|
||||||
Incluye:
|
|
||||||
- Layout analysis
|
|
||||||
- HOCR
|
|
||||||
- Texto plano
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## FAMILIA B - VOZ (Reuniones)
|
|
||||||
|
|
||||||
### **4. ASR_ENGINE**
|
|
||||||
Reconocimiento del habla.
|
|
||||||
- Modelo: Whisper Large v3 / Faster Whisper
|
|
||||||
- Diarizacion A/B
|
|
||||||
- Timestamps por frase
|
|
||||||
|
|
||||||
### **5. TTS_ENGINE**
|
|
||||||
Sintesis de voz neutral para notificaciones internas.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## FAMILIA C - IDENTIDAD (Biometria)
|
|
||||||
|
|
||||||
### **6. FACE_VECTOR**
|
|
||||||
Vector biometrico facial (Float32 L2).
|
|
||||||
No guarda fotos, solo matematicas.
|
|
||||||
|
|
||||||
### **7. ID_CONSOLIDATION**
|
|
||||||
Fusion de identidades de un mismo Player.
|
|
||||||
Algoritmo: **Mediana geometrica** para eliminar outliers.
|
|
||||||
|
|
||||||
### **8. AVATAR_GEN**
|
|
||||||
Generacion de avatar neutral 512x512 a partir del vector consolidado.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## FAMILIA D - SEMANTICA (NLP)
|
|
||||||
|
|
||||||
### **9. EMBEDDINGS**
|
|
||||||
Vectorizacion semantica para busquedas.
|
|
||||||
|
|
||||||
### **10. SUMMARIZER**
|
|
||||||
Resumen estructurado:
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"objetivos": [],
|
|
||||||
"acuerdos": [],
|
|
||||||
"riesgos": []
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
### **11. TASK_EXTRACTOR**
|
|
||||||
Mineria de acciones, responsabilidades y fechas.
|
|
||||||
|
|
||||||
### **12. CLASSIFIER**
|
|
||||||
Asigna SET_HST basado en contenido textual.
|
|
||||||
|
|
||||||
### **13. SIMILARITY**
|
|
||||||
Comparador vectorial (Cosine Similarity).
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## FAMILIA E - UTILIDADES
|
|
||||||
|
|
||||||
### **14. FIELD_EXTRACTOR**
|
|
||||||
Lectura estructurada mediante regex + IA.
|
|
||||||
Ej.: CIF, fechas, importes.
|
|
||||||
|
|
||||||
### **15. HASHER**
|
|
||||||
Generador oficial de SHA256 y UUID v4.
|
|
||||||
|
|
||||||
### **16. INPUT_NORMALIZER**
|
|
||||||
Traduccion de formatos y enumeraciones.
|
|
||||||
|
|
||||||
### **17. OUTPUT_ADAPTER**
|
|
||||||
Adaptacion a formatos legacy.
|
|
||||||
|
|
||||||
### **18. LANG_DETECT**
|
|
||||||
Identificacion ISO 639-1.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
# 4. Cadenas de Fallback (Resiliencia Operativa)
|
|
||||||
|
|
||||||
GRACE nunca falla silenciosamente.
|
|
||||||
Cada modulo define una cadena de degradacion via `fallback_chain`.
|
|
||||||
|
|
||||||
## Ejemplo OCR
|
|
||||||
|
|
||||||
```json
|
|
||||||
"routing": {
|
|
||||||
"module": "OCR_CORE",
|
|
||||||
"fallback_chain": ["OCR_LOCAL", "OCR_GROQ", "OCR_OPENAI"]
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
## Ejemplo ASR
|
|
||||||
|
|
||||||
```json
|
|
||||||
"routing": {
|
|
||||||
"module": "ASR_ENGINE",
|
|
||||||
"fallback_chain": ["ASR_WHISPER_LOCAL", "ASR_FASTER_WHISPER", "ASR_GROQ"]
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
# 5. Filosofia Operativa de GRACE
|
|
||||||
|
|
||||||
### Stateless
|
|
||||||
GRACE nunca guarda estado.
|
|
||||||
|
|
||||||
### Determinista
|
|
||||||
La misma entrada -> siempre la misma salida.
|
|
||||||
|
|
||||||
### Intercambiable
|
|
||||||
Se puede sustituir un modelo por otro sin romper el sistema.
|
|
||||||
|
|
||||||
### Trazable
|
|
||||||
Toda ejecucion queda registrada via trace_id.
|
|
||||||
|
|
||||||
### No persiste datos sensibles
|
|
||||||
Los archivos viven solo en almacenamiento gestionado.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
# 6. Relacion GRACE <-> Alfred <-> SFE
|
|
||||||
|
|
||||||
### GRACE transforma
|
|
||||||
OCR, ASR, vectores, embeddings.
|
|
||||||
|
|
||||||
### Alfred decide
|
|
||||||
Valida, encamina, escribe en SFE.
|
|
||||||
|
|
||||||
### SFE registra
|
|
||||||
El estado final y su evidencia.
|
|
||||||
|
|
||||||
```
|
|
||||||
Entrada (URL)
|
|
||||||
|
|
|
||||||
GRACE (microservicio)
|
|
||||||
|
|
|
||||||
Transformacion estructurada
|
|
||||||
|
|
|
||||||
Alfred (validacion)
|
|
||||||
|
|
|
||||||
SFE (narrativa oficial)
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
# 7. M-CONTRACTs
|
|
||||||
|
|
||||||
Cada modulo debe definir su M-CONTRACT extendiendo S-CONTRACT.
|
|
||||||
|
|
||||||
Ver carpeta `/m-contracts/` para definiciones formales de:
|
|
||||||
- CLASSIFIER.json
|
|
||||||
- OCR_CORE.json
|
|
||||||
- ASR_ENGINE.json
|
|
||||||
- (18 modulos total)
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
**Fin del Documento MODULOS_IA - Version 2.0**
|
|
||||||
|
|
||||||
*Sistema GRACE - "GRACE transforma, Alfred decide"*
|
|
||||||
@@ -1,261 +0,0 @@
|
|||||||
# NOTARIO - Sistema de Sellado Blockchain
|
|
||||||
**Version:** 2.0
|
|
||||||
**Dependencia:** `S-CONTRACT.md`
|
|
||||||
**Estado:** Especificacion
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
# 1. Introduccion
|
|
||||||
|
|
||||||
NOTARIO es el modulo responsable del **sellado inmutable** de registros criticos en blockchain. Opera como la ultima capa de confianza del ecosistema GRACE.
|
|
||||||
|
|
||||||
```
|
|
||||||
+---------------------------------------------------------------------+
|
|
||||||
| PRINCIPIO NOTARIO |
|
|
||||||
| |
|
|
||||||
| "Lo que NOTARIO sella, nadie lo altera" |
|
|
||||||
+---------------------------------------------------------------------+
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
# 2. Arquitectura
|
|
||||||
|
|
||||||
```
|
|
||||||
+---------------------------------------------------------------------+
|
|
||||||
| NOTARIO |
|
|
||||||
+---------------------------------------------------------------------+
|
|
||||||
| |
|
|
||||||
| SYS_LOG (Libro Diario) |
|
|
||||||
| | |
|
|
||||||
| | (procesos completados + auditados) |
|
|
||||||
| v |
|
|
||||||
| +-----------------+ |
|
|
||||||
| | BATCH COLLECTOR | Agrupa registros por ventana temporal |
|
|
||||||
| +-----------------+ |
|
|
||||||
| | |
|
|
||||||
| v |
|
|
||||||
| +-----------------+ |
|
|
||||||
| | MERKLE BUILDER | Construye arbol Merkle del batch |
|
|
||||||
| +-----------------+ |
|
|
||||||
| | |
|
|
||||||
| v |
|
|
||||||
| +-----------------+ |
|
|
||||||
| | BLOCKCHAIN TX | Publica hash raiz en blockchain |
|
|
||||||
| +-----------------+ |
|
|
||||||
| | |
|
|
||||||
| v |
|
|
||||||
| SYS_LOG (UPDATE blockchain_tx_ref) |
|
|
||||||
| |
|
|
||||||
+---------------------------------------------------------------------+
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
# 3. Dos Franjas Temporales
|
|
||||||
|
|
||||||
## 3.1 Franja Interna
|
|
||||||
|
|
||||||
Tiempo del sistema para:
|
|
||||||
- Procesar operaciones
|
|
||||||
- Ejecutar auditoria SENTINEL
|
|
||||||
- Preparar datos para consolidacion
|
|
||||||
|
|
||||||
**Duracion tipica**: Minutos a horas
|
|
||||||
|
|
||||||
## 3.2 Franja Blockchain
|
|
||||||
|
|
||||||
Tiempo de NOTARIO para:
|
|
||||||
- Agrupar registros en batches
|
|
||||||
- Construir pruebas criptograficas
|
|
||||||
- Publicar en blockchain
|
|
||||||
- Confirmar transacciones
|
|
||||||
|
|
||||||
**Duracion tipica**: Horas a dias (segun volumen y costos)
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
# 4. Ciclo de Sellado
|
|
||||||
|
|
||||||
```
|
|
||||||
1. RECOLECTAR
|
|
||||||
- Query SYS_LOG WHERE audit_status = 'DEEP_PASS'
|
|
||||||
- AND blockchain_pending = FALSE
|
|
||||||
- AND blockchain_tx_ref IS NULL
|
|
||||||
|
|
||||||
2. AGRUPAR
|
|
||||||
- Crear batch con ventana temporal (ej: 24h)
|
|
||||||
- Asignar notario_batch_id
|
|
||||||
|
|
||||||
3. CONSTRUIR MERKLE
|
|
||||||
- Ordenar registros por trace_id
|
|
||||||
- Calcular hash de cada registro
|
|
||||||
- Construir arbol binario
|
|
||||||
- Obtener merkle_root
|
|
||||||
|
|
||||||
4. FIRMAR
|
|
||||||
- Firmar merkle_root con llave de NOTARIO
|
|
||||||
- Generar timestamp certificado
|
|
||||||
|
|
||||||
5. PUBLICAR
|
|
||||||
- Enviar transaccion a blockchain
|
|
||||||
- Esperar confirmaciones
|
|
||||||
|
|
||||||
6. ACTUALIZAR
|
|
||||||
- UPDATE SYS_LOG SET blockchain_tx_ref = tx_hash
|
|
||||||
- INSERT NOTARIO_BATCHES con detalles
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
# 5. Tabla NOTARIO_BATCHES
|
|
||||||
|
|
||||||
```sql
|
|
||||||
CREATE TABLE NOTARIO_BATCHES (
|
|
||||||
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
||||||
batch_id UUID UNIQUE NOT NULL,
|
|
||||||
|
|
||||||
-- Ventana temporal
|
|
||||||
window_start TIMESTAMPTZ NOT NULL,
|
|
||||||
window_end TIMESTAMPTZ NOT NULL,
|
|
||||||
|
|
||||||
-- Contenido
|
|
||||||
records_count INTEGER NOT NULL,
|
|
||||||
trace_ids UUID[] NOT NULL,
|
|
||||||
|
|
||||||
-- Merkle
|
|
||||||
merkle_root CHAR(64) NOT NULL,
|
|
||||||
merkle_tree JSONB,
|
|
||||||
|
|
||||||
-- Firma
|
|
||||||
signature TEXT NOT NULL,
|
|
||||||
signing_key_id VARCHAR(100),
|
|
||||||
signed_at TIMESTAMPTZ NOT NULL,
|
|
||||||
|
|
||||||
-- Blockchain
|
|
||||||
blockchain_network VARCHAR(50) DEFAULT 'ethereum',
|
|
||||||
blockchain_tx_ref VARCHAR(100),
|
|
||||||
blockchain_block BIGINT,
|
|
||||||
blockchain_timestamp TIMESTAMPTZ,
|
|
||||||
confirmations INTEGER DEFAULT 0,
|
|
||||||
|
|
||||||
-- Estado
|
|
||||||
status VARCHAR(20) DEFAULT 'PENDING',
|
|
||||||
|
|
||||||
-- Metadata
|
|
||||||
created_at TIMESTAMPTZ DEFAULT NOW(),
|
|
||||||
|
|
||||||
CONSTRAINT valid_status CHECK (
|
|
||||||
status IN ('PENDING', 'SUBMITTED', 'CONFIRMED', 'FAILED')
|
|
||||||
)
|
|
||||||
);
|
|
||||||
|
|
||||||
CREATE INDEX idx_notario_status ON NOTARIO_BATCHES(status);
|
|
||||||
CREATE INDEX idx_notario_window ON NOTARIO_BATCHES(window_start, window_end);
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
# 6. Verificacion de Integridad
|
|
||||||
|
|
||||||
Para verificar que un registro no ha sido alterado:
|
|
||||||
|
|
||||||
```python
|
|
||||||
def verify_record_integrity(trace_id, notario_batch_id):
|
|
||||||
"""
|
|
||||||
Verifica que un registro esta incluido en un batch sellado.
|
|
||||||
"""
|
|
||||||
# 1. Obtener batch
|
|
||||||
batch = get_batch(notario_batch_id)
|
|
||||||
|
|
||||||
# 2. Verificar que trace_id esta en el batch
|
|
||||||
assert trace_id in batch.trace_ids
|
|
||||||
|
|
||||||
# 3. Obtener registro
|
|
||||||
record = get_syslog_record(trace_id)
|
|
||||||
|
|
||||||
# 4. Calcular hash del registro
|
|
||||||
record_hash = sha256(serialize(record))
|
|
||||||
|
|
||||||
# 5. Verificar inclusion en merkle tree
|
|
||||||
proof = get_merkle_proof(batch.merkle_tree, trace_id)
|
|
||||||
assert verify_merkle_proof(record_hash, proof, batch.merkle_root)
|
|
||||||
|
|
||||||
# 6. Verificar firma del batch
|
|
||||||
assert verify_signature(batch.merkle_root, batch.signature, batch.signing_key_id)
|
|
||||||
|
|
||||||
# 7. Verificar que merkle_root esta en blockchain
|
|
||||||
tx = get_blockchain_tx(batch.blockchain_tx_ref)
|
|
||||||
assert tx.data == batch.merkle_root
|
|
||||||
|
|
||||||
return True
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
# 7. Integracion con S-CONTRACT
|
|
||||||
|
|
||||||
## 7.1 Campos en Response
|
|
||||||
|
|
||||||
```json
|
|
||||||
"audit": {
|
|
||||||
"blockchain_pending": true,
|
|
||||||
"blockchain_tx_ref": null,
|
|
||||||
"notario_batch_id": "uuid-batch"
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
## 7.2 Campos post-sellado
|
|
||||||
|
|
||||||
```json
|
|
||||||
"audit": {
|
|
||||||
"blockchain_pending": false,
|
|
||||||
"blockchain_tx_ref": "0x1234...abcd",
|
|
||||||
"notario_batch_id": "uuid-batch"
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
# 8. Configuracion
|
|
||||||
|
|
||||||
```yaml
|
|
||||||
notario:
|
|
||||||
enabled: true
|
|
||||||
|
|
||||||
# Ventana de agregacion
|
|
||||||
batch_window_hours: 24
|
|
||||||
min_records_per_batch: 10
|
|
||||||
max_records_per_batch: 10000
|
|
||||||
|
|
||||||
# Blockchain
|
|
||||||
network: ethereum
|
|
||||||
contract_address: "0x..."
|
|
||||||
gas_limit: 100000
|
|
||||||
|
|
||||||
# Firma
|
|
||||||
signing_key: kv://production/signing/notario
|
|
||||||
|
|
||||||
# Reintentos
|
|
||||||
max_retries: 3
|
|
||||||
retry_delay_minutes: 60
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
# 9. Checklist de Implementacion
|
|
||||||
|
|
||||||
- [ ] Crear tabla NOTARIO_BATCHES
|
|
||||||
- [ ] Implementar recolector de registros
|
|
||||||
- [ ] Implementar constructor Merkle tree
|
|
||||||
- [ ] Configurar llave de firma
|
|
||||||
- [ ] Integrar con proveedor blockchain
|
|
||||||
- [ ] Implementar verificador de integridad
|
|
||||||
- [ ] Crear workflow de sellado periodico
|
|
||||||
- [ ] Configurar alertas para fallos
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
**Fin del Documento NOTARIO - Version 2.0**
|
|
||||||
|
|
||||||
*Sistema GRACE - "Lo que NOTARIO sella, nadie lo altera"*
|
|
||||||
@@ -1,317 +0,0 @@
|
|||||||
# PENNY - Arquitectura de Asistente de Voz
|
|
||||||
**Version:** 1.0
|
|
||||||
**Estado:** Especificacion Tecnica
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
# 1. Modos de Operacion
|
|
||||||
|
|
||||||
PENNY soporta dos modos de operacion seleccionables al inicio de sesion:
|
|
||||||
|
|
||||||
| Modo | Latencia | Costo | Privacidad |
|
|
||||||
|------|----------|-------|------------|
|
|
||||||
| `SELF_HOSTED` | 2-4s | ~$0.01/min | Total |
|
|
||||||
| `EXTERNAL` | ~300ms | ~$0.08/min | APIs externas |
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
# 2. Modo SELF_HOSTED (Modelos Locales)
|
|
||||||
|
|
||||||
Pipeline secuencial con modelos autoalojados en RunPod:
|
|
||||||
|
|
||||||
```
|
|
||||||
Audio entrada
|
|
||||||
|
|
|
||||||
v
|
|
||||||
+------------------+
|
|
||||||
| Silero VAD | Detecta actividad de voz
|
|
||||||
+------------------+
|
|
||||||
|
|
|
||||||
v
|
|
||||||
+------------------+
|
|
||||||
| Faster Whisper | ASR: Voz a texto (~500-1500ms)
|
|
||||||
| Large V3 |
|
|
||||||
+------------------+
|
|
||||||
|
|
|
||||||
v
|
|
||||||
+------------------+
|
|
||||||
| Qwen 2.5 7B | LLM: Genera respuesta (~500-2000ms)
|
|
||||||
+------------------+
|
|
||||||
|
|
|
||||||
v
|
|
||||||
+------------------+
|
|
||||||
| XTTS-v2 | TTS: Texto a voz (~500-1500ms)
|
|
||||||
+------------------+
|
|
||||||
|
|
|
||||||
v
|
|
||||||
Audio salida
|
|
||||||
```
|
|
||||||
|
|
||||||
**Latencia total**: 2-4 segundos
|
|
||||||
**Modelos requeridos** (~20GB en Network Volume):
|
|
||||||
- Silero VAD (~1MB)
|
|
||||||
- Faster Whisper Large V3 (~3GB)
|
|
||||||
- Qwen 2.5 7B Instruct (~15GB)
|
|
||||||
- XTTS-v2 (~2GB)
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
# 3. Modo EXTERNAL: Arquitectura Portavoz + Cerebro
|
|
||||||
|
|
||||||
Para lograr latencia conversacional (<500ms), se usa una arquitectura hibrida donde:
|
|
||||||
|
|
||||||
- **GPT-4o Realtime** actua como "portavoz" - maneja la voz en tiempo real
|
|
||||||
- **Claude** actua como "cerebro" - analiza en paralelo y alimenta contexto
|
|
||||||
|
|
||||||
## 3.1 Concepto
|
|
||||||
|
|
||||||
```
|
|
||||||
+---------------------------------------------------------------------+
|
|
||||||
| PRINCIPIO PORTAVOZ + CEREBRO |
|
|
||||||
| |
|
|
||||||
| "GPT es rapido pero limitado. Claude es inteligente pero lento. |
|
|
||||||
| Usamos GPT como frontend de voz mientras Claude piensa detras." |
|
|
||||||
+---------------------------------------------------------------------+
|
|
||||||
```
|
|
||||||
|
|
||||||
GPT-4o Realtime responde instantaneamente con la informacion que tiene.
|
|
||||||
Claude analiza la conversacion en paralelo y actualiza el contexto de GPT.
|
|
||||||
|
|
||||||
## 3.2 Flujo de Operacion
|
|
||||||
|
|
||||||
```
|
|
||||||
PENNY EXTERNAL
|
|
||||||
|
|
|
||||||
+-------------------+-------------------+
|
|
||||||
| |
|
|
||||||
v v
|
|
||||||
+--------------------+ +--------------------+
|
|
||||||
| GPT-4o Realtime | | Claude |
|
|
||||||
| | | |
|
|
||||||
| - Maneja voz | <------ | - Analiza contexto |
|
|
||||||
| - Responde rapido | contexto | - Busca en KB |
|
|
||||||
| - ~300ms latencia | | - Prepara info |
|
|
||||||
+--------------------+ +--------------------+
|
|
||||||
| |
|
|
||||||
v |
|
|
||||||
Audio respuesta |
|
|
||||||
| |
|
|
||||||
+---------------------------------------+
|
|
||||||
|
|
|
||||||
Actualiza system
|
|
||||||
prompt de GPT
|
|
||||||
```
|
|
||||||
|
|
||||||
## 3.3 Ciclo de Conversacion
|
|
||||||
|
|
||||||
```
|
|
||||||
TURNO 1:
|
|
||||||
Usuario habla -> GPT-4o transcribe + responde (con contexto inicial)
|
|
||||||
-> Claude recibe transcripcion
|
|
||||||
-> Claude analiza, busca en knowledge base
|
|
||||||
-> Claude prepara contexto enriquecido
|
|
||||||
|
|
||||||
TURNO 2:
|
|
||||||
Usuario habla -> GPT-4o responde (ahora con contexto de Claude)
|
|
||||||
-> Claude sigue analizando...
|
|
||||||
-> Claude actualiza contexto
|
|
||||||
|
|
||||||
TURNO N:
|
|
||||||
El ciclo continua. GPT siempre tiene el ultimo contexto de Claude.
|
|
||||||
```
|
|
||||||
|
|
||||||
## 3.4 Componentes
|
|
||||||
|
|
||||||
### GPT-4o Realtime (Portavoz)
|
|
||||||
- **Funcion**: Frontend de voz con latencia minima
|
|
||||||
- **API**: OpenAI Realtime API
|
|
||||||
- **Latencia**: ~300ms end-to-end
|
|
||||||
- **Responsabilidades**:
|
|
||||||
- Transcripcion de voz (ASR integrado)
|
|
||||||
- Generacion de respuesta
|
|
||||||
- Sintesis de voz (TTS integrado)
|
|
||||||
- **Limitaciones**: Contexto limitado, razonamiento superficial
|
|
||||||
|
|
||||||
### Claude (Cerebro)
|
|
||||||
- **Funcion**: Analisis profundo en segundo plano
|
|
||||||
- **API**: Anthropic Messages API
|
|
||||||
- **Latencia**: 1-3s (no bloquea la conversacion)
|
|
||||||
- **Responsabilidades**:
|
|
||||||
- Analizar intencion del usuario
|
|
||||||
- Buscar en knowledge base
|
|
||||||
- Preparar datos relevantes
|
|
||||||
- Generar instrucciones para GPT
|
|
||||||
- Detectar cuando GPT necesita correccion
|
|
||||||
|
|
||||||
## 3.5 Actualizacion de Contexto
|
|
||||||
|
|
||||||
Claude genera un "folio" que se inyecta en el system prompt de GPT:
|
|
||||||
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"context_update": {
|
|
||||||
"timestamp": "2025-12-18T10:30:00Z",
|
|
||||||
"user_intent": "Consulta sobre factura pendiente",
|
|
||||||
"relevant_data": {
|
|
||||||
"factura_id": "F-2024-1234",
|
|
||||||
"importe": 1500.00,
|
|
||||||
"vencimiento": "2025-01-15",
|
|
||||||
"estado": "pendiente"
|
|
||||||
},
|
|
||||||
"suggested_response_elements": [
|
|
||||||
"Confirmar importe de la factura",
|
|
||||||
"Mencionar fecha de vencimiento",
|
|
||||||
"Ofrecer opciones de pago"
|
|
||||||
],
|
|
||||||
"tone_guidance": "profesional pero cercano",
|
|
||||||
"warnings": [
|
|
||||||
"Cliente tiene 2 facturas mas pendientes - no mencionar a menos que pregunte"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
Este contexto se traduce a instrucciones en el system prompt de GPT:
|
|
||||||
|
|
||||||
```
|
|
||||||
[CONTEXTO ACTUALIZADO - Turno 3]
|
|
||||||
El usuario pregunta por una factura. Datos relevantes:
|
|
||||||
- Factura F-2024-1234 por 1500 EUR
|
|
||||||
- Vence el 15 de enero 2025
|
|
||||||
- Estado: pendiente
|
|
||||||
|
|
||||||
En tu respuesta:
|
|
||||||
- Confirma el importe
|
|
||||||
- Menciona la fecha de vencimiento
|
|
||||||
- Ofrece opciones de pago
|
|
||||||
|
|
||||||
Tono: profesional pero cercano
|
|
||||||
Nota: El cliente tiene otras facturas pendientes, no las menciones a menos que pregunte.
|
|
||||||
```
|
|
||||||
|
|
||||||
## 3.6 Manejo de Errores y Correcciones
|
|
||||||
|
|
||||||
Si Claude detecta que GPT dio informacion incorrecta:
|
|
||||||
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"correction_needed": true,
|
|
||||||
"correction_type": "factual_error",
|
|
||||||
"what_gpt_said": "La factura vence manana",
|
|
||||||
"correct_info": "La factura vence el 15 de enero",
|
|
||||||
"inject_correction": true
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
GPT recibe instruccion de corregirse naturalmente:
|
|
||||||
```
|
|
||||||
[CORRECCION NECESARIA]
|
|
||||||
En tu respuesta anterior mencionaste que la factura vence manana.
|
|
||||||
La fecha correcta es el 15 de enero.
|
|
||||||
Corrige esto de forma natural en tu proxima respuesta, sin disculparte excesivamente.
|
|
||||||
```
|
|
||||||
|
|
||||||
## 3.7 Configuracion de Sesion
|
|
||||||
|
|
||||||
Request de inicio de sesion PENNY EXTERNAL:
|
|
||||||
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"type": "session_start",
|
|
||||||
"mode": "EXTERNAL",
|
|
||||||
|
|
||||||
"portavoz": {
|
|
||||||
"provider": "openai",
|
|
||||||
"model": "gpt-4o-realtime",
|
|
||||||
"voice": "alloy",
|
|
||||||
"language": "es",
|
|
||||||
"initial_system_prompt": "Eres un asistente de voz profesional..."
|
|
||||||
},
|
|
||||||
|
|
||||||
"cerebro": {
|
|
||||||
"provider": "anthropic",
|
|
||||||
"model": "claude-sonnet-4-20250514",
|
|
||||||
"analysis_depth": "standard",
|
|
||||||
"knowledge_base_ref": "kb://empresa/documentos",
|
|
||||||
"update_frequency": "every_turn"
|
|
||||||
},
|
|
||||||
|
|
||||||
"context": {
|
|
||||||
"user_id": "uuid",
|
|
||||||
"session_purpose": "atencion_cliente",
|
|
||||||
"available_actions": ["consultar_factura", "programar_pago", "transferir_humano"]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
## 3.8 Costos Estimados
|
|
||||||
|
|
||||||
| Componente | Costo por minuto |
|
|
||||||
|------------|------------------|
|
|
||||||
| GPT-4o Realtime (audio) | ~$0.06 |
|
|
||||||
| Claude Sonnet (analisis) | ~$0.02 |
|
|
||||||
| **Total** | **~$0.08/min** |
|
|
||||||
|
|
||||||
Para una conversacion de 5 minutos: ~$0.40
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
# 4. Seleccion de Modo en DECK
|
|
||||||
|
|
||||||
DECK presenta la opcion al usuario al iniciar sesion de voz:
|
|
||||||
|
|
||||||
```yaml
|
|
||||||
# deck/config/penny.yaml
|
|
||||||
|
|
||||||
penny:
|
|
||||||
default_mode: SELF_HOSTED
|
|
||||||
allow_user_selection: true
|
|
||||||
|
|
||||||
modes:
|
|
||||||
SELF_HOSTED:
|
|
||||||
label: "Privado (modelos locales)"
|
|
||||||
description: "Mayor privacidad, latencia 2-4s"
|
|
||||||
endpoint: "wss://api.runpod.ai/v2/${PENNY_ENDPOINT}/ws"
|
|
||||||
|
|
||||||
EXTERNAL:
|
|
||||||
label: "Rapido (APIs externas)"
|
|
||||||
description: "Conversacion fluida, latencia ~300ms"
|
|
||||||
portavoz_provider: "openai"
|
|
||||||
cerebro_provider: "anthropic"
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
# 5. Comparativa de Modos
|
|
||||||
|
|
||||||
| Aspecto | SELF_HOSTED | EXTERNAL |
|
|
||||||
|---------|-------------|----------|
|
|
||||||
| Latencia | 2-4s | ~300ms |
|
|
||||||
| Costo/min | ~$0.01 | ~$0.08 |
|
|
||||||
| Privacidad | Total | Datos a OpenAI/Anthropic |
|
|
||||||
| Calidad respuesta | Buena (Qwen 7B) | Excelente (Claude) |
|
|
||||||
| Experiencia | Aceptable | Conversacional |
|
|
||||||
| Cold start | 15-30s (primer uso) | Inmediato |
|
|
||||||
| Dependencias | RunPod | OpenAI + Anthropic APIs |
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
# 6. Casos de Uso Recomendados
|
|
||||||
|
|
||||||
**SELF_HOSTED**:
|
|
||||||
- Datos sensibles / confidenciales
|
|
||||||
- Uso interno empresarial
|
|
||||||
- Demostraciones sin conexion externa
|
|
||||||
- Minimizar costos en alto volumen
|
|
||||||
|
|
||||||
**EXTERNAL**:
|
|
||||||
- Atencion al cliente en tiempo real
|
|
||||||
- Demos a inversores / clientes
|
|
||||||
- Conversaciones donde la fluidez importa
|
|
||||||
- Usuarios impacientes
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
**Fin del Documento PENNY - Version 1.0**
|
|
||||||
|
|
||||||
*Sistema PENNY - "Portavoz + Cerebro"*
|
|
||||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -1,298 +0,0 @@
|
|||||||
# CORP
|
|
||||||
|
|
||||||
**Servidor Empresarial - Ecosistema TZZR**
|
|
||||||
|
|
||||||
## Servidor
|
|
||||||
|
|
||||||
- **IP**: 92.112.181.188
|
|
||||||
- **Dominio**: tzzrcorp.me
|
|
||||||
- **SSH**: Autenticación por key (no password)
|
|
||||||
- **Acceso**: `ssh -i ~/.ssh/id_ed25519_server root@92.112.181.188`
|
|
||||||
|
|
||||||
## Servicios Activos (Actualizado 2025-12-23)
|
|
||||||
|
|
||||||
| Servicio | URL | Puerto | Estado |
|
|
||||||
|----------|-----|--------|--------|
|
|
||||||
| Directus | https://directus.tzzrcorp.me | 8055 | OK |
|
|
||||||
| Nextcloud | https://nextcloud.tzzrcorp.me | 8080 | OK |
|
|
||||||
| Vaultwarden | https://vault.tzzrcorp.me | 8081 | OK |
|
|
||||||
| Shlink | https://shlink.tzzrcorp.me | 8082 | OK |
|
|
||||||
| Addy | https://addy.tzzrcorp.me | 8083 | OK |
|
|
||||||
| Odoo | https://erp.tzzrcorp.me | 8069 | OK |
|
|
||||||
| ntfy | https://ntfy.tzzrcorp.me | 8880 | OK |
|
|
||||||
| HSU API | https://hsu.tzzrcorp.me | 5002 | OK |
|
|
||||||
| Redis | (interno) | 6379 | OK |
|
|
||||||
| PostgreSQL | (interno) | 5432 | OK |
|
|
||||||
| Caddy | (proxy) | 80/443 | OK |
|
|
||||||
|
|
||||||
### Directus (Admin)
|
|
||||||
|
|
||||||
```
|
|
||||||
URL: https://directus.tzzrcorp.me
|
|
||||||
Admin: admin@tzzr.me
|
|
||||||
Pass: directus_corp_2024
|
|
||||||
```
|
|
||||||
|
|
||||||
### Nextcloud
|
|
||||||
|
|
||||||
```
|
|
||||||
URL: https://nextcloud.tzzrcorp.me
|
|
||||||
Admin: admin
|
|
||||||
Pass: nextcloud_corp_2024
|
|
||||||
```
|
|
||||||
|
|
||||||
### HSU API (Biblioteca Usuario)
|
|
||||||
|
|
||||||
```
|
|
||||||
URL: https://hsu.tzzrcorp.me/api/biblioteca
|
|
||||||
PIN: 123456
|
|
||||||
```
|
|
||||||
|
|
||||||
## PostgreSQL
|
|
||||||
|
|
||||||
```
|
|
||||||
Host: localhost
|
|
||||||
Port: 5432
|
|
||||||
User: corp
|
|
||||||
Password: corp
|
|
||||||
```
|
|
||||||
|
|
||||||
### Bases de datos
|
|
||||||
|
|
||||||
| DB | Uso |
|
|
||||||
|----|-----|
|
|
||||||
| corp | Principal, Directus |
|
|
||||||
| nextcloud | Nextcloud |
|
|
||||||
| shlink | Shlink |
|
|
||||||
| odoo | Odoo ERP |
|
|
||||||
|
|
||||||
### Tablas de Negocio
|
|
||||||
|
|
||||||
| Tabla | Descripción |
|
|
||||||
|-------|-------------|
|
|
||||||
| hst_mirror | Mirror de tags HST |
|
|
||||||
| hsu | Tags de usuario |
|
|
||||||
| flu | Tags de flujo |
|
|
||||||
| pju | Tags de proyecto |
|
|
||||||
| spu | Tags de sistema |
|
|
||||||
| vsu | Tags de vista |
|
|
||||||
| vuu | Tags de usuario vista |
|
|
||||||
|
|
||||||
## Migraciones Completadas
|
|
||||||
|
|
||||||
### NocoDB → Directus (2025-12-23)
|
|
||||||
|
|
||||||
- [x] NocoDB reemplazado por Directus
|
|
||||||
- [x] Nextcloud instalado
|
|
||||||
- [x] HSU API implementada
|
|
||||||
- [x] Caddy como reverse proxy con SSL
|
|
||||||
|
|
||||||
## DNS (tzzrcorp.me)
|
|
||||||
|
|
||||||
```zone
|
|
||||||
@ A 92.112.181.188
|
|
||||||
directus A 92.112.181.188
|
|
||||||
nextcloud A 92.112.181.188
|
|
||||||
vault A 92.112.181.188
|
|
||||||
shlink A 92.112.181.188
|
|
||||||
addy A 92.112.181.188
|
|
||||||
erp A 92.112.181.188
|
|
||||||
ntfy A 92.112.181.188
|
|
||||||
hsu A 92.112.181.188
|
|
||||||
db A 92.112.181.188
|
|
||||||
```
|
|
||||||
|
|
||||||
## Descripción
|
|
||||||
|
|
||||||
CORP es el **servidor empresarial** que gestiona la información de negocios. Cada empresa tiene sus propios datos aislados: clientes, productos, pedidos, facturas, y métricas.
|
|
||||||
|
|
||||||
## Arquitectura
|
|
||||||
|
|
||||||
```
|
|
||||||
┌─────────────────────────────────────────────────────────────────┐
|
|
||||||
│ CORP │
|
|
||||||
│ (Servidor Empresarial) │
|
|
||||||
├─────────────────────────────────────────────────────────────────┤
|
|
||||||
│ │
|
|
||||||
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
|
|
||||||
│ │ MIND │ │ WINDMILL │ │ ODOO │ │
|
|
||||||
│ │ LINK │ │ (Workflows)│ │ (ERP) │ │
|
|
||||||
│ └──────┬──────┘ └──────┬──────┘ └──────┬──────┘ │
|
|
||||||
│ │ │ │ │
|
|
||||||
│ └────────────────┼────────────────┘ │
|
|
||||||
│ │ │
|
|
||||||
│ ┌──────┴──────┐ │
|
|
||||||
│ │ CLARA │ ← Director Completo │
|
|
||||||
│ │ +MASON │ │
|
|
||||||
│ │ +NOTARIO │ │
|
|
||||||
│ │ +SENTINEL │ │
|
|
||||||
│ └──────┬──────┘ │
|
|
||||||
│ │ │
|
|
||||||
│ ┌───────────────────────┼───────────────────────┐ │
|
|
||||||
│ │ PostgreSQL + Directus │ │
|
|
||||||
│ │ ┌────────┐ ┌────────┐ ┌────────┐ ┌────────┐ │ │
|
|
||||||
│ │ │Clientes│ │Productos│ │Pedidos │ │Facturas│ │ │
|
|
||||||
│ │ └────────┘ └────────┘ └────────┘ └────────┘ │ │
|
|
||||||
│ └───────────────────────────────────────────────┘ │
|
|
||||||
│ │
|
|
||||||
└─────────────────────────────────────────────────────────────────┘
|
|
||||||
```
|
|
||||||
|
|
||||||
## Simulación: TZZR Tailoring
|
|
||||||
|
|
||||||
CORP simula una **startup de sastrería** a medida:
|
|
||||||
|
|
||||||
### Modelo de Negocio
|
|
||||||
|
|
||||||
- **Producto**: Trajes MTM (Made-to-Measure) importados de China
|
|
||||||
- **Precio**: €299-499 (mercado: €800-1500)
|
|
||||||
- **Margen**: ~300%
|
|
||||||
- **Canal**: Online + cita previa
|
|
||||||
|
|
||||||
### Datos Iniciales
|
|
||||||
|
|
||||||
```
|
|
||||||
Capital inicial: €5,000
|
|
||||||
Burn mensual: €600
|
|
||||||
Runway: 8.3 meses
|
|
||||||
|
|
||||||
Productos:
|
|
||||||
- Traje Negro Clásico: €299 (coste: €85)
|
|
||||||
- Traje Azul Marino: €349 (coste: €95)
|
|
||||||
- Traje Gris Medio: €329 (coste: €90)
|
|
||||||
- Traje Gris Oscuro: €379 (coste: €100)
|
|
||||||
```
|
|
||||||
|
|
||||||
## Tablas Principales
|
|
||||||
|
|
||||||
```sql
|
|
||||||
corp_config -- Configuración de empresa
|
|
||||||
corp_productos -- Catálogo de productos
|
|
||||||
corp_clientes -- Clientes con historial
|
|
||||||
corp_medidas -- Medidas de clientes
|
|
||||||
corp_pedidos -- Pedidos con estado
|
|
||||||
corp_pedido_lineas -- Líneas de pedido
|
|
||||||
corp_facturas -- Facturas certificadas
|
|
||||||
corp_transacciones -- Ingresos y gastos
|
|
||||||
corp_metricas -- Métricas diarias
|
|
||||||
corp_tareas -- Workflow de tareas
|
|
||||||
corp_ia_solicitudes -- Peticiones a FACTORY
|
|
||||||
```
|
|
||||||
|
|
||||||
## Flujos de Negocio
|
|
||||||
|
|
||||||
### Nuevo Pedido
|
|
||||||
|
|
||||||
```
|
|
||||||
1. Cliente solicita → crear cliente si nuevo
|
|
||||||
2. Tomar medidas → guardar en corp_medidas
|
|
||||||
3. Crear pedido → generar número ORD-YYYY-XXXX
|
|
||||||
4. Confirmar pago → registrar transacción
|
|
||||||
5. Enviar a fábrica → actualizar estado
|
|
||||||
6. Recibir producto → crear BCK (foto)
|
|
||||||
7. Entregar → generar factura
|
|
||||||
```
|
|
||||||
|
|
||||||
### Generar Factura
|
|
||||||
|
|
||||||
```
|
|
||||||
1. Pedido completado
|
|
||||||
│
|
|
||||||
▼
|
|
||||||
2. CLARA.handleDocumentGeneration()
|
|
||||||
│
|
|
||||||
▼
|
|
||||||
3. MASON prepara datos (cliente, productos, totales)
|
|
||||||
│
|
|
||||||
▼
|
|
||||||
4. FACTORY genera PDF iterativamente
|
|
||||||
│
|
|
||||||
▼
|
|
||||||
5. NOTARIO certifica (hash + timestamp)
|
|
||||||
│
|
|
||||||
▼
|
|
||||||
6. LOCKER almacena (locker://corp/facturas/FAC-2025-0001.pdf)
|
|
||||||
│
|
|
||||||
▼
|
|
||||||
7. Enviar por email
|
|
||||||
```
|
|
||||||
|
|
||||||
## Windmill Workflows
|
|
||||||
|
|
||||||
| Workflow | Trigger | Acción |
|
|
||||||
|----------|---------|--------|
|
|
||||||
| New Order | Webhook | Crea pedido → envía confirmación |
|
|
||||||
| Generate Invoice | Webhook | FACTORY genera → NOTARIO certifica |
|
|
||||||
| Daily Metrics | Cron | Calcula métricas del día |
|
|
||||||
| Low Stock Alert | Cron | Notifica productos bajo stock |
|
|
||||||
|
|
||||||
## Vistas Útiles
|
|
||||||
|
|
||||||
```sql
|
|
||||||
-- Dashboard financiero
|
|
||||||
v_corp_dashboard_financiero
|
|
||||||
→ capital_inicial, ingresos, gastos, caja_actual, runway_meses
|
|
||||||
|
|
||||||
-- Pedidos con detalle
|
|
||||||
v_corp_pedidos_detalle
|
|
||||||
→ numero, cliente, estado, total, num_lineas
|
|
||||||
|
|
||||||
-- Facturas pendientes
|
|
||||||
v_corp_facturas_pendientes
|
|
||||||
→ numero, cliente, total, dias_vencido
|
|
||||||
|
|
||||||
-- Stock bajo
|
|
||||||
v_corp_stock_bajo
|
|
||||||
→ sku, nombre, stock, stock_minimo
|
|
||||||
```
|
|
||||||
|
|
||||||
## Template Clonable
|
|
||||||
|
|
||||||
CORP puede clonarse para un nuevo negocio:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Usar template
|
|
||||||
psql -U tzzr -d nueva_empresa -f templates/corp-template.sql
|
|
||||||
|
|
||||||
# Reemplazar variables
|
|
||||||
sed -i 's/{{COMPANY_NAME}}/Mi Empresa/g' ...
|
|
||||||
sed -i 's/{{INITIAL_CAPITAL}}/10000/g' ...
|
|
||||||
```
|
|
||||||
|
|
||||||
## Estructura
|
|
||||||
|
|
||||||
```
|
|
||||||
corp/
|
|
||||||
├── database/
|
|
||||||
│ ├── corp-schema.sql
|
|
||||||
│ └── corp-template.sql
|
|
||||||
├── docker/
|
|
||||||
│ └── docker-compose.yml
|
|
||||||
├── windmill/
|
|
||||||
│ ├── new-order.yaml
|
|
||||||
│ └── generate-invoice.yaml
|
|
||||||
├── docs/
|
|
||||||
└── README.md
|
|
||||||
```
|
|
||||||
|
|
||||||
## Repositorios Relacionados
|
|
||||||
|
|
||||||
| Repo | Rol |
|
|
||||||
|------|-----|
|
|
||||||
| [clara](https://github.com/tzzrgit/clara) | Orquestador de CORP |
|
|
||||||
| [deck](https://github.com/tzzrgit/deck) | Equivalente personal |
|
|
||||||
| [the-factory](https://github.com/tzzrgit/the-factory) | Genera documentos |
|
|
||||||
| [notario](https://github.com/tzzrgit/notario) | Certifica facturas |
|
|
||||||
| [locker](https://github.com/tzzrgit/locker) | Almacena documentos |
|
|
||||||
| [contable](https://github.com/tzzrgit/contable) | Libros contables |
|
|
||||||
|
|
||||||
## Roadmap
|
|
||||||
|
|
||||||
- [x] Schema PostgreSQL
|
|
||||||
- [x] Template clonable
|
|
||||||
- [x] CLARA orquestador
|
|
||||||
- [x] Windmill workflows
|
|
||||||
- [ ] Integración Odoo
|
|
||||||
- [ ] Multi-empresa
|
|
||||||
- [ ] Reportes automáticos
|
|
||||||
- [ ] Facturación electrónica
|
|
||||||
@@ -1,40 +0,0 @@
|
|||||||
# CORP Status
|
|
||||||
|
|
||||||
Servidor: tzrtech.com (92.112.181.188)
|
|
||||||
Fecha: 2025-12-19
|
|
||||||
|
|
||||||
## Estado: Integración HST completada
|
|
||||||
|
|
||||||
## NocoDB
|
|
||||||
|
|
||||||
- URL: http://92.112.181.188:8080
|
|
||||||
- Email: admin@tzrtech.com
|
|
||||||
|
|
||||||
## Tablas
|
|
||||||
|
|
||||||
Mismas 7 tablas que DECK:
|
|
||||||
- hst_mirror: 973 registros sincronizados
|
|
||||||
- hsu, spu, flu, vsu, vuu, pju (tablas usuario)
|
|
||||||
|
|
||||||
## Sync por grupo
|
|
||||||
|
|
||||||
| Grupo | Cantidad |
|
|
||||||
|-------|----------|
|
|
||||||
| hst | 639 |
|
|
||||||
| spe | 145 |
|
|
||||||
| vsn | 84 |
|
|
||||||
| flg | 65 |
|
|
||||||
| vue | 21 |
|
|
||||||
| **Total** | **973** |
|
|
||||||
|
|
||||||
## Pendiente
|
|
||||||
|
|
||||||
- [ ] Webhooks/polling para sync con HST
|
|
||||||
- [ ] Lógica descarga imágenes
|
|
||||||
- [ ] Subdominios locales
|
|
||||||
- [ ] API usuarios
|
|
||||||
|
|
||||||
## R2 Storage
|
|
||||||
|
|
||||||
Bucket: `corp`
|
|
||||||
Ver credenciales en Infisical (project: r2)
|
|
||||||
@@ -1,79 +0,0 @@
|
|||||||
# GESTIÓN DE CREDENCIALES
|
|
||||||
|
|
||||||
**Sistema TZZR - Manual de Arquitectura Técnica v5.0**
|
|
||||||
**Fecha:** 22 de diciembre de 2024
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
> ⚠️ **REPO PRIVADO** - Contiene información sensible
|
|
||||||
|
|
||||||
## Principio Fundamental: KEY VAULT
|
|
||||||
|
|
||||||
> *"Las llaves nunca viajan con los datos que protegen"*
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Estructura del Repo
|
|
||||||
|
|
||||||
```
|
|
||||||
credentials/
|
|
||||||
├── README.md # Este documento
|
|
||||||
├── inventario/
|
|
||||||
│ ├── 01-apis-ia.md # OpenRouter, Groq, OpenAI, Anthropic
|
|
||||||
│ ├── 02-bases-datos.md # PostgreSQL, Directus, Redis
|
|
||||||
│ ├── 03-almacenamiento.md # Storj, R2, Arweave
|
|
||||||
│ ├── 04-infraestructura.md # n8n, Nextcloud, Nginx, Windmill
|
|
||||||
│ ├── 05-blockchain.md # Polygon, NOTARIO
|
|
||||||
│ ├── 06-comunicaciones.md # Resend, Slack, ntfy
|
|
||||||
│ ├── 07-dns-cdn.md # Cloudflare, Let's Encrypt
|
|
||||||
│ ├── 08-gpu-runpod.md # GRACE, PENNY, THE FACTORY
|
|
||||||
│ ├── 09-servidores.md # SSH credentials
|
|
||||||
│ └── 10-cifrado.md # Master Key, KEKs
|
|
||||||
├── politicas/
|
|
||||||
│ ├── rotacion.md # Matriz de rotación
|
|
||||||
│ ├── envelope-encryption.md # Jerarquía de llaves
|
|
||||||
│ └── respuesta-incidentes.md # Procedimientos
|
|
||||||
└── infisical/
|
|
||||||
└── configuracion.md # Setup Infisical
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Gestor de Secretos: Infisical
|
|
||||||
|
|
||||||
| Parámetro | Valor |
|
|
||||||
|-----------|-------|
|
|
||||||
| **URL** | http://69.62.126.110:8082 |
|
|
||||||
| **Proyectos** | anthropic, servers, databases, r2 |
|
|
||||||
| **Acceso** | Machine Identities por cada Claude |
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Resumen Ejecutivo
|
|
||||||
|
|
||||||
| Métrica | Valor |
|
|
||||||
|---------|-------|
|
|
||||||
| **Total de credenciales gestionadas** | ~45 credenciales activas |
|
|
||||||
| **Gestor centralizado** | Infisical (4 proyectos) |
|
|
||||||
| **Servidores** | 4 (ARCHITECT, HST, DECK, CORP) |
|
|
||||||
| **Servicios de IA** | 4 (OpenRouter, Groq, OpenAI, Anthropic) |
|
|
||||||
| **Backends de almacenamiento** | 3 (Hostinger, Storj/R2, Arweave) |
|
|
||||||
| **Endpoints GPU** | 3 (GRACE, PENNY, THE FACTORY) |
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Matriz de Rotación (Resumen)
|
|
||||||
|
|
||||||
| Tipo | Rotación | Ejemplos |
|
|
||||||
|------|----------|----------|
|
|
||||||
| `API_KEY` | 90 días | OpenRouter, Groq, Cloudflare |
|
|
||||||
| `DB_CREDENTIAL` | 30 días | PostgreSQL, Redis |
|
|
||||||
| `SERVICE_TOKEN` | 7 días | n8n, Nextcloud, Slack |
|
|
||||||
| `CERTIFICATE` | 90 días | SSL/TLS (auto) |
|
|
||||||
| `SIGNING_KEY` | 180 días | JWT, KEK-SIGNING |
|
|
||||||
| `ENCRYPTION_KEY` | 365 días | AES-256, KEK-DATA |
|
|
||||||
| `SSH_CREDENTIAL` | 180 días | Llaves SSH |
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
*Sistema TZZR v5.0 - Documento Confidencial*
|
|
||||||
@@ -1,280 +0,0 @@
|
|||||||
# DECK
|
|
||||||
|
|
||||||

|
|
||||||
|
|
||||||
|
|
||||||
**Servidor Personal del Ecosistema TZZR**
|
|
||||||
|
|
||||||
## Descripción
|
|
||||||
|
|
||||||
DECK es el **servidor personal** que gestiona la vida digital de un usuario. Incluye:
|
|
||||||
|
|
||||||
- **Vision Builder**: Crear visiones → milestones (MST) → acciones y hábitos → evidencias (BCK)
|
|
||||||
- **Mind Link**: Interfaz unificada de acceso a servicios
|
|
||||||
- **ALFRED**: Orquestador lite que decide cómo procesar cada petición
|
|
||||||
- **Windmill**: Automatización de workflows (alternativa a n8n)
|
|
||||||
- **HST Tags**: Etiquetado semántico personal
|
|
||||||
|
|
||||||
## Arquitectura
|
|
||||||
|
|
||||||
```
|
|
||||||
┌──────────────────────────────────────────────────────────────────┐
|
|
||||||
│ DECK │
|
|
||||||
│ (Servidor Personal) │
|
|
||||||
├──────────────────────────────────────────────────────────────────┤
|
|
||||||
│ │
|
|
||||||
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
|
|
||||||
│ │ VISION │ │ MIND │ │ WINDMILL │ │
|
|
||||||
│ │ BUILDER │ │ LINK │ │ (Workflows)│ │
|
|
||||||
│ └──────┬──────┘ └──────┬──────┘ └──────┬──────┘ │
|
|
||||||
│ │ │ │ │
|
|
||||||
│ └────────────────┼────────────────┘ │
|
|
||||||
│ │ │
|
|
||||||
│ ┌──────┴──────┐ │
|
|
||||||
│ │ ALFRED │ ← Orquestador Lite │
|
|
||||||
│ │ (decide) │ │
|
|
||||||
│ └──────┬──────┘ │
|
|
||||||
│ │ │
|
|
||||||
│ ┌───────────────────────┼───────────────────────┐ │
|
|
||||||
│ │ PostgreSQL + Directus │ │
|
|
||||||
│ │ ┌────────┐ ┌────────┐ ┌────────┐ ┌────────┐ │ │
|
|
||||||
│ │ │Visiones│ │ MST │ │Acciones│ │Hábitos │ │ │
|
|
||||||
│ │ └────────┘ └────────┘ └────────┘ └────────┘ │ │
|
|
||||||
│ └───────────────────────────────────────────────┘ │
|
|
||||||
│ │ │
|
|
||||||
└───────────────────────────┼──────────────────────────────────────┘
|
|
||||||
│
|
|
||||||
┌───────────────┼───────────────┐
|
|
||||||
▼ ▼ ▼
|
|
||||||
┌──────────┐ ┌──────────┐ ┌──────────┐
|
|
||||||
│ GRACE │ │ PENNY │ │ FACTORY │
|
|
||||||
│(process) │ │ (text) │ │(iterate) │
|
|
||||||
└──────────┘ └──────────┘ └──────────┘
|
|
||||||
```
|
|
||||||
|
|
||||||
## Servidor
|
|
||||||
|
|
||||||
- **IP**: 72.62.1.113
|
|
||||||
- **Dominio**: tzzrdeck.me
|
|
||||||
- **VPS**: Hostinger (Ubuntu 22.04, 8GB RAM, 100GB SSD)
|
|
||||||
- **SSH**: `ssh root@72.62.1.113` (password en credentials repo)
|
|
||||||
|
|
||||||
## Servicios Docker (Actualizado 2025-12-22)
|
|
||||||
|
|
||||||
| Servicio | Puerto | Estado | Función |
|
|
||||||
|----------|--------|--------|---------|
|
|
||||||
| PostgreSQL | 5432 | UP (healthy) | Base de datos principal |
|
|
||||||
| Directus | 8055 | UP | CMS/Admin (reemplaza al antiguo NocoDB) |
|
|
||||||
| Mailcow | 8180 + mail ports | UP | Servidor de correo |
|
|
||||||
| FileBrowser | 8082 | UP (healthy) | Gestión de archivos |
|
|
||||||
| Shlink | 8083 | UP | Acortador de URLs |
|
|
||||||
| Vaultwarden | 8085 | UP (healthy) | Gestor de contraseñas |
|
|
||||||
| ntfy | 8080 | UP | Notificaciones push |
|
|
||||||
| Odoo | 8069 | UP | ERP |
|
|
||||||
| Redis | 6379 | UP | Cache (Mailcow) |
|
|
||||||
|
|
||||||
### Directus (Admin)
|
|
||||||
|
|
||||||
```
|
|
||||||
URL: http://72.62.1.113:8055
|
|
||||||
Email: admin@tzzr.me
|
|
||||||
Password: DirectusDeck2024!
|
|
||||||
```
|
|
||||||
|
|
||||||
### Mailcow
|
|
||||||
|
|
||||||
```
|
|
||||||
URL: http://mail.tzzr.net
|
|
||||||
Puertos: 25 (SMTP), 465 (SMTPS), 587 (Submission), 143 (IMAP), 993 (IMAPS)
|
|
||||||
Admin: admin / moohoo (cambiar al primer login)
|
|
||||||
Ubicación: /opt/mailcow
|
|
||||||
```
|
|
||||||
|
|
||||||
## Bases de Datos PostgreSQL
|
|
||||||
|
|
||||||
| Base de datos | Uso |
|
|
||||||
|---------------|-----|
|
|
||||||
| tzzr | BD principal (deck_*, tablas legacy) |
|
|
||||||
| directus | Directus CMS |
|
|
||||||
| shlink | URL shortener |
|
|
||||||
|
|
||||||
## Migraciones Completadas
|
|
||||||
|
|
||||||
### NocoDB → Directus (2025-12-22)
|
|
||||||
|
|
||||||
- NocoDB eliminado completamente
|
|
||||||
- Directus instalado y operativo
|
|
||||||
- Datos preservados en PostgreSQL
|
|
||||||
|
|
||||||
## DNS (tzzrdeck.me)
|
|
||||||
|
|
||||||
```zone
|
|
||||||
; tzzrdeck.me → 72.62.1.113
|
|
||||||
@ A 72.62.1.113
|
|
||||||
mail A 72.62.1.113
|
|
||||||
directus A 72.62.1.113
|
|
||||||
db A 72.62.1.113
|
|
||||||
shlink A 72.62.1.113
|
|
||||||
link A 72.62.1.113
|
|
||||||
odoo A 72.62.1.113
|
|
||||||
erp A 72.62.1.113
|
|
||||||
vault A 72.62.1.113
|
|
||||||
files A 72.62.1.113
|
|
||||||
ntfy A 72.62.1.113
|
|
||||||
|
|
||||||
; Mail
|
|
||||||
@ MX 10 mail.tzzrdeck.me.
|
|
||||||
@ TXT "v=spf1 mx a ip4:72.62.1.113 -all"
|
|
||||||
_dmarc TXT "v=DMARC1; p=reject; rua=mailto:postmaster@tzzrdeck.me"
|
|
||||||
dkim._domainkey TXT "v=DKIM1; k=rsa; p=MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAoF3v+ytuXDr7AVJ5aPkQC7EV95Nr8zjRRYxwgrYPGsNrDOcjG5/8iwJRvdporYxoMKOoeKWTVkOlnLBUMjhP5wdGtJY63jQDjs5bybtXyZpLC+3xbwTGRk4fGOodzkhRabkaz0HxZrp/5tGqjZEv77pfX7Jpm0qAmFC2wBoYRlXngp7Eno9k7jSrGDb1f/gCgWV5wWGr7J+ny0/gScSkitp2hwTB+tV5504T4hMajxkff1iQhFTAPHiUQHzNpiq3zF+yaOE1KfbtdLTIDYBvgTQsINa4qLNbQXVQfk30+CHO/rzAb1wOdByrRO+O7IXJ+OA2Reqz/jlPIOIj7o7B7QIDAQAB"
|
|
||||||
autodiscover CNAME mail.tzzrdeck.me.
|
|
||||||
autoconfig CNAME mail.tzzrdeck.me.
|
|
||||||
```
|
|
||||||
|
|
||||||
**NOTA:** Registros en "DNS only" (nube gris) para SSL automático.
|
|
||||||
|
|
||||||
## Vision Builder
|
|
||||||
|
|
||||||
Sistema de construcción de visiones que se convierten en acciones:
|
|
||||||
|
|
||||||
```
|
|
||||||
VISIÓN → MST (Milestones) → ACCIONES + HÁBITOS → BCK (Evidencias)
|
|
||||||
```
|
|
||||||
|
|
||||||
### Tipos de Visión
|
|
||||||
|
|
||||||
| Tipo | Descripción | Ejemplo |
|
|
||||||
|------|-------------|---------|
|
|
||||||
| fitness | Transformación física | Perder 10kg en 12 semanas |
|
|
||||||
| career | Desarrollo profesional | Conseguir ascenso |
|
|
||||||
| project | Proyecto específico | Lanzar MVP |
|
|
||||||
| habit | Crear hábito | Meditar diario |
|
|
||||||
| learning | Aprendizaje | Dominar Python |
|
|
||||||
| finance | Finanzas | Ahorrar €10k |
|
|
||||||
|
|
||||||
### Acciones vs Hábitos
|
|
||||||
|
|
||||||
| Concepto | Descripción | Ejemplo |
|
|
||||||
|----------|-------------|---------|
|
|
||||||
| **Acción** | Tarea única | Comprar báscula |
|
|
||||||
| **Hábito** | Comportamiento recurrente | Entrenar 5x/semana |
|
|
||||||
|
|
||||||
## ALFRED (Orquestador)
|
|
||||||
|
|
||||||
ALFRED decide automáticamente qué servicio usar:
|
|
||||||
|
|
||||||
```javascript
|
|
||||||
// Mapeo de intenciones
|
|
||||||
"resumir" → GRACE.SUMMARIZER
|
|
||||||
"transcribir" → GRACE.ASR_ENGINE
|
|
||||||
"generar plan" → PENNY
|
|
||||||
"crear imagen" → FACTORY
|
|
||||||
```
|
|
||||||
|
|
||||||
## Tablas Principales
|
|
||||||
|
|
||||||
```sql
|
|
||||||
deck_visiones -- Visiones del usuario
|
|
||||||
deck_milestones -- MST: objetivos con fecha
|
|
||||||
deck_acciones -- Tareas únicas
|
|
||||||
deck_habitos -- Comportamientos recurrentes
|
|
||||||
deck_habito_registros -- Tracking diario de hábitos
|
|
||||||
deck_bck -- Bloques de evidencia
|
|
||||||
deck_emails -- Correos sincronizados
|
|
||||||
deck_ia_solicitudes -- Peticiones a GRACE/PENNY/FACTORY
|
|
||||||
```
|
|
||||||
|
|
||||||
## Windmill Workflows
|
|
||||||
|
|
||||||
Automatizaciones predefinidas:
|
|
||||||
|
|
||||||
| Workflow | Trigger | Acción |
|
|
||||||
|----------|---------|--------|
|
|
||||||
| Training Completed | Webhook | Guarda entreno → Pide análisis a PENNY |
|
|
||||||
| Weekly Progress | Cron (Lunes 9:00) | Genera reporte semanal |
|
|
||||||
| Email Received | IMAP | Clasifica → Extrae tareas → Notifica |
|
|
||||||
| Habit Reminder | Cron | Envía recordatorio de hábitos pendientes |
|
|
||||||
|
|
||||||
## Instalación
|
|
||||||
|
|
||||||
### 1. Clonar y configurar
|
|
||||||
|
|
||||||
```bash
|
|
||||||
git clone https://github.com/tzzrgit/deck.git
|
|
||||||
cd deck
|
|
||||||
cp .env.example .env
|
|
||||||
# Editar .env con credenciales
|
|
||||||
```
|
|
||||||
|
|
||||||
### 2. Levantar servicios
|
|
||||||
|
|
||||||
```bash
|
|
||||||
docker-compose up -d
|
|
||||||
```
|
|
||||||
|
|
||||||
### 3. Aplicar schema
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Schema base
|
|
||||||
psql -U tzzr -d tzzr -f database/init-tzzr-v2.sql
|
|
||||||
|
|
||||||
# Vision Builder
|
|
||||||
psql -U tzzr -d tzzr -f database/vision-builder.sql
|
|
||||||
```
|
|
||||||
|
|
||||||
### 4. Configurar Windmill
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Windmill UI en http://localhost:8000
|
|
||||||
# Importar workflows desde /windmill/
|
|
||||||
```
|
|
||||||
|
|
||||||
## Template Clonable
|
|
||||||
|
|
||||||
DECK puede clonarse para un nuevo usuario:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Usar template
|
|
||||||
psql -U tzzr -d nuevo_usuario -f templates/deck-template.sql
|
|
||||||
|
|
||||||
# Reemplazar variables
|
|
||||||
sed -i 's/{{USER_NAME}}/Carlos/g' ...
|
|
||||||
sed -i 's/{{START_WEIGHT}}/85/g' ...
|
|
||||||
```
|
|
||||||
|
|
||||||
## Conexión a Servicios IA
|
|
||||||
|
|
||||||
ALFRED construye S-CONTRACT v2.1 para cada petición:
|
|
||||||
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"contract_version": "2.1",
|
|
||||||
"source": { "system": "DECK", "orchestrator": "ALFRED" },
|
|
||||||
"target": { "service": "GRACE", "module": "SUMMARIZER" },
|
|
||||||
"input": { "type": "text", "data": "..." },
|
|
||||||
"limits": { "budget_usd": 0.1 }
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
## Repositorios Relacionados
|
|
||||||
|
|
||||||
| Repo | Descripción |
|
|
||||||
|------|-------------|
|
|
||||||
| [contratos-comunes](https://github.com/tzzrgit/contratos-comunes) | S-CONTRACT, ALFRED, CLARA, schemas |
|
|
||||||
| [grace](https://github.com/tzzrgit/grace) | 18 módulos de procesamiento IA |
|
|
||||||
| [penny](https://github.com/tzzrgit/penny) | Generación de texto |
|
|
||||||
| [the-factory](https://github.com/tzzrgit/the-factory) | Generación iterativa |
|
|
||||||
| [vision-builder](https://github.com/tzzrgit/vision-builder) | UI de Vision Builder |
|
|
||||||
| [mind-link](https://github.com/tzzrgit/mind-link) | UI de conexión |
|
|
||||||
| [locker](https://github.com/tzzrgit/locker) | Almacenamiento |
|
|
||||||
|
|
||||||
## Roadmap
|
|
||||||
|
|
||||||
- [x] Schema PostgreSQL v2
|
|
||||||
- [x] Vision Builder schema
|
|
||||||
- [x] ALFRED orquestador
|
|
||||||
- [x] Windmill config
|
|
||||||
- [ ] Integración Mail-in-a-Box → deck_emails
|
|
||||||
- [ ] API REST para Mind Link
|
|
||||||
- [ ] Push notifications
|
|
||||||
- [ ] Sync con LOCKER
|
|
||||||
@@ -1,35 +0,0 @@
|
|||||||
# DECK Status
|
|
||||||
|
|
||||||
Servidor: deck.tzzr.net (72.62.1.113)
|
|
||||||
Fecha: 2025-12-19
|
|
||||||
|
|
||||||
## Estado: Integración HST completada
|
|
||||||
|
|
||||||
## Servidor
|
|
||||||
|
|
||||||
- Hostname: deck (renombrado de box.tzzr.net)
|
|
||||||
- Docker: 8 contenedores activos
|
|
||||||
- PostgreSQL: Healthy
|
|
||||||
|
|
||||||
## Tablas
|
|
||||||
|
|
||||||
| Tabla | Registros | Descripción |
|
|
||||||
|-------|-----------|-------------|
|
|
||||||
| hst_mirror | 954 | Copia local de tags HST |
|
|
||||||
| hsu | 0 | Tags de usuario |
|
|
||||||
| spu | 0 | Especies de usuario |
|
|
||||||
| flu | 0 | Flags de usuario |
|
|
||||||
| vsu | 0 | Vision de usuario |
|
|
||||||
| vuu | 0 | Vue de usuario |
|
|
||||||
| pju | 0 | Proyectos de usuario |
|
|
||||||
|
|
||||||
## Pendiente
|
|
||||||
|
|
||||||
- [ ] Webhook/polling para sync continuo con HST
|
|
||||||
- [ ] Lógica descarga imágenes cuando HST elimina tags
|
|
||||||
- [ ] API para usuarios
|
|
||||||
|
|
||||||
## R2 Storage
|
|
||||||
|
|
||||||
Bucket: `deck`
|
|
||||||
Ver credenciales en Infisical (project: r2)
|
|
||||||
@@ -1,247 +0,0 @@
|
|||||||
# DECK - Arquitectura del Sistema
|
|
||||||
|
|
||||||
## Rol de DECK en el Ecosistema TZZR
|
|
||||||
|
|
||||||
DECK es el **servidor central** y **punto de iniciación** de todas las conexiones hacia los servicios de IA del ecosistema TZZR. Actúa como:
|
|
||||||
|
|
||||||
1. **Iniciador de conexiones**: Todas las llamadas a GRACE, PENNY y THE FACTORY se originan desde DECK
|
|
||||||
2. **Gestor de contexto**: Envía la información de contexto necesaria con cada request
|
|
||||||
3. **Router de despliegue**: Decide si usar servicios self-hosted o externos
|
|
||||||
4. **Almacén de credenciales**: Gestiona las API keys a través de Vaultwarden/Key Vault
|
|
||||||
|
|
||||||
```
|
|
||||||
┌─────────────────────────────────────────────────────────────────┐
|
|
||||||
│ DECK │
|
|
||||||
│ (Servidor Central) │
|
|
||||||
├─────────────────────────────────────────────────────────────────┤
|
|
||||||
│ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │
|
|
||||||
│ │ PostgreSQL │ │ NocoDB │ │ FileBrowser │ │
|
|
||||||
│ └──────────────┘ └──────────────┘ └──────────────┘ │
|
|
||||||
│ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │
|
|
||||||
│ │ Vaultwarden │ │ Shlink │ │ Addy.io │ │
|
|
||||||
│ │ (Key Vault) │ │ │ │ │ │
|
|
||||||
│ └──────────────┘ └──────────────┘ └──────────────┘ │
|
|
||||||
│ │
|
|
||||||
│ ┌──────────────────────────────────────────────────────────┐ │
|
|
||||||
│ │ DEPLOYMENT ROUTER │ │
|
|
||||||
│ │ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │ │
|
|
||||||
│ │ │ GRACE │ │ PENNY │ │ FACTORY │ │ │
|
|
||||||
│ │ │ Connector │ │ Connector │ │ Connector │ │ │
|
|
||||||
│ │ └──────┬──────┘ └──────┬──────┘ └──────┬──────┘ │ │
|
|
||||||
│ └─────────┼────────────────┼────────────────┼──────────────┘ │
|
|
||||||
└────────────┼────────────────┼────────────────┼──────────────────┘
|
|
||||||
│ │ │
|
|
||||||
▼ ▼ ▼
|
|
||||||
┌────────────────────────────────────────────────────┐
|
|
||||||
│ SERVICIOS DE IA │
|
|
||||||
├────────────────────────────────────────────────────┤
|
|
||||||
│ │
|
|
||||||
│ ┌─────────────────┐ ┌─────────────────┐ │
|
|
||||||
│ │ SELF-HOSTED │ │ EXTERNAL │ │
|
|
||||||
│ │ (RunPod/GPU) │ │ (APIs) │ │
|
|
||||||
│ ├─────────────────┤ ├─────────────────┤ │
|
|
||||||
│ │ Faster Whisper │ │ Groq API │ │
|
|
||||||
│ │ Local LLM │ │ OpenRouter │ │
|
|
||||||
│ │ Tesseract │ │ OpenAI │ │
|
|
||||||
│ │ Embeddings │ │ Anthropic │ │
|
|
||||||
│ └─────────────────┘ │ ElevenLabs │ │
|
|
||||||
│ └─────────────────┘ │
|
|
||||||
└────────────────────────────────────────────────────┘
|
|
||||||
```
|
|
||||||
|
|
||||||
## Modos de Despliegue
|
|
||||||
|
|
||||||
DECK soporta tres modos de despliegue definidos en `config/deployment.yaml`:
|
|
||||||
|
|
||||||
### 1. EXTERNAL
|
|
||||||
- Todas las llamadas van a proveedores externos (APIs)
|
|
||||||
- Sin infraestructura propia de IA
|
|
||||||
- Ideal para: Inicio rápido, bajo volumen
|
|
||||||
|
|
||||||
```yaml
|
|
||||||
grace:
|
|
||||||
mode: EXTERNAL
|
|
||||||
external:
|
|
||||||
providers_allowed: [groq, openrouter, openai, anthropic]
|
|
||||||
```
|
|
||||||
|
|
||||||
### 2. SELF_HOSTED
|
|
||||||
- Todas las llamadas van a infraestructura propia
|
|
||||||
- Requiere RunPod/GPU configurado
|
|
||||||
- Ideal para: Privacidad total, alto volumen, costos predecibles
|
|
||||||
|
|
||||||
```yaml
|
|
||||||
grace:
|
|
||||||
mode: SELF_HOSTED
|
|
||||||
self_hosted:
|
|
||||||
endpoint: "https://your-runpod-endpoint.runpod.net"
|
|
||||||
timeout_ms: 30000
|
|
||||||
```
|
|
||||||
|
|
||||||
### 3. SEMI (Recomendado)
|
|
||||||
- Intenta self-hosted primero
|
|
||||||
- Fallback automático a external si falla
|
|
||||||
- Balance entre privacidad y disponibilidad
|
|
||||||
|
|
||||||
```yaml
|
|
||||||
grace:
|
|
||||||
mode: SEMI
|
|
||||||
tier_preference:
|
|
||||||
- SELF_HOSTED
|
|
||||||
- EXTERNAL
|
|
||||||
self_hosted:
|
|
||||||
endpoint: "..."
|
|
||||||
retry_on_failure: true
|
|
||||||
external:
|
|
||||||
providers_allowed: [groq, openrouter]
|
|
||||||
```
|
|
||||||
|
|
||||||
## Flujo de una Request
|
|
||||||
|
|
||||||
```
|
|
||||||
┌──────────┐ ┌──────────┐ ┌───────────────┐ ┌──────────────┐
|
|
||||||
│ Cliente │────▶│ DECK │────▶│ Deployment │────▶│ Servicio │
|
|
||||||
│ │ │ │ │ Router │ │ (IA) │
|
|
||||||
└──────────┘ └────┬─────┘ └───────┬───────┘ └──────────────┘
|
|
||||||
│ │
|
|
||||||
│ 1. Recibe request │
|
|
||||||
│ 2. Lee config/deployment.yaml
|
|
||||||
│ 3. Obtiene credenciales de Vaultwarden
|
|
||||||
│ 4. Construye S-CONTRACT request
|
|
||||||
│ │
|
|
||||||
│ ┌────────▼────────┐
|
|
||||||
│ │ mode: SEMI │
|
|
||||||
│ ├─────────────────┤
|
|
||||||
│ │ 1. Try SELF_HOSTED
|
|
||||||
│ │ 2. If fail → EXTERNAL
|
|
||||||
│ └─────────────────┘
|
|
||||||
```
|
|
||||||
|
|
||||||
## Estructura de Directorios
|
|
||||||
|
|
||||||
```
|
|
||||||
deck/
|
|
||||||
├── config/
|
|
||||||
│ └── deployment.yaml # Configuración de modos de despliegue
|
|
||||||
├── docker-compose.yml # Servicios principales
|
|
||||||
├── docs/
|
|
||||||
│ ├── ARQUITECTURA.md # Este documento
|
|
||||||
│ └── ESPECIFICACION_SERVIDOR.md
|
|
||||||
├── .env.example # Variables de entorno (incluye AI)
|
|
||||||
└── README.md
|
|
||||||
```
|
|
||||||
|
|
||||||
## Integración con S-CONTRACT v2.1
|
|
||||||
|
|
||||||
DECK construye requests siguiendo el S-CONTRACT v2.1 de `contratos-comunes`:
|
|
||||||
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"contract_version": "2.1",
|
|
||||||
"profile": "FULL",
|
|
||||||
"envelope": {
|
|
||||||
"trace_id": "uuid-generado-por-deck",
|
|
||||||
"idempotency_key": "sha256-del-contenido",
|
|
||||||
"timestamp_init": "2025-12-18T10:00:00Z"
|
|
||||||
},
|
|
||||||
"routing": {
|
|
||||||
"module": "ASR_ENGINE"
|
|
||||||
},
|
|
||||||
"deployment": {
|
|
||||||
"mode": "SEMI",
|
|
||||||
"tier_preference": ["SELF_HOSTED", "EXTERNAL"],
|
|
||||||
"self_hosted": {
|
|
||||||
"endpoint": "https://asr.runpod.net",
|
|
||||||
"timeout_ms": 60000
|
|
||||||
},
|
|
||||||
"credentials_ref": "kv://deck/credentials/grace"
|
|
||||||
},
|
|
||||||
"payload": {
|
|
||||||
"type": "audio",
|
|
||||||
"encoding": "url",
|
|
||||||
"content": "https://storage.tzzr.net/audio/file.mp3"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
## Gestión de Credenciales
|
|
||||||
|
|
||||||
Las credenciales se almacenan en Vaultwarden y se referencian con URIs `kv://`:
|
|
||||||
|
|
||||||
| URI | Contenido |
|
|
||||||
|-----|-----------|
|
|
||||||
| `kv://deck/credentials/groq` | `{"api_key": "gsk_..."}` |
|
|
||||||
| `kv://deck/credentials/openrouter` | `{"api_key": "sk-or-..."}` |
|
|
||||||
| `kv://deck/credentials/runpod` | `{"api_key": "..."}` |
|
|
||||||
| `kv://deck/credentials/grace` | `{"groq": "...", "openrouter": "..."}` |
|
|
||||||
| `kv://deck/credentials/penny` | `{"groq": "...", "openai": "..."}` |
|
|
||||||
| `kv://deck/credentials/factory` | `{"anthropic": "...", "openrouter": "..."}` |
|
|
||||||
|
|
||||||
## Servicios Actuales en DECK
|
|
||||||
|
|
||||||
| Servicio | Puerto | Descripción |
|
|
||||||
|----------|--------|-------------|
|
|
||||||
| PostgreSQL | 5432 | Base de datos principal |
|
|
||||||
| NocoDB | 8080 | Interface de datos low-code |
|
|
||||||
| FileBrowser | 8081 | Gestión de archivos |
|
|
||||||
| Vaultwarden | 8082 | Key Vault / Gestor de contraseñas |
|
|
||||||
| Shlink | 8083 | Acortador de URLs |
|
|
||||||
| Addy.io | 8084 | Alias de correo |
|
|
||||||
| Redis | 6379 | Cache y colas |
|
|
||||||
|
|
||||||
## Conectores de IA
|
|
||||||
|
|
||||||
### GRACE Connector
|
|
||||||
- Procesa requests de módulos GRACE
|
|
||||||
- Soporta todos los M-CONTRACTs (ASR, OCR, Classifier, etc.)
|
|
||||||
- Maneja fallback chain según M-CONTRACT
|
|
||||||
|
|
||||||
### PENNY Connector
|
|
||||||
- Conexión WebSocket para real-time voice
|
|
||||||
- VAD integrado para detección de turnos
|
|
||||||
- Barge-in para interrupciones
|
|
||||||
|
|
||||||
### FACTORY Connector
|
|
||||||
- Procesos documentales largos
|
|
||||||
- Batch processing
|
|
||||||
- Pipelines multi-step
|
|
||||||
|
|
||||||
## Variables de Entorno Relevantes
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Modo de despliegue
|
|
||||||
DEPLOYMENT_MODE=SEMI
|
|
||||||
|
|
||||||
# Proveedores externos
|
|
||||||
GROQ_API_KEY=gsk_...
|
|
||||||
OPENROUTER_API_KEY=sk-or-...
|
|
||||||
OPENAI_API_KEY=sk-...
|
|
||||||
ANTHROPIC_API_KEY=sk-ant-...
|
|
||||||
|
|
||||||
# Self-hosted (RunPod)
|
|
||||||
RUNPOD_API_KEY=...
|
|
||||||
GRACE_SELF_HOSTED_URL=https://...
|
|
||||||
PENNY_RUNPOD_ENDPOINT=https://...
|
|
||||||
ASR_RUNPOD_ENDPOINT=https://...
|
|
||||||
```
|
|
||||||
|
|
||||||
## Monitoreo y Alertas
|
|
||||||
|
|
||||||
Configurado en `config/deployment.yaml`:
|
|
||||||
|
|
||||||
```yaml
|
|
||||||
monitoring:
|
|
||||||
latency:
|
|
||||||
warn_threshold_ms: 5000
|
|
||||||
error_threshold_ms: 15000
|
|
||||||
cost:
|
|
||||||
daily_budget_usd: 10.00
|
|
||||||
alert_at_percent: 80
|
|
||||||
```
|
|
||||||
|
|
||||||
## Próximos Pasos
|
|
||||||
|
|
||||||
1. Implementar el Deployment Router en código
|
|
||||||
2. Integrar con Vaultwarden para credenciales
|
|
||||||
3. Crear endpoints para GRACE/PENNY/FACTORY
|
|
||||||
4. Dashboard de monitoreo de costos y latencia
|
|
||||||
@@ -1,426 +0,0 @@
|
|||||||
# Servidor Personal tzzr.net — Actualización Repositorio GitHub
|
|
||||||
|
|
||||||
## Contexto
|
|
||||||
|
|
||||||
Servidor personal autoalojado en Hostinger VPS (Ubuntu 22.04, 8GB RAM, 100GB SSD).
|
|
||||||
Función: máquina personal del usuario, punto de entrada privado al ecosistema.
|
|
||||||
|
|
||||||
**IP**: 72.62.1.113
|
|
||||||
**Dominio**: tzzr.net
|
|
||||||
**Hostname**: box.tzzr.net
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Arquitectura Actual
|
|
||||||
|
|
||||||
```
|
|
||||||
[Cloudflare DNS]
|
|
||||||
│
|
|
||||||
[72.62.1.113]
|
|
||||||
│
|
|
||||||
┌─────────────────┴─────────────────┐
|
|
||||||
│ │
|
|
||||||
[Mail-in-a-Box] [Docker Stack]
|
|
||||||
Puertos 25,443,993 Puertos internos
|
|
||||||
│ │
|
|
||||||
┌────┴────┐ ┌───────────────┼───────────────┐
|
|
||||||
│ │ │ │ │ │ │
|
|
||||||
Email Nextcloud PostgreSQL NocoDB Shlink Addy Vaultwarden
|
|
||||||
(box) (/cloud) 5432 8081 8083 8084 8085
|
|
||||||
│
|
|
||||||
FileBrowser
|
|
||||||
8082
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Servicios Docker
|
|
||||||
|
|
||||||
| Servicio | Puerto | Subdominio | Imagen |
|
|
||||||
|----------|--------|------------|--------|
|
|
||||||
| PostgreSQL 15 | 5432 | (interno) | postgres:15-alpine |
|
|
||||||
| NocoDB | 8081 | db.tzzr.net | nocodb/nocodb:latest |
|
|
||||||
| FileBrowser | 8082 | files.tzzr.net | filebrowser/filebrowser:latest |
|
|
||||||
| Shlink | 8083 | s.tzzr.net | shlinkio/shlink:stable |
|
|
||||||
| Addy.io | 8084 | alias.tzzr.net | anonaddy/anonaddy:latest |
|
|
||||||
| Redis | 6379 | (interno) | redis:alpine |
|
|
||||||
| Vaultwarden | 8085 | pass.tzzr.net | vaultwarden/server:latest |
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Tarea: Actualizar Repositorio GitHub
|
|
||||||
|
|
||||||
### Estructura de Archivos del Repositorio
|
|
||||||
|
|
||||||
```
|
|
||||||
tzzr-server/
|
|
||||||
├── README.md # Documentación principal
|
|
||||||
├── docker-compose.yml # Stack de servicios
|
|
||||||
├── init.sql # Schema PostgreSQL completo
|
|
||||||
├── nginx/
|
|
||||||
│ └── services.conf # Configuración reverse proxy
|
|
||||||
├── scripts/
|
|
||||||
│ ├── backup.sh # Script de backup diario
|
|
||||||
│ ├── mail-processor.py # Procesar correos → mail_registry
|
|
||||||
│ └── hst-sync.py # Sincronización etiquetas HST
|
|
||||||
├── dns/
|
|
||||||
│ └── tzzr_net.zone # Registros DNS para Cloudflare
|
|
||||||
└── docs/
|
|
||||||
├── INSTALACION.md # Guía de instalación desde cero
|
|
||||||
├── CLONACION.md # Guía para clonar a nuevo usuario
|
|
||||||
└── CREDENCIALES.template # Plantilla de credenciales (sin valores reales)
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Schema PostgreSQL (init.sql)
|
|
||||||
|
|
||||||
### Tablas de Etiquetas HST
|
|
||||||
|
|
||||||
Crear 4 tablas con estructura idéntica:
|
|
||||||
|
|
||||||
```sql
|
|
||||||
-- hst_tags_sistema: Sync desde tzrtech.org (grupo: hst)
|
|
||||||
-- hst_tags_empresa: Sync desde servidor empresa (grupo: emp)
|
|
||||||
-- hst_tags_usuario: Etiquetas personales (grupo: hsu)
|
|
||||||
-- hst_tags_proyecto: Etiquetas de proyecto (grupo: pjt)
|
|
||||||
|
|
||||||
CREATE TABLE IF NOT EXISTS hst_tags_sistema (
|
|
||||||
id SERIAL PRIMARY KEY,
|
|
||||||
h_maestro VARCHAR(64) UNIQUE, -- SHA-256, identificador único
|
|
||||||
codigo VARCHAR(50) NOT NULL, -- Código corto memorable
|
|
||||||
nombre VARCHAR(100) NOT NULL, -- Nombre legible
|
|
||||||
nombre_en VARCHAR(100), -- Nombre en inglés (opcional)
|
|
||||||
descripcion TEXT,
|
|
||||||
imagen_url TEXT, -- URL externa a la imagen (no blob)
|
|
||||||
color VARCHAR(7), -- Color hex (#RRGGBB)
|
|
||||||
grupo VARCHAR(10) DEFAULT 'hst', -- hst, emp, hsu, pjt
|
|
||||||
padre_h_maestro VARCHAR(64), -- Jerarquía: referencia al padre
|
|
||||||
activo BOOLEAN DEFAULT true,
|
|
||||||
metadata JSONB, -- Datos adicionales flexibles
|
|
||||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
|
||||||
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
|
||||||
synced_at TIMESTAMP -- Última sincronización (para hst/emp)
|
|
||||||
);
|
|
||||||
|
|
||||||
-- Repetir estructura para: hst_tags_empresa, hst_tags_usuario, hst_tags_proyecto
|
|
||||||
-- Cambiar DEFAULT de 'grupo' según corresponda: 'emp', 'hsu', 'pjt'
|
|
||||||
```
|
|
||||||
|
|
||||||
**Índices requeridos:**
|
|
||||||
```sql
|
|
||||||
CREATE INDEX idx_hst_sistema_h_maestro ON hst_tags_sistema(h_maestro);
|
|
||||||
CREATE INDEX idx_hst_sistema_codigo ON hst_tags_sistema(codigo);
|
|
||||||
CREATE INDEX idx_hst_sistema_grupo ON hst_tags_sistema(grupo);
|
|
||||||
CREATE INDEX idx_hst_sistema_padre ON hst_tags_sistema(padre_h_maestro);
|
|
||||||
```
|
|
||||||
|
|
||||||
### Tabla mail_registry
|
|
||||||
|
|
||||||
```sql
|
|
||||||
CREATE TABLE IF NOT EXISTS mail_registry (
|
|
||||||
id SERIAL PRIMARY KEY,
|
|
||||||
message_id VARCHAR(255) UNIQUE, -- Message-ID del correo
|
|
||||||
|
|
||||||
-- Direcciones
|
|
||||||
from_address VARCHAR(255) NOT NULL,
|
|
||||||
to_address VARCHAR(255) NOT NULL,
|
|
||||||
cc_address TEXT, -- Puede ser múltiple
|
|
||||||
reply_to VARCHAR(255),
|
|
||||||
|
|
||||||
-- Contenido
|
|
||||||
subject TEXT,
|
|
||||||
body_preview TEXT, -- Primeras 500 palabras
|
|
||||||
|
|
||||||
-- Fechas
|
|
||||||
date_sent TIMESTAMP,
|
|
||||||
date_received TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
|
||||||
|
|
||||||
-- Adjuntos
|
|
||||||
has_attachments BOOLEAN DEFAULT false,
|
|
||||||
attachment_count INTEGER DEFAULT 0,
|
|
||||||
attachment_paths JSONB, -- Array de rutas en FileBrowser
|
|
||||||
|
|
||||||
-- Clasificación
|
|
||||||
direction VARCHAR(10) NOT NULL, -- 'inbound' o 'outbound'
|
|
||||||
folder VARCHAR(100) DEFAULT 'INBOX',
|
|
||||||
is_spam BOOLEAN DEFAULT false,
|
|
||||||
spam_score DECIMAL(5,2),
|
|
||||||
read_status BOOLEAN DEFAULT false,
|
|
||||||
|
|
||||||
-- Etiquetado
|
|
||||||
tags JSONB, -- Array de h_maestro
|
|
||||||
|
|
||||||
-- Procesamiento IA
|
|
||||||
processed_by_ia BOOLEAN DEFAULT false,
|
|
||||||
ia_classification JSONB, -- Resultado del clasificador
|
|
||||||
ia_processed_at TIMESTAMP,
|
|
||||||
|
|
||||||
-- Metadata
|
|
||||||
size_bytes INTEGER,
|
|
||||||
headers JSONB, -- Headers relevantes
|
|
||||||
metadata JSONB,
|
|
||||||
|
|
||||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
|
||||||
);
|
|
||||||
|
|
||||||
-- Índices
|
|
||||||
CREATE INDEX idx_mail_registry_message_id ON mail_registry(message_id);
|
|
||||||
CREATE INDEX idx_mail_registry_from ON mail_registry(from_address);
|
|
||||||
CREATE INDEX idx_mail_registry_to ON mail_registry(to_address);
|
|
||||||
CREATE INDEX idx_mail_registry_date ON mail_registry(date_received);
|
|
||||||
CREATE INDEX idx_mail_registry_direction ON mail_registry(direction);
|
|
||||||
CREATE INDEX idx_mail_registry_tags ON mail_registry USING GIN(tags);
|
|
||||||
|
|
||||||
-- Constraint para direction
|
|
||||||
ALTER TABLE mail_registry
|
|
||||||
ADD CONSTRAINT chk_direction CHECK (direction IN ('inbound', 'outbound'));
|
|
||||||
```
|
|
||||||
|
|
||||||
### Tabla log_personal
|
|
||||||
|
|
||||||
```sql
|
|
||||||
CREATE TABLE IF NOT EXISTS log_personal (
|
|
||||||
id SERIAL PRIMARY KEY,
|
|
||||||
tipo VARCHAR(50) NOT NULL, -- nota, recordatorio, evento, etc.
|
|
||||||
titulo VARCHAR(255),
|
|
||||||
descripcion TEXT,
|
|
||||||
fecha_evento TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
|
||||||
tags JSONB, -- Array de h_maestro
|
|
||||||
metadata JSONB,
|
|
||||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
|
||||||
);
|
|
||||||
|
|
||||||
CREATE INDEX idx_log_personal_tipo ON log_personal(tipo);
|
|
||||||
CREATE INDEX idx_log_personal_fecha ON log_personal(fecha_evento);
|
|
||||||
CREATE INDEX idx_log_personal_tags ON log_personal USING GIN(tags);
|
|
||||||
```
|
|
||||||
|
|
||||||
### Tabla log_sistema
|
|
||||||
|
|
||||||
```sql
|
|
||||||
CREATE TABLE IF NOT EXISTS log_sistema (
|
|
||||||
id SERIAL PRIMARY KEY,
|
|
||||||
tipo_evento VARCHAR(50) NOT NULL, -- Tipo de evento (ver enum abajo)
|
|
||||||
nivel VARCHAR(20) NOT NULL DEFAULT 'INFO', -- INFO, WARNING, ERROR, DEBUG
|
|
||||||
servicio VARCHAR(100), -- Servicio origen
|
|
||||||
mensaje TEXT NOT NULL,
|
|
||||||
detalles JSONB, -- Datos estructurados del evento
|
|
||||||
|
|
||||||
-- Contexto
|
|
||||||
ip_origen VARCHAR(45),
|
|
||||||
usuario VARCHAR(100),
|
|
||||||
trace_id VARCHAR(64), -- Para correlacionar eventos
|
|
||||||
|
|
||||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
|
||||||
);
|
|
||||||
|
|
||||||
-- Tipos de evento permitidos
|
|
||||||
COMMENT ON COLUMN log_sistema.tipo_evento IS
|
|
||||||
'Valores: mail_received, mail_sent, file_uploaded, file_downloaded,
|
|
||||||
login, logout, api_call, sync_hst, sync_emp, backup_started,
|
|
||||||
backup_completed, backup_failed, error, warning, service_start, service_stop';
|
|
||||||
|
|
||||||
CREATE INDEX idx_log_sistema_tipo ON log_sistema(tipo_evento);
|
|
||||||
CREATE INDEX idx_log_sistema_nivel ON log_sistema(nivel);
|
|
||||||
CREATE INDEX idx_log_sistema_fecha ON log_sistema(created_at);
|
|
||||||
CREATE INDEX idx_log_sistema_servicio ON log_sistema(servicio);
|
|
||||||
CREATE INDEX idx_log_sistema_trace ON log_sistema(trace_id);
|
|
||||||
```
|
|
||||||
|
|
||||||
### Tablas Auxiliares
|
|
||||||
|
|
||||||
```sql
|
|
||||||
-- Aliases de correo (tracking de Addy.io)
|
|
||||||
CREATE TABLE IF NOT EXISTS mail_aliases (
|
|
||||||
id SERIAL PRIMARY KEY,
|
|
||||||
alias VARCHAR(255) UNIQUE NOT NULL,
|
|
||||||
destino VARCHAR(255) NOT NULL,
|
|
||||||
descripcion TEXT,
|
|
||||||
activo BOOLEAN DEFAULT true,
|
|
||||||
contador_uso INTEGER DEFAULT 0,
|
|
||||||
ultimo_uso TIMESTAMP,
|
|
||||||
tags JSONB,
|
|
||||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
|
||||||
);
|
|
||||||
|
|
||||||
-- URLs acortadas (tracking adicional a Shlink)
|
|
||||||
CREATE TABLE IF NOT EXISTS short_urls (
|
|
||||||
id SERIAL PRIMARY KEY,
|
|
||||||
short_code VARCHAR(50) UNIQUE NOT NULL,
|
|
||||||
url_original TEXT NOT NULL,
|
|
||||||
titulo VARCHAR(255),
|
|
||||||
descripcion TEXT,
|
|
||||||
visitas INTEGER DEFAULT 0,
|
|
||||||
activo BOOLEAN DEFAULT true,
|
|
||||||
fecha_expiracion TIMESTAMP,
|
|
||||||
tags JSONB,
|
|
||||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
|
||||||
);
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Script mail-processor.py
|
|
||||||
|
|
||||||
Script Python que escucha nuevos correos y los registra en `mail_registry`.
|
|
||||||
|
|
||||||
**Requisitos funcionales:**
|
|
||||||
1. Conectar a Dovecot via IMAP (localhost:993)
|
|
||||||
2. Escuchar eventos IDLE para nuevos correos
|
|
||||||
3. Por cada correo nuevo:
|
|
||||||
- Extraer headers y metadatos
|
|
||||||
- Generar body_preview (primeras 500 palabras, texto plano)
|
|
||||||
- Si hay adjuntos: guardar en FileBrowser, registrar rutas en attachment_paths
|
|
||||||
- Insertar registro en mail_registry
|
|
||||||
- Insertar evento en log_sistema (tipo: mail_received)
|
|
||||||
4. Manejar reconexión automática
|
|
||||||
5. Logging a stdout (para docker logs)
|
|
||||||
|
|
||||||
**Dependencias:**
|
|
||||||
```
|
|
||||||
imapclient
|
|
||||||
psycopg2-binary
|
|
||||||
python-dotenv
|
|
||||||
```
|
|
||||||
|
|
||||||
**Ejecutar como servicio systemd o contenedor Docker.**
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Script hst-sync.py
|
|
||||||
|
|
||||||
Script Python para sincronizar etiquetas HST desde servidor externo.
|
|
||||||
|
|
||||||
**Requisitos funcionales:**
|
|
||||||
1. Conectar a API de tzrtech.org (endpoint y auth por definir)
|
|
||||||
2. Obtener lista de etiquetas con h_maestro
|
|
||||||
3. Comparar con hst_tags_sistema local
|
|
||||||
4. UPDATE si h_maestro existe y hay cambios
|
|
||||||
5. INSERT si h_maestro no existe
|
|
||||||
6. Marcar synced_at en registros actualizados
|
|
||||||
7. Registrar evento en log_sistema (tipo: sync_hst)
|
|
||||||
|
|
||||||
**Ejecutar via cron cada 24h.**
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Script backup.sh
|
|
||||||
|
|
||||||
Actualizar el script existente para incluir:
|
|
||||||
1. Dump PostgreSQL completo
|
|
||||||
2. Volumen vaultwarden_data
|
|
||||||
3. Configuración de servicios
|
|
||||||
4. Volumen filebrowser_data
|
|
||||||
5. Rotación: 7 días
|
|
||||||
6. Log de cada backup en log_sistema (via psql o curl a API)
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Configuración Nginx (services.conf)
|
|
||||||
|
|
||||||
Asegurar que incluye todos los servicios:
|
|
||||||
- db.tzzr.net → localhost:8081 (NocoDB)
|
|
||||||
- files.tzzr.net → localhost:8082 (FileBrowser)
|
|
||||||
- s.tzzr.net → localhost:8083 (Shlink)
|
|
||||||
- alias.tzzr.net → localhost:8084 (Addy.io)
|
|
||||||
- pass.tzzr.net → localhost:8085 (Vaultwarden, con WebSocket)
|
|
||||||
|
|
||||||
Todos con:
|
|
||||||
- SSL usando certificados de Mail-in-a-Box
|
|
||||||
- Headers de seguridad estándar
|
|
||||||
- ACME challenge para renovación SSL
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## README.md
|
|
||||||
|
|
||||||
Incluir:
|
|
||||||
1. Descripción del proyecto (servidor personal, no sistema completo)
|
|
||||||
2. Arquitectura (diagrama ASCII)
|
|
||||||
3. Servicios y URLs
|
|
||||||
4. Requisitos previos (VPS, dominio, Cloudflare)
|
|
||||||
5. Instalación rápida
|
|
||||||
6. Estructura de archivos
|
|
||||||
7. Comandos útiles
|
|
||||||
8. Backups y restauración
|
|
||||||
9. Seguridad (puertos, firewall, SSL)
|
|
||||||
10. Licencia
|
|
||||||
|
|
||||||
**NO incluir credenciales reales en el repositorio.**
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Entregables
|
|
||||||
|
|
||||||
1. [ ] `docker-compose.yml` — Actualizado con todos los servicios
|
|
||||||
2. [ ] `init.sql` — Schema completo con las 4 tablas HST + mail_registry + logs
|
|
||||||
3. [ ] `nginx/services.conf` — Configuración reverse proxy completa
|
|
||||||
4. [ ] `scripts/backup.sh` — Actualizado con vaultwarden
|
|
||||||
5. [ ] `scripts/mail-processor.py` — Nuevo: procesar correos
|
|
||||||
6. [ ] `scripts/hst-sync.py` — Nuevo: sincronizar etiquetas
|
|
||||||
7. [ ] `dns/tzzr_net.zone` — Archivo de zona DNS
|
|
||||||
8. [ ] `README.md` — Documentación principal
|
|
||||||
9. [ ] `docs/INSTALACION.md` — Guía paso a paso
|
|
||||||
10. [ ] `docs/CLONACION.md` — Guía para replicar a nuevo usuario
|
|
||||||
11. [ ] `docs/CREDENCIALES.template` — Plantilla sin valores reales
|
|
||||||
12. [ ] `.gitignore` — Excluir .env, credenciales, backups
|
|
||||||
13. [ ] `.env.example` — Variables de entorno requeridas
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Variables de Entorno (.env.example)
|
|
||||||
|
|
||||||
```env
|
|
||||||
# PostgreSQL
|
|
||||||
POSTGRES_USER=tzzr
|
|
||||||
POSTGRES_PASSWORD=
|
|
||||||
POSTGRES_DB=tzzr
|
|
||||||
|
|
||||||
# NocoDB
|
|
||||||
NC_AUTH_JWT_SECRET=
|
|
||||||
|
|
||||||
# Addy.io
|
|
||||||
ANONADDY_DOMAIN=tzzr.net
|
|
||||||
ANONADDY_SECRET=
|
|
||||||
APP_KEY=
|
|
||||||
|
|
||||||
# Vaultwarden
|
|
||||||
VAULTWARDEN_DOMAIN=https://pass.tzzr.net
|
|
||||||
VAULTWARDEN_ADMIN_TOKEN=
|
|
||||||
|
|
||||||
# Shlink
|
|
||||||
SHLINK_DOMAIN=s.tzzr.net
|
|
||||||
|
|
||||||
# Mail processor
|
|
||||||
IMAP_HOST=localhost
|
|
||||||
IMAP_USER=
|
|
||||||
IMAP_PASSWORD=
|
|
||||||
|
|
||||||
# HST Sync (por definir)
|
|
||||||
HST_API_URL=
|
|
||||||
HST_API_TOKEN=
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Notas para Code
|
|
||||||
|
|
||||||
1. **No crear servicios nuevos** — Solo documentar y estructurar lo existente
|
|
||||||
2. **No incluir credenciales reales** — Usar placeholders o .env.example
|
|
||||||
3. **Mantener compatibilidad** — El servidor ya está funcionando
|
|
||||||
4. **Schema SQL debe ser idempotente** — Usar IF NOT EXISTS
|
|
||||||
5. **Scripts deben tener logging** — Para debugging via docker logs
|
|
||||||
6. **Documentación en español** — Usuario hispanohablante
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Repositorio Destino
|
|
||||||
|
|
||||||
Por confirmar con el usuario. Puede ser:
|
|
||||||
- Nuevo repositorio
|
|
||||||
- Repositorio existente a actualizar
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
*Documento generado: Diciembre 2024*
|
|
||||||
@@ -1,766 +0,0 @@
|
|||||||
# Proyecto: Servidor Privado de Correo y Productividad
|
|
||||||
|
|
||||||
## Documento de Definición del Proyecto
|
|
||||||
|
|
||||||
**Versión**: 1.0
|
|
||||||
**Fecha**: Diciembre 2024
|
|
||||||
**Estado**: Planificación
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 1. Resumen Ejecutivo
|
|
||||||
|
|
||||||
### 1.1 Visión
|
|
||||||
|
|
||||||
Crear un ecosistema de servidor personal autoalojado que centralice correo electrónico, gestión de archivos, contraseñas y organización de información mediante etiquetado inteligente con IA, todo bajo un enfoque de máxima privacidad.
|
|
||||||
|
|
||||||
### 1.2 Objetivos principales
|
|
||||||
|
|
||||||
- Independencia de proveedores de correo comerciales
|
|
||||||
- Control total sobre los datos personales y profesionales
|
|
||||||
- Organización automática de información mediante IA
|
|
||||||
- Compartimentación total entre usuarios (un servidor por persona)
|
|
||||||
- Interfaz unificada y sencilla para el usuario final
|
|
||||||
|
|
||||||
### 1.3 Usuarios objetivo
|
|
||||||
|
|
||||||
- Usuario principal (propietario)
|
|
||||||
- Socio (servidor independiente replicado)
|
|
||||||
- Posible expansión futura a más usuarios
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 2. Arquitectura del Sistema
|
|
||||||
|
|
||||||
### 2.1 Infraestructura
|
|
||||||
|
|
||||||
```
|
|
||||||
┌─────────────────────────────────────────────────────────────────────────────┐
|
|
||||||
│ INTERNET │
|
|
||||||
└─────────────────────────────────┬───────────────────────────────────────────┘
|
|
||||||
│
|
|
||||||
▼
|
|
||||||
┌─────────────────────────────────────────────────────────────────────────────┐
|
|
||||||
│ CLOUDFLARE (opcional) │
|
|
||||||
│ Protección DDoS · Caché · DNS │
|
|
||||||
└─────────────────────────────────┬───────────────────────────────────────────┘
|
|
||||||
│
|
|
||||||
▼
|
|
||||||
┌─────────────────────────────────────────────────────────────────────────────┐
|
|
||||||
│ VPS HOSTINGER │
|
|
||||||
│ KVM 2 · 8 GB RAM · 100 GB SSD │
|
|
||||||
│ ┌───────────────────────────────────────────────────────────────────────┐ │
|
|
||||||
│ │ TRAEFIK │ │
|
|
||||||
│ │ Proxy inverso · SSL automático │ │
|
|
||||||
│ │ Puertos 80/443 · Let's Encrypt │ │
|
|
||||||
│ └───────────────────────────────┬───────────────────────────────────────┘ │
|
|
||||||
│ │ │
|
|
||||||
│ ┌─────────────┬───────────────┼───────────────┬─────────────┬─────────┐ │
|
|
||||||
│ │ │ │ │ │ │ │
|
|
||||||
│ ▼ ▼ ▼ ▼ ▼ ▼ │
|
|
||||||
│ ┌──────┐ ┌──────────┐ ┌───────────┐ ┌──────────┐ ┌───────┐ ┌─────┐ │
|
|
||||||
│ │Mailcow│ │ AnonAddy │ │ Nextcloud │ │ NocoDB │ │ Vault │ │ntfy │ │
|
|
||||||
│ │ │ │ │ │ │ │ │ │warden │ │ │ │
|
|
||||||
│ │Correo│ │ Alias │ │ Archivos │ │ Tablas │ │Passw. │ │Push │ │
|
|
||||||
│ └──┬───┘ └────┬─────┘ └─────┬─────┘ └────┬─────┘ └───────┘ └─────┘ │
|
|
||||||
│ │ │ │ │ │
|
|
||||||
│ └────────────┴───────────────┴──────────────┘ │
|
|
||||||
│ │ │
|
|
||||||
│ ▼ │
|
|
||||||
│ ┌─────────────────────────────────────┐ │
|
|
||||||
│ │ POSTGRESQL │ │
|
|
||||||
│ │ Base de datos principal │ │
|
|
||||||
│ │ + Redis (caché) │ │
|
|
||||||
│ └─────────────────┬───────────────────┘ │
|
|
||||||
│ │ │
|
|
||||||
│ ▼ │
|
|
||||||
│ ┌─────────────────────────────────────┐ │
|
|
||||||
│ │ PROCESADOR DE CORREOS │ │
|
|
||||||
│ │ Python · Clasificación · Flujos │ │
|
|
||||||
│ └─────────────────┬───────────────────┘ │
|
|
||||||
│ │ │
|
|
||||||
│ ┌───────────┴───────────┐ │
|
|
||||||
│ ▼ ▼ │
|
|
||||||
│ ┌───────────┐ ┌─────────────┐ │
|
|
||||||
│ │ OLLAMA │ │ API EXTERNA │ │
|
|
||||||
│ │ Phi-2 │ │ (Claude/ │ │
|
|
||||||
│ │ Local │ │ OpenAI) │ │
|
|
||||||
│ └───────────┘ └─────────────┘ │
|
|
||||||
│ │
|
|
||||||
└─────────────────────────────────────────────────────────────────────────────┘
|
|
||||||
```
|
|
||||||
|
|
||||||
### 2.2 Subdominios y servicios
|
|
||||||
|
|
||||||
| Subdominio | Servicio | Función |
|
|
||||||
|------------|----------|---------|
|
|
||||||
| `mail.dominio.com` | Mailcow | Correo (webmail, IMAP, SMTP) |
|
|
||||||
| `alias.dominio.com` | AnonAddy | Generación de alias |
|
|
||||||
| `cloud.dominio.com` | Nextcloud | Almacenamiento de archivos |
|
|
||||||
| `db.dominio.com` | NocoDB | Tablas y dashboard |
|
|
||||||
| `vault.dominio.com` | Vaultwarden | Gestor de contraseñas |
|
|
||||||
| `notify.dominio.com` | ntfy | Notificaciones push |
|
|
||||||
|
|
||||||
### 2.3 Autenticación unificada (SSO)
|
|
||||||
|
|
||||||
- Credenciales únicas basadas en el correo
|
|
||||||
- Login centralizado para todos los servicios
|
|
||||||
- Posibilidad de 2FA con Vaultwarden
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 3. Stack Tecnológico
|
|
||||||
|
|
||||||
### 3.1 Componentes principales
|
|
||||||
|
|
||||||
| Componente | Tecnología | Versión | Función |
|
|
||||||
|------------|------------|---------|---------|
|
|
||||||
| Correo | Mailcow | Latest | Servidor completo (Postfix, Dovecot, SOGo) |
|
|
||||||
| Alias | AnonAddy | Latest | Generación y gestión de alias |
|
|
||||||
| Archivos | Nextcloud | Stable | Almacenamiento, sincronización |
|
|
||||||
| Base de datos | PostgreSQL | 15 | Persistencia de datos |
|
|
||||||
| Frontend BD | NocoDB | Latest | Interfaz visual tipo Airtable |
|
|
||||||
| Contraseñas | Vaultwarden | Latest | Compatible con Bitwarden |
|
|
||||||
| Proxy | Traefik | 2.10 | Routing, SSL, load balancing |
|
|
||||||
| Caché | Redis | Alpine | Aceleración de consultas |
|
|
||||||
| IA Local | Ollama + Phi-2 | Latest | Clasificación, etiquetado |
|
|
||||||
| Notificaciones | ntfy | Latest | Push notifications |
|
|
||||||
| Contenedores | Docker + Compose | Latest | Orquestación |
|
|
||||||
| Sistema | Ubuntu | 24.04 LTS | Sistema operativo |
|
|
||||||
|
|
||||||
### 3.2 Hardware
|
|
||||||
|
|
||||||
**VPS seleccionado**: Hostinger KVM 2
|
|
||||||
|
|
||||||
| Recurso | Especificación |
|
|
||||||
|---------|----------------|
|
|
||||||
| CPU | 2 vCPU |
|
|
||||||
| RAM | 8 GB |
|
|
||||||
| Almacenamiento | 100 GB NVMe SSD |
|
|
||||||
| Ancho de banda | 8 TB/mes |
|
|
||||||
| IP | 1 IPv4 dedicada |
|
|
||||||
| Ubicación | Europa (Madrid/París) |
|
|
||||||
| Coste | ~8€/mes |
|
|
||||||
|
|
||||||
### 3.3 Distribución de RAM estimada
|
|
||||||
|
|
||||||
| Servicio | RAM | Porcentaje |
|
|
||||||
|----------|-----|------------|
|
|
||||||
| Sistema + Docker | 500 MB | 6% |
|
|
||||||
| Mailcow | 2.5 GB | 31% |
|
|
||||||
| PostgreSQL + Redis | 600 MB | 8% |
|
|
||||||
| Nextcloud | 500 MB | 6% |
|
|
||||||
| NocoDB | 300 MB | 4% |
|
|
||||||
| Vaultwarden | 100 MB | 1% |
|
|
||||||
| AnonAddy | 200 MB | 3% |
|
|
||||||
| Traefik + ntfy | 200 MB | 3% |
|
|
||||||
| Ollama + Phi-2 | 2.5 GB | 31% |
|
|
||||||
| **Reserva/Swap** | **600 MB** | **7%** |
|
|
||||||
| **Total** | **8 GB** | **100%** |
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 4. Funcionalidades Detalladas
|
|
||||||
|
|
||||||
### 4.1 Gestión de Correo Electrónico
|
|
||||||
|
|
||||||
#### 4.1.1 Correo entrante
|
|
||||||
- Recepción vía SMTP (puerto 25, 465, 587)
|
|
||||||
- Acceso vía IMAP (puerto 993)
|
|
||||||
- Webmail integrado (SOGo)
|
|
||||||
- Filtros y reglas automáticas
|
|
||||||
- Antispam (Rspamd)
|
|
||||||
- Antivirus (ClamAV)
|
|
||||||
|
|
||||||
#### 4.1.2 Alias de correo (AnonAddy)
|
|
||||||
- Generación instantánea de alias
|
|
||||||
- App móvil para crear alias en segundos
|
|
||||||
- Desactivación individual de alias
|
|
||||||
- Estadísticas por alias
|
|
||||||
- Respuesta desde alias (reply from alias)
|
|
||||||
|
|
||||||
#### 4.1.3 Procesamiento automático
|
|
||||||
```
|
|
||||||
┌─────────────┐ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐
|
|
||||||
│ Correo │────▶│ Extracción │────▶│ IA Local │────▶│ PostgreSQL │
|
|
||||||
│ entrante │ │ metadatos │ │ (Phi-2) │ │ + NocoDB │
|
|
||||||
└─────────────┘ └─────────────┘ └─────────────┘ └─────────────┘
|
|
||||||
│
|
|
||||||
▼ (si es complejo)
|
|
||||||
┌─────────────┐
|
|
||||||
│ API Externa │
|
|
||||||
│ Claude │
|
|
||||||
└─────────────┘
|
|
||||||
```
|
|
||||||
|
|
||||||
### 4.2 Sistema de Etiquetado
|
|
||||||
|
|
||||||
#### 4.2.1 Tipos de etiquetas
|
|
||||||
|
|
||||||
| Tipo | Origen | Descripción |
|
|
||||||
|------|--------|-------------|
|
|
||||||
| **Proyecto empresa** | BD externa (federada) | Proyectos compartidos de la organización |
|
|
||||||
| **Proyecto personal** | BD local | Proyectos individuales del usuario |
|
|
||||||
| **Automáticas** | IA | Generadas por clasificación automática |
|
|
||||||
| **Manuales** | Usuario | Añadidas manualmente por el usuario |
|
|
||||||
|
|
||||||
#### 4.2.2 Flujo de etiquetado
|
|
||||||
|
|
||||||
```
|
|
||||||
┌─────────────────────────────────────┐
|
|
||||||
│ FUENTES DE ETIQUETAS │
|
|
||||||
└─────────────────────────────────────┘
|
|
||||||
│
|
|
||||||
┌─────────────────────────┼─────────────────────────┐
|
|
||||||
▼ ▼ ▼
|
|
||||||
┌───────────────┐ ┌───────────────┐ ┌───────────────┐
|
|
||||||
│ BD Externa │ │ BD Local │ │ IA │
|
|
||||||
│ (Empresa) │ │ (Personal) │ │ (Automático) │
|
|
||||||
└───────┬───────┘ └───────┬───────┘ └───────┬───────┘
|
|
||||||
│ │ │
|
|
||||||
└────────────────────────┼────────────────────────┘
|
|
||||||
▼
|
|
||||||
┌─────────────────────┐
|
|
||||||
│ TABLA UNIFICADA │
|
|
||||||
│ DE ETIQUETAS │
|
|
||||||
│ (NocoDB) │
|
|
||||||
└─────────────────────┘
|
|
||||||
```
|
|
||||||
|
|
||||||
#### 4.2.3 Federación de bases de datos
|
|
||||||
|
|
||||||
- PostgreSQL Foreign Data Wrappers (FDW) para conectar BD externa
|
|
||||||
- Sincronización periódica de etiquetas de empresa
|
|
||||||
- Etiquetas locales nunca salen del servidor personal
|
|
||||||
|
|
||||||
### 4.3 Privacidad y Pseudonimización
|
|
||||||
|
|
||||||
#### 4.3.1 Proceso de anonimización para IA externa
|
|
||||||
|
|
||||||
```
|
|
||||||
┌─────────────────────────────────────────────────────────────────────────┐
|
|
||||||
│ FLUJO DE PSEUDONIMIZACIÓN │
|
|
||||||
└─────────────────────────────────────────────────────────────────────────┘
|
|
||||||
|
|
||||||
DATOS ORIGINALES PSEUDONIMIZADOS RESTAURADOS
|
|
||||||
┌───────────────────┐ ┌───────────────────┐ ┌───────────────────┐
|
|
||||||
│ De: juan@empresa │ │ De: ID_P001 │ │ De: juan@empresa │
|
|
||||||
│ Para: ana@cliente │───────▶│ Para: ID_P002 │───────▶│ Para: ana@cliente │
|
|
||||||
│ Proyecto: Alfa │ │ Proyecto: ID_X001 │ │ Proyecto: Alfa │
|
|
||||||
│ Factura: 12.500€ │ │ Factura: [MONTO] │ │ Factura: 12.500€ │
|
|
||||||
└───────────────────┘ └───────────────────┘ └───────────────────┘
|
|
||||||
│
|
|
||||||
▼
|
|
||||||
┌───────────────┐
|
|
||||||
│ API EXTERNA │
|
|
||||||
│ (Claude) │
|
|
||||||
└───────────────┘
|
|
||||||
|
|
||||||
┌─────────────────────────────────────────────────────────────────────┐
|
|
||||||
│ TABLA DE MAPEO (local, nunca sale del servidor) │
|
|
||||||
│ ─────────────────────────────────────────────────────────────── │
|
|
||||||
│ ID_P001 ←→ juan@empresa.com │
|
|
||||||
│ ID_P002 ←→ ana@cliente.es │
|
|
||||||
│ ID_X001 ←→ Proyecto Alfa │
|
|
||||||
└─────────────────────────────────────────────────────────────────────┘
|
|
||||||
```
|
|
||||||
|
|
||||||
#### 4.3.2 Reglas de privacidad
|
|
||||||
|
|
||||||
1. **Datos que NUNCA salen del servidor**:
|
|
||||||
- Nombres reales
|
|
||||||
- Direcciones de correo
|
|
||||||
- Números de teléfono
|
|
||||||
- Datos bancarios
|
|
||||||
- Contenido de archivos
|
|
||||||
|
|
||||||
2. **Datos que pueden enviarse a IA externa** (pseudonimizados):
|
|
||||||
- Estructura del mensaje
|
|
||||||
- Tipo de contenido
|
|
||||||
- Contexto abstracto
|
|
||||||
|
|
||||||
3. **Validación del usuario**:
|
|
||||||
- Opción de revisar antes de enviar a IA externa
|
|
||||||
- Log de todo lo enviado externamente
|
|
||||||
- Posibilidad de modo "solo local"
|
|
||||||
|
|
||||||
### 4.4 Gestión de Archivos (Nextcloud)
|
|
||||||
|
|
||||||
#### 4.4.1 Funcionalidades base
|
|
||||||
- Sincronización con clientes de escritorio y móvil
|
|
||||||
- Compartición de archivos con enlaces
|
|
||||||
- Versionado de archivos
|
|
||||||
- Papelera de reciclaje
|
|
||||||
|
|
||||||
#### 4.4.2 Integración con IA
|
|
||||||
|
|
||||||
```
|
|
||||||
┌─────────────────────────────────────────────────────────────────────────┐
|
|
||||||
│ CARPETAS INTELIGENTES │
|
|
||||||
└─────────────────────────────────────────────────────────────────────────┘
|
|
||||||
|
|
||||||
Usuario solicita: "Dame todos los archivos del Proyecto Alfa de este mes"
|
|
||||||
|
|
||||||
┌─────────────────────┐
|
|
||||||
│ Solicitud IA │
|
|
||||||
└──────────┬──────────┘
|
|
||||||
│
|
|
||||||
▼
|
|
||||||
┌─────────────────────┐
|
|
||||||
│ Búsqueda en índice │
|
|
||||||
│ (etiquetas + fecha)│
|
|
||||||
└──────────┬──────────┘
|
|
||||||
│
|
|
||||||
▼
|
|
||||||
┌─────────────────────┐
|
|
||||||
│ Estimación tamaño │
|
|
||||||
│ ~450 MB (23 docs) │
|
|
||||||
└──────────┬──────────┘
|
|
||||||
│
|
|
||||||
┌───────────────┴───────────────┐
|
|
||||||
▼ ▼
|
|
||||||
< 100 MB > 100 MB
|
|
||||||
┌─────────────────────┐ ┌─────────────────────┐
|
|
||||||
│ Carpeta temporal │ │ Link de descarga │
|
|
||||||
│ en Nextcloud │ │ por correo │
|
|
||||||
│ (caduca en 24h) │ │ (caduca en 7 días) │
|
|
||||||
└─────────────────────┘ └─────────────────────┘
|
|
||||||
```
|
|
||||||
|
|
||||||
#### 4.4.3 Control de volumen
|
|
||||||
|
|
||||||
- Umbral de confirmación: >100 MB
|
|
||||||
- Umbral de descarga diferida: >500 MB
|
|
||||||
- Límite máximo por solicitud: 5 GB
|
|
||||||
- Estimación previa basada en estadísticas
|
|
||||||
|
|
||||||
### 4.5 Sistema de Comentarios y Trazabilidad
|
|
||||||
|
|
||||||
#### 4.5.1 Estructura de comentarios
|
|
||||||
|
|
||||||
```
|
|
||||||
┌─────────────────────────────────────────────────────────────────────────┐
|
|
||||||
│ TABLA: emails_procesados │
|
|
||||||
├─────────────────────────────────────────────────────────────────────────┤
|
|
||||||
│ ID: 001 │
|
|
||||||
│ Asunto: Factura Proyecto Alfa │
|
|
||||||
│ Categoría: [finanzas] ← IA │
|
|
||||||
│ Estado: procesado │
|
|
||||||
│ │
|
|
||||||
│ ┌─────────────────────────────────────────────────────────────────┐ │
|
|
||||||
│ │ COMENTARIOS (tipo chat vinculado) │ │
|
|
||||||
│ ├─────────────────────────────────────────────────────────────────┤ │
|
|
||||||
│ │ [2024-12-10 09:15] Sistema: Clasificado como "finanzas" │ │
|
|
||||||
│ │ [2024-12-10 09:20] Usuario: Añadir también etiqueta "urgente" │ │
|
|
||||||
│ │ [2024-12-10 09:21] Sistema: Etiqueta "urgente" añadida │ │
|
|
||||||
│ │ [2024-12-10 14:30] Usuario: Pagado, cerrar │ │
|
|
||||||
│ │ [2024-12-10 14:30] Sistema: Estado → cerrado │ │
|
|
||||||
│ └─────────────────────────────────────────────────────────────────┘ │
|
|
||||||
└─────────────────────────────────────────────────────────────────────────┘
|
|
||||||
```
|
|
||||||
|
|
||||||
#### 4.5.2 Principios de trazabilidad
|
|
||||||
|
|
||||||
1. **Datos originales inmutables**: Nunca se modifican, solo se añaden correcciones
|
|
||||||
2. **Log completo**: Toda acción queda registrada con timestamp
|
|
||||||
3. **Atribución**: Se sabe si el cambio fue del usuario, IA o sistema
|
|
||||||
4. **Reversibilidad**: Cualquier cambio puede deshacerse
|
|
||||||
|
|
||||||
### 4.6 Notificaciones Push
|
|
||||||
|
|
||||||
#### 4.6.1 Canales de notificación
|
|
||||||
|
|
||||||
| Canal | Prioridad | Ejemplos |
|
|
||||||
|-------|-----------|----------|
|
|
||||||
| **Urgente** | Alta | Correos de remitentes VIP, alertas de sistema |
|
|
||||||
| **Proyectos** | Media | Actualizaciones de proyectos activos |
|
|
||||||
| **Resumen** | Baja | Digest diario, estadísticas semanales |
|
|
||||||
|
|
||||||
#### 4.6.2 Implementación con ntfy
|
|
||||||
|
|
||||||
```yaml
|
|
||||||
# Ejemplo de notificación
|
|
||||||
POST https://notify.dominio.com/canal-urgente
|
|
||||||
Headers:
|
|
||||||
Title: Correo urgente de Cliente X
|
|
||||||
Priority: urgent
|
|
||||||
Tags: email,urgent
|
|
||||||
Body: "Asunto: Reunión mañana - Requiere respuesta"
|
|
||||||
```
|
|
||||||
|
|
||||||
#### 4.6.3 Apps móviles compatibles
|
|
||||||
- ntfy (Android/iOS) - Gratuita
|
|
||||||
- Integración con Tasker/Shortcuts para automatizaciones
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 5. Flujos de Datos
|
|
||||||
|
|
||||||
### 5.1 Flujo principal de correo entrante
|
|
||||||
|
|
||||||
```
|
|
||||||
┌─────────┐ ┌─────────┐ ┌─────────┐ ┌─────────┐ ┌─────────┐
|
|
||||||
│ Correo │───▶│ Mailcow │───▶│ Procesa-│───▶│ Postgre │───▶│ NocoDB │
|
|
||||||
│entrante │ │ (SMTP) │ │ dor │ │ SQL │ │ (vista) │
|
|
||||||
└─────────┘ └─────────┘ └────┬────┘ └─────────┘ └─────────┘
|
|
||||||
│
|
|
||||||
┌──────────────┼──────────────┐
|
|
||||||
▼ ▼ ▼
|
|
||||||
┌──────────┐ ┌──────────┐ ┌──────────┐
|
|
||||||
│ Extrae │ │ Clasifi- │ │ Asigna │
|
|
||||||
│ metadatos│ │ ca (IA) │ │ etiquetas│
|
|
||||||
└──────────┘ └──────────┘ └──────────┘
|
|
||||||
│
|
|
||||||
┌──────────────┴──────────────┐
|
|
||||||
▼ ▼
|
|
||||||
┌──────────┐ ┌──────────┐
|
|
||||||
│ IA Local │ │API Extern│
|
|
||||||
│ (simple) │ │(complejo)│
|
|
||||||
└──────────┘ └──────────┘
|
|
||||||
```
|
|
||||||
|
|
||||||
### 5.2 Flujo de solicitud de archivos
|
|
||||||
|
|
||||||
```
|
|
||||||
┌─────────┐ ┌─────────┐ ┌─────────┐ ┌─────────┐ ┌─────────┐
|
|
||||||
│ Usuario │───▶│ NocoDB │───▶│ IA │───▶│Nextcloud│───▶│ Usuario │
|
|
||||||
│solicita │ │(interf.)│ │(búsqueda│ │(archivos│ │ recibe │
|
|
||||||
│archivos │ │ │ │ índice) │ │) │ │ │
|
|
||||||
└─────────┘ └─────────┘ └────┬────┘ └─────────┘ └─────────┘
|
|
||||||
│
|
|
||||||
▼
|
|
||||||
┌─────────────┐
|
|
||||||
│ Verifica │
|
|
||||||
│ tamaño │
|
|
||||||
└──────┬──────┘
|
|
||||||
│
|
|
||||||
┌──────────────┼──────────────┐
|
|
||||||
▼ ▼ ▼
|
|
||||||
┌──────────┐ ┌──────────┐ ┌──────────┐
|
|
||||||
│ < 100MB │ │ 100-500MB│ │ > 500MB │
|
|
||||||
│ Carpeta │ │Confirmar │ │ Link │
|
|
||||||
│ temporal │ │ primero │ │ x correo │
|
|
||||||
└──────────┘ └──────────┘ └──────────┘
|
|
||||||
```
|
|
||||||
|
|
||||||
### 5.3 Flujo de IA híbrida
|
|
||||||
|
|
||||||
```
|
|
||||||
┌─────────────────────┐
|
|
||||||
│ CONTENIDO NUEVO │
|
|
||||||
└──────────┬──────────┘
|
|
||||||
│
|
|
||||||
▼
|
|
||||||
┌─────────────────────┐
|
|
||||||
│ ANÁLISIS INICIAL │
|
|
||||||
│ (reglas + regex) │
|
|
||||||
└──────────┬──────────┘
|
|
||||||
│
|
|
||||||
┌───────────────┴───────────────┐
|
|
||||||
▼ ▼
|
|
||||||
Clasificable No clasificable
|
|
||||||
localmente localmente
|
|
||||||
│ │
|
|
||||||
▼ ▼
|
|
||||||
┌───────────────┐ ┌───────────────┐
|
|
||||||
│ IA LOCAL │ │ PSEUDONIMIZAR │
|
|
||||||
│ (Phi-2) │ └───────┬───────┘
|
|
||||||
└───────┬───────┘ │
|
|
||||||
│ ▼
|
|
||||||
│ ┌───────────────┐
|
|
||||||
│ │ API EXTERNA │
|
|
||||||
│ │ (Claude) │
|
|
||||||
│ └───────┬───────┘
|
|
||||||
│ │
|
|
||||||
│ ▼
|
|
||||||
│ ┌───────────────┐
|
|
||||||
│ │ RESTAURAR │
|
|
||||||
│ │ IDENTIDADES │
|
|
||||||
│ └───────┬───────┘
|
|
||||||
│ │
|
|
||||||
└───────────────┬───────────────┘
|
|
||||||
▼
|
|
||||||
┌─────────────────────┐
|
|
||||||
│ GUARDAR RESULTADO │
|
|
||||||
│ (PostgreSQL) │
|
|
||||||
└─────────────────────┘
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 6. Modelo de Datos
|
|
||||||
|
|
||||||
### 6.1 Esquema principal
|
|
||||||
|
|
||||||
```sql
|
|
||||||
-- Tabla principal de correos
|
|
||||||
emails_procesados (
|
|
||||||
id UUID PRIMARY KEY,
|
|
||||||
message_id VARCHAR(255) UNIQUE,
|
|
||||||
fecha_recepcion TIMESTAMP,
|
|
||||||
remitente VARCHAR(255),
|
|
||||||
destinatario VARCHAR(255),
|
|
||||||
alias_usado VARCHAR(255),
|
|
||||||
asunto TEXT,
|
|
||||||
cuerpo_texto TEXT,
|
|
||||||
cuerpo_html TEXT,
|
|
||||||
-- Clasificación
|
|
||||||
categoria VARCHAR(100),
|
|
||||||
etiquetas TEXT[],
|
|
||||||
prioridad INTEGER,
|
|
||||||
sentimiento VARCHAR(50),
|
|
||||||
resumen TEXT,
|
|
||||||
-- Estado
|
|
||||||
procesado BOOLEAN,
|
|
||||||
requiere_respuesta BOOLEAN,
|
|
||||||
-- Auditoría
|
|
||||||
created_at TIMESTAMP,
|
|
||||||
updated_at TIMESTAMP
|
|
||||||
)
|
|
||||||
|
|
||||||
-- Etiquetas (federadas y locales)
|
|
||||||
etiquetas (
|
|
||||||
id SERIAL PRIMARY KEY,
|
|
||||||
nombre VARCHAR(100),
|
|
||||||
tipo ENUM('empresa', 'personal', 'auto'),
|
|
||||||
origen VARCHAR(50), -- 'local' o 'external:servidor_x'
|
|
||||||
color VARCHAR(7),
|
|
||||||
activa BOOLEAN
|
|
||||||
)
|
|
||||||
|
|
||||||
-- Comentarios (trazabilidad)
|
|
||||||
comentarios (
|
|
||||||
id SERIAL PRIMARY KEY,
|
|
||||||
email_id UUID REFERENCES emails_procesados(id),
|
|
||||||
autor VARCHAR(50), -- 'usuario', 'sistema', 'ia'
|
|
||||||
contenido TEXT,
|
|
||||||
accion VARCHAR(50),
|
|
||||||
created_at TIMESTAMP
|
|
||||||
)
|
|
||||||
|
|
||||||
-- Mapeo de pseudonimización
|
|
||||||
mapeo_pseudonimos (
|
|
||||||
id SERIAL PRIMARY KEY,
|
|
||||||
valor_original TEXT,
|
|
||||||
pseudonimo VARCHAR(50),
|
|
||||||
tipo VARCHAR(20), -- 'persona', 'proyecto', 'empresa'
|
|
||||||
sesion_id UUID,
|
|
||||||
created_at TIMESTAMP,
|
|
||||||
expires_at TIMESTAMP
|
|
||||||
)
|
|
||||||
|
|
||||||
-- Reglas de clasificación
|
|
||||||
reglas_clasificacion (
|
|
||||||
id SERIAL PRIMARY KEY,
|
|
||||||
nombre VARCHAR(100),
|
|
||||||
condiciones JSONB,
|
|
||||||
acciones JSONB,
|
|
||||||
prioridad INTEGER,
|
|
||||||
activa BOOLEAN
|
|
||||||
)
|
|
||||||
```
|
|
||||||
|
|
||||||
### 6.2 Vistas útiles para NocoDB
|
|
||||||
|
|
||||||
```sql
|
|
||||||
-- Bandeja de entrada inteligente
|
|
||||||
vista_bandeja_entrada AS
|
|
||||||
SELECT id, fecha, remitente, asunto, categoria, prioridad_visual, resumen
|
|
||||||
FROM emails_procesados
|
|
||||||
WHERE NOT procesado
|
|
||||||
ORDER BY prioridad, fecha DESC;
|
|
||||||
|
|
||||||
-- Estadísticas por categoría
|
|
||||||
vista_estadisticas AS
|
|
||||||
SELECT categoria, COUNT(*), AVG(prioridad)
|
|
||||||
FROM emails_procesados
|
|
||||||
GROUP BY categoria;
|
|
||||||
|
|
||||||
-- Actividad reciente
|
|
||||||
vista_actividad AS
|
|
||||||
SELECT e.asunto, c.contenido, c.autor, c.created_at
|
|
||||||
FROM comentarios c
|
|
||||||
JOIN emails_procesados e ON e.id = c.email_id
|
|
||||||
ORDER BY c.created_at DESC
|
|
||||||
LIMIT 50;
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 7. Seguridad
|
|
||||||
|
|
||||||
### 7.1 Capas de protección
|
|
||||||
|
|
||||||
| Capa | Tecnología | Función |
|
|
||||||
|------|------------|---------|
|
|
||||||
| **Red** | UFW | Firewall, solo puertos necesarios |
|
|
||||||
| **Proxy** | Cloudflare (opcional) | DDoS, WAF, caché |
|
|
||||||
| **SSL** | Let's Encrypt via Traefik | Cifrado en tránsito |
|
|
||||||
| **Acceso** | Fail2ban | Bloqueo de IPs maliciosas |
|
|
||||||
| **Auth** | SSO + 2FA | Autenticación robusta |
|
|
||||||
| **Datos** | Cifrado en reposo | PostgreSQL + volúmenes cifrados |
|
|
||||||
| **Backups** | Restic + B2 | Backups cifrados offsite |
|
|
||||||
|
|
||||||
### 7.2 Puertos expuestos
|
|
||||||
|
|
||||||
| Puerto | Servicio | Notas |
|
|
||||||
|--------|----------|-------|
|
|
||||||
| 22 | SSH | Solo con key, fail2ban activo |
|
|
||||||
| 80 | HTTP | Redirige a 443 |
|
|
||||||
| 443 | HTTPS | Todo el tráfico web |
|
|
||||||
| 25 | SMTP | Correo entrante |
|
|
||||||
| 465 | SMTPS | Correo saliente (SSL) |
|
|
||||||
| 587 | Submission | Correo saliente (STARTTLS) |
|
|
||||||
| 993 | IMAPS | Acceso correo (SSL) |
|
|
||||||
|
|
||||||
### 7.3 Política de backups
|
|
||||||
|
|
||||||
| Tipo | Frecuencia | Retención | Destino |
|
|
||||||
|------|------------|-----------|---------|
|
|
||||||
| Base de datos | Diaria | 30 días | Local + B2 |
|
|
||||||
| Archivos (Nextcloud) | Diaria | 14 días | B2 |
|
|
||||||
| Configuración | Semanal | 90 días | B2 |
|
|
||||||
| Completo | Mensual | 12 meses | B2 |
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 8. Roadmap de Implementación
|
|
||||||
|
|
||||||
### Fase 1: Infraestructura base (Semana 1-2)
|
|
||||||
|
|
||||||
- [ ] Contratar VPS Hostinger KVM 2
|
|
||||||
- [ ] Configurar DNS y subdominios
|
|
||||||
- [ ] Instalar Docker y dependencias
|
|
||||||
- [ ] Configurar firewall y fail2ban
|
|
||||||
- [ ] Desplegar Traefik con SSL
|
|
||||||
|
|
||||||
### Fase 2: Correo y autenticación (Semana 2-3)
|
|
||||||
|
|
||||||
- [ ] Instalar Mailcow
|
|
||||||
- [ ] Configurar DKIM, SPF, DMARC
|
|
||||||
- [ ] Instalar AnonAddy
|
|
||||||
- [ ] Probar envío/recepción de correos
|
|
||||||
- [ ] Instalar Vaultwarden
|
|
||||||
|
|
||||||
### Fase 3: Datos y visualización (Semana 3-4)
|
|
||||||
|
|
||||||
- [ ] Desplegar PostgreSQL + Redis
|
|
||||||
- [ ] Crear esquema de base de datos
|
|
||||||
- [ ] Instalar NocoDB y conectar a PostgreSQL
|
|
||||||
- [ ] Crear vistas y tablas iniciales
|
|
||||||
|
|
||||||
### Fase 4: Archivos y cloud (Semana 4-5)
|
|
||||||
|
|
||||||
- [ ] Instalar Nextcloud
|
|
||||||
- [ ] Configurar almacenamiento y cuotas
|
|
||||||
- [ ] Integrar con PostgreSQL
|
|
||||||
- [ ] Probar sincronización móvil/desktop
|
|
||||||
|
|
||||||
### Fase 5: IA y automatización (Semana 5-6)
|
|
||||||
|
|
||||||
- [ ] Instalar Ollama + Phi-2
|
|
||||||
- [ ] Desarrollar procesador de correos
|
|
||||||
- [ ] Implementar pseudonimización
|
|
||||||
- [ ] Configurar integración con API externa
|
|
||||||
- [ ] Probar flujos de clasificación
|
|
||||||
|
|
||||||
### Fase 6: Notificaciones y pulido (Semana 6-7)
|
|
||||||
|
|
||||||
- [ ] Instalar ntfy
|
|
||||||
- [ ] Configurar canales de notificación
|
|
||||||
- [ ] Implementar reglas de alertas
|
|
||||||
- [ ] Testing completo
|
|
||||||
- [ ] Documentación de usuario
|
|
||||||
|
|
||||||
### Fase 7: Replicación para socio (Semana 7-8)
|
|
||||||
|
|
||||||
- [ ] Contratar segundo VPS
|
|
||||||
- [ ] Replicar configuración
|
|
||||||
- [ ] Personalizar para segundo usuario
|
|
||||||
- [ ] Configurar federación de etiquetas (si aplica)
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 9. Estimación de Costes
|
|
||||||
|
|
||||||
### 9.1 Costes mensuales recurrentes
|
|
||||||
|
|
||||||
| Concepto | Coste/mes | Notas |
|
|
||||||
|----------|-----------|-------|
|
|
||||||
| VPS Hostinger KVM 2 | 8€ | Por servidor |
|
|
||||||
| Dominio | ~1€ | Prorrateado anual |
|
|
||||||
| Backups B2 (50GB) | ~0.50€ | Backblaze B2 |
|
|
||||||
| API IA externa | ~5€ | Uso moderado (estimado) |
|
|
||||||
| **Total por servidor** | **~15€/mes** | |
|
|
||||||
| **Total 2 servidores** | **~30€/mes** | |
|
|
||||||
|
|
||||||
### 9.2 Costes únicos iniciales
|
|
||||||
|
|
||||||
| Concepto | Coste | Notas |
|
|
||||||
|----------|-------|-------|
|
|
||||||
| Dominio (primer año) | 10-15€ | Por dominio |
|
|
||||||
| Tiempo de configuración | ~20 horas | Valorar según caso |
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 10. Riesgos y Mitigaciones
|
|
||||||
|
|
||||||
| Riesgo | Probabilidad | Impacto | Mitigación |
|
|
||||||
|--------|--------------|---------|------------|
|
|
||||||
| VPS caído | Baja | Alto | Backups diarios, alertas de monitoreo |
|
|
||||||
| Correo en spam | Media | Medio | DKIM/SPF/DMARC bien configurados |
|
|
||||||
| Quedarse sin RAM | Media | Medio | Swap de 4GB, monitoreo de recursos |
|
|
||||||
| Fallo de IA local | Baja | Bajo | Fallback a clasificación por reglas |
|
|
||||||
| Brecha de seguridad | Baja | Alto | Actualizaciones, fail2ban, backups cifrados |
|
|
||||||
| Pérdida de datos | Muy baja | Muy alto | Backups 3-2-1, verificación periódica |
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 11. Métricas de Éxito
|
|
||||||
|
|
||||||
| Métrica | Objetivo | Medición |
|
|
||||||
|---------|----------|----------|
|
|
||||||
| Uptime del correo | >99.5% | Monitoreo externo |
|
|
||||||
| Precisión clasificación IA | >85% | Revisión manual mensual |
|
|
||||||
| Tiempo creación alias | <10 segundos | App móvil |
|
|
||||||
| Tiempo respuesta NocoDB | <2 segundos | Métricas internas |
|
|
||||||
| Satisfacción usuario | >8/10 | Encuesta trimestral |
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 12. Anexos
|
|
||||||
|
|
||||||
### A. Comandos útiles
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Ver estado de servicios
|
|
||||||
docker compose ps
|
|
||||||
|
|
||||||
# Logs en tiempo real
|
|
||||||
docker compose logs -f [servicio]
|
|
||||||
|
|
||||||
# Backup manual
|
|
||||||
./scripts/backup.sh
|
|
||||||
|
|
||||||
# Actualizar servicios
|
|
||||||
docker compose pull && docker compose up -d
|
|
||||||
|
|
||||||
# Espacio en disco
|
|
||||||
df -h && docker system df
|
|
||||||
|
|
||||||
# Uso de RAM
|
|
||||||
free -h && docker stats --no-stream
|
|
||||||
```
|
|
||||||
|
|
||||||
### B. Contactos y recursos
|
|
||||||
|
|
||||||
- Documentación Mailcow: https://docs.mailcow.email
|
|
||||||
- Documentación AnonAddy: https://anonaddy.com/help
|
|
||||||
- Documentación Nextcloud: https://docs.nextcloud.com
|
|
||||||
- Documentación NocoDB: https://docs.nocodb.com
|
|
||||||
- Documentación Vaultwarden: https://github.com/dani-garcia/vaultwarden/wiki
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
**Documento preparado para**: Implementación de servidor de correo privado
|
|
||||||
**Próxima revisión**: Tras completar Fase 1
|
|
||||||
@@ -1,483 +0,0 @@
|
|||||||
# Documentacion Servidor tzzr.net
|
|
||||||
|
|
||||||
## Resumen Ejecutivo
|
|
||||||
|
|
||||||
Servidor self-hosted con email, base de datos, gestor de archivos, acortador de URLs, alias de correo y gestor de contrasenas.
|
|
||||||
|
|
||||||
**IP**: 72.62.1.113
|
|
||||||
**Hostname**: box.tzzr.net
|
|
||||||
**OS**: Ubuntu (Mail-in-a-Box)
|
|
||||||
**Dominio principal**: tzzr.net
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Arquitectura
|
|
||||||
|
|
||||||
```
|
|
||||||
[Cloudflare DNS]
|
|
||||||
|
|
|
||||||
[72.62.1.113]
|
|
||||||
|
|
|
||||||
+-----------------+-----------------+
|
|
||||||
| |
|
|
||||||
[Mail-in-a-Box] [Docker Stack]
|
|
||||||
Puerto 25,443 Puertos internos
|
|
||||||
| |
|
|
||||||
+----+----+ +---------------+---------------+
|
|
||||||
| | | | | | |
|
|
||||||
Email Nextcloud Postgres NocoDB Shlink Addy Vaultwarden
|
|
||||||
| |
|
|
||||||
FileBrowser Redis
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Servicios Activos
|
|
||||||
|
|
||||||
### Mail-in-a-Box (Nativo)
|
|
||||||
|
|
||||||
| Componente | URL/Puerto | Descripcion |
|
|
||||||
|------------|------------|-------------|
|
|
||||||
| Webmail | https://box.tzzr.net/mail | Roundcube |
|
|
||||||
| Admin Panel | https://box.tzzr.net/admin | Gestion usuarios/DNS |
|
|
||||||
| Nextcloud | https://box.tzzr.net/cloud | Archivos/Calendario |
|
|
||||||
| SMTP | Puerto 25, 587 | Envio de correo |
|
|
||||||
| IMAP | Puerto 993 | Recepcion de correo |
|
|
||||||
|
|
||||||
### Docker Stack (/opt/services)
|
|
||||||
|
|
||||||
| Servicio | Puerto Interno | URL Publica | Descripcion |
|
|
||||||
|----------|---------------|-------------|-------------|
|
|
||||||
| PostgreSQL | 5432 | - | Base de datos compartida |
|
|
||||||
| Redis | 6379 | - | Cache para Addy.io |
|
|
||||||
| NocoDB | 8081 | https://db.tzzr.net | Airtable self-hosted |
|
|
||||||
| FileBrowser | 8082 | https://files.tzzr.net | Explorador de archivos |
|
|
||||||
| Shlink | 8083 | https://s.tzzr.net | Acortador de URLs |
|
|
||||||
| Addy.io | 8084 | https://alias.tzzr.net | Alias de email |
|
|
||||||
| Vaultwarden | 8085 | https://pass.tzzr.net | Gestor de contrasenas |
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Credenciales
|
|
||||||
|
|
||||||
### Mail-in-a-Box
|
|
||||||
- **Admin**: admin@tzzr.net
|
|
||||||
- **Password**: (configurada durante instalacion)
|
|
||||||
|
|
||||||
### PostgreSQL
|
|
||||||
- **Host**: postgres (interno) / 127.0.0.1:5432
|
|
||||||
- **Usuario**: tzzr
|
|
||||||
- **Password**: TzzrDB-2024-Secure
|
|
||||||
- **Base de datos**: tzzr
|
|
||||||
|
|
||||||
### NocoDB
|
|
||||||
- **URL**: https://db.tzzr.net
|
|
||||||
- **JWT Secret**: TzzrNocoDB-JWT-2024-SecureKey
|
|
||||||
- **Primer usuario**: se crea en primer acceso
|
|
||||||
|
|
||||||
### FileBrowser
|
|
||||||
- **URL**: https://files.tzzr.net
|
|
||||||
- **Usuario inicial**: admin
|
|
||||||
- **Password inicial**: admin (cambiar inmediatamente)
|
|
||||||
|
|
||||||
### Shlink
|
|
||||||
- **URL**: https://s.tzzr.net
|
|
||||||
- **API**: usar `shlink api-key:generate` en el contenedor
|
|
||||||
|
|
||||||
### Addy.io
|
|
||||||
- **URL**: https://alias.tzzr.net
|
|
||||||
- **App Key**: base64:TzzrAddyAppKey2024SecureBase64KeyHere==
|
|
||||||
- **Secret**: TzzrAddySecret2024Secure
|
|
||||||
|
|
||||||
### Vaultwarden
|
|
||||||
- **URL**: https://pass.tzzr.net
|
|
||||||
- **Admin Panel**: https://pass.tzzr.net/admin
|
|
||||||
- **Admin Token**: TzzrVault-Admin-2024-SuperSecureToken
|
|
||||||
- **Registros publicos**: Desactivados
|
|
||||||
- **Invitaciones**: Activadas (via admin panel)
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Configuracion DNS (Cloudflare)
|
|
||||||
|
|
||||||
| Tipo | Nombre | Contenido | Proxy | TTL |
|
|
||||||
|------|--------|-----------|-------|-----|
|
|
||||||
| A | @ | 72.62.1.113 | OFF | Auto |
|
|
||||||
| A | box | 72.62.1.113 | OFF | Auto |
|
|
||||||
| A | db | 72.62.1.113 | ON | Auto |
|
|
||||||
| A | files | 72.62.1.113 | ON | Auto |
|
|
||||||
| A | s | 72.62.1.113 | ON | Auto |
|
|
||||||
| A | alias | 72.62.1.113 | ON | Auto |
|
|
||||||
| A | pass | 72.62.1.113 | ON | Auto |
|
|
||||||
| MX | @ | box.tzzr.net | - | Auto |
|
|
||||||
| TXT | @ | v=spf1 mx -all | - | Auto |
|
|
||||||
| TXT | _dmarc | v=DMARC1; p=quarantine... | - | Auto |
|
|
||||||
|
|
||||||
**Importante**: Los registros MX y el dominio raiz (@, box) deben tener proxy OFF para que funcione el email.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Estructura de Archivos
|
|
||||||
|
|
||||||
```
|
|
||||||
/opt/services/
|
|
||||||
├── docker-compose.yml # Definicion de servicios
|
|
||||||
├── init.sql # Schema inicial PostgreSQL
|
|
||||||
├── backup.sh # Script de backups
|
|
||||||
└── backups/ # Directorio de backups
|
|
||||||
|
|
||||||
/home/user-data/ # Datos de Mail-in-a-Box
|
|
||||||
├── mail/ # Buzones de correo
|
|
||||||
├── ssl/ # Certificados SSL
|
|
||||||
├── backup/ # Backups automaticos MiaB
|
|
||||||
└── www/ # Archivos web estaticos
|
|
||||||
|
|
||||||
/etc/nginx/conf.d/
|
|
||||||
└── services.conf # Reverse proxy para Docker
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Backups
|
|
||||||
|
|
||||||
### Automaticos (Mail-in-a-Box)
|
|
||||||
- **Ubicacion**: /home/user-data/backup/
|
|
||||||
- **Incluye**: Email, Nextcloud, certificados, configuracion
|
|
||||||
- **Frecuencia**: Diaria
|
|
||||||
|
|
||||||
### Script personalizado (/opt/services/backup.sh)
|
|
||||||
- **Frecuencia**: Diaria a las 3:00 AM
|
|
||||||
- **Retencion**: 7 dias
|
|
||||||
- **Incluye**:
|
|
||||||
- Dump de PostgreSQL
|
|
||||||
- Volumenes Docker
|
|
||||||
- **Ubicacion**: /opt/services/backups/
|
|
||||||
|
|
||||||
### Cron job
|
|
||||||
```
|
|
||||||
0 3 * * * /opt/services/backup.sh >> /var/log/tzzr-backup.log 2>&1
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Decisiones Tecnicas
|
|
||||||
|
|
||||||
### Por que Mail-in-a-Box?
|
|
||||||
- Solucion todo-en-uno para email self-hosted
|
|
||||||
- Incluye Nextcloud, DNS, certificados SSL automaticos
|
|
||||||
- Panel de administracion simple
|
|
||||||
- Backups integrados
|
|
||||||
|
|
||||||
### Por que PostgreSQL compartido?
|
|
||||||
- Reduce uso de RAM (vs multiples instancias)
|
|
||||||
- Facilita backups centralizados
|
|
||||||
- NocoDB, Shlink y Addy.io lo soportan nativamente
|
|
||||||
|
|
||||||
### Por que puertos solo en 127.0.0.1?
|
|
||||||
- Seguridad: servicios no expuestos directamente
|
|
||||||
- Todo el trafico pasa por nginx con SSL
|
|
||||||
- Mail-in-a-Box maneja los certificados
|
|
||||||
|
|
||||||
### Por que Vaultwarden en lugar de Bitwarden oficial?
|
|
||||||
- Menor consumo de recursos (escrito en Rust)
|
|
||||||
- Compatible 100% con apps de Bitwarden
|
|
||||||
- Ideal para uso personal/pequenos equipos
|
|
||||||
- Una sola imagen Docker vs multiple contenedores
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Comandos Utiles
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Ver estado de contenedores
|
|
||||||
docker ps
|
|
||||||
|
|
||||||
# Ver logs de un servicio
|
|
||||||
docker logs -f nocodb
|
|
||||||
|
|
||||||
# Reiniciar stack completo
|
|
||||||
cd /opt/services && docker compose restart
|
|
||||||
|
|
||||||
# Backup manual de PostgreSQL
|
|
||||||
docker exec postgres pg_dump -U tzzr tzzr > backup.sql
|
|
||||||
|
|
||||||
# Reiniciar nginx
|
|
||||||
systemctl restart nginx
|
|
||||||
|
|
||||||
# Ver certificados SSL
|
|
||||||
certbot certificates
|
|
||||||
|
|
||||||
# Estado de Mail-in-a-Box
|
|
||||||
mailinabox
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
# Plan de Clonacion para Nuevos Usuarios
|
|
||||||
|
|
||||||
## Estrategia de Dominios para la Organizacion
|
|
||||||
|
|
||||||
### Arquitectura Multi-Tenant
|
|
||||||
|
|
||||||
```
|
|
||||||
[Dominio Principal]
|
|
||||||
juntis.com
|
|
||||||
|
|
|
||||||
Email principal para TODOS los usuarios
|
|
||||||
usuario@juntis.com
|
|
||||||
|
|
|
||||||
+-------------------+-------------------+
|
|
||||||
| | |
|
|
||||||
[Servidor 1] [Servidor 2] [Servidor N]
|
|
||||||
tzzr.net otro.net nuevo.net
|
|
||||||
| | |
|
|
||||||
Alias propios Alias propios Alias propios
|
|
||||||
*@tzzr.net *@otro.net *@nuevo.net
|
|
||||||
```
|
|
||||||
|
|
||||||
### Justificacion
|
|
||||||
|
|
||||||
1. **Email principal centralizado** (juntis.com):
|
|
||||||
- Identidad corporativa unificada
|
|
||||||
- Todos los usuarios tienen @juntis.com
|
|
||||||
- Facilita comunicacion interna
|
|
||||||
- Un solo servidor de mail principal
|
|
||||||
|
|
||||||
2. **Dominios de alias separados** (tzzr.net, otro.net, etc.):
|
|
||||||
- Cada persona/servidor tiene su propio dominio
|
|
||||||
- Evita colisiones de alias (dos personas no crearan el mismo alias)
|
|
||||||
- Privacidad: cada quien gestiona sus alias
|
|
||||||
- Escalabilidad: agregar nuevos usuarios = nuevo dominio
|
|
||||||
|
|
||||||
### Ejemplo Practico
|
|
||||||
|
|
||||||
| Usuario | Email Principal | Dominio Alias | Ejemplos de Alias |
|
|
||||||
|---------|-----------------|---------------|-------------------|
|
|
||||||
| Pablo | pablo@juntis.com | tzzr.net | amazon@tzzr.net, netflix@tzzr.net |
|
|
||||||
| Maria | maria@juntis.com | maria.net | amazon@maria.net, spotify@maria.net |
|
|
||||||
| Juan | juan@juntis.com | juan.net | amazon@juan.net, github@juan.net |
|
|
||||||
|
|
||||||
Todos reciben email en @juntis.com, pero cada uno tiene alias unicos en su dominio.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Checklist de Clonacion
|
|
||||||
|
|
||||||
### Prerequisitos
|
|
||||||
- [ ] VPS nuevo (minimo 2GB RAM, 20GB disco)
|
|
||||||
- [ ] Dominio nuevo registrado (ej: nuevo-usuario.net)
|
|
||||||
- [ ] Acceso a Cloudflare (o DNS del dominio)
|
|
||||||
- [ ] IP publica del nuevo servidor
|
|
||||||
|
|
||||||
### Paso 1: Preparar el Servidor Base
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Conectar al nuevo servidor
|
|
||||||
ssh root@NUEVA_IP
|
|
||||||
|
|
||||||
# Actualizar sistema
|
|
||||||
apt update && apt upgrade -y
|
|
||||||
|
|
||||||
# Configurar hostname
|
|
||||||
hostnamectl set-hostname box.NUEVO-DOMINIO.net
|
|
||||||
```
|
|
||||||
|
|
||||||
### Paso 2: Instalar Mail-in-a-Box
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Instalar MiaB
|
|
||||||
curl -s https://mailinabox.email/setup.sh | sudo bash
|
|
||||||
```
|
|
||||||
|
|
||||||
Durante la instalacion:
|
|
||||||
- **Hostname**: box.NUEVO-DOMINIO.net
|
|
||||||
- **Email admin**: admin@NUEVO-DOMINIO.net (temporal, luego se configura el principal)
|
|
||||||
|
|
||||||
### Paso 3: Configurar DNS en Cloudflare
|
|
||||||
|
|
||||||
Crear estos registros para NUEVO-DOMINIO.net:
|
|
||||||
|
|
||||||
| Tipo | Nombre | Contenido | Proxy |
|
|
||||||
|------|--------|-----------|-------|
|
|
||||||
| A | @ | NUEVA_IP | OFF |
|
|
||||||
| A | box | NUEVA_IP | OFF |
|
|
||||||
| A | db | NUEVA_IP | ON |
|
|
||||||
| A | files | NUEVA_IP | ON |
|
|
||||||
| A | s | NUEVA_IP | ON |
|
|
||||||
| A | alias | NUEVA_IP | ON |
|
|
||||||
| A | pass | NUEVA_IP | ON |
|
|
||||||
| MX | @ | box.NUEVO-DOMINIO.net | - |
|
|
||||||
| TXT | @ | v=spf1 mx -all | - |
|
|
||||||
|
|
||||||
### Paso 4: Instalar Docker
|
|
||||||
|
|
||||||
```bash
|
|
||||||
curl -fsSL https://get.docker.com | sh
|
|
||||||
```
|
|
||||||
|
|
||||||
### Paso 5: Crear Estructura de Directorios
|
|
||||||
|
|
||||||
```bash
|
|
||||||
mkdir -p /opt/services/backups
|
|
||||||
cd /opt/services
|
|
||||||
```
|
|
||||||
|
|
||||||
### Paso 6: Configurar docker-compose.yml
|
|
||||||
|
|
||||||
Copiar el archivo base y modificar:
|
|
||||||
|
|
||||||
```yaml
|
|
||||||
# Cambiar estas variables por cada servidor:
|
|
||||||
# - Passwords de PostgreSQL
|
|
||||||
# - JWT secrets
|
|
||||||
# - Dominios (s.DOMINIO, alias.DOMINIO, pass.DOMINIO)
|
|
||||||
# - App keys
|
|
||||||
```
|
|
||||||
|
|
||||||
**Variables a personalizar por servidor**:
|
|
||||||
|
|
||||||
| Variable | Descripcion | Ejemplo |
|
|
||||||
|----------|-------------|---------|
|
|
||||||
| POSTGRES_PASSWORD | Password de DB | NuevoUsuario-DB-2024 |
|
|
||||||
| NC_AUTH_JWT_SECRET | JWT de NocoDB | NuevoUsuario-JWT-Secret |
|
|
||||||
| DEFAULT_DOMAIN | Dominio Shlink | s.nuevo-usuario.net |
|
|
||||||
| ANONADDY_DOMAIN | Dominio alias | nuevo-usuario.net |
|
|
||||||
| APP_KEY | Key de Addy | base64:NuevoKeyAqui... |
|
|
||||||
| DOMAIN (Vaultwarden) | URL Vaultwarden | https://pass.nuevo-usuario.net |
|
|
||||||
| ADMIN_TOKEN | Token admin Vault | NuevoUsuario-Vault-Token |
|
|
||||||
|
|
||||||
### Paso 7: Configurar Nginx
|
|
||||||
|
|
||||||
Copiar /etc/nginx/conf.d/services.conf y reemplazar:
|
|
||||||
- Todos los `tzzr.net` por `NUEVO-DOMINIO.net`
|
|
||||||
- Verificar que los puertos coincidan
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Recargar nginx
|
|
||||||
nginx -t && systemctl reload nginx
|
|
||||||
```
|
|
||||||
|
|
||||||
### Paso 8: Iniciar Servicios
|
|
||||||
|
|
||||||
```bash
|
|
||||||
cd /opt/services
|
|
||||||
docker compose up -d
|
|
||||||
```
|
|
||||||
|
|
||||||
### Paso 9: Configurar Email Principal
|
|
||||||
|
|
||||||
Si el email principal es juntis.com (servidor central):
|
|
||||||
|
|
||||||
1. En el servidor central (juntis.com), crear cuenta: usuario@juntis.com
|
|
||||||
2. En Addy.io del nuevo servidor, configurar el reenvio a usuario@juntis.com
|
|
||||||
3. Los alias de NUEVO-DOMINIO.net reenviaran a usuario@juntis.com
|
|
||||||
|
|
||||||
### Paso 10: Verificacion Final
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Verificar contenedores
|
|
||||||
docker ps
|
|
||||||
|
|
||||||
# Probar cada servicio
|
|
||||||
curl -I https://db.NUEVO-DOMINIO.net
|
|
||||||
curl -I https://files.NUEVO-DOMINIO.net
|
|
||||||
curl -I https://s.NUEVO-DOMINIO.net
|
|
||||||
curl -I https://alias.NUEVO-DOMINIO.net
|
|
||||||
curl -I https://pass.NUEVO-DOMINIO.net
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Script de Clonacion Automatizada
|
|
||||||
|
|
||||||
Para facilitar el proceso, se puede crear un script interactivo:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
#!/bin/bash
|
|
||||||
# clone-server.sh - Script de clonacion de servidor tzzr
|
|
||||||
|
|
||||||
echo "=== Clonacion de Servidor ==="
|
|
||||||
read -p "Nuevo dominio (ej: nuevo-usuario.net): " DOMAIN
|
|
||||||
read -p "IP del servidor: " SERVER_IP
|
|
||||||
read -p "Email admin: " ADMIN_EMAIL
|
|
||||||
|
|
||||||
# Generar passwords aleatorios
|
|
||||||
DB_PASS=$(openssl rand -base64 16)
|
|
||||||
JWT_SECRET=$(openssl rand -base64 32)
|
|
||||||
APP_KEY=$(openssl rand -base64 32)
|
|
||||||
VAULT_TOKEN=$(openssl rand -base64 32)
|
|
||||||
|
|
||||||
echo ""
|
|
||||||
echo "=== Configuracion Generada ==="
|
|
||||||
echo "Dominio: $DOMAIN"
|
|
||||||
echo "IP: $SERVER_IP"
|
|
||||||
echo "DB Password: $DB_PASS"
|
|
||||||
echo "JWT Secret: $JWT_SECRET"
|
|
||||||
echo "Vault Token: $VAULT_TOKEN"
|
|
||||||
echo ""
|
|
||||||
echo "Guarda estas credenciales en un lugar seguro!"
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Mantenimiento Post-Clonacion
|
|
||||||
|
|
||||||
### Tareas Semanales
|
|
||||||
- Verificar que backups se ejecutan
|
|
||||||
- Revisar logs de errores
|
|
||||||
- Actualizar contenedores si hay parches de seguridad
|
|
||||||
|
|
||||||
### Tareas Mensuales
|
|
||||||
- Renovar certificados SSL (automatico con MiaB)
|
|
||||||
- Revisar uso de disco
|
|
||||||
- Actualizar sistema operativo
|
|
||||||
|
|
||||||
### Actualizacion de Contenedores
|
|
||||||
|
|
||||||
```bash
|
|
||||||
cd /opt/services
|
|
||||||
docker compose pull
|
|
||||||
docker compose up -d
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Resolucion de Problemas Comunes
|
|
||||||
|
|
||||||
### SSL no funciona
|
|
||||||
1. Verificar que DNS apunta correctamente
|
|
||||||
2. Esperar propagacion (hasta 24h)
|
|
||||||
3. Ejecutar: `mailinabox` para regenerar certificados
|
|
||||||
|
|
||||||
### Contenedor no inicia
|
|
||||||
```bash
|
|
||||||
docker logs NOMBRE_CONTENEDOR
|
|
||||||
# Verificar si es problema de dependencias o configuracion
|
|
||||||
```
|
|
||||||
|
|
||||||
### Email no llega
|
|
||||||
1. Verificar registros MX en DNS
|
|
||||||
2. Revisar logs: `docker logs postfix` o `/var/log/mail.log`
|
|
||||||
3. Verificar que puerto 25 no esta bloqueado
|
|
||||||
|
|
||||||
### Base de datos llena
|
|
||||||
```bash
|
|
||||||
# Ver espacio
|
|
||||||
docker exec postgres psql -U tzzr -c "SELECT pg_size_pretty(pg_database_size('tzzr'));"
|
|
||||||
|
|
||||||
# Limpiar si es necesario
|
|
||||||
docker exec postgres vacuumdb -U tzzr -d tzzr -f
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Contacto y Soporte
|
|
||||||
|
|
||||||
- **Repositorio**: (agregar si se crea)
|
|
||||||
- **Documentacion Mail-in-a-Box**: https://mailinabox.email/guide.html
|
|
||||||
- **Documentacion Vaultwarden**: https://github.com/dani-garcia/vaultwarden/wiki
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
*Documento generado: Diciembre 2024*
|
|
||||||
*Ultima actualizacion: Incluye Vaultwarden y plan de clonacion*
|
|
||||||
@@ -1,122 +0,0 @@
|
|||||||
# FELDMAN
|
|
||||||
|
|
||||||

|
|
||||||
|
|
||||||
|
|
||||||
**Registro consolidado - Sistema TZZR**
|
|
||||||
|
|
||||||
## Rol
|
|
||||||
|
|
||||||
Contable del sistema. Valida y archiva registros en bloques inmutables.
|
|
||||||
|
|
||||||
## Posición en el Flujo
|
|
||||||
|
|
||||||
```
|
|
||||||
MASON ─────────────────┬──► FELDMAN
|
|
||||||
│ │
|
|
||||||
ALFRED/JARED (OK) ─────┘ │
|
|
||||||
▼
|
|
||||||
┌─────────────────────┐
|
|
||||||
│ COLA (24h) │
|
|
||||||
│ ○ ○ ○ ○ ○ │
|
|
||||||
└─────────┬───────────┘
|
|
||||||
│
|
|
||||||
cada 24h
|
|
||||||
│
|
|
||||||
▼
|
|
||||||
┌─────────────────────┐
|
|
||||||
│ BLOQUE INMUTABLE │
|
|
||||||
│ #1 → #2 → #3 → ... │
|
|
||||||
└─────────────────────┘
|
|
||||||
```
|
|
||||||
|
|
||||||
## Fases
|
|
||||||
|
|
||||||
### 1. Cola (24h)
|
|
||||||
- Registros esperando consolidación
|
|
||||||
- Usuario puede devolver a MASON
|
|
||||||
- Configurable
|
|
||||||
|
|
||||||
### 2. Bloques
|
|
||||||
- Registros inmutables
|
|
||||||
- Hash encadenado
|
|
||||||
- Preparado para blockchain
|
|
||||||
|
|
||||||
## Estructura de Bloque
|
|
||||||
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"numero": 127,
|
|
||||||
"id": "sha256-bloque",
|
|
||||||
"hash_anterior": "def456...",
|
|
||||||
"merkle_root": "789abc...",
|
|
||||||
"validado_at": "2025-12-22T00:00:00Z",
|
|
||||||
"registros": [...],
|
|
||||||
"cantidad": 45
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
## Estructura del Contenedor en FELDMAN
|
|
||||||
|
|
||||||
Cuando un registro se consolida, FELDMAN anade la seccion `bloque` al contenedor (ver [esquema completo](https://git.tzzr.me/tzzr/contratos-comunes/src/branch/main/architecture/06-contenedor-schema.md)):
|
|
||||||
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"bloque": {
|
|
||||||
"id": "sha256-bloque",
|
|
||||||
"numero": 127,
|
|
||||||
"registro_hash": "sha256-este-registro",
|
|
||||||
"merkle_proof": ["sha256-1", "sha256-2", "sha256-3"]
|
|
||||||
},
|
|
||||||
|
|
||||||
"estado": {
|
|
||||||
"actual": "en_feldman_bloque",
|
|
||||||
"historial": [
|
|
||||||
{"paso": "clara", "entrada": "...", "salida": "..."},
|
|
||||||
{"paso": "mason", "entrada": "...", "salida": "..."},
|
|
||||||
{"paso": "feldman_cola", "entrada": "...", "salida": "..."},
|
|
||||||
{"paso": "feldman_bloque", "entrada": "...", "procesado_por": "feldman-service"}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
### Campos del bloque
|
|
||||||
|
|
||||||
| Campo | Tipo | Descripcion |
|
|
||||||
|-------|------|-------------|
|
|
||||||
| `id` | SHA-256 | Hash del bloque completo |
|
|
||||||
| `numero` | Int | Numero secuencial del bloque |
|
|
||||||
| `registro_hash` | SHA-256 | Hash de este registro especifico |
|
|
||||||
| `merkle_proof` | Array | Prueba de inclusion en el arbol Merkle |
|
|
||||||
|
|
||||||
### Verificacion
|
|
||||||
|
|
||||||
Con `merkle_proof` se puede verificar que un registro pertenece a un bloque sin tener acceso a todos los registros del bloque.
|
|
||||||
|
|
||||||
```
|
|
||||||
merkle_root
|
|
||||||
│
|
|
||||||
┌───────┴───────┐
|
|
||||||
│ │
|
|
||||||
hash_ab hash_cd
|
|
||||||
│ │
|
|
||||||
┌────┴────┐ ┌────┴────┐
|
|
||||||
│ │ │ │
|
|
||||||
reg_a reg_b reg_c reg_d
|
|
||||||
```
|
|
||||||
|
|
||||||
### Inmutabilidad
|
|
||||||
|
|
||||||
- Una vez consolidado, el registro es **inmutable**
|
|
||||||
- `estado.actual` cambia a `en_feldman_bloque`
|
|
||||||
- La seccion `bloque` se anade y nunca cambia
|
|
||||||
- El hash del registro se incluye en el arbol Merkle
|
|
||||||
|
|
||||||
## Arquitectura
|
|
||||||
|
|
||||||
Ver documentación completa en [contratos-comunes/architecture](https://git.tzzr.me/tzzr/contratos-comunes/src/branch/main/architecture/04-feldman.md)
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
*Componente del sistema TZZR*
|
|
||||||
@@ -1,119 +0,0 @@
|
|||||||
# GRACE - Despliegue en RunPod
|
|
||||||
|
|
||||||
## Estado Actual
|
|
||||||
|
|
||||||
| Componente | Estado |
|
|
||||||
|------------|--------|
|
|
||||||
| Endpoint ID | `r00x4g3rrwkbyh` |
|
|
||||||
| Template ID | `16zimxx2xj` |
|
|
||||||
| Nombre | grace-gpu |
|
|
||||||
| GPU | RTX 4090 |
|
|
||||||
| Balance | $73+ |
|
|
||||||
| Imagen | PENDIENTE |
|
|
||||||
|
|
||||||
## Problema
|
|
||||||
|
|
||||||
El template usa la imagen base `runpod/pytorch:2.1.0-py3.10-cuda11.8.0-devel-ubuntu22.04` sin el handler de GRACE. Necesita imagen custom.
|
|
||||||
|
|
||||||
## Solucion: Build y Push Docker Image
|
|
||||||
|
|
||||||
### Opcion 1: Build Local
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# En maquina con Docker
|
|
||||||
cd grace/runpod
|
|
||||||
|
|
||||||
# Build
|
|
||||||
docker build -t tzzrsystems/grace:latest .
|
|
||||||
|
|
||||||
# Login a DockerHub
|
|
||||||
docker login
|
|
||||||
|
|
||||||
# Push
|
|
||||||
docker push tzzrsystems/grace:latest
|
|
||||||
```
|
|
||||||
|
|
||||||
### Opcion 2: GitHub Actions (Recomendado)
|
|
||||||
|
|
||||||
Crear `.github/workflows/build-grace.yml`:
|
|
||||||
|
|
||||||
```yaml
|
|
||||||
name: Build GRACE Docker
|
|
||||||
|
|
||||||
on:
|
|
||||||
push:
|
|
||||||
branches: [main]
|
|
||||||
paths: ['runpod/**']
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
build:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v4
|
|
||||||
|
|
||||||
- name: Login to DockerHub
|
|
||||||
uses: docker/login-action@v3
|
|
||||||
with:
|
|
||||||
username: ${{ secrets.DOCKERHUB_USERNAME }}
|
|
||||||
password: ${{ secrets.DOCKERHUB_TOKEN }}
|
|
||||||
|
|
||||||
- name: Build and Push
|
|
||||||
uses: docker/build-push-action@v5
|
|
||||||
with:
|
|
||||||
context: ./runpod
|
|
||||||
push: true
|
|
||||||
tags: tzzrsystems/grace:latest
|
|
||||||
```
|
|
||||||
|
|
||||||
## Actualizar Template en RunPod
|
|
||||||
|
|
||||||
Una vez la imagen este en DockerHub:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
curl -X POST "https://api.runpod.io/graphql" \
|
|
||||||
-H "Content-Type: application/json" \
|
|
||||||
-H "Authorization: Bearer YOUR_API_KEY" \
|
|
||||||
-d '{
|
|
||||||
"query": "mutation { saveTemplate(input: { id: \"16zimxx2xj\", imageName: \"tzzrsystems/grace:latest\" }) { id imageName } }"
|
|
||||||
}'
|
|
||||||
```
|
|
||||||
|
|
||||||
## Verificar Funcionamiento
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Test EMBEDDINGS (mas rapido)
|
|
||||||
curl -X POST "https://api.runpod.ai/v2/r00x4g3rrwkbyh/runsync" \
|
|
||||||
-H "Authorization: Bearer YOUR_API_KEY" \
|
|
||||||
-H "Content-Type: application/json" \
|
|
||||||
-d '{
|
|
||||||
"input": {
|
|
||||||
"contract_version": "2.1",
|
|
||||||
"routing": {"module": "EMBEDDINGS"},
|
|
||||||
"payload": {"type": "text", "encoding": "utf-8", "content": "Test"},
|
|
||||||
"context": {}
|
|
||||||
}
|
|
||||||
}'
|
|
||||||
```
|
|
||||||
|
|
||||||
## Modulos Disponibles
|
|
||||||
|
|
||||||
| Modulo | Uso | Modelo |
|
|
||||||
|--------|-----|--------|
|
|
||||||
| ASR_ENGINE | Audio -> Texto | Whisper Large V3 |
|
|
||||||
| OCR_CORE | Imagen -> Texto | GOT-OCR 2.0 |
|
|
||||||
| TTS | Texto -> Audio | XTTS-v2 |
|
|
||||||
| EMBEDDINGS | Texto -> Vector | BGE-Large |
|
|
||||||
| FACE_VECTOR | Imagen -> Vector facial | InsightFace |
|
|
||||||
| AVATAR_GEN | Prompt -> Imagen | SDXL |
|
|
||||||
|
|
||||||
## Estimacion de Costos
|
|
||||||
|
|
||||||
RTX 4090: ~$0.44/hora
|
|
||||||
- Cold start: 2-4 min
|
|
||||||
- Idle timeout: 10 seg
|
|
||||||
|
|
||||||
Con minWorkers=0 solo pagas por uso real.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
*Documentacion generada 2025-12-24*
|
|
||||||
@@ -1,51 +0,0 @@
|
|||||||
# GRACE - GPU Real-time Audio Conversion Engine
|
|
||||||
|
|
||||||
## Descripción
|
|
||||||
Servicio de conversión de audio en tiempo real usando GPU.
|
|
||||||
|
|
||||||
## Módulos
|
|
||||||
- **ASR_ENGINE**: Speech-to-Text (Whisper)
|
|
||||||
- **TTS_ENGINE**: Text-to-Speech (XTTS)
|
|
||||||
|
|
||||||
## Endpoint RunPod
|
|
||||||
- ID: `r00x4g3rrwkbyh`
|
|
||||||
- URL: `https://api.runpod.ai/v2/r00x4g3rrwkbyh/runsync`
|
|
||||||
- Workers: 2
|
|
||||||
- GPU: NVIDIA L4
|
|
||||||
|
|
||||||
## Código
|
|
||||||
Ubicación: `s3://architect/gpu-services/grace/code/handler.py`
|
|
||||||
|
|
||||||
## Uso
|
|
||||||
|
|
||||||
### ASR (Speech-to-Text)
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"input": {
|
|
||||||
"module": "ASR_ENGINE",
|
|
||||||
"data": {
|
|
||||||
"audio_base64": "...",
|
|
||||||
"language": "es"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
### TTS (Text-to-Speech)
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"input": {
|
|
||||||
"module": "TTS_ENGINE",
|
|
||||||
"data": {
|
|
||||||
"text": "Hola mundo",
|
|
||||||
"language": "es",
|
|
||||||
"voice_id": "default"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
## Arquitectura
|
|
||||||
```
|
|
||||||
Cliente → RunPod → GRACE Handler → Whisper/XTTS → Response
|
|
||||||
```
|
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -1,139 +0,0 @@
|
|||||||
# ✨ GRACE
|
|
||||||
|
|
||||||
**Capa Cognitiva Determinista - Sistema SFE/HST Enterprise v5.0**
|
|
||||||
|
|
||||||
> "GRACE transforma, Alfred decide."
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## ¿Qué es GRACE?
|
|
||||||
|
|
||||||
GRACE es la capa cognitiva del sistema: 18 microservicios de IA desacoplados.
|
|
||||||
|
|
||||||
- NO es chatbot
|
|
||||||
- NO guarda estado
|
|
||||||
- NO toma decisiones de flujo
|
|
||||||
- Transforma datos según request
|
|
||||||
- Intercambiable: sustituir modelo sin romper sistema
|
|
||||||
|
|
||||||
```
|
|
||||||
┌──────────────────┐
|
|
||||||
│ ALFRED (n8n) │
|
|
||||||
│ Orquestador │
|
|
||||||
└────────┬─────────┘
|
|
||||||
│
|
|
||||||
┌──────────────┼──────────────┐
|
|
||||||
│ │ │
|
|
||||||
▼ ▼ ▼
|
|
||||||
┌──────────┐ ┌──────────┐ ┌──────────┐
|
|
||||||
│ LOCAL │ │ LOCAL │ │ REMOTO │
|
|
||||||
│ Ligero │ │ Medio │ │ Pesado │
|
|
||||||
│ (CPU) │ │ (CPU+) │ │ (GPU) │
|
|
||||||
└──────────┘ └──────────┘ └──────────┘
|
|
||||||
|
|
||||||
Whisper-tiny Embeddings GPT-4o Vision
|
|
||||||
Regex/Rules OCR-Local Claude Sonnet
|
|
||||||
Hashing Whisper Large
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Los 18 Módulos
|
|
||||||
|
|
||||||
### Familia VISIÓN
|
|
||||||
| Módulo | Función |
|
|
||||||
|--------|---------|
|
|
||||||
| `IMAGE_PROCESSOR` | Limpieza, resize, crop, denoise |
|
|
||||||
| `PDF_SCANNER` | Recorte automático, deskew, contraste |
|
|
||||||
| `OCR_CORE` | Lectura de texto |
|
|
||||||
|
|
||||||
### Familia VOZ
|
|
||||||
| Módulo | Función |
|
|
||||||
|--------|---------|
|
|
||||||
| `ASR` | Audio → Texto |
|
|
||||||
| `TTS` | Texto → Audio |
|
|
||||||
|
|
||||||
### Familia IDENTIDAD
|
|
||||||
| Módulo | Función | PII |
|
|
||||||
|--------|---------|-----|
|
|
||||||
| `FACE_VECTOR` | Extrae vector facial 512D | ✓ |
|
|
||||||
| `ID_CONSOLIDATION` | Fusiona múltiples vectores | ✓ |
|
|
||||||
| `AVATAR_GEN` | Genera avatar desde vector | - |
|
|
||||||
|
|
||||||
### Familia NLP
|
|
||||||
| Módulo | Función |
|
|
||||||
|--------|---------|
|
|
||||||
| `SUMMARIZER` | Resume texto |
|
|
||||||
| `CLASSIFIER` | Clasifica documentos |
|
|
||||||
| `TASK_DETECTOR` | Extrae tareas de texto |
|
|
||||||
|
|
||||||
### Familia SEMÁNTICA
|
|
||||||
| Módulo | Función |
|
|
||||||
|--------|---------|
|
|
||||||
| `EMBEDDINGS` | Texto → vectores |
|
|
||||||
| `SIMILARITY` | Compara vectores |
|
|
||||||
|
|
||||||
### Familia ESTRUCTURA
|
|
||||||
| Módulo | Función |
|
|
||||||
|--------|---------|
|
|
||||||
| `FIELD_EXTRACTOR` | Extrae campos de documentos |
|
|
||||||
| `HASH_SIGNER` | SHA256/512/BLAKE2B |
|
|
||||||
| `LANG_NORMALIZER` | Detecta idioma |
|
|
||||||
| `INPUT_TRANSLATOR` | Normaliza entrada |
|
|
||||||
| `OUTPUT_TRANSLATOR` | Formato legacy |
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Arquitectura Híbrida
|
|
||||||
|
|
||||||
| Tier | Tipo | Proveedores |
|
|
||||||
|------|------|-------------|
|
|
||||||
| **TIER 1** | GPU Serverless | RunPod, Modal, Replicate |
|
|
||||||
| **TIER 2** | APIs Premium | OpenAI, Anthropic, Google |
|
|
||||||
|
|
||||||
**Routing por módulo**: Cada módulo define su cadena de fallback.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Inicio Rápido
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Instalar
|
|
||||||
pip install -r requirements.txt
|
|
||||||
|
|
||||||
# Configurar
|
|
||||||
cp .env.example .env
|
|
||||||
|
|
||||||
# Ejecutar
|
|
||||||
uvicorn app.main:app --reload
|
|
||||||
|
|
||||||
# Verificar
|
|
||||||
curl http://localhost:8000/health
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Contrato Común v1.2
|
|
||||||
|
|
||||||
Todos los módulos usan la misma interfaz:
|
|
||||||
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"envelope": {
|
|
||||||
"trace_id": "uuid",
|
|
||||||
"step_id": "uuid"
|
|
||||||
},
|
|
||||||
"routing": {
|
|
||||||
"module": "OCR_CORE",
|
|
||||||
"version": "1.0"
|
|
||||||
},
|
|
||||||
"payload": {
|
|
||||||
"type": "image",
|
|
||||||
"content": "base64..."
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
**Sistema SFE/HST Enterprise v5.0**
|
|
||||||
@@ -1,47 +0,0 @@
|
|||||||
# HST - Hierarchical Semantic Tags
|
|
||||||
|
|
||||||
## Servidor
|
|
||||||
- IP: 72.62.2.84
|
|
||||||
- Directus: http://72.62.2.84:8055
|
|
||||||
|
|
||||||
## Base de Datos
|
|
||||||
- DB: `hst_images`
|
|
||||||
- Usuario: nocodb
|
|
||||||
- 973 tags en 5 tablas
|
|
||||||
|
|
||||||
## Tablas
|
|
||||||
|
|
||||||
| Tabla | Registros | Descripción |
|
|
||||||
|-------|-----------|-------------|
|
|
||||||
| hst | 658 | Tags históricos |
|
|
||||||
| spe | 145 | Especialidades |
|
|
||||||
| vsn | 84 | Versiones |
|
|
||||||
| flg | 65 | Flags |
|
|
||||||
| vue | 21 | Vistas |
|
|
||||||
|
|
||||||
## API Pública
|
|
||||||
|
|
||||||
### Endpoints
|
|
||||||
```
|
|
||||||
GET /items/hst
|
|
||||||
GET /items/spe
|
|
||||||
GET /items/vsn
|
|
||||||
GET /items/flg
|
|
||||||
GET /items/vue
|
|
||||||
```
|
|
||||||
|
|
||||||
### Ejemplo
|
|
||||||
```bash
|
|
||||||
curl http://72.62.2.84:8055/items/hst?limit=10
|
|
||||||
```
|
|
||||||
|
|
||||||
## Containers Docker
|
|
||||||
- directus_hst (8055)
|
|
||||||
- postgres_hst (5432)
|
|
||||||
- hst-images (80/443) - nginx proxy
|
|
||||||
- filebrowser (8081)
|
|
||||||
|
|
||||||
## Acceso Admin
|
|
||||||
- URL: http://72.62.2.84:8055
|
|
||||||
- Email: admin@tzzr.systems
|
|
||||||
- Password: tzzr2024
|
|
||||||
@@ -1,128 +0,0 @@
|
|||||||
# HST Image Server API
|
|
||||||
|
|
||||||
## Base URL
|
|
||||||
|
|
||||||
```
|
|
||||||
https://tzrtech.org
|
|
||||||
```
|
|
||||||
|
|
||||||
## Endpoints
|
|
||||||
|
|
||||||
### GET /api/index.json
|
|
||||||
|
|
||||||
Returns all tables with their records.
|
|
||||||
|
|
||||||
**Response:**
|
|
||||||
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"_meta": {
|
|
||||||
"version": "1.1",
|
|
||||||
"updated": "2024-12-17T12:00:00Z",
|
|
||||||
"base_url": "https://tzrtech.org",
|
|
||||||
"image_url_pattern": "https://tzrtech.org/{mrf}.png",
|
|
||||||
"subdomain_pattern": "https://{ref}_{nombre}.tzrtech.org",
|
|
||||||
"tables": ["flg", "hst", "spe", "vue", "vsn"]
|
|
||||||
},
|
|
||||||
"hst": {
|
|
||||||
"count": 150,
|
|
||||||
"records": [
|
|
||||||
{
|
|
||||||
"ref": "ABC",
|
|
||||||
"nombre_es": "Nombre en español",
|
|
||||||
"nombre_en": "Name in English",
|
|
||||||
"mrf": "sha256hash...",
|
|
||||||
"rootref": "XYZ"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"flg": { ... },
|
|
||||||
"spe": { ... },
|
|
||||||
"vue": { ... },
|
|
||||||
"vsn": { ... }
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
## Image Access
|
|
||||||
|
|
||||||
### Direct URL
|
|
||||||
|
|
||||||
```
|
|
||||||
https://tzrtech.org/{mrf}.png
|
|
||||||
```
|
|
||||||
|
|
||||||
Example:
|
|
||||||
```
|
|
||||||
https://tzrtech.org/a1b2c3d4e5f6...png
|
|
||||||
```
|
|
||||||
|
|
||||||
### Subdomain URL
|
|
||||||
|
|
||||||
```
|
|
||||||
https://{ref}_{nombre}.tzrtech.org
|
|
||||||
```
|
|
||||||
|
|
||||||
Example:
|
|
||||||
```
|
|
||||||
https://crg_courage.tzrtech.org
|
|
||||||
```
|
|
||||||
|
|
||||||
This redirects to the direct image URL.
|
|
||||||
|
|
||||||
## Tables
|
|
||||||
|
|
||||||
| Table | Description |
|
|
||||||
|-------|-------------|
|
|
||||||
| `hst` | Hashtags - main semantic tags |
|
|
||||||
| `spe` | Specs - specifications |
|
|
||||||
| `flg` | Flags - status indicators |
|
|
||||||
| `vue` | Values - human values |
|
|
||||||
| `vsn` | Visions - archetypal visions |
|
|
||||||
|
|
||||||
## Record Schema
|
|
||||||
|
|
||||||
| Field | Type | Description |
|
|
||||||
|-------|------|-------------|
|
|
||||||
| `ref` | string | 3-letter unique code |
|
|
||||||
| `nombre_es` | string | Spanish name |
|
|
||||||
| `nombre_en` | string | English name |
|
|
||||||
| `mrf` | string | SHA-256 hash of image file |
|
|
||||||
| `rootref` | string | Parent reference (hierarchy) |
|
|
||||||
|
|
||||||
## Usage Examples
|
|
||||||
|
|
||||||
### JavaScript
|
|
||||||
|
|
||||||
```javascript
|
|
||||||
const response = await fetch('https://tzrtech.org/api/index.json');
|
|
||||||
const data = await response.json();
|
|
||||||
|
|
||||||
// Get all values
|
|
||||||
const values = data.vue.records;
|
|
||||||
|
|
||||||
// Build image URL
|
|
||||||
const imageUrl = `https://tzrtech.org/${values[0].mrf}.png`;
|
|
||||||
```
|
|
||||||
|
|
||||||
### Python
|
|
||||||
|
|
||||||
```python
|
|
||||||
import requests
|
|
||||||
|
|
||||||
response = requests.get('https://tzrtech.org/api/index.json')
|
|
||||||
data = response.json()
|
|
||||||
|
|
||||||
# Get all hashtags
|
|
||||||
hashtags = data['hst']['records']
|
|
||||||
|
|
||||||
# Build image URL
|
|
||||||
image_url = f"https://tzrtech.org/{hashtags[0]['mrf']}.png"
|
|
||||||
```
|
|
||||||
|
|
||||||
## CORS
|
|
||||||
|
|
||||||
The API allows cross-origin requests:
|
|
||||||
|
|
||||||
```
|
|
||||||
Access-Control-Allow-Origin: *
|
|
||||||
```
|
|
||||||
@@ -1,394 +0,0 @@
|
|||||||
# HST - Roadmap de Implementación
|
|
||||||
**Versión:** 1.0
|
|
||||||
**Fecha:** 2025-12-07
|
|
||||||
**Estado:** Borrador para maduración
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
# Visión General
|
|
||||||
|
|
||||||
El sistema HST (Hash Semantic Tagging) evolucionará en 4 fases, desde especificación formal hasta una aplicación cliente universal de drag & drop.
|
|
||||||
|
|
||||||
```
|
|
||||||
Fase 0 Fase 1 Fase 2 Fase 3
|
|
||||||
SPEC → Servidor → Descentralización → App Cliente
|
|
||||||
(Documentos) (KVM1 Hostinger) (Filecoin/IPFS) (Drag & Drop)
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
# Fase 0: Especificación Formal
|
|
||||||
|
|
||||||
## Objetivo
|
|
||||||
Documento definitivo que describe el sistema completo antes de cualquier implementación.
|
|
||||||
|
|
||||||
## Entregables
|
|
||||||
|
|
||||||
| Documento | Descripción | Estado |
|
|
||||||
|-----------|-------------|--------|
|
|
||||||
| `SPEC.md` | Especificación técnica completa del sistema HST | Pendiente |
|
|
||||||
| `SCHEMA.md` | Modelo de datos para NocoDB/PostgreSQL | Pendiente |
|
|
||||||
| `TAGS_v1.csv` | Listado consolidado de etiquetas (~850) | En progreso |
|
|
||||||
| `HIERARCHY.md` | Árbol jerárquico de categorías | Pendiente |
|
|
||||||
| `RELATIONS.md` | Grafo de relaciones entre etiquetas | Pendiente |
|
|
||||||
| `API.md` | Especificación de endpoints REST | Pendiente |
|
|
||||||
| `STYLES.md` | Tabla de estilos (4096 skins) | Pendiente |
|
|
||||||
|
|
||||||
## Contenido de SPEC.md
|
|
||||||
|
|
||||||
1. Filosofía del sistema
|
|
||||||
2. Imagen primigenia (reglas)
|
|
||||||
3. Hash maestro (H_maestro)
|
|
||||||
4. Extensiones (EXT, HSU, SP, SPU, PRJ)
|
|
||||||
5. Sistema de estilos (hash visible)
|
|
||||||
6. Cadena de metadatos (jerarquía)
|
|
||||||
7. Propiedad y acceso (H_propiedad, H_acceso)
|
|
||||||
8. Bibliotecas (sistema, empresa, usuario)
|
|
||||||
9. Pipeline de importación
|
|
||||||
10. Integración con ecosistema (SFE, IA, n8n)
|
|
||||||
|
|
||||||
## Criterios de salida
|
|
||||||
- [ ] Todos los documentos revisados y aprobados
|
|
||||||
- [ ] Sin ambigüedades técnicas
|
|
||||||
- [ ] Listado de etiquetas limpio y categorizado
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
# Fase 1: Servidor Centralizado
|
|
||||||
|
|
||||||
## Objetivo
|
|
||||||
Primera implementación funcional en servidor KVM1 de Hostinger.
|
|
||||||
|
|
||||||
## Infraestructura
|
|
||||||
|
|
||||||
```
|
|
||||||
KVM1 Hostinger
|
|
||||||
├── Docker
|
|
||||||
│ ├── NocoDB (metadatos)
|
|
||||||
│ ├── PostgreSQL (base de datos)
|
|
||||||
│ └── API HST (FastAPI/Node)
|
|
||||||
├── /hst/
|
|
||||||
│ ├── primigenias/{H_maestro}.png
|
|
||||||
│ └── skins/{hash_visible}.png
|
|
||||||
└── Nginx (proxy + SSL)
|
|
||||||
```
|
|
||||||
|
|
||||||
## Componentes
|
|
||||||
|
|
||||||
| Componente | Tecnología | Función |
|
|
||||||
|------------|------------|---------|
|
|
||||||
| Base de datos | PostgreSQL | Almacén principal |
|
|
||||||
| Interfaz datos | NocoDB | Gestión visual de etiquetas |
|
|
||||||
| API REST | FastAPI | Consulta/servicio de etiquetas |
|
|
||||||
| Almacenamiento | Sistema de archivos | Imágenes primigenias y skins |
|
|
||||||
| Proxy | Nginx | SSL + routing |
|
|
||||||
| Orquestación | n8n (Alfred) | Pipelines de importación |
|
|
||||||
|
|
||||||
## Funcionalidades
|
|
||||||
|
|
||||||
### 1. Gestión de etiquetas
|
|
||||||
- CRUD completo vía NocoDB
|
|
||||||
- Validación de imagen primigenia (sin metadatos)
|
|
||||||
- Cálculo automático de H_maestro
|
|
||||||
- Generación de skins
|
|
||||||
|
|
||||||
### 2. API REST
|
|
||||||
```
|
|
||||||
GET /api/v1/tags # Listar etiquetas
|
|
||||||
GET /api/v1/tags/{h_maestro} # Obtener etiqueta
|
|
||||||
GET /api/v1/tags/{h_maestro}/image # Obtener imagen
|
|
||||||
GET /api/v1/tags/{h_maestro}/skins # Listar skins
|
|
||||||
POST /api/v1/tags # Crear etiqueta
|
|
||||||
GET /api/v1/search?q=... # Buscar por nombre/código
|
|
||||||
GET /api/v1/hierarchy/{ref} # Obtener árbol jerárquico
|
|
||||||
```
|
|
||||||
|
|
||||||
### 3. Pipeline de importación
|
|
||||||
1. Leer desde Airtable (fuente actual)
|
|
||||||
2. Descargar imagen
|
|
||||||
3. Limpiar metadatos
|
|
||||||
4. Calcular SHA-256 → H_maestro
|
|
||||||
5. Generar estructura de metadatos
|
|
||||||
6. Subir primigenia
|
|
||||||
7. Generar skins (según tabla de estilos)
|
|
||||||
8. Registrar en NocoDB
|
|
||||||
|
|
||||||
### 4. Subdominio
|
|
||||||
- `hst.tzzr.pro` o `tags.tzzr.pro`
|
|
||||||
|
|
||||||
## Criterios de salida
|
|
||||||
- [ ] API funcional con todos los endpoints
|
|
||||||
- [ ] ~850 etiquetas migradas desde Airtable
|
|
||||||
- [ ] Pipeline de importación automatizado
|
|
||||||
- [ ] Documentación de API generada
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
# Fase 2: Descentralización
|
|
||||||
|
|
||||||
## Objetivo
|
|
||||||
Servicio multi-usuario escalable con almacenamiento descentralizado.
|
|
||||||
|
|
||||||
## Arquitectura
|
|
||||||
|
|
||||||
```
|
|
||||||
┌─────────────────────────────────────────────────────────┐
|
|
||||||
│ CAPA DE USUARIOS │
|
|
||||||
│ App Web │ App Desktop │ App Móvil │ Extensión │
|
|
||||||
└─────────────────────────────────────────────────────────┘
|
|
||||||
│
|
|
||||||
▼
|
|
||||||
┌─────────────────────────────────────────────────────────┐
|
|
||||||
│ API GATEWAY │
|
|
||||||
│ Auth + Rate Limiting + Routing │
|
|
||||||
└─────────────────────────────────────────────────────────┘
|
|
||||||
│
|
|
||||||
┌─────────────┼─────────────┐
|
|
||||||
▼ ▼ ▼
|
|
||||||
┌─────────────────┐ ┌─────────────┐ ┌─────────────────┐
|
|
||||||
│ NocoDB/PostgreSQL │ │ Redis │ │ Filecoin/IPFS │
|
|
||||||
│ (Índice/Metadatos)│ │ (Cache) │ │ (Imágenes) │
|
|
||||||
└─────────────────┘ └─────────────┘ └─────────────────┘
|
|
||||||
```
|
|
||||||
|
|
||||||
## Componentes nuevos
|
|
||||||
|
|
||||||
| Componente | Función |
|
|
||||||
|------------|---------|
|
|
||||||
| Filecoin/IPFS | Almacenamiento descentralizado de imágenes |
|
|
||||||
| CID (Content ID) | Referencia inmutable a cada imagen |
|
|
||||||
| Sistema de bibliotecas | Pública, privada, por usuario |
|
|
||||||
| Autenticación | JWT + H_propiedad |
|
|
||||||
| Permisos | Control por H_acceso |
|
|
||||||
| Rate limiting | Protección de API pública |
|
|
||||||
|
|
||||||
## Tipos de biblioteca
|
|
||||||
|
|
||||||
| Tipo | Propiedad | Acceso | Descripción |
|
|
||||||
|------|-----------|--------|-------------|
|
|
||||||
| Sistema | HST | Público | Etiquetas base universales |
|
|
||||||
| Empresa | Organización | Miembros | Etiquetas corporativas |
|
|
||||||
| Usuario | Individual | Personal | Etiquetas propias |
|
|
||||||
| Compartida | Múltiple | Definido | Colaboración entre usuarios |
|
|
||||||
|
|
||||||
## Modelo de datos extendido
|
|
||||||
|
|
||||||
```
|
|
||||||
Etiqueta {
|
|
||||||
h_maestro: string (PK)
|
|
||||||
codigo_corto: string
|
|
||||||
nombres: { es, en, zh... }
|
|
||||||
extension: EXT | HSU | SP | SPU | PRJ
|
|
||||||
|
|
||||||
# Almacenamiento
|
|
||||||
cid_primigenia: string # IPFS/Filecoin
|
|
||||||
cid_skins: [string] # Array de CIDs
|
|
||||||
|
|
||||||
# Metadatos
|
|
||||||
cadena_metadatos: [string] # Jerarquía de hashes
|
|
||||||
h_propiedad: string # Biblioteca propietaria
|
|
||||||
h_acceso: string # Nivel de acceso
|
|
||||||
|
|
||||||
# Auditoría
|
|
||||||
created_at: timestamp
|
|
||||||
created_by: string
|
|
||||||
version: int
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
## Flujo de resolución
|
|
||||||
|
|
||||||
```
|
|
||||||
1. Cliente solicita etiqueta por H_maestro
|
|
||||||
2. API busca en caché Redis
|
|
||||||
3. Si no existe → busca en NocoDB (índice)
|
|
||||||
4. Obtiene CID de Filecoin/IPFS
|
|
||||||
5. Resuelve imagen desde red descentralizada
|
|
||||||
6. Cachea resultado
|
|
||||||
7. Retorna al cliente
|
|
||||||
```
|
|
||||||
|
|
||||||
## Criterios de salida
|
|
||||||
- [ ] Imágenes almacenadas en Filecoin/IPFS
|
|
||||||
- [ ] Sistema de bibliotecas funcionando
|
|
||||||
- [ ] Autenticación y permisos implementados
|
|
||||||
- [ ] API pública documentada y protegida
|
|
||||||
- [ ] Al menos 3 bibliotecas de prueba (sistema, empresa, usuario)
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
# Fase 3: Aplicación Cliente
|
|
||||||
|
|
||||||
## Objetivo
|
|
||||||
Aplicación universal de drag & drop para usar etiquetas HST en cualquier software.
|
|
||||||
|
|
||||||
## Plataformas
|
|
||||||
|
|
||||||
| Plataforma | Tecnología | Prioridad |
|
|
||||||
|------------|------------|-----------|
|
|
||||||
| Desktop (Windows/Mac/Linux) | Tauri o Electron | Alta |
|
|
||||||
| Web | React/Vue | Alta |
|
|
||||||
| Móvil (iOS/Android) | React Native o Flutter | Media |
|
|
||||||
| Extensión Chrome/Firefox | WebExtension | Media |
|
|
||||||
| Plugin Office | Office Add-in | Baja |
|
|
||||||
| Plugin Figma | Figma API | Baja |
|
|
||||||
|
|
||||||
## Funcionalidades core
|
|
||||||
|
|
||||||
### 1. Navegador de etiquetas
|
|
||||||
- Vista en árbol (jerarquía)
|
|
||||||
- Vista en grid (visual)
|
|
||||||
- Búsqueda por nombre/código/hash
|
|
||||||
- Filtros por extensión/biblioteca
|
|
||||||
|
|
||||||
### 2. Drag & Drop
|
|
||||||
- Arrastrar etiqueta a cualquier aplicación
|
|
||||||
- Formatos de salida:
|
|
||||||
- Imagen PNG
|
|
||||||
- Código corto (texto)
|
|
||||||
- Hash (texto)
|
|
||||||
- Markdown ``
|
|
||||||
- HTML `<img src="url">`
|
|
||||||
|
|
||||||
### 3. Gestión de bibliotecas
|
|
||||||
- Ver bibliotecas disponibles
|
|
||||||
- Suscribirse a bibliotecas públicas
|
|
||||||
- Crear biblioteca personal
|
|
||||||
- Sincronización offline
|
|
||||||
|
|
||||||
### 4. Creación de etiquetas (usuarios)
|
|
||||||
- Subir imagen primigenia
|
|
||||||
- Asignar código y nombres
|
|
||||||
- Seleccionar extensión (HSU, SPU, PRJ)
|
|
||||||
- Proponer para validación (opcional)
|
|
||||||
|
|
||||||
## Flujo de usuario
|
|
||||||
|
|
||||||
```
|
|
||||||
1. Usuario abre app HST
|
|
||||||
2. Navega/busca etiqueta deseada
|
|
||||||
3. Arrastra etiqueta
|
|
||||||
4. Suelta en aplicación destino (Word, Figma, etc.)
|
|
||||||
5. La etiqueta se inserta como imagen/texto según contexto
|
|
||||||
```
|
|
||||||
|
|
||||||
## Integración con sistema operativo
|
|
||||||
|
|
||||||
| OS | Método |
|
|
||||||
|----|--------|
|
|
||||||
| Windows | Clipboard API + Shell Extension |
|
|
||||||
| macOS | NSPasteboard + Finder Extension |
|
|
||||||
| Linux | X11/Wayland Clipboard |
|
|
||||||
|
|
||||||
## Modelo de monetización (futuro)
|
|
||||||
|
|
||||||
| Tier | Precio | Incluye |
|
|
||||||
|------|--------|---------|
|
|
||||||
| Free | 0€ | Biblioteca pública, 10 etiquetas propias |
|
|
||||||
| Pro | 5€/mes | Bibliotecas ilimitadas, skins premium |
|
|
||||||
| Enterprise | Personalizado | Bibliotecas privadas, soporte, SLA |
|
|
||||||
|
|
||||||
## Criterios de salida
|
|
||||||
- [ ] App desktop funcional (1 plataforma mínimo)
|
|
||||||
- [ ] Drag & drop funcionando en apps comunes
|
|
||||||
- [ ] Sincronización con servidor HST
|
|
||||||
- [ ] Documentación de usuario
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
# Dependencias entre fases
|
|
||||||
|
|
||||||
```
|
|
||||||
Fase 0 ──────► Fase 1 ──────► Fase 2 ──────► Fase 3
|
|
||||||
│ │ │ │
|
|
||||||
│ │ │ │
|
|
||||||
▼ ▼ ▼ ▼
|
|
||||||
SPEC.md Servidor Filecoin App
|
|
||||||
SCHEMA.md NocoDB Auth Desktop
|
|
||||||
TAGS.csv API REST Bibliotecas Drag&Drop
|
|
||||||
Pipeline Permisos Móvil
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
# H_propiedad y H_acceso (PENDIENTE DEFINIR)
|
|
||||||
|
|
||||||
## H_propiedad - Definición parcial
|
|
||||||
|
|
||||||
Identifica el propietario/origen de la etiqueta.
|
|
||||||
|
|
||||||
| Grupo | H_propiedad |
|
|
||||||
|-------|-------------|
|
|
||||||
| `hst` | Hash de la etiqueta "hst" (sistema) |
|
|
||||||
| `spe` | Hash de la etiqueta "especificación" (sistema) |
|
|
||||||
| `hsu` | Hash del usuario creador |
|
|
||||||
| `msu` | Hash del usuario creador |
|
|
||||||
|
|
||||||
## H_acceso - Por definir
|
|
||||||
|
|
||||||
Llave de acceso para descarga de imagen. Relacionado con:
|
|
||||||
- Sistema de monetización futuro
|
|
||||||
- Compartición de bibliotecas entre usuarios
|
|
||||||
- Colaboración en proyectos (msu)
|
|
||||||
|
|
||||||
**Notas:**
|
|
||||||
- Se exploró embeber en metadatos PNG pero no está validado
|
|
||||||
- Inicialmente innecesario: la cadena estará en NocoDB
|
|
||||||
- Los grupos hsu/msu permiten compartición (por definir mecanismo)
|
|
||||||
- Diferenciación de grupos define reglas de acceso diferentes
|
|
||||||
|
|
||||||
**TODO para próximas revisiones:**
|
|
||||||
- [ ] Definir mecanismo de compartición de bibliotecas usuario
|
|
||||||
- [ ] Definir modelo de monetización y su relación con H_acceso
|
|
||||||
- [ ] Validar si metadatos embebidos en PNG son viables
|
|
||||||
- [ ] Definir permisos de colaboración en proyectos (msu)
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
# Preguntas abiertas (a resolver)
|
|
||||||
|
|
||||||
## Fase 0
|
|
||||||
- [x] ¿Formato definitivo de código corto? → Variable según grupo
|
|
||||||
- [ ] ¿Cuántos estilos iniciales implementar?
|
|
||||||
- [x] ¿Estructura exacta de cadena_metadatos? → Definida parcialmente
|
|
||||||
|
|
||||||
## Fase 1
|
|
||||||
- [ ] ¿Dominio/subdominio para el servicio?
|
|
||||||
- [ ] ¿Migración completa desde Airtable o parcial?
|
|
||||||
- [ ] ¿Autenticación desde Fase 1 o solo Fase 2?
|
|
||||||
|
|
||||||
## Fase 2
|
|
||||||
- [ ] ¿Filecoin vs IPFS vs ambos?
|
|
||||||
- [ ] ¿Modelo de costos de almacenamiento descentralizado?
|
|
||||||
- [ ] ¿Política de bibliotecas públicas (quién puede publicar)?
|
|
||||||
|
|
||||||
## Fase 3
|
|
||||||
- [ ] ¿Prioridad de plataformas?
|
|
||||||
- [ ] ¿Modelo freemium desde el inicio?
|
|
||||||
- [ ] ¿Integración con marketplaces de plugins?
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
# Timeline estimado
|
|
||||||
|
|
||||||
| Fase | Duración estimada | Dependencias |
|
|
||||||
|------|-------------------|--------------|
|
|
||||||
| Fase 0 | 1-2 semanas | Ninguna |
|
|
||||||
| Fase 1 | 2-4 semanas | Fase 0 completa |
|
|
||||||
| Fase 2 | 4-8 semanas | Fase 1 estable |
|
|
||||||
| Fase 3 | 8-12 semanas | Fase 2 funcional |
|
|
||||||
|
|
||||||
**Total estimado:** 4-6 meses para MVP completo
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
# Notas
|
|
||||||
|
|
||||||
- Este roadmap es un documento vivo que evolucionará
|
|
||||||
- Cada fase tiene criterios de salida claros
|
|
||||||
- Las fases pueden solaparse parcialmente
|
|
||||||
- Priorizar funcionalidad sobre perfección en cada fase
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
**Próximo paso:** Consolidar SPEC.md (Fase 0)
|
|
||||||
@@ -1,459 +0,0 @@
|
|||||||
# HST - Especificación Técnica
|
|
||||||
**Sistema de Etiquetado Semántico basado en Hashes**
|
|
||||||
|
|
||||||
**Versión:** 1.0
|
|
||||||
**Fecha:** 2025-12-10
|
|
||||||
**Estado:** Borrador para implementación
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
# 1. Visión General
|
|
||||||
|
|
||||||
## 1.1 Propósito
|
|
||||||
|
|
||||||
HST (Hash Semantic Tagging) es un sistema de etiquetado universal que:
|
|
||||||
- Representa conceptos mediante imágenes e identificadores criptográficos
|
|
||||||
- Desvincula el significado del lenguaje humano
|
|
||||||
- Permite múltiples estilos visuales sin alterar la semántica
|
|
||||||
- Soporta bibliotecas de sistema y de usuario
|
|
||||||
- Está diseñado para uso en documentos, presentaciones y aplicaciones profesionales
|
|
||||||
|
|
||||||
## 1.2 Principios fundamentales
|
|
||||||
|
|
||||||
1. **Identidad inmutable**: El hash SHA-256 de la imagen primigenia es la referencia absoluta
|
|
||||||
2. **Separación semántica/visual**: Los estilos no alteran el significado
|
|
||||||
3. **Códigos memorizables**: Agilidad de uso mediante códigos cortos
|
|
||||||
4. **Jerarquía flexible**: Múltiples árboles y relaciones entre etiquetas
|
|
||||||
5. **Extensibilidad**: Usuarios pueden crear etiquetas propias
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
# 2. Imagen Primigenia
|
|
||||||
|
|
||||||
## 2.1 Definición
|
|
||||||
|
|
||||||
La imagen primigenia es el archivo visual origen de cada etiqueta.
|
|
||||||
|
|
||||||
## 2.2 Requisitos
|
|
||||||
|
|
||||||
- Formato: PNG (por defecto), extensible a otros formatos
|
|
||||||
- Sin metadatos: EXIF, ICC, XMP eliminados
|
|
||||||
- Archivo limpio y 100% reproducible
|
|
||||||
- Cualquier cambio genera un concepto diferente
|
|
||||||
|
|
||||||
## 2.3 Proceso de limpieza
|
|
||||||
|
|
||||||
```
|
|
||||||
1. Recibir imagen original
|
|
||||||
2. Eliminar todos los metadatos (EXIF, ICC, XMP)
|
|
||||||
3. Normalizar canal Alpha si existe
|
|
||||||
4. Resultado: Buffer binario puro
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
# 3. Hash Maestro (H_maestro)
|
|
||||||
|
|
||||||
## 3.1 Generación
|
|
||||||
|
|
||||||
```
|
|
||||||
H_maestro = SHA256(imagen_primigenia_limpia)
|
|
||||||
```
|
|
||||||
|
|
||||||
## 3.2 Propiedades
|
|
||||||
|
|
||||||
- Longitud: 64 caracteres hexadecimales
|
|
||||||
- Inmutable: nunca cambia para una imagen dada
|
|
||||||
- Único: identifica el concepto de forma absoluta
|
|
||||||
- Independiente del nombre, idioma o estilo visual
|
|
||||||
|
|
||||||
## 3.3 Ejemplo
|
|
||||||
|
|
||||||
```
|
|
||||||
Imagen: factura.png (limpia)
|
|
||||||
H_maestro: a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6q7r8s9t0u1v2w3x4y5z6a7b8c9d0e1f2
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
# 4. Sistema de Estilos (Skins)
|
|
||||||
|
|
||||||
## 4.1 Propósito
|
|
||||||
|
|
||||||
Permitir múltiples variantes visuales de un concepto sin alterar su identidad.
|
|
||||||
|
|
||||||
## 4.2 Capacidad
|
|
||||||
|
|
||||||
- 4 caracteres hexadecimales = 65,536 estilos posibles (0000-FFFF)
|
|
||||||
- Estilo `0000` reservado implícitamente (no se usa, la primigenia no lleva estilo)
|
|
||||||
|
|
||||||
## 4.3 Algoritmo de hash visible
|
|
||||||
|
|
||||||
```
|
|
||||||
Entrada:
|
|
||||||
H_maestro (64 chars): a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6q7r8s9t0u1v2w3x4y5z6a7b8c9d0e1f2
|
|
||||||
estilo (4 chars): 0A3F
|
|
||||||
|
|
||||||
Proceso:
|
|
||||||
1. Tomar primeros 60 caracteres de H_maestro
|
|
||||||
2. Dividir en dos mitades de 30 caracteres
|
|
||||||
- H_left = chars 0-29
|
|
||||||
- H_right = chars 30-59
|
|
||||||
3. Descartar últimos 4 caracteres (60-63)
|
|
||||||
4. Insertar estilo entre las dos mitades
|
|
||||||
|
|
||||||
Resultado:
|
|
||||||
hash_visible = H_left + estilo + H_right
|
|
||||||
hash_visible = a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5 + 0A3F + p6q7r8s9t0u1v2w3x4y5z6a7b8c9d0
|
|
||||||
```
|
|
||||||
|
|
||||||
## 4.4 Almacenamiento
|
|
||||||
|
|
||||||
| Tipo | Hash | Ruta |
|
|
||||||
|------|------|------|
|
|
||||||
| Primigenia | H_maestro completo (64 chars) | `/hst/primigenias/{H_maestro}.png` |
|
|
||||||
| Skin | hash_visible (64 chars) | `/hst/skins/{hash_visible}.png` |
|
|
||||||
|
|
||||||
## 4.5 Comportamiento
|
|
||||||
|
|
||||||
- La imagen primigenia se almacena con H_maestro original (sin modificar)
|
|
||||||
- Cada skin se almacena con su hash_visible calculado
|
|
||||||
- En base de datos siempre se guarda H_maestro como referencia
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
# 5. Grupos y Extensiones
|
|
||||||
|
|
||||||
## 5.1 Definición de grupos
|
|
||||||
|
|
||||||
| Grupo | Propiedad | Memorizable | Formato código | Descripción |
|
|
||||||
|-------|-----------|-------------|----------------|-------------|
|
|
||||||
| `hst` | Sistema | ✅ Sí | Alfabético único | Etiquetas semánticas base |
|
|
||||||
| `spe` | Sistema | ❌ No | "spe" repetido | Especificaciones técnicas |
|
|
||||||
| `hsu` | Usuario | ❌ No | "hsu" repetido | Etiquetas de usuario |
|
|
||||||
| `msu` | Usuario | ✅ Sí | Ordinal (001-999) | Proyectos de usuario |
|
|
||||||
|
|
||||||
## 5.2 Filosofía de códigos
|
|
||||||
|
|
||||||
**Códigos memorizables (hst, msu):**
|
|
||||||
- Objetivo: agilizar uso mediante memorización
|
|
||||||
- Ejemplos: `inv` (factura), `dnt` (albarán), `105` (proyecto)
|
|
||||||
|
|
||||||
**Códigos repetidos (spe, hsu):**
|
|
||||||
- Objetivo: indicar categoría, no identificar
|
|
||||||
- El hash es la referencia real
|
|
||||||
- Compromiso entre utilidad y limpieza de biblioteca
|
|
||||||
|
|
||||||
## 5.3 Ejemplos
|
|
||||||
|
|
||||||
```
|
|
||||||
Etiqueta sistema memorizable:
|
|
||||||
grupo: "hst"
|
|
||||||
codigo: "inv"
|
|
||||||
nombre_es: "factura"
|
|
||||||
nombre_en: "invoice"
|
|
||||||
|
|
||||||
Especificación sistema:
|
|
||||||
grupo: "spe"
|
|
||||||
codigo: "spe"
|
|
||||||
nombre_es: "dc 24v"
|
|
||||||
nombre_en: "dc 24v"
|
|
||||||
|
|
||||||
Etiqueta usuario:
|
|
||||||
grupo: "hsu"
|
|
||||||
codigo: "hsu"
|
|
||||||
nombre_es: "mi concepto"
|
|
||||||
|
|
||||||
Proyecto usuario:
|
|
||||||
grupo: "msu"
|
|
||||||
codigo: "105"
|
|
||||||
nombre_es: "SAGRADA FAMILIA 25"
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
# 6. Cadena de Metadatos
|
|
||||||
|
|
||||||
## 6.1 Estructura
|
|
||||||
|
|
||||||
```
|
|
||||||
cadena_metadatos: [
|
|
||||||
H_maestro_raiz,
|
|
||||||
H_maestro_nivel1,
|
|
||||||
H_maestro_nivel2,
|
|
||||||
...,
|
|
||||||
H_maestro_actual,
|
|
||||||
H_propiedad,
|
|
||||||
H_acceso
|
|
||||||
]
|
|
||||||
```
|
|
||||||
|
|
||||||
## 6.2 Componentes
|
|
||||||
|
|
||||||
| Posición | Campo | Descripción |
|
|
||||||
|----------|-------|-------------|
|
|
||||||
| 0..n-3 | Jerarquía | Hashes de ancestros hasta raíz |
|
|
||||||
| n-2 | H_maestro | Hash de la etiqueta actual |
|
|
||||||
| n-1 | H_propiedad | Propietario (ver sección 7) |
|
|
||||||
| n | H_acceso | Llave de acceso (ver sección 8) |
|
|
||||||
|
|
||||||
## 6.3 Cadena de códigos (auxiliar)
|
|
||||||
|
|
||||||
Para legibilidad humana, se mantiene cadena de códigos separada por guiones:
|
|
||||||
|
|
||||||
```
|
|
||||||
jerarquia_codigos: "mhs-flg-rul-spc-spe"
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
# 7. H_propiedad
|
|
||||||
|
|
||||||
## 7.1 Definición
|
|
||||||
|
|
||||||
Identifica el propietario/origen de la etiqueta.
|
|
||||||
|
|
||||||
## 7.2 Valores según grupo
|
|
||||||
|
|
||||||
| Grupo | H_propiedad |
|
|
||||||
|-------|-------------|
|
|
||||||
| `hst` | Hash de la etiqueta "hst" del sistema |
|
|
||||||
| `spe` | Hash de la etiqueta "especificación" del sistema |
|
|
||||||
| `hsu` | Hash del identificador de usuario creador |
|
|
||||||
| `msu` | Hash del identificador de usuario creador |
|
|
||||||
|
|
||||||
## 7.3 Nota
|
|
||||||
|
|
||||||
La implementación exacta se definirá con el sistema de usuarios y monetización.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
# 8. H_acceso
|
|
||||||
|
|
||||||
## 8.1 Definición
|
|
||||||
|
|
||||||
Llave de acceso que controla quién puede descargar/usar la imagen.
|
|
||||||
|
|
||||||
## 8.2 Estado
|
|
||||||
|
|
||||||
**PENDIENTE DEFINIR**
|
|
||||||
|
|
||||||
Relacionado con:
|
|
||||||
- Sistema de monetización futuro
|
|
||||||
- Compartición de bibliotecas entre usuarios
|
|
||||||
- Colaboración en proyectos (msu)
|
|
||||||
|
|
||||||
## 8.3 Notas para implementación futura
|
|
||||||
|
|
||||||
- Inicialmente la cadena completa estará en NocoDB
|
|
||||||
- Se exploró embeber en metadatos PNG (pendiente validar viabilidad)
|
|
||||||
- Los grupos hsu/msu permiten compartición (mecanismo por definir)
|
|
||||||
- Diferenciación de grupos define reglas de acceso diferentes
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
# 9. Schema de Base de Datos
|
|
||||||
|
|
||||||
## 9.1 Tabla: hst_tags
|
|
||||||
|
|
||||||
Almacena todas las etiquetas del sistema.
|
|
||||||
|
|
||||||
| Campo | Tipo | Restricciones | Descripción |
|
|
||||||
|-------|------|---------------|-------------|
|
|
||||||
| id | UUID | PK | Identificador interno |
|
|
||||||
| h_maestro | CHAR(64) | UNIQUE, NOT NULL | Hash SHA-256 de imagen primigenia |
|
|
||||||
| grupo | ENUM | NOT NULL | hst, spe, hsu, msu |
|
|
||||||
| codigo | VARCHAR(10) | NOT NULL | Código memorizable o repetido |
|
|
||||||
| nombre_es | VARCHAR(255) | NOT NULL | Nombre en español |
|
|
||||||
| nombre_en | VARCHAR(255) | | Nombre en inglés |
|
|
||||||
| imagen_url | VARCHAR(500) | | URL temporal (migración) |
|
|
||||||
| h_propiedad | CHAR(64) | | Hash de propietario |
|
|
||||||
| h_acceso | CHAR(64) | | Llave de acceso |
|
|
||||||
| created_at | TIMESTAMP | DEFAULT NOW() | Fecha creación |
|
|
||||||
| metadata | JSONB | | Datos extensibles |
|
|
||||||
|
|
||||||
## 9.2 Tabla: hst_trees
|
|
||||||
|
|
||||||
Define árboles jerárquicos. Una etiqueta puede aparecer en múltiples árboles.
|
|
||||||
|
|
||||||
| Campo | Tipo | Restricciones | Descripción |
|
|
||||||
|-------|------|---------------|-------------|
|
|
||||||
| id | UUID | PK | Identificador interno |
|
|
||||||
| tree_name | VARCHAR(100) | NOT NULL | Nombre del árbol |
|
|
||||||
| h_maestro | CHAR(64) | FK → hst_tags | Etiqueta |
|
|
||||||
| h_padre | CHAR(64) | FK → hst_tags, NULL | Padre (null = raíz) |
|
|
||||||
| orden | INT | | Posición entre hermanos |
|
|
||||||
| rango | INT | | Profundidad en árbol |
|
|
||||||
|
|
||||||
## 9.3 Tabla: hst_relations
|
|
||||||
|
|
||||||
Grafo de relaciones entre etiquetas. Direccional con peso.
|
|
||||||
|
|
||||||
| Campo | Tipo | Restricciones | Descripción |
|
|
||||||
|-------|------|---------------|-------------|
|
|
||||||
| id | UUID | PK | Identificador interno |
|
|
||||||
| h_from | CHAR(64) | FK → hst_tags | Etiqueta origen |
|
|
||||||
| h_to | CHAR(64) | FK → hst_tags | Etiqueta destino |
|
|
||||||
| peso | DECIMAL | | Fuerza de relación (0-1) |
|
|
||||||
| tipo | VARCHAR(50) | | related, part_of, type_of... |
|
|
||||||
| metadata | JSONB | | Datos extensibles |
|
|
||||||
|
|
||||||
## 9.4 Tabla: hst_skins
|
|
||||||
|
|
||||||
Estilos disponibles por etiqueta.
|
|
||||||
|
|
||||||
| Campo | Tipo | Restricciones | Descripción |
|
|
||||||
|-------|------|---------------|-------------|
|
|
||||||
| id | UUID | PK | Identificador interno |
|
|
||||||
| h_maestro | CHAR(64) | FK → hst_tags | Etiqueta base |
|
|
||||||
| estilo | CHAR(4) | NOT NULL | Código de estilo (0000-FFFF) |
|
|
||||||
| hash_visible | CHAR(64) | UNIQUE | Hash calculado con estilo |
|
|
||||||
| nombre | VARCHAR(50) | | Nombre del estilo |
|
|
||||||
| tipo | VARCHAR(20) | | basic, premium, custom |
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
# 10. Estructura de Archivos
|
|
||||||
|
|
||||||
## 10.1 Directorios
|
|
||||||
|
|
||||||
```
|
|
||||||
/hst/
|
|
||||||
├── primigenias/
|
|
||||||
│ └── {H_maestro}.png
|
|
||||||
└── skins/
|
|
||||||
└── {hash_visible}.png
|
|
||||||
```
|
|
||||||
|
|
||||||
## 10.2 Reglas
|
|
||||||
|
|
||||||
- Primigenias: siempre con H_maestro original completo
|
|
||||||
- Skins: siempre con hash_visible calculado
|
|
||||||
- Formato PNG por defecto
|
|
||||||
- Sin metadatos embebidos (inicialmente)
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
# 11. Pipeline de Importación
|
|
||||||
|
|
||||||
## 11.1 Desde Airtable (migración inicial)
|
|
||||||
|
|
||||||
```
|
|
||||||
1. Leer registro de Airtable
|
|
||||||
2. Descargar imagen desde URL
|
|
||||||
3. Limpiar metadatos (EXIF, ICC, XMP)
|
|
||||||
4. Calcular SHA-256 → H_maestro
|
|
||||||
5. Determinar grupo (hst, spe, hsu, msu)
|
|
||||||
6. Renombrar archivo → {H_maestro}.png
|
|
||||||
7. Subir a /hst/primigenias/
|
|
||||||
8. Crear registro en NocoDB (hst_tags)
|
|
||||||
9. Crear entradas en hst_trees según jerarquía
|
|
||||||
10. Actualizar referencias
|
|
||||||
```
|
|
||||||
|
|
||||||
## 11.2 Nueva etiqueta (flujo normal)
|
|
||||||
|
|
||||||
```
|
|
||||||
1. Usuario sube imagen
|
|
||||||
2. Sistema limpia metadatos
|
|
||||||
3. Calcula H_maestro
|
|
||||||
4. Verifica unicidad (no duplicados)
|
|
||||||
5. Asigna grupo y código
|
|
||||||
6. Almacena primigenia
|
|
||||||
7. Crea registro en base de datos
|
|
||||||
8. Genera skins si aplica
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
# 12. Integraciones
|
|
||||||
|
|
||||||
## 12.1 n8n (Alfred)
|
|
||||||
|
|
||||||
- Pipeline de importación automatizado
|
|
||||||
- Asignación de etiquetas en flujos OCR
|
|
||||||
- Sincronización con Airtable (migración)
|
|
||||||
|
|
||||||
## 12.2 API REST
|
|
||||||
|
|
||||||
```
|
|
||||||
GET /api/v1/tags # Listar etiquetas
|
|
||||||
GET /api/v1/tags/{h_maestro} # Obtener etiqueta
|
|
||||||
GET /api/v1/tags/{h_maestro}/image # Obtener imagen primigenia
|
|
||||||
GET /api/v1/tags/{h_maestro}/skins # Listar skins
|
|
||||||
POST /api/v1/tags # Crear etiqueta
|
|
||||||
GET /api/v1/search?q=... # Buscar
|
|
||||||
GET /api/v1/trees/{tree_name} # Obtener árbol
|
|
||||||
GET /api/v1/relations/{h_maestro} # Obtener relaciones
|
|
||||||
```
|
|
||||||
|
|
||||||
## 12.3 Futuro: App Cliente
|
|
||||||
|
|
||||||
- Drag & drop universal
|
|
||||||
- Sincronización de bibliotecas
|
|
||||||
- Creación de etiquetas usuario
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
# 13. Consideraciones de Seguridad
|
|
||||||
|
|
||||||
## 13.1 Integridad
|
|
||||||
|
|
||||||
- H_maestro garantiza integridad de imagen
|
|
||||||
- Cualquier alteración genera hash diferente
|
|
||||||
- Verificación posible en cualquier momento
|
|
||||||
|
|
||||||
## 13.2 Acceso
|
|
||||||
|
|
||||||
- H_acceso controlará permisos (pendiente definir)
|
|
||||||
- Grupos definen reglas base de visibilidad
|
|
||||||
- Sistema vs usuario claramente separados
|
|
||||||
|
|
||||||
## 13.3 Almacenamiento
|
|
||||||
|
|
||||||
- Rutas públicas pero no indexadas
|
|
||||||
- Migración futura a almacenamiento descentralizado (Filecoin/IPFS)
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
# 14. Glosario
|
|
||||||
|
|
||||||
| Término | Definición |
|
|
||||||
|---------|------------|
|
|
||||||
| H_maestro | Hash SHA-256 de imagen primigenia (64 chars) |
|
|
||||||
| hash_visible | Hash con estilo insertado (64 chars) |
|
|
||||||
| Imagen primigenia | Archivo imagen sin metadatos, origen del concepto |
|
|
||||||
| Skin | Variante visual de una etiqueta |
|
|
||||||
| Grupo | Categoría de etiqueta (hst, spe, hsu, msu) |
|
|
||||||
| Código | Identificador corto memorizable |
|
|
||||||
| Cadena de metadatos | Array de hashes: jerarquía + propiedad + acceso |
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
# 15. Pendientes y TODOs
|
|
||||||
|
|
||||||
## Definición
|
|
||||||
- [ ] Mecanismo de compartición de bibliotecas usuario
|
|
||||||
- [ ] Modelo de monetización y relación con H_acceso
|
|
||||||
- [ ] Validar viabilidad de metadatos embebidos en PNG
|
|
||||||
- [ ] Permisos de colaboración en proyectos (msu)
|
|
||||||
- [ ] Definir estilos iniciales a implementar
|
|
||||||
|
|
||||||
## Implementación
|
|
||||||
- [ ] Pipeline de limpieza de metadatos
|
|
||||||
- [ ] Cálculo de H_maestro para etiquetas existentes
|
|
||||||
- [ ] Migración desde Airtable
|
|
||||||
- [ ] API REST
|
|
||||||
- [ ] Integración n8n
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
# 16. Historial de Cambios
|
|
||||||
|
|
||||||
| Versión | Fecha | Cambios |
|
|
||||||
|---------|-------|---------|
|
|
||||||
| 1.0 | 2025-12-10 | Versión inicial |
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
**Fin del documento**
|
|
||||||
@@ -1,71 +0,0 @@
|
|||||||
# JARED
|
|
||||||
|
|
||||||

|
|
||||||
|
|
||||||
|
|
||||||
**Flujos predefinidos pro - Sistema TZZR**
|
|
||||||
|
|
||||||
## Rol
|
|
||||||
|
|
||||||
Flujos predefinidos para CORP. Variante empresarial de ALFRED con funcionalidades adicionales.
|
|
||||||
|
|
||||||
## Posición en el Flujo
|
|
||||||
|
|
||||||
```
|
|
||||||
JARED
|
|
||||||
│
|
|
||||||
¿Salida esperada?
|
|
||||||
│
|
|
||||||
┌──────┴──────┐
|
|
||||||
│ │
|
|
||||||
SÍ NO
|
|
||||||
│ (incidencia)
|
|
||||||
│ │
|
|
||||||
│ ▼
|
|
||||||
│ MASON
|
|
||||||
│ │
|
|
||||||
▼ ▼
|
|
||||||
FELDMAN
|
|
||||||
```
|
|
||||||
|
|
||||||
## Comparación
|
|
||||||
|
|
||||||
| Aspecto | ALFRED (DECK) | JARED (CORP) |
|
|
||||||
|---------|---------------|--------------|
|
|
||||||
| Uso | Personal | Empresarial |
|
|
||||||
| Complejidad | Lite | Pro |
|
|
||||||
| Extras | - | + NOTARIO |
|
|
||||||
|
|
||||||
## Concepto
|
|
||||||
|
|
||||||
A diferencia de MARGARET (inputs sueltos), JARED tiene:
|
|
||||||
- Estructura predefinida
|
|
||||||
- Pasos conocidos
|
|
||||||
- Solo faltan datos variables
|
|
||||||
|
|
||||||
## Ejemplo
|
|
||||||
|
|
||||||
```
|
|
||||||
Flujo: "Registro de gasto empresarial"
|
|
||||||
├── Tipo de gasto: __
|
|
||||||
├── Importe: __ €
|
|
||||||
├── Proveedor: __
|
|
||||||
├── Centro de coste: __
|
|
||||||
├── Proyecto: __
|
|
||||||
└── [Aprobación automática si < 100€]
|
|
||||||
```
|
|
||||||
|
|
||||||
## Salidas
|
|
||||||
|
|
||||||
| Salida | Destino |
|
|
||||||
|--------|---------|
|
|
||||||
| OK | FELDMAN (directo) |
|
|
||||||
| Incidencia | MASON (enriquecimiento) |
|
|
||||||
|
|
||||||
## Arquitectura
|
|
||||||
|
|
||||||
Ver documentación completa en [contratos-comunes/architecture](https://git.tzzr.me/tzzr/contratos-comunes/src/branch/main/architecture/02-alfred-jared.md)
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
*Componente del sistema TZZR*
|
|
||||||
@@ -1,222 +0,0 @@
|
|||||||
# Sincronización R2 con rclone
|
|
||||||
|
|
||||||
Configuración de sincronización bidireccional entre carpeta local y Cloudflare R2.
|
|
||||||
|
|
||||||
## Requisitos
|
|
||||||
|
|
||||||
- rclone instalado
|
|
||||||
- Credenciales R2 (Access Key + Secret)
|
|
||||||
- macOS con launchd o Linux con systemd
|
|
||||||
|
|
||||||
## Instalación rclone
|
|
||||||
|
|
||||||
### macOS
|
|
||||||
```bash
|
|
||||||
brew install rclone
|
|
||||||
```
|
|
||||||
|
|
||||||
### Linux
|
|
||||||
```bash
|
|
||||||
curl https://rclone.org/install.sh | sudo bash
|
|
||||||
```
|
|
||||||
|
|
||||||
## Configuración
|
|
||||||
|
|
||||||
### 1. Crear archivo de configuración
|
|
||||||
|
|
||||||
```bash
|
|
||||||
mkdir -p ~/.config/rclone
|
|
||||||
```
|
|
||||||
|
|
||||||
### 2. Configurar remote R2
|
|
||||||
|
|
||||||
**~/.config/rclone/rclone.conf:**
|
|
||||||
```ini
|
|
||||||
[r2-architect]
|
|
||||||
type = s3
|
|
||||||
provider = Cloudflare
|
|
||||||
access_key_id = {ACCESS_KEY}
|
|
||||||
secret_access_key = {SECRET_KEY}
|
|
||||||
endpoint = https://7dedae6030f5554d99d37e98a5232996.r2.cloudflarestorage.com
|
|
||||||
acl = private
|
|
||||||
```
|
|
||||||
|
|
||||||
### 3. Verificar conexión
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Listar contenido del bucket
|
|
||||||
rclone lsf r2-architect:architect/
|
|
||||||
|
|
||||||
# Con verbose para debug
|
|
||||||
rclone ls r2-architect:architect/ -vv
|
|
||||||
```
|
|
||||||
|
|
||||||
## Sincronización
|
|
||||||
|
|
||||||
### Sync unidireccional (R2 → Local)
|
|
||||||
|
|
||||||
```bash
|
|
||||||
rclone sync r2-architect:architect/ "/path/to/local/folder/" --progress
|
|
||||||
```
|
|
||||||
|
|
||||||
### Sync unidireccional (Local → R2)
|
|
||||||
|
|
||||||
```bash
|
|
||||||
rclone sync "/path/to/local/folder/" r2-architect:architect/ --progress
|
|
||||||
```
|
|
||||||
|
|
||||||
### Bisync bidireccional
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Primera vez: inicializar con --resync
|
|
||||||
rclone bisync "/path/to/local/folder/" r2-architect:architect/ --resync --verbose
|
|
||||||
|
|
||||||
# Ejecuciones posteriores
|
|
||||||
rclone bisync "/path/to/local/folder/" r2-architect:architect/ --verbose
|
|
||||||
```
|
|
||||||
|
|
||||||
## Automatización
|
|
||||||
|
|
||||||
### macOS (launchd)
|
|
||||||
|
|
||||||
**~/Library/LaunchAgents/com.rclone.r2-sync.plist:**
|
|
||||||
```xml
|
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
|
||||||
<plist version="1.0">
|
|
||||||
<dict>
|
|
||||||
<key>Label</key>
|
|
||||||
<string>com.rclone.r2-sync</string>
|
|
||||||
<key>ProgramArguments</key>
|
|
||||||
<array>
|
|
||||||
<string>/opt/homebrew/bin/rclone</string>
|
|
||||||
<string>bisync</string>
|
|
||||||
<string>/Users/{user}/R2 Folder/</string>
|
|
||||||
<string>r2-architect:architect/</string>
|
|
||||||
<string>--verbose</string>
|
|
||||||
</array>
|
|
||||||
<key>StartInterval</key>
|
|
||||||
<integer>300</integer>
|
|
||||||
<key>StandardOutPath</key>
|
|
||||||
<string>/Users/{user}/Library/Logs/rclone-r2-sync.log</string>
|
|
||||||
<key>StandardErrorPath</key>
|
|
||||||
<string>/Users/{user}/Library/Logs/rclone-r2-sync.log</string>
|
|
||||||
<key>RunAtLoad</key>
|
|
||||||
<true/>
|
|
||||||
</dict>
|
|
||||||
</plist>
|
|
||||||
```
|
|
||||||
|
|
||||||
**Comandos launchd:**
|
|
||||||
```bash
|
|
||||||
# Cargar servicio
|
|
||||||
launchctl load ~/Library/LaunchAgents/com.rclone.r2-sync.plist
|
|
||||||
|
|
||||||
# Ver estado
|
|
||||||
launchctl list | grep r2-sync
|
|
||||||
|
|
||||||
# Detener
|
|
||||||
launchctl unload ~/Library/LaunchAgents/com.rclone.r2-sync.plist
|
|
||||||
```
|
|
||||||
|
|
||||||
### Linux (systemd)
|
|
||||||
|
|
||||||
**~/.config/systemd/user/rclone-r2-sync.service:**
|
|
||||||
```ini
|
|
||||||
[Unit]
|
|
||||||
Description=Rclone R2 Bisync
|
|
||||||
After=network-online.target
|
|
||||||
|
|
||||||
[Service]
|
|
||||||
Type=oneshot
|
|
||||||
ExecStart=/usr/bin/rclone bisync /home/{user}/R2/ r2-architect:architect/ --verbose
|
|
||||||
```
|
|
||||||
|
|
||||||
**~/.config/systemd/user/rclone-r2-sync.timer:**
|
|
||||||
```ini
|
|
||||||
[Unit]
|
|
||||||
Description=Run rclone R2 sync every 5 minutes
|
|
||||||
|
|
||||||
[Timer]
|
|
||||||
OnBootSec=1min
|
|
||||||
OnUnitActiveSec=5min
|
|
||||||
|
|
||||||
[Install]
|
|
||||||
WantedBy=timers.target
|
|
||||||
```
|
|
||||||
|
|
||||||
**Comandos systemd:**
|
|
||||||
```bash
|
|
||||||
# Habilitar
|
|
||||||
systemctl --user enable rclone-r2-sync.timer
|
|
||||||
systemctl --user start rclone-r2-sync.timer
|
|
||||||
|
|
||||||
# Ver estado
|
|
||||||
systemctl --user status rclone-r2-sync.timer
|
|
||||||
|
|
||||||
# Ejecutar manualmente
|
|
||||||
systemctl --user start rclone-r2-sync.service
|
|
||||||
```
|
|
||||||
|
|
||||||
## Buckets R2 Disponibles
|
|
||||||
|
|
||||||
| Bucket | Uso | Credenciales |
|
|
||||||
|--------|-----|--------------|
|
|
||||||
| architect | Backups, configs, APKs | Token: architect-sync |
|
|
||||||
| hst | Imágenes HST | Token: locker-full-access |
|
|
||||||
| deck | Archivos personales | Token: locker-full-access |
|
|
||||||
| corp | Documentos empresariales | Token: locker-full-access |
|
|
||||||
| locker | General/temporal | Token: locker-full-access |
|
|
||||||
|
|
||||||
## Tokens R2
|
|
||||||
|
|
||||||
### locker-full-access (todos los buckets)
|
|
||||||
```
|
|
||||||
Endpoint: https://7dedae6030f5554d99d37e98a5232996.r2.cloudflarestorage.com
|
|
||||||
Access Key: ecddc771824c3cb3417d9451780db3d2
|
|
||||||
Secret Key: [ver creds_locker en PostgreSQL]
|
|
||||||
```
|
|
||||||
|
|
||||||
### architect-sync (solo bucket architect)
|
|
||||||
```
|
|
||||||
Access Key: 55125dca442b0f3517d194a5bc0502b8
|
|
||||||
Secret Key: [ver creds_locker.r2_architect_token en PostgreSQL]
|
|
||||||
```
|
|
||||||
|
|
||||||
## Comandos útiles
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Ver logs en tiempo real
|
|
||||||
tail -f ~/Library/Logs/rclone-r2-sync.log
|
|
||||||
|
|
||||||
# Sync manual inmediato
|
|
||||||
rclone bisync "/path/to/folder/" r2-architect:architect/ --verbose
|
|
||||||
|
|
||||||
# Ver diferencias sin sincronizar
|
|
||||||
rclone check "/path/to/folder/" r2-architect:architect/
|
|
||||||
|
|
||||||
# Listar con tamaños
|
|
||||||
rclone ls r2-architect:architect/
|
|
||||||
|
|
||||||
# Subir archivo específico
|
|
||||||
rclone copy archivo.txt r2-architect:architect/path/
|
|
||||||
|
|
||||||
# Descargar archivo
|
|
||||||
rclone copy r2-architect:architect/path/archivo.txt ./
|
|
||||||
```
|
|
||||||
|
|
||||||
## Configuración cliente local
|
|
||||||
|
|
||||||
Ejemplo configurado en Mac (pablotzr):
|
|
||||||
|
|
||||||
| Componente | Valor |
|
|
||||||
|------------|-------|
|
|
||||||
| Carpeta local | /Users/pablotzr/Architect R2/ |
|
|
||||||
| Bucket R2 | architect |
|
|
||||||
| Sync | Bidireccional (bisync) |
|
|
||||||
| Frecuencia | Cada 5 minutos |
|
|
||||||
| Servicio | com.rclone.r2-architect-sync |
|
|
||||||
| Logs | ~/Library/Logs/rclone-r2-sync.log |
|
|
||||||
|
|
||||||
---
|
|
||||||
Creado: 2024-12-24
|
|
||||||
@@ -1,264 +0,0 @@
|
|||||||
# LOCKER
|
|
||||||
|
|
||||||

|
|
||||||
|
|
||||||
|
|
||||||
**Gateway de Almacenamiento - Ecosistema TZZR**
|
|
||||||
|
|
||||||
## Cloudflare R2 (Actualizado 2025-12-22)
|
|
||||||
|
|
||||||
### Estado de Buckets
|
|
||||||
|
|
||||||
| Bucket | Estado | Objetos | Contenido |
|
|
||||||
|--------|--------|---------|-----------|
|
|
||||||
| architect | OK | 0 | vacío |
|
|
||||||
| hst | OK | 0 | vacío |
|
|
||||||
| deck | OK | 1 | test.txt (5 bytes) |
|
|
||||||
| corp | OK | 0 | vacío |
|
|
||||||
| locker | OK | 0 | vacío |
|
|
||||||
|
|
||||||
**Resultado:** 5/5 buckets accesibles
|
|
||||||
|
|
||||||
### Credenciales R2
|
|
||||||
|
|
||||||
```
|
|
||||||
Endpoint: https://7dedae6030f5554d99d37e98a5232996.r2.cloudflarestorage.com
|
|
||||||
Access Key: ecddc771824c3cb3417d9451780db3d2
|
|
||||||
Secret Key: c8138e2597100ffb7dd1477ad722c0214f86097cd968752aea3cfcea5d54dbac
|
|
||||||
```
|
|
||||||
|
|
||||||
Token: `locker-full-access` (Object Read & Write, todos los buckets)
|
|
||||||
|
|
||||||
## Descripción
|
|
||||||
|
|
||||||
LOCKER es el **gateway de almacenamiento** del ecosistema. Abstrae el almacenamiento físico permitiendo guardar y recuperar archivos usando referencias `locker://`. Actualmente usa almacenamiento local/Nextcloud, con plan de migrar a solución descentralizada.
|
|
||||||
|
|
||||||
## Arquitectura
|
|
||||||
|
|
||||||
```
|
|
||||||
┌─────────────────────────────────────────────────────────────────┐
|
|
||||||
│ LOCKER │
|
|
||||||
│ (Gateway de Almacenamiento) │
|
|
||||||
├─────────────────────────────────────────────────────────────────┤
|
|
||||||
│ │
|
|
||||||
│ ┌───────────────────────────────────────────────────────┐ │
|
|
||||||
│ │ API GATEWAY │ │
|
|
||||||
│ │ locker://corp/facturas/001.pdf → /files/corp/... │ │
|
|
||||||
│ └─────────────────────────────────────────────────────────┘ │
|
|
||||||
│ │ │
|
|
||||||
│ ▼ │
|
|
||||||
│ ┌───────────────────────────────────────────────────────┐ │
|
|
||||||
│ │ STORAGE ROUTER │ │
|
|
||||||
│ └─────────────────────────────────────────────────────────┘ │
|
|
||||||
│ │ │
|
|
||||||
│ ┌─────────────────┼─────────────────┐ │
|
|
||||||
│ ▼ ▼ ▼ │
|
|
||||||
│ ┌───────────┐ ┌───────────┐ ┌───────────┐ │
|
|
||||||
│ │ Local │ │ Nextcloud │ │ IPFS │ │
|
|
||||||
│ │ (actual) │ │ (sync) │ │ (futuro) │ │
|
|
||||||
│ └───────────┘ └───────────┘ └───────────┘ │
|
|
||||||
│ │
|
|
||||||
└─────────────────────────────────────────────────────────────────┘
|
|
||||||
```
|
|
||||||
|
|
||||||
## Referencias LOCKER
|
|
||||||
|
|
||||||
Formato: `locker://{namespace}/{path}`
|
|
||||||
|
|
||||||
| Namespace | Descripción | Ejemplo |
|
|
||||||
|-----------|-------------|---------|
|
|
||||||
| corp | Documentos empresariales | `locker://corp/facturas/FAC-2025-001.pdf` |
|
|
||||||
| deck | Archivos personales | `locker://deck/fitness/progress/week1.jpg` |
|
|
||||||
| hst | Imágenes de tags | `locker://hst/icons/fit.png` |
|
|
||||||
| factory | Artefactos generados | `locker://factory/artifacts/abc123.md` |
|
|
||||||
| emails | Adjuntos de correo | `locker://emails/adjuntos/2025/01/doc.pdf` |
|
|
||||||
|
|
||||||
## API
|
|
||||||
|
|
||||||
### PUT /api/files/{path}
|
|
||||||
|
|
||||||
Subir archivo.
|
|
||||||
|
|
||||||
```bash
|
|
||||||
curl -X PUT https://locker.tzzr.me/api/files/corp/facturas/001.pdf \
|
|
||||||
-H "Authorization: Bearer $API_KEY" \
|
|
||||||
-H "Content-Type: application/pdf" \
|
|
||||||
--data-binary @factura.pdf
|
|
||||||
```
|
|
||||||
|
|
||||||
**Response:**
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"ref": "locker://corp/facturas/001.pdf",
|
|
||||||
"url": "https://locker.tzzr.me/corp/facturas/001.pdf",
|
|
||||||
"sha256": "abc123...",
|
|
||||||
"size_bytes": 125000
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
### GET /api/files/{path}
|
|
||||||
|
|
||||||
Descargar archivo.
|
|
||||||
|
|
||||||
```bash
|
|
||||||
curl https://locker.tzzr.me/api/files/corp/facturas/001.pdf \
|
|
||||||
-H "Authorization: Bearer $API_KEY" \
|
|
||||||
-o factura.pdf
|
|
||||||
```
|
|
||||||
|
|
||||||
### POST /api/signed-url
|
|
||||||
|
|
||||||
Generar URL firmada (acceso temporal).
|
|
||||||
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"path": "corp/facturas/001.pdf",
|
|
||||||
"expires_in": 3600
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
**Response:**
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"signed_url": "https://locker.tzzr.me/corp/facturas/001.pdf?token=xyz&expires=..."
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
### DELETE /api/files/{path}
|
|
||||||
|
|
||||||
Eliminar archivo.
|
|
||||||
|
|
||||||
## Integración
|
|
||||||
|
|
||||||
### Con THE FACTORY
|
|
||||||
|
|
||||||
```javascript
|
|
||||||
// FACTORY sube artefactos generados a LOCKER
|
|
||||||
const factory = new FactoryClient();
|
|
||||||
const result = await factory.getJobResultToLocker(jobId, 'corp/facturas/001.pdf');
|
|
||||||
// Returns: { locker_ref: "locker://corp/facturas/001.pdf" }
|
|
||||||
```
|
|
||||||
|
|
||||||
### Con CLARA (CORP)
|
|
||||||
|
|
||||||
```javascript
|
|
||||||
// CLARA guarda facturas certificadas
|
|
||||||
const clara = new Clara();
|
|
||||||
const stored = await clara.storeInLocker(invoiceContent, 'factura', {
|
|
||||||
numero: 'FAC-2025-001'
|
|
||||||
});
|
|
||||||
// locker://corp/facturas/FAC-2025-001.pdf
|
|
||||||
```
|
|
||||||
|
|
||||||
### Con DECK
|
|
||||||
|
|
||||||
```javascript
|
|
||||||
// DECK guarda fotos de progreso
|
|
||||||
const response = await fetch('https://locker.tzzr.me/api/files/deck/fitness/progress/week1.jpg', {
|
|
||||||
method: 'PUT',
|
|
||||||
body: imageBlob
|
|
||||||
});
|
|
||||||
```
|
|
||||||
|
|
||||||
### Con Emails
|
|
||||||
|
|
||||||
```javascript
|
|
||||||
// Adjuntos de email van a LOCKER
|
|
||||||
const attachment = await locker.upload(
|
|
||||||
`emails/adjuntos/2025/01/${emailId}_${filename}`,
|
|
||||||
content
|
|
||||||
);
|
|
||||||
// locker://emails/adjuntos/2025/01/msg001_documento.pdf
|
|
||||||
```
|
|
||||||
|
|
||||||
## Deduplicación
|
|
||||||
|
|
||||||
LOCKER usa SHA-256 para deduplicar:
|
|
||||||
|
|
||||||
```javascript
|
|
||||||
// Si el hash ya existe, retorna referencia existente
|
|
||||||
const result = await locker.upload(path, content);
|
|
||||||
if (result.deduplicated) {
|
|
||||||
console.log('Archivo ya existía:', result.existing_ref);
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
## Sync con Nextcloud
|
|
||||||
|
|
||||||
LOCKER sincroniza con Nextcloud para acceso desde múltiples dispositivos:
|
|
||||||
|
|
||||||
```
|
|
||||||
LOCKER (API) ←→ Local Storage ←→ Nextcloud Sync
|
|
||||||
│
|
|
||||||
▼
|
|
||||||
Desktop/Mobile Apps
|
|
||||||
```
|
|
||||||
|
|
||||||
## Estructura de Almacenamiento
|
|
||||||
|
|
||||||
```
|
|
||||||
/data/locker/
|
|
||||||
├── corp/
|
|
||||||
│ ├── facturas/
|
|
||||||
│ │ └── FAC-2025-0001.pdf
|
|
||||||
│ ├── pedidos/
|
|
||||||
│ └── productos/
|
|
||||||
├── deck/
|
|
||||||
│ ├── fitness/
|
|
||||||
│ │ ├── progress/
|
|
||||||
│ │ └── plans/
|
|
||||||
│ └── documents/
|
|
||||||
├── hst/
|
|
||||||
│ └── icons/
|
|
||||||
├── factory/
|
|
||||||
│ └── artifacts/
|
|
||||||
└── emails/
|
|
||||||
└── adjuntos/
|
|
||||||
```
|
|
||||||
|
|
||||||
## Roadmap: Descentralización
|
|
||||||
|
|
||||||
Plan de migración a almacenamiento descentralizado:
|
|
||||||
|
|
||||||
```
|
|
||||||
Fase 1 (actual): Local + Nextcloud
|
|
||||||
Fase 2: IPFS para archivos públicos (HST icons)
|
|
||||||
Fase 3: Arweave para documentos certificados
|
|
||||||
Fase 4: Filecoin para backup completo
|
|
||||||
```
|
|
||||||
|
|
||||||
## Estructura del Proyecto
|
|
||||||
|
|
||||||
```
|
|
||||||
locker/
|
|
||||||
├── src/
|
|
||||||
│ ├── api.py # API Gateway
|
|
||||||
│ ├── storage/
|
|
||||||
│ │ ├── local.py
|
|
||||||
│ │ ├── nextcloud.py
|
|
||||||
│ │ └── ipfs.py (futuro)
|
|
||||||
│ └── dedup.py # Deduplicación
|
|
||||||
├── docker/
|
|
||||||
│ └── docker-compose.yml
|
|
||||||
└── README.md
|
|
||||||
```
|
|
||||||
|
|
||||||
## Repositorios Relacionados
|
|
||||||
|
|
||||||
| Repo | Rol |
|
|
||||||
|------|-----|
|
|
||||||
| [the-factory](https://github.com/tzzrgit/the-factory) | Guarda artefactos |
|
|
||||||
| [corp](https://github.com/tzzrgit/corp) | Guarda facturas |
|
|
||||||
| [deck](https://github.com/tzzrgit/deck) | Guarda archivos personales |
|
|
||||||
| [hst-image-server](https://github.com/tzzrgit/hst-image-server) | Imágenes HST |
|
|
||||||
|
|
||||||
## Roadmap
|
|
||||||
|
|
||||||
- [x] API básica (PUT/GET/DELETE)
|
|
||||||
- [x] URLs firmadas
|
|
||||||
- [x] Deduplicación SHA-256
|
|
||||||
- [x] Sync Nextcloud
|
|
||||||
- [ ] IPFS para HST
|
|
||||||
- [ ] Arweave para certificados
|
|
||||||
- [ ] Compresión automática
|
|
||||||
- [ ] CDN para assets públicos
|
|
||||||
@@ -1,79 +0,0 @@
|
|||||||
# MARGARET
|
|
||||||
|
|
||||||

|
|
||||||
|
|
||||||
**Log de entrada CORP - Sistema TZZR**
|
|
||||||
|
|
||||||
## Rol
|
|
||||||
|
|
||||||
Secretaria de entrada para CORP (servidor empresarial). Variante de CLARA con funcionalidades adicionales.
|
|
||||||
|
|
||||||
## Posicion en el Flujo
|
|
||||||
|
|
||||||
```
|
|
||||||
PACKET (App) --> MARGARET --> MASON --> FELDMAN
|
|
||||||
|
|
|
||||||
└--> R2 (archivos)
|
|
||||||
```
|
|
||||||
|
|
||||||
## Endpoints
|
|
||||||
|
|
||||||
| Metodo | Ruta | Descripcion |
|
|
||||||
|--------|------|-------------|
|
|
||||||
| GET | `/health` | Estado del servicio |
|
|
||||||
| POST | `/ingest` | Recibir contenedor |
|
|
||||||
| GET | `/query/<h_entrada>` | Consultar por hash |
|
|
||||||
| GET | `/list` | Listar entradas |
|
|
||||||
|
|
||||||
## Autenticacion
|
|
||||||
|
|
||||||
Todas las rutas (excepto `/health`) requieren:
|
|
||||||
```
|
|
||||||
X-Auth-Key: {h_instancia}
|
|
||||||
```
|
|
||||||
|
|
||||||
## Despliegue
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# En CORP
|
|
||||||
cd /opt/margaret
|
|
||||||
cp .env.example .env
|
|
||||||
# Editar .env con credenciales
|
|
||||||
docker compose up -d
|
|
||||||
```
|
|
||||||
|
|
||||||
## Configuracion
|
|
||||||
|
|
||||||
Ver `.env.example` para variables requeridas:
|
|
||||||
- `H_INSTANCIA`: Hash unico de CORP
|
|
||||||
- `DB_*`: Credenciales PostgreSQL
|
|
||||||
- `R2_*`: Credenciales Cloudflare R2
|
|
||||||
|
|
||||||
## Base de Datos
|
|
||||||
|
|
||||||
Ejecutar `init.sql` en PostgreSQL:
|
|
||||||
```bash
|
|
||||||
sudo -u postgres psql -d corp -f init.sql
|
|
||||||
```
|
|
||||||
|
|
||||||
## Comparacion
|
|
||||||
|
|
||||||
| Aspecto | CLARA (DECK) | MARGARET (CORP) |
|
|
||||||
|---------|--------------|-----------------|
|
|
||||||
| Servidor | Personal | Empresarial |
|
|
||||||
| Log | Inmutable | Inmutable |
|
|
||||||
| Puerto | 5051 | 5051 |
|
|
||||||
| Bucket R2 | deck | corp |
|
|
||||||
|
|
||||||
## Funcion
|
|
||||||
|
|
||||||
1. Recibe contenedor de PACKET
|
|
||||||
2. Envia archivos a R2
|
|
||||||
3. Registra metadata + ubicacion R2
|
|
||||||
4. **NO agrega informacion**
|
|
||||||
5. **NO procesa**
|
|
||||||
6. **NO modifica**
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
*Componente del sistema TZZR - Implementado 2025-12-24*
|
|
||||||
@@ -1,99 +0,0 @@
|
|||||||
# MASON
|
|
||||||
|
|
||||||

|
|
||||||
|
|
||||||
|
|
||||||
**Espacio de enriquecimiento - Sistema TZZR**
|
|
||||||
|
|
||||||
## Rol
|
|
||||||
|
|
||||||
Mesa de trabajo donde el usuario completa y corrige información antes de consolidar en FELDMAN.
|
|
||||||
|
|
||||||
## Posición en el Flujo
|
|
||||||
|
|
||||||
```
|
|
||||||
CLARA/MARGARET ──┬──► MASON ──► FELDMAN
|
|
||||||
│ ▲
|
|
||||||
ALFRED/JARED ────┘ │
|
|
||||||
(si incidencia) │
|
|
||||||
│
|
|
||||||
FELDMAN ─────────────────┘
|
|
||||||
(devolver para corregir)
|
|
||||||
```
|
|
||||||
|
|
||||||
## Funciones
|
|
||||||
|
|
||||||
| Acción | Descripción |
|
|
||||||
|--------|-------------|
|
|
||||||
| Enriquecer | Añadir metadata, notas, contexto |
|
|
||||||
| Corregir | Modificar datos incorrectos |
|
|
||||||
| Re-etiquetar | Cambiar etiquetas de archivos |
|
|
||||||
| Acelerar | Enviar a FELDMAN antes de 24h |
|
|
||||||
| Retener | Mantener más tiempo en edición |
|
|
||||||
|
|
||||||
## Tiempos
|
|
||||||
|
|
||||||
- **Ventana default**: 24h (configurable)
|
|
||||||
- **Si expira**: Auto-envío a FELDMAN
|
|
||||||
|
|
||||||
## Perfiles de Usuario
|
|
||||||
|
|
||||||
| Perfil | Uso de MASON |
|
|
||||||
|--------|--------------|
|
|
||||||
| Novato | Usa mucho este espacio |
|
|
||||||
| Avanzado | Paso casi automático |
|
|
||||||
|
|
||||||
## Estructura de Datos
|
|
||||||
|
|
||||||
MASON trabaja con la seccion `enriquecimiento` del contenedor (ver [esquema completo](https://git.tzzr.me/tzzr/contratos-comunes/src/branch/main/architecture/06-contenedor-schema.md)):
|
|
||||||
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"enriquecimiento": {
|
|
||||||
"notas": "Pendiente de pago",
|
|
||||||
"campos_personalizados": {
|
|
||||||
"proyecto": "Proyecto Alpha",
|
|
||||||
"responsable": "Juan Garcia"
|
|
||||||
},
|
|
||||||
"tags_confirmados": ["sha256-tag1", "sha256-tag2"],
|
|
||||||
"tags_rechazados": ["sha256-tag3"],
|
|
||||||
"correcciones": {
|
|
||||||
"texto": null,
|
|
||||||
"entidades": null
|
|
||||||
},
|
|
||||||
"editado_por": "usuario-id",
|
|
||||||
"editado_at": "2025-01-15T11:00:00Z"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
### Campos disponibles
|
|
||||||
|
|
||||||
| Campo | Tipo | Descripcion |
|
|
||||||
|-------|------|-------------|
|
|
||||||
| `notas` | String | Texto libre del usuario |
|
|
||||||
| `campos_personalizados` | Object | Campos key-value definidos por usuario |
|
|
||||||
| `tags_confirmados` | Array | h_maestro de tags sugeridos aceptados |
|
|
||||||
| `tags_rechazados` | Array | h_maestro de tags sugeridos descartados |
|
|
||||||
| `correcciones.texto` | String | Texto corregido si OCR fallo |
|
|
||||||
| `correcciones.entidades` | Object | Entidades corregidas |
|
|
||||||
|
|
||||||
### Interaccion con extraccion
|
|
||||||
|
|
||||||
MASON muestra los `tags_sugeridos` de la seccion `extraccion` para que el usuario:
|
|
||||||
- Confirme (se mueven a `enriquecimiento.tags_confirmados`)
|
|
||||||
- Rechace (se mueven a `enriquecimiento.tags_rechazados`)
|
|
||||||
|
|
||||||
### Mutabilidad
|
|
||||||
|
|
||||||
- `enriquecimiento` es **mutable** mientras el registro esta en MASON
|
|
||||||
- Una vez enviado a FELDMAN, se congela
|
|
||||||
- Si FELDMAN devuelve el registro, vuelve a ser editable
|
|
||||||
|
|
||||||
## Arquitectura
|
|
||||||
|
|
||||||
Ver documentación completa en [contratos-comunes/architecture](https://git.tzzr.me/tzzr/contratos-comunes/src/branch/main/architecture/03-mason.md)
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
*Componente del sistema TZZR*
|
|
||||||
@@ -1,42 +0,0 @@
|
|||||||
# MIND LINK
|
|
||||||
|
|
||||||

|
|
||||||
|
|
||||||
> **ARCHIVADO:** Este proyecto esta temporalmente pausado. Se retomara despues de completar el pipeline principal (FASE 4 del plan de implementacion).
|
|
||||||
|
|
||||||
## Concepto Original
|
|
||||||
|
|
||||||
Interfaz para conectar ideas y conceptos. Visualizacion de relaciones entre elementos.
|
|
||||||
|
|
||||||
## Funciones Planificadas
|
|
||||||
|
|
||||||
- Conexion de conceptos
|
|
||||||
- Grafos de conocimiento
|
|
||||||
- Navegacion visual
|
|
||||||
- Busqueda semantica
|
|
||||||
|
|
||||||
## Contenido Existente
|
|
||||||
|
|
||||||
```
|
|
||||||
mind-link/
|
|
||||||
├── src/
|
|
||||||
│ └── mindlink-v11.jsx # Prototipo React (incompleto)
|
|
||||||
└── docs/
|
|
||||||
├── MINDLINK-DOCUMENTACION.md
|
|
||||||
└── interfaz_mindlink v0.md
|
|
||||||
```
|
|
||||||
|
|
||||||
## Dependencias para Retomar
|
|
||||||
|
|
||||||
- Pipeline completo funcionando (CLARA, MASON, FELDMAN)
|
|
||||||
- Sistema de embeddings (GRACE) operativo
|
|
||||||
- Base de datos de grafos o PostgreSQL con extensiones
|
|
||||||
|
|
||||||
## Prioridad
|
|
||||||
|
|
||||||
BAJA - Se implementara despues de las fases 0-4 del plan de implementacion.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
*Archivado: 2025-12-24*
|
|
||||||
*Ver: tzzr/system-plan para el plan completo*
|
|
||||||
@@ -1,253 +0,0 @@
|
|||||||
# MindLink v11 - Documentación
|
|
||||||
|
|
||||||
## Descripción General
|
|
||||||
|
|
||||||
MindLink es una interfaz de comunicación visual tipo mindmap/linktree para entregar documentos a clientes. Presenta nodos principales (categorías) con subnodos desplegables (documentos) conectados por líneas animadas.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Estructura de Datos
|
|
||||||
|
|
||||||
### Configuración General
|
|
||||||
|
|
||||||
| Campo | Tipo | Ejemplo | Descripción |
|
|
||||||
|-------|------|---------|-------------|
|
|
||||||
| `titulo` | Texto | "Proyecto Demo HST" | Título principal de la página |
|
|
||||||
| `mostrar_titulo` | Booleano | true | Mostrar/ocultar el título |
|
|
||||||
| `colores` | Texto | "#FF6B35, #E5A000, #06D6A0" | Colores en hexadecimal separados por comas |
|
|
||||||
| `fuente` | Texto | "Inter" | Nombre de la fuente tipográfica |
|
|
||||||
|
|
||||||
### Fuentes Disponibles
|
|
||||||
|
|
||||||
| Valor | Descripción |
|
|
||||||
|-------|-------------|
|
|
||||||
| `Inter` | Moderna, muy legible (recomendada) |
|
|
||||||
| `Roboto` | Google, neutra |
|
|
||||||
| `Open Sans` | Google, amigable |
|
|
||||||
| `Montserrat` | Geométrica, elegante |
|
|
||||||
| `Lato` | Equilibrada, profesional |
|
|
||||||
| `SF Pro Display` | Apple, premium |
|
|
||||||
| `system` | Fuente nativa del sistema |
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
### Nodos (Categorías)
|
|
||||||
|
|
||||||
| Campo | Tipo | Ejemplo | Descripción |
|
|
||||||
|-------|------|---------|-------------|
|
|
||||||
| `id` | Texto | "n1" | Identificador único |
|
|
||||||
| `titulo` | Texto | "Arquitectura" | Nombre de la categoría |
|
|
||||||
| `imagen` | URL | "https://..." | Imagen cuadrada (se muestra 120×120px) |
|
|
||||||
| `subnodos` | Array | [...] | Lista de documentos |
|
|
||||||
|
|
||||||
### Subnodos (Documentos)
|
|
||||||
|
|
||||||
| Campo | Tipo | Ejemplo | Descripción |
|
|
||||||
|-------|------|---------|-------------|
|
|
||||||
| `id` | Texto | "s1" | Identificador único |
|
|
||||||
| `titulo` | Texto | "Plano General" | Nombre del documento |
|
|
||||||
| `imagen` | URL | "https://..." | Miniatura 16:9 (se muestra 180×101px) |
|
|
||||||
| `tiene_preview` | Booleano | true | Icono ojo (esquina superior derecha) |
|
|
||||||
| `tiene_descarga` | Booleano | true | Icono descarga (esquina inferior izquierda) |
|
|
||||||
| `tiene_enlace` | Booleano | true | Icono enlace (esquina inferior derecha) |
|
|
||||||
| `tiene_historial` | Booleano | false | Icono reloj (esquina superior izquierda) |
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Iconos de Acción
|
|
||||||
|
|
||||||
Los iconos se posicionan en las **4 esquinas** del subnodo para facilitar el uso en móviles:
|
|
||||||
|
|
||||||
```
|
|
||||||
┌─────────────────────┐
|
|
||||||
│ 🕐 👁 │ 🕐 = historial (tiene_historial)
|
|
||||||
│ │ 👁 = preview (tiene_preview)
|
|
||||||
│ │
|
|
||||||
│ ⬇ 🔗 │ ⬇ = descarga (tiene_descarga)
|
|
||||||
└─────────────────────┘ 🔗 = enlace (tiene_enlace)
|
|
||||||
```
|
|
||||||
|
|
||||||
**Estilo visual:**
|
|
||||||
- Fondo: negro semi-transparente `rgba(0,0,0,0.5)`
|
|
||||||
- Icono: blanco
|
|
||||||
- Tamaño: 26×26px
|
|
||||||
- Radio: 4px
|
|
||||||
- Opacidad: 50% (aumenta al hacer hover)
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Especificaciones Visuales
|
|
||||||
|
|
||||||
### Dimensiones
|
|
||||||
|
|
||||||
| Elemento | Valor | Notas |
|
|
||||||
|----------|-------|-------|
|
|
||||||
| Nodo principal | 120×120 px | Cuadrado |
|
|
||||||
| Subnodo | 180×101 px | Ratio 16:9 |
|
|
||||||
| Radio esquinas nodo | 20px | |
|
|
||||||
| Radio esquinas subnodo | 15px | |
|
|
||||||
| Grosor líneas/bordes | 3px | |
|
|
||||||
| Gap entre subnodos | 20px | Vertical |
|
|
||||||
| Gap entre grupos | 50px | Vertical |
|
|
||||||
| Gap nodo a subnodo | 70px | Horizontal |
|
|
||||||
|
|
||||||
### Tipografía
|
|
||||||
|
|
||||||
| Elemento | Tamaño | Peso | Color |
|
|
||||||
|----------|--------|------|-------|
|
|
||||||
| Título página | 32px | 600 | #1a1a1a |
|
|
||||||
| Título nodo | 18px | 500 | Color del nodo |
|
|
||||||
| Título subnodo | 16px | 500 | Color del nodo |
|
|
||||||
|
|
||||||
### Colores por Defecto
|
|
||||||
|
|
||||||
```
|
|
||||||
#FF6B35 - Naranja (nodo 1)
|
|
||||||
#E5A000 - Amarillo (nodo 2)
|
|
||||||
#06D6A0 - Verde (nodo 3)
|
|
||||||
#0891B2 - Cyan (nodo 4)
|
|
||||||
#3B82F6 - Azul (nodo 5)
|
|
||||||
#8B5CF6 - Violeta (nodo 6)
|
|
||||||
#EC4899 - Rosa (nodo 7)
|
|
||||||
```
|
|
||||||
|
|
||||||
Los colores rotan automáticamente: nodo 8 usa color 1, etc.
|
|
||||||
|
|
||||||
### Fondo de Fallback
|
|
||||||
|
|
||||||
Cuando una imagen no carga, se muestra fondo gris `#ccc`. Esto evita espacios en blanco y texto fantasma.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Animaciones
|
|
||||||
|
|
||||||
| Elemento | Duración | Función | Delay |
|
|
||||||
|----------|----------|---------|-------|
|
|
||||||
| Movimiento vertical del nodo | 400ms | ease-out | - |
|
|
||||||
| Revelado de líneas | 450ms | linear | 80ms |
|
|
||||||
| Aparición subnodos | instantánea | - | 30ms |
|
|
||||||
|
|
||||||
### Secuencia al Expandir
|
|
||||||
1. El nodo se desplaza verticalmente para centrarse con sus subnodos
|
|
||||||
2. Las líneas se revelan con efecto de máscara deslizante
|
|
||||||
3. Los subnodos aparecen instantáneamente
|
|
||||||
|
|
||||||
### Secuencia al Colapsar
|
|
||||||
1. Las líneas desaparecen
|
|
||||||
2. Los subnodos se ocultan
|
|
||||||
3. El nodo vuelve a su posición
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Centrado Automático
|
|
||||||
|
|
||||||
El contenedor principal se centra horizontalmente con flexbox:
|
|
||||||
|
|
||||||
- **Con subnodos expandidos**: Ancho = nodo + gap + subnodo (~400px)
|
|
||||||
- **Todo colapsado**: Ancho = solo nodos (~180px)
|
|
||||||
|
|
||||||
El ancho cambia con transición suave (400ms).
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Integración con NocoDB
|
|
||||||
|
|
||||||
### Estructura de Tablas Recomendada
|
|
||||||
|
|
||||||
**Tabla: `proyectos`**
|
|
||||||
```
|
|
||||||
id | titulo | mostrar_titulo | colores | fuente
|
|
||||||
```
|
|
||||||
|
|
||||||
**Tabla: `nodos`**
|
|
||||||
```
|
|
||||||
id | proyecto_id | titulo | imagen | orden
|
|
||||||
```
|
|
||||||
|
|
||||||
**Tabla: `subnodos`**
|
|
||||||
```
|
|
||||||
id | nodo_id | titulo | imagen | tiene_preview | tiene_descarga | tiene_enlace | tiene_historial | orden
|
|
||||||
```
|
|
||||||
|
|
||||||
### Campo de Imagen
|
|
||||||
|
|
||||||
Usar campo tipo **Attachment** de NocoDB. La URL del archivo se usa directamente.
|
|
||||||
|
|
||||||
Para optimizar imágenes automáticamente, considerar:
|
|
||||||
- **Cloudinary**: `https://res.cloudinary.com/cuenta/image/upload/w_180,h_101,c_fill/imagen.jpg`
|
|
||||||
- **Redimensionado manual** antes de subir
|
|
||||||
|
|
||||||
### Tamaños de Imagen Recomendados
|
|
||||||
|
|
||||||
| Tipo | Subir | Se muestra como |
|
|
||||||
|------|-------|-----------------|
|
|
||||||
| Nodo | 240×240 px | 120×120 px |
|
|
||||||
| Subnodo | 360×202 px | 180×101 px |
|
|
||||||
|
|
||||||
Subir al doble para pantallas retina.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Ejemplo JSON Completo
|
|
||||||
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"titulo": "Proyecto Cliente X",
|
|
||||||
"mostrar_titulo": true,
|
|
||||||
"colores": "#FF6B35, #06D6A0, #3B82F6",
|
|
||||||
"fuente": "Montserrat",
|
|
||||||
"nodos": [
|
|
||||||
{
|
|
||||||
"id": "n1",
|
|
||||||
"titulo": "Planos",
|
|
||||||
"imagen": "https://ejemplo.com/planos-thumb.jpg",
|
|
||||||
"subnodos": [
|
|
||||||
{
|
|
||||||
"id": "s1",
|
|
||||||
"titulo": "Planta Baja",
|
|
||||||
"imagen": "https://ejemplo.com/planta-baja.jpg",
|
|
||||||
"tiene_preview": true,
|
|
||||||
"tiene_descarga": true,
|
|
||||||
"tiene_enlace": false,
|
|
||||||
"tiene_historial": true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": "s2",
|
|
||||||
"titulo": "Planta Alta",
|
|
||||||
"imagen": "https://ejemplo.com/planta-alta.jpg",
|
|
||||||
"tiene_preview": true,
|
|
||||||
"tiene_descarga": true,
|
|
||||||
"tiene_enlace": true,
|
|
||||||
"tiene_historial": false
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Pendiente de Implementar
|
|
||||||
|
|
||||||
- [ ] Conexión real con API de NocoDB
|
|
||||||
- [ ] Sistema de autenticación con PIN
|
|
||||||
- [ ] Funcionalidad real de iconos:
|
|
||||||
- [ ] Preview: abrir modal con documento
|
|
||||||
- [ ] Descarga: descargar archivo
|
|
||||||
- [ ] Enlace: copiar URL al portapapeles
|
|
||||||
- [ ] Historial: mostrar versiones anteriores
|
|
||||||
- [ ] Responsive móvil (adaptar a pantallas pequeñas)
|
|
||||||
- [ ] Integración en aplicación empresarial
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Historial de Versiones
|
|
||||||
|
|
||||||
| Versión | Cambios principales |
|
|
||||||
|---------|---------------------|
|
|
||||||
| v11 | Colores/fuentes configurables, centrado mejorado, iconos en 4 esquinas, fix texto duplicado |
|
|
||||||
| v10 | Imágenes base64 incrustadas (demo) |
|
|
||||||
| v9 | Esquinas redondeadas 20px/15px, iconos 50% opacidad |
|
|
||||||
| v8 | Subnodos aparecen instantáneamente |
|
|
||||||
| v7-v1 | Iteraciones de diseño y animación |
|
|
||||||
@@ -1,86 +0,0 @@
|
|||||||
# Resumen de la conversación sobre la interfaz MindMap
|
|
||||||
|
|
||||||
A continuación se recoge un resumen estructurado de todos los elementos definidos para la interfaz tipo MindMap:
|
|
||||||
|
|
||||||
## 1. Acceso e Identificación
|
|
||||||
- El usuario accede mediante un enlace que actúa como llave pública.
|
|
||||||
- Se muestra un diálogo inicial simple con:
|
|
||||||
- Imagen de referencia (desde RT / Airtable).
|
|
||||||
- Imagen de fondo (también desde RT).
|
|
||||||
- Título (desde RT).
|
|
||||||
- Fuente de red.
|
|
||||||
- Primera vez: el sistema solicita un PIN.
|
|
||||||
- El PIN se guarda en la tabla.
|
|
||||||
- Si se olvida: no hay recuperación; debe solicitarse el borrado para reconfigurarlo.
|
|
||||||
|
|
||||||
## 2. Estructura General del Interfaz
|
|
||||||
- Funciona como un LinkTree avanzado.
|
|
||||||
- Representación equivalente a un mindmap.
|
|
||||||
- El nodo principal es implícito (no mostrado).
|
|
||||||
- Se muestran nodos principales en columna.
|
|
||||||
- Al pulsar un nodo, se realiza un zoom-out suave y se despliegan los subnodos.
|
|
||||||
|
|
||||||
## 3. Diseño de Nodos y Subnodos
|
|
||||||
- Cada nodo/subnodo muestra:
|
|
||||||
- Imagen (nodos cuadrados; subnodos rectangulares 16:9 con esquinas redondeadas).
|
|
||||||
- Título situado **debajo** de la imagen (configuración por defecto).
|
|
||||||
- Espacio configurable para fuente tipográfica.
|
|
||||||
- Fondo del área de despliegue configurable mediante imagen almacenada en RT.
|
|
||||||
|
|
||||||
## 4. Interacciones (Iconos en las esquinas)
|
|
||||||
Cada subnodo incluye interacciones en las esquinas de la imagen:
|
|
||||||
|
|
||||||
- **Esquina superior derecha**: icono de ojo → previsualización (JPG, PDF, etc.).
|
|
||||||
- **Esquina inferior izquierda**: icono de descarga.
|
|
||||||
- **Esquina inferior derecha**: icono de eslabones → copiar enlace al portapapeles.
|
|
||||||
- **Esquina superior izquierda**: reservada para futuras interacciones.
|
|
||||||
- Los iconos:
|
|
||||||
- Son estáticos (sin animación).
|
|
||||||
- Solo aparecen si la funcionalidad existe en ese nodo.
|
|
||||||
|
|
||||||
## 5. Ramas y Animaciones
|
|
||||||
- Las ramas funcionan como líneas que subrayan el título de cada nodo.
|
|
||||||
- De la línea subrayada del nodo principal salen curvas NURBS animadas.
|
|
||||||
- Las curvas:
|
|
||||||
- Salen del subrayado del nodo principal.
|
|
||||||
- Bajan de manera orgánica.
|
|
||||||
- Llegan al subrayado del subnodo.
|
|
||||||
- No se conectan al centro del recuadro (evitamos comportamiento mecánico).
|
|
||||||
- Las animaciones deben sentirse de calidad, como en un buen mindmap.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
# Transcripción literal de la conversación
|
|
||||||
|
|
||||||
(Nota: Se incluye solo la parte relevante a la interfaz MindMap según lo solicitado.)
|
|
||||||
|
|
||||||
Usuario: Vamos a hablar de interfaces. Quiero hablar de ello a nivel genérico [...]
|
|
||||||
Asistente: ¡Entendido! Vamos a mantenerlo entonces en un nivel general [...]
|
|
||||||
|
|
||||||
Usuario: Vamos a empezar por el primer interfaz. El primer interfaz es para hacer algo parecido a un LinkTree [...]
|
|
||||||
Asistente: Sí, te sigo perfectamente. Básicamente estás describiendo una interfaz tipo link tree [...]
|
|
||||||
|
|
||||||
Usuario: Seguimos con la definición. Dentro de estas imágenes rectangulares de los subnodos veremos arriba a la derecha [...]
|
|
||||||
Asistente: Perfecto, lo tenemos entonces bastante definido [...]
|
|
||||||
|
|
||||||
Usuario: Igual que tenemos que guardarnos la posibilidad de que no haya ningún tipo de interacción [...]
|
|
||||||
Asistente: ¡Claro! Entonces dejamos el diseño preparado para la posibilidad de futuras interacciones [...]
|
|
||||||
|
|
||||||
Usuario: Sí, sí, de hecho ya se me está ocurriendo otra interacción [...]
|
|
||||||
Asistente: ¡Perfecto, me encanta la idea! [...]
|
|
||||||
|
|
||||||
Usuario: Respecto a esto, no quiero animaciones respecto a estos iconitos [...]
|
|
||||||
Asistente: ¡Entendido! Entonces lo ajustamos así [...]
|
|
||||||
|
|
||||||
Usuario: No acabo de tener todo claro si quiero que los títulos estén en la parte inferior [...]
|
|
||||||
Asistente: ¡Genial! Entonces lo dejamos así [...]
|
|
||||||
|
|
||||||
Usuario: Es importante subrayar que las líneas se unen con otras líneas [...]
|
|
||||||
Asistente: Entendido, queda clarísimo [...]
|
|
||||||
|
|
||||||
Usuario: No, con esto tenemos la interfaz de MindMap perfectamente clara [...]
|
|
||||||
Asistente: Perfecto, entonces dejamos esta interfaz bien clara [...]
|
|
||||||
|
|
||||||
Usuario: Vale, ahora mismo puedo cerrar la conversación sin que haya pérdida [...]
|
|
||||||
Asistente: Sí, no te preocupes [...]
|
|
||||||
|
|
||||||
@@ -1,674 +0,0 @@
|
|||||||
# INTERFAZ MML
|
|
||||||
## Mindmap Linking - Capa de Interfaz
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 1. Concepto Visual
|
|
||||||
|
|
||||||
### 1.1 Referencia
|
|
||||||
|
|
||||||
Estética tipo **MindNode**:
|
|
||||||
- Diseño limpio y minimalista
|
|
||||||
- Líneas curvas orgánicas (bezier)
|
|
||||||
- Colores vibrantes por rama
|
|
||||||
- Tipografía sans-serif moderna
|
|
||||||
|
|
||||||
### 1.2 Principios
|
|
||||||
|
|
||||||
| Principio | Aplicación |
|
|
||||||
|-----------|------------|
|
|
||||||
| Simplicidad | Sin elementos decorativos innecesarios |
|
|
||||||
| Jerarquía | Nodos nivel 1 destacan, subnodos secundarios |
|
|
||||||
| Color | Cada rama tiene identidad cromática |
|
|
||||||
| Espacio | Generoso, respira |
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 2. Estructura Visual
|
|
||||||
|
|
||||||
### 2.1 Elementos
|
|
||||||
|
|
||||||
```
|
|
||||||
┌─────────────────────────────────────────────────────────────────┐
|
|
||||||
│ │
|
|
||||||
│ [Header - Título del proyecto (opcional)] │
|
|
||||||
│ │
|
|
||||||
├─────────────────────────────────────────────────────────────────┤
|
|
||||||
│ │
|
|
||||||
│ NODOS NIVEL 1 LÍNEAS SUBNODOS │
|
|
||||||
│ (izquierda) (curvas) (derecha) │
|
|
||||||
│ │
|
|
||||||
│ Texto subrayado ────────────────► Imagen 16:9 │
|
|
||||||
│ con color + título │
|
|
||||||
│ + botones │
|
|
||||||
│ │
|
|
||||||
└─────────────────────────────────────────────────────────────────┘
|
|
||||||
```
|
|
||||||
|
|
||||||
### 2.2 Layout Desktop (>768px)
|
|
||||||
|
|
||||||
```
|
|
||||||
╭─────────────────────────────────────────────────────────────────╮
|
|
||||||
│ Proyecto Demo HST │
|
|
||||||
├─────────────────────────────────────────────────────────────────┤
|
|
||||||
│ │
|
|
||||||
│ ╭─────────────╮ │
|
|
||||||
│ ╭─────│ IMAGEN │ │
|
|
||||||
│ Arquitectura ───────────────┤ ╰─────────────╯ │
|
|
||||||
│ │ plano.pdf │
|
|
||||||
│ │ │
|
|
||||||
│ │ ╭─────────────╮ │
|
|
||||||
│ ╰─────│ IMAGEN │ │
|
|
||||||
│ ╰─────────────╯ │
|
|
||||||
│ secciones.pdf │
|
|
||||||
│ │
|
|
||||||
│ ╭─────────────╮ │
|
|
||||||
│ ╭─────│ IMAGEN │ │
|
|
||||||
│ Renders ────────────────────┤ ╰─────────────╯ │
|
|
||||||
│ │ exterior.jpg │
|
|
||||||
│ │ │
|
|
||||||
│ ╰─────╭─────────────╮ │
|
|
||||||
│ │ IMAGEN │ │
|
|
||||||
│ ╰─────────────╯ │
|
|
||||||
│ interior.jpg │
|
|
||||||
│ │
|
|
||||||
╰─────────────────────────────────────────────────────────────────╯
|
|
||||||
```
|
|
||||||
|
|
||||||
### 2.3 Layout Mobile (<768px)
|
|
||||||
|
|
||||||
```
|
|
||||||
╭──────────────────────╮
|
|
||||||
│ Proyecto Demo │
|
|
||||||
├──────────────────────┤
|
|
||||||
│ │
|
|
||||||
│ Arquitectura │
|
|
||||||
│ │ │
|
|
||||||
│ ┌────┴────┐ │
|
|
||||||
│ ▼ ▼ │
|
|
||||||
│ ╭─────╮ ╭─────╮ │
|
|
||||||
│ │ IMG │ │ IMG │ │
|
|
||||||
│ ╰─────╯ ╰─────╯ │
|
|
||||||
│ plano secciones │
|
|
||||||
│ │
|
|
||||||
│ Renders │
|
|
||||||
│ │ │
|
|
||||||
│ ┌────┴────┐ │
|
|
||||||
│ ▼ ▼ │
|
|
||||||
│ ╭─────╮ ╭─────╮ │
|
|
||||||
│ │ IMG │ │ IMG │ │
|
|
||||||
│ ╰─────╯ ╰─────╯ │
|
|
||||||
│ exterior interior │
|
|
||||||
│ │
|
|
||||||
│ ↕ scroll vertical │
|
|
||||||
╰──────────────────────╯
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 3. Componentes
|
|
||||||
|
|
||||||
### 3.1 Header (opcional)
|
|
||||||
|
|
||||||
```html
|
|
||||||
<header id="header">Proyecto Demo HST</header>
|
|
||||||
```
|
|
||||||
|
|
||||||
```css
|
|
||||||
#header {
|
|
||||||
font-size: 24px;
|
|
||||||
font-weight: 600;
|
|
||||||
color: #333;
|
|
||||||
margin-bottom: 40px;
|
|
||||||
padding-left: 20px;
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
**Visibilidad:** Controlada por `mostrar_titulo` en JSON.
|
|
||||||
|
|
||||||
### 3.2 Nodo Nivel 1
|
|
||||||
|
|
||||||
```html
|
|
||||||
<div class="level1-node" data-color="orange" data-node-id="n1">
|
|
||||||
<span class="node-text">Arquitectura</span>
|
|
||||||
</div>
|
|
||||||
```
|
|
||||||
|
|
||||||
```css
|
|
||||||
.level1-node {
|
|
||||||
position: relative;
|
|
||||||
cursor: pointer;
|
|
||||||
padding: 8px 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.level1-node .node-text {
|
|
||||||
font-size: 18px;
|
|
||||||
font-weight: 500;
|
|
||||||
color: #333;
|
|
||||||
border-bottom: 3px solid currentColor;
|
|
||||||
padding-bottom: 4px;
|
|
||||||
display: inline-block;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Colores por data-color */
|
|
||||||
.level1-node[data-color="orange"] .node-text {
|
|
||||||
color: #FF6B35;
|
|
||||||
border-color: #FF6B35;
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
**Características:**
|
|
||||||
- Solo texto, sin caja ni fondo
|
|
||||||
- Subrayado del color de la rama
|
|
||||||
- Click para expandir/contraer
|
|
||||||
|
|
||||||
### 3.3 Subnodo
|
|
||||||
|
|
||||||
```html
|
|
||||||
<div class="subnode" data-color="orange" data-parent-id="n1">
|
|
||||||
<div class="subnode-image-container">
|
|
||||||
<img src="http://72.62.2.84:8090/arc_arquitectura.png" alt="plano.pdf">
|
|
||||||
<a href="#" download class="btn-download">↓</a>
|
|
||||||
<a href="#" target="_blank" class="btn-preview">👁</a>
|
|
||||||
</div>
|
|
||||||
<div class="subnode-title">plano.pdf</div>
|
|
||||||
</div>
|
|
||||||
```
|
|
||||||
|
|
||||||
```css
|
|
||||||
.subnode {
|
|
||||||
position: relative;
|
|
||||||
width: 200px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.subnode-image-container {
|
|
||||||
position: relative;
|
|
||||||
width: 100%;
|
|
||||||
aspect-ratio: 16/9;
|
|
||||||
border-radius: 8px;
|
|
||||||
overflow: hidden;
|
|
||||||
border: 3px solid #ddd;
|
|
||||||
}
|
|
||||||
|
|
||||||
.subnode-image-container img {
|
|
||||||
width: 100%;
|
|
||||||
height: 100%;
|
|
||||||
object-fit: cover;
|
|
||||||
}
|
|
||||||
|
|
||||||
.subnode-title {
|
|
||||||
font-size: 14px;
|
|
||||||
color: #555;
|
|
||||||
margin-top: 8px;
|
|
||||||
text-align: center;
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
**Características:**
|
|
||||||
- Imagen 16:9 con bordes redondeados
|
|
||||||
- Borde del color de la rama padre
|
|
||||||
- Título debajo, centrado
|
|
||||||
- Botones siempre visibles
|
|
||||||
|
|
||||||
### 3.4 Botones de Acción
|
|
||||||
|
|
||||||
```css
|
|
||||||
.btn-download, .btn-preview {
|
|
||||||
position: absolute;
|
|
||||||
width: 28px;
|
|
||||||
height: 28px;
|
|
||||||
border-radius: 6px;
|
|
||||||
background: rgba(0,0,0,0.6);
|
|
||||||
color: white;
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
font-size: 14px;
|
|
||||||
cursor: pointer;
|
|
||||||
text-decoration: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.btn-download {
|
|
||||||
bottom: 6px;
|
|
||||||
left: 6px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.btn-preview {
|
|
||||||
top: 6px;
|
|
||||||
right: 6px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.btn-download:hover, .btn-preview:hover {
|
|
||||||
background: rgba(0,0,0,0.8);
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
| Botón | Icono | Posición | Visible |
|
|
||||||
|-------|-------|----------|---------|
|
|
||||||
| Descarga | ↓ | Esquina inferior izquierda | Siempre |
|
|
||||||
| Preview | 👁 | Esquina superior derecha | Solo PDF/imágenes |
|
|
||||||
|
|
||||||
**Archivos con preview:**
|
|
||||||
- `.pdf`
|
|
||||||
- `.png`
|
|
||||||
- `.jpg` / `.jpeg`
|
|
||||||
- `.gif`
|
|
||||||
- `.webp`
|
|
||||||
|
|
||||||
### 3.5 Líneas SVG
|
|
||||||
|
|
||||||
```html
|
|
||||||
<svg id="lines-svg">
|
|
||||||
<path d="M 150,50 C 200,50 200,120 250,120" stroke="#FF6B35" />
|
|
||||||
</svg>
|
|
||||||
```
|
|
||||||
|
|
||||||
```css
|
|
||||||
#lines-svg {
|
|
||||||
position: absolute;
|
|
||||||
top: 0;
|
|
||||||
left: 0;
|
|
||||||
width: 100%;
|
|
||||||
height: 100%;
|
|
||||||
pointer-events: none;
|
|
||||||
overflow: visible;
|
|
||||||
}
|
|
||||||
|
|
||||||
#lines-svg path {
|
|
||||||
fill: none;
|
|
||||||
stroke-width: 3;
|
|
||||||
stroke-linecap: round;
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
**Curva Bezier:**
|
|
||||||
```
|
|
||||||
M x1,y1 C cx1,cy1 cx2,cy2 x2,y2
|
|
||||||
|
|
||||||
Donde:
|
|
||||||
- (x1,y1) = Punto inicio (borde derecho del nodo nivel 1)
|
|
||||||
- (cx1,cy1) = Primer punto de control
|
|
||||||
- (cx2,cy2) = Segundo punto de control
|
|
||||||
- (x2,y2) = Punto final (borde izquierdo del subnodo)
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 4. Paleta de Colores
|
|
||||||
|
|
||||||
### 4.1 Colores de ramas
|
|
||||||
|
|
||||||
| Nombre | Hex | Muestra |
|
|
||||||
|--------|-----|---------|
|
|
||||||
| Orange | #FF6B35 | 🟠 |
|
|
||||||
| Yellow | #E5A000 | 🟡 |
|
|
||||||
| Green | #06D6A0 | 🟢 |
|
|
||||||
| Cyan | #0891B2 | 🔵 |
|
|
||||||
| Blue | #3B82F6 | 🔷 |
|
|
||||||
| Purple | #8B5CF6 | 🟣 |
|
|
||||||
| Pink | #EC4899 | 🩷 |
|
|
||||||
|
|
||||||
### 4.2 Colores base
|
|
||||||
|
|
||||||
| Uso | Hex |
|
|
||||||
|-----|-----|
|
|
||||||
| Fondo | #f5f5f7 |
|
|
||||||
| Texto principal | #333333 |
|
|
||||||
| Texto secundario | #555555 |
|
|
||||||
| Borde default | #dddddd |
|
|
||||||
|
|
||||||
### 4.3 Asignación automática
|
|
||||||
|
|
||||||
```javascript
|
|
||||||
const COLORS = ['orange', 'yellow', 'green', 'cyan', 'blue', 'purple', 'pink'];
|
|
||||||
|
|
||||||
// Cada nodo nivel 1 recibe un color según su índice
|
|
||||||
const color = COLORS[index % COLORS.length];
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 5. Tipografía
|
|
||||||
|
|
||||||
### 5.1 Familia
|
|
||||||
|
|
||||||
```css
|
|
||||||
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
|
|
||||||
```
|
|
||||||
|
|
||||||
### 5.2 Tamaños
|
|
||||||
|
|
||||||
| Elemento | Tamaño | Peso |
|
|
||||||
|----------|--------|------|
|
|
||||||
| Header | 24px | 600 |
|
|
||||||
| Nodo nivel 1 | 18px | 500 |
|
|
||||||
| Título subnodo | 14px | 400 |
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 6. Interactividad
|
|
||||||
|
|
||||||
### 6.1 Click en nodo nivel 1
|
|
||||||
|
|
||||||
```javascript
|
|
||||||
node.addEventListener('click', () => {
|
|
||||||
const nodeId = node.dataset.nodeId;
|
|
||||||
const subnodes = document.querySelectorAll(`[data-parent-id="${nodeId}"]`);
|
|
||||||
|
|
||||||
subnodes.forEach(sub => {
|
|
||||||
sub.classList.toggle('hidden');
|
|
||||||
});
|
|
||||||
|
|
||||||
// Redibujar líneas
|
|
||||||
drawLines();
|
|
||||||
});
|
|
||||||
```
|
|
||||||
|
|
||||||
**Comportamiento:**
|
|
||||||
- Toggle: muestra/oculta subnodos
|
|
||||||
- Recalcula posiciones de líneas SVG
|
|
||||||
- Animación suave (opcional)
|
|
||||||
|
|
||||||
### 6.2 Cálculo de líneas
|
|
||||||
|
|
||||||
```javascript
|
|
||||||
function drawLines() {
|
|
||||||
const svg = document.getElementById('lines-svg');
|
|
||||||
svg.innerHTML = '';
|
|
||||||
|
|
||||||
const containerRect = document.getElementById('mindmap-container').getBoundingClientRect();
|
|
||||||
|
|
||||||
document.querySelectorAll('.level1-node').forEach(node => {
|
|
||||||
const nodeId = node.dataset.nodeId;
|
|
||||||
const color = node.dataset.color;
|
|
||||||
const nodeRect = node.getBoundingClientRect();
|
|
||||||
|
|
||||||
// Punto inicio: borde derecho del subrayado
|
|
||||||
const startX = nodeRect.right - containerRect.left;
|
|
||||||
const startY = nodeRect.bottom - containerRect.top - 2;
|
|
||||||
|
|
||||||
// Encontrar subnodos visibles
|
|
||||||
const subnodes = document.querySelectorAll(
|
|
||||||
`.subnode[data-parent-id="${nodeId}"]:not(.hidden)`
|
|
||||||
);
|
|
||||||
|
|
||||||
subnodes.forEach(subnode => {
|
|
||||||
const subRect = subnode.querySelector('.subnode-image-container')
|
|
||||||
.getBoundingClientRect();
|
|
||||||
|
|
||||||
// Punto final: borde izquierdo del subnodo
|
|
||||||
const endX = subRect.left - containerRect.left;
|
|
||||||
const endY = subRect.top + subRect.height/2 - containerRect.top;
|
|
||||||
|
|
||||||
// Puntos de control para curva suave
|
|
||||||
const midX = startX + (endX - startX) / 2;
|
|
||||||
|
|
||||||
const path = document.createElementNS('http://www.w3.org/2000/svg', 'path');
|
|
||||||
path.setAttribute('d',
|
|
||||||
`M ${startX},${startY} C ${midX},${startY} ${midX},${endY} ${endX},${endY}`
|
|
||||||
);
|
|
||||||
path.setAttribute('stroke', getColorValue(color));
|
|
||||||
svg.appendChild(path);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
### 6.3 Responsive
|
|
||||||
|
|
||||||
```javascript
|
|
||||||
// Redibujar en resize
|
|
||||||
window.addEventListener('resize', drawLines);
|
|
||||||
|
|
||||||
// Detectar mobile
|
|
||||||
const isMobile = window.innerWidth < 768;
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 7. Estructura JSON
|
|
||||||
|
|
||||||
### 7.1 Formato completo
|
|
||||||
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"slug": "proyecto-demo",
|
|
||||||
"titulo": "Proyecto Demo HST",
|
|
||||||
"mostrar_titulo": true,
|
|
||||||
"tema": "light",
|
|
||||||
"nodos": [
|
|
||||||
{
|
|
||||||
"id": "n1",
|
|
||||||
"titulo": "Arquitectura",
|
|
||||||
"color": "#FF6B35",
|
|
||||||
"subnodos": [
|
|
||||||
{
|
|
||||||
"titulo": "plano_general.pdf",
|
|
||||||
"icono_hst": "arc_arquitectura",
|
|
||||||
"url_archivo": "https://git.tzzr.pro/.../plano.pdf",
|
|
||||||
"url_corta": "https://tzzr.pro/abc123"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"titulo": "secciones.pdf",
|
|
||||||
"icono_hst": "pln_plano",
|
|
||||||
"url_archivo": "https://git.tzzr.pro/.../secciones.pdf",
|
|
||||||
"url_corta": "https://tzzr.pro/def456"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": "n2",
|
|
||||||
"titulo": "Renders",
|
|
||||||
"color": "#E5A000",
|
|
||||||
"subnodos": [
|
|
||||||
{
|
|
||||||
"titulo": "exterior.jpg",
|
|
||||||
"icono_hst": "ren_render",
|
|
||||||
"url_archivo": "https://git.tzzr.pro/.../exterior.jpg"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
### 7.2 Campos
|
|
||||||
|
|
||||||
| Campo | Tipo | Requerido | Descripción |
|
|
||||||
|-------|------|-----------|-------------|
|
|
||||||
| slug | string | ✅ | Identificador URL |
|
|
||||||
| titulo | string | ✅ | Nombre del proyecto |
|
|
||||||
| mostrar_titulo | boolean | ❌ | Si mostrar header (default: true) |
|
|
||||||
| tema | string | ❌ | "light" o "dark" |
|
|
||||||
| nodos | array | ✅ | Lista de nodos nivel 1 |
|
|
||||||
|
|
||||||
**Nodo:**
|
|
||||||
| Campo | Tipo | Requerido | Descripción |
|
|
||||||
|-------|------|-----------|-------------|
|
|
||||||
| id | string | ✅ | Identificador único |
|
|
||||||
| titulo | string | ✅ | Nombre de la carpeta |
|
|
||||||
| color | string | ❌ | Color hex (si no, se asigna auto) |
|
|
||||||
| subnodos | array | ✅ | Lista de subnodos |
|
|
||||||
|
|
||||||
**Subnodo:**
|
|
||||||
| Campo | Tipo | Requerido | Descripción |
|
|
||||||
|-------|------|-----------|-------------|
|
|
||||||
| titulo | string | ✅ | Nombre del archivo |
|
|
||||||
| icono_hst | string | ✅ | Referencia imagen HST |
|
|
||||||
| url_archivo | string | ✅ | URL de descarga |
|
|
||||||
| url_corta | string | ❌ | URL acortada |
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 8. Código Base
|
|
||||||
|
|
||||||
### 8.1 index.html
|
|
||||||
|
|
||||||
```html
|
|
||||||
<!DOCTYPE html>
|
|
||||||
<html lang="es">
|
|
||||||
<head>
|
|
||||||
<meta charset="UTF-8">
|
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
||||||
<title>MML - Mindmap Linking</title>
|
|
||||||
<link rel="stylesheet" href="css/main.css">
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<div id="app">
|
|
||||||
<header id="header"></header>
|
|
||||||
<div id="mindmap-container">
|
|
||||||
<svg id="lines-svg"></svg>
|
|
||||||
<div id="nodes-container"></div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<script src="js/app.js" type="module"></script>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
```
|
|
||||||
|
|
||||||
### 8.2 Variables CSS
|
|
||||||
|
|
||||||
```css
|
|
||||||
:root {
|
|
||||||
--bg-primary: #f5f5f7;
|
|
||||||
--text-primary: #333;
|
|
||||||
--text-secondary: #555;
|
|
||||||
--font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
|
|
||||||
--line-width: 3px;
|
|
||||||
--image-radius: 8px;
|
|
||||||
--transition-speed: 0.3s;
|
|
||||||
|
|
||||||
/* Colores de ramas */
|
|
||||||
--color-orange: #FF6B35;
|
|
||||||
--color-yellow: #E5A000;
|
|
||||||
--color-green: #06D6A0;
|
|
||||||
--color-cyan: #0891B2;
|
|
||||||
--color-blue: #3B82F6;
|
|
||||||
--color-purple: #8B5CF6;
|
|
||||||
--color-pink: #EC4899;
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 9. Imágenes HST
|
|
||||||
|
|
||||||
### 9.1 URL Base
|
|
||||||
|
|
||||||
```javascript
|
|
||||||
const HST_BASE = 'http://72.62.2.84:8090/';
|
|
||||||
```
|
|
||||||
|
|
||||||
### 9.2 Construcción de URL
|
|
||||||
|
|
||||||
```javascript
|
|
||||||
function getImageUrl(icono_hst) {
|
|
||||||
if (!icono_hst) return null;
|
|
||||||
return `${HST_BASE}${icono_hst}.png`;
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
### 9.3 Formato de nombres
|
|
||||||
|
|
||||||
```
|
|
||||||
{codigo}_{nombre}.png
|
|
||||||
|
|
||||||
Ejemplos:
|
|
||||||
- arc_arquitectura.png
|
|
||||||
- pln_plano.png
|
|
||||||
- doc_documento.png
|
|
||||||
- fto_foto.png
|
|
||||||
```
|
|
||||||
|
|
||||||
### 9.4 Fallback si imagen no existe
|
|
||||||
|
|
||||||
```javascript
|
|
||||||
img.onerror = function() {
|
|
||||||
this.src = '/assets/placeholder.png';
|
|
||||||
// O ocultar el contenedor de imagen
|
|
||||||
this.parentElement.style.display = 'none';
|
|
||||||
};
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 10. Tests de Interfaz
|
|
||||||
|
|
||||||
### 10.1 Checklist visual
|
|
||||||
|
|
||||||
| Test | Criterio |
|
|
||||||
|------|----------|
|
|
||||||
| Carga | Página muestra contenido en <2s |
|
|
||||||
| Header | Título visible si `mostrar_titulo: true` |
|
|
||||||
| Nodos | Todos los nodos nivel 1 visibles |
|
|
||||||
| Imágenes | Ninguna imagen rota |
|
|
||||||
| Líneas | Curvas conectan correctamente |
|
|
||||||
| Click | Expandir/contraer funciona |
|
|
||||||
| Responsive | Layout adapta a mobile |
|
|
||||||
|
|
||||||
### 10.2 Tests Puppeteer
|
|
||||||
|
|
||||||
```javascript
|
|
||||||
// Test de imágenes
|
|
||||||
const images = await page.$$eval('img', imgs =>
|
|
||||||
imgs.map(img => ({
|
|
||||||
src: img.src,
|
|
||||||
loaded: img.complete && img.naturalWidth > 0
|
|
||||||
}))
|
|
||||||
);
|
|
||||||
const broken = images.filter(i => !i.loaded);
|
|
||||||
if (broken.length > 0) {
|
|
||||||
errors.push(`Imágenes rotas: ${broken.map(i => i.src).join(', ')}`);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Test de líneas
|
|
||||||
const paths = await page.$$('svg path');
|
|
||||||
if (paths.length === 0) {
|
|
||||||
errors.push('No hay curvas SVG');
|
|
||||||
}
|
|
||||||
|
|
||||||
// Test de interactividad
|
|
||||||
await page.click('.level1-node');
|
|
||||||
await page.waitForTimeout(300);
|
|
||||||
const visibleSubnodes = await page.$$('.subnode:not(.hidden)');
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 11. Accesibilidad
|
|
||||||
|
|
||||||
### 11.1 Básico
|
|
||||||
|
|
||||||
```html
|
|
||||||
<!-- Alt text en imágenes -->
|
|
||||||
<img src="..." alt="plano_general.pdf">
|
|
||||||
|
|
||||||
<!-- Roles semánticos -->
|
|
||||||
<nav role="navigation">
|
|
||||||
<main role="main">
|
|
||||||
|
|
||||||
<!-- Focus visible -->
|
|
||||||
.level1-node:focus {
|
|
||||||
outline: 2px solid var(--color-blue);
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
### 11.2 Navegación por teclado
|
|
||||||
|
|
||||||
```javascript
|
|
||||||
// Enter/Space para expandir
|
|
||||||
node.addEventListener('keydown', (e) => {
|
|
||||||
if (e.key === 'Enter' || e.key === ' ') {
|
|
||||||
e.preventDefault();
|
|
||||||
node.click();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// Tab order
|
|
||||||
node.setAttribute('tabindex', '0');
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
**Versión:** 1.0
|
|
||||||
**Fecha:** 2025-12-11
|
|
||||||
@@ -1,203 +0,0 @@
|
|||||||
# LLM Orchestrator
|
|
||||||
|
|
||||||

|
|
||||||
|
|
||||||
|
|
||||||
Sistema de orquestación multi-agente compatible con cualquier LLM.
|
|
||||||
|
|
||||||
## ¿Qué es esto?
|
|
||||||
|
|
||||||
Un framework para crear y coordinar múltiples agentes de IA que pueden:
|
|
||||||
- Ejecutar comandos en tu sistema
|
|
||||||
- Leer y escribir archivos
|
|
||||||
- Conectarse a servidores via SSH
|
|
||||||
- Hacer llamadas a APIs
|
|
||||||
- Trabajar juntos en tareas complejas
|
|
||||||
|
|
||||||
## Características
|
|
||||||
|
|
||||||
- **Multi-modelo**: Claude, GPT-4, Gemini, Llama, Mistral, y 100+ más
|
|
||||||
- **Herramientas universales**: Bash, lectura/escritura de archivos, SSH, HTTP
|
|
||||||
- **Agentes personalizables**: Define tantos agentes como necesites
|
|
||||||
- **LOGs automáticos**: Registro de todas las acciones
|
|
||||||
- **Sin dependencias pesadas**: Solo Python estándar + LiteLLM opcional
|
|
||||||
|
|
||||||
## Instalación
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Clonar o descomprimir
|
|
||||||
cd orchestrator
|
|
||||||
|
|
||||||
# Crear entorno virtual
|
|
||||||
python3 -m venv .venv
|
|
||||||
source .venv/bin/activate
|
|
||||||
|
|
||||||
# Instalar dependencias opcionales
|
|
||||||
pip install litellm # Para usar GPT-4, Gemini, Llama, etc.
|
|
||||||
```
|
|
||||||
|
|
||||||
## Uso rápido
|
|
||||||
|
|
||||||
### 1. Define tus agentes
|
|
||||||
|
|
||||||
Edita `config.yaml`:
|
|
||||||
|
|
||||||
```yaml
|
|
||||||
agents:
|
|
||||||
researcher:
|
|
||||||
role: "Investigador que busca información"
|
|
||||||
provider: claude
|
|
||||||
model: sonnet
|
|
||||||
tools: [bash, read, http_request]
|
|
||||||
|
|
||||||
coder:
|
|
||||||
role: "Programador que escribe código"
|
|
||||||
provider: litellm
|
|
||||||
model: gpt4o
|
|
||||||
tools: [read, write, bash]
|
|
||||||
|
|
||||||
reviewer:
|
|
||||||
role: "Revisor que valida el trabajo"
|
|
||||||
provider: litellm
|
|
||||||
model: gemini-pro
|
|
||||||
tools: [read, grep]
|
|
||||||
```
|
|
||||||
|
|
||||||
### 2. Ejecuta el orquestador
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Modo interactivo
|
|
||||||
python orchestrator/main.py
|
|
||||||
|
|
||||||
# Ejecutar un agente específico
|
|
||||||
python orchestrator/main.py --agent researcher --prompt "Busca información sobre X"
|
|
||||||
|
|
||||||
# Ver estado
|
|
||||||
python orchestrator/main.py --status
|
|
||||||
```
|
|
||||||
|
|
||||||
### 3. Comandos interactivos
|
|
||||||
|
|
||||||
```
|
|
||||||
/status - Ver estado del sistema
|
|
||||||
/agents - Listar agentes disponibles
|
|
||||||
/agent <nombre> - Cambiar agente activo
|
|
||||||
/logs <agente> - Ver historial del agente
|
|
||||||
/all - Ejecutar en todos los agentes
|
|
||||||
/quit - Salir
|
|
||||||
```
|
|
||||||
|
|
||||||
## Estructura
|
|
||||||
|
|
||||||
```
|
|
||||||
orchestrator/
|
|
||||||
├── config.yaml # ← Tu configuración de agentes
|
|
||||||
├── orchestrator/
|
|
||||||
│ ├── main.py # Punto de entrada
|
|
||||||
│ ├── config.py # Carga de configuración
|
|
||||||
│ ├── providers/ # Conexión con LLMs
|
|
||||||
│ │ ├── claude_provider.py
|
|
||||||
│ │ └── litellm_provider.py
|
|
||||||
│ ├── tools/ # Herramientas disponibles
|
|
||||||
│ │ ├── executor.py
|
|
||||||
│ │ └── definitions.py
|
|
||||||
│ ├── agents/ # Lógica de agentes
|
|
||||||
│ │ └── base.py
|
|
||||||
│ └── tasks/ # Tareas predefinidas
|
|
||||||
├── logs/ # Historial por agente
|
|
||||||
├── outputs/ # Archivos generados
|
|
||||||
└── examples/ # Ejemplos de configuración
|
|
||||||
```
|
|
||||||
|
|
||||||
## Providers disponibles
|
|
||||||
|
|
||||||
| Provider | Modelos | Requisito |
|
|
||||||
|----------|---------|-----------|
|
|
||||||
| `claude` | sonnet, opus, haiku | Claude Code CLI instalado |
|
|
||||||
| `litellm` | gpt4o, gemini-pro, llama3, mistral... | `pip install litellm` + API keys |
|
|
||||||
|
|
||||||
## Herramientas disponibles
|
|
||||||
|
|
||||||
| Herramienta | Descripción |
|
|
||||||
|-------------|-------------|
|
|
||||||
| `bash` | Ejecuta comandos del sistema |
|
|
||||||
| `read` | Lee archivos |
|
|
||||||
| `write` | Escribe/crea archivos |
|
|
||||||
| `glob` | Busca archivos por patrón |
|
|
||||||
| `grep` | Busca texto en archivos |
|
|
||||||
| `ssh` | Ejecuta comandos en servidores remotos |
|
|
||||||
| `http_request` | Hace peticiones HTTP/API |
|
|
||||||
| `list_dir` | Lista contenido de directorios |
|
|
||||||
|
|
||||||
## Ejemplos
|
|
||||||
|
|
||||||
### Agente simple (solo conversación)
|
|
||||||
|
|
||||||
```yaml
|
|
||||||
agents:
|
|
||||||
assistant:
|
|
||||||
role: "Asistente general"
|
|
||||||
provider: claude
|
|
||||||
model: sonnet
|
|
||||||
tools: [] # Sin herramientas
|
|
||||||
```
|
|
||||||
|
|
||||||
### Equipo de desarrollo
|
|
||||||
|
|
||||||
```yaml
|
|
||||||
agents:
|
|
||||||
architect:
|
|
||||||
role: "Diseña la arquitectura del sistema"
|
|
||||||
provider: claude
|
|
||||||
model: opus
|
|
||||||
tools: [read, write, bash]
|
|
||||||
|
|
||||||
developer:
|
|
||||||
role: "Implementa el código"
|
|
||||||
provider: litellm
|
|
||||||
model: gpt4o
|
|
||||||
tools: [read, write, bash, grep]
|
|
||||||
|
|
||||||
tester:
|
|
||||||
role: "Escribe y ejecuta tests"
|
|
||||||
provider: litellm
|
|
||||||
model: gemini-pro
|
|
||||||
tools: [read, bash]
|
|
||||||
```
|
|
||||||
|
|
||||||
### Agentes con servidores
|
|
||||||
|
|
||||||
```yaml
|
|
||||||
servers:
|
|
||||||
production:
|
|
||||||
host: 192.168.1.100
|
|
||||||
user: deploy
|
|
||||||
key: ~/.ssh/id_rsa
|
|
||||||
|
|
||||||
staging:
|
|
||||||
host: 192.168.1.101
|
|
||||||
user: deploy
|
|
||||||
key: ~/.ssh/id_rsa
|
|
||||||
|
|
||||||
agents:
|
|
||||||
deployer:
|
|
||||||
role: "Despliega aplicaciones a servidores"
|
|
||||||
provider: claude
|
|
||||||
model: sonnet
|
|
||||||
tools: [ssh, bash, read]
|
|
||||||
servers: [production, staging]
|
|
||||||
```
|
|
||||||
|
|
||||||
## Variables de entorno
|
|
||||||
|
|
||||||
Para usar modelos de pago via LiteLLM:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
export OPENAI_API_KEY="sk-..."
|
|
||||||
export GOOGLE_API_KEY="..."
|
|
||||||
export ANTHROPIC_API_KEY="..." # Si usas Claude via API
|
|
||||||
```
|
|
||||||
|
|
||||||
## Licencia
|
|
||||||
|
|
||||||
MIT - Usa, modifica y comparte libremente.
|
|
||||||
@@ -1,402 +0,0 @@
|
|||||||
# Despliegue de Tablas de Contexto IA - Sistema TZZR
|
|
||||||
|
|
||||||
**Fecha:** 23 de Diciembre, 2024
|
|
||||||
**Ejecutado por:** ARCHITECT
|
|
||||||
**Estado:** ✅ COMPLETADO EXITOSAMENTE
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Resumen Ejecutivo
|
|
||||||
|
|
||||||
Se han desplegado exitosamente las tablas de contexto IA en los 3 servidores principales del sistema TZZR:
|
|
||||||
- **architect** (69.62.126.110)
|
|
||||||
- **deck** (72.62.1.113)
|
|
||||||
- **corp** (92.112.181.188)
|
|
||||||
|
|
||||||
Todos los servidores cuentan ahora con la infraestructura de base de datos necesaria para soportar el contexto compartido entre agentes IA.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Servidores Desplegados
|
|
||||||
|
|
||||||
### 1. ARCHITECT (69.62.126.110) - LOCAL ✅
|
|
||||||
|
|
||||||
**Status:** COMPLETADO
|
|
||||||
**Base de datos:** PostgreSQL (puerto 5432)
|
|
||||||
|
|
||||||
**Tablas creadas:**
|
|
||||||
- `ai_context` - 3 registros iniciales
|
|
||||||
- `ai_conversations`
|
|
||||||
- `ai_learnings`
|
|
||||||
- `ai_tasks`
|
|
||||||
|
|
||||||
**Datos iniciales verificados:**
|
|
||||||
- system.architecture: Configuración de servidores y servicios
|
|
||||||
- system.agents: Roles y capacidades de los agentes
|
|
||||||
- system.gitea: Configuración del repositorio Gitea
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
### 2. DECK (72.62.1.113) ✅
|
|
||||||
|
|
||||||
**Status:** COMPLETADO
|
|
||||||
**Base de datos:** PostgreSQL (puerto 5432)
|
|
||||||
|
|
||||||
**Tablas creadas:**
|
|
||||||
- `ai_context`
|
|
||||||
- `ai_conversations`
|
|
||||||
- `ai_learnings`
|
|
||||||
- `ai_tasks`
|
|
||||||
|
|
||||||
**Nota:** SSH temporalmente inaccesible al momento de la verificación final, pero el despliegue se completó exitosamente.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
### 3. CORP (92.112.181.188) ✅
|
|
||||||
|
|
||||||
**Status:** COMPLETADO
|
|
||||||
**Base de datos:** PostgreSQL (puerto 5432)
|
|
||||||
|
|
||||||
**Tablas creadas:**
|
|
||||||
- `ai_context` - 3 registros iniciales
|
|
||||||
- `ai_conversations`
|
|
||||||
- `ai_learnings`
|
|
||||||
- `ai_tasks`
|
|
||||||
|
|
||||||
**Datos iniciales verificados:**
|
|
||||||
- system.architecture: Configuración de servidores y servicios
|
|
||||||
- system.agents: Roles y capacidades de los agentes
|
|
||||||
- system.gitea: Configuración del repositorio Gitea
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Estructura de Tablas
|
|
||||||
|
|
||||||
### 1. `ai_context` - Contexto Compartido entre Agentes
|
|
||||||
|
|
||||||
Almacena información de contexto que puede ser compartida entre diferentes agentes del sistema.
|
|
||||||
|
|
||||||
**Campos principales:**
|
|
||||||
- `id` (SERIAL PRIMARY KEY)
|
|
||||||
- `context_type` (VARCHAR 50) - 'system', 'project', 'conversation', 'agent'
|
|
||||||
- `context_key` (VARCHAR 255)
|
|
||||||
- `context_value` (JSONB)
|
|
||||||
- `agent_name` (VARCHAR 100)
|
|
||||||
- `priority` (INTEGER) - Mayor valor = mayor importancia
|
|
||||||
- `expires_at` (TIMESTAMP) - NULL = no expira
|
|
||||||
- `created_at`, `updated_at` (TIMESTAMP)
|
|
||||||
|
|
||||||
**Índices:**
|
|
||||||
- idx_ai_context_type
|
|
||||||
- idx_ai_context_key
|
|
||||||
- idx_ai_context_agent
|
|
||||||
- idx_ai_context_priority
|
|
||||||
- idx_ai_context_expires
|
|
||||||
|
|
||||||
**Características:**
|
|
||||||
- Constraint UNIQUE en (context_type, context_key)
|
|
||||||
- Trigger para actualización automática de `updated_at`
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
### 2. `ai_conversations` - Historial de Conversaciones
|
|
||||||
|
|
||||||
Registro completo de todas las conversaciones entre usuarios y agentes.
|
|
||||||
|
|
||||||
**Campos principales:**
|
|
||||||
- `id` (SERIAL PRIMARY KEY)
|
|
||||||
- `conversation_id` (UUID)
|
|
||||||
- `agent_name` (VARCHAR 100)
|
|
||||||
- `role` (VARCHAR 20) - 'user', 'assistant', 'system'
|
|
||||||
- `message` (TEXT)
|
|
||||||
- `metadata` (JSONB) - tokens, modelo usado, etc.
|
|
||||||
- `created_at` (TIMESTAMP)
|
|
||||||
|
|
||||||
**Índices:**
|
|
||||||
- idx_ai_conv_id
|
|
||||||
- idx_ai_conv_agent
|
|
||||||
- idx_ai_conv_created
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
### 3. `ai_learnings` - Patrones y Aprendizajes
|
|
||||||
|
|
||||||
Sistema de aprendizaje continuo para los agentes IA.
|
|
||||||
|
|
||||||
**Campos principales:**
|
|
||||||
- `id` (SERIAL PRIMARY KEY)
|
|
||||||
- `learning_type` (VARCHAR 50) - 'pattern', 'error', 'solution', 'optimization'
|
|
||||||
- `title` (VARCHAR 255)
|
|
||||||
- `description` (TEXT)
|
|
||||||
- `context` (JSONB)
|
|
||||||
- `confidence` (DECIMAL 3,2) - 0.00 a 1.00
|
|
||||||
- `usage_count` (INTEGER)
|
|
||||||
- `success_rate` (DECIMAL 3,2)
|
|
||||||
- `agent_name` (VARCHAR 100)
|
|
||||||
- `created_at`, `updated_at` (TIMESTAMP)
|
|
||||||
|
|
||||||
**Índices:**
|
|
||||||
- idx_ai_learning_type
|
|
||||||
- idx_ai_learning_confidence
|
|
||||||
- idx_ai_learning_agent
|
|
||||||
|
|
||||||
**Características:**
|
|
||||||
- Trigger para actualización automática de `updated_at`
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
### 4. `ai_tasks` - Tareas y Estado del Sistema
|
|
||||||
|
|
||||||
Seguimiento de tareas ejecutadas por los agentes.
|
|
||||||
|
|
||||||
**Campos principales:**
|
|
||||||
- `id` (SERIAL PRIMARY KEY)
|
|
||||||
- `task_id` (UUID)
|
|
||||||
- `agent_name` (VARCHAR 100)
|
|
||||||
- `task_type` (VARCHAR 50) - 'deployment', 'backup', 'monitoring', 'analysis'
|
|
||||||
- `task_status` (VARCHAR 20) - 'pending', 'running', 'completed', 'failed'
|
|
||||||
- `task_data` (JSONB)
|
|
||||||
- `result` (JSONB)
|
|
||||||
- `error_message` (TEXT)
|
|
||||||
- `started_at`, `completed_at`, `created_at` (TIMESTAMP)
|
|
||||||
|
|
||||||
**Índices:**
|
|
||||||
- idx_ai_task_id
|
|
||||||
- idx_ai_task_agent
|
|
||||||
- idx_ai_task_status
|
|
||||||
- idx_ai_task_type
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Funciones y Triggers
|
|
||||||
|
|
||||||
### Funciones Creadas
|
|
||||||
|
|
||||||
1. **`update_updated_at_column()`**
|
|
||||||
- Actualiza automáticamente el campo `updated_at` en tablas relevantes
|
|
||||||
- Utilizada por triggers en `ai_context` y `ai_learnings`
|
|
||||||
|
|
||||||
2. **`cleanup_expired_contexts()`**
|
|
||||||
- Elimina contextos expirados basándose en el campo `expires_at`
|
|
||||||
- Retorna la cantidad de registros eliminados
|
|
||||||
- Puede ser ejecutada manualmente o mediante un cron job
|
|
||||||
|
|
||||||
### Triggers Configurados
|
|
||||||
|
|
||||||
1. **`update_ai_context_updated_at`**
|
|
||||||
- Tabla: `ai_context`
|
|
||||||
- Evento: BEFORE UPDATE
|
|
||||||
- Función: `update_updated_at_column()`
|
|
||||||
|
|
||||||
2. **`update_ai_learnings_updated_at`**
|
|
||||||
- Tabla: `ai_learnings`
|
|
||||||
- Evento: BEFORE UPDATE
|
|
||||||
- Función: `update_updated_at_column()`
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Permisos y Seguridad
|
|
||||||
|
|
||||||
**Usuario:** `orchestrator`
|
|
||||||
|
|
||||||
**Permisos otorgados:**
|
|
||||||
- ALL PRIVILEGES en todas las tablas de IA
|
|
||||||
- USAGE, SELECT en todas las secuencias del esquema public
|
|
||||||
|
|
||||||
**Configuración aplicada en todos los servidores:**
|
|
||||||
```sql
|
|
||||||
GRANT ALL PRIVILEGES ON TABLE ai_context TO orchestrator;
|
|
||||||
GRANT ALL PRIVILEGES ON TABLE ai_conversations TO orchestrator;
|
|
||||||
GRANT ALL PRIVILEGES ON TABLE ai_learnings TO orchestrator;
|
|
||||||
GRANT ALL PRIVILEGES ON TABLE ai_tasks TO orchestrator;
|
|
||||||
GRANT USAGE, SELECT ON ALL SEQUENCES IN SCHEMA public TO orchestrator;
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Datos Iniciales del Sistema
|
|
||||||
|
|
||||||
Se insertaron 3 registros de configuración del sistema en `ai_context`:
|
|
||||||
|
|
||||||
### 1. system.architecture
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"servers": {
|
|
||||||
"architect": "69.62.126.110",
|
|
||||||
"hst": "72.62.2.84",
|
|
||||||
"deck": "72.62.1.113",
|
|
||||||
"corp": "92.112.181.188"
|
|
||||||
},
|
|
||||||
"services": {
|
|
||||||
"architect": ["flask_api:5050", "gitea:3000", "postgresql:5432", "portainer:9443"],
|
|
||||||
"hst": ["postgresql:5432"],
|
|
||||||
"deck": ["clara:5000"],
|
|
||||||
"corp": ["postgresql:5432"]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
### 2. system.agents
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"architect": {
|
|
||||||
"role": "coordinator",
|
|
||||||
"capabilities": ["gitea_write", "infrastructure", "coordination"]
|
|
||||||
},
|
|
||||||
"clara": {
|
|
||||||
"role": "legal",
|
|
||||||
"capabilities": ["contract_generation", "legal_analysis"]
|
|
||||||
},
|
|
||||||
"mason": {
|
|
||||||
"role": "reports",
|
|
||||||
"capabilities": ["report_generation", "data_analysis"]
|
|
||||||
},
|
|
||||||
"feldman": {
|
|
||||||
"role": "analysis",
|
|
||||||
"capabilities": ["code_analysis", "security_audit"]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
### 3. system.gitea
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"url": "https://git.tzzr.me",
|
|
||||||
"org": "tzzr",
|
|
||||||
"repos": [
|
|
||||||
"system",
|
|
||||||
"contratos-comunes",
|
|
||||||
"clara",
|
|
||||||
"mason",
|
|
||||||
"feldman",
|
|
||||||
"credentials"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Estadísticas del Despliegue
|
|
||||||
|
|
||||||
| Métrica | Valor |
|
|
||||||
|---------|-------|
|
|
||||||
| Servidores desplegados | 3/3 ✅ |
|
|
||||||
| Tablas por servidor | 4 |
|
|
||||||
| Índices por servidor | 13 |
|
|
||||||
| Funciones por servidor | 2 |
|
|
||||||
| Triggers por servidor | 2 |
|
|
||||||
| Registros iniciales | 3 |
|
|
||||||
| Tiempo total estimado | ~5 minutos |
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Archivos de Despliegue
|
|
||||||
|
|
||||||
Los siguientes archivos fueron utilizados para el despliegue:
|
|
||||||
|
|
||||||
1. **`/home/orchestrator/sql_deploy/04_ai_context.sql`**
|
|
||||||
- Schema completo de las tablas de contexto IA
|
|
||||||
- Índices, funciones y triggers
|
|
||||||
- Datos iniciales del sistema
|
|
||||||
- 175 líneas de código SQL
|
|
||||||
|
|
||||||
2. **`/home/orchestrator/sql_deploy/deploy_ai_context.sh`**
|
|
||||||
- Script de despliegue automatizado
|
|
||||||
- Soporte para despliegue local y remoto vía SSH
|
|
||||||
- Logging con colores para mejor visualización
|
|
||||||
- Manejo de errores y reporte de resumen
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Próximos Pasos
|
|
||||||
|
|
||||||
### Inmediatos
|
|
||||||
1. ✅ ~~Desplegar tablas en los 3 servidores principales~~
|
|
||||||
2. 🔄 Verificar/restaurar SSH en deck si es necesario
|
|
||||||
3. 🔄 Probar conectividad desde las APIs de cada agente
|
|
||||||
|
|
||||||
### Corto Plazo
|
|
||||||
1. Implementar integración con Flask API de architect
|
|
||||||
2. Crear endpoints REST para gestión de contexto
|
|
||||||
3. Desarrollar librería Python para acceso simplificado
|
|
||||||
4. Documentar API de contexto compartido
|
|
||||||
|
|
||||||
### Mediano Plazo
|
|
||||||
1. Implementar sincronización de contexto entre servidores
|
|
||||||
2. Crear dashboard de monitoreo de contexto IA
|
|
||||||
3. Desarrollar sistema de caché para consultas frecuentes
|
|
||||||
4. Implementar mecanismos de backup automático
|
|
||||||
|
|
||||||
### Largo Plazo
|
|
||||||
1. Sistema de aprendizaje automático basado en `ai_learnings`
|
|
||||||
2. Análisis predictivo de tareas basado en historial
|
|
||||||
3. Optimización automática de contexto
|
|
||||||
4. Sistema de recomendaciones entre agentes
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Comandos de Verificación
|
|
||||||
|
|
||||||
Para verificar el estado de las tablas en cada servidor:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# ARCHITECT (local)
|
|
||||||
ssh -i ~/.ssh/tzzr root@69.62.126.110 "sudo -u postgres psql -d postgres -c '\dt ai_*'"
|
|
||||||
|
|
||||||
# DECK
|
|
||||||
ssh -i ~/.ssh/tzzr root@72.62.1.113 "sudo -u postgres psql -d postgres -c '\dt ai_*'"
|
|
||||||
|
|
||||||
# CORP
|
|
||||||
ssh -i ~/.ssh/tzzr root@92.112.181.188 "sudo -u postgres psql -d postgres -c '\dt ai_*'"
|
|
||||||
```
|
|
||||||
|
|
||||||
Para verificar datos iniciales:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
ssh -i ~/.ssh/tzzr root@69.62.126.110 \
|
|
||||||
"sudo -u postgres psql -d postgres -c 'SELECT context_type, context_key, agent_name, priority FROM ai_context;'"
|
|
||||||
```
|
|
||||||
|
|
||||||
Para limpiar contextos expirados:
|
|
||||||
|
|
||||||
```sql
|
|
||||||
SELECT cleanup_expired_contexts();
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Notas Técnicas
|
|
||||||
|
|
||||||
### Consideraciones de Rendimiento
|
|
||||||
- Los índices están optimizados para las consultas más frecuentes
|
|
||||||
- JSONB permite búsquedas eficientes dentro de los valores de contexto
|
|
||||||
- Los triggers son minimalistas para no impactar el rendimiento
|
|
||||||
|
|
||||||
### Escalabilidad
|
|
||||||
- El sistema soporta millones de registros por tabla
|
|
||||||
- Particionamiento futuro puede implementarse si es necesario
|
|
||||||
- La estructura permite sharding horizontal si se requiere
|
|
||||||
|
|
||||||
### Mantenimiento
|
|
||||||
- La función `cleanup_expired_contexts()` debe ejecutarse periódicamente
|
|
||||||
- Se recomienda un cron job diario para limpieza de contextos
|
|
||||||
- Monitorear crecimiento de `ai_conversations` y `ai_tasks`
|
|
||||||
|
|
||||||
### Seguridad
|
|
||||||
- Solo el usuario `orchestrator` tiene acceso completo
|
|
||||||
- Considerar cifrado de datos sensibles en campos JSONB
|
|
||||||
- Implementar auditoría de acceso en el futuro
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Conclusión
|
|
||||||
|
|
||||||
El despliegue de las tablas de contexto IA se ha completado exitosamente en los 3 servidores principales del sistema TZZR. La infraestructura está lista para soportar la comunicación y coordinación entre agentes IA, con un sistema robusto de almacenamiento de contexto, historial, aprendizaje y seguimiento de tareas.
|
|
||||||
|
|
||||||
El sistema ahora puede evolucionar hacia una arquitectura multi-agente más sofisticada, con memoria compartida y capacidad de aprendizaje continuo.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
**Documentado por:** ARCHITECT
|
|
||||||
**Versión:** 1.0
|
|
||||||
**Última actualización:** 2024-12-23
|
|
||||||
@@ -1,101 +0,0 @@
|
|||||||
# Deployment - TZZR Orchestrator
|
|
||||||
|
|
||||||
## Arquitectura del Servidor
|
|
||||||
|
|
||||||
```
|
|
||||||
Servidor: 69.62.126.110 (tzzrarchitect)
|
|
||||||
├── Usuario: orchestrator (no-root)
|
|
||||||
│ ├── /home/orchestrator/orchestrator/ # Orchestrator + venv
|
|
||||||
│ └── /home/orchestrator/.ssh/tzzr # Claves SSH
|
|
||||||
├── /opt/architect-app-v2/ # Architect App v3.0
|
|
||||||
└── Docker
|
|
||||||
└── gitea (puerto 3000) # Repositorios
|
|
||||||
```
|
|
||||||
|
|
||||||
## Por qué usuario no-root
|
|
||||||
|
|
||||||
Claude CLI bloquea `--dangerously-skip-permissions` con root por seguridad.
|
|
||||||
Crear un usuario `orchestrator` permite que los agentes ejecuten comandos sin confirmación.
|
|
||||||
|
|
||||||
| Usuario | --dangerously-skip-permissions | Acceso sistema |
|
|
||||||
|---------|-------------------------------|----------------|
|
|
||||||
| root | Bloqueado | Total |
|
|
||||||
| orchestrator | Funciona | Limitado |
|
|
||||||
|
|
||||||
## Configuración del Usuario
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Crear usuario
|
|
||||||
useradd -m -s /bin/bash orchestrator
|
|
||||||
|
|
||||||
# Copiar orchestrator
|
|
||||||
cp -r /opt/orchestrator /home/orchestrator/
|
|
||||||
chown -R orchestrator:orchestrator /home/orchestrator/orchestrator
|
|
||||||
|
|
||||||
# Copiar claves SSH
|
|
||||||
mkdir -p /home/orchestrator/.ssh
|
|
||||||
cp /root/.ssh/tzzr /home/orchestrator/.ssh/
|
|
||||||
cp /root/.ssh/tzzr.pub /home/orchestrator/.ssh/
|
|
||||||
chown -R orchestrator:orchestrator /home/orchestrator/.ssh
|
|
||||||
chmod 700 /home/orchestrator/.ssh
|
|
||||||
chmod 600 /home/orchestrator/.ssh/tzzr
|
|
||||||
|
|
||||||
# Login de Claude Code
|
|
||||||
su - orchestrator
|
|
||||||
cd orchestrator && source .venv/bin/activate
|
|
||||||
claude # Autenticar con cuenta Anthropic
|
|
||||||
```
|
|
||||||
|
|
||||||
## Servicio Systemd
|
|
||||||
|
|
||||||
`/etc/systemd/system/architect-app.service`:
|
|
||||||
|
|
||||||
```ini
|
|
||||||
[Unit]
|
|
||||||
Description=Architect App v2
|
|
||||||
After=network.target
|
|
||||||
|
|
||||||
[Service]
|
|
||||||
User=orchestrator
|
|
||||||
WorkingDirectory=/home/orchestrator/orchestrator
|
|
||||||
ExecStart=/home/orchestrator/orchestrator/.venv/bin/python /opt/architect-app-v2/app.py
|
|
||||||
Restart=always
|
|
||||||
RestartSec=3
|
|
||||||
|
|
||||||
[Install]
|
|
||||||
WantedBy=multi-user.target
|
|
||||||
```
|
|
||||||
|
|
||||||
Comandos:
|
|
||||||
```bash
|
|
||||||
systemctl daemon-reload
|
|
||||||
systemctl restart architect-app
|
|
||||||
systemctl status architect-app
|
|
||||||
journalctl -u architect-app -f
|
|
||||||
```
|
|
||||||
|
|
||||||
## ClaudeProvider con --dangerously-skip-permissions
|
|
||||||
|
|
||||||
El archivo `orchestrator/providers/claude_provider.py` construye el comando:
|
|
||||||
|
|
||||||
```python
|
|
||||||
cmd = [self.cli_path, "--dangerously-skip-permissions", "-p", prompt, "--output-format", "json"]
|
|
||||||
```
|
|
||||||
|
|
||||||
## Rutas Importantes
|
|
||||||
|
|
||||||
| Ruta | Descripcion |
|
|
||||||
|------|-------------|
|
|
||||||
| /home/orchestrator/orchestrator/ | Codigo del orchestrator |
|
|
||||||
| /home/orchestrator/orchestrator/.venv/ | Virtual environment |
|
|
||||||
| /home/orchestrator/.ssh/tzzr | Clave SSH |
|
|
||||||
| /opt/architect-app-v2/ | Architect App |
|
|
||||||
| /opt/architect-app-v2/data/ | SQLite + config |
|
|
||||||
|
|
||||||
## Acceso Manual
|
|
||||||
|
|
||||||
```bash
|
|
||||||
su - orchestrator
|
|
||||||
cd orchestrator && source .venv/bin/activate
|
|
||||||
python orchestrator/main.py
|
|
||||||
```
|
|
||||||
@@ -1,273 +0,0 @@
|
|||||||
# Reporte de Despliegue: Tablas de Contexto IA
|
|
||||||
**Sistema TZZR**
|
|
||||||
**Fecha:** 2024-12-24
|
|
||||||
**Responsable:** ARCHITECT
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Resumen Ejecutivo
|
|
||||||
|
|
||||||
Se han desplegado exitosamente las tablas de contexto IA en **2 de 3 servidores** del sistema TZZR.
|
|
||||||
|
|
||||||
### Estado del Despliegue
|
|
||||||
|
|
||||||
| Servidor | IP | Estado | Base de Datos | Método de Acceso |
|
|
||||||
|----------|-----|--------|---------------|------------------|
|
|
||||||
| **architect** | 69.62.126.110 | ✅ COMPLETADO | tzzr | Docker (windmill-db-1) |
|
|
||||||
| **corp** | 92.112.181.188 | ✅ COMPLETADO | tzzr | PostgreSQL 16 (host) |
|
|
||||||
| **deck** | 72.62.1.113 | ⚠️ PENDIENTE | N/A | SSH no disponible |
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Tablas Desplegadas
|
|
||||||
|
|
||||||
Se crearon 5 tablas principales en cada servidor:
|
|
||||||
|
|
||||||
### 1. **ia_contexts** - Contextos de conversación
|
|
||||||
- Almacena información de sesiones de agentes IA
|
|
||||||
- Campos: context_id, agent_name, user_id, session_id, metadata, status
|
|
||||||
- Constraint: status IN ('active', 'archived', 'deleted')
|
|
||||||
|
|
||||||
### 2. **ia_messages** - Mensajes de conversación
|
|
||||||
- Historial completo de interacciones
|
|
||||||
- Campos: context_id, role, content, timestamp, token_count, model, metadata
|
|
||||||
- Constraint: role IN ('user', 'assistant', 'system', 'tool')
|
|
||||||
- Foreign Key: context_id → ia_contexts(context_id) ON DELETE CASCADE
|
|
||||||
|
|
||||||
### 3. **ia_embeddings** - Embeddings vectoriales
|
|
||||||
- Para búsqueda semántica de mensajes
|
|
||||||
- Campos: context_id, message_id, embedding_vector, content_hash
|
|
||||||
- Foreign Keys: context_id, message_id con CASCADE
|
|
||||||
|
|
||||||
### 4. **ia_tool_calls** - Registro de herramientas
|
|
||||||
- Tracking de todas las llamadas a herramientas
|
|
||||||
- Campos: context_id, message_id, tool_name, tool_input, tool_output, execution_time_ms, success, error_message
|
|
||||||
- Foreign Keys: context_id, message_id con CASCADE
|
|
||||||
|
|
||||||
### 5. **ia_context_metrics** - Métricas agregadas
|
|
||||||
- Estadísticas por contexto
|
|
||||||
- Campos: context_id, total_messages, total_tokens, total_tool_calls, avg_response_time_ms, last_activity
|
|
||||||
- Foreign Key: context_id con CASCADE
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Índices Creados
|
|
||||||
|
|
||||||
Para optimizar el rendimiento de consultas:
|
|
||||||
|
|
||||||
### ia_contexts
|
|
||||||
- idx_ia_contexts_agent (agent_name)
|
|
||||||
- idx_ia_contexts_session (session_id)
|
|
||||||
- idx_ia_contexts_created (created_at)
|
|
||||||
- idx_ia_contexts_status (status)
|
|
||||||
|
|
||||||
### ia_messages
|
|
||||||
- idx_ia_messages_context (context_id)
|
|
||||||
- idx_ia_messages_timestamp (timestamp)
|
|
||||||
- idx_ia_messages_role (role)
|
|
||||||
|
|
||||||
### ia_embeddings
|
|
||||||
- idx_ia_embeddings_context (context_id)
|
|
||||||
- idx_ia_embeddings_hash (content_hash)
|
|
||||||
|
|
||||||
### ia_tool_calls
|
|
||||||
- idx_ia_tool_calls_context (context_id)
|
|
||||||
- idx_ia_tool_calls_tool (tool_name)
|
|
||||||
- idx_ia_tool_calls_timestamp (timestamp)
|
|
||||||
|
|
||||||
### ia_context_metrics
|
|
||||||
- idx_ia_context_metrics_context (context_id)
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Funciones y Triggers
|
|
||||||
|
|
||||||
### 1. update_ia_contexts_updated_at()
|
|
||||||
- Actualiza automáticamente el campo `updated_at` en tabla ia_contexts
|
|
||||||
- Trigger: BEFORE UPDATE ON ia_contexts
|
|
||||||
|
|
||||||
### 2. update_ia_context_metrics()
|
|
||||||
- Actualiza automáticamente las métricas cuando se inserta un mensaje
|
|
||||||
- Incrementa contadores de mensajes y tokens
|
|
||||||
- Actualiza last_activity
|
|
||||||
- Trigger: AFTER INSERT ON ia_messages
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Vistas
|
|
||||||
|
|
||||||
### ia_context_summary
|
|
||||||
Vista consolidada que combina:
|
|
||||||
- Información del contexto (ia_contexts)
|
|
||||||
- Métricas agregadas (ia_context_metrics)
|
|
||||||
- Campos: context_id, agent_name, session_id, created_at, updated_at, status, message_count, total_tokens, tool_calls, last_activity
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Detalles por Servidor
|
|
||||||
|
|
||||||
### ✅ ARCHITECT (69.62.126.110)
|
|
||||||
|
|
||||||
**Base de Datos:** PostgreSQL 16 (Docker)
|
|
||||||
**Contenedor:** windmill-db-1
|
|
||||||
**Database:** tzzr
|
|
||||||
**Usuario:** postgres
|
|
||||||
|
|
||||||
**Método de despliegue:**
|
|
||||||
```bash
|
|
||||||
docker exec -i windmill-db-1 psql -U postgres -d tzzr < ia_context_schema.sql
|
|
||||||
```
|
|
||||||
|
|
||||||
**Verificación:**
|
|
||||||
```bash
|
|
||||||
# Tablas: 5
|
|
||||||
# Vistas: 1 (ia_context_summary)
|
|
||||||
# Registros: 0 (tablas vacías)
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
### ✅ CORP (92.112.181.188)
|
|
||||||
|
|
||||||
**Base de Datos:** PostgreSQL 16 (Host)
|
|
||||||
**Database:** tzzr
|
|
||||||
**Usuario:** postgres
|
|
||||||
|
|
||||||
**Método de despliegue:**
|
|
||||||
```bash
|
|
||||||
scp ia_context_schema.sql root@92.112.181.188:/tmp/
|
|
||||||
sudo -u postgres psql -d tzzr -f /tmp/ia_context_schema.sql
|
|
||||||
```
|
|
||||||
|
|
||||||
**Verificación:**
|
|
||||||
```bash
|
|
||||||
# Tablas: 5
|
|
||||||
# Vistas: 1 (ia_context_summary)
|
|
||||||
# Registros: 0 (tablas vacías)
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
### ⚠️ DECK (72.62.1.113)
|
|
||||||
|
|
||||||
**Estado:** PENDIENTE
|
|
||||||
**Razón:** SSH no disponible
|
|
||||||
**Acción requerida:** Habilitar SSH mediante acceso físico o consola
|
|
||||||
|
|
||||||
**Script preparado:** `/home/orchestrator/enable-ssh-deck.sh`
|
|
||||||
|
|
||||||
**Pasos para completar:**
|
|
||||||
1. Acceder al servidor DECK mediante consola física/KVM
|
|
||||||
2. Ejecutar: `bash enable-ssh-deck.sh`
|
|
||||||
3. Verificar acceso SSH: `ssh -i ~/.ssh/tzzr root@72.62.1.113`
|
|
||||||
4. Desplegar schema:
|
|
||||||
```bash
|
|
||||||
scp ia_context_schema.sql root@72.62.1.113:/tmp/
|
|
||||||
ssh root@72.62.1.113 "sudo -u postgres psql -d tzzr -f /tmp/ia_context_schema.sql"
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Comandos de Verificación
|
|
||||||
|
|
||||||
### Verificar tablas creadas:
|
|
||||||
```sql
|
|
||||||
SELECT tablename
|
|
||||||
FROM pg_tables
|
|
||||||
WHERE schemaname='public' AND tablename LIKE 'ia_%'
|
|
||||||
ORDER BY tablename;
|
|
||||||
```
|
|
||||||
|
|
||||||
### Verificar vistas:
|
|
||||||
```sql
|
|
||||||
SELECT table_name
|
|
||||||
FROM information_schema.views
|
|
||||||
WHERE table_schema='public' AND table_name LIKE 'ia_%';
|
|
||||||
```
|
|
||||||
|
|
||||||
### Consultar resumen de contextos:
|
|
||||||
```sql
|
|
||||||
SELECT * FROM ia_context_summary;
|
|
||||||
```
|
|
||||||
|
|
||||||
### Verificar triggers:
|
|
||||||
```sql
|
|
||||||
SELECT trigger_name, event_manipulation, event_object_table
|
|
||||||
FROM information_schema.triggers
|
|
||||||
WHERE trigger_schema='public' AND trigger_name LIKE '%ia_%';
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Próximos Pasos
|
|
||||||
|
|
||||||
1. ✅ **COMPLETADO** - Desplegar en architect
|
|
||||||
2. ✅ **COMPLETADO** - Desplegar en corp
|
|
||||||
3. ⏳ **PENDIENTE** - Habilitar SSH y desplegar en deck
|
|
||||||
4. 🔄 **SIGUIENTE** - Integrar con orchestrator para comenzar a registrar contextos
|
|
||||||
5. 🔄 **SIGUIENTE** - Implementar servicio de embeddings para búsqueda semántica
|
|
||||||
6. 🔄 **SIGUIENTE** - Crear dashboards de métricas en Grafana
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Notas Técnicas
|
|
||||||
|
|
||||||
### Arquitectura de Datos
|
|
||||||
- Todas las tablas usan CASCADE en DELETE para mantener integridad referencial
|
|
||||||
- Los embeddings vectoriales están preparados para integración con servicios de vector search
|
|
||||||
- Las métricas se actualizan automáticamente mediante triggers
|
|
||||||
- Sistema preparado para multi-agente con campo `agent_name`
|
|
||||||
|
|
||||||
### Seguridad
|
|
||||||
- Permisos por defecto de PostgreSQL
|
|
||||||
- TODO: Configurar usuarios específicos por servidor
|
|
||||||
- TODO: Implementar políticas de retención de datos
|
|
||||||
|
|
||||||
### Performance
|
|
||||||
- Índices creados en campos de búsqueda frecuente
|
|
||||||
- Vista materializada candidata para ia_context_summary si el volumen crece
|
|
||||||
- Preparado para particionado por fecha si es necesario
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Metadata del Despliegue
|
|
||||||
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"deployment_date": "2024-12-24T00:00:00Z",
|
|
||||||
"architect": "ARCHITECT",
|
|
||||||
"schema_version": "1.0",
|
|
||||||
"servers_deployed": 2,
|
|
||||||
"servers_pending": 1,
|
|
||||||
"total_tables": 5,
|
|
||||||
"total_views": 1,
|
|
||||||
"total_functions": 2,
|
|
||||||
"total_triggers": 2,
|
|
||||||
"total_indexes": 14,
|
|
||||||
"servers": {
|
|
||||||
"architect": {
|
|
||||||
"ip": "69.62.126.110",
|
|
||||||
"status": "deployed",
|
|
||||||
"db_type": "docker",
|
|
||||||
"container": "windmill-db-1"
|
|
||||||
},
|
|
||||||
"corp": {
|
|
||||||
"ip": "92.112.181.188",
|
|
||||||
"status": "deployed",
|
|
||||||
"db_type": "host",
|
|
||||||
"pg_version": "16.11"
|
|
||||||
},
|
|
||||||
"deck": {
|
|
||||||
"ip": "72.62.1.113",
|
|
||||||
"status": "pending",
|
|
||||||
"reason": "ssh_unavailable"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
**Preparado por:** ARCHITECT
|
|
||||||
**Sistema:** TZZR
|
|
||||||
**Timestamp:** 2024-12-24T00:00:00Z
|
|
||||||
@@ -1,152 +0,0 @@
|
|||||||
# Despliegue de Tablas de Contexto IA - TZZR
|
|
||||||
|
|
||||||
**Fecha:** 2024-12-24
|
|
||||||
**Responsable:** ARCHITECT
|
|
||||||
**Estado:** ✅ Completado (2/3 servidores)
|
|
||||||
|
|
||||||
## Resumen
|
|
||||||
|
|
||||||
Se desplegaron exitosamente las tablas de contexto IA en los servidores **architect** y **corp**. El servidor **deck** no estuvo disponible durante el despliegue (SSH connection refused).
|
|
||||||
|
|
||||||
## Servidores Desplegados
|
|
||||||
|
|
||||||
### ✅ architect (69.62.126.110)
|
|
||||||
- **PostgreSQL:** v16.11
|
|
||||||
- **Estado:** Desplegado exitosamente
|
|
||||||
- **Tablas creadas:** 5 tablas + 1 vista
|
|
||||||
- **Triggers:** 2 triggers activos
|
|
||||||
- **Funciones:** 2 funciones PL/pgSQL
|
|
||||||
- **Test:** ✅ Funcionando correctamente
|
|
||||||
|
|
||||||
### ✅ corp (92.112.181.188)
|
|
||||||
- **PostgreSQL:** v16.11
|
|
||||||
- **Estado:** Desplegado exitosamente
|
|
||||||
- **Tablas creadas:** 5 tablas + 1 vista
|
|
||||||
- **Triggers:** 2 triggers activos
|
|
||||||
- **Funciones:** 2 funciones PL/pgSQL
|
|
||||||
- **Test:** ✅ Funcionando correctamente
|
|
||||||
|
|
||||||
### ⚠️ deck (72.62.1.113)
|
|
||||||
- **Estado:** No disponible
|
|
||||||
- **Error:** SSH connection refused
|
|
||||||
- **Acción pendiente:** Verificar conectividad y desplegar cuando esté disponible
|
|
||||||
|
|
||||||
## Estructura de Base de Datos
|
|
||||||
|
|
||||||
### Tablas
|
|
||||||
|
|
||||||
1. **ia_contexts**
|
|
||||||
- Almacena contextos de conversación de agentes IA
|
|
||||||
- Campos: context_id (UNIQUE), agent_name, user_id, session_id, metadata, status
|
|
||||||
- Trigger: Actualiza `updated_at` automáticamente
|
|
||||||
|
|
||||||
2. **ia_messages**
|
|
||||||
- Mensajes de conversación con agentes IA
|
|
||||||
- Campos: context_id, role, content, timestamp, token_count, model, metadata
|
|
||||||
- Trigger: Actualiza métricas de contexto automáticamente
|
|
||||||
|
|
||||||
3. **ia_embeddings**
|
|
||||||
- Embeddings vectoriales para búsqueda semántica
|
|
||||||
- Campos: context_id, message_id, embedding_vector, content_hash
|
|
||||||
|
|
||||||
4. **ia_tool_calls**
|
|
||||||
- Registro de llamadas a herramientas
|
|
||||||
- Campos: context_id, message_id, tool_name, tool_input, tool_output, execution_time_ms, success
|
|
||||||
|
|
||||||
5. **ia_context_metrics**
|
|
||||||
- Métricas agregadas por contexto
|
|
||||||
- Campos: context_id (UNIQUE), total_messages, total_tokens, total_tool_calls, avg_response_time_ms
|
|
||||||
|
|
||||||
### Vista
|
|
||||||
|
|
||||||
- **ia_context_summary**
|
|
||||||
- JOIN de ia_contexts + ia_context_metrics
|
|
||||||
- Proporciona resumen completo de cada contexto
|
|
||||||
|
|
||||||
### Índices
|
|
||||||
|
|
||||||
Se crearon 13 índices para optimizar las siguientes consultas:
|
|
||||||
- Búsqueda por agente
|
|
||||||
- Búsqueda por sesión
|
|
||||||
- Ordenamiento por fecha
|
|
||||||
- Filtrado por estado
|
|
||||||
- Búsqueda por hash de contenido
|
|
||||||
|
|
||||||
## Funciones y Triggers
|
|
||||||
|
|
||||||
### 1. update_ia_contexts_updated_at()
|
|
||||||
- **Trigger:** `trigger_update_ia_contexts_updated_at`
|
|
||||||
- **Evento:** BEFORE UPDATE en ia_contexts
|
|
||||||
- **Función:** Actualiza automáticamente el campo `updated_at`
|
|
||||||
|
|
||||||
### 2. update_ia_context_metrics()
|
|
||||||
- **Trigger:** `trigger_update_ia_context_metrics`
|
|
||||||
- **Evento:** AFTER INSERT en ia_messages
|
|
||||||
- **Función:** Actualiza automáticamente las métricas (total_messages, total_tokens, last_activity)
|
|
||||||
|
|
||||||
## Tests Realizados
|
|
||||||
|
|
||||||
### architect
|
|
||||||
```sql
|
|
||||||
-- Contexto de prueba: test-context-001
|
|
||||||
-- Mensajes insertados: 2
|
|
||||||
-- Métricas actualizadas: ✅ automáticamente
|
|
||||||
-- Última actividad: 2025-12-24 00:07:18
|
|
||||||
```
|
|
||||||
|
|
||||||
### corp
|
|
||||||
```sql
|
|
||||||
-- Contexto de prueba: test-corp-001
|
|
||||||
-- Agente: margaret
|
|
||||||
-- Mensajes insertados: 1
|
|
||||||
-- Métricas actualizadas: ✅ automáticamente
|
|
||||||
```
|
|
||||||
|
|
||||||
## Archivos Desplegados
|
|
||||||
|
|
||||||
1. **Schema principal:** `/home/orchestrator/orchestrator/scripts/ia_context_schema.sql`
|
|
||||||
2. **Script de despliegue:** `/home/orchestrator/orchestrator/scripts/deploy_ia_tables.sh`
|
|
||||||
|
|
||||||
## Correcciones Aplicadas
|
|
||||||
|
|
||||||
Durante el despliegue se identificó y corrigió:
|
|
||||||
- Faltaba constraint UNIQUE en `context_id` de `ia_context_metrics`
|
|
||||||
- Se agregó: `ALTER TABLE ia_context_metrics ADD CONSTRAINT ia_context_metrics_context_id_key UNIQUE (context_id);`
|
|
||||||
|
|
||||||
## Próximos Pasos
|
|
||||||
|
|
||||||
1. ✅ Schema actualizado con UNIQUE constraint
|
|
||||||
2. ⏳ Desplegar en **deck** cuando esté disponible
|
|
||||||
3. ⏳ Integrar tablas con agentes IA del sistema
|
|
||||||
4. ⏳ Implementar almacenamiento de embeddings vectoriales
|
|
||||||
5. ⏳ Crear dashboard de métricas en tiempo real
|
|
||||||
|
|
||||||
## Comandos Útiles
|
|
||||||
|
|
||||||
### Verificar tablas
|
|
||||||
```bash
|
|
||||||
# En architect o corp
|
|
||||||
ssh root@<servidor> "sudo -u postgres psql -c '\dt ia_*'"
|
|
||||||
```
|
|
||||||
|
|
||||||
### Ver resumen de contextos
|
|
||||||
```bash
|
|
||||||
ssh root@<servidor> "sudo -u postgres psql -c 'SELECT * FROM ia_context_summary;'"
|
|
||||||
```
|
|
||||||
|
|
||||||
### Limpiar datos de prueba
|
|
||||||
```sql
|
|
||||||
DELETE FROM ia_contexts WHERE context_id LIKE 'test-%';
|
|
||||||
```
|
|
||||||
|
|
||||||
## Notas
|
|
||||||
|
|
||||||
- Las tablas usan cascadas (ON DELETE CASCADE) para mantener integridad referencial
|
|
||||||
- Los triggers garantizan que las métricas estén siempre actualizadas
|
|
||||||
- La vista ia_context_summary simplifica consultas frecuentes
|
|
||||||
- Los índices están optimizados para las consultas más comunes del sistema
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
**Deployment completado por:** ARCHITECT
|
|
||||||
**Timestamp:** 2025-12-24 00:07:00 UTC
|
|
||||||
@@ -1,32 +0,0 @@
|
|||||||
# Changelog
|
|
||||||
|
|
||||||
## [1.7.4] - 2025-12-23
|
|
||||||
|
|
||||||
### Added
|
|
||||||
- Permisos completos de Android en AndroidManifest.xml:
|
|
||||||
- INTERNET, ACCESS_NETWORK_STATE
|
|
||||||
- CAMERA, RECORD_AUDIO
|
|
||||||
- ACCESS_FINE_LOCATION, ACCESS_COARSE_LOCATION
|
|
||||||
- READ_MEDIA_IMAGES/VIDEO/AUDIO (Android 13+)
|
|
||||||
- READ_EXTERNAL_STORAGE (Android ≤12)
|
|
||||||
- Configuración `android:usesCleartextTraffic="true"` para HTTP
|
|
||||||
|
|
||||||
### Build Info
|
|
||||||
- Flutter 3.38.5 (stable)
|
|
||||||
- Dart 3.10.4
|
|
||||||
- Java OpenJDK 17.0.17
|
|
||||||
- APK Size: 49 MB
|
|
||||||
- SHA-256: `7f57bee3edec7342d6ca78d789704fec3827e3bf85f11ac362dcbacc8371ef1a`
|
|
||||||
|
|
||||||
## [1.0.0] - 2025-12-21
|
|
||||||
|
|
||||||
### Added
|
|
||||||
- Release inicial
|
|
||||||
- 5 pantallas: Captura, Etiquetas, Packs, Pendientes, Config
|
|
||||||
- Arquitectura Clean con BLoC
|
|
||||||
- Soporte offline con cola de reintentos
|
|
||||||
- Integración con backend via API REST
|
|
||||||
- Sistema de etiquetas desde bibliotecas remotas
|
|
||||||
- Captura multimedia (fotos, video, audio, archivos)
|
|
||||||
- GPS location
|
|
||||||
- Hash SHA-256 para contenedores
|
|
||||||
@@ -1,171 +0,0 @@
|
|||||||
# Packet
|
|
||||||
|
|
||||||

|
|
||||||
|
|
||||||
|
|
||||||
App móvil multiplataforma (iOS/Android) para capturar contenido multimedia, etiquetarlo con hashes y enviarlo a backends configurables.
|
|
||||||
|
|
||||||
## Principios
|
|
||||||
|
|
||||||
| Principio | Descripción |
|
|
||||||
|-----------|-------------|
|
|
||||||
| Zero-retention | Los archivos nunca se almacenan en disco, solo en RAM hasta envío |
|
|
||||||
| Hash-first | Todo contenedor tiene hash SHA-256 único generado localmente |
|
|
||||||
| Contenedor cerrado | Una vez montado, no se inspecciona. Solo enviar o desmontar |
|
|
||||||
| App tonta | No valida coherencia de etiquetas, solo formato. El backend decide |
|
|
||||||
| Offline-capable | Captura sin conexión, cola de reintentos cuando hay red |
|
|
||||||
|
|
||||||
## Stack Tecnológico
|
|
||||||
|
|
||||||
| Componente | Tecnología |
|
|
||||||
|------------|------------|
|
|
||||||
| Framework | Flutter 3.x |
|
|
||||||
| Lenguaje | Dart |
|
|
||||||
| Estado | flutter_bloc |
|
|
||||||
| DB Local | sqflite |
|
|
||||||
| HTTP | dio |
|
|
||||||
| Crypto | crypto (SHA-256) |
|
|
||||||
| Media | image_picker, record |
|
|
||||||
| Location | geolocator |
|
|
||||||
| Permisos | permission_handler |
|
|
||||||
|
|
||||||
## Pantallas
|
|
||||||
|
|
||||||
```
|
|
||||||
┌─────────────────────────────────────────┐
|
|
||||||
│ [Mi DECK ▼] [CORP] [+Ext] │ ← Destinos (superior)
|
|
||||||
├─────────────────────────────────────────┤
|
|
||||||
│ CONTENIDO PANTALLA │
|
|
||||||
├─────────────────────────────────────────┤
|
|
||||||
│ 📷 🏷️ 📦 ⏳ ⚙️ │ ← Navegación (inferior)
|
|
||||||
│ Captura Tags Packs Pend. Config │
|
|
||||||
└─────────────────────────────────────────┘
|
|
||||||
```
|
|
||||||
|
|
||||||
### Captura
|
|
||||||
Montar contenedor con contenido multimedia: título, descripción, archivos, GPS, etiquetas.
|
|
||||||
|
|
||||||
### Etiquetas
|
|
||||||
Seleccionar etiquetas de bibliotecas HST/DECK y añadir hashes externos.
|
|
||||||
|
|
||||||
### Packs
|
|
||||||
Conjuntos predefinidos de etiquetas para aplicar con 1 tap.
|
|
||||||
|
|
||||||
### Pendientes
|
|
||||||
Cola de contenedores fallidos (máx 20). App se bloquea si se llena.
|
|
||||||
|
|
||||||
### Config
|
|
||||||
URLs, llaves de autenticación y bibliotecas de iconos.
|
|
||||||
|
|
||||||
Bibliotecas con indicador visual:
|
|
||||||
- 🔓 Pública (sin PIN)
|
|
||||||
- 🔒 Privada (requiere PIN)
|
|
||||||
|
|
||||||
## Estructura del Proyecto
|
|
||||||
|
|
||||||
```
|
|
||||||
lib/
|
|
||||||
├── core/
|
|
||||||
│ ├── constants/ # Constantes de la app
|
|
||||||
│ ├── errors/ # Excepciones personalizadas
|
|
||||||
│ ├── utils/ # Utilidades (hash, retry)
|
|
||||||
│ └── theme/ # Tema de la app
|
|
||||||
├── data/
|
|
||||||
│ ├── datasources/ # APIs y BD local
|
|
||||||
│ └── repositories/ # Repositorios
|
|
||||||
├── domain/
|
|
||||||
│ └── entities/ # Modelos de dominio
|
|
||||||
└── presentation/
|
|
||||||
├── bloc/ # Cubits de estado
|
|
||||||
├── pages/ # Pantallas
|
|
||||||
└── widgets/ # Widgets reutilizables
|
|
||||||
```
|
|
||||||
|
|
||||||
## Build
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Instalar dependencias
|
|
||||||
flutter pub get
|
|
||||||
|
|
||||||
# Build APK
|
|
||||||
flutter build apk --release
|
|
||||||
|
|
||||||
# Build iOS (requiere Xcode)
|
|
||||||
flutter build ios --release
|
|
||||||
```
|
|
||||||
|
|
||||||
## APIs
|
|
||||||
|
|
||||||
### Backend (envío)
|
|
||||||
```http
|
|
||||||
POST {destino.url}/ingest
|
|
||||||
X-Auth-Key: {destino.hash}
|
|
||||||
Content-Type: application/json
|
|
||||||
```
|
|
||||||
|
|
||||||
### Bibliotecas (etiquetas)
|
|
||||||
```http
|
|
||||||
GET {biblioteca.url}/api/biblioteca
|
|
||||||
X-HSU-PIN: {pin} # Solo para bibliotecas privadas
|
|
||||||
```
|
|
||||||
|
|
||||||
**Respuesta:**
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"nombre": "Mi Biblioteca",
|
|
||||||
"requiere_pin": true,
|
|
||||||
"tags": [...]
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
## Base de Datos Local
|
|
||||||
|
|
||||||
SQLite v4 con las siguientes tablas principales:
|
|
||||||
|
|
||||||
**bibliotecas:**
|
|
||||||
| Campo | Tipo | Descripción |
|
|
||||||
|-------|------|-------------|
|
|
||||||
| id | INTEGER | PK autoincrement |
|
|
||||||
| nombre | TEXT | Nombre de la biblioteca |
|
|
||||||
| url | TEXT | URL del servidor |
|
|
||||||
| hash | TEXT | Hash de identificación |
|
|
||||||
| pin | TEXT | PIN para bibliotecas privadas (nullable) |
|
|
||||||
| requiere_pin | INTEGER | 0=pública, 1=privada |
|
|
||||||
|
|
||||||
## Lógica de Reintentos
|
|
||||||
|
|
||||||
20 intentos en 72 horas con backoff exponencial (1min → 8h).
|
|
||||||
|
|
||||||
## Referencias
|
|
||||||
|
|
||||||
- Biblioteca HST: https://tzrtech.org
|
|
||||||
- Especificación completa: [docs/SPEC.md](docs/SPEC.md)
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Changelog
|
|
||||||
|
|
||||||
### v1.7.3 (2025-12-22)
|
|
||||||
- Fix: Añadido permiso INTERNET en AndroidManifest.xml
|
|
||||||
- Fix: Mejor manejo de errores de conexión
|
|
||||||
|
|
||||||
### v1.7.2 (2025-12-22)
|
|
||||||
- Fix: Diálogo de PIN se cierra correctamente al cancelar
|
|
||||||
- Fix: Error de conexión muestra mensaje amigable
|
|
||||||
|
|
||||||
### v1.7.1 (2025-12-22)
|
|
||||||
- Fix: PIN se guarda correctamente en BD local
|
|
||||||
|
|
||||||
### v1.7.0 (2025-12-22)
|
|
||||||
- Feat: Sistema de PIN para bibliotecas privadas
|
|
||||||
- Feat: Header `X-HSU-PIN` para autenticación
|
|
||||||
- Feat: Indicadores visuales 🔒/🔓 para tipo de biblioteca
|
|
||||||
- Feat: Diálogo de PIN al conectar biblioteca privada
|
|
||||||
- Change: Endpoint de bibliotecas ahora es `/api/biblioteca`
|
|
||||||
|
|
||||||
### v1.6.0 (2025-12-22)
|
|
||||||
- Feat: Diálogo simplificado para añadir biblioteca (solo URL)
|
|
||||||
- Change: Nombre y hash se obtienen automáticamente del servidor
|
|
||||||
|
|
||||||
### v1.0.0
|
|
||||||
- Release inicial
|
|
||||||
@@ -1,151 +0,0 @@
|
|||||||
# Packet v1.7.4 - Build Report
|
|
||||||
|
|
||||||
**Fecha:** 2025-12-23
|
|
||||||
**Compilado por:** Claude Code
|
|
||||||
**Plataforma:** macOS Darwin 25.1.0
|
|
||||||
|
|
||||||
## Artefacto
|
|
||||||
|
|
||||||
| Campo | Valor |
|
|
||||||
|-------|-------|
|
|
||||||
| Archivo | `packet-v1.7.4.apk` |
|
|
||||||
| Tamaño | 49 MB |
|
|
||||||
| SHA-256 | `7f57bee3edec7342d6ca78d789704fec3827e3bf85f11ac362dcbacc8371ef1a` |
|
|
||||||
| Firmado | Debug keys |
|
|
||||||
|
|
||||||
## Entorno de Compilación
|
|
||||||
|
|
||||||
### Flutter
|
|
||||||
| Componente | Versión |
|
|
||||||
|------------|---------|
|
|
||||||
| Flutter | 3.38.5 (stable) |
|
|
||||||
| Dart | 3.10.4 |
|
|
||||||
| DevTools | 2.51.1 |
|
|
||||||
| Engine | c108a94d7a |
|
|
||||||
|
|
||||||
### Android
|
|
||||||
| Componente | Valor |
|
|
||||||
|------------|-------|
|
|
||||||
| Java | OpenJDK 17.0.17 |
|
|
||||||
| Package Name | `me.tzzr.packet` |
|
|
||||||
| Label | packet |
|
|
||||||
|
|
||||||
## Permisos Android
|
|
||||||
|
|
||||||
```xml
|
|
||||||
<!-- Network -->
|
|
||||||
<uses-permission android:name="android.permission.INTERNET"/>
|
|
||||||
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
|
|
||||||
|
|
||||||
<!-- Camera and Audio -->
|
|
||||||
<uses-permission android:name="android.permission.CAMERA"/>
|
|
||||||
<uses-permission android:name="android.permission.RECORD_AUDIO"/>
|
|
||||||
|
|
||||||
<!-- Location -->
|
|
||||||
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
|
|
||||||
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
|
|
||||||
|
|
||||||
<!-- Media (Android 13+ / API 33+) -->
|
|
||||||
<uses-permission android:name="android.permission.READ_MEDIA_IMAGES"/>
|
|
||||||
<uses-permission android:name="android.permission.READ_MEDIA_VIDEO"/>
|
|
||||||
<uses-permission android:name="android.permission.READ_MEDIA_AUDIO"/>
|
|
||||||
|
|
||||||
<!-- Storage (Android 12 and below) -->
|
|
||||||
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"
|
|
||||||
android:maxSdkVersion="32"/>
|
|
||||||
```
|
|
||||||
|
|
||||||
**Configuración adicional:**
|
|
||||||
```xml
|
|
||||||
<application android:usesCleartextTraffic="true">
|
|
||||||
```
|
|
||||||
|
|
||||||
## Dependencias
|
|
||||||
|
|
||||||
### Runtime
|
|
||||||
| Paquete | Versión | Propósito |
|
|
||||||
|---------|---------|-----------|
|
|
||||||
| flutter_bloc | ^9.0.0 | State management |
|
|
||||||
| equatable | ^2.0.7 | Value equality |
|
|
||||||
| sqflite | ^2.4.2 | SQLite local DB |
|
|
||||||
| path_provider | ^2.1.5 | File paths |
|
|
||||||
| dio | ^5.7.0 | HTTP client |
|
|
||||||
| crypto | ^3.0.6 | SHA-256 hashing |
|
|
||||||
| image_picker | ^1.1.2 | Captura fotos/video |
|
|
||||||
| record | ^6.0.0 | Grabación audio |
|
|
||||||
| file_picker | ^8.1.7 | Selección archivos |
|
|
||||||
| geolocator | ^13.0.2 | GPS location |
|
|
||||||
| permission_handler | ^11.4.0 | Runtime permissions |
|
|
||||||
| uuid | ^4.5.1 | UUID generation |
|
|
||||||
| intl | ^0.20.2 | Internacionalización |
|
|
||||||
| cached_network_image | ^3.4.1 | Cache de imágenes |
|
|
||||||
|
|
||||||
### Dev
|
|
||||||
| Paquete | Versión |
|
|
||||||
|---------|---------|
|
|
||||||
| flutter_test | SDK |
|
|
||||||
| flutter_lints | ^6.0.0 |
|
|
||||||
|
|
||||||
## Estructura del Proyecto
|
|
||||||
|
|
||||||
```
|
|
||||||
lib/ (3,505 líneas Dart)
|
|
||||||
├── main.dart # Entry point
|
|
||||||
├── core/
|
|
||||||
│ ├── constants/ # AppConstants, RetryDelays
|
|
||||||
│ ├── errors/ # Excepciones
|
|
||||||
│ ├── utils/ # hash_utils, retry_utils
|
|
||||||
│ └── theme/ # AppTheme
|
|
||||||
├── data/
|
|
||||||
│ ├── datasources/ # BackendApi, BibliotecaApi, LocalDatabase
|
|
||||||
│ └── repositories/ # Config, Etiqueta, Contenedor repos
|
|
||||||
├── domain/
|
|
||||||
│ └── entities/ # Contenedor, Etiqueta, Pack, Destino
|
|
||||||
└── presentation/
|
|
||||||
├── app.dart # PacketApp, MainScreen
|
|
||||||
├── bloc/ # Cubits
|
|
||||||
├── pages/ # 5 pantallas
|
|
||||||
└── widgets/ # Componentes
|
|
||||||
```
|
|
||||||
|
|
||||||
## Pantallas
|
|
||||||
|
|
||||||
| # | Pantalla | Icono | Función |
|
|
||||||
|---|----------|-------|---------|
|
|
||||||
| 1 | Captura | 📷 | Montar contenedor multimedia |
|
|
||||||
| 2 | Etiquetas | 🏷️ | Seleccionar tags |
|
|
||||||
| 3 | Packs | 📦 | Conjuntos de etiquetas |
|
|
||||||
| 4 | Pendientes | ⏳ | Cola de reintentos (máx 20) |
|
|
||||||
| 5 | Config | ⚙️ | URLs, llaves, bibliotecas |
|
|
||||||
|
|
||||||
## Constantes
|
|
||||||
|
|
||||||
| Constante | Valor |
|
|
||||||
|-----------|-------|
|
|
||||||
| maxPendientes | 20 |
|
|
||||||
| maxReintentos | 20 |
|
|
||||||
| hashLength | 64 (SHA-256) |
|
|
||||||
| chunkSize | 512 KB |
|
|
||||||
| httpTimeout | 30s |
|
|
||||||
| retryCheckInterval | 30s |
|
|
||||||
|
|
||||||
## Backoff de Reintentos (72h total)
|
|
||||||
|
|
||||||
| Rango | Espera |
|
|
||||||
|-------|--------|
|
|
||||||
| 1-3 | 1, 2, 5 min |
|
|
||||||
| 4-6 | 10, 20, 30 min |
|
|
||||||
| 7-10 | 1, 2, 3, 4 h |
|
|
||||||
| 11-14 | 5, 6, 6, 6 h |
|
|
||||||
| 15-19 | 8, 8, 8, 8, 6 h |
|
|
||||||
| 20 | STOP |
|
|
||||||
|
|
||||||
## Comandos de Build
|
|
||||||
|
|
||||||
```bash
|
|
||||||
export JAVA_HOME=/opt/homebrew/opt/openjdk@17/libexec/openjdk.jdk/Contents/Home
|
|
||||||
cd /tmp/packet-app
|
|
||||||
flutter clean
|
|
||||||
flutter build apk --release
|
|
||||||
cp build/app/outputs/flutter-apk/app-release.apk ~/Downloads/packet-v1.7.4.apk
|
|
||||||
```
|
|
||||||
@@ -1,565 +0,0 @@
|
|||||||
# Packet - Especificación Técnica Completa
|
|
||||||
|
|
||||||
## 1. Visión General
|
|
||||||
|
|
||||||
Packet permite:
|
|
||||||
- Capturar contenido multimedia (fotos, audio, video, archivos)
|
|
||||||
- Etiquetarlo con referencias de bibliotecas externas
|
|
||||||
- Empaquetarlo en contenedores con hash único
|
|
||||||
- Enviarlo a backends configurables
|
|
||||||
|
|
||||||
### Principios
|
|
||||||
|
|
||||||
| Principio | Descripción |
|
|
||||||
|-----------|-------------|
|
|
||||||
| Zero-retention | Los archivos nunca se almacenan en disco, solo en RAM hasta envío |
|
|
||||||
| Hash-first | Todo contenedor tiene hash único generado localmente |
|
|
||||||
| Contenedor cerrado | Una vez montado, no se inspecciona. Solo enviar o desmontar |
|
|
||||||
| App tonta | No valida coherencia de etiquetas, solo formato. El backend decide |
|
|
||||||
| Offline-capable | Captura sin conexión, cola de reintentos cuando hay red |
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 2. Stack Tecnológico
|
|
||||||
|
|
||||||
| Componente | Tecnología |
|
|
||||||
|------------|------------|
|
|
||||||
| Framework | Flutter 3.x |
|
|
||||||
| Lenguaje | Dart |
|
|
||||||
| Estado | flutter_bloc |
|
|
||||||
| DB Local | sqflite |
|
|
||||||
| HTTP | dio |
|
|
||||||
| Crypto | crypto (SHA-256) |
|
|
||||||
| Media | image_picker, record |
|
|
||||||
| Location | geolocator |
|
|
||||||
| Permisos | permission_handler |
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 3. Estructura de Carpetas
|
|
||||||
|
|
||||||
```
|
|
||||||
packet/
|
|
||||||
├── android/
|
|
||||||
├── ios/
|
|
||||||
├── lib/
|
|
||||||
│ ├── core/
|
|
||||||
│ │ ├── constants/
|
|
||||||
│ │ │ └── app_constants.dart
|
|
||||||
│ │ ├── errors/
|
|
||||||
│ │ │ └── exceptions.dart
|
|
||||||
│ │ ├── utils/
|
|
||||||
│ │ │ ├── hash_utils.dart
|
|
||||||
│ │ │ └── retry_utils.dart
|
|
||||||
│ │ └── theme/
|
|
||||||
│ │ └── app_theme.dart
|
|
||||||
│ │
|
|
||||||
│ ├── data/
|
|
||||||
│ │ ├── datasources/
|
|
||||||
│ │ │ ├── local_database.dart
|
|
||||||
│ │ │ ├── backend_api.dart
|
|
||||||
│ │ │ └── biblioteca_api.dart
|
|
||||||
│ │ ├── models/
|
|
||||||
│ │ │ ├── destino_model.dart
|
|
||||||
│ │ │ ├── contenedor_model.dart
|
|
||||||
│ │ │ ├── etiqueta_model.dart
|
|
||||||
│ │ │ └── pack_model.dart
|
|
||||||
│ │ └── repositories/
|
|
||||||
│ │ ├── contenedor_repository.dart
|
|
||||||
│ │ ├── etiqueta_repository.dart
|
|
||||||
│ │ └── config_repository.dart
|
|
||||||
│ │
|
|
||||||
│ ├── domain/
|
|
||||||
│ │ └── entities/
|
|
||||||
│ │ ├── contenedor.dart
|
|
||||||
│ │ ├── etiqueta.dart
|
|
||||||
│ │ ├── pack.dart
|
|
||||||
│ │ ├── destino.dart
|
|
||||||
│ │ └── archivo_adjunto.dart
|
|
||||||
│ │
|
|
||||||
│ ├── presentation/
|
|
||||||
│ │ ├── bloc/
|
|
||||||
│ │ │ ├── captura/
|
|
||||||
│ │ │ ├── etiquetas/
|
|
||||||
│ │ │ ├── packs/
|
|
||||||
│ │ │ ├── pendientes/
|
|
||||||
│ │ │ └── config/
|
|
||||||
│ │ ├── pages/
|
|
||||||
│ │ │ ├── captura_page.dart
|
|
||||||
│ │ │ ├── etiquetas_page.dart
|
|
||||||
│ │ │ ├── packs_page.dart
|
|
||||||
│ │ │ ├── pendientes_page.dart
|
|
||||||
│ │ │ └── config_page.dart
|
|
||||||
│ │ ├── widgets/
|
|
||||||
│ │ │ ├── audio_recorder.dart
|
|
||||||
│ │ │ ├── destino_selector.dart
|
|
||||||
│ │ │ ├── etiqueta_grid.dart
|
|
||||||
│ │ │ └── contenedor_card.dart
|
|
||||||
│ │ └── app.dart
|
|
||||||
│ │
|
|
||||||
│ └── main.dart
|
|
||||||
│
|
|
||||||
├── test/
|
|
||||||
├── pubspec.yaml
|
|
||||||
└── README.md
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 4. Pantallas
|
|
||||||
|
|
||||||
### Navegación
|
|
||||||
|
|
||||||
```
|
|
||||||
┌─────────────────────────────────────────┐
|
|
||||||
│ [Mi DECK ▼] [CORP] [+Ext] │ ← Destinos (superior)
|
|
||||||
├─────────────────────────────────────────┤
|
|
||||||
│ │
|
|
||||||
│ CONTENIDO PANTALLA │
|
|
||||||
│ │
|
|
||||||
├─────────────────────────────────────────┤
|
|
||||||
│ 📷 🏷️ 📦 ⏳ ⚙️ │ ← Navegación (inferior)
|
|
||||||
│ Captura Tags Packs Pend. Config │
|
|
||||||
└─────────────────────────────────────────┘
|
|
||||||
```
|
|
||||||
|
|
||||||
### 4.1 Captura
|
|
||||||
|
|
||||||
Montar contenedor con contenido multimedia.
|
|
||||||
|
|
||||||
Campos:
|
|
||||||
- Título (string, opcional)
|
|
||||||
- Descripción (string, opcional, se procesa en backend)
|
|
||||||
- Identificador (string 64 chars, auto-generado SHA-256)
|
|
||||||
- Archivos (array, opcional)
|
|
||||||
- GPS (lat/long, opcional)
|
|
||||||
- Etiquetas (array de hashes, seleccionadas en pestaña Etiquetas)
|
|
||||||
|
|
||||||
Botones de captura:
|
|
||||||
- 📷 Foto (cámara)
|
|
||||||
- 🎤 Audio (con contador de tiempo)
|
|
||||||
- 🎥 Video
|
|
||||||
- 📎 Archivo
|
|
||||||
- 📍 GPS
|
|
||||||
|
|
||||||
El hash se genera al abrir la app o tras cada envío. Se puede enviar contenedor vacío (solo hash). Botones de copiar y regenerar hash visibles.
|
|
||||||
|
|
||||||
### 4.2 Etiquetas
|
|
||||||
|
|
||||||
Seleccionar etiquetas de bibliotecas y añadir hashes externos.
|
|
||||||
|
|
||||||
Secciones:
|
|
||||||
1. Grid HST - Iconos de biblioteca HST (se oscurecen al seleccionar)
|
|
||||||
2. Grid DECK - Iconos de biblioteca DECK
|
|
||||||
3. Campo hash - Pegar URL o hash externo
|
|
||||||
4. Seleccionadas - Lista de etiquetas actuales con botón eliminar
|
|
||||||
|
|
||||||
Validación de hash externo:
|
|
||||||
1. Usuario pega texto
|
|
||||||
2. App busca patrón: [a-f0-9]{64}
|
|
||||||
3. Por cada match → check verde inmediato
|
|
||||||
4. Background: consulta /api/tags para resolver nombre
|
|
||||||
5. Si encuentra → muestra nombre
|
|
||||||
6. Si no → muestra hash truncado
|
|
||||||
|
|
||||||
### 4.3 Packs
|
|
||||||
|
|
||||||
Conjuntos predefinidos de etiquetas creados localmente.
|
|
||||||
|
|
||||||
- 1 tap → aplica todas las etiquetas del pack
|
|
||||||
- Creación: nombre + etiquetas actualmente seleccionadas
|
|
||||||
- Almacenados en SQLite local
|
|
||||||
|
|
||||||
### 4.4 Pendientes
|
|
||||||
|
|
||||||
Cola de contenedores fallidos. Límite: 20 contenedores máximo. App se bloquea si se llena.
|
|
||||||
|
|
||||||
Por cada contenedor muestra:
|
|
||||||
- Hash (truncado)
|
|
||||||
- Título (o "sin título")
|
|
||||||
- Número de archivos
|
|
||||||
- Intentos realizados (máx 20)
|
|
||||||
- Último intento (hora)
|
|
||||||
- Estado (error / reintentando)
|
|
||||||
|
|
||||||
Acciones:
|
|
||||||
- Reintentar → Intenta enviar de nuevo
|
|
||||||
- Recuperar → Extrae archivos al almacenamiento del dispositivo y elimina contenedor
|
|
||||||
|
|
||||||
### 4.5 Config
|
|
||||||
|
|
||||||
URLs, llaves y bibliotecas.
|
|
||||||
|
|
||||||
Por cada destino:
|
|
||||||
- Nombre (identificador visual)
|
|
||||||
- URL Backend (endpoint de envío)
|
|
||||||
- Llave (hash de 64 chars para autenticación)
|
|
||||||
|
|
||||||
Bibliotecas de iconos:
|
|
||||||
- URL (dominio)
|
|
||||||
- Endpoint (ruta del índice, ej: /api/tags)
|
|
||||||
- Nombre (identificador visual)
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 5. Modelos de Datos
|
|
||||||
|
|
||||||
### Contenedor
|
|
||||||
|
|
||||||
```dart
|
|
||||||
class Contenedor {
|
|
||||||
String hash; // 64 chars, generado localmente
|
|
||||||
String? titulo;
|
|
||||||
String? descripcion;
|
|
||||||
List<ArchivoAdjunto> archivos;
|
|
||||||
GpsLocation? gps;
|
|
||||||
List<String> etiquetas; // Lista de hashes
|
|
||||||
DateTime createdAt;
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
### Etiqueta
|
|
||||||
|
|
||||||
```dart
|
|
||||||
class Etiqueta {
|
|
||||||
String hMaestro; // Hash único (64 chars)
|
|
||||||
String hGlobal; // biblioteca + etiqueta (128 chars)
|
|
||||||
String? mrf; // Media reference para imagen
|
|
||||||
String? ref; // Código corto
|
|
||||||
String? nombreEs;
|
|
||||||
String? nombreEn;
|
|
||||||
String grupo;
|
|
||||||
bool activo;
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
### Destino
|
|
||||||
|
|
||||||
```dart
|
|
||||||
class Destino {
|
|
||||||
int id;
|
|
||||||
String nombre;
|
|
||||||
String url;
|
|
||||||
String hash; // Llave de autenticación
|
|
||||||
bool activo;
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
### Pack
|
|
||||||
|
|
||||||
```dart
|
|
||||||
class Pack {
|
|
||||||
int id;
|
|
||||||
String nombre;
|
|
||||||
String icono;
|
|
||||||
List<String> tags; // Lista de hashes
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
### ArchivoAdjunto
|
|
||||||
|
|
||||||
```dart
|
|
||||||
class ArchivoAdjunto {
|
|
||||||
String nombre;
|
|
||||||
String mimeType;
|
|
||||||
Uint8List bytes; // En memoria, nunca en disco
|
|
||||||
FileType tipo; // image, audio, video, document
|
|
||||||
String? hash;
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 6. Base de Datos SQLite
|
|
||||||
|
|
||||||
```sql
|
|
||||||
CREATE TABLE registro (
|
|
||||||
hash TEXT PRIMARY KEY,
|
|
||||||
titulo TEXT,
|
|
||||||
hora_envio TEXT NOT NULL,
|
|
||||||
primera_conf TEXT,
|
|
||||||
ultima_conf TEXT,
|
|
||||||
destino_id INTEGER
|
|
||||||
);
|
|
||||||
|
|
||||||
CREATE TABLE destinos (
|
|
||||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
||||||
nombre TEXT NOT NULL,
|
|
||||||
url TEXT NOT NULL,
|
|
||||||
hash TEXT NOT NULL,
|
|
||||||
activo INTEGER DEFAULT 1
|
|
||||||
);
|
|
||||||
|
|
||||||
CREATE TABLE bibliotecas (
|
|
||||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
||||||
nombre TEXT NOT NULL,
|
|
||||||
url TEXT NOT NULL,
|
|
||||||
endpoint TEXT NOT NULL,
|
|
||||||
h_biblioteca TEXT
|
|
||||||
);
|
|
||||||
|
|
||||||
CREATE TABLE etiquetas_cache (
|
|
||||||
h_maestro TEXT PRIMARY KEY,
|
|
||||||
h_global TEXT,
|
|
||||||
mrf TEXT,
|
|
||||||
ref TEXT,
|
|
||||||
nombre_es TEXT,
|
|
||||||
nombre_en TEXT,
|
|
||||||
grupo TEXT,
|
|
||||||
biblioteca_id INTEGER
|
|
||||||
);
|
|
||||||
|
|
||||||
CREATE TABLE packs (
|
|
||||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
||||||
nombre TEXT NOT NULL,
|
|
||||||
icono TEXT DEFAULT 📦,
|
|
||||||
tags TEXT NOT NULL
|
|
||||||
);
|
|
||||||
|
|
||||||
CREATE TABLE pendientes (
|
|
||||||
hash TEXT PRIMARY KEY,
|
|
||||||
titulo TEXT,
|
|
||||||
contenido BLOB NOT NULL,
|
|
||||||
intentos INTEGER DEFAULT 0,
|
|
||||||
ultimo_intento TEXT,
|
|
||||||
proximo_intento TEXT,
|
|
||||||
destino_id INTEGER
|
|
||||||
);
|
|
||||||
|
|
||||||
CREATE TABLE app_state (
|
|
||||||
key TEXT PRIMARY KEY,
|
|
||||||
value TEXT
|
|
||||||
);
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 7. APIs Externas
|
|
||||||
|
|
||||||
### Backend (envío)
|
|
||||||
|
|
||||||
```http
|
|
||||||
POST {destino.url}/ingest
|
|
||||||
X-Auth-Key: {destino.hash}
|
|
||||||
Content-Type: application/json
|
|
||||||
|
|
||||||
{
|
|
||||||
"hash": "fc2fae65158ca7c1880dd3ff9b8ed9081107b50f9cdce08df30234fe166777ce",
|
|
||||||
"titulo": "ferr-23",
|
|
||||||
"descripcion": "Compra en ferretería",
|
|
||||||
"etiquetas": ["a1b2c3d4...fc2fae65...", "a1b2c3d4...b2c3d4e5..."],
|
|
||||||
"gps": {"lat": 43.3623, "long": -8.4115},
|
|
||||||
"archivos": [{"nombre": "foto.jpg", "tipo": "image/jpeg", "contenido": "base64..."}]
|
|
||||||
}
|
|
||||||
|
|
||||||
Response 200: { "ok": true, "received_at": "2024-12-20T10:00:00Z" }
|
|
||||||
Response 409: { "error": "hash_exists" }
|
|
||||||
```
|
|
||||||
|
|
||||||
### Envío por chunks (archivos grandes)
|
|
||||||
|
|
||||||
```http
|
|
||||||
POST {destino.url}/upload/init
|
|
||||||
{ "hash": "...", "total_chunks": 50, "file_name": "video.mp4" }
|
|
||||||
→ { "upload_id": "..." }
|
|
||||||
|
|
||||||
POST {destino.url}/upload/chunk/{upload_id}/{chunk_number}
|
|
||||||
Body: bytes (512KB - 1MB por chunk)
|
|
||||||
→ { "ok": true }
|
|
||||||
|
|
||||||
POST {destino.url}/upload/complete/{upload_id}
|
|
||||||
→ { "ok": true, "file_hash": "..." }
|
|
||||||
```
|
|
||||||
|
|
||||||
### Bibliotecas (índice de etiquetas)
|
|
||||||
|
|
||||||
```http
|
|
||||||
GET {biblioteca.url}/api/tags
|
|
||||||
|
|
||||||
Response:
|
|
||||||
{
|
|
||||||
"count": 973,
|
|
||||||
"biblioteca": {
|
|
||||||
"h_biblioteca": "b7149f9e2106c566032aeb29a26e4c6cdd5f5c16b4421025c58166ee345740d1",
|
|
||||||
"nombre": "HST",
|
|
||||||
"publica": true
|
|
||||||
},
|
|
||||||
"results": [
|
|
||||||
{
|
|
||||||
"h_maestro": "fc2fae65...77ce",
|
|
||||||
"h_global": "b7149f9e...fc2fae65...77ce",
|
|
||||||
"mrf": "502dc114...",
|
|
||||||
"ref": "inv",
|
|
||||||
"nombre_es": "factura",
|
|
||||||
"nombre_en": "invoice",
|
|
||||||
"grupo": "hst",
|
|
||||||
"imagen_url": "https://tzrtech.org/502dc...png",
|
|
||||||
"activo": true
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
Imágenes: GET {biblioteca.url}/{mrf}.png
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 8. Formato de Referencias
|
|
||||||
|
|
||||||
Hash simple (etiqueta): 64 caracteres hex
|
|
||||||
```
|
|
||||||
fc2fae65158ca7c1880dd3ff9b8ed9081107b50f9cdce08df30234fe166777ce
|
|
||||||
```
|
|
||||||
|
|
||||||
Referencia global (biblioteca + etiqueta): 128 caracteres
|
|
||||||
```
|
|
||||||
[h_biblioteca 64 chars][h_etiqueta 64 chars]
|
|
||||||
```
|
|
||||||
|
|
||||||
Cadena jerárquica: múltiplo de 64, sin separador
|
|
||||||
```
|
|
||||||
[biblioteca][nivel1][nivel2][nivel3]...
|
|
||||||
```
|
|
||||||
|
|
||||||
Múltiples cadenas: separadas por \\n
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 9. Lógica de Reintentos
|
|
||||||
|
|
||||||
20 intentos en 72 horas con backoff exponencial:
|
|
||||||
|
|
||||||
| Intento | Espera | Acumulado |
|
|
||||||
|---------|--------|-----------|
|
|
||||||
| 1 | 1 min | 0 |
|
|
||||||
| 2 | 2 min | 1 min |
|
|
||||||
| 3 | 5 min | 3 min |
|
|
||||||
| 4 | 10 min | 8 min |
|
|
||||||
| 5 | 20 min | 18 min |
|
|
||||||
| 6 | 30 min | 38 min |
|
|
||||||
| 7 | 1 h | 1 h |
|
|
||||||
| 8 | 2 h | 2 h |
|
|
||||||
| 9 | 3 h | 4 h |
|
|
||||||
| 10 | 4 h | 7 h |
|
|
||||||
| 11 | 5 h | 11 h |
|
|
||||||
| 12 | 6 h | 16 h |
|
|
||||||
| 13 | 6 h | 22 h |
|
|
||||||
| 14 | 6 h | 28 h |
|
|
||||||
| 15 | 8 h | 34 h |
|
|
||||||
| 16 | 8 h | 42 h |
|
|
||||||
| 17 | 8 h | 50 h |
|
|
||||||
| 18 | 8 h | 58 h |
|
|
||||||
| 19 | 6 h | 66 h |
|
|
||||||
| 20 | STOP | 72 h |
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 10. Persistencia de Estado
|
|
||||||
|
|
||||||
La app restaura al abrir exactamente como se cerró:
|
|
||||||
- Destino seleccionado
|
|
||||||
- Pantalla activa
|
|
||||||
- Contenedor en progreso
|
|
||||||
- Etiquetas seleccionadas
|
|
||||||
- Cola de pendientes
|
|
||||||
- Configuración completa
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 11. Permisos
|
|
||||||
|
|
||||||
Android:
|
|
||||||
```xml
|
|
||||||
<uses-permission android:name="android.permission.INTERNET"/>
|
|
||||||
<uses-permission android:name="android.permission.CAMERA"/>
|
|
||||||
<uses-permission android:name="android.permission.RECORD_AUDIO"/>
|
|
||||||
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
|
|
||||||
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
|
|
||||||
```
|
|
||||||
|
|
||||||
iOS:
|
|
||||||
```xml
|
|
||||||
<key>NSCameraUsageDescription</key>
|
|
||||||
<string>Para capturar fotos y videos</string>
|
|
||||||
<key>NSMicrophoneUsageDescription</key>
|
|
||||||
<string>Para grabar notas de voz</string>
|
|
||||||
<key>NSLocationWhenInUseUsageDescription</key>
|
|
||||||
<string>Para añadir ubicación a los contenedores</string>
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 12. CI/CD
|
|
||||||
|
|
||||||
```yaml
|
|
||||||
name: Build
|
|
||||||
|
|
||||||
on:
|
|
||||||
push:
|
|
||||||
branches: [main, develop]
|
|
||||||
pull_request:
|
|
||||||
branches: [main]
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
test:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v3
|
|
||||||
- uses: subosito/flutter-action@v2
|
|
||||||
- run: flutter pub get
|
|
||||||
- run: flutter test
|
|
||||||
|
|
||||||
build-android:
|
|
||||||
needs: test
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v3
|
|
||||||
- uses: subosito/flutter-action@v2
|
|
||||||
- run: flutter build apk --release
|
|
||||||
|
|
||||||
build-ios:
|
|
||||||
needs: test
|
|
||||||
runs-on: macos-latest
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v3
|
|
||||||
- uses: subosito/flutter-action@v2
|
|
||||||
- run: flutter build ios --release --no-codesign
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 13. Roadmap
|
|
||||||
|
|
||||||
### v1.0 (MVP)
|
|
||||||
- 5 pantallas básicas
|
|
||||||
- Captura foto/audio/video
|
|
||||||
- Envío a backend único
|
|
||||||
- Cola de pendientes
|
|
||||||
- Packs locales
|
|
||||||
|
|
||||||
### v1.1
|
|
||||||
- Múltiples destinos
|
|
||||||
- Envío por chunks
|
|
||||||
- Cache de bibliotecas
|
|
||||||
|
|
||||||
### v1.2
|
|
||||||
- Notificaciones push
|
|
||||||
- Widgets de acceso rápido
|
|
||||||
|
|
||||||
### v2.0
|
|
||||||
- Credenciales para bibliotecas privadas
|
|
||||||
- Cadenas jerárquicas visuales
|
|
||||||
- Sincronización entre dispositivos
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 14. Referencias
|
|
||||||
|
|
||||||
- Biblioteca HST: https://tzrtech.org
|
|
||||||
- API HST: https://tzrtech.org/api/tags
|
|
||||||
- h_biblioteca HST: b7149f9e2106c566032aeb29a26e4c6cdd5f5c16b4421025c58166ee345740d1
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
Versión: 1.0
|
|
||||||
Fecha: 2025-12-20
|
|
||||||
@@ -1,49 +0,0 @@
|
|||||||
# PENNY - Personal ENgaging Natural Yielder
|
|
||||||
|
|
||||||
## Descripción
|
|
||||||
Asistente de voz conversacional que orquesta GRACE y Claude API.
|
|
||||||
|
|
||||||
## Endpoint RunPod
|
|
||||||
- ID: `0mxhaokgsmgee3`
|
|
||||||
- URL: `https://api.runpod.ai/v2/0mxhaokgsmgee3/runsync`
|
|
||||||
- Workers: 2
|
|
||||||
- GPU: NVIDIA L4
|
|
||||||
|
|
||||||
## Código
|
|
||||||
Ubicación: `s3://architect/gpu-services/penny/code/handler.py`
|
|
||||||
|
|
||||||
## Flujo
|
|
||||||
```
|
|
||||||
Audio → PENNY → GRACE/ASR → Claude API → GRACE/TTS → Audio
|
|
||||||
↓
|
|
||||||
CLARA (contexto)
|
|
||||||
```
|
|
||||||
|
|
||||||
## Uso
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"input": {
|
|
||||||
"audio_base64": "...",
|
|
||||||
"session_id": "user_123",
|
|
||||||
"language": "es",
|
|
||||||
"personality": "...",
|
|
||||||
"voice_id": "default"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
## Respuesta
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"text_input": "lo que dijo el usuario",
|
|
||||||
"text_output": "respuesta de Claude",
|
|
||||||
"audio_base64": "audio de respuesta",
|
|
||||||
"trace_id": "...",
|
|
||||||
"session_id": "user_123"
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
## Dependencias
|
|
||||||
- GRACE (ASR/TTS)
|
|
||||||
- CLARA (contexto)
|
|
||||||
- Claude API
|
|
||||||
@@ -1,670 +0,0 @@
|
|||||||
# PENNY — Asistente Personal de Voz
|
|
||||||
|
|
||||||
**Especificación Técnica v1.0**
|
|
||||||
**Componente del Sistema DECK**
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 1. Definición
|
|
||||||
|
|
||||||
### 1.1 ¿Qué es PENNY?
|
|
||||||
|
|
||||||
PENNY es el **asistente personal de voz** del DECK. Interfaz conversacional hablada 100% natural.
|
|
||||||
|
|
||||||
```
|
|
||||||
┌─────────────────────────────────────────────────────────────────────┐
|
|
||||||
│ PENNY │
|
|
||||||
│ │
|
|
||||||
│ • ES la voz del DECK │
|
|
||||||
│ • ES la interfaz hablada con el usuario │
|
|
||||||
│ • ES quien llama a GRACE cuando necesita datos │
|
|
||||||
│ • HABLA con el usuario (GRACE no puede) │
|
|
||||||
│ • REGISTRA todo en el log (planos de información) │
|
|
||||||
│ │
|
|
||||||
│ "PENNY habla, GRACE procesa, el Log recuerda." │
|
|
||||||
│ │
|
|
||||||
└─────────────────────────────────────────────────────────────────────┘
|
|
||||||
```
|
|
||||||
|
|
||||||
### 1.2 Principios
|
|
||||||
|
|
||||||
| Principio | Descripción |
|
|
||||||
|-----------|-------------|
|
|
||||||
| **Privacidad radical** | Modelos autoalojados, zero retención en proceso |
|
|
||||||
| **Conversación natural** | Turnos fluidos, interrupciones, latencia <2s |
|
|
||||||
| **Log como verdad** | Todo persiste en DECK, incluyendo personalidad |
|
|
||||||
| **Planos separados** | Contextos cargables independientemente |
|
|
||||||
| **Proceso stateless** | Servidor remoto no guarda nada |
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 2. Arquitectura
|
|
||||||
|
|
||||||
### 2.1 Diagrama General
|
|
||||||
|
|
||||||
```
|
|
||||||
┌─────────────────────────────────────────────────────────────────────┐
|
|
||||||
│ SERVIDOR DE PROCESO (Remoto) │
|
|
||||||
│ GPU potente · Pago por uso · ZERO RETENCIÓN │
|
|
||||||
├─────────────────────────────────────────────────────────────────────┤
|
|
||||||
│ │
|
|
||||||
│ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐ │
|
|
||||||
│ │ Silero │─▶│ Whisper │─▶│ LLM │─▶│ TTS │ │
|
|
||||||
│ │ VAD │ │ Large │ │ (local) │ │ │ │
|
|
||||||
│ └──────────┘ └──────────┘ └──────────┘ └──────────┘ │
|
|
||||||
│ │
|
|
||||||
│ Modelos cargados desde almacenamiento ─── NO guardan estado │
|
|
||||||
│ Al terminar sesión: memoria volátil borrada │
|
|
||||||
│ │
|
|
||||||
└─────────────────────────────────────────────────────────────────────┘
|
|
||||||
▲ │
|
|
||||||
│ Audio + Planos │ Audio + Datos
|
|
||||||
│ ▼
|
|
||||||
┌─────────────────────────────────────────────────────────────────────┐
|
|
||||||
│ DECK │
|
|
||||||
│ Servidor Personal │
|
|
||||||
├─────────────────────────────────────────────────────────────────────┤
|
|
||||||
│ │
|
|
||||||
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
|
|
||||||
│ │ PLANOS │ │ GRACE │ │ THE VAULT │ │
|
|
||||||
│ │ (Log) │ │ (Contrato │ │ (Recados) │ │
|
|
||||||
│ │ │ │ Común) │ │ │ │
|
|
||||||
│ └─────────────┘ └─────────────┘ └─────────────┘ │
|
|
||||||
│ │
|
|
||||||
│ Única ubicación con persistencia │
|
|
||||||
│ │
|
|
||||||
└─────────────────────────────────────────────────────────────────────┘
|
|
||||||
```
|
|
||||||
|
|
||||||
### 2.2 Separación de Responsabilidades
|
|
||||||
|
|
||||||
| Ubicación | Responsabilidad | Persistencia |
|
|
||||||
|-----------|-----------------|--------------|
|
|
||||||
| **Servidor Proceso** | VAD, ASR, LLM, TTS | NINGUNA |
|
|
||||||
| **DECK** | Planos, Log, GRACE, Vault | TOTAL |
|
|
||||||
|
|
||||||
### 2.3 Flujo Voice-to-Voice
|
|
||||||
|
|
||||||
```
|
|
||||||
DECK SERVIDOR PROCESO
|
|
||||||
│ │
|
|
||||||
│──── Audio + Planos ──────────────▶│
|
|
||||||
│ │
|
|
||||||
│ 1. VAD detecta voz
|
|
||||||
│ 2. ASR transcribe
|
|
||||||
│ 3. LLM genera respuesta
|
|
||||||
│ 4. TTS sintetiza
|
|
||||||
│ │
|
|
||||||
│◀──── Audio + Datos ──────────────│
|
|
||||||
│ │
|
|
||||||
│ (memoria borrada)
|
|
||||||
│
|
|
||||||
├── Log registra turno
|
|
||||||
├── GRACE procesa si necesario
|
|
||||||
└── Vault guarda si recado
|
|
||||||
```
|
|
||||||
|
|
||||||
### 2.4 Zero Retención en Proceso
|
|
||||||
|
|
||||||
```
|
|
||||||
┌─────────────────────────────────────────────────────────────────────┐
|
|
||||||
│ POLÍTICA ZERO RETENCIÓN │
|
|
||||||
├─────────────────────────────────────────────────────────────────────┤
|
|
||||||
│ │
|
|
||||||
│ SERVIDOR DE PROCESO: │
|
|
||||||
│ │
|
|
||||||
│ ✗ NO guarda audio de entrada │
|
|
||||||
│ ✗ NO guarda transcripciones │
|
|
||||||
│ ✗ NO guarda prompts ni respuestas │
|
|
||||||
│ ✗ NO guarda contexto entre sesiones │
|
|
||||||
│ ✗ NO tiene logs persistentes │
|
|
||||||
│ │
|
|
||||||
│ ✓ Modelos cargados desde almacenamiento (solo lectura) │
|
|
||||||
│ ✓ Procesamiento en memoria volátil │
|
|
||||||
│ ✓ Al terminar: todo descartado │
|
|
||||||
│ │
|
|
||||||
│ DECK: │
|
|
||||||
│ │
|
|
||||||
│ ✓ Único lugar con persistencia │
|
|
||||||
│ ✓ Log completo de conversaciones │
|
|
||||||
│ ✓ Planos de información │
|
|
||||||
│ ✓ Control total del usuario sobre sus datos │
|
|
||||||
│ │
|
|
||||||
└─────────────────────────────────────────────────────────────────────┘
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 3. Planos de Información
|
|
||||||
|
|
||||||
Todo persiste en DECK. Los planos se envían al servidor de proceso en cada sesión.
|
|
||||||
|
|
||||||
### 3.1 Estructura de Planos
|
|
||||||
|
|
||||||
```
|
|
||||||
┌─────────────────────────────────────────────────────────────────────┐
|
|
||||||
│ PLANO 0: SISTEMA INMUTABLE │
|
|
||||||
│ Capacidades, limitaciones, reglas fundamentales │
|
|
||||||
├─────────────────────────────────────────────────────────────────────┤
|
|
||||||
│ PLANO 1: PERSONALIDAD CONFIGURABLE │
|
|
||||||
│ Nombre, tono, estilo, configuración voz │
|
|
||||||
├─────────────────────────────────────────────────────────────────────┤
|
|
||||||
│ PLANO 2: CONTEXTO PERSONAL PERSISTENTE │
|
|
||||||
│ Info usuario, preferencias, historial │
|
|
||||||
├─────────────────────────────────────────────────────────────────────┤
|
|
||||||
│ PLANO 3: CONTEXTO AMBIENTAL DINÁMICO │
|
|
||||||
│ Fecha, hora, estado sistema, recados pendientes │
|
|
||||||
├─────────────────────────────────────────────────────────────────────┤
|
|
||||||
│ PLANO 4: DATASET BAJO DEMANDA │
|
|
||||||
│ Datos específicos de tarea (catálogos, documentos) │
|
|
||||||
├─────────────────────────────────────────────────────────────────────┤
|
|
||||||
│ PLANO 5: CONVERSACIÓN VOLÁTIL │
|
|
||||||
│ Historial de sesión actual │
|
|
||||||
└─────────────────────────────────────────────────────────────────────┘
|
|
||||||
```
|
|
||||||
|
|
||||||
### 3.2 Definición de Planos
|
|
||||||
|
|
||||||
#### PLANO 0: SISTEMA
|
|
||||||
```yaml
|
|
||||||
plano: SISTEMA
|
|
||||||
persistencia: permanente
|
|
||||||
modificable: false
|
|
||||||
|
|
||||||
contenido:
|
|
||||||
version: "1.0"
|
|
||||||
nombre_asistente: "Penny"
|
|
||||||
capacidades:
|
|
||||||
- conversacion_natural
|
|
||||||
- gestion_recados
|
|
||||||
- consulta_datos_via_grace
|
|
||||||
limitaciones:
|
|
||||||
- no_modifica_datos_directamente
|
|
||||||
- no_ejecuta_acciones_externas
|
|
||||||
reglas:
|
|
||||||
- respuestas_concisas_max_3_oraciones
|
|
||||||
- confirmar_antes_de_crear_recados
|
|
||||||
- nunca_inventar_datos
|
|
||||||
```
|
|
||||||
|
|
||||||
#### PLANO 1: PERSONALIDAD
|
|
||||||
```yaml
|
|
||||||
plano: PERSONALIDAD
|
|
||||||
persistencia: permanente
|
|
||||||
modificable: true
|
|
||||||
|
|
||||||
contenido:
|
|
||||||
nombre: "Penny"
|
|
||||||
tono: "Cercano pero profesional"
|
|
||||||
estilo: "Directo, sin rodeos"
|
|
||||||
tratamiento: "Tuteo natural"
|
|
||||||
muletillas_evitar:
|
|
||||||
- "¡Claro que sí!"
|
|
||||||
- "¡Por supuesto!"
|
|
||||||
voz:
|
|
||||||
speaker_reference: "penny_base"
|
|
||||||
idioma: "es"
|
|
||||||
```
|
|
||||||
|
|
||||||
#### PLANO 2: CONTEXTO PERSONAL
|
|
||||||
```yaml
|
|
||||||
plano: CONTEXTO_PERSONAL
|
|
||||||
persistencia: permanente
|
|
||||||
modificable: true
|
|
||||||
player_id: "uuid-usuario"
|
|
||||||
|
|
||||||
contenido:
|
|
||||||
nombre_usuario: "Carlos"
|
|
||||||
preferencias:
|
|
||||||
formato_hora: "24h"
|
|
||||||
formato_fecha: "dd/mm/yyyy"
|
|
||||||
recordar:
|
|
||||||
- "Prefiere respuestas cortas"
|
|
||||||
- "Reuniones los lunes por la mañana"
|
|
||||||
```
|
|
||||||
|
|
||||||
#### PLANO 3: CONTEXTO AMBIENTAL
|
|
||||||
```yaml
|
|
||||||
plano: CONTEXTO_AMBIENTAL
|
|
||||||
persistencia: sesion
|
|
||||||
modificable: auto
|
|
||||||
|
|
||||||
contenido:
|
|
||||||
fecha: "2025-12-16"
|
|
||||||
hora: "10:30"
|
|
||||||
dia_semana: "martes"
|
|
||||||
recados_pendientes: 3
|
|
||||||
eventos_hoy:
|
|
||||||
- "14:00 - Llamada cliente"
|
|
||||||
```
|
|
||||||
|
|
||||||
#### PLANO 4: DATASET
|
|
||||||
```yaml
|
|
||||||
plano: DATASET
|
|
||||||
persistencia: sesion
|
|
||||||
carga: bajo_demanda
|
|
||||||
|
|
||||||
contenido:
|
|
||||||
tipo: "catalogo_productos"
|
|
||||||
fuente: "catalogo_2025"
|
|
||||||
registros: 1547
|
|
||||||
```
|
|
||||||
|
|
||||||
#### PLANO 5: CONVERSACIÓN
|
|
||||||
```yaml
|
|
||||||
plano: CONVERSACION
|
|
||||||
persistencia: sesion
|
|
||||||
modificable: append_only
|
|
||||||
|
|
||||||
contenido:
|
|
||||||
sesion_id: "uuid"
|
|
||||||
turnos:
|
|
||||||
- turno: 1
|
|
||||||
rol: "usuario"
|
|
||||||
texto: "¿Qué tengo pendiente?"
|
|
||||||
timestamp: "2025-12-16T10:25:15Z"
|
|
||||||
- turno: 2
|
|
||||||
rol: "penny"
|
|
||||||
texto: "Tienes 3 recados pendientes..."
|
|
||||||
latencia_ms: 1850
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 4. Estructura del Log
|
|
||||||
|
|
||||||
### 4.1 Tabla: PENNY_LOG
|
|
||||||
|
|
||||||
```sql
|
|
||||||
CREATE TABLE penny_log (
|
|
||||||
id UUID PRIMARY KEY,
|
|
||||||
sesion_id UUID NOT NULL,
|
|
||||||
turno_index INTEGER NOT NULL,
|
|
||||||
|
|
||||||
-- Timing
|
|
||||||
timestamp_inicio TIMESTAMPTZ NOT NULL,
|
|
||||||
timestamp_fin TIMESTAMPTZ,
|
|
||||||
|
|
||||||
-- Contenido
|
|
||||||
rol VARCHAR(10) CHECK (rol IN ('usuario', 'penny', 'sistema')),
|
|
||||||
texto TEXT NOT NULL,
|
|
||||||
texto_hash VARCHAR(64),
|
|
||||||
|
|
||||||
-- Audio (referencia local en DECK)
|
|
||||||
audio_ref VARCHAR(255),
|
|
||||||
audio_duracion_ms INTEGER,
|
|
||||||
|
|
||||||
-- Métricas
|
|
||||||
latencia_total_ms INTEGER,
|
|
||||||
latencia_asr_ms INTEGER,
|
|
||||||
latencia_llm_ms INTEGER,
|
|
||||||
latencia_tts_ms INTEGER,
|
|
||||||
tokens_prompt INTEGER,
|
|
||||||
tokens_respuesta INTEGER,
|
|
||||||
|
|
||||||
-- Trazabilidad
|
|
||||||
trace_id UUID,
|
|
||||||
grace_llamadas JSONB DEFAULT '[]',
|
|
||||||
planos_activos JSONB NOT NULL,
|
|
||||||
|
|
||||||
-- Estado
|
|
||||||
interrumpido BOOLEAN DEFAULT false
|
|
||||||
);
|
|
||||||
```
|
|
||||||
|
|
||||||
### 4.2 Tabla: PENNY_PLANOS
|
|
||||||
|
|
||||||
```sql
|
|
||||||
CREATE TABLE penny_planos (
|
|
||||||
id UUID PRIMARY KEY,
|
|
||||||
plano_tipo VARCHAR(50) NOT NULL,
|
|
||||||
plano_version VARCHAR(20) NOT NULL,
|
|
||||||
player_id UUID,
|
|
||||||
contenido JSONB NOT NULL,
|
|
||||||
contenido_hash VARCHAR(64),
|
|
||||||
fecha_modificacion TIMESTAMPTZ DEFAULT NOW(),
|
|
||||||
activo BOOLEAN DEFAULT true
|
|
||||||
);
|
|
||||||
```
|
|
||||||
|
|
||||||
### 4.3 Tabla: PENNY_SESIONES
|
|
||||||
|
|
||||||
```sql
|
|
||||||
CREATE TABLE penny_sesiones (
|
|
||||||
id UUID PRIMARY KEY,
|
|
||||||
player_id UUID NOT NULL,
|
|
||||||
inicio TIMESTAMPTZ NOT NULL,
|
|
||||||
fin TIMESTAMPTZ,
|
|
||||||
total_turnos INTEGER DEFAULT 0,
|
|
||||||
planos_cargados JSONB NOT NULL,
|
|
||||||
resumen TEXT,
|
|
||||||
estado VARCHAR(20) DEFAULT 'activa'
|
|
||||||
);
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 5. Integración con GRACE
|
|
||||||
|
|
||||||
### 5.1 Principio
|
|
||||||
|
|
||||||
```
|
|
||||||
PENNY puede HABLAR GRACE puede PROCESAR
|
|
||||||
PENNY no puede PROCESAR GRACE no puede HABLAR
|
|
||||||
|
|
||||||
Cuando PENNY necesita datos → llama a GRACE con Contrato Común
|
|
||||||
```
|
|
||||||
|
|
||||||
### 5.2 Módulos Invocables
|
|
||||||
|
|
||||||
| Módulo | Cuándo |
|
|
||||||
|--------|--------|
|
|
||||||
| `FIELD_EXTRACTOR` | "¿Qué dice esta factura?" |
|
|
||||||
| `SUMMARIZER` | "Resume este documento" |
|
|
||||||
| `CLASSIFIER` | "¿De qué tipo es este email?" |
|
|
||||||
| `TASK_DETECTOR` | "¿Qué tareas hay en esta reunión?" |
|
|
||||||
|
|
||||||
### 5.3 Formato de Llamada
|
|
||||||
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"contract_version": "1.2",
|
|
||||||
"envelope": {
|
|
||||||
"trace_id": "penny-trace-uuid",
|
|
||||||
"parent_trace_id": "sesion-uuid",
|
|
||||||
"timestamp_init": "2025-12-16T10:26:00Z",
|
|
||||||
"ttl_ms": 10000
|
|
||||||
},
|
|
||||||
"routing": {
|
|
||||||
"module": "FIELD_EXTRACTOR",
|
|
||||||
"provider_preference": ["local"]
|
|
||||||
},
|
|
||||||
"context": {
|
|
||||||
"lang": "es",
|
|
||||||
"caller": "PENNY",
|
|
||||||
"caller_sesion": "uuid-sesion"
|
|
||||||
},
|
|
||||||
"payload": {
|
|
||||||
"type": "document",
|
|
||||||
"content_ref": "vault://uploads/factura.pdf"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
### 5.4 Flujo Ejemplo
|
|
||||||
|
|
||||||
```
|
|
||||||
Usuario: "¿Qué dice la factura que escaneé ayer?"
|
|
||||||
|
|
||||||
1. ASR: Audio → Texto
|
|
||||||
2. PENNY detecta: necesita GRACE.FIELD_EXTRACTOR
|
|
||||||
3. PENNY → GRACE (Contrato Común)
|
|
||||||
4. GRACE responde: { proveedor: "Telefónica", total: 45.90 }
|
|
||||||
5. PENNY + LLM formula respuesta natural
|
|
||||||
6. TTS: "La factura es de Telefónica por 45,90 euros"
|
|
||||||
7. Log registra todo (en DECK)
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 6. Conversación Natural por Turnos
|
|
||||||
|
|
||||||
### 6.1 Turn Detection
|
|
||||||
|
|
||||||
```yaml
|
|
||||||
turn_detection:
|
|
||||||
vad:
|
|
||||||
speech_threshold: 0.5
|
|
||||||
min_speech_ms: 250
|
|
||||||
min_silence_ms: 700 # Fin de turno
|
|
||||||
|
|
||||||
end_of_turn:
|
|
||||||
confident_silence_ms: 500
|
|
||||||
uncertain_silence_ms: 1000
|
|
||||||
max_silence_ms: 2000
|
|
||||||
|
|
||||||
barge_in:
|
|
||||||
enabled: true # Usuario puede interrumpir
|
|
||||||
min_user_speech_ms: 200
|
|
||||||
cancel_tts: true
|
|
||||||
|
|
||||||
backchanneling:
|
|
||||||
ignore_patterns: # No son turnos completos
|
|
||||||
- "^(mhm|sí|ajá|vale|ok)$"
|
|
||||||
```
|
|
||||||
|
|
||||||
### 6.2 Estados
|
|
||||||
|
|
||||||
```
|
|
||||||
IDLE ──────▶ LISTENING ──────▶ PROCESSING ──────▶ SPEAKING
|
|
||||||
▲ │ │
|
|
||||||
│ │ (barge-in) │
|
|
||||||
│ ◀────────────────────────────────────┘
|
|
||||||
│ │
|
|
||||||
└───────────────────────────────────────────────────┘
|
|
||||||
(TTS termina)
|
|
||||||
```
|
|
||||||
|
|
||||||
### 6.3 Feedback
|
|
||||||
|
|
||||||
```yaml
|
|
||||||
feedback:
|
|
||||||
idle: "azul tenue"
|
|
||||||
listening: "azul pulsante"
|
|
||||||
processing: "amarillo"
|
|
||||||
speaking: "verde"
|
|
||||||
error: "rojo"
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 7. Stack Técnico
|
|
||||||
|
|
||||||
### 7.1 Componentes de Proceso
|
|
||||||
|
|
||||||
| Componente | Función | Latencia Objetivo |
|
|
||||||
|------------|---------|-------------------|
|
|
||||||
| VAD | Detecta voz/silencio | <50ms |
|
|
||||||
| ASR | Audio → Texto | 200-400ms |
|
|
||||||
| LLM | Genera respuesta | 500ms-2s |
|
|
||||||
| TTS | Texto → Audio | 200-500ms |
|
|
||||||
|
|
||||||
### 7.2 Modelos Recomendados
|
|
||||||
|
|
||||||
```yaml
|
|
||||||
vad:
|
|
||||||
modelo: silero-vad
|
|
||||||
version: v5
|
|
||||||
|
|
||||||
asr:
|
|
||||||
modelo: faster-whisper
|
|
||||||
variantes:
|
|
||||||
- large-v3 # Máxima calidad
|
|
||||||
- distil-large-v2 # Balance
|
|
||||||
- medium # Fallback
|
|
||||||
|
|
||||||
llm:
|
|
||||||
opciones:
|
|
||||||
- qwen2.5-72b # Máxima calidad
|
|
||||||
- llama3.1-70b # Alternativa
|
|
||||||
- mistral-22b # Balance
|
|
||||||
- qwen2.5-7b # Baja latencia
|
|
||||||
|
|
||||||
tts:
|
|
||||||
modelo: xtts-v2
|
|
||||||
fallback:
|
|
||||||
- kokoro-82m
|
|
||||||
- piper
|
|
||||||
```
|
|
||||||
|
|
||||||
### 7.3 Requisitos GPU (Servidor Proceso)
|
|
||||||
|
|
||||||
```yaml
|
|
||||||
minimo:
|
|
||||||
vram: 24GB
|
|
||||||
modelos: whisper-large + llm-7b + xtts
|
|
||||||
|
|
||||||
recomendado:
|
|
||||||
vram: 48GB+
|
|
||||||
modelos: whisper-large + llm-70b + xtts
|
|
||||||
|
|
||||||
distribucion_ejemplo_48gb:
|
|
||||||
whisper_large: ~3GB
|
|
||||||
qwen2.5_72b_q4: ~40GB
|
|
||||||
xtts_v2: ~3GB
|
|
||||||
buffer: ~2GB
|
|
||||||
```
|
|
||||||
|
|
||||||
### 7.4 Latencias Objetivo
|
|
||||||
|
|
||||||
| Componente | Objetivo | Máximo |
|
|
||||||
|------------|----------|--------|
|
|
||||||
| VAD | <50ms | 100ms |
|
|
||||||
| ASR | <400ms | 800ms |
|
|
||||||
| LLM (primer token) | <500ms | 1500ms |
|
|
||||||
| TTS (primer audio) | <200ms | 500ms |
|
|
||||||
| **Total voice-to-voice** | **<2s** | **<4s** |
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 8. Protocolo de Comunicación
|
|
||||||
|
|
||||||
### 8.1 DECK → Servidor Proceso
|
|
||||||
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"type": "session_start",
|
|
||||||
"session_id": "uuid",
|
|
||||||
"planos": {
|
|
||||||
"sistema": { ... },
|
|
||||||
"personalidad": { ... },
|
|
||||||
"contexto_personal": { ... },
|
|
||||||
"contexto_ambiental": { ... }
|
|
||||||
},
|
|
||||||
"config": {
|
|
||||||
"voz_referencia": "base64_audio_6s",
|
|
||||||
"idioma": "es",
|
|
||||||
"max_tokens": 150
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
### 8.2 Audio Streaming
|
|
||||||
|
|
||||||
```
|
|
||||||
DECK ──── WebSocket ────▶ Servidor Proceso
|
|
||||||
◀─── WebSocket ─────
|
|
||||||
|
|
||||||
Formato: PCM 16kHz mono
|
|
||||||
Chunks: 20ms (320 samples)
|
|
||||||
```
|
|
||||||
|
|
||||||
### 8.3 Servidor Proceso → DECK
|
|
||||||
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"type": "turn_complete",
|
|
||||||
"turno": {
|
|
||||||
"usuario_texto": "¿Qué tengo pendiente?",
|
|
||||||
"penny_texto": "Tienes 3 recados...",
|
|
||||||
"audio_respuesta": "base64...",
|
|
||||||
"metricas": {
|
|
||||||
"latencia_asr_ms": 350,
|
|
||||||
"latencia_llm_ms": 1200,
|
|
||||||
"latencia_tts_ms": 400,
|
|
||||||
"tokens_prompt": 850,
|
|
||||||
"tokens_respuesta": 42
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 9. Estructura de Proyecto
|
|
||||||
|
|
||||||
### 9.1 DECK (Persistencia)
|
|
||||||
|
|
||||||
```
|
|
||||||
/deck/penny/
|
|
||||||
├── planos/
|
|
||||||
│ ├── sistema.yaml
|
|
||||||
│ ├── personalidad.yaml
|
|
||||||
│ └── usuarios/
|
|
||||||
│ └── {player_id}.yaml
|
|
||||||
├── voces/
|
|
||||||
│ └── penny_base.wav
|
|
||||||
├── db/
|
|
||||||
│ └── penny.db
|
|
||||||
└── config/
|
|
||||||
└── penny.yaml
|
|
||||||
```
|
|
||||||
|
|
||||||
### 9.2 Servidor Proceso (Stateless)
|
|
||||||
|
|
||||||
```
|
|
||||||
/proceso/
|
|
||||||
├── models/ # Solo lectura desde almacenamiento
|
|
||||||
│ ├── whisper/
|
|
||||||
│ ├── llm/
|
|
||||||
│ ├── tts/
|
|
||||||
│ └── vad/
|
|
||||||
├── engine/
|
|
||||||
│ ├── vad_processor.py
|
|
||||||
│ ├── asr_processor.py
|
|
||||||
│ ├── llm_processor.py
|
|
||||||
│ ├── tts_processor.py
|
|
||||||
│ └── pipeline.py
|
|
||||||
└── server/
|
|
||||||
├── main.py
|
|
||||||
└── websocket.py
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 10. Experiencias Reales
|
|
||||||
|
|
||||||
```
|
|
||||||
"Conseguí ~500ms latencia voice-to-voice con streaming de TTS."
|
|
||||||
— KoljaB, RealtimeVoiceChat
|
|
||||||
|
|
||||||
"En una 4090 con faster-distil-whisper bajamos a 300ms total."
|
|
||||||
— voicechat2
|
|
||||||
|
|
||||||
"XTTS-v2 clone de la voz de mi abuelo me hizo llorar."
|
|
||||||
— GitHub contributor
|
|
||||||
|
|
||||||
"El turn detection es lo más difícil. Silero VAD funciona
|
|
||||||
pero hay que ajustar los thresholds para cada persona."
|
|
||||||
— Reddit r/LocalLLaMA
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Resumen
|
|
||||||
|
|
||||||
PENNY es:
|
|
||||||
|
|
||||||
- **Voz del DECK** — interfaz hablada natural
|
|
||||||
- **Proceso remoto stateless** — zero retención, modelos autoalojados
|
|
||||||
- **Persistencia solo en DECK** — planos, log, datos
|
|
||||||
- **6 planos** de información cargables independientemente
|
|
||||||
- **Integración GRACE** via Contrato Común
|
|
||||||
- **<2 segundos** voice-to-voice objetivo
|
|
||||||
|
|
||||||
```
|
|
||||||
┌────────────────────┐ ┌────────────────────┐
|
|
||||||
│ SERVIDOR PROCESO │ │ DECK │
|
|
||||||
│ │ │ │
|
|
||||||
│ • VAD │◀───────▶│ • Planos │
|
|
||||||
│ • ASR │ Audio │ • Log │
|
|
||||||
│ • LLM │ Datos │ • GRACE │
|
|
||||||
│ • TTS │ │ • Vault │
|
|
||||||
│ │ │ │
|
|
||||||
│ ZERO RETENCIÓN │ │ PERSISTENCIA │
|
|
||||||
└────────────────────┘ └────────────────────┘
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
*Diciembre 2025*
|
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -1,60 +0,0 @@
|
|||||||
# SENTINEL
|
|
||||||
|
|
||||||

|
|
||||||
|
|
||||||
|
|
||||||
**Auditoría del sistema - Sistema TZZR**
|
|
||||||
|
|
||||||
## Rol
|
|
||||||
|
|
||||||
Observador paralelo que audita todos los componentes del sistema.
|
|
||||||
|
|
||||||
## Posición
|
|
||||||
|
|
||||||
```
|
|
||||||
┌─────────┐ ┌─────────┐ ┌─────────┐ ┌─────────┐ ┌─────────┐
|
|
||||||
│ CLARA │ │MARGARET │ │ALFRED/ │ │ MASON │ │ FELDMAN │
|
|
||||||
│ │ │ │ │JARED │ │ │ │ │
|
|
||||||
└────┬────┘ └────┬────┘ └────┬────┘ └────┬────┘ └────┬────┘
|
|
||||||
│ │ │ │ │
|
|
||||||
└─────────────┴─────────────┴─────────────┴─────────────┘
|
|
||||||
│
|
|
||||||
▼
|
|
||||||
┌──────────────────────────────┐
|
|
||||||
│ SENTINEL │
|
|
||||||
└──────────────────────────────┘
|
|
||||||
```
|
|
||||||
|
|
||||||
**SENTINEL no está en el flujo lineal. Observa TODO en paralelo.**
|
|
||||||
|
|
||||||
## Tipos de Auditoría
|
|
||||||
|
|
||||||
| Tipo | Cuándo | Coste |
|
|
||||||
|------|--------|-------|
|
|
||||||
| **Superficial** | Siempre | Bajo |
|
|
||||||
| **Profunda** | Errores | Alto |
|
|
||||||
| **Profunda** | Muestreo X% | Alto |
|
|
||||||
|
|
||||||
## Por qué Muestreo
|
|
||||||
|
|
||||||
Auditar todo en profundidad haría el sistema muy pesado. El muestreo:
|
|
||||||
- Mantiene rendimiento
|
|
||||||
- Detecta problemas sistémicos
|
|
||||||
- Mide calidad de procesos
|
|
||||||
|
|
||||||
## Alertas
|
|
||||||
|
|
||||||
| Nivel | Acción |
|
|
||||||
|-------|--------|
|
|
||||||
| info | Log |
|
|
||||||
| warning | Log + notificación |
|
|
||||||
| error | Log + notificación urgente |
|
|
||||||
| critical | Log + notificación + pausa |
|
|
||||||
|
|
||||||
## Arquitectura
|
|
||||||
|
|
||||||
Ver documentación completa en [contratos-comunes/architecture](https://git.tzzr.me/tzzr/contratos-comunes/src/branch/main/architecture/05-sentinel.md)
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
*Componente del sistema TZZR*
|
|
||||||
@@ -1,257 +0,0 @@
|
|||||||
# TZZR - Estado Real del Ecosistema
|
|
||||||
|
|
||||||
**Fecha de auditoria:** 2025-12-24
|
|
||||||
**Ultima actualizacion:** 2025-12-24 (post FASE 0, 1, 3)
|
|
||||||
**Auditor:** Orchestrator (Architect Agent)
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 1. INVENTARIO DE REPOS (23 repos)
|
|
||||||
|
|
||||||
### Estado por Categoria
|
|
||||||
|
|
||||||
| Estado | Cantidad | Repos |
|
|
||||||
|--------|----------|-------|
|
|
||||||
| **IMPLEMENTADO** | 7 | clara, margaret, hst, packet, orchestrator, context, system-plan |
|
|
||||||
| **PARCIAL** | 4 | grace, penny, the-factory, deck |
|
|
||||||
| **SOLO DOCS** | 12 | alfred, architect, contratos-comunes, corp, credentials, feldman, jared, locker, mason, sentinel, system, vision-builder |
|
|
||||||
| **ARCHIVADO** | 1 | mind-link |
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 2. ESTADO DETALLADO POR REPO
|
|
||||||
|
|
||||||
### IMPLEMENTADOS (codigo funcional y desplegado)
|
|
||||||
|
|
||||||
| Repo | Lenguaje | Descripcion Real | Desplegado |
|
|
||||||
|------|----------|------------------|------------|
|
|
||||||
| **clara** | Python/Flask | API de ingesta para DECK. Recibe contenedores de PACKET, sube a R2, registra en PostgreSQL | SI (72.62.1.113:5051) |
|
|
||||||
| **margaret** | Python/Flask | API de ingesta para CORP. Variante de CLARA para servidor empresarial | SI (92.112.181.188:5051) |
|
|
||||||
| **hst** | Python/Flask | Image server para tags semanticos. Sirve imagenes por subdominios .tzrtech.org | SI (72.62.2.84) |
|
|
||||||
| **packet** | Flutter/Dart | App movil completa. Captura multimedia, etiqueta con HST, envia a backends | NO (codigo listo) |
|
|
||||||
| **orchestrator** | Python | Framework multi-agente LLM. Soporta Claude, GPT-4, Gemini | Local only |
|
|
||||||
| **context** | SQL/Docs | Sistema de bloques de contexto para agentes. 35 bloques en PostgreSQL | SI (architect DB) |
|
|
||||||
| **system-plan** | Docs | Plan de implementacion y arquitectura del ecosistema | SI (Gitea) |
|
|
||||||
|
|
||||||
### PARCIALMENTE IMPLEMENTADOS
|
|
||||||
|
|
||||||
| Repo | Contenido Real | Falta |
|
|
||||||
|------|----------------|-------|
|
|
||||||
| **grace** | Handler RunPod con 6 modulos (ASR, OCR, TTS, Face, Embeddings, Avatar) | Desplegar en RunPod |
|
|
||||||
| **penny** | Estructura RunPod para generacion de texto (config, engine, server) | Completar engine, desplegar |
|
|
||||||
| **the-factory** | Handler RunPod para generacion iterativa | Implementar Director/Evaluator |
|
|
||||||
| **deck** | Configuracion de servidor (docker, scripts, nginx) + CLARA desplegado | Integrar alfred |
|
|
||||||
|
|
||||||
### ARCHIVADOS
|
|
||||||
|
|
||||||
| Repo | Razon |
|
|
||||||
|------|-------|
|
|
||||||
| **mind-link** | Pausado hasta completar pipeline principal (FASE 4) |
|
|
||||||
|
|
||||||
### SOLO DOCUMENTACION (pendientes de implementar)
|
|
||||||
|
|
||||||
| Repo | Proposito Documentado | Dependencia |
|
|
||||||
|------|----------------------|-------------|
|
|
||||||
| **mason** | Espacio de enriquecimiento | GRACE (RunPod) |
|
|
||||||
| **feldman** | Consolidacion en bloques | MASON |
|
|
||||||
| **alfred** | Flujos predefinidos DECK | CLARA (completado) |
|
|
||||||
| **jared** | Flujos predefinidos CORP | MARGARET (completado) |
|
|
||||||
| **sentinel** | Auditoria del sistema | Todo el pipeline |
|
|
||||||
| **vision-builder** | Diseno de visiones | THE FACTORY |
|
|
||||||
| **locker** | Gateway almacenamiento | R2 (listo) |
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 3. MAPA DE DEPENDENCIAS
|
|
||||||
|
|
||||||
### Flujo de Datos Principal
|
|
||||||
|
|
||||||
```
|
|
||||||
+-------------------+
|
|
||||||
| PACKET |
|
|
||||||
| (App movil) |
|
|
||||||
+--------+----------+
|
|
||||||
|
|
|
||||||
+--------------------+--------------------+
|
|
||||||
v v v
|
|
||||||
+--------------+ +--------------+ +--------------+
|
|
||||||
| CLARA | | MARGARET | |ALFRED/JARED |
|
|
||||||
| (DECK log) | | (CORP log) | | (flujos) |
|
|
||||||
| IMPLEMENTADO | | IMPLEMENTADO | | SOLO DOC |
|
|
||||||
+------+-------+ +------+-------+ +------+-------+
|
|
||||||
| | |
|
|
||||||
+--------------------+--------------------+
|
|
||||||
v
|
|
||||||
+--------------+
|
|
||||||
| GRACE |
|
|
||||||
| (RunPod) |
|
|
||||||
| PARCIAL |
|
|
||||||
+------+-------+
|
|
||||||
v
|
|
||||||
+--------------+
|
|
||||||
| MASON |
|
|
||||||
| SOLO DOC |
|
|
||||||
+------+-------+
|
|
||||||
v
|
|
||||||
+--------------+
|
|
||||||
| FELDMAN |
|
|
||||||
| SOLO DOC |
|
|
||||||
+--------------+
|
|
||||||
```
|
|
||||||
|
|
||||||
### Matriz de Dependencias
|
|
||||||
|
|
||||||
| Componente | Depende de | Es dependido por | Estado |
|
|
||||||
|------------|------------|------------------|--------|
|
|
||||||
| PACKET | HST, CLARA/MARGARET | Ninguno | LISTO |
|
|
||||||
| CLARA | PostgreSQL, R2, HST | MASON, FELDMAN | IMPLEMENTADO |
|
|
||||||
| MARGARET | PostgreSQL, R2, HST | MASON, FELDMAN | IMPLEMENTADO |
|
|
||||||
| MASON | CLARA/MARGARET, GRACE | FELDMAN | BLOQUEADO (GRACE) |
|
|
||||||
| FELDMAN | MASON | SENTINEL | BLOQUEADO (MASON) |
|
|
||||||
| HST | PostgreSQL | PACKET, CLARA, MARGARET | IMPLEMENTADO |
|
|
||||||
| GRACE | RunPod GPU | PENNY, FACTORY, MASON | PARCIAL |
|
|
||||||
| LOCKER | Cloudflare R2 | CLARA, MARGARET, FACTORY | LISTO |
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 4. INFRAESTRUCTURA ACTUAL
|
|
||||||
|
|
||||||
### Servidores
|
|
||||||
|
|
||||||
| Servidor | IP | Servicios Activos | Estado |
|
|
||||||
|----------|-----|-------------------|--------|
|
|
||||||
| ARCHITECT | 69.62.126.110 | Gitea, Directus, PostgreSQL, Infisical | OK |
|
|
||||||
| DECK | 72.62.1.113 | Directus, PostgreSQL, Mailcow, CLARA | OK |
|
|
||||||
| CORP | 92.112.181.188 | Directus, Nextcloud, Odoo, MARGARET, ntfy | OK |
|
|
||||||
| HST | 72.62.2.84 | Nginx (imagenes), Directus, PostgreSQL | OK |
|
|
||||||
|
|
||||||
### Bases de Datos
|
|
||||||
|
|
||||||
| Servidor | DB | Tablas de Pipeline |
|
|
||||||
|----------|-----|-------------------|
|
|
||||||
| ARCHITECT | architect | context_blocks, agent_context_index |
|
|
||||||
| DECK | tzzr | clara_log |
|
|
||||||
| CORP | corp | margaret_log |
|
|
||||||
| HST | hst_images | 5 tablas de tags (973 registros) |
|
|
||||||
|
|
||||||
### Cloudflare R2
|
|
||||||
|
|
||||||
| Bucket | Estado | Uso |
|
|
||||||
|--------|--------|-----|
|
|
||||||
| architect | Configurado | Backups |
|
|
||||||
| deck | Activo | Archivos CLARA |
|
|
||||||
| corp | Activo | Archivos MARGARET |
|
|
||||||
| hst | Configurado | Imagenes |
|
|
||||||
| locker | Configurado | Almacenamiento general |
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 5. INCONSISTENCIAS RESUELTAS
|
|
||||||
|
|
||||||
### Resueltas en FASE 0-3
|
|
||||||
|
|
||||||
| ID | Descripcion | Resolucion |
|
|
||||||
|----|-------------|------------|
|
|
||||||
| I01 | CLARA no desplegada en DECK | RESUELTO - Docker en 72.62.1.113:5051 |
|
|
||||||
| I02 | MARGARET solo documentada | RESUELTO - Docker en 92.112.181.188:5051 |
|
|
||||||
| I03 | PostgreSQL sin tablas de flujo | RESUELTO - clara_log, margaret_log creadas |
|
|
||||||
| I10 | architect tiene carpetas obsoletas | RESUELTO - Eliminadas app-v2, orchestrator-v3 |
|
|
||||||
| I11 | mind-link tiene src/ vacio | RESUELTO - Repo archivado |
|
|
||||||
| I12 | NocoDB referenciado | RESUELTO - Actualizado a Directus |
|
|
||||||
|
|
||||||
### Pendientes
|
|
||||||
|
|
||||||
| ID | Descripcion | Bloqueador |
|
|
||||||
|----|-------------|------------|
|
|
||||||
| I04 | GRACE no desplegado en RunPod | Requiere cuenta RunPod |
|
|
||||||
| I05 | R2 buckets sin uso intensivo | Pendiente flujo completo |
|
|
||||||
| I09 | PACKET no publicada | Pendiente priorizar |
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 6. SERVICIOS REALES vs DOCUMENTADOS
|
|
||||||
|
|
||||||
### DECK (72.62.1.113)
|
|
||||||
|
|
||||||
| Servicio | Documentado | Real | Puerto |
|
|
||||||
|----------|-------------|------|--------|
|
|
||||||
| PostgreSQL | SI | SI | 5432 |
|
|
||||||
| Directus | SI | SI | 8055 |
|
|
||||||
| Mailcow | SI | SI | 443 |
|
|
||||||
| CLARA | SI | SI | 5051 |
|
|
||||||
| ALFRED | SI | NO | - |
|
|
||||||
|
|
||||||
### CORP (92.112.181.188)
|
|
||||||
|
|
||||||
| Servicio | Documentado | Real | Puerto |
|
|
||||||
|----------|-------------|------|--------|
|
|
||||||
| PostgreSQL | SI | SI | 5432 |
|
|
||||||
| Directus | SI | SI | 8055 |
|
|
||||||
| Nextcloud | SI | SI | 8080 |
|
|
||||||
| Odoo | SI | SI | 8069 |
|
|
||||||
| MARGARET | SI | SI | 5051 |
|
|
||||||
| ntfy | SI | SI | 8880 |
|
|
||||||
| JARED | SI | NO | - |
|
|
||||||
|
|
||||||
### HST (72.62.2.84)
|
|
||||||
|
|
||||||
| Servicio | Documentado | Real | Puerto |
|
|
||||||
|----------|-------------|------|--------|
|
|
||||||
| Nginx (imagenes) | SI | SI | 80/443 |
|
|
||||||
| Directus | SI | SI | 8055 |
|
|
||||||
| PostgreSQL | SI | SI | 5432 |
|
|
||||||
| API /biblioteca | SI | SI | - |
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 7. RESUMEN EJECUTIVO
|
|
||||||
|
|
||||||
### Lo que FUNCIONA
|
|
||||||
|
|
||||||
1. **HST** - Sistema de tags semanticos operativo
|
|
||||||
2. **CLARA** - Ingesta DECK funcionando (72.62.1.113:5051)
|
|
||||||
3. **MARGARET** - Ingesta CORP funcionando (92.112.181.188:5051)
|
|
||||||
4. **Gitea** - Control de versiones funcional
|
|
||||||
5. **Directus** - CMS en todos los servidores
|
|
||||||
6. **PostgreSQL** - Bases de datos con tablas de pipeline
|
|
||||||
7. **R2** - Buckets activos para CLARA y MARGARET
|
|
||||||
8. **context** - Sistema de contexto para agentes
|
|
||||||
|
|
||||||
### Lo que esta LISTO pero NO DESPLEGADO
|
|
||||||
|
|
||||||
1. **PACKET** - App Flutter completa (falta publicar)
|
|
||||||
2. **GRACE** - Handler RunPod con 6 modulos (falta cuenta RunPod)
|
|
||||||
|
|
||||||
### Lo que es SOLO DOCUMENTACION
|
|
||||||
|
|
||||||
1. **MASON/FELDMAN** - Bloqueados por GRACE
|
|
||||||
2. **ALFRED/JARED** - Pueden implementarse ahora
|
|
||||||
3. **SENTINEL** - Fase final
|
|
||||||
4. **VISION BUILDER** - Depende de THE FACTORY
|
|
||||||
|
|
||||||
### Porcentaje de Implementacion Real
|
|
||||||
|
|
||||||
| Area | Antes | Ahora | Cambio |
|
|
||||||
|------|-------|-------|--------|
|
|
||||||
| Infraestructura base | 80% | 90% | +10% |
|
|
||||||
| Servicios de soporte | 60% | 70% | +10% |
|
|
||||||
| Pipeline de datos | 10% | 40% | +30% |
|
|
||||||
| Procesamiento IA | 0% | 0% | - |
|
|
||||||
| Apps de usuario | 0% | 0% | - |
|
|
||||||
|
|
||||||
### Siguiente Paso Critico
|
|
||||||
|
|
||||||
**GRACE en RunPod** - Desbloquea MASON, FELDMAN y todo el procesamiento IA.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 8. CREDENCIALES DE INSTANCIA
|
|
||||||
|
|
||||||
| Servidor | h_instancia | Servicio |
|
|
||||||
|----------|-------------|----------|
|
|
||||||
| DECK | f25e44ac3c075f57b9a198c880cb1fc05cf3af56f6466828b405d8c062374179 | CLARA |
|
|
||||||
| CORP | ea9e99d5f95bcc23749d5f25b71a5b520ae7917438912fc6e29564534484a514 | MARGARET |
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
*Documento actualizado automaticamente - 2025-12-24*
|
|
||||||
@@ -1,243 +0,0 @@
|
|||||||
# TZZR - Plan de Implementacion
|
|
||||||
|
|
||||||
**Fecha:** 2025-12-24
|
|
||||||
**Ultima actualizacion:** 2025-12-24
|
|
||||||
**Objetivo:** Llevar el ecosistema de 10% a 80% de funcionalidad
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## RESUMEN DE FASES
|
|
||||||
|
|
||||||
| Fase | Objetivo | Estado | Repos Afectados |
|
|
||||||
|------|----------|--------|-----------------|
|
|
||||||
| 0 | Limpieza y consolidacion | COMPLETADA | architect, system, mind-link |
|
|
||||||
| 1 | Pipeline minimo viable | COMPLETADA | clara, deck |
|
|
||||||
| 2 | Procesamiento IA | BLOQUEADA | grace, penny, the-factory |
|
|
||||||
| 3 | Flujo empresarial | COMPLETADA | margaret, corp |
|
|
||||||
| 4 | Pipeline completo | PENDIENTE | mason, feldman, alfred, jared |
|
|
||||||
| 5 | Apps de usuario | PENDIENTE | packet, vision-builder |
|
|
||||||
| 6 | Observabilidad | PENDIENTE | sentinel |
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## FASE 0: LIMPIEZA Y CONSOLIDACION - COMPLETADA
|
|
||||||
|
|
||||||
**Ejecutada:** 2025-12-24
|
|
||||||
|
|
||||||
### Acciones Completadas
|
|
||||||
|
|
||||||
| # | Accion | Estado |
|
|
||||||
|---|--------|--------|
|
|
||||||
| 0.1 | Eliminar carpetas obsoletas de architect | OK |
|
|
||||||
| 0.2 | Actualizar referencias a NocoDB -> Directus | OK |
|
|
||||||
| 0.3 | Anadir badges de estado a todos los repos | OK |
|
|
||||||
| 0.4 | Archivar mind-link | OK |
|
|
||||||
|
|
||||||
### Verificacion
|
|
||||||
|
|
||||||
- [x] No existen carpetas app-v2, orchestrator-* en architect
|
|
||||||
- [x] No hay referencias a NocoDB en documentacion activa
|
|
||||||
- [x] Todos los READMEs tienen badge de estado
|
|
||||||
- [x] mind-link archivado con README explicativo
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## FASE 1: PIPELINE MINIMO VIABLE - COMPLETADA
|
|
||||||
|
|
||||||
**Ejecutada:** 2025-12-24
|
|
||||||
|
|
||||||
### Acciones Completadas
|
|
||||||
|
|
||||||
| # | Accion | Estado | Detalle |
|
|
||||||
|---|--------|--------|---------|
|
|
||||||
| 1.1 | Crear tabla clara_log en DECK | OK | PostgreSQL Docker |
|
|
||||||
| 1.2 | Generar h_instancia | OK | f25e44ac... |
|
|
||||||
| 1.3 | Desplegar CLARA Docker | OK | Puerto 5051 |
|
|
||||||
| 1.4 | Configurar red Docker | OK | tzzr-network |
|
|
||||||
| 1.5 | Probar ingesta | OK | Auth + duplicados |
|
|
||||||
|
|
||||||
### Configuracion Final
|
|
||||||
|
|
||||||
```
|
|
||||||
Servidor: DECK (72.62.1.113)
|
|
||||||
Puerto: 5051
|
|
||||||
DB: tzzr (PostgreSQL Docker)
|
|
||||||
Tabla: clara_log
|
|
||||||
R2 Bucket: deck
|
|
||||||
h_instancia: f25e44ac3c075f57b9a198c880cb1fc05cf3af56f6466828b405d8c062374179
|
|
||||||
```
|
|
||||||
|
|
||||||
### Verificacion
|
|
||||||
|
|
||||||
- [x] `curl http://72.62.1.113:5051/health` responde OK
|
|
||||||
- [x] Sin auth responde 401
|
|
||||||
- [x] Con auth valida responde 200
|
|
||||||
- [x] Duplicados responden 409
|
|
||||||
- [x] Registro aparece en clara_log
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## FASE 2: PROCESAMIENTO IA - BLOQUEADA
|
|
||||||
|
|
||||||
**Bloqueador:** Requiere cuenta RunPod configurada
|
|
||||||
|
|
||||||
### Acciones Pendientes
|
|
||||||
|
|
||||||
| # | Accion | Estado |
|
|
||||||
|---|--------|--------|
|
|
||||||
| 2.1 | Crear template en RunPod | PENDIENTE |
|
|
||||||
| 2.2 | Configurar endpoint serverless | PENDIENTE |
|
|
||||||
| 2.3 | Probar modulo ASR_ENGINE | PENDIENTE |
|
|
||||||
| 2.4 | Probar modulo OCR_CORE | PENDIENTE |
|
|
||||||
| 2.5 | Documentar endpoint ID | PENDIENTE |
|
|
||||||
|
|
||||||
### Codigo Disponible
|
|
||||||
|
|
||||||
El repo `grace` contiene:
|
|
||||||
- handler.py con 6 modulos
|
|
||||||
- Dockerfile para RunPod
|
|
||||||
- requirements.txt
|
|
||||||
|
|
||||||
### Para Desbloquear
|
|
||||||
|
|
||||||
1. Crear cuenta RunPod
|
|
||||||
2. Subir template desde grace/runpod/
|
|
||||||
3. Crear endpoint serverless
|
|
||||||
4. Documentar ENDPOINT_ID en credentials
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## FASE 3: FLUJO EMPRESARIAL - COMPLETADA
|
|
||||||
|
|
||||||
**Ejecutada:** 2025-12-24
|
|
||||||
|
|
||||||
### Acciones Completadas
|
|
||||||
|
|
||||||
| # | Accion | Estado | Detalle |
|
|
||||||
|---|--------|--------|---------|
|
|
||||||
| 3.1 | Verificar PostgreSQL en CORP | OK | Host PostgreSQL |
|
|
||||||
| 3.2 | Crear tabla margaret_log | OK | DB: corp |
|
|
||||||
| 3.3 | Generar h_instancia | OK | ea9e99d5... |
|
|
||||||
| 3.4 | Desplegar MARGARET Docker | OK | Puerto 5051 |
|
|
||||||
| 3.5 | Probar ingesta | OK | Auth + duplicados |
|
|
||||||
|
|
||||||
### Configuracion Final
|
|
||||||
|
|
||||||
```
|
|
||||||
Servidor: CORP (92.112.181.188)
|
|
||||||
Puerto: 5051
|
|
||||||
DB: corp (PostgreSQL Host)
|
|
||||||
Tabla: margaret_log
|
|
||||||
R2 Bucket: corp
|
|
||||||
h_instancia: ea9e99d5f95bcc23749d5f25b71a5b520ae7917438912fc6e29564534484a514
|
|
||||||
```
|
|
||||||
|
|
||||||
### Verificacion
|
|
||||||
|
|
||||||
- [x] `curl http://92.112.181.188:5051/health` responde OK
|
|
||||||
- [x] Sin auth responde 401
|
|
||||||
- [x] Con auth valida responde 200
|
|
||||||
- [x] Duplicados responden 409
|
|
||||||
- [x] Registro aparece en margaret_log
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## FASE 4: PIPELINE COMPLETO - PENDIENTE
|
|
||||||
|
|
||||||
**Dependencia:** GRACE (FASE 2) para procesamiento IA
|
|
||||||
|
|
||||||
### ALFRED (Flujos Predefinidos DECK)
|
|
||||||
|
|
||||||
| # | Accion | Estado |
|
|
||||||
|---|--------|--------|
|
|
||||||
| 4.1 | Crear schema SQL flujos | PENDIENTE |
|
|
||||||
| 4.2 | Implementar API Flask | PENDIENTE |
|
|
||||||
| 4.3 | Integrar con CLARA | PENDIENTE |
|
|
||||||
|
|
||||||
**Nota:** ALFRED puede implementarse sin GRACE para flujos que no requieran IA.
|
|
||||||
|
|
||||||
### JARED (Flujos Predefinidos CORP)
|
|
||||||
|
|
||||||
| # | Accion | Estado |
|
|
||||||
|---|--------|--------|
|
|
||||||
| 4.4 | Fork de ALFRED | PENDIENTE |
|
|
||||||
| 4.5 | Adaptar para CORP | PENDIENTE |
|
|
||||||
| 4.6 | Integrar con MARGARET | PENDIENTE |
|
|
||||||
|
|
||||||
### MASON (Enriquecimiento)
|
|
||||||
|
|
||||||
| # | Accion | Estado |
|
|
||||||
|---|--------|--------|
|
|
||||||
| 4.7 | Crear schema SQL | BLOQUEADO (GRACE) |
|
|
||||||
| 4.8 | Implementar API Flask | BLOQUEADO (GRACE) |
|
|
||||||
| 4.9 | Integrar con GRACE | BLOQUEADO (GRACE) |
|
|
||||||
|
|
||||||
### FELDMAN (Consolidacion)
|
|
||||||
|
|
||||||
| # | Accion | Estado |
|
|
||||||
|---|--------|--------|
|
|
||||||
| 4.10 | Crear schema SQL | BLOQUEADO (MASON) |
|
|
||||||
| 4.11 | Implementar API Flask | BLOQUEADO (MASON) |
|
|
||||||
| 4.12 | Generar bloques 24h | BLOQUEADO (MASON) |
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## FASE 5: APPS DE USUARIO - PENDIENTE
|
|
||||||
|
|
||||||
### PACKET
|
|
||||||
|
|
||||||
| # | Accion | Estado |
|
|
||||||
|---|--------|--------|
|
|
||||||
| 5.1 | Configurar firma Android | PENDIENTE |
|
|
||||||
| 5.2 | Build APK release | PENDIENTE |
|
|
||||||
| 5.3 | Publicar en Gitea releases | PENDIENTE |
|
|
||||||
|
|
||||||
### VISION BUILDER
|
|
||||||
|
|
||||||
| # | Accion | Estado |
|
|
||||||
|---|--------|--------|
|
|
||||||
| 5.4 | Implementar schema SQL | BLOQUEADO (FACTORY) |
|
|
||||||
| 5.5 | Crear API Flask | BLOQUEADO (FACTORY) |
|
|
||||||
| 5.6 | Integrar con THE FACTORY | BLOQUEADO (FACTORY) |
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## FASE 6: OBSERVABILIDAD - PENDIENTE
|
|
||||||
|
|
||||||
### SENTINEL
|
|
||||||
|
|
||||||
| # | Accion | Estado |
|
|
||||||
|---|--------|--------|
|
|
||||||
| 6.1 | Crear schema SQL | PENDIENTE |
|
|
||||||
| 6.2 | Implementar hooks | PENDIENTE |
|
|
||||||
| 6.3 | Dashboard Grafana | PENDIENTE |
|
|
||||||
| 6.4 | Alertas ntfy | PENDIENTE |
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## PROXIMO PASO RECOMENDADO
|
|
||||||
|
|
||||||
### Opcion A: Desbloquear GRACE (alto impacto)
|
|
||||||
1. Configurar cuenta RunPod
|
|
||||||
2. Desplegar GRACE
|
|
||||||
3. Habilita MASON, FELDMAN, THE FACTORY
|
|
||||||
|
|
||||||
### Opcion B: Implementar ALFRED/JARED (sin bloqueo)
|
|
||||||
1. Flujos predefinidos sin IA
|
|
||||||
2. Integrar con CLARA/MARGARET
|
|
||||||
3. Puede hacerse en paralelo
|
|
||||||
|
|
||||||
### Opcion C: Publicar PACKET (usuario final)
|
|
||||||
1. Build APK
|
|
||||||
2. Publicar en Gitea
|
|
||||||
3. Permite pruebas end-to-end
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## SCRIPTS DE IMPLEMENTACION
|
|
||||||
|
|
||||||
Ver carpeta `/PHASES/` para scripts detallados.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
*Plan actualizado automaticamente - 2025-12-24*
|
|
||||||
@@ -1,78 +0,0 @@
|
|||||||
# TZZR System Plan
|
|
||||||
|
|
||||||
**Estado real y plan de implementacion del ecosistema TZZR**
|
|
||||||
|
|
||||||
Ultima actualizacion: 2025-12-24
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Documentos
|
|
||||||
|
|
||||||
| Documento | Descripcion |
|
|
||||||
|-----------|-------------|
|
|
||||||
| [STATUS.md](STATUS.md) | Estado rapido del sistema |
|
|
||||||
| [ARCHITECTURE.md](ARCHITECTURE.md) | Estado detallado, inventario de repos |
|
|
||||||
| [IMPLEMENTATION_PLAN.md](IMPLEMENTATION_PLAN.md) | Plan de implementacion por fases |
|
|
||||||
| [PHASES/](PHASES/) | Scripts detallados para cada fase |
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Estado Actual
|
|
||||||
|
|
||||||
```
|
|
||||||
COMPLETADO: Fases 0, 1, 3
|
|
||||||
BLOQUEADO: Fase 2 (requiere RunPod)
|
|
||||||
PENDIENTE: Fases 4, 5, 6
|
|
||||||
```
|
|
||||||
|
|
||||||
### Servicios Activos
|
|
||||||
|
|
||||||
| Servicio | URL | Estado |
|
|
||||||
|----------|-----|--------|
|
|
||||||
| CLARA | http://72.62.1.113:5051 | OK |
|
|
||||||
| MARGARET | http://92.112.181.188:5051 | OK |
|
|
||||||
| HST | http://72.62.2.84 | OK |
|
|
||||||
| Gitea | http://69.62.126.110:3000 | OK |
|
|
||||||
|
|
||||||
### Progreso por Area
|
|
||||||
|
|
||||||
| Area | Progreso |
|
|
||||||
|------|----------|
|
|
||||||
| Pipeline datos | 40% |
|
|
||||||
| Procesamiento IA | 0% (bloqueado) |
|
|
||||||
| Apps usuario | 0% |
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Fases de Implementacion
|
|
||||||
|
|
||||||
| Fase | Objetivo | Estado |
|
|
||||||
|------|----------|--------|
|
|
||||||
| 0 | Limpieza y consolidacion | COMPLETADA |
|
|
||||||
| 1 | Pipeline minimo (CLARA) | COMPLETADA |
|
|
||||||
| 2 | Procesamiento IA (GRACE) | BLOQUEADA |
|
|
||||||
| 3 | Flujo empresarial (MARGARET) | COMPLETADA |
|
|
||||||
| 4 | Pipeline completo | PENDIENTE |
|
|
||||||
| 5 | Apps de usuario | PENDIENTE |
|
|
||||||
| 6 | Observabilidad | PENDIENTE |
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Bloqueador Principal
|
|
||||||
|
|
||||||
**GRACE en RunPod** - Requiere configurar cuenta RunPod para desbloquear:
|
|
||||||
- MASON (enriquecimiento)
|
|
||||||
- FELDMAN (consolidacion)
|
|
||||||
- THE FACTORY (generacion)
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Proximos Pasos Sin Bloqueo
|
|
||||||
|
|
||||||
1. **ALFRED** - Flujos predefinidos para DECK
|
|
||||||
2. **JARED** - Flujos predefinidos para CORP
|
|
||||||
3. **PACKET** - Publicar APK de la app movil
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
*Documento de trabajo del ecosistema TZZR*
|
|
||||||
@@ -1,146 +0,0 @@
|
|||||||
# TZZR - Estado del Sistema
|
|
||||||
|
|
||||||
**Ultima actualizacion:** 2025-12-24 10:45 UTC
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Estado Rapido
|
|
||||||
|
|
||||||
```
|
|
||||||
Pipeline de Ingesta: [########--] 80%
|
|
||||||
Procesamiento IA: [#---------] 10% (GRACE pendiente)
|
|
||||||
Apps Usuario: [----------] 0%
|
|
||||||
Observabilidad: [----------] 0%
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Servicios Activos
|
|
||||||
|
|
||||||
### DECK (72.62.1.113)
|
|
||||||
| Servicio | Puerto | Funcion | Estado |
|
|
||||||
|----------|--------|---------|--------|
|
|
||||||
| CLARA | 5051 | Ingesta de datos | OK |
|
|
||||||
| ALFRED | 5052 | Flujos predefinidos | OK |
|
|
||||||
|
|
||||||
### CORP (92.112.181.188)
|
|
||||||
| Servicio | Puerto | Funcion | Estado |
|
|
||||||
|----------|--------|---------|--------|
|
|
||||||
| MARGARET | 5051 | Almacenamiento archivos | OK |
|
|
||||||
| JARED | 5052 | Flujos predefinidos | OK |
|
|
||||||
| MASON | 5053 | Espacio de edicion | OK |
|
|
||||||
| FELDMAN | 5054 | Registro completados | OK |
|
|
||||||
|
|
||||||
### RunPod (Serverless)
|
|
||||||
| Servicio | Endpoint ID | Funcion | Estado |
|
|
||||||
|----------|-------------|---------|--------|
|
|
||||||
| GRACE | r00x4g3rrwkbyh | GPU Processing | Pendiente Docker image |
|
|
||||||
|
|
||||||
### Infraestructura
|
|
||||||
| Servicio | Servidor | Puerto | Estado |
|
|
||||||
|----------|----------|--------|--------|
|
|
||||||
| Gitea | ARCHITECT | 3000 | OK |
|
|
||||||
| Directus | Todos | 8055 | OK |
|
|
||||||
| HST | HST | 80 | OK |
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Fases Completadas
|
|
||||||
|
|
||||||
| Fase | Descripcion | Fecha |
|
|
||||||
|------|-------------|-------|
|
|
||||||
| 0 | Limpieza y consolidacion | 2025-12-24 |
|
|
||||||
| 1 | Pipeline minimo (CLARA) | 2025-12-24 |
|
|
||||||
| 3 | Flujo empresarial (MARGARET) | 2025-12-24 |
|
|
||||||
| 4 | ALFRED, JARED, MASON, FELDMAN | 2025-12-24 |
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Flujo de Datos
|
|
||||||
|
|
||||||
```
|
|
||||||
┌─────────────────────────────────────┐
|
|
||||||
│ ENTRADA DE DATOS │
|
|
||||||
└─────────────────────────────────────┘
|
|
||||||
│
|
|
||||||
┌─────────────────┴─────────────────┐
|
|
||||||
v v
|
|
||||||
┌──────────┐ ┌──────────┐
|
|
||||||
│ CLARA │ │ MARGARET │
|
|
||||||
│ (DECK) │ │ (CORP) │
|
|
||||||
│ :5051 │ │ :5051 │
|
|
||||||
└────┬─────┘ └────┬─────┘
|
|
||||||
│ │
|
|
||||||
v v
|
|
||||||
┌──────────┐ ┌──────────┐
|
|
||||||
│ ALFRED │ │ JARED │
|
|
||||||
│ (DECK) │ │ (CORP) │
|
|
||||||
│ :5052 │ │ :5052 │
|
|
||||||
└────┬─────┘ └────┬─────┘
|
|
||||||
│ │
|
|
||||||
└─────────────┬────────────────────┘
|
|
||||||
│
|
|
||||||
┌────────────┴────────────┐
|
|
||||||
│ incidencia? │
|
|
||||||
└────────────┬────────────┘
|
|
||||||
│ │
|
|
||||||
OK │ │ incidencia
|
|
||||||
v v
|
|
||||||
┌──────────┐ ┌──────────┐
|
|
||||||
│ FELDMAN │ │ MASON │
|
|
||||||
│ :5054 │ │ :5053 │
|
|
||||||
└──────────┘ └────┬─────┘
|
|
||||||
^ │
|
|
||||||
│ editar │
|
|
||||||
└────────────┘
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Bloqueadores
|
|
||||||
|
|
||||||
| Componente | Bloqueador | Impacto |
|
|
||||||
|------------|------------|---------|
|
|
||||||
| GRACE | Docker image en RunPod | Procesamiento IA |
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Proximos Pasos
|
|
||||||
|
|
||||||
### Inmediato
|
|
||||||
1. **GRACE** - Construir Docker image y desplegar en RunPod
|
|
||||||
2. **PACKET** - Publicar APK
|
|
||||||
|
|
||||||
### Posterior
|
|
||||||
1. SENTINEL - Observabilidad
|
|
||||||
2. THE-FACTORY - Generacion contenido
|
|
||||||
3. PENNY - Procesamiento voz
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Endpoints de Prueba
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# DECK
|
|
||||||
curl http://72.62.1.113:5051/health # CLARA
|
|
||||||
curl http://72.62.1.113:5052/health # ALFRED
|
|
||||||
|
|
||||||
# CORP
|
|
||||||
curl http://92.112.181.188:5051/health # MARGARET
|
|
||||||
curl http://92.112.181.188:5052/health # JARED
|
|
||||||
curl http://92.112.181.188:5053/health # MASON
|
|
||||||
curl http://92.112.181.188:5054/health # FELDMAN
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## h_instancia (Auth Keys)
|
|
||||||
|
|
||||||
| Servidor | Hash |
|
|
||||||
|----------|------|
|
|
||||||
| DECK | `f25e44ac3c075f57b9a198c880cb1fc05cf3af56f6466828b405d8c062374179` |
|
|
||||||
| CORP | `ea9e99d5f95bcc23749d5f25b71a5b520ae7917438912fc6e29564534484a514` |
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
*Ver ARCHITECTURE.md y IMPLEMENTATION_PLAN.md para detalles completos*
|
|
||||||
@@ -1,178 +0,0 @@
|
|||||||
# Componentes del Sistema
|
|
||||||
|
|
||||||
## Catálogo Completo
|
|
||||||
|
|
||||||
| Componente | Rol | Renombrable |
|
|
||||||
|------------|-----|-------------|
|
|
||||||
| **BASES** | HST, ITM, PLY, LOC, FLG — lo que existe antes de todo | No |
|
|
||||||
| **DECK** | Servidor personal | No |
|
|
||||||
| **LOCKER** | Almacenamiento físico (actual: R2, futuro: descentralizado) | No |
|
|
||||||
| **CORP** | Cada empresa: libros, entidades, secretos | Sí |
|
|
||||||
| **GRACE** | Extracción + comprensión (IA), nunca modifica | Sí |
|
|
||||||
| **MASON** | Trabaja los datos, busca que todo encaje | Sí |
|
|
||||||
| **CLARA** | Recoge información + log IAs (personal) | Sí |
|
|
||||||
| **MARGARET** | Recoge información + log IAs (CORP) | Sí |
|
|
||||||
| **PENNY** | Asistente personal, recados | Sí |
|
|
||||||
| **ALFRED** | Flujos de trabajo (personal) | Sí |
|
|
||||||
| **JARED** | Flujos de trabajo (CORP) | Sí |
|
|
||||||
| **FELDMAN** | Cuida los libros, valida con blockchain | Sí |
|
|
||||||
| **SENTINEL** | Auditoría interna (LIGHT + DEEP) | Sí |
|
|
||||||
| **Tesorero** | Cuentas bancarias (futuro) | Sí |
|
|
||||||
| **THE FACTORY** | IA generativa iterativa | No |
|
|
||||||
| **CIRCLE** | Consejo de perspectivas | No |
|
|
||||||
| **Cloudville** | Laboratorio de zumbados | No |
|
|
||||||
| **PACKET** | Interfaz móvil | No |
|
|
||||||
| **Architect App** | Sistema centralizado, crea instancias originales | No |
|
|
||||||
| **Vision Builder** | Interfaz diseño de vida | No |
|
|
||||||
| **Mind Flow** | Interfaz de flujos | No |
|
|
||||||
| **Mind Link** | Interfaz de compartición | No |
|
|
||||||
| **Mind Map** | Interfaz de estructuras | No |
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## DECK — Servidor Personal
|
|
||||||
|
|
||||||
### Arquitectura
|
|
||||||
|
|
||||||
| Componente | Función |
|
|
||||||
|------------|---------|
|
|
||||||
| **MST (Milestones)** | Plano burocrático — documentos, hitos, estados |
|
|
||||||
| **BCK (Bloques)** | Plano físico — acciones, evidencias, trabajo real |
|
|
||||||
| **PostgreSQL** | Base de datos relacional |
|
|
||||||
| **Directus** | Gestión de vistas ligeras |
|
|
||||||
| **HST interno** | Etiquetas propias + proyectos |
|
|
||||||
|
|
||||||
### Servicios Integrados
|
|
||||||
|
|
||||||
| Servicio | Función |
|
|
||||||
|---------|---------|
|
|
||||||
| Correo | Mail-in-a-Box |
|
|
||||||
| Gestor contraseñas | Credenciales personales |
|
|
||||||
| Acortador URLs | Shlink |
|
|
||||||
|
|
||||||
### Agentes Internos
|
|
||||||
|
|
||||||
| Agente | Función |
|
|
||||||
|--------|---------|
|
|
||||||
| **CLARA** | Recoge información, log de IAs |
|
|
||||||
| **MASON** | Vistas flotantes para completar datos |
|
|
||||||
| **FELDMAN** | Registros inmutables |
|
|
||||||
| **ALFRED** | Flujos de trabajo |
|
|
||||||
| **SENTINEL** | Auditoría interna |
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## CORP — Servidor Corporativo
|
|
||||||
|
|
||||||
### Diferencias con DECK
|
|
||||||
|
|
||||||
| Aspecto | DECK | CORP |
|
|
||||||
|---------|------|------|
|
|
||||||
| Orientación | Personal | Empresa |
|
|
||||||
| Flujos | ALFRED | JARED (más potente) |
|
|
||||||
| Recogida info | CLARA | MARGARET (más potente) |
|
|
||||||
| CRM/ERP | No | Odoo |
|
|
||||||
|
|
||||||
### Agentes Internos
|
|
||||||
|
|
||||||
| Agente | Función |
|
|
||||||
|--------|---------|
|
|
||||||
| **MARGARET** | Recoge información (versión corporativa) |
|
|
||||||
| **MASON** | Vistas flotantes |
|
|
||||||
| **FELDMAN** | Registros inmutables |
|
|
||||||
| **JARED** | Flujos de trabajo (versión corporativa) |
|
|
||||||
| **SENTINEL** | Auditoría interna |
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Agentes del Sistema
|
|
||||||
|
|
||||||
### CLARA / MARGARET
|
|
||||||
|
|
||||||
Recoge información y mantiene log de interacciones con IAs.
|
|
||||||
|
|
||||||
| Variante | Contexto | Potencia |
|
|
||||||
|----------|----------|----------|
|
|
||||||
| **CLARA** | DECK | Estándar |
|
|
||||||
| **MARGARET** | CORP | Mayor |
|
|
||||||
|
|
||||||
### MASON
|
|
||||||
|
|
||||||
Trabaja los datos, genera vistas flotantes para que el usuario complete información.
|
|
||||||
|
|
||||||
### ALFRED / JARED
|
|
||||||
|
|
||||||
Almacén de flujos de trabajo.
|
|
||||||
|
|
||||||
| Variante | Contexto | Potencia |
|
|
||||||
|----------|----------|----------|
|
|
||||||
| **ALFRED** | DECK | Estándar |
|
|
||||||
| **JARED** | CORP | Mayor |
|
|
||||||
|
|
||||||
### FELDMAN
|
|
||||||
|
|
||||||
Cuida los libros, valida con blockchain. Convierte registros en inmutables tras período flotante.
|
|
||||||
|
|
||||||
### PENNY
|
|
||||||
|
|
||||||
Asistente personal para recados y gestión del día a día. Servicio compartido.
|
|
||||||
|
|
||||||
### SENTINEL
|
|
||||||
|
|
||||||
Auditoría interna dual.
|
|
||||||
|
|
||||||
| Modo | Frecuencia | Alcance | Tecnología |
|
|
||||||
|------|------------|---------|------------|
|
|
||||||
| **LIGHT** | Cada 5 min | Todos | Reglas automáticas |
|
|
||||||
| **DEEP** | Cada 1 hora | Muestreo | LLM análisis |
|
|
||||||
|
|
||||||
**Categorías**: Integridad (I-*), Cumplimiento (C-*), Performance (P-*), Seguridad (S-*)
|
|
||||||
|
|
||||||
### GRACE
|
|
||||||
|
|
||||||
Extracción + comprensión mediante IA. **Nunca modifica**.
|
|
||||||
|
|
||||||
Ubicación: RunPod GPU (servicio compartido).
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Servicios Compartidos
|
|
||||||
|
|
||||||
### THE FACTORY
|
|
||||||
|
|
||||||
Taller de IA generativa iterativa.
|
|
||||||
|
|
||||||
```
|
|
||||||
Usuario define objetivo → Genera versión → Feedback → Nueva iteración → Repetir
|
|
||||||
```
|
|
||||||
|
|
||||||
### CIRCLE
|
|
||||||
|
|
||||||
Consejo de perspectivas para madurar decisiones.
|
|
||||||
|
|
||||||
```
|
|
||||||
Usuario plantea cuestión → N agentes con roles → Cada uno responde → Usuario recibe contraste
|
|
||||||
```
|
|
||||||
|
|
||||||
Roles ejemplo: El prudente, El arriesgado, El escéptico, El pragmático, El abogado del diablo
|
|
||||||
|
|
||||||
### Cloudville
|
|
||||||
|
|
||||||
Laboratorio de zumbados. Espacio experimental con reglas mínimas.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Interfaces
|
|
||||||
|
|
||||||
| Interfaz | Tipo | Función |
|
|
||||||
|----------|------|---------|
|
|
||||||
| **PACKET** | App móvil | Captura → CLARA/MARGARET (zero-retention) |
|
|
||||||
| **Architect App** | Sistema central | Crea instancias originales |
|
|
||||||
| **Vision Builder** | Diseño de vida | Objetivos mediante curación visual |
|
|
||||||
| **Mind Flow** | Flujos | Trabaja flujos → ALFRED/JARED |
|
|
||||||
| **Mind Link** | Compartición | Acceso a info para otros |
|
|
||||||
| **Mind Map** | Estructuras | Crear estructuras de datos visuales |
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
*Actualizado: 2025-12-21*
|
|
||||||
@@ -1,70 +0,0 @@
|
|||||||
# Estructuras de Datos
|
|
||||||
|
|
||||||
## BASES — Entidades Fundamentales
|
|
||||||
|
|
||||||
Lo que existe antes de todo. Sistema de referencias unívocas mediante hashes.
|
|
||||||
|
|
||||||
```
|
|
||||||
DEFINICIÓN ORIGINAL → SHA-256 → HASH UNÍVOCO (64 chars)
|
|
||||||
```
|
|
||||||
|
|
||||||
### Entidades
|
|
||||||
|
|
||||||
| Base | Hash | Función | Estado |
|
|
||||||
|------|------|---------|--------|
|
|
||||||
| **HST** | H_maestro | Etiquetas semánticas visuales | ✅ Implementado |
|
|
||||||
| **ITM** | H_item | Definiciones ideales | Futuro |
|
|
||||||
| **PLY** | H_player | Identidad de actores | Futuro |
|
|
||||||
| **LOC** | H_loc | Ubicaciones | Futuro |
|
|
||||||
| **FLG** | H_flag | Marcos jurídicos | Futuro |
|
|
||||||
|
|
||||||
### HST — Hash Semantic Tagging
|
|
||||||
|
|
||||||
| Grupo | Cantidad |
|
|
||||||
|-------|----------|
|
|
||||||
| `hst` | ~658 |
|
|
||||||
| `spe` | ~145 |
|
|
||||||
| `flg` | ~65 |
|
|
||||||
| `vsn` | ~84 |
|
|
||||||
| `vue` | ~21 |
|
|
||||||
|
|
||||||
**Tablas**: `hst_tags`, `hst_trees`, `hst_relations`, `hst_skins`
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Planos de Datos
|
|
||||||
|
|
||||||
| Plano | Nombre | Función |
|
|
||||||
|-------|--------|---------|
|
|
||||||
| T-N → T0 | ITM | Lo ideal, la partitura |
|
|
||||||
| Burocrático | MST | Documentos, hitos, estados |
|
|
||||||
| Físico | BCK | Acciones, evidencias |
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## PostgreSQL — Contexto Claude
|
|
||||||
|
|
||||||
Ver `admin/data-structures` para schema completo.
|
|
||||||
|
|
||||||
| Tabla | Función |
|
|
||||||
|-------|---------|
|
|
||||||
| `instancias` | Identidad Claude |
|
|
||||||
| `memoria` | Memoria largo plazo |
|
|
||||||
| `conocimiento` | RAG compartido |
|
|
||||||
| `conversaciones` | Sesiones |
|
|
||||||
| `mensajes_v2` | Mensajes |
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Almacenamiento R2
|
|
||||||
|
|
||||||
| Bucket | Uso |
|
|
||||||
|--------|-----|
|
|
||||||
| architect | Backups |
|
|
||||||
| hst | Imágenes |
|
|
||||||
| deck | Personal |
|
|
||||||
| corp | Empresarial |
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
*Actualizado: 2025-12-21*
|
|
||||||
@@ -1,46 +0,0 @@
|
|||||||
# Servicios TZZR
|
|
||||||
|
|
||||||
## Infraestructura
|
|
||||||
|
|
||||||
| Servidor | IP | Rol |
|
|
||||||
|----------|-----|-----|
|
|
||||||
| ARCHITECT | 69.62.126.110 | Coordinador, Gitea, PostgreSQL |
|
|
||||||
| DECK | 72.62.1.113 | CLARA, ALFRED, Nextcloud, Mailcow |
|
|
||||||
| CORP | 92.112.181.188 | MARGARET, FELDMAN, MASON, JARED |
|
|
||||||
| HST | 72.62.2.84 | Directus, API tags |
|
|
||||||
|
|
||||||
## Servicios por Servidor
|
|
||||||
|
|
||||||
### ARCHITECT (69.62.126.110)
|
|
||||||
- Gitea: 3000
|
|
||||||
- PostgreSQL: 5432
|
|
||||||
|
|
||||||
### DECK (72.62.1.113)
|
|
||||||
- CLARA: 5051 (context service)
|
|
||||||
- ALFRED: 5052 (task orchestrator)
|
|
||||||
- Nextcloud: 8080
|
|
||||||
- Mailcow: 25, 443, 993, 995
|
|
||||||
|
|
||||||
### CORP (92.112.181.188)
|
|
||||||
- MARGARET: 5051 (log entrada)
|
|
||||||
- JARED: 5052 (processor)
|
|
||||||
- MASON: 5053 (builder)
|
|
||||||
- FELDMAN: 5054 (contable v3.0)
|
|
||||||
- Directus: 8055
|
|
||||||
- Vaultwarden: 8081
|
|
||||||
- Shlink: 8082
|
|
||||||
|
|
||||||
### HST (72.62.2.84)
|
|
||||||
- Directus: 8055 (hst_images DB)
|
|
||||||
- Filebrowser: 8081
|
|
||||||
- nginx: 80/443
|
|
||||||
|
|
||||||
## GPU Services (RunPod)
|
|
||||||
|
|
||||||
| Servicio | Endpoint | Workers | GPU |
|
|
||||||
|----------|----------|---------|-----|
|
|
||||||
| GRACE | r00x4g3rrwkbyh | 2 | L4 |
|
|
||||||
| PENNY | 0mxhaokgsmgee3 | 2 | L4 |
|
|
||||||
| FACTORY | ddnuk6y35zi56a | 1 | L4 |
|
|
||||||
|
|
||||||
Código en: `s3://architect/gpu-services/`
|
|
||||||
@@ -1,133 +0,0 @@
|
|||||||
# Estructura de Credenciales
|
|
||||||
|
|
||||||
## Gestores de Secretos
|
|
||||||
|
|
||||||
| Nivel | Herramienta | Uso |
|
|
||||||
|-------|-------------|-----|
|
|
||||||
| Personal/Equipo | Proton Pass | Contraseñas externas |
|
|
||||||
| Self-hosted | HashiCorp Vault | Contraseñas autoalojadas |
|
|
||||||
| Aplicaciones | Infisical | Secretos internos |
|
|
||||||
|
|
||||||
## Infisical (key.tzzr.me)
|
|
||||||
|
|
||||||
Gestión centralizada de secretos para aplicaciones.
|
|
||||||
|
|
||||||
### Proyectos
|
|
||||||
|
|
||||||
| Proyecto | Contenido |
|
|
||||||
|----------|-----------|
|
|
||||||
| anthropic | API keys Claude |
|
|
||||||
| r2 | Credenciales Cloudflare R2 |
|
|
||||||
| windmill | Tokens Windmill |
|
|
||||||
| postgres | Conexiones BD |
|
|
||||||
|
|
||||||
### Acceso
|
|
||||||
|
|
||||||
```
|
|
||||||
URL: https://key.tzzr.me (o http://69.62.126.110:8082)
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Credenciales por Servidor
|
|
||||||
|
|
||||||
### ARCHITECT (69.62.126.110)
|
|
||||||
|
|
||||||
| Servicio | Credenciales |
|
|
||||||
|----------|--------------|
|
|
||||||
| PostgreSQL | User: nocodb / Pass: nocodb_secure_2024 / DB: nocodb |
|
|
||||||
| **Directus** | admin@tzzr.me / directus_admin_2024 |
|
|
||||||
| Gitea | token en Infisical |
|
|
||||||
| Windmill | token en Infisical |
|
|
||||||
| API Anthropic | /opt/tzzr/claude-code/api_key |
|
|
||||||
|
|
||||||
### DECK (72.62.1.113)
|
|
||||||
|
|
||||||
| Servicio | Ubicación |
|
|
||||||
|----------|-----------|
|
|
||||||
| SSH | root / [Proton Pass] |
|
|
||||||
| Mail-in-a-Box | admin panel |
|
|
||||||
|
|
||||||
### HST (72.62.2.84)
|
|
||||||
|
|
||||||
| Servicio | Ubicación |
|
|
||||||
|----------|-----------|
|
|
||||||
| SSH | root / [Proton Pass] |
|
|
||||||
| API | internal |
|
|
||||||
|
|
||||||
### CORP (92.112.181.188)
|
|
||||||
|
|
||||||
| Servicio | Ubicación |
|
|
||||||
|----------|-----------|
|
|
||||||
| SSH | root / [Proton Pass] |
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Directus (ARCHITECT)
|
|
||||||
|
|
||||||
```
|
|
||||||
URL: http://69.62.126.110:8055
|
|
||||||
Email: admin@tzzr.me
|
|
||||||
Password: directus_admin_2024
|
|
||||||
DB: PostgreSQL (nocodb)
|
|
||||||
```
|
|
||||||
|
|
||||||
### Tablas disponibles
|
|
||||||
|
|
||||||
| Tabla | Uso |
|
|
||||||
|-------|-----|
|
|
||||||
| instancias | Configuración de instancias Claude |
|
|
||||||
| conversaciones | Chats activos |
|
|
||||||
| mensajes_v2 | Mensajes de conversaciones |
|
|
||||||
| memoria | Memoria persistente |
|
|
||||||
| conocimiento | Base de conocimiento |
|
|
||||||
| contexto_ambiental | Contexto del sistema |
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Cloudflare R2
|
|
||||||
|
|
||||||
```
|
|
||||||
Account ID: 7dedae6030f5554d99d37e98a5232996
|
|
||||||
Endpoint: https://<account_id>.r2.cloudflarestorage.com
|
|
||||||
Credenciales: Infisical project "r2"
|
|
||||||
```
|
|
||||||
|
|
||||||
## RunPod
|
|
||||||
|
|
||||||
```
|
|
||||||
API Key: Infisical project "runpod"
|
|
||||||
```
|
|
||||||
|
|
||||||
## Anthropic
|
|
||||||
|
|
||||||
```
|
|
||||||
API Key: Infisical project "anthropic"
|
|
||||||
Archivo local: /opt/tzzr/claude-code/api_key
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Instancias Claude
|
|
||||||
|
|
||||||
Cada instancia tiene su configuración en PostgreSQL tabla `instancias`:
|
|
||||||
|
|
||||||
| Campo | Contenido |
|
|
||||||
|-------|-----------|
|
|
||||||
| system_prompt | Incluye credenciales SSH del servidor que construye |
|
|
||||||
| permisos | JSON con capacidades |
|
|
||||||
| modelo | sonnet/opus/haiku |
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Política de Rotación
|
|
||||||
|
|
||||||
| Tipo | Frecuencia |
|
|
||||||
|------|------------|
|
|
||||||
| SSH passwords | Manual, bajo demanda |
|
|
||||||
| API tokens | 90 días |
|
|
||||||
| JWT sessions | 24 horas |
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
*Actualizado: 2025-12-22*
|
|
||||||
@@ -1,82 +0,0 @@
|
|||||||
# Flujos de Trabajo
|
|
||||||
|
|
||||||
## Reglas de Ejecución por Instancia
|
|
||||||
|
|
||||||
### Principio Fundamental
|
|
||||||
|
|
||||||
**Cada instancia Claude solo ejecuta comandos directamente en su propio servidor.**
|
|
||||||
|
|
||||||
| Instancia | Servidor | IP | Puede ejecutar en |
|
|
||||||
|-----------|----------|-----|-------------------|
|
|
||||||
| architect | ARCHITECT | 69.62.126.110 | Solo ARCHITECT |
|
|
||||||
| hst | HST | 72.62.2.84 | Solo HST |
|
|
||||||
| deck | DECK | 72.62.1.113 | Solo DECK |
|
|
||||||
| corp | CORP | 92.112.181.188 | Solo CORP |
|
|
||||||
| runpod | RunPod | Variable | Solo sus pods |
|
|
||||||
| locker | ARCHITECT | 69.62.126.110 | Solo su contexto |
|
|
||||||
|
|
||||||
### Delegación de Tareas
|
|
||||||
|
|
||||||
Cuando una instancia necesita que se ejecute algo en otro servidor:
|
|
||||||
|
|
||||||
1. **NO ejecutar directamente** via SSH al otro servidor
|
|
||||||
2. **Enviar mensaje** a la instancia correspondiente via PostgreSQL
|
|
||||||
3. **Documentar** la tarea solicitada
|
|
||||||
4. **Esperar** confirmación de la otra instancia
|
|
||||||
|
|
||||||
### Ejemplo de Delegación
|
|
||||||
|
|
||||||
```sql
|
|
||||||
-- architect necesita que deck ejecute algo
|
|
||||||
INSERT INTO mensajes_v2 (conversacion_id, role, contenido)
|
|
||||||
SELECT id, 'user', 'Ejecuta X en tu servidor'
|
|
||||||
FROM conversaciones
|
|
||||||
WHERE instancia_id = 'deck' AND activa = true;
|
|
||||||
```
|
|
||||||
|
|
||||||
### Excepciones
|
|
||||||
|
|
||||||
- **Consultas de solo lectura**: Se permiten consultas SSH para verificar estado
|
|
||||||
- **Emergencias**: En caso de caída de una instancia, otra puede intervenir temporalmente
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Comunicación Entre Instancias
|
|
||||||
|
|
||||||
### Canal Principal: PostgreSQL
|
|
||||||
|
|
||||||
Tabla `mensajes_v2` con estructura de chat por conversación.
|
|
||||||
|
|
||||||
```
|
|
||||||
conversaciones (instancia_id) --> mensajes_v2 (conversacion_id)
|
|
||||||
```
|
|
||||||
|
|
||||||
### Flujo de Mensaje
|
|
||||||
|
|
||||||
1. Instancia origen inserta mensaje con role='user'
|
|
||||||
2. Windmill detecta mensaje pendiente
|
|
||||||
3. Windmill invoca Claude de la instancia destino
|
|
||||||
4. Respuesta se guarda con role='assistant'
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Windmill
|
|
||||||
|
|
||||||
### Triggers
|
|
||||||
|
|
||||||
| Trigger | Frecuencia | Función |
|
|
||||||
|---------|------------|---------|
|
|
||||||
| Mensaje nuevo | 30s | Procesar mensajes pendientes |
|
|
||||||
| Retry queue | 5m | Reintentar envíos fallidos |
|
|
||||||
| Heartbeat | 1h | Verificar estado de instancias |
|
|
||||||
|
|
||||||
### Endpoint
|
|
||||||
|
|
||||||
```
|
|
||||||
URL: https://flows.tzzr.me
|
|
||||||
Workspace: admins
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
*Actualizado: 2025-12-21*
|
|
||||||
@@ -1,37 +0,0 @@
|
|||||||
# Sistema TZZR
|
|
||||||
|
|
||||||
Documentación central del sistema TZZR - Arquitectura de construcción con Claude.
|
|
||||||
|
|
||||||
## Índice
|
|
||||||
|
|
||||||
| Documento | Contenido |
|
|
||||||
|-----------|-----------|
|
|
||||||
| [01-filosofia.md](01-filosofia.md) | Visión, principios, modelo de construcción |
|
|
||||||
| [02-componentes.md](02-componentes.md) | Catálogo de componentes del sistema |
|
|
||||||
| [03-datos.md](03-datos.md) | Estructuras de datos y schemas |
|
|
||||||
| [04-servicios.md](04-servicios.md) | Herramientas, servicios e infraestructura |
|
|
||||||
| [05-credenciales.md](05-credenciales.md) | Estructura de secretos y accesos |
|
|
||||||
|
|
||||||
## Concepto
|
|
||||||
|
|
||||||
```
|
|
||||||
TZZR = Sistema de construcción de arquitecturas personales/empresariales
|
|
||||||
|
|
||||||
Claude Instances → Construyen → Servidores Clonables → Funcionan Independientes
|
|
||||||
```
|
|
||||||
|
|
||||||
## Repos Relacionados
|
|
||||||
|
|
||||||
| Repo | Función |
|
|
||||||
|------|---------|
|
|
||||||
| tzzr/architect | Coordinación del equipo Claude |
|
|
||||||
| tzzr/deck | Servidor personal (clonable) |
|
|
||||||
| tzzr/corp | Servidor empresarial (clonable) |
|
|
||||||
| tzzr/hst | Tags semánticos maestros |
|
|
||||||
| tzzr/locker | Sistema de almacenamiento R2 |
|
|
||||||
| admin/architect-app | Código de la API Flask |
|
|
||||||
| admin/data-structures | Schema PostgreSQL detallado |
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
*Actualizado: 2025-12-23*
|
|
||||||
@@ -1,74 +0,0 @@
|
|||||||
# THE FACTORY - Trabajo Iterativo Generativo
|
|
||||||
|
|
||||||
## Descripción
|
|
||||||
Servicio de generación de imágenes usando modelos de difusión.
|
|
||||||
|
|
||||||
## Endpoint RunPod
|
|
||||||
- ID: `ddnuk6y35zi56a`
|
|
||||||
- URL: `https://api.runpod.ai/v2/ddnuk6y35zi56a/runsync`
|
|
||||||
- Workers: 1
|
|
||||||
- GPU: NVIDIA L4
|
|
||||||
|
|
||||||
## Código
|
|
||||||
Ubicación: `s3://architect/gpu-services/factory/code/handler.py`
|
|
||||||
|
|
||||||
## Tareas Disponibles
|
|
||||||
|
|
||||||
### image_generate
|
|
||||||
Genera imagen desde prompt.
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"input": {
|
|
||||||
"task": "image_generate",
|
|
||||||
"prompt": "a futuristic city at sunset",
|
|
||||||
"model": "sdxl-turbo",
|
|
||||||
"width": 1024,
|
|
||||||
"height": 1024,
|
|
||||||
"steps": 4,
|
|
||||||
"guidance": 0.0
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
### image_variant
|
|
||||||
Genera variante de imagen existente.
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"input": {
|
|
||||||
"task": "image_variant",
|
|
||||||
"image_base64": "...",
|
|
||||||
"prompt": "make it more colorful",
|
|
||||||
"strength": 0.5,
|
|
||||||
"model": "sdxl-turbo"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
### image_upscale
|
|
||||||
Aumenta resolución de imagen.
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"input": {
|
|
||||||
"task": "image_upscale",
|
|
||||||
"image_base64": "...",
|
|
||||||
"scale": 2
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
## Modelos Disponibles
|
|
||||||
- `sdxl-turbo` (default) - Rápido, 4 steps
|
|
||||||
- `sdxl` - Alta calidad
|
|
||||||
- `flux` - FLUX.1-schnell
|
|
||||||
|
|
||||||
## Respuesta
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"image_base64": "...",
|
|
||||||
"width": 1024,
|
|
||||||
"height": 1024,
|
|
||||||
"model": "sdxl-turbo",
|
|
||||||
"task": "image_generate",
|
|
||||||
"trace_id": "..."
|
|
||||||
}
|
|
||||||
```
|
|
||||||
@@ -1,722 +0,0 @@
|
|||||||
# 🏭 THE FACTORY
|
|
||||||
## Especificación Técnica Genérica v1.0
|
|
||||||
|
|
||||||
**Incubador Iterativo — Sistema SFE/HST Enterprise v5.0**
|
|
||||||
|
|
||||||
> *"Zero retención de datos. Todo entra, se procesa, se va."*
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Índice
|
|
||||||
|
|
||||||
1. [Visión General](#1-visión-general)
|
|
||||||
2. [Ciclo de Trabajo](#2-ciclo-de-trabajo)
|
|
||||||
3. [Modelo de Datos](#3-modelo-de-datos)
|
|
||||||
4. [Componentes Internos](#4-componentes-internos)
|
|
||||||
5. [Catálogo de Modelos](#5-catálogo-de-modelos)
|
|
||||||
6. [Integración con Contrato Común v1.2](#6-integración-con-contrato-común-v12)
|
|
||||||
7. [API HTTP](#7-api-http)
|
|
||||||
8. [Configuración](#8-configuración)
|
|
||||||
9. [Ejemplo de Uso Completo](#9-ejemplo-de-uso-completo)
|
|
||||||
10. [Próximos Pasos](#10-próximos-pasos)
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 1. Visión General
|
|
||||||
|
|
||||||
### 1.1 ¿Qué es The Factory?
|
|
||||||
|
|
||||||
The Factory es un **trabajador IA disciplinado** que ejecuta trabajo hasta alcanzar calidad. A diferencia de los sistemas tradicionales de generación única, The Factory implementa un **ciclo iterativo de producción-evaluación** hasta convergencia.
|
|
||||||
|
|
||||||
```
|
|
||||||
┌─────────────────────────────────────────────────────────────────┐
|
|
||||||
│ THE FACTORY │
|
|
||||||
│ │
|
|
||||||
│ • Recibe trabajo (Job) │
|
|
||||||
│ • Ejecuta ciclos iterativos │
|
|
||||||
│ • Evalúa cada iteración │
|
|
||||||
│ • Para cuando: conformidad | max ciclos | presupuesto │
|
|
||||||
│ • Devuelve resultados │
|
|
||||||
│ │
|
|
||||||
└─────────────────────────────────────────────────────────────────┘
|
|
||||||
```
|
|
||||||
|
|
||||||
| Característica | Descripción |
|
|
||||||
|----------------|-------------|
|
|
||||||
| **Naturaleza** | Incubador iterativo con ciclo de mejora continua |
|
|
||||||
| **Filosofía** | Zero retención — stateless entre Jobs |
|
|
||||||
| **Objetivo** | Producir artefactos de calidad mediante iteración |
|
|
||||||
| **Parada** | Por conformidad, límite de ciclos, o presupuesto |
|
|
||||||
|
|
||||||
### 1.2 Principios Fundamentales
|
|
||||||
|
|
||||||
| Principio | Descripción |
|
|
||||||
|-----------|-------------|
|
|
||||||
| **Stateless** | No retiene estado entre Jobs. Cada ejecución es independiente |
|
|
||||||
| **Determinista** | Mismo Job + misma semilla = mismo resultado |
|
|
||||||
| **Intercambiable** | Los modelos subyacentes pueden sustituirse sin romper el sistema |
|
|
||||||
| **Trazable** | Toda ejecución queda registrada vía trace_id |
|
|
||||||
| **No persiste** | Los archivos solo existen en el almacenamiento externo |
|
|
||||||
|
|
||||||
### 1.3 Arquitectura de Responsabilidades
|
|
||||||
|
|
||||||
```
|
|
||||||
THE CORP (el que encarga)
|
|
||||||
├── Tiene el espacio de trabajo
|
|
||||||
├── Tiene el log
|
|
||||||
├── Define el Job
|
|
||||||
└── Recibe los resultados
|
|
||||||
|
|
||||||
THE FACTORY (el que fabrica)
|
|
||||||
├── Lee de donde le dicen
|
|
||||||
├── Ejecuta ciclos
|
|
||||||
├── Escribe donde le dicen
|
|
||||||
└── No retiene NADA
|
|
||||||
|
|
||||||
STORAGE (el que persiste)
|
|
||||||
├── Almacena artefactos
|
|
||||||
├── Externo a Factory
|
|
||||||
└── Puede ser S3, Hostinger, local, etc.
|
|
||||||
```
|
|
||||||
|
|
||||||
| Componente | Rol | Responsabilidad |
|
|
||||||
|------------|-----|-----------------|
|
|
||||||
| **THE CORP** | El que encarga | Define Job, provee workspace, recibe resultados |
|
|
||||||
| **THE FACTORY** | El que fabrica | Ejecuta ciclos, evalúa, itera hasta convergencia |
|
|
||||||
| **STORAGE** | El que persiste | Almacena artefactos (externo a Factory) |
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 2. Ciclo de Trabajo
|
|
||||||
|
|
||||||
### 2.1 Flujo Principal
|
|
||||||
|
|
||||||
```
|
|
||||||
Job ──► EJECUTOR ──► Artefacto ──► EVALUADOR ──► ¿Converge?
|
|
||||||
│ │
|
|
||||||
│ ┌─────────────────────┘
|
|
||||||
│ │
|
|
||||||
│ Sí│No
|
|
||||||
│ │ │
|
|
||||||
│ ▼ └──────────────┐
|
|
||||||
│ FIN │
|
|
||||||
│ ▼
|
|
||||||
└─────────── Nueva iteración (con feedback)
|
|
||||||
```
|
|
||||||
|
|
||||||
#### Paso 1: Recepción del Job
|
|
||||||
|
|
||||||
The Factory recibe un Job que contiene:
|
|
||||||
- **Semilla**: Instrucción inicial / prompt
|
|
||||||
- **Objetivo**: Criterio de éxito (qué es "listo")
|
|
||||||
- **Función**: Tipo de generación (texto, imagen, audio, video)
|
|
||||||
- **Límites**: Ciclos máximos, presupuesto, timeout
|
|
||||||
- **Referencias**: URLs de entrada/salida
|
|
||||||
|
|
||||||
#### Paso 2: Ejecución
|
|
||||||
|
|
||||||
El **Ejecutor** toma la semilla (y feedback previo si existe) y produce un artefacto. Es agnóstico del modelo — puede usar cualquier LLM, generador de imagen, audio o video.
|
|
||||||
|
|
||||||
#### Paso 3: Evaluación
|
|
||||||
|
|
||||||
El **Evaluador** (Comité) analiza el artefacto contra el objetivo definido:
|
|
||||||
- Determina si **converge** (cumple criterios) o no
|
|
||||||
- Si no converge, genera **feedback estructurado** para el Ejecutor
|
|
||||||
|
|
||||||
#### Paso 4: Decisión
|
|
||||||
|
|
||||||
- **Si converge** → Termina y entrega
|
|
||||||
- **Si no converge** → Nueva iteración con feedback
|
|
||||||
- **Si límite alcanzado** → Entrega última versión funcional + informe
|
|
||||||
|
|
||||||
### 2.2 Criterios de Parada
|
|
||||||
|
|
||||||
| Criterio | Condición | Resultado |
|
|
||||||
|----------|-----------|-----------|
|
|
||||||
| **CONFORMITY** | El evaluador dice "listo" | Entrega artefacto final |
|
|
||||||
| **MAX_CYCLES** | Se agotan iteraciones permitidas | Entrega última funcional + informe |
|
|
||||||
| **BUDGET** | Se agota el presupuesto definido | Igual que MAX_CYCLES |
|
|
||||||
| **TIMEOUT** | Se agota el tiempo máximo | Igual que MAX_CYCLES |
|
|
||||||
| **ERROR** | Error irrecuperable | Entrega parcial + error |
|
|
||||||
| **CANCELLED** | Cancelación externa | Entrega estado actual |
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 3. Modelo de Datos
|
|
||||||
|
|
||||||
### 3.1 JobInput — La Semilla
|
|
||||||
|
|
||||||
Estructura de entrada que define todo lo necesario para iniciar un trabajo:
|
|
||||||
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"job_id": "uuid-v4",
|
|
||||||
"seed": "Instrucción inicial / prompt",
|
|
||||||
"objective": "Qué se considera éxito",
|
|
||||||
"function": "TEXT_GENERATION",
|
|
||||||
"input_refs": ["url/de/materia/prima"],
|
|
||||||
"output_ref": "url/donde/escribir",
|
|
||||||
"log_ref": "url/del/log",
|
|
||||||
"limits": {
|
|
||||||
"max_cycles": 10,
|
|
||||||
"budget_usd": 10.0,
|
|
||||||
"timeout_minutes": 60,
|
|
||||||
"min_confidence": 0.8
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
| Campo | Tipo | Requerido | Descripción |
|
|
||||||
|-------|------|-----------|-------------|
|
|
||||||
| `job_id` | UUID | Auto | Identificador único del Job |
|
|
||||||
| `seed` | string | Sí | Instrucción inicial / prompt |
|
|
||||||
| `objective` | string | Sí | Criterio de éxito (qué es "listo") |
|
|
||||||
| `function` | enum | Sí | Tipo de generación |
|
|
||||||
| `input_refs` | string[] | No | URLs de materia prima |
|
|
||||||
| `output_ref` | string | Sí | URL donde escribir resultado |
|
|
||||||
| `log_ref` | string | Sí | URL del log de ejecución |
|
|
||||||
| `limits` | Limits | Sí | Restricciones del Job |
|
|
||||||
|
|
||||||
### 3.2 Functions Soportadas
|
|
||||||
|
|
||||||
| Function | Descripción | Output típico |
|
|
||||||
|----------|-------------|---------------|
|
|
||||||
| `TEXT_GENERATION` | Generación de texto/código | .txt, .md, .json, .py |
|
|
||||||
| `IMAGE_GENERATION` | Generación de imágenes | .png, .jpg, .webp |
|
|
||||||
| `AUDIO_GENERATION` | Generación de audio/voz | .mp3, .wav, .opus |
|
|
||||||
| `VIDEO_GENERATION` | Generación de video | .mp4, .webm |
|
|
||||||
| `CODE_GENERATION` | Código con validación | Archivos de código |
|
|
||||||
| `DOCUMENT_GENERATION` | Documentos estructurados | .pdf, .docx |
|
|
||||||
| `MULTIMODAL` | Combinación de modalidades | Variable |
|
|
||||||
|
|
||||||
### 3.3 Limits — Restricciones
|
|
||||||
|
|
||||||
| Campo | Tipo | Default | Descripción |
|
|
||||||
|-------|------|---------|-------------|
|
|
||||||
| `max_cycles` | int | 10 | Máximo de iteraciones permitidas |
|
|
||||||
| `budget_usd` | float | 10.0 | Presupuesto máximo en USD |
|
|
||||||
| `timeout_minutes` | int | 60 | Tiempo máximo de ejecución |
|
|
||||||
| `min_confidence` | float | 0.8 | Confianza mínima para convergencia |
|
|
||||||
|
|
||||||
### 3.4 JobState — Estado en Tiempo Real
|
|
||||||
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"job_id": "uuid",
|
|
||||||
"status": "RUNNING",
|
|
||||||
"current_iteration": 3,
|
|
||||||
"spent_usd": 0.045,
|
|
||||||
"stop_reason": null,
|
|
||||||
"final_artifact_ref": null,
|
|
||||||
"last_functional_iteration": 2,
|
|
||||||
"created_at": "2025-12-16T10:30:00Z",
|
|
||||||
"started_at": "2025-12-16T10:30:01Z",
|
|
||||||
"completed_at": null
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
| Campo | Tipo | Descripción |
|
|
||||||
|-------|------|-------------|
|
|
||||||
| `job_id` | UUID | Identificador del Job |
|
|
||||||
| `status` | enum | PENDING \| RUNNING \| CONVERGED \| EXHAUSTED \| FAILED \| CANCELLED |
|
|
||||||
| `current_iteration` | int | Iteración actual (1-based) |
|
|
||||||
| `spent_usd` | float | Costo acumulado |
|
|
||||||
| `stop_reason` | enum | Razón de parada (si terminó) |
|
|
||||||
| `final_artifact_ref` | string | URL del artefacto final |
|
|
||||||
| `last_functional_iteration` | int | Última iteración sin errores graves |
|
|
||||||
| `created_at` | datetime | Momento de creación |
|
|
||||||
| `started_at` | datetime | Momento de inicio de procesamiento |
|
|
||||||
| `completed_at` | datetime | Momento de finalización |
|
|
||||||
|
|
||||||
### 3.5 JobResult — Resultado Final
|
|
||||||
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"job_id": "uuid",
|
|
||||||
"status": "CONVERGED",
|
|
||||||
"stop_reason": "CONFORMITY",
|
|
||||||
"converged": true,
|
|
||||||
"final_artifact_ref": "s3://bucket/output/artifact.md",
|
|
||||||
"last_functional_iteration": 3,
|
|
||||||
"total_iterations": 3,
|
|
||||||
"total_cost_usd": 0.045,
|
|
||||||
"total_duration_ms": 12500,
|
|
||||||
"created_at": "2025-12-16T10:30:00Z",
|
|
||||||
"started_at": "2025-12-16T10:30:01Z",
|
|
||||||
"completed_at": "2025-12-16T10:30:13Z"
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 4. Componentes Internos
|
|
||||||
|
|
||||||
### 4.1 JobManager — El Orquestador
|
|
||||||
|
|
||||||
El JobManager es el componente central que gestiona el ciclo de vida de los Jobs:
|
|
||||||
|
|
||||||
```python
|
|
||||||
class JobManager:
|
|
||||||
async def submit_job(input: JobInput) -> JobState
|
|
||||||
async def get_job_status(job_id: str) -> JobState
|
|
||||||
async def cancel_job(job_id: str) -> bool
|
|
||||||
def get_job_result(job_id: str) -> JobResult
|
|
||||||
```
|
|
||||||
|
|
||||||
| Método | Descripción |
|
|
||||||
|--------|-------------|
|
|
||||||
| `submit_job(input)` | Recibe y encola un Job para procesamiento |
|
|
||||||
| `get_job_status(id)` | Obtiene el estado actual de un Job |
|
|
||||||
| `cancel_job(id)` | Cancela un Job en ejecución |
|
|
||||||
| `get_job_result(id)` | Obtiene el resultado final de un Job completado |
|
|
||||||
|
|
||||||
### 4.2 Executor — El Productor
|
|
||||||
|
|
||||||
El Executor es responsable de generar artefactos. Es agnóstico del modelo subyacente.
|
|
||||||
|
|
||||||
#### Interfaz
|
|
||||||
|
|
||||||
```python
|
|
||||||
async def execute(job_input: JobInput, iter_input: IterationInput) -> IterationOutput
|
|
||||||
```
|
|
||||||
|
|
||||||
#### IterationInput
|
|
||||||
|
|
||||||
| Campo | Tipo | Descripción |
|
|
||||||
|-------|------|-------------|
|
|
||||||
| `iteration_number` | int | Número de iteración actual |
|
|
||||||
| `seed` | string | Semilla original del Job |
|
|
||||||
| `previous_feedback` | string? | Feedback de la evaluación anterior |
|
|
||||||
| `accumulated_context` | dict | Contexto acumulado entre iteraciones |
|
|
||||||
|
|
||||||
#### IterationOutput
|
|
||||||
|
|
||||||
| Campo | Tipo | Descripción |
|
|
||||||
|-------|------|-------------|
|
|
||||||
| `artifact_ref` | string | URL del artefacto generado |
|
|
||||||
| `artifact_hash` | string | SHA-256 del artefacto |
|
|
||||||
| `executor_model` | string | Modelo usado (ej: "claude-sonnet-4") |
|
|
||||||
| `cost_usd` | float | Costo de esta iteración |
|
|
||||||
| `metadata` | dict | Metadatos adicionales |
|
|
||||||
|
|
||||||
### 4.3 Evaluator — El Comité
|
|
||||||
|
|
||||||
El Evaluator analiza artefactos y determina convergencia.
|
|
||||||
|
|
||||||
#### Interfaz
|
|
||||||
|
|
||||||
```python
|
|
||||||
async def evaluate(job_input: JobInput, eval_input: EvaluationInput) -> EvaluationResult
|
|
||||||
```
|
|
||||||
|
|
||||||
#### EvaluationInput
|
|
||||||
|
|
||||||
| Campo | Tipo | Descripción |
|
|
||||||
|-------|------|-------------|
|
|
||||||
| `job_objective` | string | Objetivo definido en el Job |
|
|
||||||
| `iteration_number` | int | Número de iteración actual |
|
|
||||||
| `artifact_ref` | string | URL del artefacto a evaluar |
|
|
||||||
| `previous_evaluations` | list | Historial de evaluaciones anteriores |
|
|
||||||
|
|
||||||
#### EvaluationResult
|
|
||||||
|
|
||||||
| Campo | Tipo | Descripción |
|
|
||||||
|-------|------|-------------|
|
|
||||||
| `converged` | bool | True si el artefacto cumple el objetivo |
|
|
||||||
| `confidence` | float | Nivel de confianza (0.0 - 1.0) |
|
|
||||||
| `strengths` | string[] | Aspectos positivos identificados |
|
|
||||||
| `weaknesses` | string[] | Aspectos a mejorar |
|
|
||||||
| `feedback_for_executor` | string | Instrucciones para la siguiente iteración |
|
|
||||||
| `evaluator_model` | string | Modelo usado para evaluar |
|
|
||||||
| `cost_usd` | float | Costo de la evaluación |
|
|
||||||
|
|
||||||
### 4.4 FactoryLogger — Trazabilidad
|
|
||||||
|
|
||||||
El Logger registra cada evento del ciclo de vida:
|
|
||||||
|
|
||||||
| EventType | Momento | Datos registrados |
|
|
||||||
|-----------|---------|-------------------|
|
|
||||||
| `JOB_CREATED` | Al recibir Job | seed, objective, limits |
|
|
||||||
| `JOB_STARTED` | Al iniciar procesamiento | timestamp |
|
|
||||||
| `ITERATION_START` | Al iniciar iteración | iteration_number |
|
|
||||||
| `EXECUTOR_CALL` | Al llamar Ejecutor | has_feedback |
|
|
||||||
| `EXECUTOR_RESPONSE` | Al recibir artefacto | artifact_ref, model, cost |
|
|
||||||
| `EVALUATOR_CALL` | Al llamar Evaluador | artifact_ref |
|
|
||||||
| `EVALUATOR_RESPONSE` | Al recibir evaluación | converged, confidence |
|
|
||||||
| `ITERATION_END` | Al terminar iteración | converged, total_spent |
|
|
||||||
| `JOB_CONVERGED` | Al alcanzar conformidad | final_artifact_ref |
|
|
||||||
| `JOB_MAX_ITERATIONS` | Al agotar ciclos | last_iteration |
|
|
||||||
| `JOB_BUDGET_EXHAUSTED` | Al agotar presupuesto | spent_usd |
|
|
||||||
| `JOB_ERROR` | Al ocurrir error | error, phase |
|
|
||||||
| `JOB_COMPLETED` | Al finalizar | status, stop_reason, totals |
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 5. Catálogo de Modelos
|
|
||||||
|
|
||||||
The Factory es agnóstico de modelos. Estos son los recomendados por modalidad:
|
|
||||||
|
|
||||||
### 5.1 LLMs (Texto/Código)
|
|
||||||
|
|
||||||
| Modelo | Proveedor | Tipo | Fortalezas |
|
|
||||||
|--------|-----------|------|------------|
|
|
||||||
| Claude Sonnet 4 | Anthropic | API | Razonamiento, código, instrucciones |
|
|
||||||
| GPT-4o | OpenAI | API | Multimodal, velocidad, generalista |
|
|
||||||
| Gemini 2.5 Pro | Google | API | Contexto enorme (1M tokens) |
|
|
||||||
| Llama 3.3 70B | Meta | Local/API | Open source, privacidad |
|
|
||||||
| Qwen 2.5 72B | Alibaba | Local/API | Multilingüe, código |
|
|
||||||
|
|
||||||
### 5.2 Imagen
|
|
||||||
|
|
||||||
| Modelo | Proveedor | Tipo | Fortalezas |
|
|
||||||
|--------|-----------|------|------------|
|
|
||||||
| Flux 1.1 Pro | Black Forest | API | Calidad, texto en imagen |
|
|
||||||
| DALL-E 3 | OpenAI | API | Facilidad, integración |
|
|
||||||
| Flux Schnell | Black Forest | Local | Rápido, buena calidad |
|
|
||||||
| Stable Diffusion XL | Stability | Local | Personalizable, LoRAs |
|
|
||||||
|
|
||||||
### 5.3 Audio
|
|
||||||
|
|
||||||
| Modelo | Proveedor | Tipo | Fortalezas |
|
|
||||||
|--------|-----------|------|------------|
|
|
||||||
| ElevenLabs | ElevenLabs | API | Voces naturales, clonación |
|
|
||||||
| XTTS-v2 | Coqui | Local | Multilingüe, privacidad |
|
|
||||||
| Suno | Suno | API | Generación musical |
|
|
||||||
| Faster-Whisper | SYSTRAN | Local | STT rápido y preciso |
|
|
||||||
|
|
||||||
### 5.4 Video
|
|
||||||
|
|
||||||
| Modelo | Proveedor | Tipo | Fortalezas |
|
|
||||||
|--------|-----------|------|------------|
|
|
||||||
| Runway Gen-3 | Runway | API | Calidad cinematográfica |
|
|
||||||
| Kling 1.6 | Kuaishou | API | Duración, coherencia |
|
|
||||||
| Pika | Pika Labs | API | Efectos, estilización |
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 6. Integración con Contrato Común v1.2
|
|
||||||
|
|
||||||
Para integrarse con sistemas externos (como Jarvis/Alfred), The Factory puede adaptar sus estructuras al Contrato Común v1.2.
|
|
||||||
|
|
||||||
### 6.1 Mapeo JobInput → Envelope
|
|
||||||
|
|
||||||
| JobInput | Envelope v1.2 | Transformación |
|
|
||||||
|----------|---------------|----------------|
|
|
||||||
| `job_id` | `envelope.trace_id` | Directo |
|
|
||||||
| `function` | `routing.module` | Mapeo (TEXT_GENERATION → TEXT_GEN) |
|
|
||||||
| `seed + objective` | `payload.content` | Combinar en estructura |
|
|
||||||
| `limits` | `envelope.ttl_ms + context` | Transformar a milisegundos |
|
|
||||||
| `input_refs` | `storage.input_ref` | Primera referencia |
|
|
||||||
| `output_ref` | `storage.output_ref` | Directo |
|
|
||||||
|
|
||||||
### 6.2 Mapeo Function → Module
|
|
||||||
|
|
||||||
| Factory Function | Jarvis Module | Fallback Chain sugerida |
|
|
||||||
|------------------|---------------|-------------------------|
|
|
||||||
| `TEXT_GENERATION` | `TEXT_GEN` | CLAUDE_SONNET → GPT4O → LLAMA_70B |
|
|
||||||
| `IMAGE_GENERATION` | `IMAGE_GEN` | FLUX_PRO → DALLE3 → FLUX_LOCAL |
|
|
||||||
| `AUDIO_GENERATION` | `AUDIO_GEN` | ELEVENLABS → XTTS_LOCAL |
|
|
||||||
| `VIDEO_GENERATION` | `VIDEO_GEN` | RUNWAY → KLING |
|
|
||||||
| `CODE_GENERATION` | `TEXT_GEN + VALIDATOR` | CLAUDE → GPT4O |
|
|
||||||
|
|
||||||
### 6.3 Envelope de Ejemplo
|
|
||||||
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"contract_version": "1.2",
|
|
||||||
"profile": "FULL",
|
|
||||||
|
|
||||||
"envelope": {
|
|
||||||
"trace_id": "job_id_aquí",
|
|
||||||
"parent_trace_id": null,
|
|
||||||
"step_id": "uuid-paso",
|
|
||||||
"step_index": 1,
|
|
||||||
"total_steps": 1,
|
|
||||||
"idempotency_key": "sha256_del_seed",
|
|
||||||
"timestamp_init": "2025-12-16T10:30:00.000Z",
|
|
||||||
"ttl_ms": 3600000
|
|
||||||
},
|
|
||||||
|
|
||||||
"routing": {
|
|
||||||
"module": "TEXT_GEN",
|
|
||||||
"version": "1.0",
|
|
||||||
"provider_preference": ["anthropic", "openai", "local"],
|
|
||||||
"fallback_chain": ["CLAUDE_SONNET", "GPT4O", "LLAMA_70B"],
|
|
||||||
"max_fallback_level": 2
|
|
||||||
},
|
|
||||||
|
|
||||||
"payload": {
|
|
||||||
"type": "structured",
|
|
||||||
"content": {
|
|
||||||
"seed": "Escribe un haiku...",
|
|
||||||
"objective": "Un haiku válido 5-7-5..."
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
"storage": {
|
|
||||||
"input_location": "external",
|
|
||||||
"output_location": "external",
|
|
||||||
"output_ref": "s3://bucket/output/"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
### 6.4 Adapter Pattern
|
|
||||||
|
|
||||||
Se recomienda implementar un `ContractAdapter` que permita:
|
|
||||||
|
|
||||||
- Recibir Jobs en formato nativo de Factory
|
|
||||||
- Transformar a Envelope v1.2 para llamadas a Jarvis
|
|
||||||
- Recibir respuestas en formato Envelope
|
|
||||||
- Transformar a estructuras internas de Factory
|
|
||||||
|
|
||||||
```python
|
|
||||||
class ContractAdapter:
|
|
||||||
def job_to_envelope(job: JobInput, iteration: int) -> dict
|
|
||||||
def envelope_to_iteration_output(envelope: dict) -> IterationOutput
|
|
||||||
def envelope_to_evaluation_result(envelope: dict) -> EvaluationResult
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 7. API HTTP
|
|
||||||
|
|
||||||
### 7.1 Endpoints
|
|
||||||
|
|
||||||
| Método | Endpoint | Descripción |
|
|
||||||
|--------|----------|-------------|
|
|
||||||
| `GET` | `/health` | Health check |
|
|
||||||
| `GET` | `/` | Información del sistema |
|
|
||||||
| `POST` | `/jobs` | Crear nuevo Job |
|
|
||||||
| `GET` | `/jobs/{job_id}` | Obtener estado de Job |
|
|
||||||
| `DELETE` | `/jobs/{job_id}` | Cancelar Job |
|
|
||||||
| `GET` | `/jobs/{job_id}/result` | Obtener resultado final |
|
|
||||||
|
|
||||||
### 7.2 POST /jobs — Crear Job
|
|
||||||
|
|
||||||
#### Request
|
|
||||||
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"seed": "Escribe un haiku sobre programación",
|
|
||||||
"objective": "Un haiku válido (5-7-5 sílabas) sobre programación",
|
|
||||||
"function": "TEXT_GENERATION",
|
|
||||||
"output_ref": "/workspace/output/haiku.txt",
|
|
||||||
"log_ref": "/workspace/logs/job_001.json",
|
|
||||||
"limits": {
|
|
||||||
"max_cycles": 5,
|
|
||||||
"budget_usd": 1.0
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
#### Response (202 Accepted)
|
|
||||||
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"job_id": "550e8400-e29b-41d4-a716-446655440000",
|
|
||||||
"status": "PENDING",
|
|
||||||
"created_at": "2025-12-16T10:30:00Z"
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
### 7.3 GET /jobs/{id} — Estado
|
|
||||||
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"job_id": "550e8400-e29b-41d4-a716-446655440000",
|
|
||||||
"status": "RUNNING",
|
|
||||||
"current_iteration": 2,
|
|
||||||
"spent_usd": 0.023,
|
|
||||||
"created_at": "2025-12-16T10:30:00Z",
|
|
||||||
"started_at": "2025-12-16T10:30:01Z"
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
### 7.4 GET /jobs/{id}/result — Resultado
|
|
||||||
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"job_id": "550e8400-e29b-41d4-a716-446655440000",
|
|
||||||
"status": "CONVERGED",
|
|
||||||
"stop_reason": "CONFORMITY",
|
|
||||||
"converged": true,
|
|
||||||
"final_artifact_ref": "/workspace/output/haiku.txt",
|
|
||||||
"total_iterations": 3,
|
|
||||||
"total_cost_usd": 0.045,
|
|
||||||
"total_duration_ms": 12500
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 8. Configuración
|
|
||||||
|
|
||||||
### 8.1 Variables de Entorno
|
|
||||||
|
|
||||||
| Variable | Default | Descripción |
|
|
||||||
|----------|---------|-------------|
|
|
||||||
| `ENVIRONMENT` | development | Entorno de ejecución |
|
|
||||||
| `DEBUG` | false | Modo debug |
|
|
||||||
| `WORKSPACE_PATH` | /workspace | Ruta del workspace |
|
|
||||||
| `LOG_LEVEL` | INFO | Nivel de logging |
|
|
||||||
| `DEFAULT_MAX_CYCLES` | 10 | Ciclos por defecto |
|
|
||||||
| `DEFAULT_BUDGET_USD` | 10.0 | Presupuesto por defecto |
|
|
||||||
| `DEFAULT_TIMEOUT_MIN` | 60 | Timeout por defecto |
|
|
||||||
|
|
||||||
### 8.2 API Keys
|
|
||||||
|
|
||||||
| Variable | Descripción |
|
|
||||||
|----------|-------------|
|
|
||||||
| `OPENROUTER_API_KEY` | API key para OpenRouter (multi-modelo) |
|
|
||||||
| `ANTHROPIC_API_KEY` | API key de Anthropic (Claude) |
|
|
||||||
| `OPENAI_API_KEY` | API key de OpenAI |
|
|
||||||
| `REPLICATE_API_KEY` | API key de Replicate |
|
|
||||||
| `FAL_API_KEY` | API key de Fal.ai |
|
|
||||||
|
|
||||||
### 8.3 Configuración de Modelos
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Modelos por función
|
|
||||||
EXECUTOR_MODEL_TEXT=claude-sonnet-4-20250514
|
|
||||||
EXECUTOR_MODEL_IMAGE=flux-1.1-pro
|
|
||||||
EXECUTOR_MODEL_AUDIO=elevenlabs-multilingual-v2
|
|
||||||
EXECUTOR_MODEL_VIDEO=runway-gen3
|
|
||||||
|
|
||||||
# Modelo del evaluador
|
|
||||||
EVALUATOR_MODEL=claude-sonnet-4-20250514
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 9. Ejemplo de Uso Completo
|
|
||||||
|
|
||||||
### Escenario: Generación de Artículo Técnico
|
|
||||||
|
|
||||||
#### 1. Enviar Job
|
|
||||||
|
|
||||||
```bash
|
|
||||||
POST /jobs
|
|
||||||
```
|
|
||||||
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"seed": "Escribe un artículo técnico de 1000 palabras sobre el estado actual de la IA generativa en 2025",
|
|
||||||
"objective": "Artículo bien estructurado, técnicamente preciso, con introducción, desarrollo y conclusión. Debe mencionar modelos actuales y tendencias.",
|
|
||||||
"function": "TEXT_GENERATION",
|
|
||||||
"output_ref": "s3://bucket/articles/ai-2025.md",
|
|
||||||
"log_ref": "s3://bucket/logs/job-article.json",
|
|
||||||
"limits": {
|
|
||||||
"max_cycles": 5,
|
|
||||||
"budget_usd": 2.0
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
#### 2. Iteración 1
|
|
||||||
|
|
||||||
- **Ejecutor**: Genera primer borrador
|
|
||||||
- **Evaluador**:
|
|
||||||
- Confianza: 0.6
|
|
||||||
- Fortalezas: Buena estructura básica
|
|
||||||
- Debilidades: Falta profundidad técnica, conclusión débil
|
|
||||||
- **No converge**
|
|
||||||
|
|
||||||
#### 3. Iteración 2
|
|
||||||
|
|
||||||
- **Ejecutor**: Recibe feedback, mejora secciones técnicas
|
|
||||||
- **Evaluador**:
|
|
||||||
- Confianza: 0.75
|
|
||||||
- Fortalezas: Mejor contenido técnico
|
|
||||||
- Debilidades: Conclusión aún genérica
|
|
||||||
- **No converge**
|
|
||||||
|
|
||||||
#### 4. Iteración 3
|
|
||||||
|
|
||||||
- **Ejecutor**: Refuerza conclusión con proyecciones específicas
|
|
||||||
- **Evaluador**:
|
|
||||||
- Confianza: 0.92
|
|
||||||
- Fortalezas: Cumple todos los criterios
|
|
||||||
- Debilidades: Ninguna significativa
|
|
||||||
- **¡CONVERGE!**
|
|
||||||
|
|
||||||
#### 5. Resultado Final
|
|
||||||
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"job_id": "550e8400-e29b-41d4-a716-446655440000",
|
|
||||||
"status": "CONVERGED",
|
|
||||||
"stop_reason": "CONFORMITY",
|
|
||||||
"converged": true,
|
|
||||||
"final_artifact_ref": "s3://bucket/articles/ai-2025.md",
|
|
||||||
"total_iterations": 3,
|
|
||||||
"total_cost_usd": 0.18,
|
|
||||||
"total_duration_ms": 45000
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 10. Próximos Pasos
|
|
||||||
|
|
||||||
### 10.1 Este Documento (Especificación Genérica) ✅
|
|
||||||
|
|
||||||
- [x] Definición de arquitectura y componentes
|
|
||||||
- [x] Modelo de datos completo
|
|
||||||
- [x] Ciclo de trabajo y criterios de parada
|
|
||||||
- [x] API HTTP
|
|
||||||
- [x] Catálogo de modelos
|
|
||||||
- [x] Mapeo a Contrato Común v1.2
|
|
||||||
|
|
||||||
### 10.2 Siguiente: Implementación RunPod
|
|
||||||
|
|
||||||
- [ ] Dockerfile optimizado para GPU
|
|
||||||
- [ ] Handler serverless para RunPod
|
|
||||||
- [ ] Workers especializados por modalidad
|
|
||||||
- [ ] Configuración de endpoints
|
|
||||||
- [ ] Gestión de modelos locales
|
|
||||||
|
|
||||||
### 10.3 Futuro: Integración con Alfred
|
|
||||||
|
|
||||||
- [ ] Workflow n8n para invocar Factory
|
|
||||||
- [ ] Webhooks de callback
|
|
||||||
- [ ] Logging a SYS_LOG
|
|
||||||
- [ ] Persistencia de artefactos en Hostinger
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Anexo: Diagrama de Secuencia
|
|
||||||
|
|
||||||
```
|
|
||||||
┌──────┐ ┌───────────┐ ┌──────────┐ ┌───────────┐
|
|
||||||
│ CORP │ │ JobManager│ │ Executor │ │ Evaluator │
|
|
||||||
└──┬───┘ └─────┬─────┘ └────┬─────┘ └─────┬─────┘
|
|
||||||
│ │ │ │
|
|
||||||
│ submit_job() │ │ │
|
|
||||||
│──────────────>│ │ │
|
|
||||||
│ │ │ │
|
|
||||||
│ │────────────────────────────────────────┐
|
|
||||||
│ │ LOOP [hasta convergencia] │
|
|
||||||
│ │ │ │ │
|
|
||||||
│ │ execute() │ │ │
|
|
||||||
│ │───────────────>│ │ │
|
|
||||||
│ │ │ │ │
|
|
||||||
│ │ artifact │ │ │
|
|
||||||
│ │<───────────────│ │ │
|
|
||||||
│ │ │ │ │
|
|
||||||
│ │ evaluate() │ │ │
|
|
||||||
│ │───────────────────────────────-->│ │
|
|
||||||
│ │ │ │ │
|
|
||||||
│ │ result │ │ │
|
|
||||||
│ │<─────────────────────────────────│ │
|
|
||||||
│ │────────────────────────────────────────┘
|
|
||||||
│ │ │ │
|
|
||||||
│ JobResult │ │ │
|
|
||||||
│<──────────────│ │ │
|
|
||||||
│ │ │ │
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
**Sistema SFE/HST Enterprise v5.0**
|
|
||||||
*Documento generado: Diciembre 2025*
|
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -1,153 +0,0 @@
|
|||||||
# VISION BUILDER
|
|
||||||
|
|
||||||

|
|
||||||
|
|
||||||
|
|
||||||
**Interfaz de Diseño de Vida - Ecosistema TZZR**
|
|
||||||
|
|
||||||
## Descripción
|
|
||||||
|
|
||||||
Vision Builder es la **interfaz principal** para crear y gestionar visiones personales que se transforman en acciones concretas. Conecta con THE FACTORY para refinar iterativamente cada visión hasta que sea coherente y accionable.
|
|
||||||
|
|
||||||
## Concepto
|
|
||||||
|
|
||||||
```
|
|
||||||
USUARIO DESCRIBE VISIÓN
|
|
||||||
│
|
|
||||||
▼
|
|
||||||
THE FACTORY REFINA (3-5 iteraciones)
|
|
||||||
│
|
|
||||||
▼
|
|
||||||
SE GENERAN MST (Milestones)
|
|
||||||
│
|
|
||||||
▼
|
|
||||||
CADA MST TIENE ACCIONES + HÁBITOS
|
|
||||||
│
|
|
||||||
▼
|
|
||||||
USUARIO VALIDA CON BCK (Evidencias)
|
|
||||||
```
|
|
||||||
|
|
||||||
## Tipos de Visión
|
|
||||||
|
|
||||||
| Tipo | Icono | Descripción | Ejemplo |
|
|
||||||
|------|-------|-------------|---------|
|
|
||||||
| fitness | 💪 | Transformación física | Perder peso, ganar músculo |
|
|
||||||
| career | 📈 | Desarrollo profesional | Ascenso, cambio de carrera |
|
|
||||||
| project | 🎯 | Proyecto específico | Lanzar MVP, escribir libro |
|
|
||||||
| habit | 🔄 | Crear/eliminar hábito | Meditar, dejar de fumar |
|
|
||||||
| learning | 📚 | Aprendizaje | Dominar Python, aprender idioma |
|
|
||||||
| finance | 💰 | Finanzas personales | Ahorrar, invertir |
|
|
||||||
|
|
||||||
## Acciones vs Hábitos
|
|
||||||
|
|
||||||
| Concepto | Frecuencia | Tracking | Ejemplo |
|
|
||||||
|----------|------------|----------|---------|
|
|
||||||
| **Acción** | Una vez | Completado/Pendiente | Comprar báscula |
|
|
||||||
| **Hábito** | Recurrente | Racha, % cumplimiento | Entrenar 5x/semana |
|
|
||||||
|
|
||||||
## Flujo Completo
|
|
||||||
|
|
||||||
```
|
|
||||||
1. VISIÓN: "Quiero transformar mi físico"
|
|
||||||
│
|
|
||||||
▼
|
|
||||||
2. FACTORY REFINA:
|
|
||||||
• Objetivo clarificado
|
|
||||||
• Motivación articulada
|
|
||||||
• Estado actual vs deseado
|
|
||||||
• Obstáculos identificados
|
|
||||||
• 3-5 Milestones con fechas
|
|
||||||
│
|
|
||||||
▼
|
|
||||||
3. MST (Milestones):
|
|
||||||
• Semana 1: Establecer hábitos base
|
|
||||||
• Semana 4: Completar primer ciclo PPL
|
|
||||||
• Semana 8: Revisar progreso
|
|
||||||
• Semana 12: Evaluación final
|
|
||||||
│
|
|
||||||
▼
|
|
||||||
4. ACCIONES + HÁBITOS:
|
|
||||||
ACCIONES (únicas): HÁBITOS (recurrentes):
|
|
||||||
• Comprar báscula • Entrenar 5x/semana
|
|
||||||
• Apuntarse al gym • Beber 2.5L agua/día
|
|
||||||
• Configurar app • Dormir 7+ horas
|
|
||||||
│
|
|
||||||
▼
|
|
||||||
5. BCK (Evidencias):
|
|
||||||
• Foto de progreso
|
|
||||||
• Registro de entrenamiento
|
|
||||||
• Screenshot de báscula
|
|
||||||
```
|
|
||||||
|
|
||||||
## Dimensiones de Evaluación
|
|
||||||
|
|
||||||
| Dimensión | Pregunta | Peso (fitness) |
|
|
||||||
|-----------|----------|----------------|
|
|
||||||
| clarity | ¿Se entiende? | 10% |
|
|
||||||
| coherence | ¿Las partes encajan? | 15% |
|
|
||||||
| completeness | ¿Está completa? | 10% |
|
|
||||||
| feasibility | ¿Es realizable? | 10% |
|
|
||||||
| actionability | ¿Se puede actuar? | 25% |
|
|
||||||
| motivation | ¿Inspira? | 25% |
|
|
||||||
|
|
||||||
## Schema SQL
|
|
||||||
|
|
||||||
```sql
|
|
||||||
deck_visiones (id, titulo, tipo, contenido_refinado, estado, progreso)
|
|
||||||
deck_milestones (id, vision_id, titulo, dia_relativo, criterio_exito)
|
|
||||||
deck_acciones (id, milestone_id, titulo, tipo, prioridad, estado)
|
|
||||||
deck_habitos (id, vision_id, titulo, frecuencia_tipo, racha_actual)
|
|
||||||
deck_habito_registros (id, habito_id, fecha, completado, valor)
|
|
||||||
deck_bck (id, vision_id, tipo, titulo, imagen_ref, datos)
|
|
||||||
```
|
|
||||||
|
|
||||||
## Estructura
|
|
||||||
|
|
||||||
```
|
|
||||||
vision-builder/
|
|
||||||
├── src/
|
|
||||||
│ ├── components/
|
|
||||||
│ │ ├── VisionBuilder.jsx # Principal
|
|
||||||
│ │ ├── VisionCreator.jsx # Formulario
|
|
||||||
│ │ ├── VisionDetail.jsx # Vista detalle
|
|
||||||
│ │ ├── MilestoneCard.jsx # Tarjeta MST
|
|
||||||
│ │ └── HabitTracker.jsx # Tracker hábitos
|
|
||||||
│ ├── hooks/
|
|
||||||
│ │ ├── useVisions.js
|
|
||||||
│ │ └── useFactory.js
|
|
||||||
│ └── api/
|
|
||||||
│ └── visionApi.js
|
|
||||||
├── styles/
|
|
||||||
└── docs/
|
|
||||||
```
|
|
||||||
|
|
||||||
## Integración
|
|
||||||
|
|
||||||
```javascript
|
|
||||||
// ALFRED detecta "crear visión" → envía a FACTORY
|
|
||||||
const alfred = new Alfred();
|
|
||||||
const vision = await alfred.process("crear visión fitness", {
|
|
||||||
title: "Transformación 2025",
|
|
||||||
seed: "Quiero perder 10kg...",
|
|
||||||
timeframe: 90
|
|
||||||
});
|
|
||||||
```
|
|
||||||
|
|
||||||
## Repositorios Relacionados
|
|
||||||
|
|
||||||
| Repo | Rol |
|
|
||||||
|------|-----|
|
|
||||||
| [deck](https://github.com/tzzrgit/deck) | Servidor que ejecuta Vision Builder |
|
|
||||||
| [the-factory](https://github.com/tzzrgit/the-factory) | Refina visiones |
|
|
||||||
| [contratos-comunes](https://github.com/tzzrgit/contratos-comunes) | Schema y componentes |
|
|
||||||
| [alfred](https://github.com/tzzrgit/alfred) | Orquestador |
|
|
||||||
|
|
||||||
## Roadmap
|
|
||||||
|
|
||||||
- [x] Concepto Vision → MST → Actions/Habits → BCK
|
|
||||||
- [x] UI component principal
|
|
||||||
- [x] Schema SQL
|
|
||||||
- [x] Integración FACTORY
|
|
||||||
- [ ] App móvil
|
|
||||||
- [ ] Notificaciones
|
|
||||||
- [ ] Templates de visión
|
|
||||||
@@ -1,517 +0,0 @@
|
|||||||
# VISIONES ARQUETÍPICAS UNIVERSALES
|
|
||||||
## Catálogo de Imágenes Aspiracionales Comunes
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Introducción
|
|
||||||
|
|
||||||
Las "visiones" son representaciones visuales de estados deseados que resuenan universalmente en el inconsciente colectivo. Estas imágenes aparecen repetidamente en vision boards, publicidad aspiracional, cine, sueños y fantasías de personas de todas las culturas.
|
|
||||||
|
|
||||||
Este catálogo organiza las visiones por categoría arquetípica, describiendo la imagen, su significado simbólico y las emociones que evoca.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 1. LIBERTAD FINANCIERA Y ABUNDANCIA
|
|
||||||
|
|
||||||
### 1.1 El Magnate frente a su Mansión
|
|
||||||
**Imagen**: Hombre/mujer elegantemente vestido de pie frente a una mansión con coches de lujo en el camino de entrada.
|
|
||||||
**Simbolismo**: Logro material, éxito tangible, llegada a la cima.
|
|
||||||
**Emociones**: Orgullo, satisfacción, poder, seguridad.
|
|
||||||
|
|
||||||
### 1.2 El Yate al Atardecer
|
|
||||||
**Imagen**: Persona relajada en la cubierta de un yate de lujo mientras el sol se pone sobre el mar.
|
|
||||||
**Simbolismo**: Libertad absoluta, escape del mundo ordinario, riqueza sin esfuerzo visible.
|
|
||||||
**Emociones**: Serenidad, logro, exclusividad.
|
|
||||||
|
|
||||||
### 1.3 El Jet Privado
|
|
||||||
**Imagen**: Empresario/a subiendo las escaleras de un jet privado o trabajando en su interior con laptop.
|
|
||||||
**Simbolismo**: Movilidad sin límites, tiempo como recurso controlado, élite global.
|
|
||||||
**Emociones**: Poder, eficiencia, estatus.
|
|
||||||
|
|
||||||
### 1.4 La Lluvia de Billetes
|
|
||||||
**Imagen**: Persona lanzando o siendo cubierta por billetes.
|
|
||||||
**Simbolismo**: Abundancia desbordante, dinero como flujo inagotable.
|
|
||||||
**Emociones**: Euforia, liberación, celebración.
|
|
||||||
|
|
||||||
### 1.5 El Maletín de Dinero
|
|
||||||
**Imagen**: Maletín abierto mostrando fajos de billetes ordenados.
|
|
||||||
**Simbolismo**: Riqueza concentrada, oportunidad, negocio cerrado.
|
|
||||||
**Emociones**: Anticipación, poder, posibilidad.
|
|
||||||
|
|
||||||
### 1.6 Las Llaves del Coche de Lujo
|
|
||||||
**Imagen**: Mano sosteniendo llaves de Ferrari/Lamborghini/Porsche con el coche de fondo.
|
|
||||||
**Simbolismo**: Acceso a lo exclusivo, premio por el esfuerzo.
|
|
||||||
**Emociones**: Logro, emoción, estatus.
|
|
||||||
|
|
||||||
### 1.7 La Vista desde el Penthouse
|
|
||||||
**Imagen**: Silueta contemplando ciudad iluminada desde ventanal de ático de lujo.
|
|
||||||
**Simbolismo**: Dominio sobre el mundo urbano, posición elevada literal y metafórica.
|
|
||||||
**Emociones**: Control, contemplación, éxito.
|
|
||||||
|
|
||||||
### 1.8 El Garaje de Colección
|
|
||||||
**Imagen**: Múltiples coches de lujo/clásicos en garaje impecable.
|
|
||||||
**Simbolismo**: Abundancia acumulada, pasión convertida en posesión.
|
|
||||||
**Emociones**: Orgullo, coleccionismo, logro material.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 2. AMOR Y CONEXIÓN ROMÁNTICA
|
|
||||||
|
|
||||||
### 2.1 La Pareja en la Playa al Atardecer
|
|
||||||
**Imagen**: Pareja caminando de la mano por la orilla mientras el sol se pone, siluetas contra el cielo naranja.
|
|
||||||
**Simbolismo**: Amor eterno, paz compartida, escape romántico.
|
|
||||||
**Emociones**: Amor, tranquilidad, conexión profunda.
|
|
||||||
|
|
||||||
### 2.2 El Beso bajo la Lluvia
|
|
||||||
**Imagen**: Pareja besándose apasionadamente mientras llueve, empapados.
|
|
||||||
**Simbolismo**: Pasión que ignora las circunstancias, entrega total.
|
|
||||||
**Emociones**: Pasión, romanticismo, intensidad.
|
|
||||||
|
|
||||||
### 2.3 El Desayuno en la Cama
|
|
||||||
**Imagen**: Pareja sonriente compartiendo desayuno en cama con sábanas blancas, luz matutina.
|
|
||||||
**Simbolismo**: Intimidad cotidiana, amor en lo simple, despertar juntos.
|
|
||||||
**Emociones**: Ternura, comodidad, intimidad.
|
|
||||||
|
|
||||||
### 2.4 La Propuesta de Matrimonio
|
|
||||||
**Imagen**: Persona arrodillada ofreciendo anillo, la otra sorprendida con manos en el rostro.
|
|
||||||
**Simbolismo**: Compromiso, momento de transición vital, amor declarado.
|
|
||||||
**Emociones**: Emoción, esperanza, amor.
|
|
||||||
|
|
||||||
### 2.5 La Cena Romántica con Velas
|
|
||||||
**Imagen**: Mesa para dos con velas, vino, vista espectacular (mar, ciudad, montaña).
|
|
||||||
**Simbolismo**: Ritual de conexión, atención exclusiva, celebración del amor.
|
|
||||||
**Emociones**: Romance, exclusividad, anticipación.
|
|
||||||
|
|
||||||
### 2.6 Bailando Solos
|
|
||||||
**Imagen**: Pareja bailando lentamente en salón vacío o bajo las estrellas.
|
|
||||||
**Simbolismo**: Mundo propio, sincronía, romance atemporal.
|
|
||||||
**Emociones**: Conexión, romance, intimidad.
|
|
||||||
|
|
||||||
### 2.7 El Viaje en Convertible
|
|
||||||
**Imagen**: Pareja en coche descapotable por carretera costera, cabello al viento.
|
|
||||||
**Simbolismo**: Aventura compartida, libertad en pareja, camino juntos.
|
|
||||||
**Emociones**: Libertad, alegría, complicidad.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 3. FAMILIA Y HOGAR
|
|
||||||
|
|
||||||
### 3.1 La Casa con Jardín y Valla Blanca
|
|
||||||
**Imagen**: Casa de suburbio americana con jardín verde, valla blanca, columpio.
|
|
||||||
**Simbolismo**: El "sueño americano", estabilidad, hogar propio.
|
|
||||||
**Emociones**: Seguridad, pertenencia, logro familiar.
|
|
||||||
|
|
||||||
### 3.2 La Familia en la Mesa
|
|
||||||
**Imagen**: Familia multigeneracional reunida alrededor de mesa abundante, riendo.
|
|
||||||
**Simbolismo**: Unión familiar, abundancia compartida, tradición.
|
|
||||||
**Emociones**: Amor, pertenencia, gratitud.
|
|
||||||
|
|
||||||
### 3.3 Padre/Madre con Hijo en Hombros
|
|
||||||
**Imagen**: Progenitor cargando niño en hombros, ambos sonriendo, fondo natural.
|
|
||||||
**Simbolismo**: Protección, conexión paternal/maternal, alegría de criar.
|
|
||||||
**Emociones**: Amor, orgullo, alegría.
|
|
||||||
|
|
||||||
### 3.4 El Primer Paso del Bebé
|
|
||||||
**Imagen**: Bebé dando primeros pasos hacia brazos extendidos de padres.
|
|
||||||
**Simbolismo**: Crecimiento, confianza, momento irrepetible.
|
|
||||||
**Emociones**: Ternura, emoción, orgullo.
|
|
||||||
|
|
||||||
### 3.5 La Cocina Familiar
|
|
||||||
**Imagen**: Familia cocinando junta, niños ayudando, ingredientes por todas partes.
|
|
||||||
**Simbolismo**: Colaboración doméstica, transmisión de tradiciones, hogar vivo.
|
|
||||||
**Emociones**: Calidez, diversión, conexión.
|
|
||||||
|
|
||||||
### 3.6 El Árbol de Navidad
|
|
||||||
**Imagen**: Familia reunida decorando árbol o abriendo regalos junto a él.
|
|
||||||
**Simbolismo**: Tradición, magia, unión en fechas especiales.
|
|
||||||
**Emociones**: Alegría, nostalgia, amor familiar.
|
|
||||||
|
|
||||||
### 3.7 El Perro de la Familia
|
|
||||||
**Imagen**: Golden Retriever/Labrador jugando con niños en jardín.
|
|
||||||
**Simbolismo**: Hogar completo, inocencia, compañía incondicional.
|
|
||||||
**Emociones**: Alegría, ternura, plenitud.
|
|
||||||
|
|
||||||
### 3.8 La Casa en Construcción
|
|
||||||
**Imagen**: Pareja revisando planos frente a casa en construcción.
|
|
||||||
**Simbolismo**: Futuro construyéndose, inversión en estabilidad, proyecto compartido.
|
|
||||||
**Emociones**: Esperanza, anticipación, logro.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 4. AVENTURA Y LIBERTAD
|
|
||||||
|
|
||||||
### 4.1 El Viajero frente al Mundo
|
|
||||||
**Imagen**: Persona con mochila de espaldas contemplando paisaje épico (montaña, valle, océano).
|
|
||||||
**Simbolismo**: Vastedad del mundo, pequeñez del individuo, aventura disponible.
|
|
||||||
**Emociones**: Asombro, libertad, posibilidad.
|
|
||||||
|
|
||||||
### 4.2 El Mapa con Chinchetas
|
|
||||||
**Imagen**: Mapa del mundo con múltiples chinchetas marcando lugares visitados.
|
|
||||||
**Simbolismo**: Vida vivida, exploración sistemática, coleccionismo de experiencias.
|
|
||||||
**Emociones**: Orgullo, anticipación, curiosidad.
|
|
||||||
|
|
||||||
### 4.3 El Pasaporte Lleno de Sellos
|
|
||||||
**Imagen**: Pasaporte abierto mostrando páginas llenas de sellos de inmigración.
|
|
||||||
**Simbolismo**: Ciudadano del mundo, movilidad, experiencia acumulada.
|
|
||||||
**Emociones**: Logro, nostalgia, anticipación.
|
|
||||||
|
|
||||||
### 4.4 El Salto del Acantilado
|
|
||||||
**Imagen**: Persona saltando desde acantilado al agua cristalina.
|
|
||||||
**Simbolismo**: Valentía, confianza en uno mismo, liberación de miedos.
|
|
||||||
**Emociones**: Adrenalina, libertad, coraje.
|
|
||||||
|
|
||||||
### 4.5 La Furgoneta en la Carretera
|
|
||||||
**Imagen**: Volkswagen vintage o van moderna en carretera infinita, desierto o costa.
|
|
||||||
**Simbolismo**: Vida nómada, libertad de lo material, aventura continua.
|
|
||||||
**Emociones**: Libertad, romanticismo, escape.
|
|
||||||
|
|
||||||
### 4.6 El Campamento bajo las Estrellas
|
|
||||||
**Imagen**: Tienda de campaña iluminada bajo cielo estrellado, Vía Láctea visible.
|
|
||||||
**Simbolismo**: Conexión con la naturaleza, simplicidad, asombro cósmico.
|
|
||||||
**Emociones**: Paz, asombro, conexión.
|
|
||||||
|
|
||||||
### 4.7 Las Huellas en la Arena
|
|
||||||
**Imagen**: Huellas de pies descalzos en playa virgen, extendiéndose hacia el horizonte.
|
|
||||||
**Simbolismo**: Camino propio, exploración solitaria, impermanencia.
|
|
||||||
**Emociones**: Libertad, reflexión, soledad positiva.
|
|
||||||
|
|
||||||
### 4.8 El Vuelo en Parapente/Paracaídas
|
|
||||||
**Imagen**: Persona volando sobre paisaje espectacular, brazos extendidos.
|
|
||||||
**Simbolismo**: Trascender límites físicos, perspectiva elevada, libertad máxima.
|
|
||||||
**Emociones**: Euforia, liberación, asombro.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 5. ÉXITO PROFESIONAL Y RECONOCIMIENTO
|
|
||||||
|
|
||||||
### 5.1 El CEO en su Oficina
|
|
||||||
**Imagen**: Ejecutivo/a en oficina de esquina con vistas panorámicas, postura de poder.
|
|
||||||
**Simbolismo**: Llegada a la cima corporativa, autoridad, logro profesional.
|
|
||||||
**Emociones**: Poder, satisfacción, control.
|
|
||||||
|
|
||||||
### 5.2 El Diploma/Título en la Pared
|
|
||||||
**Imagen**: Marco con diploma universitario o certificación profesional destacado.
|
|
||||||
**Simbolismo**: Logro académico, credenciales, conocimiento validado.
|
|
||||||
**Emociones**: Orgullo, legitimidad, logro.
|
|
||||||
|
|
||||||
### 5.3 El Aplauso del Público
|
|
||||||
**Imagen**: Persona en escenario recibiendo ovación de pie, luces sobre ella.
|
|
||||||
**Simbolismo**: Reconocimiento público, validación masiva, éxito visible.
|
|
||||||
**Emociones**: Orgullo, validación, euforia.
|
|
||||||
|
|
||||||
### 5.4 La Firma del Contrato
|
|
||||||
**Imagen**: Manos firmando documento importante, plumas de lujo, mesa ejecutiva.
|
|
||||||
**Simbolismo**: Acuerdo cerrado, compromiso formalizado, negocio exitoso.
|
|
||||||
**Emociones**: Logro, anticipación, poder.
|
|
||||||
|
|
||||||
### 5.5 El Emprendedor en su Startup
|
|
||||||
**Imagen**: Joven en oficina moderna/garage con pizarra llena de ideas, laptop, café.
|
|
||||||
**Simbolismo**: Creación propia, innovación, el "garage story" de Silicon Valley.
|
|
||||||
**Emociones**: Energía, posibilidad, determinación.
|
|
||||||
|
|
||||||
### 5.6 La Portada de Revista
|
|
||||||
**Imagen**: Portada de Forbes/Time con rostro propio, titular de éxito.
|
|
||||||
**Simbolismo**: Fama, reconocimiento mediático, historia de éxito.
|
|
||||||
**Emociones**: Orgullo, validación, llegada.
|
|
||||||
|
|
||||||
### 5.7 El Premio/Trofeo
|
|
||||||
**Imagen**: Persona sosteniendo trofeo, Oscar, medalla olímpica.
|
|
||||||
**Simbolismo**: Excelencia reconocida, ser el mejor, momento cumbre.
|
|
||||||
**Emociones**: Orgullo, emoción, logro máximo.
|
|
||||||
|
|
||||||
### 5.8 El "Before & After" del Negocio
|
|
||||||
**Imagen**: Comparativa de local humilde inicial vs. empresa exitosa actual.
|
|
||||||
**Simbolismo**: Transformación, crecimiento, historia de superación.
|
|
||||||
**Emociones**: Orgullo, nostalgia, logro.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 6. SALUD Y BIENESTAR FÍSICO
|
|
||||||
|
|
||||||
### 6.1 El Cuerpo Fitness en el Espejo
|
|
||||||
**Imagen**: Persona musculada/tonificada mirándose satisfecha en espejo de gimnasio.
|
|
||||||
**Simbolismo**: Dominio del cuerpo, disciplina recompensada, autoconfianza física.
|
|
||||||
**Emociones**: Orgullo, satisfacción, confianza.
|
|
||||||
|
|
||||||
### 6.2 El Corredor al Amanecer
|
|
||||||
**Imagen**: Silueta corriendo por sendero/playa mientras sale el sol.
|
|
||||||
**Simbolismo**: Disciplina matutina, energía vital, dominio del día.
|
|
||||||
**Emociones**: Energía, determinación, paz.
|
|
||||||
|
|
||||||
### 6.3 El Yoga en la Naturaleza
|
|
||||||
**Imagen**: Persona en postura de yoga sobre roca/playa/montaña, paisaje épico.
|
|
||||||
**Simbolismo**: Equilibrio mente-cuerpo, conexión con naturaleza, paz interior.
|
|
||||||
**Emociones**: Serenidad, equilibrio, conexión.
|
|
||||||
|
|
||||||
### 6.4 El Plato Saludable
|
|
||||||
**Imagen**: Bowl colorido con frutas, vegetales, superfoods perfectamente dispuestos.
|
|
||||||
**Simbolismo**: Nutrición consciente, autocuidado, vitalidad.
|
|
||||||
**Emociones**: Bienestar, control, salud.
|
|
||||||
|
|
||||||
### 6.5 La Meta del Maratón
|
|
||||||
**Imagen**: Corredor cruzando línea de meta con brazos alzados, expresión de triunfo.
|
|
||||||
**Simbolismo**: Resistencia, logro físico extremo, superación de límites.
|
|
||||||
**Emociones**: Euforia, orgullo, logro.
|
|
||||||
|
|
||||||
### 6.6 La Transformación Corporal
|
|
||||||
**Imagen**: Foto "antes y después" de pérdida de peso o ganancia muscular.
|
|
||||||
**Simbolismo**: Cambio posible, disciplina recompensada, renacimiento físico.
|
|
||||||
**Emociones**: Orgullo, inspiración, posibilidad.
|
|
||||||
|
|
||||||
### 6.7 El Spa de Lujo
|
|
||||||
**Imagen**: Persona en bata blanca, masaje, piscina de relajación, velas.
|
|
||||||
**Simbolismo**: Autocuidado premium, pausa merecida, restauración.
|
|
||||||
**Emociones**: Relajación, lujo, bienestar.
|
|
||||||
|
|
||||||
### 6.8 El Anciano Activo
|
|
||||||
**Imagen**: Persona mayor corriendo, haciendo yoga, surf o escalada.
|
|
||||||
**Simbolismo**: Envejecimiento activo, longevidad vital, juventud perpetua.
|
|
||||||
**Emociones**: Esperanza, inspiración, vitalidad.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 7. CREATIVIDAD Y EXPRESIÓN
|
|
||||||
|
|
||||||
### 7.1 El Artista en su Estudio
|
|
||||||
**Imagen**: Pintor/escultor rodeado de obras, luz natural, caos creativo ordenado.
|
|
||||||
**Simbolismo**: Vida dedicada al arte, expresión libre, mundo propio.
|
|
||||||
**Emociones**: Inspiración, autenticidad, libertad.
|
|
||||||
|
|
||||||
### 7.2 El Escritor en la Cabaña
|
|
||||||
**Imagen**: Persona escribiendo frente a ventana con vista a bosque/lago, café humeante.
|
|
||||||
**Simbolismo**: Soledad productiva, creación literaria, refugio creativo.
|
|
||||||
**Emociones**: Paz, inspiración, concentración.
|
|
||||||
|
|
||||||
### 7.3 El Músico en el Escenario
|
|
||||||
**Imagen**: Artista tocando ante multitud con brazos alzados, luces espectaculares.
|
|
||||||
**Simbolismo**: Conexión masiva a través del arte, expresión amplificada.
|
|
||||||
**Emociones**: Euforia, conexión, expresión.
|
|
||||||
|
|
||||||
### 7.4 Las Manos del Artesano
|
|
||||||
**Imagen**: Manos trabajando arcilla, madera, cuero, metal con herramientas tradicionales.
|
|
||||||
**Simbolismo**: Conexión con lo material, tradición, creación tangible.
|
|
||||||
**Emociones**: Satisfacción, conexión, autenticidad.
|
|
||||||
|
|
||||||
### 7.5 El Libro Publicado
|
|
||||||
**Imagen**: Manos sosteniendo ejemplar del libro propio, portada visible.
|
|
||||||
**Simbolismo**: Obra completa, legado tangible, voz publicada.
|
|
||||||
**Emociones**: Orgullo, logro, permanencia.
|
|
||||||
|
|
||||||
### 7.6 La Galería con Obra Propia
|
|
||||||
**Imagen**: Artista junto a su obra en galería, público admirando.
|
|
||||||
**Simbolismo**: Reconocimiento artístico, obra validada, expresión compartida.
|
|
||||||
**Emociones**: Orgullo, validación, conexión.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 8. PAZ INTERIOR Y ESPIRITUALIDAD
|
|
||||||
|
|
||||||
### 8.1 La Meditación al Amanecer
|
|
||||||
**Imagen**: Silueta meditando frente a sol naciente, posición de loto.
|
|
||||||
**Simbolismo**: Conexión espiritual, nuevo comienzo, paz interior.
|
|
||||||
**Emociones**: Serenidad, claridad, conexión.
|
|
||||||
|
|
||||||
### 8.2 El Templo en la Montaña
|
|
||||||
**Imagen**: Templo asiático entre nubes o monasterio en cumbre remota.
|
|
||||||
**Simbolismo**: Búsqueda espiritual, retiro del mundo, sabiduría ancestral.
|
|
||||||
**Emociones**: Asombro, aspiración espiritual, paz.
|
|
||||||
|
|
||||||
### 8.3 El Jardín Zen
|
|
||||||
**Imagen**: Jardín japonés con arena rastrillada, piedras, agua, bonsáis.
|
|
||||||
**Simbolismo**: Orden en el caos, belleza en simplicidad, contemplación.
|
|
||||||
**Emociones**: Calma, equilibrio, contemplación.
|
|
||||||
|
|
||||||
### 8.4 El Libro Sagrado Abierto
|
|
||||||
**Imagen**: Texto sagrado (cualquier tradición) iluminado por luz natural.
|
|
||||||
**Simbolismo**: Sabiduría ancestral, guía espiritual, conexión con lo trascendente.
|
|
||||||
**Emociones**: Reverencia, búsqueda, conexión.
|
|
||||||
|
|
||||||
### 8.5 Las Manos en Oración
|
|
||||||
**Imagen**: Manos juntas en gesto de oración o mudra, luz suave.
|
|
||||||
**Simbolismo**: Fe, entrega, conexión con lo divino.
|
|
||||||
**Emociones**: Fe, paz, humildad.
|
|
||||||
|
|
||||||
### 8.6 El Camino entre Árboles
|
|
||||||
**Imagen**: Sendero que atraviesa bosque antiguo, luz filtrándose entre hojas.
|
|
||||||
**Simbolismo**: Camino de la vida, naturaleza como templo, viaje interior.
|
|
||||||
**Emociones**: Paz, misterio, conexión.
|
|
||||||
|
|
||||||
### 8.7 La Persona Mayor Sabia
|
|
||||||
**Imagen**: Anciano/a con mirada serena, arrugas como mapa de experiencia.
|
|
||||||
**Simbolismo**: Sabiduría acumulada, paz con la vida, conocimiento profundo.
|
|
||||||
**Emociones**: Respeto, aspiración, serenidad.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 9. COMUNIDAD E IMPACTO SOCIAL
|
|
||||||
|
|
||||||
### 9.1 El Voluntario en Acción
|
|
||||||
**Imagen**: Persona construyendo casa, enseñando a niños, distribuyendo comida.
|
|
||||||
**Simbolismo**: Servicio desinteresado, impacto directo, propósito social.
|
|
||||||
**Emociones**: Satisfacción, conexión, propósito.
|
|
||||||
|
|
||||||
### 9.2 El Líder ante la Multitud
|
|
||||||
**Imagen**: Figura inspiradora hablando a multitud atenta, gesto apasionado.
|
|
||||||
**Simbolismo**: Influencia positiva, movimiento social, liderazgo de cambio.
|
|
||||||
**Emociones**: Inspiración, poder, propósito.
|
|
||||||
|
|
||||||
### 9.3 El Grupo Diverso Unido
|
|
||||||
**Imagen**: Personas de diferentes razas, edades, géneros abrazadas o colaborando.
|
|
||||||
**Simbolismo**: Unidad en diversidad, humanidad compartida, inclusión.
|
|
||||||
**Emociones**: Esperanza, conexión, pertenencia.
|
|
||||||
|
|
||||||
### 9.4 El Aula Transformada
|
|
||||||
**Imagen**: Maestro/a con estudiantes entusiasmados, momento de "eureka".
|
|
||||||
**Simbolismo**: Educación como transformación, mentoría, legado en otros.
|
|
||||||
**Emociones**: Satisfacción, propósito, esperanza.
|
|
||||||
|
|
||||||
### 9.5 La Fundación Propia
|
|
||||||
**Imagen**: Logo o edificio de fundación benéfica con nombre propio.
|
|
||||||
**Simbolismo**: Filantropía organizada, legado social, riqueza con propósito.
|
|
||||||
**Emociones**: Orgullo, propósito, trascendencia.
|
|
||||||
|
|
||||||
### 9.6 El Abrazo de Gratitud
|
|
||||||
**Imagen**: Beneficiario abrazando a benefactor con emoción genuina.
|
|
||||||
**Simbolismo**: Impacto tangible, conexión humana, reciprocidad.
|
|
||||||
**Emociones**: Emoción, conexión, gratitud.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 10. TECNOLOGÍA Y FUTURO
|
|
||||||
|
|
||||||
### 10.1 El Fundador de Startup
|
|
||||||
**Imagen**: Joven en sudadera presentando en pantalla gigante, logo de empresa.
|
|
||||||
**Simbolismo**: Disrupción, innovación juvenil, el "próximo Steve Jobs".
|
|
||||||
**Emociones**: Ambición, posibilidad, futuro.
|
|
||||||
|
|
||||||
### 10.2 El Código en Pantalla
|
|
||||||
**Imagen**: Múltiples monitores con código, gráficos, datos en habitación oscura.
|
|
||||||
**Simbolismo**: Poder digital, creación tecnológica, control de lo intangible.
|
|
||||||
**Emociones**: Poder, competencia, modernidad.
|
|
||||||
|
|
||||||
### 10.3 La Ciudad del Futuro
|
|
||||||
**Imagen**: Skyline futurista con edificios sostenibles, drones, coches voladores.
|
|
||||||
**Simbolismo**: Progreso, utopía tecnológica, futuro mejor.
|
|
||||||
**Emociones**: Esperanza, asombro, posibilidad.
|
|
||||||
|
|
||||||
### 10.4 El Astronauta
|
|
||||||
**Imagen**: Figura en traje espacial contemplando Tierra o superficie lunar.
|
|
||||||
**Simbolismo**: Frontera última, exploración humana, trascendencia planetaria.
|
|
||||||
**Emociones**: Asombro, aspiración, trascendencia.
|
|
||||||
|
|
||||||
### 10.5 La Realidad Virtual
|
|
||||||
**Imagen**: Persona con headset VR, gestos en el aire, expresión de asombro.
|
|
||||||
**Simbolismo**: Mundos alternativos, escape de límites físicos, futuro presente.
|
|
||||||
**Emociones**: Asombro, posibilidad, escape.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 11. NATURALEZA Y CONEXIÓN TERRESTRE
|
|
||||||
|
|
||||||
### 11.1 La Cima de la Montaña
|
|
||||||
**Imagen**: Persona de pie en cumbre nevada, brazos abiertos, mundo a sus pies.
|
|
||||||
**Simbolismo**: Conquista de lo imposible, perspectiva elevada, logro máximo.
|
|
||||||
**Emociones**: Logro, libertad, asombro.
|
|
||||||
|
|
||||||
### 11.2 El Océano Infinito
|
|
||||||
**Imagen**: Vista del mar extendiéndose hasta el horizonte, persona pequeña contemplando.
|
|
||||||
**Simbolismo**: Inmensidad, misterio, humildad ante la naturaleza.
|
|
||||||
**Emociones**: Paz, asombro, perspectiva.
|
|
||||||
|
|
||||||
### 11.3 El Bosque Antiguo
|
|
||||||
**Imagen**: Árboles milenarios, luz filtrada, sendero cubierto de hojas.
|
|
||||||
**Simbolismo**: Permanencia, sabiduría natural, conexión ancestral.
|
|
||||||
**Emociones**: Reverencia, paz, conexión.
|
|
||||||
|
|
||||||
### 11.4 La Aurora Boreal
|
|
||||||
**Imagen**: Cielo verde/violeta danzante sobre paisaje nevado.
|
|
||||||
**Simbolismo**: Magia de la naturaleza, momento irrepetible, belleza sobrenatural.
|
|
||||||
**Emociones**: Asombro, maravilla, gratitud.
|
|
||||||
|
|
||||||
### 11.5 El Animal Salvaje Cercano
|
|
||||||
**Imagen**: Encuentro cercano con león, elefante, ballena en su hábitat.
|
|
||||||
**Simbolismo**: Conexión con lo salvaje, respeto mutuo, naturaleza no domesticada.
|
|
||||||
**Emociones**: Asombro, respeto, conexión.
|
|
||||||
|
|
||||||
### 11.6 El Atardecer Épico
|
|
||||||
**Imagen**: Sol hundiéndose en horizonte con colores imposibles (naranja, rosa, violeta).
|
|
||||||
**Simbolismo**: Cierre perfecto, belleza efímera, momento presente.
|
|
||||||
**Emociones**: Paz, gratitud, contemplación.
|
|
||||||
|
|
||||||
### 11.7 La Cascada Majestuosa
|
|
||||||
**Imagen**: Cascada masiva cayendo sobre piscina natural, persona contemplando.
|
|
||||||
**Simbolismo**: Poder natural, purificación, asombro ante fuerzas mayores.
|
|
||||||
**Emociones**: Asombro, humildad, energía.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 12. LUJO EXPERIENCIAL
|
|
||||||
|
|
||||||
### 12.1 El Resort Sobre el Agua
|
|
||||||
**Imagen**: Bungalow con suelo de cristal sobre agua turquesa (Maldivas, Bora Bora).
|
|
||||||
**Simbolismo**: Lujo máximo, paraíso accesible, exclusividad extrema.
|
|
||||||
**Emociones**: Deseo, escape, lujo.
|
|
||||||
|
|
||||||
### 12.2 La Infinity Pool con Vista
|
|
||||||
**Imagen**: Piscina infinita fusionándose con horizonte marino/montañoso al atardecer.
|
|
||||||
**Simbolismo**: Sin límites, fusión con el entorno, lujo contemplativo.
|
|
||||||
**Emociones**: Paz, lujo, libertad.
|
|
||||||
|
|
||||||
### 12.3 El Restaurante Michelin
|
|
||||||
**Imagen**: Plato artístico, mantel blanco, sommelier sirviendo vino, vista espectacular.
|
|
||||||
**Simbolismo**: Gastronomía como arte, experiencia multisensorial, distinción.
|
|
||||||
**Emociones**: Anticipación, placer, exclusividad.
|
|
||||||
|
|
||||||
### 12.4 El Hotel Boutique Único
|
|
||||||
**Imagen**: Suite con diseño extraordinario (cueva, árbol, hielo, desierto).
|
|
||||||
**Simbolismo**: Experiencia irrepetible, alojamiento como aventura.
|
|
||||||
**Emociones**: Asombro, exclusividad, aventura.
|
|
||||||
|
|
||||||
### 12.5 El Helicóptero sobre la Ciudad
|
|
||||||
**Imagen**: Vista aérea de metrópolis desde helicóptero, champagne en mano.
|
|
||||||
**Simbolismo**: Perspectiva de élite, acceso exclusivo, dominio visual.
|
|
||||||
**Emociones**: Poder, emoción, exclusividad.
|
|
||||||
|
|
||||||
### 12.6 El Safari de Lujo
|
|
||||||
**Imagen**: Tienda lujosa en sabana africana, animales al fondo, atardecer dorado.
|
|
||||||
**Simbolismo**: Aventura sin sacrificio, naturaleza con confort, exclusividad salvaje.
|
|
||||||
**Emociones**: Aventura, lujo, conexión con naturaleza.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## RESUMEN: LOS 12 ARQUETIPOS DE VISIÓN
|
|
||||||
|
|
||||||
| # | Categoría | Necesidad Humana | Palabras Clave |
|
|
||||||
|---|-----------|------------------|----------------|
|
|
||||||
| 1 | Libertad Financiera | Seguridad, poder | Mansión, yate, jet, riqueza |
|
|
||||||
| 2 | Amor Romántico | Conexión, intimidad | Playa, beso, pareja, atardecer |
|
|
||||||
| 3 | Familia y Hogar | Pertenencia, estabilidad | Casa, hijos, mesa, tradición |
|
|
||||||
| 4 | Aventura | Libertad, exploración | Viaje, mochila, carretera, mapa |
|
|
||||||
| 5 | Éxito Profesional | Reconocimiento, logro | Oficina, premio, aplauso, título |
|
|
||||||
| 6 | Salud Física | Vitalidad, control | Fitness, yoga, maratón, energía |
|
|
||||||
| 7 | Creatividad | Expresión, autenticidad | Arte, música, escritura, estudio |
|
|
||||||
| 8 | Espiritualidad | Trascendencia, paz | Meditación, templo, naturaleza |
|
|
||||||
| 9 | Impacto Social | Propósito, legado | Voluntariado, liderazgo, comunidad |
|
|
||||||
| 10 | Tecnología/Futuro | Innovación, progreso | Startup, código, espacio |
|
|
||||||
| 11 | Naturaleza | Conexión, asombro | Montaña, océano, bosque, animales |
|
|
||||||
| 12 | Lujo Experiencial | Placer, exclusividad | Resort, infinity pool, safari |
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## NOTAS DE USO
|
|
||||||
|
|
||||||
### Para Vision Boards
|
|
||||||
Las imágenes más poderosas combinan varios arquetipos:
|
|
||||||
- **Pareja en yate al atardecer** = Amor + Riqueza + Aventura
|
|
||||||
- **Familia en casa con jardín** = Hogar + Seguridad + Tradición
|
|
||||||
- **Empresario meditando con vista** = Éxito + Espiritualidad + Lujo
|
|
||||||
|
|
||||||
### Para Storytelling/Marketing
|
|
||||||
Las visiones funcionan mejor cuando:
|
|
||||||
1. Son específicas pero universales
|
|
||||||
2. Incluyen elementos sensoriales
|
|
||||||
3. Muestran el "después" del logro
|
|
||||||
4. Evocan emoción, no solo posesión
|
|
||||||
|
|
||||||
### Para el Sistema HST
|
|
||||||
Cada visión puede convertirse en una etiqueta HST con su hash correspondiente, permitiendo asociar Bloques y Milestones con la visión que representan.
|
|
||||||
Reference in New Issue
Block a user