El regalo de despedida: lo que entregamos el último día del proyecto
Lo más útil que dejamos no fue documentación — fue un repositorio de arranque que le permitió al equipo usar Claude Code de forma segura desde el primer día después de que nos fuimos.

Punto Clave
El último día de un proyecto de cinco meses, entregamos un repositorio git con una plantilla CLAUDE.md, ejemplos de hooks y un doc de mejores prácticas. No porque la documentación ayude. Porque un starter kit le permite a un equipo nuevo usar la IA de forma segura desde el día uno, sin reconstruir las barreras desde cero.
El último día de un proyecto de cinco meses, entregué un repositorio que no tenía nada que ver con la migración para la que nos habían contratado.
Sin nuevos modelos dbt. Sin correcciones a dashboards. Sin parches de calidad de datos. Solo un repositorio git con un README, una plantilla CLAUDE.md y algunos ejemplos de hooks. Tomó unas cuatro horas armarlo. Fue lo más útil que dejé atrás.
La idea que lo provocó: el equipo de datos de la empresa de seguridad en la nube había visto cómo usábamos Claude Code durante todo el proyecto — había visto las barreras funcionando, lo que el setup estructurado hacía posible, la diferencia entre sesiones que arrancaban con buen contexto y las que no. Iban a intentar adoptarlo después de que nos fuéramos. Y sin el framework, pasarían las primeras tres semanas cometiendo los mismos errores que nosotros ya habíamos superado.
No puedes resolver ese problema solo con documentación. Un documento de entrega explica qué son las barreras. Un repositorio de arranque hace posible usarlas de verdad.
Eso fue lo que construimos. Y pasó por tres versiones antes de estar listo para entregar.
Cuando un equipo de analytics recibe un codebase de manos de un consultor, el entregable estándar es un documento de handoff. Resumen del repositorio. Notas de arquitectura. Cómo correr los modelos. Cómo actualizar los seeds. Una sección de "cosas a las que hay que prestar atención."
Estos documentos los escriben personas que conocen el sistema profundamente, para personas que todavía no lo conocen, en un formato que no se puede consultar. Se desactualizan de inmediato. Para cuando el nuevo equipo se topa con un problema real — un conflicto de prioridad en descuentos, un JOIN que genera duplicados silenciosos, un nivel de precios que cambió sin documentación — el documento responde la pregunta que tenían hace tres semanas, no la que tienen ahora.
Los flujos con IA lo empeoran antes de mejorarlo.
Cuando el equipo empieza a usar Claude Code sobre un codebase que no construyó, la IA reconstruye la lógica de negocio a partir de nombres de modelos, comentarios en columnas y patrones generales de dbt. A veces lo hace bien. A veces genera SQL que suena razonable pero viola una regla de negocio que nadie escribió — una restricción que era obvia para todos los que construyeron el sistema e invisible para los que llegaron después. El error aparece en una revisión de Finanzas dos sprints más tarde, y para entonces el rastro hasta la causa raíz ya está frío.
El problema del handoff en flujos con IA no es la documentación. Es que la IA necesita entradas distintas a las de un humano. Un humano lee el README y hace preguntas. La IA lee lo que hay en el repositorio y genera a partir de eso. Si las barreras no están en el repo — si CLAUDE.md no existe, si los hooks no están configurados — la IA opera con valores predeterminados, y los valores predeterminados no conocen tu calendario fiscal ni tus reglas de precios ni qué macros encapsulan lógica de negocio de varios años que no debe tocarse.
Un starter kit resuelve un problema distinto al del documento de handoff. El documento explica el sistema. El kit hace posible usar el sistema de forma segura con asistencia de IA, desde el primer día.
Las tres versiones
v1: El setup específico del proyecto
La primera versión la construimos para nosotros, no para ellos.
En la segunda semana del proyecto, CLAUDE.md se había convertido en el archivo más importante del repositorio. No porque lo hubiéramos planeado así — lo fuimos completando después de las sesiones que salieron mal, después de aprender qué necesitaba que le dijéramos a Claude versus qué descubriría por su cuenta. El archivo fue creciendo. Las reglas se agregaron conforme íbamos encontrando los huecos. El contexto de dominio se fue llenando conforme entendíamos la lógica de negocio lo suficiente como para escribirla.
Para el final del proyecto, la v1 era densa. Codificaba todo lo específico de ese proyecto:
## Role & Mission
You are a Staff Analytics Engineer working on:
- Migrating legacy BI dashboards to dbt + Snowflake + Sigma
- Starting with ~20 revenue views
- Keeping 100% logical parity first (lift-and-shift) before any refactor
## ABSOLUTE RULES
1. NEVER modify anything under the legacy dashboard directory. Read/Grep/Glob only.
2. NEVER run destructive Snowflake commands (DROP, TRUNCATE, ALTER TABLE ... DROP)
3. NEVER run dbt run without --select. Prefer narrow: dbt run --select fct_revenue_* --target dev
4. NEVER change pricing or billing macros without detailed comments + human approval.
5. For monetary amounts: NEVER use FLOAT. Always NUMBER(38,9).
## Domain Context
pricing_tier maps to contractual commitments, not usage bands.
fiscal_quarter uses a 4-4-5 retail calendar. Do not assume ISO quarters.
client_id in billing tables ≠ account_id in CRM. Joining on the wrong key = silent duplicates.
Regional multipliers apply to one product line only. The other uses a global flat rate.
Quarterly model output lags by one month by design — this is correct, not a bug.
La v1 también tenía el setup completo de hooks: pre-commit bloqueando DROP y TRUNCATE en archivos de modelos, y un hook PreToolUse que impedía que Claude editara el directorio de macros protegidas sin confirmación explícita. Esa protección no era negociable — esas macros encapsulaban lógica de precios y negocio que databa de años antes del equipo actual.
Esta versión era útil. También era completamente intransferible. La definición de rol hacía referencia al contexto específico de la migración. El contexto de dominio usaba llaves y nombres de productos propios del cliente. Los paths protegidos estaban hardcodeados a la estructura de ese repositorio. No podías entregarle esto a un equipo nuevo y decirles que lo adaptaran. Tendrías que reconstruirlo desde cero, que es exactamente el problema que queríamos resolver.
v2: El playbook generalizado
La segunda versión vive en la organización interna de Clarivant. Es la que llevamos a nuevos proyectos.
El objetivo era quitar todo lo específico del proyecto mientras se conservaban los patrones estructurales. Eso resultó ser un ejercicio útil: nos forzó a articular cuáles partes de la v1 eran lógica del proyecto y cuáles eran el framework debajo de esa lógica.
La respuesta fue más limpia de lo esperado. Tres categorías de contenido pertenecen a cualquier CLAUDE.md de analytics engineering, sin importar el proyecto específico:
## Architecture Rules
[Fill in your layer structure: staging → intermediate → marts or equivalent]
[Fill in your naming conventions]
[Fill in your materialization defaults]
Never run dbt run without --select. Full-refresh on prod is a warehouse billing event.
## Hard Boundaries
Never use FLOAT or DOUBLE for financial columns. Always NUMBER(38,9) or equivalent.
Never edit [your protected macro directory] without detailed comments + human approval.
For any model touching revenue, billing, or pricing: pause and request human confirmation.
[Add your environment-specific constraints here — Snowflake native, BigQuery, etc.]
## Domain Context
[This section is intentionally blank — fill in the specifics of your project]
[What does your pricing structure look like?]
[What are the non-obvious key relationships that cause silent duplicates on JOIN?]
[What fiscal calendar do you use?]
[What are the legacy models that must remain read-only?]
La sección de hooks se convirtió en una plantilla con ejemplos comentados:
# Customize the path list for your project
PROTECTED_PATHS = [
"macros/fiscal/", # date conversion definitions
"macros/pricing/", # pricing engine macros
"seeds/pricing_tiers.csv", # contractual tier structure
]
def hook(tool, tool_input):
if tool == "edit":
path = tool_input.get("path", "")
for protected in PROTECTED_PATHS:
if protected in path:
raise Exception(f"Protected path: {protected} requires manual review")
La v2 es la que usamos. La sección de contexto de dominio es el espacio en blanco que se llena en el primer día de cada proyecto. Todo lo demás — las plantillas de arquitectura, las reglas de precisión financiera, los patrones de hooks — se transfiere intacto.
v3: El regalo de despedida
La tercera versión fue la que requirió más reflexión sobre la audiencia.
La v1 era para nosotros. La v2 sigue siendo para nosotros — es nuestro playbook interno. La v3 era para un equipo que no había construido nada de esto, que no había pasado cinco meses aprendiendo por qué existía cada regla, y que usaría Claude Code de forma independiente después de que nos fuéramos.
Ese es un restricción de diseño fundamentalmente diferente. Un equipo que no construyó el sistema necesita tres cosas: una barrera de entrada baja, suficiente explicación para que las reglas tengan sentido sin conocer el contexto histórico, y que quede claro qué hay que llenar versus qué dejar como está.
El README se convirtió en el artefacto principal:
# Claude Code Starter — Getting Started
## What's in this repo
- CLAUDE.md — AI session instructions for your dbt project
- hooks/pre_commit.sh — blocks destructive SQL before it lands in the repo
- hooks/pre_tool_use.py — intercepts Claude before it edits protected paths
- best-practices.md — lessons from production use: when to use what, and why
## Setup (5 steps)
1. Copy CLAUDE.md to the root of your dbt project
2. Fill in the [YOUR PROJECT] sections (see comments inline)
3. Copy hooks/ to your project's .claude/ directory
4. Update PROTECTED_PATHS in pre_tool_use.py to match your macro structure
5. Start a Claude Code session — it reads CLAUDE.md automatically
## The one rule you must not skip
Fill in the Domain Context section before your first session.
This is the section Claude cannot infer from your schema.
It takes 30 minutes and prevents the class of mistakes that take days to debug.
La plantilla CLAUDE.md de la v3 tenía comentarios en línea más claros — no solo qué poner en cada sección, sino por qué existe esa sección y qué sale mal si queda vacía:
## Domain Context
# -------------------------------------------------------------------------
# This section is the most important one in the file.
# Claude can infer your dbt layer structure from your model names.
# It cannot infer your fiscal calendar, your non-obvious key relationships,
# or which product lines use different pricing rules.
#
# Things to document here:
# - Fiscal calendar: does your quarter match ISO? When does FY start?
# - Key relationships: any IDs that look the same but mean different things
# - Pricing rules: which product lines use which rate structures
# - Legacy constraints: read-only files, tables to never touch, things that
# "look wrong but are actually correct" in your data model
#
# Leaving this blank is valid for a new greenfield project.
# For a migration or an existing system, this is where you earn your money.
# -------------------------------------------------------------------------
[Fill in your domain context here]
El documento de mejores prácticas fue la última adición — un resumen corto de lecciones aprendidas en producción que no encajaban en ningún otro lugar. No un tutorial. No una referencia. Más bien esas cosas que le dirías a alguien nuevo en su primer día si tuvieras veinte minutos.
Qué se conservó, qué se eliminó y qué se simplificó
La forma más clara de mostrar la destilación: así evolucionó la sección de contexto de dominio entre versiones.
v1 — contexto completo específico del proyecto (patrón verbatim, anonimizado):
## Domain Context
pricing_tier maps to contractual commitments, not usage bands.
fiscal_quarter uses a 4-4-5 retail calendar. Do not assume ISO quarters.
client_id in billing != account_id in CRM. Wrong join key = silent duplicate rows.
Regional multipliers apply to product line A only. Product line B uses a global flat rate.
Quarterly output lags one month by design — correct, not a bug.
The legacy dashboard repo is read-only. May grep/glob, never edit.
v2 — plantilla con indicaciones para completar:
## Domain Context
[What does your pricing tier structure map to? Usage bands? Contracts?]
[What fiscal calendar do you use? 4-4-5? ISO? When does your FY start?]
[Are there ID fields that look the same but join to different entities?]
[Do different product lines use different rate structures?]
[Is there any "looks wrong but is intentional" behavior the AI should know about?]
[What are the read-only legacy sources, if any?]
v3 — misma plantilla, con un ejemplo resuelto agregado:
## Domain Context
# Example (fill in your own):
# pricing_tier maps to [contractual commitments / usage bands / seat count]
# fiscal_quarter uses [4-4-5 / ISO / custom] — FY starts [month]
# [id_field_a] in [table_x] != [id_field_a] in [table_y] — join on [correct_key]
# [product_line_a] uses [rate structure]; [product_line_b] uses [different rate structure]
# [Known legacy behavior that looks wrong but is correct]: [description]
[Your domain context here]
El ejemplo resuelto hace mucho trabajo. Le dice al nuevo integrante del equipo no solo cuál es el formato, sino qué tipo de cosa corresponde en cada placeholder — que es la información que realmente cuesta descubrir por cuenta propia.
El setup de hooks siguió un arco similar: la v1 estaba hardcodeada a los paths del proyecto, la v2 se convirtió en una plantilla con comentarios que explicaban el mecanismo, y la v3 agregó un walkthrough de cinco minutos para que alguien que nunca hubiera tocado hooks de Claude Code pudiera configurarlos sin tener que leer el código fuente.
Lo que aprendimos en la destilación
Algunas cosas que me sorprendieron del proceso.
Lo más difícil de la v3 no fue el código. Fue la explicación.
La v1 y la v2 fueron escritas para personas que entendían por qué existía cada regla. Habíamos vivido las sesiones donde la regla no estaba y pagamos el costo. La audiencia de la v3 no había pasado por eso. Escribir los comentarios en línea de la v3 me obligó a articular el costo de saltarse cada sección — no solo "llena esto" sino "si te lo saltas, pasa esto." Eso es un tipo de documentación diferente. Es más difícil de escribir y significativamente más útil de leer.
La sección de contexto de dominio es la contribución humana irreducible.
Todo lo demás en el framework se transfiere: los patrones de hooks, las reglas de precisión financiera, las convenciones de arquitectura, el flujo de gestión de sesiones. El contexto de dominio no se puede generar a partir del codebase. Tiene que venir de las personas que construyeron la lógica de negocio — las que saben por qué el calendario fiscal tiene un mes de desfase, cuáles campos de ID se ven idénticos pero apuntan a entidades distintas, qué significan realmente las reglas de precios más allá de cómo están implementadas. Ninguna cantidad de introspección de esquema recupera eso. Hay que escribirlo.
Este es el insight que sostiene todo el framework: Claude Code es excelente para trabajar dentro de un contexto bien definido. No puede definir ese contexto por ti. Los 30 minutos que inviertes escribiendo la sección de contexto de dominio antes de un sprint valen más que una docena de mejoras de prompts durante ese sprint.
Tres versiones es el número correcto para este tipo de destilación.
La v1 es específica e inmediatamente útil. La v2 es el patrón extraído — útil para reusar pero abstracto. La v3 está optimizada para adopción: devuelve suficientes ejemplos concretos para que un equipo nuevo pueda arrancar sin necesitar entender toda la historia. Si te saltas la v3 y entregas la plantilla, estás entregando algo que parece completo pero requiere demasiada inferencia para usarse bien.
Esto corresponde a un patrón general: siempre hay una brecha entre "técnicamente reusable" y "realmente adoptable." La v2 es técnicamente reusable. La v3 es adoptable. La diferencia son los ejemplos resueltos y la lógica explicada. Cuesta cuatro horas. Determina si el framework se usa o no.
Las barreras son más valiosas justo cuando el consultor se va.
Parece obvio en retrospectiva. Pero el timing importa más de lo que esperaba. El momento en que termina el proyecto es exactamente cuando el equipo está solo con un sistema que no construyó, recurriendo a la IA para responder preguntas que antes le hacían al consultor. Si las barreras no están desde el primer día de esa transición, las primeras sesiones independientes de Claude Code corren con valores predeterminados — y los valores predeterminados no conocen el calendario fiscal, ni las macros protegidas, ni las restricciones de dominio que pasamos cinco meses documentando.
El starter kit de la v3 fue diseñado para cerrar exactamente esa ventana. Clonas el repositorio, corres el setup de cinco pasos, arrancas la primera sesión con el contexto de dominio ya cargado. Sin brecha.
El handoff más costoso no es el que tiene documentación incorrecta. Es el que tiene documentación técnicamente correcta pero que el nuevo equipo no sabe interpretar.
El starter de la v3 funcionó porque fue diseñado para ser entendido por alguien que no lo construyó. Eso requirió un tipo de escritura diferente: no "así fue lo que hicimos" sino "si te saltas este paso, te vas a encontrar con esto." Menos impresionante de escribir. Más útil de recibir.
El equipo adoptó Claude Code de forma independiente después del proyecto. No porque el framework fuera sofisticado. Porque era lo suficientemente simple como para usarse de verdad.
Escribimos sobre el sistema de barreras con detalle — estructura de CLAUDE.md, implementación de hooks y el enfoque de gestión de contexto — en Analytics Engineering con IA: cómo Claude Code transformó nuestro flujo con dbt. El proyecto que produjo estas barreras está documentado en el caso de estudio de la empresa de seguridad en la nube.
Si vas a incorporar herramientas de IA en tu equipo de datos y quieres controles que sobrevivan después de la implementación, podemos armar el kit inicial para tu stack. Platiquemos.
Temas
Arturo Cárdenas
Fundador y Chief Data Analytics & AI Officer
Arturo es un consultor senior en analítica e IA que ayuda a empresas medianas y grandes a eliminar el caos de datos para desbloquear claridad, velocidad y ROI medible.


