@dforce2055/dai 0.10.0 → 0.12.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +168 -0
- package/README.md +12 -2
- package/VERSION +1 -1
- package/cli/dai.mjs +492 -36
- package/cli/lib/bootstrap.mjs +5 -2
- package/cli/lib/branch-scope.mjs +200 -0
- package/cli/lib/forge-api.mjs +57 -0
- package/cli/lib/pm-adapter.mjs +16 -2
- package/cli/lib/pm-clickup.mjs +16 -1
- package/cli/lib/pm-jira.mjs +21 -1
- package/cli/lib/pr.mjs +21 -1
- package/cli/lib/us-format.mjs +147 -0
- package/docs/EJEMPLO-END-TO-END.md +26 -3
- package/docs/METODOLOGIA.md +5 -0
- package/docs/PROBAR.md +12 -1
- package/docs/SCRUM-CON-IA.md +2 -2
- package/docs/adr/0018-alcance-de-stamp-y-gate-de-ci.md +183 -0
- package/docs/adr/README.md +1 -0
- package/docs/detalle/01-refinamiento.md +14 -0
- package/docs/detalle/07-merge-trazabilidad.md +13 -2
- package/docs/glosario.md +1 -1
- package/docs/guias/dev.md +21 -0
- package/docs/guias/po.md +40 -1
- package/docs/public/tutoriales/funcional-1-skills-usuario.png +0 -0
- package/docs/public/tutoriales/funcional-2-copilot-signin.png +0 -0
- package/docs/public/tutoriales/funcional-3-carpeta-configurada.png +0 -0
- package/docs/public/tutoriales/funcional-4-doctor.png +0 -0
- package/docs/public/tutoriales/funcional-5-publish-parent.png +0 -0
- package/docs/tutoriales/index.md +9 -0
- package/docs/tutoriales/setup-dev.md +516 -0
- package/docs/tutoriales/setup-funcional.md +480 -0
- package/governance/ci-rules.md +47 -8
- package/package.json +1 -1
- package/skills/dai-review/SKILL.md +1 -1
- package/skills/grill-epic/SKILL.md +2 -2
- package/skills/grill-intent/SKILL.md +1 -1
- package/skills/grill-user-story/SKILL.md +58 -10
- package/templates/ci-dai-gate.yml +50 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: grill-user-story
|
|
3
|
-
description: "Interroga a un PO o analista funcional para producir una User Story funcional y testeable siguiendo el formato del modelo de trazabilidad — o pule una US vaga existente. Se queda a nivel funcional/usuario y se niega a derivar en diseño técnico o a emitir una US con criterios no testeables. Al terminar
|
|
3
|
+
description: "Interroga a un PO o analista funcional para producir una User Story funcional y testeable siguiendo el formato del modelo de trazabilidad — o pule una US vaga existente. Se queda a nivel funcional/usuario y se niega a derivar en diseño técnico o a emitir una US con criterios no testeables. Al terminar la PUBLICA en el tracker configurado del repo (Jira o ClickUp, según DAI_PM de su .env.dai o .env): si la US es NUEVA la crea (MCP o `dai publish`); si YA tiene key la actualiza con `dai edit-us --no-editor`, que valida el formato y pregunta si sube el spec_version antes de pisar nada. Sin MCP ni token, deja un .md con el mismo formato para copiar y pegar. Invocar como /grill-user-story, opcionalmente con un título, un ID/URL del tracker, y/o una US rústica existente. Usar antes de opsx:propose, o cuando alguien dice \"necesito una US\", \"convierte esto en una US como corresponde\", o \"esta historia está muy vaga\"."
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
# grill-user-story
|
|
@@ -31,15 +31,17 @@ Si no viene nada, pedir título y si hay un borrador existente.
|
|
|
31
31
|
|
|
32
32
|
1. **Cortar en lo técnico.** Si la charla deriva a tablas, endpoints, migraciones o elección de framework, frenar: "eso es diseño, no ahora". La US nombra *qué necesita el usuario*, nunca *cómo se construye*.
|
|
33
33
|
2. **Cortar en lo no testeable.** Nunca emitir un criterio que no pueda volverse un test. "El usuario tiene una buena experiencia" se rechaza. "Un carrito vacío no se puede finalizar" se acepta — funcional y verificable. Empujar cada AC hasta que sea observable.
|
|
34
|
-
3. **Publicar, no pedir.** Si el tracker está configurado (`DAI_PM=jira|clickup` con token en `.env`), **
|
|
34
|
+
3. **Publicar, no pedir.** Si el tracker está configurado (`DAI_PM=jira|clickup` con token en `.env.dai` o `.env`), **dejá la US publicada tú**. **Nunca** cierres pidiéndole al usuario que te "pase el ID/URL del ticket" como si ya existiera, ni que copie y pegue el markdown al navegador. Dos caminos según si la US ya tiene key:
|
|
35
|
+
- **No tiene key → la CREÁS** (MCP o `dai publish`).
|
|
36
|
+
- **Ya tiene key → la ACTUALIZÁS con `dai edit-us <ID> --no-editor`**, nunca pisando el ticket a mano por MCP. El comando valida el formato antes de escribir, muestra qué cambia y pregunta si sube el `spec_version` — controles que por MCP no existen.
|
|
35
37
|
|
|
36
38
|
## Proceso
|
|
37
39
|
|
|
38
|
-
0. **Detectar el tracker (SIEMPRE, antes de nada).** Lee
|
|
40
|
+
0. **Detectar el tracker (SIEMPRE, antes de nada).** Lee la config de dai del repo y observa `DAI_PM`. **Está en `.env.dai` o en el `.env` del equipo: mirá los dos.** dai carga ambos, y si una clave está en los dos gana `.env.dai` (ADR-0017). Un repo que tiene todo en `.env` funciona igual — no hace falta migrar nada:
|
|
39
41
|
- `DAI_PM=jira` → publicas en **Jira** (base: `DAI_JIRA_BASE_URL`), vía el MCP de Atlassian/Jira.
|
|
40
42
|
- `DAI_PM=clickup` → publicas en **ClickUp**, vía el MCP de ClickUp.
|
|
41
|
-
- `DAI_PM=md` (o sin
|
|
42
|
-
**No asumas el tracker** — depende
|
|
43
|
+
- `DAI_PM=md` (o sin config) → no hay tracker: dejas la US como `.md`.
|
|
44
|
+
**No asumas el tracker** — depende de la config. Si no hay `.env.dai` ni `.env`, pregunta cuál usa el equipo.
|
|
43
45
|
1. **Resolver inputs.** Obtener título e ID del tracker (si existe). Si se refina, leer la US y anotar — para uno mismo — qué secciones del formato faltan o están flojas: rol genérico ("el usuario"), falta el "para", sin flujo de excepción, solución prefijada, ACs vagos.
|
|
44
46
|
2. **Grillar, un eje por vez.** No tirar un cuestionario — preguntar, escuchar, profundizar, y seguir. Cubrir en orden:
|
|
45
47
|
- **Título** — corto, **3 a 6 palabras**, nombra la capacidad (de ahí sale la branch). Si el título es una frase larga, acórtalo: el detalle va en la descripción, no en el título. Ej: "Confirmar acciones con consecuencias", no "Confirmación deliberada antes de ejecutar acciones con consecuencias".
|
|
@@ -49,11 +51,18 @@ Si no viene nada, pedir título y si hay un borrador existente.
|
|
|
49
51
|
- **Criterios de aceptación** — convertir cada flujo en una condición funcional y testeable, en Gherkin. Aplicar el corte #2 acá, fuerte.
|
|
50
52
|
- **Fuera de scope** — qué NO hace esta historia (mata el scope creep más adelante).
|
|
51
53
|
3. **Chequeo de tamaño (INVEST).** Si los flujos y ACs desbordan y la historia se dispersa, es demasiado grande para una sola US. No seguir empujando: **promoverla a una épica** con `/grill-epic` (que la parte en varias US independientes) y después volver acá para grillar cada US hija. Una US que no entra en un sprint es la señal de que hay una épica adentro.
|
|
52
|
-
4. **
|
|
54
|
+
4. **Dejar la US en el tracker (PASO OBLIGATORIO, ver abajo).** No termines con "¿la guardo y/o disparo el siguiente paso?": el trabajo de esta skill **incluye dejar la US publicada** en el tracker (con su key), no solo redactarla. Si la US ya existía, actualizarla cuenta como publicarla.
|
|
53
55
|
|
|
54
|
-
## Salida —
|
|
56
|
+
## Salida — dejar la US en el tracker (según `DAI_PM`), con fallback a .md
|
|
55
57
|
|
|
56
|
-
La US se produce UNA vez con el formato de `../../templates/formato-us.md`. Lo que cambia es **dónde
|
|
58
|
+
La US se produce UNA vez con el formato de `../../templates/formato-us.md`. Lo que cambia es **dónde va** y **si se crea o se actualiza**.
|
|
59
|
+
|
|
60
|
+
> **Primero: ¿la US ya tiene key?**
|
|
61
|
+
> - **No** (nació en esta sesión) → **CREAR** — pasos 1–4 de abajo.
|
|
62
|
+
> - **Sí** (el usuario trajo `ABC-482`, o vos la creaste antes en esta misma charla) →
|
|
63
|
+
> **ACTUALIZAR** — saltá a *"Si la US ya existe"*.
|
|
64
|
+
|
|
65
|
+
### Si la US es nueva (crear)
|
|
57
66
|
|
|
58
67
|
1. **Armar la US** completa: metadata de trazabilidad (`ID`, `spec_version: v1`, autor, repos esperados) + historia + contexto + casos de uso + criterios Gherkin + fuera de scope + reglas + dependencias + métricas.
|
|
59
68
|
2. **Publicar en el tracker que dice `DAI_PM`:**
|
|
@@ -62,10 +71,10 @@ La US se produce UNA vez con el formato de `../../templates/formato-us.md`. Lo q
|
|
|
62
71
|
- Confirmar al usuario con el link al ticket publicado.
|
|
63
72
|
- **Importante:** los criterios SIEMPRE van bajo `## Criterios de aceptación` en la descripción — así `dai link-us`/`check` los encuentran, sin importar el tracker.
|
|
64
73
|
3. **Fallback SIN MCP → publicar con el CLI (`dai publish`):**
|
|
65
|
-
- Si NO hay MCP del tracker conectado (pero sí `DAI_PM=jira|clickup` + token en `.env`):
|
|
74
|
+
- Si NO hay MCP del tracker conectado (pero sí `DAI_PM=jira|clickup` + token en `.env.dai` o `.env`):
|
|
66
75
|
escribe la US como `.md` (formato `formato-us.md`) y publícala con el comando:
|
|
67
76
|
**`dai publish <ruta-del-md>`** → crea el issue/tarea vía REST y devuelve el key.
|
|
68
|
-
(Jira necesita además `DAI_JIRA_PROJECT`
|
|
77
|
+
(Jira necesita además `DAI_JIRA_PROJECT` — la clave del **proyecto**,
|
|
69
78
|
`PROJ`, no la de un ticket.)
|
|
70
79
|
- **Si la US pertenece a una épica:** `dai publish <us.md> --parent <KEY-de-la-épica>`.
|
|
71
80
|
- **Si el proyecto exige campos propios** (típico en Jira corporativo): van con
|
|
@@ -82,6 +91,45 @@ La US se produce UNA vez con el formato de `../../templates/formato-us.md`. Lo q
|
|
|
82
91
|
atajo publica igual, pero el `## Criterios de aceptación` puede quedar mal formado y
|
|
83
92
|
**el link QUÉ↔CÓMO se rompe en silencio**. Si el error nombra un campo obligatorio que
|
|
84
93
|
falta, decláralo en `.dai/jira-fields.json` (molde en `.dai/templates/`) y reintenta.
|
|
94
|
+
### Si la US ya existe (refinar) — `dai edit-us`
|
|
95
|
+
|
|
96
|
+
Cuando la US **ya tiene key**, el trabajo no es crearla sino **pisarla con la versión
|
|
97
|
+
refinada**. Eso NO se hace por MCP ni editando el ticket en el navegador: se hace con
|
|
98
|
+
|
|
99
|
+
```bash
|
|
100
|
+
dai edit-us <ID> --us <ruta-del-md> --no-editor
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
Escribí la US refinada al `.md` y pasáselo. `--no-editor` es lo que hace que el comando
|
|
104
|
+
sirva desde una skill: no abre `$EDITOR` (vos ya editaste), pero **conserva todo lo demás**.
|
|
105
|
+
|
|
106
|
+
Qué te da ese camino, que por MCP no existe:
|
|
107
|
+
|
|
108
|
+
1. **Valida el formato antes de escribir.** Frena si falta el `# Título`, la sección
|
|
109
|
+
`## Criterios de aceptación`, o si está vacía — las tres cosas sin las cuales no hay
|
|
110
|
+
`ac_hash` y el link QUÉ↔CÓMO se rompe. Y **avisa** si un criterio no es Gherkin
|
|
111
|
+
completo o se metió en el CÓMO. Si frena, **arreglá el `.md` y reintentá**: no busques
|
|
112
|
+
otra vía para publicar igual, el chequeo está para eso.
|
|
113
|
+
2. **Muestra qué cambia** en el tracker (título, cuántos criterios, `ac_hash`) antes de
|
|
114
|
+
tocarlo.
|
|
115
|
+
3. **Pregunta si sube el `spec_version`** — y esta pregunta **es de la persona, no tuya**:
|
|
116
|
+
- **material** (un criterio nuevo, una regla distinta) → sube `v1` → `v2`, y los repos
|
|
117
|
+
que implementaron `v1` se marcan **atrasados** solos.
|
|
118
|
+
- **editorial** (typo, redacción más clara) → se queda en `v1`, nadie se marca atrasado.
|
|
119
|
+
|
|
120
|
+
Con `--yes` el comando asume material y sube la versión. **No pongas `--yes` sin
|
|
121
|
+
preguntar**: marcar repos como atrasados de más entrena al equipo a ignorar los ⚠️.
|
|
122
|
+
Preguntale al PO cuál de las dos es, y recién entonces corré con `--bump` o `--no-bump`.
|
|
123
|
+
4. **Re-estampa el `ac_hash`** del `implements.yaml` si el repo ya implementaba esa US,
|
|
124
|
+
para que `dai check` no la marque atrasada por la propia edición.
|
|
125
|
+
|
|
126
|
+
Usá **`--dry-run` primero** para mostrarle el preview a la persona, y corré en firme
|
|
127
|
+
recién cuando lo apruebe. Si el backend es `md` (sin tracker), el mismo comando actualiza
|
|
128
|
+
el `.md` canónico.
|
|
129
|
+
|
|
130
|
+
> Si preferís no traer nada del tracker porque ya tenés la US entera escrita,
|
|
131
|
+
> `dai update-us <ID> --us <md>` es el mismo camino sin el paso de bajarla.
|
|
132
|
+
|
|
85
133
|
5. **Estado.** Dejar la US en `pulida`. Ofrecer que el dev siga con `dai link-us <ID>` → `opsx:propose` (lado técnico).
|
|
86
134
|
|
|
87
135
|
## Hand-off
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
# Gate de trazabilidad de dai — la regla de governance/ci-rules.md, ejecutable.
|
|
2
|
+
#
|
|
3
|
+
# Qué hace: en cada PR, verifica que una branch de producto declare qué US implementa
|
|
4
|
+
# (implements.yaml) y que ese link no haya quedado atrasado contra la US viva.
|
|
5
|
+
#
|
|
6
|
+
# Qué NO hace: exigirle US a todo. `chore/`, `docs/`, `ci/`, `build/`, `test/`,
|
|
7
|
+
# `refactor/`, `style/`, `release/`, `hotfix/` y `revert/` pasan sin link — son trabajo
|
|
8
|
+
# legítimo sin ticket (governance/branch-naming.md). Un gate que bloquea esas branches
|
|
9
|
+
# se termina desactivando, y entonces no protege nada.
|
|
10
|
+
#
|
|
11
|
+
# Cómo se instala: copialo a .github/workflows/ de tu repo. Si tu CI no es GitHub
|
|
12
|
+
# Actions, el contrato es el mismo en cualquier runner — es un solo comando:
|
|
13
|
+
#
|
|
14
|
+
# npx --yes @dforce2055/dai check --ci
|
|
15
|
+
#
|
|
16
|
+
# Códigos de salida: 0 = pasa · 1 = falta el link · 2 = el QUÉ cambió (US atrasada)
|
|
17
|
+
|
|
18
|
+
name: dai · trazabilidad
|
|
19
|
+
|
|
20
|
+
on:
|
|
21
|
+
pull_request:
|
|
22
|
+
|
|
23
|
+
jobs:
|
|
24
|
+
link:
|
|
25
|
+
name: link QUÉ↔CÓMO
|
|
26
|
+
runs-on: ubuntu-latest
|
|
27
|
+
steps:
|
|
28
|
+
- uses: actions/checkout@v4
|
|
29
|
+
- uses: actions/setup-node@v4
|
|
30
|
+
with:
|
|
31
|
+
node-version: 20
|
|
32
|
+
|
|
33
|
+
# `dai check --ci` detecta solo la branch de la PR (GITHUB_HEAD_REF): en una PR,
|
|
34
|
+
# HEAD es un merge commit detached y `git rev-parse --abbrev-ref HEAD` diría "HEAD".
|
|
35
|
+
#
|
|
36
|
+
# Sin secrets del tracker, el gate valida el LINK y no compara contra la US viva
|
|
37
|
+
# (--no-network). Con secrets, sacá el flag y además detecta las US atrasadas.
|
|
38
|
+
- name: Gate de trazabilidad
|
|
39
|
+
run: npx --yes @dforce2055/dai check --ci --no-network
|
|
40
|
+
|
|
41
|
+
# Variante con tracker — descomentala y cargá los secrets del repo para que el
|
|
42
|
+
# gate marque también las US ATRASADAS (salida 2). Comentá el paso de arriba.
|
|
43
|
+
#
|
|
44
|
+
# - name: Gate de trazabilidad (con tracker)
|
|
45
|
+
# env:
|
|
46
|
+
# DAI_PM: jira # o clickup
|
|
47
|
+
# DAI_JIRA_BASE_URL: ${{ vars.DAI_JIRA_BASE_URL }}
|
|
48
|
+
# DAI_JIRA_EMAIL: ${{ secrets.DAI_JIRA_EMAIL }}
|
|
49
|
+
# DAI_JIRA_TOKEN: ${{ secrets.DAI_JIRA_TOKEN }}
|
|
50
|
+
# run: npx --yes @dforce2055/dai check --ci
|