Qué entidades tiene el producto, qué puede hacer cada rol desde cada pantalla, qué cambia cada ruta: eso no lo saca ningún script de una fuente. Lo escribe una IA leyendo el código, el esquema y el contrato del API. Por eso cada mapa del negocio vive adentro de una skill de contexto, como un HTML que un humano abre en el navegador y que la IA lee por sección con bun run context:map. Este deck explica qué es un mapa, cómo se lee y cómo se mantiene honesto.
data, features o api leen las fuentes y escriben el mapa.
references/<map>.html, una sección por hecho.
bun run context:map saca el SVG y deja el texto, por sección.
Un briefing inyecta el comando; un humano usa --open y lo ve en el navegador.
Lo que contradice al mapa se propone con evidencia y se aplica con tu sí.
.context/ guarda lo que un SCRIPT trae de una fuente de verdad y lo que este repo mismo es fuente de verdad. Un mapa del negocio no es ninguna de las dos cosas: dos sesiones lo escribirían distinto y rehacerlo cuesta miles de tokens. Es conocimiento escrito, y el conocimiento que tiene que llegar sin que nadie lo pida es una skill.
| La pregunta, para cada pieza de conocimiento | Si la respuesta es sí, va a | Se recupera con |
|---|---|---|
| Un script la trae de una fuente externa? (Jira, el spec OpenAPI, el esquema) | .context/ como caché [SYNC], o tipos generados | bun run context:hydrate, bun run api:sync |
| Este repo es la fuente de verdad? (ADR, PRD, SRS, glosario, plan de diseño) | .context/ como [COMMIT] | git checkout |
| Si no: la IA la sintetiza del código, la base y los contratos | Una skill de contexto: el mapa generado adentro, el juicio en sus reglas | Regenerar cuesta caro: se corrige por sección |
La lista única de skills con mapa es CONTEXT_MAP_SKILLS en cli/lib/context-maps.ts: cada entrada nombra su mapa, su generador y el markdown viejo que reemplaza. La tabla de abajo es lo que trae el boilerplate; para saber qué hay en tu repo, lee esa constante.
| Skill | Qué sabe | Generador | Ante un conflicto gana |
|---|---|---|---|
| business-data-context | Entidades y relaciones, RLS, migraciones, máquinas de estado, procesos automáticos, integraciones | project-context modo data | La base viva de Supabase (capability db) |
| business-feature-context | Catálogo de features, matriz CRUD, inventario de UI, flujos entre features | project-context modo features | El árbol del frontend; la app corriendo, para el comportamiento |
| business-api-context | Modelo de auth, grupos de rutas, superficie OpenAPI, recorridos entre rutas | project-context modo api | El spec para la forma; los handlers y el API corriendo, para el comportamiento |
Un HTML autocontenido que abre desde file://, con secciones planas. El id de cada sección es el ancla de edición: se fija en el CREATE y no cambia nunca más.
<!-- línea 1 de un mapa generado --> <!-- generated by project-context mode data; edited in place by business-data-context refresh; do not hand-edit --> <!-- o, si todavía no se generó --> <!-- placeholder: run project-context mode data to generate this map --> <section id="orders-lifecycle" data-sources="src/app/api/orders/, db:orders, migration:<file>" data-updated="YYYY-MM-DD"> <h2>...</h2> <p> <ul> <table> <code> <!-- HTML semántico simple --> <figure data-diagram="state" data-for="orders-lifecycle"><svg>…</svg><figcaption>…</figcaption></figure> </section> ... <section id="discovery-gaps"> <!-- siempre la última -->
El lector, el updater y el doctor leen SOLO esa línea para saber si el mapa está generado o es un placeholder. El generador que nombra sale tal cual de la entrada de CONTEXT_MAP_SKILLS.
Una entidad, un flujo, una feature, un grupo de rutas. Nunca anidadas, cada una abre con su <h2>. data-sources lista las señales de las que salió (el chequeo de frescura las lee); data-updated, la fecha.
Todo lo que muestra un diagrama también está en el texto. Una figura de resumen arriba, y una por sección solo donde un dibujo explica el mecanismo.
Lo que no se pudo verificar. "No pude verificar X" le gana a una respuesta inventada. Una sección migrada de un mapa markdown viejo lleva data-migrated-from una vez, hasta que se regenera.
El SVG inline es casi todo el peso de un mapa y ninguno de sus hechos. El lector, scripts/context-map.ts, saca el SVG, el <style> y el <head>, e imprime cada sección como texto con su id, su fecha y sus fuentes.
| Necesitas | Comando |
|---|---|
| El mapa entero, como texto | bun run context:map <slug> |
| Una sección (una dispatch que toca una entidad o un grupo de rutas) | bun run context:map <slug> --section <id> |
| El índice, para un chequeo de frescura (id · fecha · fuentes) | bun run context:map <slug> --list |
| El mapa dibujado, para un humano | bun run context:map <slug> --open |
Generar es trabajo de project-context: sus modos, sus gates y el orden de refresh-all los explica su propio deck. Aquí va lo que le pasa al mapa. El id de sección es lo que vuelve mecánico el ahorro: una edición sobre un bloque <section>.
| Estado del mapa | Qué corre | Qué escribe |
|---|---|---|
| Ausente o placeholder | CREATE del modo: todas las secciones desde las fuentes. Si existe el markdown viejo que reemplaza (la lista legacy de su entrada), se lee como entrada y se cita en data-migrated-from | El archivo entero, una sola vez |
| Generado | UPDATE del modo: chequeo de frescura, regenera SOLO las secciones viejas, muestra un diff por sección y ESPERA tu aprobación | Las secciones aprobadas |
| Cambiaron los hechos de una sección con figura | Se redibuja esa figura | Un <figure> |
Lee cada fuente que pide el modo. Lo que no verificó va a discovery-gaps, no al cuerpo.
Después de escribir un mapa, revisa las ## Rules y los gotchas de esa skill contra el mapa nuevo y PROPONE cambios.
Qué modo corre: si no lo nombras, la IA pregunta.
Si el diff de un UPDATE se aplica.
references/<map>.html adentro de su skill, y nada más: el modo escribe solo ese archivo.
Los mapas markdown viejos de .context/business/ no se borran nunca.
El chequeo recorre --list y mira cada señal de data-sources contra su fecha. Las señales genéricas están en la doctrina; cada skill agrega las de su aspecto en su propio references/refresh.md.
| Señal | Vieja cuando |
|---|---|
| Una ruta del repo | git log --since=<data-updated> --oneline -- <path> devuelve algún commit |
| db:<table>, migration:<file> | Hay una migración posterior, o la base (capability db) muestra una columna, constraint, policy o trigger que la sección no describe |
| openapi:<x> | El contrato cambió desde la fecha (salida de bun run api:sync, o el git log del spec) |
| route:<path> | Cambió el handler o la página |
| Señales propias del aspecto | Las declara el refresh.md de cada skill: por ejemplo cron:<job> y webhook:<event> en datos, auth:<scheme> en API, un flag o un gate de rol en features |
Una skill de contexto no corre workflows. Lo único que hace es mantener honesto su mapa: cuando una sesión ve algo que contradice una sección (una columna que el mapa omite, un status que el mapa dice imposible, una acción CRUD que falta en la matriz), propone la edición.
# la propuesta, en un solo mensaje (references/refresh.md) business-data-context · proposed edit to section <id> (updated <date>) evidence: <what was observed, how, where: query / request / file@commit / session label> before: <the sentence or row as the map has it> after: <the replacement> figure: <unchanged | redraw: why> apply? (yes / no)
La skill lo declara en su frontmatter con metadata.writes: [references/], y un lint lo hace cumplir. Nada de Jira, nada de .context/, ninguna otra skill, ni migraciones ni código del producto.
Las figuras las dibuja la skill diagram-design, que instala cli/install.ts a nivel proyecto; una instalación de usuario o un plugin del harness también sirve. Es la única capability que se resuelve por la presencia de una skill y no por el sufijo de una herramienta.
# la línea que nombra el STOP (mcp-capabilities.md)
bunx skills add https://github.com/cathrynlavery/diagram-design --skill diagram-design --yes
Toda skill <aspect>-context es local del proyecto: el updater nunca la entrega, la pisa ni la borra (isProjectLocalSkillPath en cli/lib/updater-core.ts). Las de CONTEXT_MAP_SKILLS son la única excepción, y es solo de entrega.
bun sync entrega la carpeta de la skill cuando falta (collectContextMapBootstrap), con un mapa placeholder adentro.
A partir de ahí, nada del updater pisa ni borra lo que hay adentro: el mapa es la síntesis de TU producto, y sus reglas y gotchas también.
Un mapa que falta o sigue en placeholder (con el markdown viejo al lado, si lo hay) aparece como fila informativa en el reporte final de bun sync (en la página y en la terminal), y bun run setup:doctor imprime la misma línea, con el generador a correr.
billing, auth, stripe: la capa de juicio sobre un aspecto que una sesión competente leería mal. La crea project-context modo context-skill, siempre a través de skill-creator. Las fuentes guardan los hechos; la skill, las reglas para leerlos.
Lee completo lo que la skill va a cubrir y lista cada lugar donde se puede leer mal: borrado lógico, RLS que esconde filas a un rol, estados con nombres distintos en base, API y UI.
Pasa cada candidato por las tres preguntas de §01: solo el juicio queda como regla.
El aspecto y sobre qué se apoya.
En UPDATE, si el diff se aplica: las reglas se agregan con fecha, nunca se reescriben.
.agents/skills/<aspect>-context/ con metadata.kind: context, más references/gotchas.md.
Del proyecto, nunca enviada upstream.
Generar un mapa es un modo de project-context. Leerlo es un comando del repo, igual en los tres hosts. Cargar la skill pasa solo, por su descripción, o nombrándola.
Genera o actualiza el mapa de datos. Igual con features o api.
Sin barra: nombras la skill y el modo en la frase.
Mismo patrón que OpenCode, CLI o Desktop.
# leer, en cualquier host bun run context:map business-data-context --section <id> bun run context:map business-feature-context --list bun run context:map business-api-context --open # para ti, en el navegador # una skill de contexto propia /project-context context-skill billing # o: carga la skill project-context, modo context-skill
Los mapas no son de un solo workflow: los escribe uno y los consultan varios.
Sus modos data, features y api escriben los mapas; master-plan exige el mapa de datos generado. Sus gates y su orden viven en su SKILL.md.
Su fase de Discovery corre los modos de mapa y verifica el mapa de datos con bun run context:map antes del plan maestro.
Para evaluar el impacto de una historia que toca varios dominios. Si un mapa sigue en placeholder, sigue sin él y lo anota en el plan.
Su pase de dependencias usa el grafo de entidades, la matriz CRUD y el catálogo de rutas antes de crear o editar una historia.