1391 lines
33 KiB
Markdown
Raw Permalink Normal View History

---
theme: default
title: Ontology and Reflection
titleTemplate: '%s - OntoRef'
layout: cover
keywords: Nickel,Nushell,Ontology,Reflection,StratumIOps
download: true
exportFilename: OntoRef
monaco: true
remoteAssets: true
selectable: true
record: true
colorSchema: dark
lineNumbers: false
themeConfig:
primary: '#f74c00'
logoHeader: '/ferris.svg'
fonts:
mono: 'Victor Mono'
drawings:
enabled: true
persist: false
presenterOnly: false
syncAll: true
scripts:
- setup/image-overlay.ts
class: 'justify-center flex flex-cols'
---
<h1 class="font-medium">Ontology & Reflection</h1>
<h2 class="flex justify-center mt-5 font-medium text-orange-400">
<img class="-mt-2 h-32" src="/ontoref-text.svg">
</h2>
<div class="flex justify-center mt-3 text-gray-400 text-lg italic">
Typing the invisible. Verifying the obvious. Sealing what matters.
</div>
<div class="flex justify-center">
<img class="mt-8 w-40" src="/jesusperez_w.svg">
</div>
<div class="flex justify-center">
<img class="mt-8 w-40" src="/ontoref_img.svg">
</div>
<style scoped>
h1, h2, p { z-index: 10; }
</style>
<Footer />
<!--
Open with silence. Let the subtitle land.
This talk is not about tools — it is about the epistemic contract between code and understanding.
-->
---
layout: two-cols
---
# ¿Qué estamos resolviendo?
<div>
**Los problemas**
<div class="mt-3 space-y-3">
<div class="flex items-start gap-2">
<span class="text-red-500 font-bold text-sm mt-1">🔴</span>
<div><span class="text-gray-200 font-semibold">Epistemic drift</span><br><span class="text-gray-400 text-sm">El código hace X, el equipo cree que hace Y.<br> Silencioso. Acumulativo.</span></div>
</div>
<div class="flex items-start gap-2">
<span class="text-red-500 font-bold text-sm mt-1">🔴</span>
<div><span class="text-gray-200 font-semibold">Multi-actor collision</span><br><span class="text-gray-400 text-sm">Humano + agente IA escriben al mismo fichero,<br> sin coordinación.</span></div>
</div>
<div class="flex items-start gap-2">
<span class="text-orange-400 font-bold text-sm mt-1">🟠</span>
<div><span class="text-gray-200 font-semibold">Decision amnesia</span><br><span class="text-gray-400 text-sm">¿Por qué se tomó esta decisión? ¿Quién la autorizó?</span></div>
</div>
<div class="flex items-start gap-2">
<span class="text-orange-400 font-bold text-sm mt-1">🟠</span>
<div><span class="text-gray-200 font-semibold">Config schizophrenia</span><br><span class="text-gray-400 text-sm">Staging funciona, prod no. ¿Qué campo cambió y cuándo?</span></div>
</div>
</div>
</div>
::right::
<div>
<div class="flex items-start gap-2">
<span class="text-orange-400 font-bold text-sm mt-1">🟠</span>
<div><span class="text-gray-200 font-semibold">Docs como artefactos muertos</span><br><span class="text-gray-400 text-sm">Escritas una vez, olvidadas, nunca actualizadas.</span></div>
</div>
<div class="flex items-start gap-2 mt-2">
<span class="text-yellow-400 font-bold text-sm mt-1">🟡</span>
<div><span class="text-gray-200 font-semibold">Agent con ceguera</span><br><span class="text-gray-400 text-sm">Los agentes IA empiezan sin contexto,<br> violan invariantes establecidas.</span></div>
</div>
<v-click>
<div class="mt-2 text-xs text-gray-400 space-y-2 font-mono">
**Ejemplo: desincronización real**
```bash
# Documentación (2024-01)
config.max_retries = 3
# Código actual (después de cambio sin registrar)
config.max_retries = 7
# Equipo cree que está usando 3 ✗
# Sistema usa 7 silenciosamente ✓
# Nadie sabe cuándo cambió ni por qué
```
</div>
</v-click>
</div>
<Footer />
<!--
Pause after each severity badge. The audience will recognize these — they have lived this.
Goal is recognition, not education. Ask silently: "how many of these are in your project right now?"
-->
---
layout: default
---
# El coste de ignorarlo
<div class="grid grid-cols-2 gap-8 mt-4">
<div>
<div class="box-highlight mt-2 font-mono text-xs">
```text
Deuda técnica → arreglable
Deuda epistémica → sistémica
Deuda de confianza → letal
```
</div>
<v-click>
<div class="mt-4 space-y-5 text-xs text-gray-300">
<div class="border-l-2 border-red-500 pl-2">
<div class="font-semibold text-red-300">Técnica</div>
<div class="text-gray-400">Refactoriza, reescribe, corrige.</div>
<div class="text-gray-500 text-xs">1-3 sprints</div>
</div>
<div class="border-l-2 border-orange-500 pl-2">
<div class="font-semibold text-orange-300">Epistémica</div>
<div class="text-gray-400">Acumula silenciosamente. No sabes dónde.</div>
<div class="text-gray-500 text-xs">Crece cada semana</div>
</div>
<div class="border-l-2 border-yellow-600 pl-2">
<div class="font-semibold text-yellow-300">Confianza</div>
<div class="text-gray-400">Se disuelve cuando se descubre el drift.</div>
<div class="text-gray-500 text-xs">Imposible reparar rápido</div>
</div>
</div>
</v-click>
</div>
<div>
<v-click>
<div class="mt-2 text-gray-300">
**Escenario: 6 meses de ignorar**
<div class="mt-3 font-mono text-xs space-y-2 text-gray-400">
```yaml
Mes 1: "Solo refactorizar esto"
Mes 2: "Documentación está desactualizada"
Mes 3: "¿Por qué prod falla y staging no?"
Mes 4: "Nadie sabe quién cambió qué"
Mes 5: Pánico. Rollback arriesgado.
Mes 6: Equipo rechaza cambios nuevos.
"No confiamos sin entender"
```
</div>
</div>
</v-click>
<v-click>
<div class="mt-8 text-gray-300 text-base leading-7 border-l-4 border-orange-500 pl-4">
Estos problemas no tienen solución técnica.<br>
Tienen solución de <em>arquitectura</em>.
</div>
</v-click>
</div>
</div>
---
layout: default
---
<h1 class="-mt-5"> Verdad y operación — dos fuerzas que deben coexistir </h1>
<div class="grid grid-cols-2 gap-8 mt-4">
<div class="border-l-4 border-blue-500 pl-4">
**Yin — la capa formal**
*Lo que debe ser verdad*
<div class="mt-3 space-y-2 text-sm text-gray-300">
- **Nickel schemas** → corrección estructural<br> en tiempo de definición
- **ADR constraints** → "esto nunca puede violarse"
- **Config seals** → estados sellados, verificables con sha256
- **Ontology invariants** → lo que no puede cambiar <br> sin un nuevo ADR
- **Hashes matemáticos** → prueba de qué fue sellado<br> y cuándo
</div>
</div>
<div class="border-l-4 border-orange-500 pl-4">
**Yang — la capa operacional**
*Cómo las cosas se mueven y cambian*
<div class="-mt-2 space-y-2 text-sm text-gray-300">
- **Nu commands** → transformación estructurada de datos
- **Actors** (human/agent/CI) → mismo protocolo,<br> distintas capacidades
- **Register flow** → captura cambios,<br> los enruta al artefacto correcto
- **Mode definitions** → secuencias de operaciones<br> con verificación
- **Pre-commit hooks** → sincronización forzada <br>en el momento del commit
</div>
</div>
</div>
<v-click>
<div class="mt-1 border border-gray-700 rounded p-4 bg-gray-900 text-sm text-gray-300 font-mono leading-7">
```text
Yang sin Yin = fluido pero caótico. Cualquier cosa puede cambiar. Nada es verificable.
Yin sin Yang = correcto pero inútil. Schemas perfectos sin operaciones = documentación muerta.
```
<div class="text-orange-400 text-center mt-2 font-sans font-semibold">El sistema vive en la coexistencia.</div>
</div>
</v-click>
<Footer />
<!--
The Yin/Yang is not metaphor for aesthetics — it is the architectural duality.
Pure formal layer without operation is a museum. Pure operation without formal layer is controlled chaos.
Hold the tension statement at the end. It is the thesis.
-->
---
layout: center
---
# Los ingredientes
<div class="mt-2 space-y-3">
<div class="border-l-4 border-blue-400 pl-4 py-2 bg-gray-900 rounded-r">
<div class="text-blue-300 font-mono font-semibold text-sm">CAPA DECLARATIVA &nbsp;·&nbsp; Nickel</div>
<div class="text-gray-400 text-sm mt-1"><code>.ontology/</code> &nbsp;·&nbsp; <code>adrs/</code> &nbsp;·&nbsp; <code>reflection/schemas/</code> &nbsp;·&nbsp; <code>reflection/configs/</code></div>
<div class="text-gray-500 text-xs mt-1">Tipos fuertes, contratos, enums. Falla en definición, no en runtime.</div>
</div>
<div class="border-l-4 border-orange-400 pl-4 py-2 bg-gray-900 rounded-r">
<div class="text-orange-300 font-mono font-semibold text-sm">CAPA OPERACIONAL &nbsp;·&nbsp; Nushell</div>
<div class="text-gray-400 text-sm mt-1"><code>adr</code> &nbsp;·&nbsp; <code>register</code> &nbsp;·&nbsp; <code>config</code> &nbsp;·&nbsp; <code>backlog</code> &nbsp;·&nbsp; <code>forms</code> &nbsp;·&nbsp; <code>prereqs</code></div>
<div class="text-gray-500 text-xs mt-1">Pipelines tipadas sobre datos estructurados. No streams de texto.</div>
</div>
<div class="border-l-4 border-green-400 pl-4 py-2 bg-gray-900 rounded-r">
<div class="text-green-300 font-mono font-semibold text-sm">PUNTO DE ENTRADA &nbsp;·&nbsp; Bash → Nu</div>
<div class="text-gray-400 text-sm mt-1"><code>stratum.sh</code> &nbsp;·&nbsp; actor detection &nbsp;·&nbsp; locking &nbsp;·&nbsp; <code>NICKEL_IMPORT_PATH</code></div>
<div class="text-gray-500 text-xs mt-1">Un único entry point. Detecta actor, adquiere lock, despacha al módulo Nu correcto.</div>
</div>
<div class="border-l-4 border-purple-400 pl-4 py-2 bg-gray-900 rounded-r">
<div class="text-purple-300 font-mono font-semibold text-sm">GRAFO DE CONOCIMIENTO &nbsp;·&nbsp; Ontología + ADRs</div>
<div class="text-gray-400 text-sm mt-1">nodes &nbsp;·&nbsp; invariants &nbsp;·&nbsp; gates &nbsp;·&nbsp; dimensions &nbsp;·&nbsp; states</div>
<div class="text-gray-500 text-xs mt-1">El sistema sabe qué sabe. Actor-agnostic. Machine-queryable.</div>
</div>
<div class="border-l-4 border-yellow-400 pl-4 py-2 bg-gray-900 rounded-r">
<div class="text-yellow-300 font-mono font-semibold text-sm">ESTADOS SELLADOS &nbsp;·&nbsp; Config + Historia</div>
<div class="text-gray-400 text-sm mt-1">profiles &nbsp;·&nbsp; sha256 seals &nbsp;·&nbsp; audit trail &nbsp;·&nbsp; rollback</div>
<div class="text-gray-500 text-xs mt-1">Inmutabilidad verificable. Drift detection. Trazabilidad completa ADR/PR/bug.</div>
</div>
</div>
<Footer />
<!--
This is the map, not the territory. Each layer will get its own slide.
Point bottom-up: sealed states give you history; the graph gives you meaning; the entry point gives you discipline.
-->
---
layout: default
---
# Nickel — configuración con tipos, sin runtime
<div class="grid grid-cols-2 gap-8 mt-4">
<div>
**Qué es Nickel**
<div class="text-sm text-gray-300 space-y-1 mt-2">
- Lenguaje de configuración con tipos fuertes (de Tweag)
- Puramente declarativo: sin efectos secundarios, sin loops, sin runtime
- Superset de JSON: JSON válido es Nickel válido
- Imports: <small>`let s = import "schema.ncl" in`</small>
- Contratos: `field | TypeName` — verificado al merge
- Enums tipados: <small>`[| 'Proposed, 'Accepted, 'Superseded |]`</small>
- Registros abiertos/cerrados: <br> <small>`{ _: String }` vs `{ field | String }`</small>
- `nickel export file.ncl` → JSON estable pipelines Nu
</div>
<div class="mt-4 text-lg text-gray-500 border-l-2 border-orange-500 pl-3 italic">
El sistema de tipos <em>es</em> la documentación.
</div>
</div>
<div>
**Por qué no alternativas**
<div class="font-mono text-xs text-gray-400 -mt-4 space-y-1">
```text
YAML → sin tipos, whitespace-sensitive,
coerciones implícitas
TOML → sin tipos ≥ primitivos, sin imports
JSON → sin comentarios, sin imports, sin tipos
HCL → efectos secundarios, no es config pura
CUE → similar pero peor historia de imports
KCL → tipos + validación, pero vendedor
lenguaje opaco
```
</div>
<div class="mt-i2 text-lg text-gray-300 font-semibold">Por qué aquí específicamente</div>
<div class="text-xs text-gray-400 mt-1 space-y-1">
- ADR constraints necesitan typecheck, no validación manual
- Perfiles de config deben fallar en definición, no en runtime
- `nickel export` produce JSON estable para consumo Nu
</div>
<v-click>
<div class="mt-1 font-mono text-xs">
```bash
# YAML: silently accepts garbage
actor: developr # typo, accepted
# Nickel: rejected at typecheck
{ actor | [| 'developer, 'agent, 'ci |] = "developr" }
# ^^^^^^^^^
# error: tag not in enum type
```
</div>
</v-click>
</div>
</div>
<Footer />
<!--
The before/after example is the punchline. Let it sit.
"The type system IS the documentation" — this is the core Nickel thesis. Not a feature, the philosophy.
-->
---
layout: default
---
# Nushell — datos estructurados, no streams de texto
<div class="grid grid-cols-2 gap-8 mt-4">
<div>
**Shell tradicional: texto opaco**
<div class="mt-2 font-mono text-xs">
```bash
# Bash: parsear texto, error-prone
grep 'severity' adrs/adr-001.json |\
python3 -c "import sys,json; ..."
```
</div>
<v-click>
<div class="mt-4 text-sm font-semibold text-gray-200">Nushell: records nativos</div>
<div class="mt-2 font-mono text-xs">
```nu
nickel export adrs/adr-001.ncl
| from json
| get constraints
| where severity == "Hard"
| select id claim
```
</div>
<div class="mt-3 font-mono text-xs text-gray-500">
```text
╭───┬────────────┬──────────────────────────────╮
│ # │ id │ claim │
├───┼────────────┼──────────────────────────────┤
│ 0 │ adr-001-c1 │ nickel export must succeed… │
│ 1 │ adr-001-c2 │ schema is sole source of… │
╰───┴────────────┴──────────────────────────────╯
```
</div>
</v-click>
</div>
<div>
<v-click>
**Nickel → Nu → Bash — tres capas, tres roles**
<div class="mt-3 space-y-3 text-sm">
<div class="box-highlight border-l-4 border-blue-500 pl-3 py-2">
<div class="font-semibold text-blue-300">Nickel exporta JSON tipado</div>
<div class="text-gray-400 text-xs">Nunca strings mágicos. Contratos en la definición, no en runtime.</div>
</div>
<div class="box-highlight border-l-4 border-orange-400 pl-3 py-2">
<div class="font-semibold text-orange-300">Nu consume estructuras</div>
<div class="text-gray-400 text-xs">Tables, records, pipelines. Filter, sort, merge — sin awk ni sed.</div>
</div>
<div class="box-highlight border-l-4 border-gray-500 pl-3 py-2">
<div class="font-semibold text-gray-300">Bash orquesta procesos</div>
<div class="text-gray-400 text-xs">Locking, signals, exec. Solo lo que bash hace de forma nativa.</div>
</div>
</div>
<div class="mt-4 font-mono text-xs">
```nu
# Constraints Hard del sistema completo
glob "adrs/adr-*.ncl"
| each { |f| nickel export $f | complete | get stdout }
| each { from json }
| where status == "Accepted"
| get constraints | flatten
| where severity == "Hard"
```
</div>
</v-click>
</div>
</div>
<Footer />
<!--
Nu is not "better bash". It is a different semantic layer.
Text pipelines are broken by design — structured pipelines are the fix.
Nickel/Nu/Bash: each covers what the others cannot. The division is deliberate.
-->
---
layout: default
---
# DAGs y FSMs — grafos acíclicos y máquinas de estado
<div class="grid grid-cols-2 gap-8 mt-4">
<div>
**FSM: ciclo de vida de un ADR**
<div class="mt-3 font-mono text-xs">
```text
┌──────────┐ adr accept ┌──────────┐
│ Proposed │ ───────────▶ │ Accepted │
└──────────┘ └──────────┘
│ new ADR
│ supersedes
┌────────────┐
│ Superseded │
└────────────┘
```
</div>
<div class="mt-3 text-sm text-gray-300">Transiciones typecheck-enforced en Nickel:</div>
<div class="font-mono text-xs mt-1">
```text
status | [| 'Proposed, 'Accepted, 'Superseded |]
superseded_by | String | default = ""
```
</div>
<v-click>
<div class="mt-4 text-xs text-gray-400">
Las transiciones inválidas no existen <br>
— el tipo las elimina del espacio de posibilidades.<br>
Un ADR no puede volver a Proposed.<br>
Superseded no puede tener constraints activas.
</div>
</v-click>
</div>
<div>
**DAG: ontología como grafo de dependencias**
<div class="mt-3 font-mono text-xs text-gray-300">
```text
invariante: backend-agnostic-core
└─ tensión: nickel-as-canonical-schema
└─ gate: nickel-primacy-gate [activa]
└─ protege: nickel-integration-depth
invariante: zero-external-runtime-core
└─ gate: core-dependency-gate [activa]
└─ protege: backend-agnostic-core
```
</div>
<v-click>
<div class="mt-4 text-sm font-semibold text-gray-200">Por qué importa la aciclicidad</div>
<div class="mt-2 space-y-1 text-sm text-gray-400">
<div>→ Un invariante no puede depender de sí mismo</div>
<div>→ Las gates protegen nodos hoja, no ciclos</div>
<div>→ El rollback es determinista: sin ambigüedad de orden</div>
</div>
<div class="mt-3 font-mono text-xs">
```nu
# Invariantes activos
nickel export .ontology/core.ncl
| from json | get nodos
| where invariante == true
| select id descripcion
```
</div>
</v-click>
</div>
</div>
<Footer />
<!--
State machines are architecture, not documentation.
The ADR FSM has 3 states and 2 transitions — that simplicity is the power.
The ontology DAG is the dependency graph of semantic constraints, not a diagram.
-->
---
layout: default
---
# La Ontología Operacional — el grafo operacional
<div class="grid grid-cols-2 gap-8 mt-4">
<div>
**`core.ncl` — lo que no puede cambiar**
<div class="mt-2 font-mono text-xs">
```text
# .ontology/core.ncl
{
nodos = [
{
id = "backend-agnostic-core",
invariante = true,
descripcion = "business logic sin deps de UI",
tensiones = ["nickel-as-canonical-schema"],
},
],
practicas = [...],
}
```
</div>
<div class="mt-3 text-sm text-gray-400">
Tocar un nodo con <code class="text-orange-300">invariante = true</code> requiere un nuevo ADR. Sin excepción.
</div>
</div>
<div>
**`state.ncl` y `gate.ncl` — dónde estamos**
<v-click>
<div class="mt-2 font-mono text-xs">
```nu
nickel export .ontology/state.ncl
| from json | get dimensiones
| select id estado_actual estado_deseado
```
</div>
<div class="mt-2 font-mono text-xs text-gray-400">
```text
backend-maturity multi-stable → all-production
nickel-integration-depth schema-input → bidirectional
```
</div>
</v-click>
<v-click>
<div class="mt-4 font-mono text-xs">
```nu
nickel export .ontology/gate.ncl
| from json | get membranas
| where activa == true
| select id permeabilidad protege
```
</div>
<div class="mt-2 font-mono text-xs text-gray-400">
```text
core-dependency-gate Low [backend-agnostic-core, ...]
nickel-primacy-gate Low [nickel-as-canonical-schema]
```
</div>
</v-click>
<div class="mt-3 text-xs text-gray-500">
La ontología no es un diagrama.<br>
Es un grafo consultable que el sistema y los agentes leen.
</div>
</div>
</div>
<Footer />
<!--
The .ontology/ directory separates three orthogonal concerns in three files:
core.ncl — what the project IS: invariant axioms and structural tensions.
state.ncl — where it IS vs where it wants to BE.
gate.ncl — when it is READY to cross a boundary.
reflection/ reads all three and answers self-knowledge queries.
This separation allows an agent to understand the project without reading code —
only by consulting the declarative graph.
-->
---
layout: default
---
# Reflection — modos, formas, módulos, perfiles
<div class="grid grid-cols-2 gap-8 -mt-5">
<div>
**Modo: especificación ejecutable**
<div class="mt-1 font-mono text-xs">
```bash
# reflection/modes/new_service.ncl
{
id = "new_service",
trigger = "When adding a service",
steps = [
{
id = "create-adr",
actor = "developer",
action = "Draft ADR for service boundary",
cmd = "stratum form new_adr",
on_error = { strategy = "abort" },
},
{
id = "seal-config",
actor = "developer",
action = "Apply initial config seal",
cmd = "stratum config apply development",
depends_on = [{ step = "create-adr" }],
on_error = { strategy = "abort" },
},
],
}
```
</div>
</div>
<div>
**Forma: entrada estructurada tipada**
<div class="mt-2 font-mono text-xs">
```bash
# reflection/forms/register_change.ncl
{
elements = [
{ type = "section_header", label = "Change" },
{
type = "text",
id = "title",
label = "Title",
required = true,
},
{
type = "select",
id = "change_type",
options = ["feature","fix","refactor","config"],
},
]
}
```
</div>
<v-click>
<div class="mt-3 space-y-2 text-sm">
<div class="box-highlight border-l-4 border-purple-500 pl-3 py-1">
<div class="font-semibold text-purple-300">Perfil de config = estado sellado</div>
<div class="text-gray-400 text-xs"><code>sha256(nickel export profile.ncl)</code> — drift detection instantánea</div>
</div>
<div class="text-xs text-gray-400 mt-2">
<code>stratum config verify development</code> → compara hash actual con hash sellado
</div>
</div>
</v-click>
</div>
</div>
<Footer />
<!--
Modes are not runbooks. They are typed, versioned, queryable operational specifications.
Forms are the structured capture layer — TypeDialog renders them across CLI/TUI/Web backends.
Config profiles seal the observable state with a cryptographic fingerprint.
-->
---
layout: default
---
# ADRs vivos
## — de documento muerto a constraint machine
<div class="grid grid-cols-2 gap-8 mt-1">
<div>
**Estructura Nickel de un ADR**
<div class="-mt-2 font-mono text-xs">
```bash
# adrs/adr-001-nickel-as-canonical.ncl
let s = import "adrs/schema.ncl" in
{
id = "adr-001",
title = "Nickel as First-Class Form Definition",
status = "Accepted",
date = "2025-12-01",
constraints = [
{
id = "adr-001-c1",
severity = "Hard",
claim =
"nickel export must succeed before "
++ "any user interaction",
},
],
superseded_by = "",
} | s.ADR
```
</div>
</div>
<div>
<p class="-mt-2 text-sm font-semibold text-gray-200"> Ciclo de vida y consulta </p>
<div class="-mt-2 font-mono text-xs text-gray-300">
```text
Proposed ──────▶ Accepted ──────▶ Superseded
│ ▲
│ new ADR │
└──────── superseded_by ────────────┘
```
</div>
<v-click>
<div class="mt-2 text-sm font-semibold text-gray-200">Constraints Hard activas del sistema</div>
<div class="mt-2 font-mono text-xs">
```nu
glob "adrs/adr-*.ncl"
| each { |f|
nickel export $f | complete
| if $in.exit_code == 0 {
$in.stdout | from json
} else { null }
}
| compact
| where status == "Accepted"
| get constraints | flatten
| where severity == "Hard"
| select id claim
```
</div>
</v-click>
<v-click>
<div class="mt-3 text-xs text-gray-500">
El conjunto activo de constraints es el contrato en vigor — no la prosa del ADR.
La prosa explica el porqué. Los constraints enforcan el qué.
</div>
</v-click>
</div>
</div>
<Footer />
<!--
"Living ADRs" is not a metaphor.
The machine can query them, validate against them, and enforce them.
The prose explains why. The constraints enforce what.
-->
---
layout: default
---
# Implementación — las partes y cómo encajan
<div class="grid grid-cols-2 gap-8 mt-4">
<div>
**Stack de archivos operativos**
<div class="mt-2 font-mono text-xs text-gray-300">
```bash
stratum.sh ← entry point, locking, env
└─ reflection/bin/stratum.nu ← dispatcher
├─ modules/adr.nu ← ADR lifecycle
├─ modules/register.nu ← CHANGELOG + ontology
├─ modules/config.nu ← sealed profiles
├─ modules/backlog.nu ← backlog items
└─ modules/forms.nu ← TypeDialog integrated
.ontology/ ← queryable truth
├─ core.ncl ← invariants
├─ state.ncl ← dimensions
└─ gate.ncl ← active guards
adrs/ ← typed decisions
reflection/configs/ ← sealed config history
```
</div>
</div>
<div>
**Flujo de escritura protegida**
<v-click>
<div class="mt-2 space-y-2 text-sm">
<div class="box-highlight border-l-4 border-gray-600 pl-3 py-1">
<div class="font-semibold text-gray-200">stratum.sh</div>
<div class="text-gray-400 text-xs">detect actor → acquire lock (mkdir) → delegate → release</div>
</div>
<div class="box-highlight border-l-4 border-orange-500 pl-3 py-1">
<div class="font-semibold text-orange-300">Lock resources</div>
<div class="text-gray-400 text-xs"><code>manifest</code> (config apply/rollback) · <code>changelog</code> (register) · <code>backlog</code> (done/cancel)</div>
</div>
<div class="box-highlight border-l-4 border-blue-500 pl-3 py-1">
<div class="font-semibold text-blue-300">Timestamp IDs</div>
<div class="text-gray-400 text-xs"><code>cfg-20260309T045206-developer</code> — colisión imposible, sin TOCTOU</div>
</div>
</div>
</v-click>
<v-click>
<div class="mt-4 font-mono text-xs text-gray-400">
```bash
# Advisory lock: mkdir es POSIX-atómico
mkdir .stratumiops/locks/manifest.lock 2>/dev/null
echo "$$:developer:$(date -u +%Y%m%dT%H%M%SZ)"
> .stratumiops/locks/manifest.lock/owner
```
</div>
</v-click>
</div>
</div>
<Footer />
<!--
Implementation is derived from architecture — not the other way around.
Every piece exists because a specific problem required it.
The lock is 4 lines of bash because mkdir is atomic on POSIX. No daemon needed.
-->
---
layout: default
---
# Mecánica y flujo — casos de uso reales
<div class="grid grid-cols-2 gap-8 mt-4">
<div>
**Flujo: registrar un cambio**
<div class="mt-2 text-xs space-y-1">
<div class="flex items-start gap-2 mt-1">
<span class="text-orange-400 font-mono font-bold"></span>
<div><code>stratum register</code> → forma TypeDialog interactiva</div>
</div>
<div class="flex items-start gap-2">
<span class="text-orange-400 font-mono font-bold"></span>
<div>Clasificar: tipo de cambio, impacto, ADR relacionado</div>
</div>
<div class="flex items-start gap-2">
<span class="text-orange-400 font-mono font-bold"></span>
<div>Artefacto: entrada CHANGELOG + stub ADR si aplica</div>
</div>
<div class="flex items-start gap-2">
<span class="text-orange-400 font-mono font-bold"></span>
<div>Verificar: <code>nickel typecheck</code> debe pasar</div>
</div>
<div class="flex items-start gap-2">
<span class="text-orange-400 font-mono font-bold"></span>
<div>Sellar si afecta config: <code>stratum config apply</code></div>
</div>
</div>
<v-click>
<div class="mt-4 text-sm font-semibold text-gray-200">Detección de drift</div>
<div class="mt-2 font-mono text-xs">
```nu
stratum config apply production --adr adr-006 --pr 42
# Meses después:
stratum config verify production
# → ✓ verified a3f7c12d8b4e9f01...
# → ✗ DRIFT DETECTED stored vs current hash
```
</div>
</v-click>
</div>
<div>
**Rollback verificado**
<v-click>
<div class="mt-2 font-mono text-xs">
```nu
stratum config history production
stratum config rollback production \
cfg-20260301T120000-developer \
--adr adr-007 \
--note "revert breaking change"
```
</div>
</v-click>
<v-click>
<div class="mt-3 text-xs text-gray-400 space-y-1">
<div><code>snapshot_hash</code> verifica integridad antes de restaurar</div>
<div>→ Rollback genera nuevo sello — la historia es append-only</div>
<div>→ Trazabilidad completa: ADR + PR + bug en cada sello</div>
</div>
<div class="mt-4 font-mono text-xs text-gray-500">
```text
cfg-20260301T120000-developer (original)
└─ cfg-20260309T045206-agent (change)
└─ cfg-20260309T120000-developer (rollback)
```
</div>
</v-click>
</div>
</div>
<Footer />
<!--
Walk through a real scenario. The audience needs to see the flow, not just the components.
Drift detection is the killer feature: no guessing what changed in production.
-->
---
layout: default
---
# Integración en proyectos — onboarding al ecosistema
<div class="grid grid-cols-2 gap-8 mt-4">
<div>
**Lo que un proyecto necesita**
<div class="mt-2 font-mono text-xs text-gray-300">
```bash
proyecto/
.ontology/
core.ncl ← invariants del proyecto
state.ncl ← dimensiones de madurez
gate.ncl ← guards activos
adrs/
schema.ncl
reflection.ncl
adr-001-*.ncl ← ADR fundacional
reflection/
forms/ ← TypeDialog forms
modes/ ← operational modes
configs/ ← sealed profiles
modules/ ← Nu modules
bin/stratum.nu
stratum.sh
```
</div>
</div>
<div>
**Inicialización**
<v-click>
<div class="mt-2 text-xs space-y-2">
<div class="box-highlight border-l-4 border-green-500 pl-3 py-1">
<div class="font-semibold text-green-300">Comando de onboarding</div>
<div class="font-mono text-gray-400 text-xs mt-1"><code>/onboard-project</code> → genera <code>.ontology/ <br></code> + ADR fundacional</div>
</div>
<div class="box-highlight border-l-4 border-blue-500 pl-3 py-1">
<div class="font-semibold text-blue-300">Primer ADR obligatorio</div>
<div class="text-gray-400 text-xs">Define las invariantes — qué no puede cambiar sin ADR nuevo</div>
</div>
<div class="box-highlight border-l-4 border-orange-400 pl-3 py-1">
<div class="font-semibold text-orange-300">Pre-commit como sincronización</div>
<div class="text-gray-400 text-xs"><code>nickel typecheck</code> en cada commit<br> — la capa declarativa nunca queda rota</div>
</div>
</div>
</v-click>
<v-click>
<div class="mt-4 font-mono text-xs">
```bash
./stratum.sh check
# ✓ nushell 0.110.0
# ✓ nickel 1.9.0
# ✓ .ontology/core.ncl exportable
# ✓ adrs/adr-001 Accepted
# ✗ no sealed config profiles yet
```
</div>
</v-click>
</div>
</div>
<Footer />
<!--
Onboarding is a contract, not a tutorial.
The system tells the project what it needs via `stratum check`.
The foundational ADR is the project's semantic constitution.
-->
---
layout: default
---
# Integración con Claude Code & Uso concurrente
<div class="grid grid-cols-2 gap-8 mt-4">
<div>
**SessionStart: contexto automático**
<div class="mt-2 text-xs text-gray-300">
<code>stratum-session-start.sh</code> se ejecuta al inicio de cada sesión:
</div>
<div class="mt-2 font-mono text-xs">
```bash
=== STRATUM CONTEXT: typedialog ===
ADRS
adr-001 [Accepted] Nickel as First-Class Form...
adr-002 [Accepted] NCL element order from position
HARD CONSTRAINTS
adr-001-c1 nickel export must succeed before...
adr-002-c1 web/tui must render headers interleaved
STATE
backend-maturity: multi-stable → all-production
ACTIVE GATES
nickel-primacy-gate [Low] Protects: nickel-as-...
=== END STRATUM CONTEXT ===
```
</div>
</div>
<div>
**Uso concurrente: humano + agente IA**
<v-click>
<div class="mt-4 space-y-4 text-sm">
<div class="box-highlight border-l-4 border-blue-500 pl-3 py-1">
<div class="font-semibold text-blue-300">IDs timestamp con actor</div>
<div class="font-mono text-gray-400 text-xs">cfg-20260309T045206-developer<br>cfg-20260309T045207-agent</div>
<div class="text-gray-400 text-xs">Sin coordinador. Sin TOCTOU. Trazabilidad por actor.</div>
</div>
<div class="box-highlight border-l-4 border-orange-400 pl-3 py-1">
<div class="font-semibold text-orange-300">Advisory locks (mkdir)</div>
<div class="text-gray-400 text-xs">Serializa escrituras en manifest/changelog/backlog. Stale detection por PID.</div>
</div>
<div class="box-highlight border-l-4 border-gray-600 pl-3 py-1">
<div class="font-semibold text-gray-300">Actor-agnostic protocol</div>
<div class="text-gray-400 text-xs">El sistema no distingue humano de agente. El protocolo enforcea igual para ambos.</div>
</div>
</div>
</v-click>
<v-click>
<div class="mt-8 text-sm text-gray-500">
Worktrees aíslan el working-tree (branches diferentes).<br>
Locking serializa escrituras sobre el mismo árbol.<br>
Son complementarios, no alternativos.
</div>
</v-click>
</div>
</div>
<Footer />
<!--
AI agents are first-class actors in this system. The protocol does not distinguish — it enforces.
The session hook means Claude starts informed, not blind.
Concurrent use without a central coordinator is the scaling property that makes this practical.
-->
---
layout: cover
name: end
class: 'justify-center flex flex-cols'
---
<div class="standalone-slide text-shadow-lg text-xl">
# Ontology & Reflection
<div class="meters-final -mt-3 mb-7">
<span class="text-green-400">✓ Typed</span>
<span class="text-green-400">✓ Verified</span>
<span class="text-green-400">✓ Sealed</span>
<span class="text-green-400">✓ Decided</span>
</div>
<div class="text-2xl leading-11 text-gray-200">
El código y el entendimiento del código deben converger.<br>
Los <em>ADRs</em> y la <em>ontología</em> son el contrato entre ambos.<br>
La <em>reflection</em> es la operación sobre ese contrato.
</div>
<div class="text-4xl leading-12 text-gray-200 my-5">
Gracias. ¿Preguntas?
</div>
<small>jesusperez.pro · ontoref.dev </small>
</div>
<style>
.meters-final {
display: inline-flex;
gap: 2rem;
font-size: 1.4rem;
font-family: monospace;
}
</style>
<Footer />
<!--
Direct eye contact. Slow delivery.
The three green checks are the promise: typed, verified, sealed. If those three hold, the system holds.
-->