@dforce2055/dai 0.9.0 → 0.10.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/{.env.example → .env.dai.example} +3 -3
- package/CHANGELOG.md +41 -0
- package/README.md +36 -25
- package/VERSION +1 -1
- package/cli/dai.mjs +97 -41
- package/cli/lib/bootstrap.mjs +39 -7
- package/cli/lib/env.mjs +12 -0
- package/cli/lib/pm-clickup.mjs +2 -2
- package/cli/lib/pm-jira.mjs +2 -2
- package/cli/lib/skills-source.mjs +8 -0
- package/docs/EJEMPLO-END-TO-END.md +52 -43
- package/docs/MANIFIESTO.md +2 -2
- package/docs/METODOLOGIA.md +20 -15
- package/docs/PROBAR.md +13 -14
- package/docs/SCRUM-CON-IA.md +10 -10
- package/docs/adr/0003-deteccion-y-estampado-son-comandos.md +1 -1
- package/docs/adr/0006-distribucion-y-licencia.md +1 -1
- package/docs/adr/0013-skills-externas-install-from.md +11 -4
- package/docs/adr/0015-jira-corporativo.md +1 -1
- package/docs/adr/0017-env-dai.md +64 -0
- package/docs/adr/README.md +1 -0
- package/docs/detalle/01-refinamiento.md +6 -5
- package/docs/detalle/03-ramas.md +2 -2
- package/docs/detalle/04-tdd.md +15 -9
- package/docs/detalle/06-code-review.md +8 -5
- package/docs/detalle/08-daily.md +1 -1
- package/docs/detalle/README.md +1 -1
- package/docs/glosario.md +2 -2
- package/docs/guias/dev.md +10 -7
- package/docs/guias/index.md +12 -0
- package/docs/guias/lead.md +1 -1
- package/docs/guias/po.md +13 -7
- package/docs/index.md +35 -0
- package/docs/public/favicon.svg +12 -0
- package/docs/public/logo-link.svg +12 -0
- package/docs/public/logo.svg +12 -0
- package/docs/public/tutoriales/clickup-1-settings.png +0 -0
- package/docs/public/tutoriales/clickup-2-api.png +0 -0
- package/docs/public/tutoriales/clickup-3-generate-copy.png +0 -0
- package/docs/public/tutoriales/jira-1-avatar.png +0 -0
- package/docs/public/tutoriales/jira-2-seguridad-tokens.png +0 -0
- package/docs/public/tutoriales/jira-3-crear-token.png +0 -0
- package/docs/public/tutoriales/jira-4-nombre-vencimiento.png +0 -0
- package/docs/public/tutoriales/jira-5-copiar.png +0 -0
- package/docs/tutoriales/claves-ssh.md +93 -0
- package/docs/tutoriales/configurar-git.md +53 -0
- package/docs/tutoriales/index.md +18 -0
- package/docs/tutoriales/instalar-glab.md +74 -0
- package/docs/tutoriales/token-clickup.md +73 -0
- package/docs/tutoriales/token-jira.md +74 -0
- package/package.json +9 -3
package/cli/lib/pm-clickup.mjs
CHANGED
|
@@ -22,7 +22,7 @@ export function clickupTaskToText(json) {
|
|
|
22
22
|
}
|
|
23
23
|
|
|
24
24
|
export function clickupAdapter(env) {
|
|
25
|
-
if (!env.DAI_CLICKUP_TOKEN) throw new Error("falta DAI_CLICKUP_TOKEN en el .env (backend clickup).");
|
|
25
|
+
if (!env.DAI_CLICKUP_TOKEN) throw new Error("falta DAI_CLICKUP_TOKEN en el .env.dai (backend clickup).");
|
|
26
26
|
return {
|
|
27
27
|
kind: "clickup",
|
|
28
28
|
async fetchUS(id) {
|
|
@@ -43,7 +43,7 @@ export function clickupAdapter(env) {
|
|
|
43
43
|
},
|
|
44
44
|
async createUS({ title, descriptionMarkdown }) {
|
|
45
45
|
const list = env.DAI_CLICKUP_LIST_ID;
|
|
46
|
-
if (!list) throw new Error("falta DAI_CLICKUP_LIST_ID en el .env (la lista donde crear la tarea).");
|
|
46
|
+
if (!list) throw new Error("falta DAI_CLICKUP_LIST_ID en el .env.dai (la lista donde crear la tarea).");
|
|
47
47
|
const res = await fetch(`${API}/list/${encodeURIComponent(list)}/task`, {
|
|
48
48
|
method: "POST", headers: clickupAuthHeaders(env),
|
|
49
49
|
body: JSON.stringify({ name: title, markdown_content: descriptionMarkdown }),
|
package/cli/lib/pm-jira.mjs
CHANGED
|
@@ -15,7 +15,7 @@ const trim = (b) => String(b || "").replace(/\/+$/, "");
|
|
|
15
15
|
// error de config más común: `dai init` deja DAI_JIRA_PROJECT vacío y quien lo completa
|
|
16
16
|
// suele pegar la épica que tiene a mano. Jira responde un 400 que no lo explica.
|
|
17
17
|
export function assertProjectKey(key) {
|
|
18
|
-
if (!key) throw new Error("falta DAI_JIRA_PROJECT en el .env (la clave del proyecto donde crear el issue).");
|
|
18
|
+
if (!key) throw new Error("falta DAI_JIRA_PROJECT en el .env.dai (la clave del proyecto donde crear el issue).");
|
|
19
19
|
const k = String(key).trim();
|
|
20
20
|
const m = k.match(/^([A-Za-z][A-Za-z0-9_]*)-\d+$/);
|
|
21
21
|
if (m) {
|
|
@@ -136,7 +136,7 @@ export function createHint(status, body = "") {
|
|
|
136
136
|
|
|
137
137
|
export function jiraAdapter(env) {
|
|
138
138
|
const base = env.DAI_JIRA_BASE_URL;
|
|
139
|
-
if (!base) throw new Error("falta DAI_JIRA_BASE_URL en el .env (backend jira).");
|
|
139
|
+
if (!base) throw new Error("falta DAI_JIRA_BASE_URL en el .env.dai (backend jira).");
|
|
140
140
|
return {
|
|
141
141
|
kind: "jira",
|
|
142
142
|
async fetchUS(id) {
|
|
@@ -15,6 +15,14 @@ export function parseSource(src) {
|
|
|
15
15
|
const hash = raw.lastIndexOf("#");
|
|
16
16
|
if (hash > 0) { ref = raw.slice(hash + 1) || null; loc = raw.slice(0, hash); }
|
|
17
17
|
|
|
18
|
+
// Paquete npm: `npm:@scope/pkg[@version]`. dai hace `npm pack` a un temp, respetando el
|
|
19
|
+
// `.npmrc` del repo (así resuelve registries privados con scope). La versión va en el
|
|
20
|
+
// propio spec (`@1.2.3`), no como ref con '#'.
|
|
21
|
+
if (loc.startsWith("npm:")) {
|
|
22
|
+
const spec = loc.slice(4).trim();
|
|
23
|
+
if (!spec) throw new Error("fuente npm vacía (usá npm:@scope/paquete)");
|
|
24
|
+
return { type: "npm", location: spec, ref: null };
|
|
25
|
+
}
|
|
18
26
|
// Path local explícito (./ ../ / ~/).
|
|
19
27
|
if (/^(\.\.?\/|\/|~\/)/.test(loc)) return { type: "path", location: loc, ref };
|
|
20
28
|
// git por sintaxis de URL (https, ssh, scp git@host:…).
|
|
@@ -12,10 +12,10 @@
|
|
|
12
12
|
|
|
13
13
|
| Paso | Skill / evento | Artefacto que produce |
|
|
14
14
|
|---|---|---|
|
|
15
|
-
| 1 Refinamiento | `grill-
|
|
15
|
+
| 1 Refinamiento | `grill-user-story` → `grill-intent` (Gate 0) | la **US** (`ABC-482`) + `intent.md` |
|
|
16
16
|
| 2 Planning | `opsx:propose` | `proposal.md` + `design.md` + `tasks.md` + `specs/` |
|
|
17
17
|
| 3 Rama | `link-us` | branch + `implements.yaml` |
|
|
18
|
-
| 4
|
|
18
|
+
| 4 Implementación | `opsx:apply` (con TDD) | test (RED) → código (GREEN), por el agente |
|
|
19
19
|
| 5 Smoke | skill de smoke | escenario end-to-end verde |
|
|
20
20
|
| 6 Code review | review propio del dev → `dai pr` → partner (con `/dai-review`) | PR (código + spec) + aprobación |
|
|
21
21
|
| 7 Merge | `dai stamp` | cobertura estampada en el tracker |
|
|
@@ -37,34 +37,9 @@ ABC-482 · "Arreglar lo del carrito que a veces deja comprar de más"
|
|
|
37
37
|
|
|
38
38
|
Impresentable para implementar. Acá entra la IA.
|
|
39
39
|
|
|
40
|
-
### 1b ·
|
|
40
|
+
### 1b · `grill-user-story` produce la US
|
|
41
41
|
|
|
42
|
-
|
|
43
|
-
[`MANIFIESTO.md`](MANIFIESTO.md)).
|
|
44
|
-
|
|
45
|
-
```
|
|
46
|
-
IA: ¿Qué duele HOY, concretamente? "Comprar de más" es un síntoma.
|
|
47
|
-
PO: Un cliente finalizó la compra de un producto que ya no tenía stock, y quedó
|
|
48
|
-
una orden que no podemos cumplir. También pasa que finalizan con el carrito
|
|
49
|
-
vacío y se genera una orden fantasma.
|
|
50
|
-
IA: ¿Quién siente el dolor? "El sistema" no es un usuario.
|
|
51
|
-
PO: El comprador (recibe un error después de comprar) y depósito, que recibe
|
|
52
|
-
órdenes que no puede despachar.
|
|
53
|
-
IA: ¿Y si no lo hacemos? (costo de no actuar)
|
|
54
|
-
PO: Órdenes que se cancelan a mano, clientes enojados. Pasó bastante el último mes.
|
|
55
|
-
IA: La solución implícita es "validar el carrito al finalizar". ¿Es el salto correcto,
|
|
56
|
-
o el problema real es que el stock que muestra el carrito no es confiable?
|
|
57
|
-
PO: No, validar al finalizar es lo correcto: el stock ya existe, falta chequearlo
|
|
58
|
-
en el momento de la compra.
|
|
59
|
-
|
|
60
|
-
Veredicto: a-spec ✅ (problema real, usuario concreto, costo claro, sin solution-lock)
|
|
61
|
-
```
|
|
62
|
-
|
|
63
|
-
→ produce `openspec/intents/20260703-checkout-invalido/intent.md` con ese veredicto.
|
|
64
|
-
|
|
65
|
-
### 1c · `grill-user-story` produce la US
|
|
66
|
-
|
|
67
|
-
Con el problema validado, la skill interroga hasta que la US es **testeable por
|
|
42
|
+
Acá entra la IA: `grill-user-story` interroga al PO hasta que la US es **testeable por
|
|
68
43
|
construcción** ([`formato-us.md`](../templates/formato-us.md)) y la publica en el gestor:
|
|
69
44
|
|
|
70
45
|
```markdown
|
|
@@ -113,6 +88,33 @@ para **recibir los productos que elijo sin sorpresas**.
|
|
|
113
88
|
> Nota que la US **no dice** tablas, endpoints ni framework — solo el QUÉ. Y cada
|
|
114
89
|
> AC es un test en potencia ([Art. 3](./MANIFIESTO.md#art-3) del manifiesto).
|
|
115
90
|
|
|
91
|
+
### 1c · Gate 0 — `grill-intent` desafía el problema
|
|
92
|
+
|
|
93
|
+
Con la US ya formada, **antes** de invertir en el spec, el Gate 0 cuestiona el *problema*
|
|
94
|
+
detrás (contra el [`MANIFIESTO.md`](MANIFIESTO.md)):
|
|
95
|
+
|
|
96
|
+
```
|
|
97
|
+
IA: ¿Qué duele HOY, concretamente? "Comprar de más" es un síntoma.
|
|
98
|
+
PO: Un cliente finalizó la compra de un producto que ya no tenía stock, y quedó
|
|
99
|
+
una orden que no podemos cumplir. También pasa que finalizan con el carrito
|
|
100
|
+
vacío y se genera una orden fantasma.
|
|
101
|
+
IA: ¿Quién siente el dolor? "El sistema" no es un usuario.
|
|
102
|
+
PO: El comprador (recibe un error después de comprar) y depósito, que recibe
|
|
103
|
+
órdenes que no puede despachar.
|
|
104
|
+
IA: ¿Y si no lo hacemos? (costo de no actuar)
|
|
105
|
+
PO: Órdenes que se cancelan a mano, clientes enojados. Pasó bastante el último mes.
|
|
106
|
+
IA: La solución implícita es "validar el carrito al finalizar". ¿Es el salto correcto,
|
|
107
|
+
o el problema real es que el stock que muestra el carrito no es confiable?
|
|
108
|
+
PO: No, validar al finalizar es lo correcto: el stock ya existe, falta chequearlo
|
|
109
|
+
en el momento de la compra.
|
|
110
|
+
|
|
111
|
+
Veredicto: a-spec ✅ (problema real, usuario concreto, costo claro, sin solution-lock)
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
→ produce `openspec/intents/20260703-checkout-invalido/intent.md` con ese veredicto. Si
|
|
115
|
+
hubiera dado *reframe* o *don't build*, la US volvería al PO **antes** de gastar un solo
|
|
116
|
+
artefacto de spec — ese es el punto del Gate 0.
|
|
117
|
+
|
|
116
118
|
---
|
|
117
119
|
|
|
118
120
|
## Paso 2 — Planning: `opsx:propose` deriva el CÓMO
|
|
@@ -175,9 +177,10 @@ autor: D. Force (dev)
|
|
|
175
177
|
|
|
176
178
|
---
|
|
177
179
|
|
|
178
|
-
## Paso 4 —
|
|
180
|
+
## Paso 4 — Implementación: el agente construye con TDD (`/opsx:apply`)
|
|
179
181
|
|
|
180
|
-
|
|
182
|
+
`/opsx:apply` implementa las tareas del change, un test a la vez. Vertical slice del AC-2
|
|
183
|
+
(el guard del carrito vacío). **Primero el test (RED):**
|
|
181
184
|
|
|
182
185
|
```typescript
|
|
183
186
|
test("un carrito vacío no se puede finalizar", async () => {
|
|
@@ -205,8 +208,9 @@ export async function finalizarCompra(id: CarritoId) {
|
|
|
205
208
|
// ▶ VERDE. Repetir el ciclo para AC-1 y AC-3.
|
|
206
209
|
```
|
|
207
210
|
|
|
208
|
-
> El test verifica por la **interfaz pública**
|
|
209
|
-
> espía lo interno. Sobrevive a un refactor
|
|
211
|
+
> El test (que escribió el agente) verifica por la **interfaz pública**
|
|
212
|
+
> (`finalizarCompra`, `ordenesDe`), no espía lo interno. Sobrevive a un refactor
|
|
213
|
+
> (Art. 7 + skill `tdd`). El dev revisa cada slice: es responsable del código.
|
|
210
214
|
|
|
211
215
|
---
|
|
212
216
|
|
|
@@ -239,21 +243,26 @@ $ dai pr --assignee mgomez
|
|
|
239
243
|
✓ PR #123 creada → …/pull/123 (base: main · US: ABC-482 @ v1 · dai check ✅)
|
|
240
244
|
```
|
|
241
245
|
|
|
242
|
-
El **partner** revisa la PR. Se apoya en la skill `/dai-review` para un primer pase
|
|
243
|
-
comentario
|
|
246
|
+
El **partner** revisa la PR. Se apoya en la skill `/dai-review` para un primer pase: deja
|
|
247
|
+
un **review inline** (resumen + un comentario anclado por línea, low/medium/high). La skill
|
|
248
|
+
le muestra el preview y **espera su OK antes de postear**; después el partner **firma**
|
|
249
|
+
aprobación o rechazo:
|
|
244
250
|
|
|
245
251
|
```
|
|
246
|
-
🤖 /dai-review
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
252
|
+
🤖 /dai-review — resumen
|
|
253
|
+
US: ABC-482 @ v1 · dai check: ✅ al día · DoD: 5/5
|
|
254
|
+
1 comentario en línea: 1 🔵 Low.
|
|
255
|
+
|
|
256
|
+
🔵 Low — src/checkout/errors.ts:12
|
|
257
|
+
CarritoVacioError y SinStockError podrían extender un DomainError común,
|
|
258
|
+
como el resto del módulo.
|
|
251
259
|
|
|
252
|
-
👤 M. Gómez (partner):
|
|
260
|
+
👤 M. Gómez (partner): reviso el preview, lo posteo, y apruebo tras el ajuste.
|
|
253
261
|
```
|
|
254
262
|
|
|
255
263
|
> El dev revisa su propio código; un partner distinto revisa la PR y **firma** (Art. 5).
|
|
256
|
-
>
|
|
264
|
+
> El review sale con el nombre y el token del partner (nunca `APPROVE` automático): la
|
|
265
|
+
> skill asiste, la persona firma.
|
|
257
266
|
|
|
258
267
|
---
|
|
259
268
|
|
|
@@ -282,7 +291,7 @@ ABC-482 · implementado por (lo estampó dai stamp)
|
|
|
282
291
|
## Paso 8 — Daily *(humano, a propósito)*
|
|
283
292
|
|
|
284
293
|
> *"Ayer cerré ABC-482, la validación del checkout con el guard de carrito. Hoy
|
|
285
|
-
>
|
|
294
|
+
> tomo ABC-490. Sin trabas."* — La IA no genera esto; el equipo se sincroniza (Art. 6).
|
|
286
295
|
|
|
287
296
|
## Paso 9 — Review / Demo
|
|
288
297
|
|
package/docs/MANIFIESTO.md
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
> **Qué es esto.** La *constitución* de la metodología: los principios inmutables
|
|
4
4
|
> contra los que se mide toda decisión. Cuando `grill-intent` desafía un problema,
|
|
5
5
|
> lo hace contra estos artículos. Cuando dudas si algo "va con el método", la
|
|
6
|
-
> respuesta está
|
|
6
|
+
> respuesta está aquí. Es corto a propósito — un manifiesto que no se puede citar de
|
|
7
7
|
> memoria no gobierna nada.
|
|
8
8
|
>
|
|
9
9
|
> **Cómo se usa.** Es el input de constitución que las skills asumen (junto con
|
|
@@ -56,7 +56,7 @@ El *daily* y la *retro* se hacen a mano, a propósito. Son donde el equipo se
|
|
|
56
56
|
apropia del proceso y lo entiende. La IA puede darles datos; no los reemplaza.
|
|
57
57
|
|
|
58
58
|
<a id="art-7"></a>**Art. 7 — No vibe coding.**
|
|
59
|
-
No se improvisa código sobre una idea vaga. Toda implementación
|
|
59
|
+
No se improvisa código sobre una idea vaga. Toda implementación parte de una US
|
|
60
60
|
bien definida, pasa por un design, y se construye con tests. La disciplina no es
|
|
61
61
|
opcional: es lo que separa este método de "pedirle cosas a un chat".
|
|
62
62
|
|
package/docs/METODOLOGIA.md
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
> **Fuente de verdad única.** Este documento es el maestro. Los dos HTML
|
|
4
4
|
> (`desarrollo-asistido-por-ia.html` federado y `-equipos-compactos.html`) son
|
|
5
|
-
> **vistas de presentación** derivadas de
|
|
5
|
+
> **vistas de presentación** derivadas de aquí — si algo contradice a este `.md`,
|
|
6
6
|
> gana este `.md`. Versionado por git para que no driftee.
|
|
7
7
|
|
|
8
8
|
Una sola metodología para dos escalas opuestas:
|
|
@@ -57,9 +57,9 @@ identidad el día que se crea el ticket/change.
|
|
|
57
57
|
### 2.2 Formato linkeable garantizado
|
|
58
58
|
|
|
59
59
|
El QUÉ se produce con una forma mínima **testeable**: `id · spec_version · autor ·
|
|
60
|
-
criterios de aceptación en Gherkin`. Es exactamente lo que
|
|
61
|
-
`grill-
|
|
62
|
-
a qué linkear.
|
|
60
|
+
criterios de aceptación en Gherkin`. Es exactamente lo que asegura la skill
|
|
61
|
+
`grill-user-story` (y después el Gate 0 de `grill-intent` desafía el problema; ver
|
|
62
|
+
`formato-us.md`). Sin esa forma, no hay a qué linkear.
|
|
63
63
|
|
|
64
64
|
### 2.3 El link se autora una sola vez, del lado del CÓMO
|
|
65
65
|
|
|
@@ -122,8 +122,10 @@ federación.**
|
|
|
122
122
|
|
|
123
123
|
El CÓMO se construye con **test primero**, en *vertical slices* (un test → una
|
|
124
124
|
implementación → repetir), verificando por la **interfaz pública**, no espiando lo
|
|
125
|
-
interno. Un buen test lee como una spec y sobrevive a un refactor.
|
|
126
|
-
`
|
|
125
|
+
interno. Un buen test lee como una spec y sobrevive a un refactor. **Quien lo ejecuta
|
|
126
|
+
es el agente**, dentro de `/opsx:apply` (la disciplina la encapsula la skill `tdd`); el
|
|
127
|
+
dev decide qué comportamientos importa testear y es responsable de revisar el resultado
|
|
128
|
+
([Art. 7](MANIFIESTO.md#art-7)). Ver `skills/tdd/`.
|
|
127
129
|
|
|
128
130
|
---
|
|
129
131
|
|
|
@@ -134,7 +136,7 @@ duele, no antes.**
|
|
|
134
136
|
|
|
135
137
|
| | **N1 · Solo / 1 repo** | **N2 · Equipo compacto** | **N3 · Federado** |
|
|
136
138
|
|---|---|---|---|
|
|
137
|
-
| Caso típico | equipo chico
|
|
139
|
+
| Caso típico | equipo chico empezando, un dev | equipo chico | organización grande |
|
|
138
140
|
| El QUÉ vive en | `proposal.md` de OpenSpec | ClickUp (US) → el change la referencia | Jira (`ABC-###`, hub) |
|
|
139
141
|
| El link vive en | la carpeta del change (co-localizado) | `implements.yaml` en el repo | `implements.yaml` versionado |
|
|
140
142
|
| Inversa la genera | un comando local | comando / CI liviano | CI estampa cobertura + CD reporta ambiente |
|
|
@@ -178,13 +180,13 @@ El artefacto no desaparece; se aligera la ceremonia alrededor.
|
|
|
178
180
|
|
|
179
181
|
```
|
|
180
182
|
① Nace la idea → ticket vago en el PM (o intención suelta en N1)
|
|
181
|
-
②
|
|
182
|
-
③ Se pule el QUÉ → /grill-user-story → US testeable (formato-us.md),
|
|
183
|
+
② Se pule el QUÉ → /grill-user-story → US testeable (formato-us.md),
|
|
183
184
|
publicada en Jira/ClickUp (o .md si no hay MCP)
|
|
185
|
+
③ Gate 0: ¿problema OK? → /grill-intent → veredicto: a-spec / reframe / descartar
|
|
184
186
|
④ Se abre el CÓMO → /link-us ABC-### → branch + implements.yaml ligados al ID
|
|
185
187
|
⑤ Se arma el change → opsx:explore → opsx:propose (proposal/design/tasks + specs)
|
|
186
|
-
⑥ Se implementa → TDD (red
|
|
187
|
-
⑦ Se promueve → opsx:
|
|
188
|
+
⑥ Se implementa → opsx:apply → el agente aplica las tareas con TDD (red→green→refactor)
|
|
189
|
+
⑦ Se promueve → opsx:archive; el CI estampa cobertura en el PM
|
|
188
190
|
⑧ Se despliega → el CD reporta a qué ambiente (dev/test/pre/prod) fue la versión
|
|
189
191
|
```
|
|
190
192
|
|
|
@@ -203,11 +205,14 @@ El artefacto no desaparece; se aligera la ceremonia alrededor.
|
|
|
203
205
|
|
|
204
206
|
| Skill | Lado | Qué hace |
|
|
205
207
|
|---|---|---|
|
|
206
|
-
| `
|
|
208
|
+
| `doc-to-backlog` | QUÉ | Un documento (PDF/Word) → backlog candidato de épicas + US para priorizar. |
|
|
209
|
+
| `grill-epic` | QUÉ | Algo grande → una épica partida en varias US. |
|
|
207
210
|
| `grill-user-story` | QUÉ | Interroga hasta producir una US testeable (INVEST + Gherkin). Publica en Jira/ClickUp o deja `.md`. |
|
|
211
|
+
| `grill-intent` | QUÉ | Gate 0: con la US ya formada, desafía el *problema* antes de escribir spec. Veredicto: a-spec / reframe / descartar. |
|
|
208
212
|
| `link-us` | CÓMO | Crea branch + `implements.yaml` desde el ID del PM. El link, correcto por construcción. |
|
|
209
|
-
| `
|
|
210
|
-
| `
|
|
213
|
+
| `opsx:*` | CÓMO | OpenSpec: explore → propose → apply (el agente implementa con TDD) → archive. Lo provee OpenSpec. |
|
|
214
|
+
| `tdd` | CÓMO | La disciplina red-green-refactor (vertical slices, tests por interfaz pública) que aplica `opsx:apply`. |
|
|
215
|
+
| `dai-review` | CÓMO | Review inline de una PR/MR ajena: resumen + un comentario por línea, con gate humano de OK antes de postear. |
|
|
211
216
|
|
|
212
217
|
El **adaptador de PM** es un seam único: las skills del QUÉ publican en Jira **o**
|
|
213
218
|
ClickUp **o** dejan un `.md` según qué MCP/token haya. Es la **misma** skill con
|
|
@@ -228,7 +233,7 @@ de N3 queda **una** decisión sin resolver; el resto se cerró al construir la h
|
|
|
228
233
|
|
|
229
234
|
**Ya resueltas** (al construir dai):
|
|
230
235
|
- **Adaptador de PM configurable** → `getAdapter` (backends `md`/`jira`/`clickup`, token del
|
|
231
|
-
`.env`); modelo de auth en [ADR-0007](adr/0007-modelo-de-autenticacion.md).
|
|
236
|
+
`.env.dai` no versionado — [ADR-0017](adr/0017-env-dai.md)); modelo de auth en [ADR-0007](adr/0007-modelo-de-autenticacion.md).
|
|
232
237
|
- **Formato de `implements.yaml`** → congelado en [ADR-0004](adr/0004-ubicacion-y-schema-implements.md)
|
|
233
238
|
(schema + ubicación + descubrimiento por glob).
|
|
234
239
|
- **Escritura multi-repo en el tracker** → `dai stamp` deja un **comentario por repo** (no se
|
package/docs/PROBAR.md
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
# Probar dai
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
**
|
|
5
|
-
**
|
|
3
|
+
La forma más rápida de conocer dai: instala el CLI y corre el ciclo completo en tu
|
|
4
|
+
máquina. Empieza **sin credenciales** (backend `md`) para ver el flujo entero en un par de
|
|
5
|
+
minutos, y después pruébalo **contra tu tracker real** (ClickUp o Jira).
|
|
6
6
|
|
|
7
7
|
> Esto es la guía para **usar** dai por primera vez. Para verlo funcionando sobre una
|
|
8
8
|
> US real (narrado), mira [`EJEMPLO-END-TO-END.md`](EJEMPLO-END-TO-END.md).
|
|
@@ -10,19 +10,17 @@ No hace falta publicar en npm para probarlo. Se prueba local. Recomendado: hacer
|
|
|
10
10
|
## Instalar el CLI
|
|
11
11
|
|
|
12
12
|
```bash
|
|
13
|
-
npm i -g @dforce2055/dai
|
|
14
|
-
# — o, si clonaste el repo —
|
|
15
|
-
git clone https://github.com/dforce2055/dai && cd dai && npm link
|
|
16
|
-
|
|
13
|
+
npm i -g @dforce2055/dai
|
|
17
14
|
dai --version
|
|
18
15
|
```
|
|
19
16
|
|
|
20
|
-
##
|
|
17
|
+
## Paso 1 — sin credenciales (backend `md`)
|
|
21
18
|
|
|
22
|
-
|
|
19
|
+
Recorre el loop completo `link-us → check → stamp` sin red ni tokens: todo local. Perfecto
|
|
20
|
+
para ver cómo funciona antes de conectar nada.
|
|
23
21
|
|
|
24
22
|
```bash
|
|
25
|
-
# 1. Repo de prueba + bootstrap (dai init deja el .env; elige "md" cuando pregunte)
|
|
23
|
+
# 1. Repo de prueba + bootstrap (dai init deja el .env.dai; elige "md" cuando pregunte)
|
|
26
24
|
mkdir /tmp/dai-test && cd /tmp/dai-test
|
|
27
25
|
git init && git commit --allow-empty -m init
|
|
28
26
|
git remote add origin git@github.com:TU-USUARIO/dai-test.git # para los links de branch/commit
|
|
@@ -48,9 +46,9 @@ dai check # ⚠️ ATRASADO (exit 1) → sugiere: dai li
|
|
|
48
46
|
dai stamp # con md, deja .dai/us/<slug>.coverage.md
|
|
49
47
|
```
|
|
50
48
|
|
|
51
|
-
|
|
49
|
+
Con esto ya viste el ciclo entero. Ahora conéctalo a tu tracker real.
|
|
52
50
|
|
|
53
|
-
##
|
|
51
|
+
## Paso 2 — contra tu tracker real (ClickUp)
|
|
54
52
|
|
|
55
53
|
**Preparar ClickUp:**
|
|
56
54
|
|
|
@@ -62,7 +60,7 @@ Si esto anda, el flujo está bien. Pasa al tracker real.
|
|
|
62
60
|
**Config y flujo:**
|
|
63
61
|
|
|
64
62
|
```bash
|
|
65
|
-
cat > .env <<'EOF'
|
|
63
|
+
cat > .env.dai <<'EOF'
|
|
66
64
|
DAI_PM=clickup
|
|
67
65
|
DAI_CLICKUP_TOKEN=pk_XXXXXXXX
|
|
68
66
|
EOF
|
|
@@ -79,7 +77,8 @@ dai check # ⚠️ ATRASADO (lo detectó solo)
|
|
|
79
77
|
dai stamp # deja un COMENTARIO en la tarea con la cobertura
|
|
80
78
|
```
|
|
81
79
|
|
|
82
|
-
> El `.env`
|
|
80
|
+
> El `.env.dai` **no se versiona**: el token no se commitea, y el `.env` del equipo no se
|
|
81
|
+
> toca ([ADR-0017](adr/0017-env-dai.md); modelo de auth en [ADR-0007](adr/0007-modelo-de-autenticacion.md)).
|
|
83
82
|
|
|
84
83
|
## Troubleshooting
|
|
85
84
|
|
package/docs/SCRUM-CON-IA.md
CHANGED
|
@@ -49,9 +49,9 @@
|
|
|
49
49
|
|---|---|
|
|
50
50
|
| **Clásico** | El PO parte épicas en Historias de Usuario y les pone criterios de aceptación. |
|
|
51
51
|
| **Dolor** | US vagas, no testeables ("el usuario quiere un botón"). El malentendido se descubre tarde, ya implementado. |
|
|
52
|
-
| **Con IA** | `grill-
|
|
52
|
+
| **Con IA** | `grill-user-story` **interroga** al PO hasta que la US es testeable por construcción (INVEST + Gherkin); y después el Gate 0 de `grill-intent` desafía el *problema* detrás (veredicto: a-spec / reframe / descartar). La IA no *escribe* la US: la *saca a preguntas*. La US nace con ID estable y criterios hasheables. |
|
|
53
53
|
| **Humano (HITL)** | El PO responde y decide. La IA no inventa requerimientos: los pule. |
|
|
54
|
-
| **Herramienta** | `grill-
|
|
54
|
+
| **Herramienta** | `grill-user-story`, `grill-intent`, `formato-us.md` |
|
|
55
55
|
| **Detalle →** | [`detalle/01-refinamiento.md`](detalle/01-refinamiento.md) |
|
|
56
56
|
|
|
57
57
|
#### 2. Sprint Planning: comprometer US y derivar tareas
|
|
@@ -76,19 +76,19 @@
|
|
|
76
76
|
| **Clásico** | El dev crea una rama para trabajar la US. |
|
|
77
77
|
| **Dolor** | Nombres inconsistentes, ramas que no se sabe a qué US pertenecen → trazabilidad rota desde el commit uno. |
|
|
78
78
|
| **Con IA** | `link-us ABC-###` crea la rama **desde el ID de la US, sin tipearlo a mano**, y genera el `implements.yaml`. La rama *es* el link: correcto por construcción. |
|
|
79
|
-
| **Humano (HITL)** | El dev elige qué US
|
|
79
|
+
| **Humano (HITL)** | El dev elige qué US toma. |
|
|
80
80
|
| **Herramienta** | `link-us` |
|
|
81
81
|
| **Detalle →** | [`detalle/03-ramas.md`](detalle/03-ramas.md) |
|
|
82
82
|
|
|
83
|
-
#### 4. Implementación con TDD
|
|
83
|
+
#### 4. Implementación (`/opsx:apply`, con TDD)
|
|
84
84
|
|
|
85
85
|
| | |
|
|
86
86
|
|---|---|
|
|
87
87
|
| **Clásico** | El dev codea. Idealmente con tests. |
|
|
88
88
|
| **Dolor** | Se codea primero y se testea "si queda tiempo" (nunca queda). Vibe coding. |
|
|
89
|
-
| **Con IA** |
|
|
90
|
-
| **Humano (HITL)** | El dev decide qué comportamientos importa testear y revisa
|
|
91
|
-
| **Herramienta** | `tdd` |
|
|
89
|
+
| **Con IA** | El **agente implementa** con `/opsx:apply`: aplica las tareas de `opsx:propose` en *vertical slices* (un test → el código mínimo → repetir), escribiendo el test como spec ejecutable **antes** del código y verificando por la interfaz pública (la disciplina TDD la encapsula la skill `tdd`). Anti vibe-coding real. |
|
|
90
|
+
| **Humano (HITL)** | El dev decide qué comportamientos importa testear, valida cada slice y **es responsable del código** (no la IA) — lo revisa en el paso 6. |
|
|
91
|
+
| **Herramienta** | `opsx:apply` (con la disciplina de `tdd`) |
|
|
92
92
|
| **Detalle →** | [`detalle/04-tdd.md`](detalle/04-tdd.md) |
|
|
93
93
|
|
|
94
94
|
#### 5. Smoke test de la US
|
|
@@ -108,9 +108,9 @@
|
|
|
108
108
|
|---|---|
|
|
109
109
|
| **Clásico** | Un compañero revisa el PR/MR antes de mergear. |
|
|
110
110
|
| **Dolor** | Depende de que el partner tenga tiempo y ganas; reviews superficiales que dejan pasar lo importante. |
|
|
111
|
-
| **Con IA** | La IA hace el **primer pase** (
|
|
111
|
+
| **Con IA** | La IA hace el **primer pase**: un **review inline** (corre `dai check` + valida el DoD, y deja un resumen + **un comentario por línea**, low/medium/high). Muestra el preview y **espera el OK del partner antes de postear**; el partner revisa lo que importa, no el ruido. |
|
|
112
112
|
| **Humano (HITL)** | El partner aprueba o rechaza. La IA sugiere; la persona decide y firma. |
|
|
113
|
-
| **Herramienta** | `dai-review` |
|
|
113
|
+
| **Herramienta** | `dai-review` (`dai forge review`) |
|
|
114
114
|
| **Detalle →** | [`detalle/06-code-review.md`](detalle/06-code-review.md) |
|
|
115
115
|
|
|
116
116
|
#### 7. Merge + trazabilidad automática
|
|
@@ -170,7 +170,7 @@
|
|
|
170
170
|
| 1 Refinamiento | ●●● | La US testeable es la base de todo. |
|
|
171
171
|
| 2 Planning | ●● | El design y las tareas se derivan de la US. |
|
|
172
172
|
| 3 Rama | ●●● | El link correcto por construcción. |
|
|
173
|
-
| 4
|
|
173
|
+
| 4 Implementación | ●●● | El agente construye con TDD; el corazón del anti vibe-coding. |
|
|
174
174
|
| 5 Smoke | ●● | Cierre verificable de la US. |
|
|
175
175
|
| 6 Code review | ●● | Primer pase automático, humano decide. |
|
|
176
176
|
| 7 Merge + trazabilidad | ●●● | La matriz se deriva sola. |
|
|
@@ -49,7 +49,7 @@ Pasar de distribuido a automático es mover la invocación, no reescribir nada.
|
|
|
49
49
|
|
|
50
50
|
## Consecuencias
|
|
51
51
|
|
|
52
|
-
- ✅ **No hace falta ningún CI para empezar.** La metodología
|
|
52
|
+
- ✅ **No hace falta ningún CI para empezar.** La metodología empieza con un dev
|
|
53
53
|
tipeando `dai check` / `dai stamp`. El [Art. 14](../MANIFIESTO.md#art-14) queda respetado.
|
|
54
54
|
- ✅ **Rampa de adopción continua:** manual → git-hook → CI, siempre el mismo comando.
|
|
55
55
|
- ✅ **Honra el [Art. 10](../MANIFIESTO.md#art-10):** el humano *dispara* la derivación; no *escribe a mano* el
|
|
@@ -20,7 +20,7 @@ más fuerte de eso es el **copyleft**: quien distribuya un `dai` modificado debe
|
|
|
20
20
|
publicar sus cambios bajo la misma licencia. La GPL convierte "las mejoras vuelven"
|
|
21
21
|
en cláusula, no en deseo.
|
|
22
22
|
|
|
23
|
-
El downside típico de la GPL **no aplica**
|
|
23
|
+
El downside típico de la GPL **no aplica** aquí: `dai` es un **CLI que se ejecuta**,
|
|
24
24
|
no una librería que se embebe. Usar `dai` sobre tu código —aunque sea propietario y
|
|
25
25
|
comercial— **no genera ninguna obligación**; el copyleft solo se activa si alguien
|
|
26
26
|
**forkea y redistribuye** una versión modificada. Y *libre ≠ gratis*: se puede
|
|
@@ -18,11 +18,17 @@ dueño ni gatekeeper de ellas.
|
|
|
18
18
|
|
|
19
19
|
## Decisión
|
|
20
20
|
|
|
21
|
-
Agregamos **`dai skills install --from <git-url|path>[#ref]`**: instala skills
|
|
22
|
-
**externas** desde un repo/dir (con estructura `skills/<nombre>/SKILL.md`, la misma
|
|
21
|
+
Agregamos **`dai skills install --from <git-url|npm:pkg|path>[#ref]`**: instala skills
|
|
22
|
+
**externas** desde un repo/dir/paquete (con estructura `skills/<nombre>/SKILL.md`, la misma
|
|
23
23
|
de dai), **convertidas para los 3 asistentes** (Claude copia · Cursor `skillToCursor`
|
|
24
24
|
· Copilot `skillToPrompt` → `.github/prompts/`).
|
|
25
25
|
|
|
26
|
+
- **Tres fuentes:** un **git URL** (`github.com/org/skills[#ref]` → clone), un **path
|
|
27
|
+
local**, o un **paquete npm** (`npm:@scope/pkg[@version]` → `npm pack` a un temp,
|
|
28
|
+
respetando el `.npmrc` del cwd, así resuelve registries privados con scope). Es común
|
|
29
|
+
distribuir skills como paquete npm (una org publica sus componentes + skills juntas);
|
|
30
|
+
materializarlo a mano era fricción de más.
|
|
31
|
+
|
|
26
32
|
- **`dai skills` es el namespace canónico** de las operaciones de skills, consistente
|
|
27
33
|
con `dai forge <verb>`. `dai skills install` (sin `--from`) instala las de dai;
|
|
28
34
|
**`dai install` queda como alias** silencioso (backward-compatible).
|
|
@@ -42,8 +48,9 @@ de dai), **convertidas para los 3 asistentes** (Claude copia · Cursor `skillToC
|
|
|
42
48
|
- **Se acepta pagar:** es **one-off** (dai no mantiene esas skills al día; re-corrés
|
|
43
49
|
`--from`). **Sin registro** → dai no sabe qué repos tienen skills externas, a
|
|
44
50
|
propósito: cero gatekeeping, bajo riesgo del equipo. Las fuentes remotas dependen de
|
|
45
|
-
git/red, y la **auth se delega en
|
|
46
|
-
|
|
51
|
+
git/red/npm, y la **auth se delega en la herramienta** (git: SSH o credential helper;
|
|
52
|
+
npm: el `.npmrc` del repo — dai no autentica): *si puedes `git clone` o `npm pack` la
|
|
53
|
+
fuente, dai instala desde ahí*.
|
|
47
54
|
|
|
48
55
|
## Alternativas consideradas
|
|
49
56
|
|
|
@@ -89,7 +89,7 @@ error de config más común. El mensaje da los dos caminos: `DAI_JIRA_PROJECT=PR
|
|
|
89
89
|
- **`dai doctor`** valida la clave de proyecto y que el archivo de campos parsee. Sigue
|
|
90
90
|
**sin** verificar que el token sirva — eso es red, y lo dice `dai publish`. El chequeo
|
|
91
91
|
ahora lo admite en voz alta en vez de dar un ✓ engañoso.
|
|
92
|
-
- **ClickUp queda con el mismo hueco de TLS.** `daiFetch` está listo para adoptarse
|
|
92
|
+
- **ClickUp queda con el mismo hueco de TLS.** `daiFetch` está listo para adoptarse allí
|
|
93
93
|
con un import; no lo hicimos ahora por alcance.
|
|
94
94
|
|
|
95
95
|
## Alternativas descartadas
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
# ADR-0017 — La config de dai vive en `.env.dai`, no en el `.env` del equipo
|
|
2
|
+
|
|
3
|
+
- **Estado:** aceptado
|
|
4
|
+
- **Fecha:** 2026-07-18
|
|
5
|
+
- **Decide:** lead / arquitecto de la metodología
|
|
6
|
+
|
|
7
|
+
## Contexto
|
|
8
|
+
|
|
9
|
+
dai guarda su config y sus secretos (token del tracker, email, plantilla de URL) en
|
|
10
|
+
variables de entorno, y hasta ahora las escribía en el `.env` del repo, con la premisa de
|
|
11
|
+
que ese `.env` está **gitignored** (por eso `dai init` lo agregaba al `.gitignore` y el
|
|
12
|
+
loader avisaba "NUNCA commitees tokens").
|
|
13
|
+
|
|
14
|
+
Esa premisa se rompe en muchas empresas: **versionan el `.env`** como política (mismas
|
|
15
|
+
variables públicas para todo el equipo y el CI). Pasó de verdad en un repo de frontend
|
|
16
|
+
corporativo: el `.env` estaba trackeado con `VITE_*` públicas, y `dai init`
|
|
17
|
+
|
|
18
|
+
1. le **inyectaba** sus claves `DAI_*` a un archivo compartido del equipo, y
|
|
19
|
+
2. le agregaba `.env` al `.gitignore` — inútil, porque git no ignora un archivo ya
|
|
20
|
+
trackeado, y encima confuso (parece que lo protege y no lo hace).
|
|
21
|
+
|
|
22
|
+
El día que un dev completara `DAI_JIRA_TOKEN` en ese `.env` versionado, git lo marcaba
|
|
23
|
+
para commit: **un secreto a un empujón de filtrarse** al historial del repo corporativo.
|
|
24
|
+
|
|
25
|
+
## Decisión
|
|
26
|
+
|
|
27
|
+
dai deja de tocar el `.env` del equipo. Toda su config vive en archivos **propios**:
|
|
28
|
+
|
|
29
|
+
| Archivo | Versionado | Quién lo maneja | Contenido |
|
|
30
|
+
|---|---|---|---|
|
|
31
|
+
| `.env` | según el equipo | el equipo | dai **no lo escribe**; solo lo **lee** (compat) |
|
|
32
|
+
| `.env.dai` | **no** (gitignored) | cada dev | config + secretos de dai (token, email) |
|
|
33
|
+
| `.env.dai.example` | sí | dai / el equipo | plantilla: mismas claves, valores vacíos |
|
|
34
|
+
|
|
35
|
+
- **`dai init`** crea `.env.dai` (real, ignorado) y `.env.dai.example` (plantilla
|
|
36
|
+
versionada), de forma aditiva, y **nunca** modifica `.env`/`.env.example`.
|
|
37
|
+
- **`reconcileGitignore`** ignora `.env.dai` (su archivo), **no** `.env`: el `.env` del
|
|
38
|
+
equipo es del equipo, y muchas orgs lo versionan a propósito. `.env.dai.example` no
|
|
39
|
+
matchea el patrón exacto `.env.dai`, así que se versiona sin negación extra.
|
|
40
|
+
- **El loader** (`loadDaiEnv`) lee `.env.dai` **y** `.env`. Precedencia:
|
|
41
|
+
**entorno (shell/CI) > `.env.dai` > `.env`**. Se logra cargando `.env.dai` primero,
|
|
42
|
+
porque el loader es "primero-gana". Seguir leyendo `.env` mantiene compatibilidad con
|
|
43
|
+
repos previos que tienen los `DAI_*` ahí — no se rompe nada.
|
|
44
|
+
|
|
45
|
+
## Consecuencias
|
|
46
|
+
|
|
47
|
+
- **A favor:** dai no ensucia ni pone en riesgo un archivo compartido del equipo. El
|
|
48
|
+
secreto vive en un archivo que git ignora de verdad (no trackeado). Funciona igual en
|
|
49
|
+
equipos que versionan el `.env` y en los que no. Los repos viejos siguen andando (se
|
|
50
|
+
lee `.env`).
|
|
51
|
+
- **En contra:** una convención más de archivos (`.env.dai`, `.env.dai.example`) que
|
|
52
|
+
documentar. Un repo que ya tenía `DAI_*` en un `.env` gitignored puede migrarlos a
|
|
53
|
+
`.env.dai` cuando quiera; no es urgente, porque el loader sigue leyendo `.env`.
|
|
54
|
+
- **Vite:** el nombre `.env.dai` solo lo cargaría Vite con `vite --mode dai` (raro), y
|
|
55
|
+
las claves de dai no llevan prefijo `VITE_`, así que nunca van al bundle del cliente.
|
|
56
|
+
|
|
57
|
+
## Alternativas descartadas
|
|
58
|
+
|
|
59
|
+
- **Destrackear el `.env`** (`git rm --cached`): rompe la convención del equipo y les saca
|
|
60
|
+
del control de versiones las `VITE_*` públicas que comparten a propósito.
|
|
61
|
+
- **Secreto solo por variable de shell:** anda hoy (el loader no pisa el entorno), pero
|
|
62
|
+
obliga a `source` en cada sesión: fricción para todo el equipo, sin plantilla que guíe.
|
|
63
|
+
- **Seguir usando `.env` y forzar el `.gitignore`:** es justo lo que fallaba — inerte
|
|
64
|
+
sobre un archivo ya trackeado, y peligroso el día que alguien escribe el token.
|
package/docs/adr/README.md
CHANGED
|
@@ -22,6 +22,7 @@ decisión cambia, se escribe un ADR nuevo que supersede al viejo. Molde en
|
|
|
22
22
|
| [0014](0014-copilot-agent-skills.md) | Copilot lee `SKILL.md` nativo (Agent Skills): se elimina el adaptador `.prompt.md` — modifica la 0002 | aceptado |
|
|
23
23
|
| [0015](0015-jira-corporativo.md) | `dai publish` en Jira corporativo: campos propios declarados, `--parent`/`--issuetype`, TLS con CA (nunca apagar la verificación) | aceptado |
|
|
24
24
|
| [0016](0016-review-inline.md) | Review inline: `review.json` como contrato y puerta humana, el CLI valida las posiciones contra el diff, `--yes` explícito, nunca `APPROVE` | aceptado |
|
|
25
|
+
| [0017](0017-env-dai.md) | La config de dai vive en `.env.dai` (no versionado), no en el `.env` del equipo; el loader lee ambos con precedencia shell > `.env.dai` > `.env` | aceptado |
|
|
25
26
|
|
|
26
27
|
> Estas son las decisiones que cierran las "Decisiones abiertas" de
|
|
27
28
|
> [`METODOLOGIA.md §7`](../METODOLOGIA.md) y las enmiendas al
|
|
@@ -7,17 +7,18 @@
|
|
|
7
7
|
El PO llega con una idea (a veces un ticket de una línea). Antes de escribir specs,
|
|
8
8
|
la IA hace dos cosas, en orden:
|
|
9
9
|
|
|
10
|
-
1. **
|
|
11
|
-
`a-spec` (seguir), `reframe` (el problema real es otro) o `descartar` (no vale la
|
|
12
|
-
pena ahora). Un "no lo construyas" es un éxito del gate, no una falla.
|
|
13
|
-
2. **Pulido** (`grill-user-story`) — interroga hasta que la US es **testeable por
|
|
10
|
+
1. **Pulido** (`grill-user-story`) — interroga hasta que la US es **testeable por
|
|
14
11
|
construcción** (INVEST + Gherkin) y la publica en el tracker.
|
|
12
|
+
2. **Gate 0** (`grill-intent`) — con la US ya formada, desafía el *problema* detrás
|
|
13
|
+
(no la solución). Veredicto: `a-spec` (seguir), `reframe` (el problema real es otro)
|
|
14
|
+
o `descartar` (no vale la pena ahora). Un "no lo construyas" es un éxito del gate,
|
|
15
|
+
no una falla.
|
|
15
16
|
|
|
16
17
|
## Herramientas
|
|
17
18
|
|
|
18
|
-
- `/grill-intent` → `openspec/intents/<fecha-slug>/intent.md`
|
|
19
19
|
- `/grill-user-story` → US en formato [`formato-us.md`](../../templates/formato-us.md),
|
|
20
20
|
publicada en Jira/ClickUp (o `.md` de fallback).
|
|
21
|
+
- `/grill-intent` → `openspec/intents/<fecha-slug>/intent.md`
|
|
21
22
|
- Gate de entrada: [`definition-of-ready.md`](../../templates/definition-of-ready.md).
|
|
22
23
|
|
|
23
24
|
## Qué firma el humano
|
package/docs/detalle/03-ramas.md
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
|
|
5
5
|
## En qué consiste en detalle
|
|
6
6
|
|
|
7
|
-
El dev
|
|
7
|
+
El dev empieza la implementación **atándola al QUÉ**: la branch y el `implements.yaml`
|
|
8
8
|
salen del mismo ID del tracker, así el link no puede quedar mal tipeado.
|
|
9
9
|
|
|
10
10
|
## Herramientas
|
|
@@ -21,7 +21,7 @@ dai link-us ABC-482 --us us.md
|
|
|
21
21
|
|
|
22
22
|
## Qué firma el humano
|
|
23
23
|
|
|
24
|
-
El dev **elige qué US
|
|
24
|
+
El dev **elige qué US toma**. El resto es mecánico y determinista (el CLI), no
|
|
25
25
|
criterio humano — por eso el key **no se tipea a mano** ([Art. 8](../MANIFIESTO.md#art-8), Art. 9).
|
|
26
26
|
|
|
27
27
|
## Antipatrones
|