Cada corte development → main se vuelve un release: versionado solo, asociado al proyecto del cliente, con los tasks y bugs que despliega, escrito en la voz de crescō. Dos agentes capturan y publican; una base es la fuente. La marca nunca postea en automático.
El cronista captura los hechos sin tono y los deja en la base. El editor los escribe en voz y espera tu visto bueno. Ningún agente le habla al otro: escriben y leen filas, lo que los hace reanudables, idempotentes y reversibles.
Se mergea el PR de release. El cronista lee el rango desde el último tag.
triggerDel repo: el cliente. De las magic words closes CSC-…: tasks, bugs y proyecto.
repo→customerGitmoji de cada PR → semver por proyecto. Taggea main.
v1.3 → v1.4Una fila por proyecto, en voz, lista para tu visto bueno.
status: readyUna fila por versión, relacionada a Customer · Project · Tasks · Bugs · Channels. Esta base es el changelog y es la cola de publicación. Tres vistas: cola · changelog · por cliente.
El buffer entre los dos relojesAl confirmar tú un changelog, el webhook lo despierta para ese release.
webhook · NotionArma la pieza leyendo la config de Channels. La deja en Draft.
lee config de ChannelsRevisas la cola de borradores y publicas a tu ritmo.
máx 3/sem · canalSale de tu cuenta personal. Nunca por PR, nunca en automático.
LinkedIn / XGitHub dispara al cronista al mergear dev→main; Notion dispara al editor cuando confirmas un changelog. La base es el buffer entre ambos — y de paso, el changelog mismo. v1 arranca solo con el cronista + tu confirmación.
El evento que dispara no es cada PR a main — es el PR development → main. Lo que el release incluye son las PRs que viajan en ese corte, resueltas por diff entre tags. Dos cosas distintas, dos campos distintos.
Monorepo: un corte dev→main puede tocar varios proyectos de un cliente → N releases de un PR. Versión y tag son por proyecto; el Release PR es compartido. Referencias: el «release PR» es justo el patrón de Release Please; el versionado por commits, el de semantic-release; la intención por pieza, la de Changesets — acá inferida del gitmoji que crescō ya usa.
Releases (modelo B: una fila por versión) es el corazón. Channels es la config de cada canal. Piezas es la unión Release×Channel — solo necesaria en v2, cuando cada canal lleva su propio body y estado.
| Release | Bump | Status | Canales | Cliente | Tasks | Bugs | Release PR | Incluidos | Tag | Firma |
|---|---|---|---|---|---|---|---|---|---|---|
| amedi · v1.4.0 | minor | ready | Changelog | Amedi | CSC-512CSC-514 | CSC-509 | dev→main #352 | #341#347#349 | amedi-v1.4.0 | Eugenia |
| mogos · v2.1.0 | minor | published | Changelog | Mogos | CSC-488 | CSC-490CSC-491 | dev→main #210 | #201#205 | mogos-v2.1.0 | Carlos |
| kenco · v0.3.1 | patch | draft | Changelog | Kenco | CSC-530 | CSC-530 | dev→main #61 | #58 | kenco-v0.3.1 | Carlos |
El versionado es por proyecto: el cronista lee el último tag de ese proyecto y sube desde ahí, según el gitmoji de las PRs incluidas.
| Segmento | Cuándo sube | Gatillo en crescō | Ejemplo |
|---|---|---|---|
| MAJOR | Cambio que rompe compatibilidad hacia atrás | 💥 break · footer BREAKING CHANGE | 1.4.0 → 2.0.0 |
| MINOR | Funcionalidad nueva, compatible | ✨ feat · 🎨 design | 1.3.2 → 1.4.0 |
| PATCH | Bug fix compatible, sin tocar la interfaz | 🐛 fix | 1.4.0 → 1.4.1 |
| -pre.N opcional | Corte previo, inestable, menor precedencia | deploy a staging / preview | 2.0.0-rc.1 |
| +build opcional | Metadata de build, no afecta precedencia | commit / build del corte | 1.4.0+a1b2c3 |
Cada canal es una fila con su config. El guardrail vive como dato: el editor lee «máx 3/sem» y «auto vs borrador» de la base, no de su prompt. Añadir un canal nuevo es una fila, no un cambio de esquema.
| Channel | Surface | Modo | Máx/sem | Formato | Target | Activo |
|---|---|---|---|---|---|---|
| Changelog | Web | auto | ∞ | Entrada versionada · porqué + bullets | /{cliente} | ● activo |
| Social | draft | 3 | Post 800–1400 · cuenta personal | in/{writer} | ○ v2 | |
| X | Social | draft | 3 | Hilo 5–9 · tensión → link | @{writer} | ○ v2 |
| Messaging | draft | 1 | 1 párrafo + link · lista opt-in | broadcast | ○ v2 | |
| Newsletter | draft | 2 | Cuerpo completo · sin truncar | inbox | ○ v2 |
Cambiar la cadencia de un canal, su modo o su voz es editar una fila, no tocar el agente. Eso mantiene a los dos agentes tontos y a la política en un solo lugar.
El cliente lee el changelog para saber qué cambió; el mercado lee LinkedIn para saber cómo pensamos. Ambos nacen de la misma fila madre, cada uno en su voz. El changelog se autopublica; lo social siempre es borrador.
Las familias piden una pantalla de «cómo va» — no para compararse con otros, sino para confirmarse que lo están haciendo bien. Percentiles y rankings empujan lo contrario. Probamos cinco versiones antes de publicar.
Probamos cinco versiones de una pantalla antes de publicar una. Las primeras tres tenían gráficos. Todas se sentían mal.
Las familias en Amedi piden una pantalla de «cómo va». No para compararse con otros niños — para confirmarse a sí mismas que lo están haciendo bien.
La versión que salió no tiene ni un gráfico de competencia. Hitos del niño, en su ritmo.
Lo escribí completo → changelog.cresco.so/amedi
Nada de crons ni polling. El cronista reacciona a un webhook de GitHub (merge dev→main); el editor reacciona a un webhook de Notion (cuando confirmas un changelog). Las dos compuertas humanas son tuyas: confirmar el changelog y aprobar lo social. v1 es solo el cronista + tu confirmación; el editor entra en v2.
Se corta el release.
Versión, tasks, bugs y changelog en voz. Aún sin publicar.
La entrada aparece pública.
El editor redacta por canal. Solo borrador — no postea.
Tú publicas en LinkedIn/X a tu ritmo.
Respuesta directa: el editor arranca con un webhook de Notion cuando una fila pasa a Published — o sea, justo cuando confirmaste el changelog. Solo redacta el borrador, nunca postea: tú curas la cola y publicas a tu ritmo (el guardrail máx 3/sem + tu aprobación). El batcheo vive en tu compuerta, no en el disparador. El cronista, en cambio, reacciona al webhook de GitHub al mergear, y nunca te espera.
Qué hace: resuelve cliente/proyecto/tasks/bugs, sube el semver, taggea y escribe la fila Ready con el changelog en voz.
Salida: fila Ready; el changelog sale cuando tú la confirmas. Nunca: social.
Qué hace: al confirmar tú un changelog, redacta la pieza por canal leyendo la config de Channels y la deja en Draft.
Respeta: solo borrador, nunca postea. Tú curas y publicas — máx por canal/semana, desde la base.
El orden importa: crear el modelo, probar la lógica del cronista en una corrida manual sobre PRs reales, y recién ahí programar. La voz y lo social vienen cuando el v1 esté probado.
Channels (sembrada: solo changelog activo, modo auto) y Releases con la relación a Channels y los campos Release PR / Included PRs / Tag.
Sobre los últimos cortes dev→main de Amedi: validar versionado, tag-diff, resolución de tasks/bugs y la copy en voz antes de automatizar nada.
GitHub Action on: push → main que corre el skill. Resolver primero la autenticación a Notion (token de integración propio, no el MCP de claude.ai que puede faltar en headless).
Vista pública de Notion filtrada Status=published · Customer=X. Después, opcional, servida desde cresco-design con permalinks + RSS.
Activar canales sociales en Channels, crear la unión Piezas, el segundo skill que redacta por canal, y la automatización de Notion (Status=Published → webhook) que lo dispara.
Ambos skills se scaffoldean con skill-factory (ficha de 8 campos, voz de marca, registro de Notion verificado) y se shipean por PR a main → dispara el auto-update del plugin del equipo y el sync de la base «Skills» en Notion. El skill es la capacidad; la routine es la cadencia.
Ninguna bloquea el v1. Son las palancas para subir de «muy bueno» a «lo mejor que hay».
Inferir major del gitmoji 💥 es frágil.
A veces un fix urgente va → main sin pasar por development.
La vista pública de Notion es MVP, sin permalinks ni RSS.
El gitmoji no siempre captura la intención real del corte.