workspace-v1/02-fase-core-orchestration/ARTEFACTOS/SERVICE-DESCRIPTOR-STANDARD.md
Adrian Flores Cortes 967ab360bb Initial commit: Workspace v1 with 3-layer architecture
Structure:
- control-plane/: Registries, SIMCO directives, CI/CD templates
- projects/: Gamilit, ERP-Suite, Trading-Platform, Betting-Analytics
- shared/: Libs catalog, knowledge-base

Key features:
- Centralized port, domain, database, and service registries
- 23 SIMCO directives + 6 fundamental principles
- NEXUS agent profiles with delegation rules
- Validation scripts for workspace integrity
- Dockerfiles for all services
- Path aliases for quick reference

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-23 00:35:19 -06:00

13 KiB

SERVICE DESCRIPTOR STANDARD

Version: 1.0.0 Fecha: 2025-12-18 Sistema: SIMCO v2 - Workspace v1 Tipo: Estandar de Contrato de Servicio


PROPOSITO

El Service Descriptor es un contrato universal que define completamente un servicio, conectando:

  • Codigo fuente con registries
  • Agentes con responsabilidades
  • CI/CD con configuracion
  • Monitoreo con endpoints

Principio: Los agentes dejan de "inferir" y empiezan a "leer contrato".


UBICACION

Cada servicio debe tener un archivo service.descriptor.yml en su raiz:

gamilit-platform/
  +-- apps/
  |     +-- backend/
  |     |     +-- service.descriptor.yml  # <- Descriptor del backend
  |     |     +-- src/
  |     |     +-- package.json
  |     +-- frontend/
  |           +-- service.descriptor.yml  # <- Descriptor del frontend
  |           +-- src/
  |           +-- package.json
  +-- docker/
  +-- orchestration/

SCHEMA COMPLETO

# ==============================================================================
# SERVICE DESCRIPTOR - Schema v1.0.0
# ==============================================================================
# Este archivo define completamente un servicio
# OBLIGATORIO en la raiz de cada servicio
# ==============================================================================

# ------------------------------------------------------------------------------
# IDENTIFICACION DEL SERVICIO
# ------------------------------------------------------------------------------
service:
  # Nombre unico del servicio (kebab-case)
  name: "string"  # Ej: "gamilit-api", "erp-frontend"

  # Tipo de servicio
  type: "backend | frontend | database | ml | worker | gateway"

  # Runtime/tecnologia
  runtime: "node | python | go | java | static | postgres"

  # Version del servicio (semver)
  version: "string"  # Ej: "1.0.0"

  # Descripcion breve
  description: "string"

  # Agente responsable (para SIMCO)
  owner_agent: "NEXUS-BACKEND | NEXUS-FRONTEND | NEXUS-DATABASE | NEXUS-ML"

# ------------------------------------------------------------------------------
# REPOSITORIO
# ------------------------------------------------------------------------------
repository:
  # Nombre del repo
  name: "string"  # Ej: "gamilit-platform"

  # Ruta relativa al servicio dentro del repo
  path: "string"  # Ej: "apps/backend"

  # Branch principal
  main_branch: "main | master"

# ------------------------------------------------------------------------------
# PUERTOS (referencia a ports.registry.yml)
# ------------------------------------------------------------------------------
ports:
  # Puerto interno del servicio
  internal: number  # Ej: 3000

  # Referencia al registry (para validacion)
  registry_ref: "string"  # Ej: "projects.gamilit.api"

  # Protocolo
  protocol: "http | https | ws | wss | grpc"

# ------------------------------------------------------------------------------
# DOMINIOS (referencia a domains.registry.yml)
# ------------------------------------------------------------------------------
domains:
  # Referencia al proyecto en domains.registry
  registry_ref: "string"  # Ej: "gamilit"

  # Override por ambiente (opcional)
  overrides:
    local: "string"     # Ej: "localhost:3000"
    development: "string"
    staging: "string"
    production: "string"

# ------------------------------------------------------------------------------
# BASE DE DATOS (referencia a databases.registry.yml)
# ------------------------------------------------------------------------------
database:
  # Referencia al proyecto en databases.registry
  registry_ref: "string"  # Ej: "gamilit"

  # Rol a usar (del registry)
  role: "runtime | migrator | owner"

  # Schemas que usa este servicio
  schemas:
    - "string"  # Ej: ["public", "auth"]

# ------------------------------------------------------------------------------
# AMBIENTES
# ------------------------------------------------------------------------------
environments:
  # Lista de ambientes donde despliega
  deployed_to:
    - "local"
    - "development"
    - "staging"
    - "production"

  # Ambiente por defecto para desarrollo
  default: "local"

# ------------------------------------------------------------------------------
# HEALTH CHECK
# ------------------------------------------------------------------------------
healthcheck:
  # Path del endpoint de health
  path: "string"  # Ej: "/health"

  # Intervalo de verificacion
  interval: "string"  # Ej: "30s"

  # Timeout
  timeout: "string"  # Ej: "5s"

  # Reintentos antes de marcar unhealthy
  retries: number  # Ej: 3

# ------------------------------------------------------------------------------
# DEPENDENCIAS
# ------------------------------------------------------------------------------
dependencies:
  # Otros servicios de los que depende
  services:
    - name: "string"
      required: boolean
      healthcheck: "string"  # URL del healthcheck

  # Bases de datos
  databases:
    - "string"  # Nombres de BD del registry

  # Servicios externos
  external:
    - name: "string"
      url: "string"
      required: boolean

# ------------------------------------------------------------------------------
# CI/CD
# ------------------------------------------------------------------------------
ci:
  # Nombre del pipeline a usar
  pipeline: "string"  # Ej: "node-backend-standard"

  # Flags de CI
  tests: boolean
  lint: boolean
  build: boolean
  docker: boolean

  # Imagen Docker (si aplica)
  docker_image: "string"  # Ej: "gamilit-api:latest"

  # Registry de Docker
  docker_registry: "string"  # Ej: "ghcr.io/tu-org"

# ------------------------------------------------------------------------------
# OBSERVABILIDAD
# ------------------------------------------------------------------------------
observability:
  # Metricas
  metrics:
    enabled: boolean
    path: "string"  # Ej: "/metrics"
    port: number    # Ej: 9090

  # Logging
  logging:
    level: "debug | info | warn | error"
    format: "json | text"

  # Tracing
  tracing:
    enabled: boolean
    provider: "string"  # Ej: "jaeger", "zipkin"

# ------------------------------------------------------------------------------
# RECURSOS (para Kubernetes/Docker)
# ------------------------------------------------------------------------------
resources:
  # Limites de CPU
  cpu:
    request: "string"  # Ej: "100m"
    limit: "string"    # Ej: "500m"

  # Limites de memoria
  memory:
    request: "string"  # Ej: "128Mi"
    limit: "string"    # Ej: "512Mi"

  # Replicas
  replicas:
    min: number
    max: number

# ------------------------------------------------------------------------------
# METADATA
# ------------------------------------------------------------------------------
metadata:
  # Fecha de creacion
  created: "string"  # ISO date

  # Ultima actualizacion
  updated: "string"  # ISO date

  # Mantenedores
  maintainers:
    - name: "string"
      email: "string"

  # Tags para busqueda
  tags:
    - "string"

  # Links relacionados
  links:
    documentation: "string"
    repository: "string"
    monitoring: "string"

EJEMPLOS

Backend NestJS

# gamilit-platform/apps/backend/service.descriptor.yml

service:
  name: "gamilit-api"
  type: "backend"
  runtime: "node"
  version: "1.0.0"
  description: "API principal de Gamilit - Plataforma de gamificacion educativa"
  owner_agent: "NEXUS-BACKEND"

repository:
  name: "gamilit-platform"
  path: "apps/backend"
  main_branch: "main"

ports:
  internal: 3000
  registry_ref: "projects.gamilit.api"
  protocol: "http"

domains:
  registry_ref: "gamilit"
  overrides:
    local: "localhost:3000"

database:
  registry_ref: "gamilit"
  role: "runtime"
  schemas:
    - "public"
    - "auth"
    - "gamification"
    - "progress_tracking"

environments:
  deployed_to:
    - "local"
    - "development"
    - "production"
  default: "local"

healthcheck:
  path: "/health"
  interval: "30s"
  timeout: "5s"
  retries: 3

dependencies:
  services: []
  databases:
    - "gamilit_db"
  external:
    - name: "stripe"
      url: "https://api.stripe.com"
      required: false

ci:
  pipeline: "node-backend-standard"
  tests: true
  lint: true
  build: true
  docker: true
  docker_image: "gamilit-api"
  docker_registry: "ghcr.io/tu-org"

observability:
  metrics:
    enabled: true
    path: "/metrics"
    port: 9090
  logging:
    level: "info"
    format: "json"
  tracing:
    enabled: false

resources:
  cpu:
    request: "100m"
    limit: "500m"
  memory:
    request: "256Mi"
    limit: "512Mi"
  replicas:
    min: 1
    max: 3

metadata:
  created: "2025-01-01"
  updated: "2025-12-18"
  maintainers:
    - name: "Tech Team"
      email: "tech@ejemplo.com"
  tags:
    - "api"
    - "nestjs"
    - "gamification"
  links:
    documentation: "/docs"
    repository: "https://github.com/tu-org/gamilit-platform"

Frontend React

# gamilit-platform/apps/frontend/service.descriptor.yml

service:
  name: "gamilit-web"
  type: "frontend"
  runtime: "static"
  version: "1.0.0"
  description: "Frontend web de Gamilit"
  owner_agent: "NEXUS-FRONTEND"

repository:
  name: "gamilit-platform"
  path: "apps/frontend"
  main_branch: "main"

ports:
  internal: 3001
  registry_ref: "projects.gamilit.web"
  protocol: "http"

domains:
  registry_ref: "gamilit"
  overrides:
    local: "localhost:3001"

database:
  registry_ref: null  # Frontend no accede directo a BD

environments:
  deployed_to:
    - "local"
    - "development"
    - "production"
  default: "local"

healthcheck:
  path: "/"
  interval: "60s"

dependencies:
  services:
    - name: "gamilit-api"
      required: true
      healthcheck: "http://gamilit-api:3000/health"
  databases: []
  external: []

ci:
  pipeline: "react-frontend-standard"
  tests: true
  lint: true
  build: true
  docker: true
  docker_image: "gamilit-web"

metadata:
  created: "2025-01-01"
  updated: "2025-12-18"
  tags:
    - "frontend"
    - "react"
    - "web"

USO POR AGENTES

Backend-Agent

# En PERFIL-BACKEND.md, agregar:

PASO_NUEVO_SERVICE_DESCRIPTOR:
  al_crear_servicio:
    - Crear service.descriptor.yml en raiz del servicio
    - Verificar que ports.registry_ref existe en ports.registry.yml
    - Verificar que database.registry_ref existe en databases.registry.yml
    - Completar todos los campos obligatorios

  al_modificar_servicio:
    - Actualizar version en service.descriptor.yml
    - Actualizar metadata.updated
    - Si cambian puertos: actualizar ports.registry.yml PRIMERO

DevOps-Agent

# En PERFIL-DEVOPS.md:

VALIDACION_SERVICE_DESCRIPTOR:
  pre_deploy:
    - Leer service.descriptor.yml
    - Validar ports.registry_ref existe
    - Validar domains.registry_ref existe
    - Validar database.registry_ref existe
    - Ejecutar healthcheck.path

  ci_pipeline:
    - Usar ci.pipeline para seleccionar template
    - Ejecutar ci.tests, ci.lint, ci.build segun flags
    - Construir ci.docker_image si docker: true

VALIDACION

Script: validate-service-descriptor.sh

#!/bin/bash
# Valida que un service.descriptor.yml sea correcto

DESCRIPTOR="$1"

if [ ! -f "$DESCRIPTOR" ]; then
    echo "ERROR: Descriptor no encontrado: $DESCRIPTOR"
    exit 1
fi

# Validar YAML
python3 -c "import yaml; yaml.safe_load(open('$DESCRIPTOR'))" || exit 1

# Validar campos obligatorios
python3 << EOF
import yaml
import sys

with open('$DESCRIPTOR', 'r') as f:
    d = yaml.safe_load(f)

required = ['service', 'repository', 'ports', 'environments', 'ci']
for field in required:
    if field not in d:
        print(f"ERROR: Campo obligatorio faltante: {field}")
        sys.exit(1)

# Validar service
for field in ['name', 'type', 'runtime', 'owner_agent']:
    if field not in d['service']:
        print(f"ERROR: service.{field} es obligatorio")
        sys.exit(1)

print("OK: Descriptor valido")
EOF

INTEGRACION CON SIMCO

SIMCO-SERVICE-DESCRIPTOR.md (Nueva directiva)

# SIMCO: SERVICE DESCRIPTOR

## REGLA FUNDAMENTAL

Todo servicio DEBE tener un service.descriptor.yml en su raiz.
El descriptor es la fuente de verdad para:
- Configuracion de puertos
- Configuracion de dominios
- Configuracion de BD
- Pipelines de CI/CD

## CUANDO CREAR

1. Al crear un nuevo servicio
2. Al migrar un servicio existente al workspace v1

## COMO CREAR

1. Copiar SERVICE-DESCRIPTOR-TEMPLATE.yml
2. Completar todos los campos
3. Verificar referencias a registries
4. Validar con validate-service-descriptor.sh

## CUANDO ACTUALIZAR

1. Cambio de puerto -> Actualizar ports + registry
2. Cambio de BD -> Actualizar database + registry
3. Nueva dependencia -> Actualizar dependencies
4. Cualquier cambio -> Actualizar metadata.updated

Documento generado por: Architecture-Analyst Version: 1.0.0