MetsuOS

Construyendo la plena inclusión a través del videojuego

Especificación e Implementación Técnica: MOM (MetsuOS Methodology) 🔴②

MOM (MetsuOS Methodology) 🟡③

1. Introducción y Visión General

MOM (MetsuOS Methodology) es un marco metodológico y de ingeniería de software enfocado en el Desarrollo A Prueba de IA. Se fundamenta en la norma ESA PSS-05 (European Space Agency Software Engineering Standards), aplicando un principio de atomización extrema de especificaciones:


2. Metodología ESA PSS-05 Completa, Herencia Múltiple y Flujo de Cambios

2.1 Fases del Ciclo de Vida ESA PSS-05

MOM cubre el 100% de la jerarquía de especificación del estándar ESA PSS-05, integrando la documentación de usuario y el onboarding en la misma cascada:

  1. URD (User Requirements Document): Definición de las necesidades del usuario, objetivos del sistema, guía de usuario requerida y onboarding.
  2. SRD (Software Requirements Document): Requisitos funcionales, no funcionales y especificaciones de interfaces/documentación derivables de los URD.
  3. ADD (Architectural Design Document): Diseño de la arquitectura, componentes principales, estructuras de datos, conectores de agentes y módulos de documentación.
  4. DDD (Detailed Design Document): Especificación de funciones, clases, manuales de usuario, contratos de código y archivos de contexto (AGENTS.md).

2.2 Herencia Múltiple de Proyectos y Resolución de Diamantes (DAG)

MOM permite que un proyecto declare múltiples proyectos padre en su archivo de configuración project.json mediante el campo parent_projects:

flowchart TD
    P1[std-posix] --> W1[std-html-css-js]
    P2[std-esa-pss05] --> W1
    P3[std-crypto-base] --> W1

    W1 --> B1[std-browser-core]
    P4[std-a11y-universal] --> B1

    B1 --> NAV[Navegador Web Soberano Final]

2.3 Reglas de Trazabilidad e Integridad Estricta


3. Arquitectura Multiproyecto y Estructura del Repositorio

MOM se organiza de forma que el mismo repositorio aloje tanto el motor Python como el motor C/C++, compartiendo la misma carpeta raíz de proyectos/datos (data/projects/).

3.1 Estructura del Repositorio de Directorios

Nivel 1 (Raíz)Nivel 2 (Directorio)Nivel 3 (Ficheros / Contenido)Descripción del Elemento
data/projects/<project_name>/Carpeta global de almacenamiento de proyectos administrados por MOM.
data/projects/<proj>/project.jsonMetafichero con configuración del proyecto y lista de parent_projects.
data/projects/<proj>/src/{urd,srd,add,ddd}/Fuente de la verdad atómica en ficheros JSON por fase ESA para el proyecto.
data/projects/<proj>/doc/Documentos consolidados renderizados (URD.md, SRD.md, ADD.md, DDD.md, USER_MANUAL.md).
data/projects/<proj>/vault/Vault hipervinculado navegable en Obsidian específico del proyecto.
data/projects/<proj>/AGENTS.mdFichero auto-generado con reglas inmutables de IA acumuladas por herencia.
mom/(python engine)*.pyMotor en Python 3.11+ (Gestor CRUD, resolutor DAG, CLI, compilador).
native/src/*.c, *.cpp, *.hMotor nativo en C/C++ agnóstico y compatible con sistemas modernos y legacy.
native/Makefile / CMakeLists.txtBuild scriptsScripts de compilación nativa multiplataforma.
COMPILING_NATIVE.txt----Instrucciones en texto plano para compilar la versión C/C++ sin dependencias.
pyproject.toml----Configuración de entorno y empaquetado Poetry para la versión Python.

4. Motor Nativo C/C++ Agnosticismo y Compatibilidad Legacy

Para garantizar la viabilidad a muy largo plazo y la ejecución en sistemas donde Python 3.11+ no esté disponible, se proporciona mom-core-native.

4.1 Estándares y Dialectos Seleccionados

4.2 Instrucciones de Compilación Nativa (COMPILING_NATIVE.txt)

========================================================================
MOM (MetsuOS Methodology) - GUÍA DE COMPILACIÓN DEL MOTOR NATIVO C/C++
========================================================================

Este motor nativo está escrito en C89/C99 y C++98 para garantizar la 
máxima compatibilidad con sistemas modernos y máquinas antiguas/legacy 
donde no exista un intérprete de Python 3.11+.

1. COMPILACIÓN EN SISTEMAS UNIX / LINUX / MACOS (GCC / CLANG)
-------------------------------------------------------------
Para compilar con GCC utilizando el estándar C99:
    gcc -O2 -std=c99 -I native/include native/src/*.c -o mom-native

Para compilar con C++98:
    g++ -O2 -std=c++98 -I native/include native/src/*.cpp -o mom-native

Si se dispone de Make:
    make -f native/Makefile

2. COMPILACIÓN EN WINDOWS (MSVC / MINDEV / CLANG-CL)
-------------------------------------------------------------
Usando el Símbolo del sistema de herramientas nativas de Visual Studio:
    cl /O2 /I native\include native\src\*.c /Femom-native.exe

Usando GCC / MinGW:
    gcc -O2 -std=c99 -I native/include native/src/*.c -o mom-native.exe

3. COMPILACIÓN EN COMPILADORES LEGACY / EMBEBIDOS (ej. TCC, WATCOM)
-------------------------------------------------------------------
Usando Tiny C Compiler (TCC):
    tcc -I native/include native/src/*.c -o mom-native

4. USO DEL EJECUTABLE NATIVO
----------------------------
Listar proyectos:
    ./mom-native list

Crear proyecto con herencia:
    ./mom-native create --name "MiAppSoberana" --parents "std-posix,std-a11y-universal"

Compilar un proyecto y desplegarlo en su carpeta de destino:
    ./mom-native compile --project "data/projects/MiAppSoberana" --target-docs "/ruta/destino/proyecto/docs"

5. Implementación en Python 3.11+ (stdlib sin dependencias de PyPI)

5.1 Fichero de Configuración Poetry (pyproject.toml)

[tool.poetry]
name = "mom-core"
version = "0.2.0"
description = "MetsuOS Methodology (MOM) - Sistema multiproyecto de especificación atómica con herencia DAG y cero-dependencias"
authors = ["Metsuke <metsuke@metsuos.org>"]
readme = "README.md"
packages = [{include = "mom"}]

[tool.poetry.dependencies]
python = "^3.11"

[tool.poetry.group.dev.dependencies]
pytest = "^8.0.0"
mypy = "^1.8.0"
ruff = "^0.2.0"

[tool.poetry.scripts]
mom = "mom.cli:main"

[build-system]
requires = ["poetry-core"]
build-backend = "poetry.core.masonry.api"

[tool.ruff]
target-version = "py311"
line-length = 100

[tool.mypy]
python_version = "3.11"
strict = true

5.2 Modelos de Datos Nativos (mom/schemas.py)

from enum import Enum
from dataclasses import dataclass, field, asdict
from typing import List, Dict, Any, Optional

class ESAPhase(str, Enum):
    URD = "urd"
    SRD = "srd"
    ADD = "add"
    DDD = "ddd"

class PriorityEnum(str, Enum):
    LOW = "LOW"
    MEDIUM = "MEDIUM"
    HIGH = "HIGH"
    CRITICAL = "CRITICAL"

class StatusEnum(str, Enum):
    DRAFT = "DRAFT"
    REVIEW = "REVIEW"
    APPROVED = "APPROVED"
    REJECTED = "REJECTED"
    DEPRECATED = "DEPRECATED"

class VerificationMethod(str, Enum):
    INSPECTION = "INSPECTION"
    ANALYSIS = "ANALYSIS"
    DEMONSTRATION = "DEMONSTRATION"
    UNIT_TEST = "UNIT_TEST"
    INTEGRATION_TEST = "INTEGRATION_TEST"
    SYSTEM_TEST = "SYSTEM_TEST"

@dataclass
class ItemAttributes:
    priority: PriorityEnum = PriorityEnum.MEDIUM
    verification_method: VerificationMethod = VerificationMethod.UNIT_TEST
    status: StatusEnum = StatusEnum.DRAFT
    is_user_doc: bool = False
    extra: Dict[str, Any] = field(default_factory=dict)

@dataclass
class ItemMetadata:
    author: str = "Metsuke"
    declared_in_project: str = ""
    ai_guardrails: Optional[str] = None
    created_at: Optional[str] = None
    updated_at: Optional[str] = None

@dataclass
class MOMItem:
    id: str
    phase: ESAPhase
    title: str
    description: str
    parent_ids: List[str] = field(default_factory=list)
    child_ids: List[str] = field(default_factory=list)
    attributes: ItemAttributes = field(default_factory=ItemAttributes)
    metadata: ItemMetadata = field(default_factory=ItemMetadata)

    def __post_init__(self) -> None:
        if isinstance(self.phase, str):
            self.phase = ESAPhase(self.phase)

        prefix = self.phase.value.upper()
        if not self.id.startswith(f"{prefix}-"):
            raise ValueError(f"El ID '{self.id}' debe comenzar con el prefijo '{prefix}-'")

    def to_dict(self) -> Dict[str, Any]:
        return asdict(self)

    @classmethod
    def from_dict(cls, data: Dict[str, Any]) -> "MOMItem":
        attr_data = data.get("attributes", {})
        meta_data = data.get("metadata", {})

        attr = ItemAttributes(
            priority=PriorityEnum(attr_data.get("priority", "MEDIUM")),
            verification_method=VerificationMethod(attr_data.get("verification_method", "UNIT_TEST")),
            status=StatusEnum(attr_data.get("status", "DRAFT")),
            is_user_doc=attr_data.get("is_user_doc", False),
            extra=attr_data.get("extra", {})
        )
        meta = ItemMetadata(
            author=meta_data.get("author", "Metsuke"),
            declared_in_project=meta_data.get("declared_in_project", ""),
            ai_guardrails=meta_data.get("ai_guardrails"),
            created_at=meta_data.get("created_at"),
            updated_at=meta_data.get("updated_at")
        )
        return cls(
            id=data["id"],
            phase=ESAPhase(data["phase"]),
            title=data["title"],
            description=data["description"],
            parent_ids=data.get("parent_ids", []),
            child_ids=data.get("child_ids", []),
            attributes=attr,
            metadata=meta
        )

6. Gestor Multiproyecto y Herencia Resolutiva (mom/projects.py)

Administración de proyectos con resolución de herencia múltiple mediante un Grafo Acíclico Dirigido (DAG).

import json
import shutil
from pathlib import Path
from typing import List, Dict, Set, Optional
from mom.schemas import MOMItem, ESAPhase

class ProjectManager:
    def __init__(self, data_dir: Path = Path("data/projects")) -> None:
        self.data_dir = data_dir
        self.data_dir.mkdir(parents=True, exist_ok=True)

    def create_project(self, project_name: str, parent_projects: Optional[List[str]] = None) -> Path:
        proj_dir = self.data_dir / project_name
        if proj_dir.exists():
            raise FileExistsError(f"El proyecto '{project_name}' ya existe.")

        for phase in ESAPhase:
            (proj_dir / "src" / phase.value).mkdir(parents=True, exist_ok=True)

        (proj_dir / "doc").mkdir(parents=True, exist_ok=True)
        (proj_dir / "vault").mkdir(parents=True, exist_ok=True)

        meta = {
            "name": project_name,
            "version": "0.1.0",
            "parent_projects": parent_projects or []
        }
        with open(proj_dir / "project.json", "w", encoding="utf-8") as f:
            json.dump(meta, f, indent=2)

        return proj_dir

    def get_inheritance_chain(self, target_project: str) -> List[str]:
        """Calcula el orden topológico de resolución de proyectos evitando ciclos."""
        resolved: List[str] = []
        visited: Set[str] = set()

        def dfs(p_name: str, path: Set[str]) -> None:
            if p_name in path:
                raise ValueError(f"Ciclo de herencia detectado: {' -> '.join(path)} -> {p_name}")
            if p_name not in visited:
                visited.add(p_name)
                path.add(p_name)
                p_json = self.data_dir / p_name / "project.json"
                if p_json.exists():
                    with open(p_json, "r", encoding="utf-8") as f:
                        data = json.load(f)
                    for parent in data.get("parent_projects", []):
                        dfs(parent, path)
                path.remove(p_name)
                resolved.append(p_name)

        dfs(target_project, set())
        return resolved

class MOMInheritedRepository:
    """Repositorio que agrega y consolida los elementos del proyecto objetivo y todos sus ancestros."""
    def __init__(self, pm: ProjectManager, project_name: str) -> None:
        self.pm = pm
        self.project_name = project_name
        self.chain = pm.get_inheritance_chain(project_name)
        self.project_dir = pm.data_dir / project_name

    def list_all_consolidated(self) -> Dict[str, MOMItem]:
        """Devuelve un mapa con los elementos acumulados, aplicando sobrescritura de especialización."""
        items: Dict[str, MOMItem] = {}
        for proj_name in self.chain:
            proj_src = self.pm.data_dir / proj_name / "src"
            for phase in ESAPhase:
                p_dir = proj_src / phase.value
                if p_dir.exists():
                    for f_path in p_dir.glob("*.json"):
                        with open(f_path, "r", encoding="utf-8") as f:
                            data = json.load(f)
                            item = MOMItem.from_dict(data)
                            if not item.metadata.declared_in_project:
                                item.metadata.declared_in_project = proj_name
                            items[item.id] = item
        return items

7. Compilador y Despliegue en Carpeta Target (mom/compiler.py)

Compila el proyecto consolidado y copia automáticamente los entregables a la carpeta docs/ del software destino.

import shutil
from pathlib import Path
from typing import Dict, List, Optional
from mom.projects import MOMInheritedRepository
from mom.schemas import ESAPhase, MOMItem

class MOMCompiler:
    def __init__(self, repo: MOMInheritedRepository, target_docs_dir: Optional[Path] = None) -> None:
        self.repo = repo
        self.project_dir = repo.project_dir
        self.doc_out = self.project_dir / "doc"
        self.vault_out = self.project_dir / "vault"
        self.agents_out = self.project_dir / "AGENTS.md"
        self.target_docs_dir = target_docs_dir

    def validate_graph(self) -> List[str]:
        errors: List[str] = []
        all_items = self.repo.list_all_consolidated()

        for item_id, item in all_items.items():
            for pid in item.parent_ids:
                if pid not in all_items:
                    errors.append(f"[{item.id}] (de '{item.metadata.declared_in_project}') apunta a parent_id inexistente: '{pid}'")

            if item.phase != ESAPhase.URD and not item.parent_ids:
                errors.append(f"[{item.id}] El elemento de fase '{item.phase.value}' no tiene padres.")

        return errors

    def compile_all(self) -> None:
        self.doc_out.mkdir(parents=True, exist_ok=True)
        self.vault_out.mkdir(parents=True, exist_ok=True)
        all_items = self.repo.list_all_consolidated()

        # 1. Compilación de documentos consolidados
        for phase in ESAPhase:
            phase_items = [i for i in all_items.values() if i.phase == phase]
            phase_items.sort(key=lambda x: x.id)

            blocks: List[str] = []
            for item in phase_items:
                guardrail = f"\n> ⚠️ **AI Guardrails:** {item.metadata.ai_guardrails}\n" if item.metadata.ai_guardrails else ""
                parents = f"**Padres:** {', '.join(item.parent_ids)}\n" if item.parent_ids else ""
                children = f"**Hijos:** {', '.join(item.child_ids)}\n" if item.child_ids else ""
                origin = f"**Origen:** `{item.metadata.declared_in_project}`\n"

                block = f"## {item.id}: {item.title}\n" \
                        f"**Estado:** `{item.attributes.status.value}` | **Prioridad:** `{item.attributes.priority.value}` | {origin}\n" \
                        f"### Descripción\n{item.description}\n\n" \
                        f"{parents}{children}{guardrail}\n---"
                blocks.append(block)

            content = f"# Documentación Consolidada ESA PSS-05 - Fase {phase.value.upper()}\n\n" + "\n\n".join(blocks)
            with open(self.doc_out / f"{phase.value.upper()}.md", "w", encoding="utf-8") as f:
                f.write(content)

        # 2. Compilación de AGENTS.md acumulado
        guardrail_items = [i for i in all_items.values() if i.metadata.ai_guardrails]
        blocks = [f"### Componente `{i.id}` ({i.title}) - Origen: `{i.metadata.declared_in_project}`\n> 🛑 **Guardrail Inmutable:** {i.metadata.ai_guardrails}\n" for i in guardrail_items]
        agents_content = "# AGENTS.md - Contexto de Onboarding e Instrucciones para IA\n\n" + "\n".join(blocks)
        with open(self.agents_out, "w", encoding="utf-8") as f:
            f.write(agents_content)

        # 3. Despliegue en carpeta target
        if self.target_docs_dir:
            self.target_docs_dir.mkdir(parents=True, exist_ok=True)
            for md_file in self.doc_out.glob("*.md"):
                shutil.copy(md_file, self.target_docs_dir / md_file.name)
            if self.agents_out.exists():
                shutil.copy(self.agents_out, self.target_docs_dir / "AGENTS.md")

8. Interfaz CLI Unificada (mom/cli.py)

import sys
import argparse
from pathlib import Path
from mom.projects import ProjectManager, MOMInheritedRepository
from mom.compiler import MOMCompiler

def main() -> None:
    parser = argparse.ArgumentParser(description="MOM (MetsuOS Methodology) Multi-Project Standalone CLI")
    subparsers = parser.add_subparsers(dest="command")

    # Comando: projects
    proj_parser = subparsers.add_parser("projects", help="Gestión de proyectos MOM")
    proj_parser.add_argument("--action", choices=["list", "create"], required=True)
    proj_parser.add_argument("--name", help="Nombre del proyecto")
    proj_parser.add_argument("--parents", help="Proyectos padres separados por coma (ej. std-posix,std-a11y)")

    # Comando: compile
    compile_parser = subparsers.add_parser("compile", help="Compila las especificaciones con herencia de un proyecto")
    compile_parser.add_argument("--project", required=True, help="Nombre del proyecto")
    compile_parser.add_argument("--target-docs", help="Ruta destino opcional (ej. /mi-repo/docs)")

    args = parser.parse_args()
    pm = ProjectManager()

    if args.command == "projects":
        if args.action == "list":
            print(f"📋 Proyectos MOM disponibles:")
            for p in pm.data_dir.iterdir():
                if p.is_dir() and (p / "project.json").exists():
                    print(f"  - {p.name}")
        elif args.action == "create":
            if not args.name:
                print("❌ Debe especificar --name para crear un proyecto.")
                sys.exit(1)
            parents = [p.strip() for p in args.parents.split(",")] if args.parents else []
            proj_dir = pm.create_project(args.name, parent_projects=parents)
            print(f"✅ Proyecto '{args.name}' creado. Hereda de: {parents}")

    elif args.command == "compile":
        repo = MOMInheritedRepository(pm, args.project)
        target_path = Path(args.target_docs) if args.target_docs else None
        compiler = MOMCompiler(repo, target_docs_dir=target_path)

        errors = compiler.validate_graph()
        if errors:
            print("❌ Error de validación en el grafo de herencia del proyecto:")
            for err in errors:
                print(f"  - {err}")
            sys.exit(1)

        compiler.compile_all()
        print(f"✅ Proyecto '{args.project}' y sus dependencias compilados correctamente.")
        if target_path:
            print(f"📦 Documentación desplegada en: {target_path}")

    else:
        parser.print_help()

if __name__ == "__main__":
    main()

9. Ejemplo de Especificación JSON Atómica con Namespace (data/projects/std-a11y/src/urd/URD-A11Y-001.json)

{
  "id": "URD-A11Y-001",
  "phase": "urd",
  "title": "Soporte Universal de Navegación por Teclado",
  "description": "Todos los componentes interactivos de la interfaz deben ser plenamente operables a través de secuencias de teclado estándar sin atrapar el foco.",
  "parent_ids": [],
  "child_ids": [
    "SRD-A11Y-KEYBOARD-01"
  ],
  "attributes": {
    "priority": "CRITICAL",
    "verification_method": "DEMONSTRATION",
    "status": "APPROVED",
    "is_user_doc": true,
    "extra": {}
  },
  "metadata": {
    "author": "Metsuke",
    "declared_in_project": "std-a11y",
    "ai_guardrails": "Prohibido eliminar eventos onKeyDown/onKeyPress en componentes reutilizables.",
    "created_at": null,
    "updated_at": null
  }
}

10. Bibliografía y Referencias

  1. ESA Board for Software Standardisation and Control (BSSC) (1991): ESA Software Engineering Standards (PSS-05-0 Issue 2). European Space Agency. 🟡③🌐 .- Estándar normativo de la ESA (PSS-05-0 Issue 2, febrero 1991) que define el ciclo de vida del software, prácticas obligatorias, gestión de requisitos, diseño, trazabilidad formal y aseguramiento de calidad para software entregable, ya sea desarrollado internamente o por industria.
  2. Metsuke (2026): Novedades MOS / Definición de MOM (MetsuOS Methodology). 🟡③🌐 .- Anuncio conceptual de MOM (MetsuOS Methodology) como marco metodológico de atomización extrema y trazabilidad estricta inspirado en los estándares ESA, orientado a la contención de agentes de IA y al desarrollo controlado de MetsuOS (MOS2/MOS3) y sistemas relacionados.
  3. Martin, R. C. (2017): Clean Architecture: A Craftsman's Guide to Software Structure and Design. Prentice Hall. 🟡③🌐 .- Principios de arquitectura de software, fronteras entre componentes, inmutabilidad, capas y prácticas de diseño mantenible basados en las reglas de Robert C. Martin (Uncle Bob), aplicables a aplicaciones web, de base de datos, thick-client, consola y embebidas.
  4. ISO/IEC (1990/1999): Programming Languages — C (ISO/IEC 9899:1990 / ISO/IEC 9899:1999) y ISO/IEC 14882:1998 (C++98). 🟡③🌐 .- Especificaciones formales de los lenguajes C (C90/C99) y C++98 que definen la sintaxis, semántica y requisitos de implementación para software nativo portable, independiente de dependencias corporativas y compatible con plataformas modernas y legacy.