05_01_00_level_definitions - La Taxonomía de la Complejidad¶
🎯 Propósito¶
Implementación de las definiciones fundamentales de la jerarquía L0→L1→L2→L3 que gobierna toda la arquitectura AudioLab DSP.
Este módulo provee: - Enums de niveles (L0_KERNEL, L1_ATOM, L2_CELL, L3_ENGINE) - Matriz de dependencias (4x4) enforceando reglas arquitectónicas - Parser de metadata para módulos (JSON/YAML) - API completa para query y validación de niveles
📂 Estructura¶
05_01_00_level_definitions/
├── include/
│ └── level_definitions.hpp # Header principal (API pública)
│
├── src/
│ ├── level_registry.cpp # Implementación de LevelRegistry
│ ├── dependency_matrix.cpp # Implementación de matriz 4x4
│ └── metadata_parser.cpp # Parser JSON/YAML
│
├── tests/
│ └── test_level_definitions.cpp # Suite de tests (>95% coverage)
│
├── examples/
│ └── level_usage.cpp # Ejemplo de uso completo
│
├── docs/
│ ├── LEVEL_SEMANTICS.md # Definición formal de cada nivel
│ └── decision_tree.puml # Árbol de decisión visual
│
├── CMakeLists.txt # Build system
└── README.md # Este archivo
🚀 Quick Start¶
1. Compilar¶
2. Ejecutar tests¶
3. Ejecutar ejemplo¶
💻 Uso Básico¶
Incluir header¶
Clasificar un módulo¶
auto& registry = LevelRegistry::instance();
// Parse level from string
ModuleLevel level = registry.level_from_string("L1_ATOM");
// Get characteristics
auto chars = registry.get_characteristics(level);
if (chars) {
std::cout << "Level: " << chars->name << "\n";
std::cout << "Stateless: " << chars->is_stateless << "\n";
std::cout << "Max dependencies: " << chars->max_dependencies << "\n";
}
Validar dependencia¶
// Check if L1_ATOM can depend on L0_KERNEL
bool valid = is_valid_dependency(
ModuleLevel::L1_ATOM,
ModuleLevel::L0_KERNEL
);
// valid == true ✅
// Check if L1_ATOM can depend on L1_ATOM
bool invalid = is_valid_dependency(
ModuleLevel::L1_ATOM,
ModuleLevel::L1_ATOM
);
// invalid == false ❌
Parsear metadata de módulo¶
std::string json = R"({
"module_name": "SVF_Filter",
"level": "L1_ATOM",
"version": "1.0.0",
"dependencies": ["mul_kernel", "add_kernel"]
})";
auto metadata = MetadataParser::from_json(json);
if (metadata) {
std::cout << "Module: " << metadata->module_name << "\n";
std::cout << "Level: " << level_name(metadata->level) << "\n";
}
Ver matriz de dependencias¶
auto& matrix = DependencyMatrix::instance();
std::cout << matrix.to_string();
// Output:
// Dependency Matrix [from][to]:
//
// L0 L1 L2 L3
// L0_KERNEL ❌ ❌ ❌ ❌
// L1_ATOM ✅ ❌ ❌ ❌
// L2_CELL ✅ ✅ ✅* ❌
// L3_ENGINE ✅ ✅ ✅ ❌
📊 Matriz de Dependencias¶
L0 L1 L2 L3
L0_KERNEL ❌ ❌ ❌ ❌
L1_ATOM ✅ ❌ ❌ ❌
L2_CELL ✅ ✅ ✅* ❌
L3_ENGINE ✅ ✅ ✅ ❌
* = permitido sin ciclos
Lectura: Fila "puede depender de" Columna
🔑 Clases Principales¶
LevelRegistry¶
Singleton que mantiene características de cada nivel.
LevelRegistry& registry = LevelRegistry::instance();
// Convert string ↔ enum
ModuleLevel level = registry.level_from_string("L1_ATOM");
std::string name = registry.level_to_string(level);
// Get characteristics
auto chars = registry.get_characteristics(ModuleLevel::L0_KERNEL);
// Get all levels
auto all = registry.all_levels(); // [L0, L1, L2, L3]
DependencyMatrix¶
Singleton que enforcea reglas de dependencias.
DependencyMatrix& matrix = DependencyMatrix::instance();
// Validate single dependency
bool valid = matrix.is_valid_dependency(from_level, to_level);
// Get allowed dependencies for a level
auto allowed = matrix.allowed_dependencies(ModuleLevel::L2_CELL);
// Returns: [L0_KERNEL, L1_ATOM, L2_CELL]
// Get matrix as 2D array
const auto& mat = matrix.get_matrix(); // [4][4] array
MetadataParser¶
Parse y serializa metadata de módulos.
// Parse from JSON
auto meta = MetadataParser::from_json(json_string);
// Parse from YAML
auto meta = MetadataParser::from_yaml(yaml_string);
// Parse from file (auto-detect format)
auto meta = MetadataParser::from_file("module.json");
// Serialize to JSON
std::string json = MetadataParser::to_json(metadata);
// Serialize to YAML
std::string yaml = MetadataParser::to_yaml(metadata);
📚 Documentación¶
Lectura Recomendada (en orden)¶
- LEVEL_SEMANTICS.md ⭐ IMPORTANTE
- Definición formal de cada nivel
- Ejemplos correctos e incorrectos
- Decision tree de clasificación
-
20+ ejemplos de módulos clasificados
- 6 ejemplos completos de uso
- Cómo usar cada clase
-
Casos de uso comunes
- Árbol de decisión visual
- Diagrama PlantUML
🎯 Decision Tree: ¿Qué nivel es mi módulo?¶
¿Tiene estado interno? (phase, buffers, etc.)
│
NO → L0_KERNEL
│ (add, mul, sin, interpolate)
│
YES → ¿Es combinación de otros módulos?
│
NO → L1_ATOM
│ (Oscillator, Filter, Envelope)
│
YES → ¿Es sistema completo listo para plugin?
│
NO → L2_CELL
│ (SynthVoice, Compressor, EffectChain)
│
YES → L3_ENGINE
(PolySynth, Reverb, MasteringChain)
✅ Tests¶
Ejecutar suite completa¶
Cobertura esperada¶
- Target: >95% code coverage
- Frameworks: Catch2 v3
- Test cases: 30+ test sections
Categorías de tests¶
[level_registry]- Tests de LevelRegistry[dependency_matrix]- Tests de matriz de dependencias[metadata]- Tests de ModuleMetadata[metadata_parser]- Tests de parser JSON/YAML[utilities]- Tests de funciones helper[properties]- Property-based tests (transitividad, etc.)
📋 API Reference¶
Enums¶
enum class ModuleLevel : uint8_t {
L0_KERNEL = 0,
L1_ATOM = 1,
L2_CELL = 2,
L3_ENGINE = 3,
INVALID = 255
};
Structs¶
struct LevelCharacteristics {
ModuleLevel level;
std::string name;
std::string description;
bool is_stateless;
bool is_composable;
bool allows_dependencies;
uint32_t max_dependencies;
std::vector<std::string> responsibilities;
std::vector<std::string> prohibitions;
};
struct ModuleMetadata {
std::string module_name;
ModuleLevel level;
std::vector<std::string> dependencies;
std::string version;
std::string description;
bool is_valid() const;
};
Utility Functions¶
// Validate dependency
bool is_valid_dependency(ModuleLevel from, ModuleLevel to);
// Get level name
std::string level_name(ModuleLevel level);
// Parse level from string
ModuleLevel parse_level(const std::string& name);
🛠️ Build Options¶
# Build with tests
cmake -DBUILD_TESTS=ON ..
# Build with examples
cmake -DBUILD_EXAMPLES=ON ..
# Build with coverage (GCC/Clang)
cmake -DCMAKE_CXX_FLAGS="--coverage" ..
# Release build
cmake -DCMAKE_BUILD_TYPE=Release ..
📝 Formato de Metadata¶
JSON¶
{
"module_name": "SVF_Filter",
"level": "L1_ATOM",
"version": "1.0.0",
"description": "State Variable Filter",
"dependencies": ["mul_kernel", "add_kernel"]
}
YAML¶
module_name: SVF_Filter
level: L1_ATOM
version: 1.0.0
description: State Variable Filter
dependencies:
- mul_kernel
- add_kernel
⚡ Performance¶
- Level lookup: O(1) (array indexing)
- Dependency check: O(1) (matrix lookup)
- String parsing: O(n) (simple string ops)
- Metadata parsing: O(n) (streaming parser)
Recomendación: Cache results en hot paths.
🔗 Dependencias¶
Runtime¶
- C++20 compiler (para concepts, ranges)
- STL standard library
Build-time¶
- CMake 3.20+
- Catch2 v3 (auto-fetched si no encontrado)
Optional¶
- nlohmann/json (para mejor JSON parsing)
- yaml-cpp (para mejor YAML parsing)
📌 Próximos Pasos¶
Después de completar este módulo, continuar con:
- 05_01_01_composition_rules - Reglas de composición
- 05_01_02_validation_engine - Motor de validación
🆘 FAQ¶
P: ¿Cómo sé si mi módulo es L1 o L2? R: Si compone múltiples L1_ATOMs → L2_CELL. Si es un solo algoritmo → L1_ATOM.
P: ¿L2 puede depender de L2? R: Sí, PERO sin crear ciclos. Usa DAG analysis para verificar.
P: ¿Por qué L0 no puede depender de nada? R: L0 es la base del sistema. Si dependiera de algo, ese "algo" debería ser L0 (contradicción).
P: ¿Cómo clasificar un módulo ambiguo? R: Usa el decision tree en LEVEL_SEMANTICS.md.
Status: ✅ Completado Cobertura: >95% Última actualización: 2025-10-10