cis-modelo · modelo/reglas.py · 27 reglas · 7 ámbitos
Reglas del sistema
El grupo tiene 27 reglas declaradas en cis-modelo/modelo/reglas.py, identificadas H01 a H27. Cada una trae cuatro cosas: un id para citarla en un informe o un ticket, un enunciado que dice qué exige en una frase, una fuente que dice dónde está escrita (ninguna regla se inventa en el archivo) y un comprueba que dice cómo se mide, para que el chequeo sea repetible.
Esta página transcribe las 27 tal como están en el código, agrupadas por ámbito: estructura, dominios, seguridad, estilo, código, contratos y prosa. Tres de ellas todavía no tienen chequeo que las mida y se marcan como pendientes de instrumentar.
El principio: violación citable, no opinión
Hasta que existió este archivo, una inconsistencia del ecosistema se reportaba como opinión: «esto está mal». Con las reglas pasa a ser una afirmación verificable: «viola la regla H13, y la evidencia es esta medición». La diferencia importa porque una opinión se discute y una violación se cierra. Quien no esté de acuerdo con una violación no argumenta: repite la medición que la columna comprueba describe y refuta con datos, o confirma.
Por eso cada violación que emite el corredor sale con cuatro campos, calcados del dataclass Violacion de modelo/chequeos.py: la regla que se incumple, el objeto que la incumple, lo medido y la evidencia (el comando o cruce del que salió la medición). El ejemplo de abajo es una violación real de la corrida del 2026-08-20, montada con los badges del kit.
<div style="border:1px solid var(--line);background:var(--paper-raised);padding:16px 18px">
<span class="badge badge--err">H13 · alta</span>
<span style="font:12px var(--font-mono)">portal.innovacionsantiago.cl</span>
<div><b>Medido:</b> el registro declara v6 y el sitio carga v9.</div>
<div><b>Evidencia:</b> consumers.yaml contra el <link> del HTML servido.</div>
</div>Cómo leer las tablas
La severidad es de la violación, no de la regla: dice cuánto duele incumplirla. En estas tablas se pinta con los badges reales del kit (base/components.css): alta con badge--err, media con badge--warn y baja con el badge neutro.
Una regla sin chequeo que la mida es decorativa: se puede declarar y nadie sabría si se cumple. Las tres que están en ese estado (H03, H04 y H07, automatica=False en el código) se marcan abajo como pendientes de instrumentar y el informe las lista aparte, no como cumplidas. Publicar una regla que ningún chequeo verifica da una sensación de control que no existe.
<span class="badge badge--err">alta</span>
<span class="badge badge--warn">media</span>
<span class="badge">baja</span>
<span class="badge badge--warn">pendiente de instrumentar</span>Estructura · 6 reglas
Qué puede ser marca, producto, vista, auxiliar o infraestructura, y qué privilegios trae cada clase. Fuente principal: core/core-style/ESTRUCTURA.md, dictada el 2026-08-09.
| Id | Enunciado | Fuente | Cómo se comprueba | Severidad |
|---|---|---|---|---|
| H01 | Solo una marca tiene contabilidad propia y hoja de estilo propia. | ESTRUCTURA.md §2, regla 1 | Ninguna entidad de clase producto, vista o auxiliar declara hoja de estilo propia ni centro de resultado. | alta |
| H02 | Un producto hereda el estilo de su marca y nunca lleva hoja propia. Si necesita una, es que en realidad es una marca. | ESTRUCTURA.md §4 | Para cada producto, la hoja que carga su sitio es la de su marca. | alta |
| H03 | Un sitio auxiliar nunca es producto. Si le nacen KPI propios, se reclasifica en vez de estirarle la definición. | ESTRUCTURA.md §2, regla 2 | Ningún auxiliar aparece con métricas de negocio propias. pendiente de instrumentar | media |
| H04 | Una vista no sube a producto por crecer. Sube si le nace un público que no venía por el producto padre. | ESTRUCTURA.md §2, regla 3 | Ninguna vista declara dominio propio ni marca propia. pendiente de instrumentar | media |
| H05 | La infraestructura no lleva marca ni namebrand. | ESTRUCTURA.md §2, regla 4 | Ningún sitio de clase infraestructura carga una hoja de marca ni muestra wordmark. | baja |
| H06 | Todo host servido está clasificado en alguna de las ocho clases. | ESTRUCTURA.md §2 y §3 | Cada host de Caddy tiene clase asignada en el registro. | media |
Dominios · 3 reglas
Bajo qué dominio nace lo nuevo y cuándo se justifica un dominio raíz propio.
| Id | Enunciado | Fuente | Cómo se comprueba | Severidad |
|---|---|---|---|---|
| H07 | Todo servicio nuevo del grupo vive bajo innovacionsantiago.cl. Circulodesantiago.cl es legal y legacy: no se construye ahí. | CONSTITUTION.md §1.6 · ADR-005 | Ningún host creado después del 2026-05 cuelga de circulodesantiago.cl. pendiente de instrumentar | media |
| H08 | Un dominio propio se justifica solo para una marca con razón comercial. Registrado y sin montar es costo, no una opción abierta. | ESTRUCTURA.md §3 | Todo dominio raíz registrado sirve al menos un host con contenido. | baja |
| H09 | Un nombre que Caddy sirve y el DNS no resuelve se retira. | Medición propia · sesión del mapa de operación | Todo host del Caddyfile resuelve a una dirección. | media |
Seguridad · 2 reglas
Cómo entra el tráfico público y qué no se le muestra al anónimo ni a los buscadores.
| Id | Enunciado | Fuente | Cómo se comprueba | Severidad |
|---|---|---|---|---|
| H10 | Lo público entra por el proxy de Cloudflare. La excepción es lo que necesita la IP real del cliente, y se declara. | Medición propia · capítulo de la cadena de borde | Todo host público resuelve a una IP de borde de Cloudflare. | alta |
| H11 | Todo sitio técnico responde noindex y no se sirve al anónimo si publica algo interno. | CATALOGO.md §2 · incidente del 2026-05-29 | Cada host de clase servicio o infraestructura declara X-Robots-Tag. | media |
Estilo · 5 reglas
Las que le tocan directo a este hub: versión fijada del kit, tipografía de la casa, logos canónicos y la prohibición del borde de acento.
| Id | Enunciado | Fuente | Cómo se comprueba | Severidad |
|---|---|---|---|---|
| H12 | Un consumidor del design system fija la versión que carga y no usa una ruta genérica. | core/CONTRACTS.md · sla.yaml, obligaciones del consumidor | Cada sitio carga una hoja con versión explícita en la URL. | media |
| H13 | La versión que un sitio carga de verdad coincide con la que el registro de consumidores declara. | cis-style/registry/consumers.yaml | Para cada consumidor, version_pinned es igual a la versión medida en el HTML servido. | alta |
| H14 | Tipografía IBM Plex Sans y JetBrains Mono, servidas por el propio grupo. Nunca Inter, Roboto ni Google Fonts. | CANON.md · ADR-021 | Ningún sitio carga fonts.googleapis.com ni declara Inter como familia de marca. | media |
| H15 | Los logos salen de LOGOS-CANONICOS.md. No se inventan ni se regeneran. | CANON.md · cis-style/brands/LOGOS-CANONICOS.md | Ningún brands/*/mark.svg difiere del canónico de su marca. | media |
| H16 | Prohibido el borde de acento a la izquierda en tarjetas, avisos y notas. La jerarquía se hace con fondo, tipografía o etiqueta. | CANON.md, decisión de Martín del 2026-08-06 | Ninguna hoja del grupo declara border-left con color de acento. | baja |
Así se ve un consumidor que cumple H12 y H13 a la vez: las seis hojas del kit con versión y digest explícitos en la URL, iguales a lo que declara su fila en consumers.yaml. Esta misma página carga exactamente ese bloque.
<link rel=stylesheet href=".../v9/<digest>/fonts/css/ibm-plex-sans.css">
<link rel=stylesheet href=".../v9/<digest>/fonts/css/jetbrains-mono.css">
<link rel=stylesheet href=".../v9/<digest>/base/tokens.css">
<link rel=stylesheet href=".../v9/<digest>/base/chrome.css">
<link rel=stylesheet href=".../v9/<digest>/base/components.css">
<link rel=stylesheet href=".../v9/<digest>/brands/cis/tokens.css">Código · 5 reglas
Framework, librerías compartidas, auth, correo y desde dónde corre producción. H27 lleva número tardío porque se agregó después, pero su ámbito es código.
| Id | Enunciado | Fuente | Cómo se comprueba | Severidad |
|---|---|---|---|---|
| H17 | Next.js es la elección para lo nuevo, y está prohibido mezclar Vite y Next en un mismo repositorio. | CANON.md · ADR-037 | Ningún repositorio tiene next.config y vite.config a la vez. | alta |
| H18 | Las librerías compartidas siguen semver y un cambio mayor requiere un ADR. | core/CONTRACTS.md §1 | La versión instalada en cada consumidor coincide con la que declara el manifest de la librería. | media |
| H19 | La autenticación se integra a cis-auth por OIDC con core-auth-lib. No se reinventa login ni JWT por servicio. | CANON.md · CONSTITUTION.md | Ningún servicio implementa emisión de token propia. | alta |
| H20 | El correo sale por cis-mailer. Nunca smtplib ni nodemailer ad-hoc. | CANON.md · memoria reference_mail_sending | Ningún repositorio importa smtplib ni nodemailer para enviar. | media |
| H27 | Un servicio corre desde un release inmutable o desde el árbol, y se sabe cuál. Editar el repo de un servicio fijado a release no cambia nada en producción. | Medición propia · memoria feedback_servicios_corren_desde_rama_divergente | Para cada unidad, WorkingDirectory coincide con el cwd real del proceso. | alta |
Contratos · 5 reglas
Acoplamientos declarados antes de mergear, topología completa, runbooks y responsables con nombre.
| Id | Enunciado | Fuente | Cómo se comprueba | Severidad |
|---|---|---|---|---|
| H21 | Todo acoplamiento entre un proveedor y un consumidor se declara antes de mergear. | cis/CONTRACTS.md, encabezado | Cada comunicación observada entre dos servicios tiene fila en CONTRACTS.md o arista en topologia.yaml. | alta |
| H22 | Un contrato declarado apunta a algo que existe. | Medición propia · discrepancias de la sonda | Cada contrato declarado resuelve a un proceso que escucha. | alta |
| H23 | Todo servicio que corre está representado en la topología. | Medición propia · sesión del mapa de operación | Ninguna unidad del grupo queda fuera del conjunto de nodos. | media |
| H24 | Un servicio crítico tiene runbook. | cis/DR-PLAN.md · cis-docs/runbooks | Cada servicio marcado como crítico tiene archivo en runbooks/. | alta |
| H25 | Cada servicio tiene una persona que responde por él. | ESTRUCTURA.md §5 · protocolo operacional §2.4 | Cada servicio tiene responsable nombrado y distinto de «todos». | alta |
Prosa · 1 regla
La norma editorial de la casa aplica a todo documento en español del grupo, incluida esta página. El detalle está en la página Escritura del hub.
| Id | Enunciado | Fuente | Cómo se comprueba | Severidad |
|---|---|---|---|---|
| H26 | La prosa en español del grupo cumple la norma: sin em-dash, sin voseo, sin muletillas de IA, con tildes. | CANON.md · core/prosa/NORMA.md | prosa-lint sobre el documento da cero violaciones bloqueantes. | media |
Cómo correr los chequeos
El corredor vive en cis-modelo/modelo/chequeos.py y se ejecuta como módulo desde la raíz del repo. Hoy instrumenta H13, H17 y H27 contra los barridos de data/ (barrido-repos.json, estilo-medido.json); las demás automáticas describen su medición en la columna comprueba y van entrando al corredor a medida que se instrumentan. Emite JSON con las violaciones ordenadas por severidad, el total y el conteo por regla. La salida de abajo es de la corrida real del 2026-08-20: 13 violaciones, todas H13.
$ cd /srv/projects/cis/cis-modelo
$ python3 -m modelo.chequeos
{
"violaciones": [
{
"regla": "H13",
"objeto": "innovacionsantiago.cl",
"medido": "el registro declara v6 y el sitio carga ninguna",
"evidencia": "consumers.yaml contra el <link> del HTML servido",
"severidad": "alta"
},
... 12 más ...
],
"total": 13,
"por_regla": {"H13": 13}
}Para refutar una violación no se discute: se repite el comando que aparece en su campo evidencia. Si la medición da otra cosa, la violación cae; si da lo mismo, se cierra arreglando el objeto, no la regla.
Dónde se ven las violaciones vivas
El estado vigente se publica en cis/docs/ecosistema/STATUS-LIVE.md, sección Versionado · producción contra repositorio. Ahí queda el barrido de cis-modelo con fecha: repos barridos, sucios, con trabajo sin empujar, y el veredicto H27 (al 2026-08-20: 101 repos, H27 limpio, todo lo desplegado es ancestro de su repo). STATUS-LIVE.md es el documento generado y vivo; STATUS.md es un snapshot histórico y no sirve para citar estado actual.
Cuando una regla sale limpia, el barrido también lo dice con fecha y universo medido, para que «no hay violaciones» sea una medición y no una ausencia de datos. Así se ve el veredicto vigente de H27:
<span class="badge badge--ok">H27 limpio · 101 repos · 2026-08-20</span>REGLA DE ORO · Si vas a citar una violación en un ticket o un informe, cita el id (por ejemplo H13), el objeto y la evidencia. Un reporte sin esos tres campos vuelve a ser una opinión.