Skip to content

ADR-0011: cornerstone-builder — pipeline spec-driven con arquetipos

  • Status: Accepted
  • Date: 2026-03-26
  • Deciders: DeAcero Agentic Team

Context

El template Cornerstone actual scaffoldea proyectos Python genéricos con infraestructura Agentic CI. Pero los proyectos reales de DeAcero siguen patrones recurrentes y bien definidos:

  • Servidores MCP — exponen lógica de negocio migrada como herramientas para agentes
  • MCP + UI — servidor MCP con interfaz React para usuarios finales
  • MCP + API — servidor MCP más una API REST para integración con sistemas externos
  • API sola — FastAPI REST sin capa MCP
  • SPs migrados — Stored Procedures SQL Server portados a Python + SQLAlchemy
  • MCP + UI + API — la combinación completa

Hoy, cada proyecto nuevo requiere: 1. Generar el template base con cookiecutter 2. Configurar manualmente la estructura del proyecto según el patrón 3. Escribir features BDD desde cero o copiarlas de otro proyecto

Además, el pipeline de arqueología produce .feature files verificadas (# status: verified) que deberían poder usarse directamente como input del scaffold — pero no hay nada que conecte ese output con la generación del nuevo proyecto.

La oportunidad

Cerrar el pipeline completo:

[Legacy system]
      ↓
software-archeologist → bdd-writer → characterization-tester → [cornerstone-builder]
                                                                        ↑
[Nueva necesidad]
      ↓
problem-intake → bdd-writer (features nuevas) ─────────────────────────┘

El cornerstone-builder es el eslabón que falta: toma features verificadas y un arquetipo, y produce un proyecto completamente scaffoldeado y BDD-first desde el primer commit.


Decision

Crear el directorio builder/ en el repositorio Cornerstone como un segundo template Cookiecutter dentro del mismo monorepo, accesible vía:

cookiecutter gh:deagentic/cornerstone --directory builder

Arquetipos disponibles

Grupo: Servidor / API

Arquetipo Descripción Stack generado
mcp-only Servidor MCP puro — expone lógica de negocio a agentes FastMCP, pytest-bdd, Docker
mcp-api MCP + REST API — lógica accesible tanto a agentes como a sistemas externos FastMCP, FastAPI, pytest-bdd, Docker Compose
mcp-ui MCP + interfaz React — lógica con UI para usuarios finales FastMCP, Next.js/React, shadcn-ui, Docker Compose
mcp-ui-api Combinación completa FastMCP + FastAPI + React, Docker Compose
api-only REST API sin MCP — integración con sistemas externos sin capa agéntica FastAPI, pytest, Docker

Grupo: Datos y Migración

Arquetipo Descripción Stack generado
sql-procedures SPs SQL Server portados a Python SQLAlchemy, pytest-bdd, Alembic, Docker
etl-pipeline Reemplazo de paquetes SSIS o flujos de migración de datos SQLAlchemy, pandas, pytest, Docker
cobol-bridge Capa adaptadora COBOL → Python (para el pipeline cobol-analyst) ctypes/subprocess bridge, pytest-bdd, Docker

Grupo: Procesamiento Asíncrono

Arquetipo Descripción Stack generado
scheduled-job Reemplazo de SQL Server Agent Jobs (RUNS_ON_SCHEDULE en el grafo) APScheduler / Celery Beat, pytest, Docker
worker Procesamiento asíncrono en cola — tasks que antes eran SPs ad-hoc Celery + Redis/RabbitMQ, pytest, Docker
mcp-worker Servidor MCP + worker de cola — para flujos que requieren procesamiento diferido FastMCP + Celery, pytest-bdd, Docker Compose

Grupo: Utilitarios

Arquetipo Descripción Stack generado
library Librería Python pura — lógica de negocio compartida extraída de múltiples SPs pyproject.toml, pytest, sin Docker
cli-tool Herramienta de línea de comandos — utilitarios internos, scripts de migración Typer/Click, pytest, Docker opcional
report Servicio de reportes — reemplazo de SSRS, output PDF/Excel ReportLab/Jinja2/openpyxl, pytest, Docker

Input del builder

El cornerstone-builder acepta dos tipos de input:

Path de features verificadas (del pipeline de arqueología o greenfield):

builder/
└── input/
    └── features/
        ├── sp_generar_factura.feature   # status: verified
        ├── sp_aplicar_descuento.feature # status: verified
        └── ...

cookiecutter.json ampliado:

{
  "project_name": "facturacion-service",
  "archetype": ["mcp-api", "mcp-only", "mcp-ui", "mcp-ui-api", "api-only",
                "sql-procedures", "etl-pipeline", "cobol-bridge",
                "scheduled-job", "worker", "mcp-worker",
                "library", "cli-tool", "report"],
  "features_path": "input/features/",
  "database": ["sqlserver", "postgresql", "none"],
  "python_version": "3.11",
  "include_ui": false
}

El primer valor de cada lista es el default. Cookiecutter presenta un menú de selección interactivo.

Output del builder

Para el arquetipo mcp-api, el proyecto generado incluye:

facturacion-service/
├── AGENTS.md                    ← routing directives del proyecto
├── CLAUDE.md                    ← entry point para Claude Code
├── .agents/skills/              ← skills heredados de Cornerstone
├── docs/
│   └── adr/                     ← ADR inicial generado desde las features
├── src/
│   └── facturacion/
│       ├── __init__.py
│       ├── mcp_server.py        ← herramientas MCP (stubs desde features)
│       └── api/
│           └── routes.py        ← endpoints REST (stubs desde features)
├── tests/
│   ├── features/                ← .feature files copiadas desde input/
│   │   └── *.feature
│   ├── step_defs/               ← stubs de step definitions (pytest-bdd)
│   │   └── conftest.py
│   └── characterization/       ← regression suite del sistema legacy (si aplica)
├── pyproject.toml
├── Dockerfile
├── docker-compose.yml
├── .github/
│   └── workflows/
│       └── ci.yml               ← pipeline CI con ADR gate + BDD tests
└── setup/
    └── install.sh

Generación de stubs desde features

Para cada .feature verificada, el builder genera automáticamente:

  1. MCP tool stub (para arquetipos con MCP):

    @mcp.tool()
    def generar_factura(pedido_id: int, cliente_id: str) -> dict:
        """
        Generada desde: sp_generar_factura.feature (status: verified)
        Comportamiento verificado: retorna monto total con impuesto incluido
        TODO: implementar lógica migrada desde sp_generar_factura
        """
        raise NotImplementedError
    

  2. API endpoint stub (para arquetipos con API):

    @router.post("/facturas")
    async def create_factura(pedido_id: int, cliente_id: str):
        """Generada desde sp_generar_factura.feature"""
        raise NotImplementedError
    

  3. Step definition stub (para todos los arquetipos):

    @given("un pedido con id {pedido_id} del cliente {cliente_id}")
    def step_pedido(context, pedido_id, cliente_id):
        # TODO: setup test data
        pass
    
    @when("se ejecuta generar_factura")
    def step_execute(context):
        # TODO: call MCP tool or API endpoint
        pass
    
    @then("el monto total es {expected_monto}")
    def step_assert(context, expected_monto):
        assert context.result["monto"] == float(expected_monto)
    

Los stubs garantizan que el proyecto arranca con tests que fallan de forma significativa (NotImplementedError / pending steps) — no con tests vacíos. El primer sprint consiste en hacer que esos tests pasen.

Skill asociado: cornerstone-builder

Se crea el skill .agents/skills/software/architecture/cornerstone-builder/SKILL.md que: - Lee las features verificadas del characterization-tester o del bdd-writer (greenfield) - Solicita al usuario que seleccione un arquetipo - Ejecuta cookiecutter gh:deagentic/cornerstone --directory builder con los parámetros - Post-procesa los stubs generados con las firmas correctas inferidas de las features


Flujo completo

═══════════════════════ ARQUEOLOGÍA ════════════════════════════
legacy SQL / DLL / JAR
        ↓
software-archeologist   (mapea el sistema, genera graph)
        ↓
bdd-writer              (features hypothesis)
        ↓
characterization-tester (features verified / conflict)
        ↓ (solo verified)
cornerstone-builder ────────────────────────────────────────────┐
                                                                │
═══════════════════════ GREENFIELD ═════════════════════════════│
nueva necesidad de negocio                                      │
        ↓                                                       │
problem-intake          (genera Archaeology Brief)              │
        ↓                                                       │
bdd-writer              (features nuevas desde brief)           │
        ↓                                                       │
cornerstone-builder ────────────────────────────────────────────┘
        ↓
proyecto scaffoldeado con:
- stubs MCP / API / SQL
- BDD test harness listo
- CI/CD con ADR gate
- regression suite del legacy (si aplica)

Consecuencias

Positivo

  • Cierra el pipeline end-to-end: del legacy o del brief al proyecto nuevo en un comando
  • Los proyectos nuevos nacen con tests que fallan significativamente — no con código vacío
  • Los features verificadas se convierten en el contrato de paridad del sistema migrado
  • Elimina la configuración manual repetitiva entre proyectos
  • Estandariza la estructura de todos los proyectos de modernización de DeAcero

Negativo

  • Los stubs generados desde features son punto de partida, no implementación completa — el equipo debe completarlos; existe riesgo de que queden como stubs permanentes
  • Cookiecutter --directory requiere que el template builder/ sea mantenido en paralelo con el template raíz — duplicación de algunos archivos comunes (AGENTS.md base, skills)
  • La selección del arquetipo es una decisión arquitectónica que debe ir acompañada de un ADR — el builder debe incluir un ADR plantilla pre-llenado para este propósito
  • 14 arquetipos representan una superficie de mantenimiento significativa — se recomienda implementar por grupos: Servidor/API primero, luego Datos, luego Procesamiento Asíncrono, finalmente Utilitarios

Dependencias

  • bdd-writer skill — produce las features de entrada (ambas rutas)
  • characterization-tester (ADR-0012) — produce features verificadas (ruta arqueología)
  • problem-intake skill (ADR-0009) — genera el brief para la ruta greenfield
  • stitch-skills (ADR-0008) — para arquetipos con UI, el builder invoca stitch-design
  • Cookiecutter ≥ 2.1 — requerido para --directory en monorepos

Alternativas consideradas

Un template Cookiecutter por arquetipo (N repos): Más simple por arquetipo pero fragmenta el mantenimiento. Cambios en skills comunes, hooks, o CI deben replicarse en N repos. Descartado — el monorepo con --directory resuelve esto.

Generar el proyecto completamente desde código (sin Cookiecutter): Mayor flexibilidad pero elimina la familiaridad de Cookiecutter y complica el bootstrap para nuevos equipos. Cookiecutter es el estándar establecido en el proyecto. Descartado.

Solo generar el scaffold sin stubs de features: Más simple de implementar pero pierde el valor principal — que el proyecto nazca con su contrato de paridad listo. Descartado.