1391 lines
33 KiB
Markdown
1391 lines
33 KiB
Markdown
---
|
|
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 · Nickel</div>
|
|
<div class="text-gray-400 text-sm mt-1"><code>.ontology/</code> · <code>adrs/</code> · <code>reflection/schemas/</code> · <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 · Nushell</div>
|
|
<div class="text-gray-400 text-sm mt-1"><code>adr</code> · <code>register</code> · <code>config</code> · <code>backlog</code> · <code>forms</code> · <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 · Bash → Nu</div>
|
|
<div class="text-gray-400 text-sm mt-1"><code>stratum.sh</code> · actor detection · locking · <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 · Ontología + ADRs</div>
|
|
<div class="text-gray-400 text-sm mt-1">nodes · invariants · gates · dimensions · 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 · Config + Historia</div>
|
|
<div class="text-gray-400 text-sm mt-1">profiles · sha256 seals · audit trail · 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.
|
|
-->
|