feat: unified auth model, project onboarding, install pipeline, config management
The full scope across this batch: POST /sessions key→token exchange, SessionStore dual-index with revoke_by_id, CLI Bearer injection (ONTOREF_TOKEN), ontoref setup
--gen-keys, install scripts, daemon config form roundtrip, ADR-004/005, on+re self-description update (fully-self-described), and landing page refresh.
2026-03-13 20:56:31 +00:00
---
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 / >
<!--
2026-03-16 01:48:17 +00:00
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.
feat: unified auth model, project onboarding, install pipeline, config management
The full scope across this batch: POST /sessions key→token exchange, SessionStore dual-index with revoke_by_id, CLI Bearer injection (ONTOREF_TOKEN), ontoref setup
--gen-keys, install scripts, daemon config form roundtrip, ADR-004/005, on+re self-description update (fully-self-described), and landing page refresh.
2026-03-13 20:56:31 +00:00
-->
---
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.
-->