Ir al contenido

La habilidad /codebase-design

Fuente: The /codebase-design Skill — traducción comunitaria no oficial al español.

codebase-design corrige las palabras que usas para diseñar un módulo: módulo, interfaz, profundidad, costura, adaptador, apalancamiento, localidad. Define cada una con precisión, prohíbe los sustitutos laxos («componente», «servicio», «API», «frontera»), y enuncia el puñado de principios que se derivan de ellas.

Es una referencia, no un proceso. No hay bucle que ejecutar, ningún artefacto que produzca, ningún punto de control donde te haga una pregunta. Cada otra habilidad que toca diseño toma prestado su vocabulario; por sí sola te da el lenguaje y se detiene. Eso es lo que hay que saber antes de invocarla, porque una habilidad sin proceso ni regla de parada improvisará una si apuntas una sesión hacia ella y dices «dale». Ver las preguntas más abajo para saber cómo se ve eso en la práctica.

Escribe /codebase-design, o el agente la usará automáticamente cuando una tarea de diseño encaje.

Úsala cuando ya sabes qué código estás rediseñando y necesitas pensar en su forma: dónde va la costura, qué tan pequeña puede ser la interfaz, si una extracción compensa. También es a lo que recurres para zanjar una discusión sobre qué significa una palabra.

Varias habilidades están cerca de ella. Cuál quieres depende de cuál sea el problema real:

El problema La habilidad
La forma de un módulo: su interfaz, su costura, su profundidad codebase-design
Las palabras del dominio: «cuenta» significa tres cosas, dos personas entienden distinto «cancelación» domain-modeling
Aún no sabes qué módulo rediseñar improve-codebase-architecture (el estudio que encuentra candidatos)
Quieres que el diseño se discuta, no solo se nombre interrogatorio
Hay un comportamiento concreto que construir y quieres tests que sobrevivan a un refactor tdd

El glosario es la habilidad. Cada término se define contra los demás, y cada uno viene con la palabra que reemplaza.

Término Qué significa No digas
Módulo Todo lo que tiene una interfaz y una implementación. Deliberadamente agnóstico a la escala: una función, una clase, un paquete, un corte que cruza capas. unidad, componente, servicio
Interfaz Todo lo que quien llama debe saber para usarlo bien: la firma de tipos, más invariantes, restricciones de orden, modos de error, configuración requerida, características de rendimiento. API, firma
Profundidad Apalancamiento en la interfaz: cuánto comportamiento puede ejercer quien llama o un test por unidad de interfaz que debe aprender. Profundo: mucho comportamiento tras una interfaz pequeña. Superficial: la interfaz es casi tan compleja como la implementación. ninguno
Costura El término de Michael Feathers: un lugar donde puedes alterar el comportamiento sin editar en ese lugar. Es la ubicación de una interfaz, y dónde ponerla es su propia decisión, separada de qué va detrás. frontera
Adaptador Algo concreto que satisface una interfaz en una costura. Nombra un rol, no una sustancia: un fake en memoria y un repo de Postgres son ambos adaptadores. ninguno
Apalancamiento Lo que quienes llaman obtienen de la profundidad: más capacidad por unidad de interfaz aprendida. ninguno
Localidad Lo que quienes mantienen obtienen de la profundidad: cambio, errores y verificación se concentran en un lugar. Corrige una vez, corregido en todas partes. ninguno

La profundidad deliberadamente no se define como la razón entre líneas de implementación y líneas de interfaz, que es la propia definición de Ousterhout. Esa métrica premia rellenar la implementación. Se usa en cambio profundidad como apalancamiento.

  • La profundidad es una propiedad de la interfaz, no de la implementación. Un módulo profundo puede construirse internamente con piezas pequeñas e intercambiables. Simplemente no afloran a quienes llaman. Un módulo puede tener costuras internas que sus propios tests usan, y una costura externa en su interfaz.
  • La prueba de eliminación. Imagina eliminar el módulo. Si la complejidad desaparece, era un pass-through. Si reaparece en N llamadores, estaba ganándose su lugar.
  • La interfaz es la superficie de test. Llamadores y tests cruzan la misma costura. Si quieres probar más allá de la interfaz, el módulo tiene la forma equivocada.
  • Un adaptador significa una costura hipotética. Dos adaptadores significan una real. No cortes una costura hasta que algo varíe realmente a través de ella. Una costura de un solo adaptador es solo indirección.

Dos archivos de apoyo van más lejos, y la habilidad los lee bajo demanda en vez de por adelantado. DEEPENING.md clasifica las dependencias de un candidato en cuatro categorías (en proceso, sustituible local, remota pero propia, verdaderamente externa), porque la categoría decide cómo se prueba el módulo profundizado a través de su costura. DESIGN-IT-TWICE.md lanza subagentes paralelos para producir tres o más interfaces radicalmente distintas para el mismo módulo, y luego las compara en profundidad, localidad y colocación de costura.

¿Cómo construyo realmente un módulo profundo en TypeScript?

Esta es la pregunta más hecha sobre la habilidad y la habilidad no la responde. Define lo que un módulo profundo es; no dice nada sobre cómo impedir que un import perdido alcance más allá de la interfaz. El issue #458 lo dijo claro: «digamos que estamos contentos con la interfaz, oculta los detalles, etc. Pero ¿cómo lo imponemos? Creo que sin linting o rieles claros, humanos y LLMs por igual empezarán a ensuciarlo con el tiempo.» La respuesta de Matt, en ese hilo, fueron tres opciones: envolverlo en una clase o IIFE y aceptar que la clase se vuelve enorme; hacerlo un paquete en un monorepo y aceptar el tooling del monorepo; o usar un linter como dependency-cruiser para prohibir imports que eviten la interfaz. Por separado ha llamado a Effect el mejor mecanismo y a dependency-cruiser el segundo mejor. Hay una habilidad setup-ts-deep-modules en el bucket in-progress/ del repo que establece una convención src/packages/<name>/index.ts, pero es una habilidad de canal beta sin página de docs, y no trae regla de lint incluida.

Apunté una sesión hacia ella y quemó 100k tokens rediseñando cosas que nunca pedí.

Conocido, y presentado como issue #449. La habilidad es invocada por el modelo y se describe como vocabulario, pero nada en ella impide con firmeza que un agente la trate como un proceso ejecutable. Tras decirle «retoma en /codebase-design e impulsa las decisiones abiertas», un agente tomó el contenido con forma más accionable que encontró: los subagentes paralelos en DESIGN-IT-TWICE.md. Reexploró código que una sesión previa ya había mapeado, y corrió largo antes de preguntar nada. Ninguna de las guardas que una habilidad conductora tiene (puntos de control, una pregunta a la vez, sin avance automático) está presente aquí, porque una referencia no tiene ninguna. La solución es nombrar una habilidad conductora y dejar esta debajo: /grill-with-docs, /improve-codebase-architecture o /tdd con codebase-design como vocabulario. El issue está abierto.

¿A dónde fue design-an-interface? ¿Y existe una habilidad /interface-design?

design-an-interface se eliminó y se absorbió en esta habilidad. No se perdió nada: su técnica «deséñalo dos veces» (subagentes paralelos que generan diseños radicalmente distintos, de Ousterhout) viene aquí como DESIGN-IT-TWICE.md. Por separado, varias personas han pedido una habilidad dedicada /interface-design para la filosofía de módulo profundo/interfaz delgada; esa filosofía ya vive aquí, y no hay planes de una habilidad separada. Si venías buscando cualquiera de esos nombres, esta es la página.

¿No es esto una convención de estructura de archivos, como carpetas, barrel files, cortes por funcionalidad?

No, y la habilidad ha sostenido esa línea bajo presión repetida. El issue #95 propuso una estructura de árbol fractal formalizada como implementación concreta de módulos profundos; la respuesta fue que ambas son ortogonales: «los módulos profundos tratan del diseño de la interfaz y de acceder a través de una interfaz estricta, sin importar cómo se vea el sistema de archivos. Parece perfectamente posible tener módulos superficiales con este enfoque.» Lo mismo surgió en #458: «Creo que podrías estar atando el concepto de módulos demasiado al sistema de archivos. El sistema de archivos ciertamente puede ser una pista útil de la forma de los módulos, pero no hay necesidad de usar el sistema de archivos en la construcción de módulos profundos.» El glosario define módulo como agnóstico a la escala a propósito.

¿tdd usa realmente este vocabulario?

Ahora sí. Durante mucho tiempo no. Las notas inline de módulo profundo que vivían dentro de tdd se eliminaron en v1.0 a favor de esta habilidad compartida, pero el puntero que las reemplazaba nunca se añadió, así que tdd definía «costura» por sí mismo y no referenciaba nada. La brecha está cerrada: el puntero ya está en la habilidad, y se alcanza cuando la forma de la interfaz es la pregunta abierta y no los tests. tdd sigue siendo dueño de «costura» como el límite donde pruebas; esta habilidad es dueña de la forma del módulo detrás.

¿El patrón de diseñar dos veces funciona fuera de Claude Code?

No limpiamente. DESIGN-IT-TWICE.md dice «spawn 3+ sub-agents in parallel using the Agent tool», que es la herramienta de Claude Code con el nombre de Claude Code. El repo publica metadatos para otros harnesses, incluido Codex, y esos pueden no exponer nada bajo ese nombre, así que la fase de diseño paralelo es menos portable de lo que sugieren sus metadatos. Rastreado en el issue #564, abierto.

¿Puedo añadir mis propios conceptos al glosario, como connascence, secretos de módulo, divulgación progresiva?

La gente ha propuesto exactamente esos. El issue #180 añade los secretos de módulo de Parnas y la connascence de Page-Jones como capa de nombres para qué se fuga a través de una costura, con un diff funcional adjunto; el issue #303 propone divulgación progresiva dentro de la implementación, para que un módulo profundo en su interfaz pública no sea un bloque indiferenciado por debajo. Ambos están abiertos y sin fusionar. El glosario publicado es deliberadamente pequeño, y la razón por la que sigue pequeño está en la propia habilidad: lenguaje consistente es todo el punto, y un término que nadie usa de forma consistente es peor que ningún término.

  • La conversación de diseño deja de producir las palabras «componente», «servicio» y «frontera», y empieza a producir «módulo», «interfaz» y «costura».
  • Alguien puede apuntar a una extracción propuesta y decir si pasa la prueba de eliminación, sin titubear.
  • Una costura propuesta viene con un segundo adaptador nombrado, no solo el primero.
  • La discusión de una interfaz cubre invariantes, orden y modos de error, no solo la firma de tipos.
  • Invocarla no inicia una sesión. Si el agente empieza a leer archivos y a proponer refactors solo con /codebase-design, ha confundido la referencia con un conductor.

codebase-design es una habilidad independiente para usar en cualquier momento, y la capa de vocabulario bajo las habilidades de ingeniería más que un paso en cualquier cadena. Su vecina más cercana es domain-modeling, la referencia paralela para las palabras del dominio del problema más que para la forma del módulo. Ambas suelen quererse juntas, ya que nombrar bien un módulo profundo necesita las dos. improve-codebase-architecture es la otra: estudia una base de código buscando candidatos a profundizar y escribe cada uno de ellos en este glosario, así encuentra el módulo y esta habilidad es el banco donde lo diseñas. Cuando no sabes qué habilidad o flujo encaja, ask-matt te enruta.