@dforce2055/dai 0.1.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.
Files changed (81) hide show
  1. package/.env.example +30 -0
  2. package/CHANGELOG.md +46 -0
  3. package/CODE_OF_CONDUCT.md +37 -0
  4. package/CONTRIBUTING.md +66 -0
  5. package/LICENSE +674 -0
  6. package/README.md +288 -0
  7. package/SECURITY.md +37 -0
  8. package/VERSION +1 -0
  9. package/cli/dai.mjs +692 -0
  10. package/cli/lib/ac-hash.mjs +74 -0
  11. package/cli/lib/args.mjs +23 -0
  12. package/cli/lib/bootstrap.mjs +74 -0
  13. package/cli/lib/env.mjs +23 -0
  14. package/cli/lib/forge-api.mjs +96 -0
  15. package/cli/lib/forge-url.mjs +61 -0
  16. package/cli/lib/fsutil.mjs +24 -0
  17. package/cli/lib/implements.mjs +94 -0
  18. package/cli/lib/link-us.mjs +59 -0
  19. package/cli/lib/pm-adapter.mjs +59 -0
  20. package/cli/lib/pm-clickup.mjs +54 -0
  21. package/cli/lib/pm-jira.mjs +123 -0
  22. package/cli/lib/pr.mjs +53 -0
  23. package/cli/lib/us.mjs +36 -0
  24. package/docs/EJEMPLO-END-TO-END.md +330 -0
  25. package/docs/MANIFIESTO.md +114 -0
  26. package/docs/METODOLOGIA.md +254 -0
  27. package/docs/PROBAR.md +91 -0
  28. package/docs/SCRUM-CON-IA.md +190 -0
  29. package/docs/adr/0001-contrato-ac-hash.md +86 -0
  30. package/docs/adr/0002-agnostico-del-asistente.md +87 -0
  31. package/docs/adr/0003-deteccion-y-estampado-son-comandos.md +73 -0
  32. package/docs/adr/0004-ubicacion-y-schema-implements.md +94 -0
  33. package/docs/adr/0005-superficie-comandos-y-stamp.md +65 -0
  34. package/docs/adr/0006-distribucion-y-licencia.md +59 -0
  35. package/docs/adr/0007-modelo-de-autenticacion.md +63 -0
  36. package/docs/adr/README.md +19 -0
  37. package/docs/detalle/01-refinamiento.md +33 -0
  38. package/docs/detalle/02-planning.md +27 -0
  39. package/docs/detalle/03-ramas.md +32 -0
  40. package/docs/detalle/04-tdd.md +35 -0
  41. package/docs/detalle/05-smoke.md +32 -0
  42. package/docs/detalle/06-code-review.md +34 -0
  43. package/docs/detalle/07-merge-trazabilidad.md +33 -0
  44. package/docs/detalle/08-daily.md +29 -0
  45. package/docs/detalle/09-review.md +25 -0
  46. package/docs/detalle/10-retro.md +27 -0
  47. package/docs/detalle/README.md +20 -0
  48. package/docs/glosario.md +79 -0
  49. package/docs/guias/dev.md +66 -0
  50. package/docs/guias/lead.md +53 -0
  51. package/docs/guias/po.md +50 -0
  52. package/governance/branch-naming.md +36 -0
  53. package/governance/ci-rules.md +57 -0
  54. package/governance/commit-convention.md +76 -0
  55. package/index.html +479 -0
  56. package/install.sh +19 -0
  57. package/manifest.yaml +76 -0
  58. package/package.json +55 -0
  59. package/skills/dai-review/SKILL.md +78 -0
  60. package/skills/doc-to-backlog/SKILL.md +70 -0
  61. package/skills/doc-to-backlog/templates/backlog-candidato.md +49 -0
  62. package/skills/grill-epic/SKILL.md +76 -0
  63. package/skills/grill-intent/SKILL.md +43 -0
  64. package/skills/grill-intent/templates/intent.md +36 -0
  65. package/skills/grill-user-story/SKILL.md +76 -0
  66. package/skills/grill-user-story/templates/user-story.md +61 -0
  67. package/skills/link-us/SKILL.md +42 -0
  68. package/skills/link-us/templates/implements.yaml +16 -0
  69. package/skills/tdd/SKILL.md +109 -0
  70. package/skills/tdd/deep-modules.md +33 -0
  71. package/skills/tdd/interface-design.md +31 -0
  72. package/skills/tdd/mocking.md +59 -0
  73. package/skills/tdd/refactoring.md +10 -0
  74. package/skills/tdd/tests.md +61 -0
  75. package/templates/adr.md +43 -0
  76. package/templates/commit-msg +48 -0
  77. package/templates/definition-of-done.md +50 -0
  78. package/templates/definition-of-ready.md +51 -0
  79. package/templates/epica.md +62 -0
  80. package/templates/formato-us.md +129 -0
  81. package/templates/pull-request.md +62 -0
@@ -0,0 +1,87 @@
1
+ # ADR-0002 — La metodología es agnóstica del asistente de IA
2
+
3
+ - **Estado:** aceptado
4
+ - **Fecha:** 2026-07-03
5
+ - **Decide:** lead / arquitecto de la metodología
6
+
7
+ ## Contexto
8
+
9
+ Las skills están hoy empaquetadas como **skills de Claude Code** (`SKILL.md` en
10
+ `.claude/skills/`). Pero los equipos usan asistentes distintos: una organización usa
11
+ **GitHub Copilot** (nadie usa Claude), otra usa **Claude Code**. Si atamos la
12
+ metodología a un asistente, dejamos afuera a media empresa — y contradecimos el
13
+ principio rector "sin importar la herramienta de abajo" ([Art. 2](../MANIFIESTO.md#art-2)), que ya aplicamos a
14
+ las herramientas de spec (OpenSpec/Swagger/yml). Falta aplicarlo **una capa más
15
+ arriba**: el asistente de IA.
16
+
17
+ ## Decisión
18
+
19
+ Aplicamos el mismo principio al asistente. Una "skill" se separa en tres capas:
20
+
21
+ 1. **Contenido portable** — la lógica de interrogación, el formato, los cortes. Se
22
+ escribe **una sola vez**, neutral al asistente. Es la fuente de verdad.
23
+ 2. **Acciones deterministas = CLI `dai`** — todo lo mecánico (crear rama,
24
+ generar `implements.yaml`, calcular `ac_hash`, indexar cobertura) vive en el
25
+ **CLI**, no en la inteligencia del asistente. `dai link-us ABC-###` anda igual
26
+ con Claude, con Copilot, o sin ningún asistente. Es la forma más agnóstica de
27
+ garantizar comportamiento determinista: el asistente solo lo **invoca**.
28
+ 3. **Adaptadores por asistente (delgados, generados)** — de la Capa 1 se emiten los
29
+ wrappers finos de cada asistente:
30
+ - **Claude Code** → `SKILL.md` en `.claude/skills/`.
31
+ - **Copilot** → `.github/prompts/*.prompt.md` + `.github/copilot-instructions.md`
32
+ (este último auto-inyecta el manifiesto en cada chat del repo).
33
+
34
+ El instalador elige el target: `dai init --for claude` | `--for copilot` | `--for both`.
35
+ Mismo método, misma CLI, distinto wrapper. **`--for` es aditivo, no destructivo**: los
36
+ adaptadores coexisten en el mismo repo (viven en carpetas distintas —
37
+ `.claude/skills/` y `.github/prompts/`— y no se pisan). Un equipo mixto (unos con
38
+ Copilot, otros con Claude) versiona los dos y cada quien usa el suyo. Como lo mecánico
39
+ vive en el CLI, el **output es idéntico** sin importar qué asistente lo disparó: misma
40
+ rama, mismo `implements.yaml`, mismo `ac_hash`. El repo queda consistente aunque el
41
+ equipo esté mezclado.
42
+
43
+ | Capacidad | Naturaleza | Claude Code | Copilot |
44
+ |---|---|---|---|
45
+ | `grill-intent`, `grill-user-story` | interrogación (prompt puro) | `SKILL.md` | `*.prompt.md` |
46
+ | `link-us`, `ac-hash`, `coverage` | acción mecánica | wrapper → `dai <cmd>` | prompt/CLI → `dai <cmd>` |
47
+ | el manifiesto y las reglas | contexto siempre presente | `CLAUDE.md` / `project.md` | `.github/copilot-instructions.md` |
48
+
49
+ ## Consecuencias
50
+
51
+ - ✅ La misma metodología corre en una organización con Copilot y en una factory con
52
+ Claude — "un protocolo, distinta plomería" aplicado al asistente.
53
+ - ✅ Lo mecánico se vuelve **más confiable**: un CLI determinista no alucina.
54
+ - ✅ Los docs (`MANIFIESTO`, `METODOLOGIA`, guías, glosario) ya eran 100% agnósticos:
55
+ la dualidad solo toca la capa `skills/`.
56
+ - ⚠️ Hay que **construir el CLI `dai`** con los subcomandos mecánicos (hoy esa lógica
57
+ está descrita dentro de las skills de Claude). Es trabajo nuevo.
58
+ - ⚠️ Las capacidades de agente difieren: los prompts puros portan limpio; las
59
+ acciones se apoyan en el CLI. Copilot en modo agente puede correr el CLI; en modo
60
+ chat, el dev lo corre a mano.
61
+ - ⚠️ **Límite de superficie de Copilot (verificado):** los `.github/prompts/*.prompt.md`
62
+ se invocan **solo en VS Code / Visual Studio / JetBrains** (o, como custom agents, en
63
+ el **Copilot CLI**). **No** en la app standalone de Copilot ni en el chat de
64
+ github.com. Claude, en cambio, lee `~/.claude/skills/` tanto en **Claude Code** como
65
+ en **Claude Desktop**. Consecuencia: el analista funcional "sin IDE" cierra con Claude
66
+ Desktop; con Copilot necesita VS Code o el Copilot CLI. Es un límite de Copilot, no de
67
+ dai — el CLI `dai` corre igual en cualquier terminal.
68
+ - ⚠️ Los wrappers se **generan**, no se mantienen a mano — si no, se desincronizan (la misma
69
+ regla de oro del link).
70
+
71
+ **Estado de implementación:** `dai init` es un **scaffolder interactivo** (estilo
72
+ `create-vue`): pregunta asistente (`--for claude|copilot|both`) y gestor
73
+ (`--pm md|clickup|jira`), genera los adaptadores (`.claude/skills/` + `CLAUDE.md`;
74
+ `.github/prompts/*.prompt.md` + `.github/copilot-instructions.md`, transformando los
75
+ `SKILL.md` con `cli/lib/bootstrap.mjs`), deja un `.env` configurado, y cierra con
76
+ próximos pasos. **OpenSpec:** se detecta; si falta, se **ofrece instalarlo**
77
+ (`npm i -g @fission-ai/openspec@latest` + `openspec init`) — no se bundlea (Art. 2).
78
+ Con flags o sin TTY corre no-interactivo (defaults `both`/`md`, OpenSpec solo con `--openspec`).
79
+
80
+ ## Alternativas consideradas
81
+
82
+ - **Mantener skills separadas por asistente a mano** — descartado: desincronización garantizada
83
+ al primer cambio (viola Art. 9/Art. 10 aplicados al propio paquete).
84
+ - **Atarse solo a Claude** — descartado: deja afuera a la organización que usa
85
+ Copilot, que es justo uno de los dos casos que el método debe soportar.
86
+ - **Meter toda la lógica mecánica en el asistente (sin CLI)** — descartado: no es
87
+ portable y es menos confiable (el asistente puede alucinar un paso determinista).
@@ -0,0 +1,73 @@
1
+ # ADR-0003 — La detección y el estampado son comandos, no infraestructura
2
+
3
+ - **Estado:** aceptado
4
+ - **Fecha:** 2026-07-03
5
+ - **Decide:** lead / arquitecto de la metodología
6
+
7
+ ## Contexto
8
+
9
+ El ADR-0001 dice que la **autoridad** de la detección de atrasos es "el CI, que
10
+ re-deriva el `ac_hash` de la US viva y compara". Leído literal, suena a que hace
11
+ falta **montar un CI que corra del lado de Jira/ClickUp** antes de poder usar la
12
+ metodología — infraestructura pesada, y una barrera de entrada que contradice el
13
+ [Art. 14](../MANIFIESTO.md#art-14) (*no adelantar complejidad*).
14
+
15
+ Además, un equipo que ya está en escala N3 (organización grande federada; los niveles
16
+ N1/N2/N3 están en el [glosario](../glosario.md)) puede **no tener** todavía esa
17
+ automatización. La trazabilidad federada tiene que funcionar igual, de forma
18
+ **distribuida**, sin depender de que exista un pipeline corriendo.
19
+
20
+ El malentendido está en la palabra "CI". Jira/ClickUp **no ejecutan** nada: solo
21
+ **guardan** la US. La detección es comparar dos hashes — eso es un **comando**, no
22
+ un servidor.
23
+
24
+ ## Decisión
25
+
26
+ La trazabilidad se expone como **comandos del CLI `dai`**, invocables por un humano
27
+ o por un CI indistintamente (mismo binario, mismo output — ADR-0002):
28
+
29
+ | Comando | Naturaleza | Qué hace |
30
+ |---|---|---|
31
+ | `dai ac-hash <us>` | puro | calcula el hash de los criterios (ADR-0001). |
32
+ | `dai check` | **read-only** | lee el `implements.yaml` del repo + la US viva, re-deriva el hash y **compara**. Reporta al día / ⚠️ atrasado. Exit code ≠ 0 si hay atraso → sirve de **gate de PR**. **No escribe nada.** |
33
+ | `dai stamp` | **write** | calcula la cobertura derivada y la **escribe en el tracker** (la trazabilidad inversa del Art. 10: "`<repo>` @ `<version>` ✅/⚠️"). Requiere token de escritura. |
34
+
35
+ **El tracker solo almacena y sirve la US.** La lógica corre donde se invoca el
36
+ comando: la máquina del dev, un git-hook, o un pipeline.
37
+
38
+ ### Modo distribuido (sin infraestructura) vs automático
39
+
40
+ - **Distribuido (default, N1–N2 y N3 sin CI):** el dev corre `dai check` cuando
41
+ quiere saber si está atrasado, y `dai stamp` después de mergear para publicar su
42
+ cobertura. **Cero infraestructura nueva.** Depende de disciplina (alguien tiene
43
+ que correr `dai stamp`), mitigable con un git-hook local.
44
+ - **Automático (N3 maduro):** el CI que la organización **ya tiene** corre
45
+ `dai check` como gate y `dai stamp` al mergear. La automatización es, literalmente,
46
+ *"correr los mismos comandos en un hook"* — no hay un código distinto.
47
+
48
+ Pasar de distribuido a automático es mover la invocación, no reescribir nada.
49
+
50
+ ## Consecuencias
51
+
52
+ - ✅ **No hace falta ningún CI para empezar.** La metodología arranca con un dev
53
+ tipeando `dai check` / `dai stamp`. El [Art. 14](../MANIFIESTO.md#art-14) queda respetado.
54
+ - ✅ **Rampa de adopción continua:** manual → git-hook → CI, siempre el mismo comando.
55
+ - ✅ **Honra el [Art. 10](../MANIFIESTO.md#art-10):** el humano *dispara* la derivación; no *escribe a mano* el
56
+ contenido (eso sigue prohibido). Un `dai stamp` corrido por una persona escribe lo
57
+ mismo que uno corrido por el CI.
58
+ - ✅ Un equipo N3 sin pipeline tiene trazabilidad federada **distribuida** ya mismo.
59
+ - ⚠️ En modo distribuido, `dai stamp` depende de que alguien lo corra. `dai check`
60
+ como git-hook o gate de PR reduce el riesgo de olvido.
61
+ - ⚠️ Ambos comandos necesitan **leer** la US viva (y `dai stamp`, escribir): eso es el
62
+ adaptador de PM (Jira/ClickUp/`.md`), ya implementado en `getAdapter`. Es un token +
63
+ llamadas HTTP, **no** un CI.
64
+
65
+ ## Alternativas consideradas
66
+
67
+ - **Exigir un CI corriendo en Jira/ClickUp** — descartado: barrera de entrada que
68
+ contradice el [Art. 14](../MANIFIESTO.md#art-14) y que además es un fantasma (el tracker no ejecuta nada).
69
+ - **Estampar la cobertura a mano en el tracker** — descartado: viola el [Art. 10](../MANIFIESTO.md#art-10) (el
70
+ contenido debe derivarse, no escribirse a mano) y se desincroniza.
71
+ - **Un solo comando que compare y escriba a la vez** — descartado: separar `check`
72
+ (read-only, gate) de `stamp` (write) permite usar `check` como gate de PR sin
73
+ permisos de escritura, y correr `stamp` solo cuando corresponde.
@@ -0,0 +1,94 @@
1
+ # ADR-0004 — Ubicación y schema del `implements.yaml`
2
+
3
+ - **Estado:** aceptado
4
+ - **Fecha:** 2026-07-03
5
+ - **Decide:** lead / arquitecto de la metodología
6
+
7
+ ## Contexto
8
+
9
+ El `implements.yaml` es el **único registro autorado** del link QUÉ↔CÓMO ([Art. 9](../MANIFIESTO.md#art-9)).
10
+ Para que `link-us` lo scaffoldee y `dai check`/`stamp` lo parseen, hay que congelar
11
+ **dónde vive** y **qué campos tiene**. Cierra la decisión abierta de METODOLOGIA §7 sobre el formato del link.
12
+
13
+ Dos requisitos duros (Art. 9): vive **en el repo de código** y está **versionado por
14
+ git** — así el `ac_hash` estampado viaja con el commit y el link es revisable en el PR.
15
+
16
+ ## Decisión
17
+
18
+ ### Ubicación
19
+
20
+ - **Co-localizado con la unidad de trabajo** (una US = una capacidad entera = un
21
+ `implements.yaml`). Default usando OpenSpec: `openspec/changes/<change-id>/implements.yaml`.
22
+
23
+ El `implements.yaml` vive **junto a los artefactos de OpenSpec** del change, no aparte:
24
+
25
+ ```
26
+ openspec/
27
+ └── changes/
28
+ └── finalizar-compra/ # el change = el CÓMO (una US = una capacidad entera)
29
+ ├── proposal.md # opsx:propose · qué se propone y por qué
30
+ ├── design.md # opsx:propose · el diseño técnico
31
+ ├── tasks.md # opsx:propose · las tareas (se implementan con TDD)
32
+ ├── specs/ # opsx:propose · las deltas de spec
33
+ │ └── carrito/
34
+ │ └── spec.md
35
+ └── implements.yaml # ★ dai link-us · el link QUÉ↔CÓMO (id + @version + ac_hash)
36
+ ```
37
+
38
+ Los tres primeros los genera **OpenSpec** (`opsx:propose`); el `implements.yaml` lo agrega
39
+ **dai** (`link-us`) en la misma carpeta. Al archivar, el change entero (incluido el
40
+ `implements.yaml`) se mueve a `openspec/changes/archive/` y **sigue contando** para la cobertura.
41
+
42
+ - **Tool-agnóstico por descubrimiento (Art. 2):** `dai` **no** hardcodea la ruta de
43
+ OpenSpec. Hace un glob de `**/implements.yaml` (excluyendo `node_modules`, `dist`,
44
+ etc.). Un equipo con Swagger u otra herramienta lo pone donde quiera y `dai` lo
45
+ encuentra.
46
+ - **Incluye archivados:** el glob abarca `openspec/changes/archive/**` — un change
47
+ archivado sigue vivo en el código, así que **cuenta** para la cobertura.
48
+ - **La lista de "qué implementa el repo" es derivada**, no un manifiesto a mano: se
49
+ arma escaneando los `implements.yaml` co-localizados (Art. 10).
50
+
51
+ ### Schema
52
+
53
+ ```yaml
54
+ change: finalizar-compra # identidad del CÓMO (nombre local del change/spec).
55
+ # Explícito, NO derivado del path → sobrevive al archivado.
56
+ repo: frontend # repo donde vive.
57
+
58
+ implements: # FORWARD: qué QUÉ cumple este change (capacidad entera).
59
+ - id: ABC-482 # ticket de Jira/ClickUp (identidad del QUÉ). No se tipea: lo pone link-us.
60
+ version: v1 # spec_version de la US al implementar (nº legible).
61
+ ac_hash: 7f3a9c2e # snapshot del hash de criterios (lo calcula `dai ac-hash`).
62
+
63
+ introduces: # specs técnicas nuevas que crea este change (opcional).
64
+ - guard-carrito-vacio
65
+
66
+ autor: D. Force (dev) # quién implementa.
67
+ ```
68
+
69
+ - `change` y `repo` son obligatorios y hacen el registro **auto-contenido**: `dai stamp`
70
+ puede reportar "ABC-482 ← frontend/finalizar-compra @v1" sin parsear rutas.
71
+ - `implements` es una lista (un change podría cumplir más de un QUÉ, aunque el default
72
+ es uno — capacidad entera, §2.6).
73
+ - El link es **dirigido CÓMO→QUÉ**; la inversa (QUÉ→CÓMO en Jira) la deriva `dai stamp`.
74
+
75
+ ## Consecuencias
76
+
77
+ - ✅ `link-us` tiene molde exacto para generar; `check`/`stamp` tienen contrato para
78
+ parsear.
79
+ - ✅ Registro auto-contenido → robusto al archivado y a mover carpetas.
80
+ - ✅ Independiente de OpenSpec: la ubicación es convención, el descubrimiento es glob.
81
+ - ⚠️ El glob debe excluir directorios ruidosos (`node_modules`, `dist`, `vendor`) para no
82
+ escanear de más.
83
+ - ⚠️ Si un repo tuviera dos `implements.yaml` con el mismo `change`, es un error a
84
+ detectar (identidad duplicada).
85
+
86
+ ## Alternativas consideradas
87
+
88
+ - **Un manifiesto único en la raíz (`.dai/implements.yaml`)** — descartado: archivo
89
+ compartido que todos editan (conflictos de merge), y pierde la co-localización que
90
+ hace el diff del PR revisable.
91
+ - **Derivar la identidad del CÓMO del path de la carpeta** — descartado: se rompe al
92
+ archivar/mover; mejor un campo `change` explícito.
93
+ - **Registrar el mapping también a mano en Jira** — descartado: sería un tercer
94
+ registro que se desincroniza; la inversa se deriva (Art. 10).
@@ -0,0 +1,65 @@
1
+ # ADR-0005 — Superficie de comandos del CLI y contenido del stamp
2
+
3
+ - **Estado:** aceptado
4
+ - **Fecha:** 2026-07-03
5
+ - **Decide:** lead / arquitecto de la metodología
6
+
7
+ ## Contexto
8
+
9
+ Los ADR-0001/0003/0004 definieron el hash, el modelo de detección y el schema del
10
+ `implements.yaml`. Falta congelar **qué comandos** expone `dai` para la trazabilidad
11
+ y **qué estampa** exactamente `dai stamp` en el tracker (que es el router de Nivel-1,
12
+ §2.5, y por lo tanto debe llevar links a la implementación).
13
+
14
+ ## Decisión
15
+
16
+ ### Superficie de comandos de trazabilidad
17
+
18
+ | Comando | Acceso | Qué hace |
19
+ |---|---|---|
20
+ | `dai ac-hash <us>` | local | calcula el hash de criterios (ADR-0001). |
21
+ | `dai ls [--json]` | **local, offline** | escanea `**/implements.yaml`, lista las US que implementa el repo + su link al tracker. Base de los otros dos. |
22
+ | `dai check` | lee la US viva | `ls` + trae la US + compara hashes → al día / ⚠️ atrasado. Exit ≠ 0 si atraso (gate de PR). |
23
+ | `dai stamp` | escribe al tracker | `ls` + trae la US + **escribe la cobertura** (inversa, [Art. 10](../MANIFIESTO.md#art-10)). |
24
+
25
+ `check` y `stamp` se construyen sobre `ls` (un solo lugar descubre y parsea).
26
+
27
+ ### Contenido del stamp (el router necesita links)
28
+
29
+ `dai stamp` escribe en el ticket, por cada repo/change que lo implementa:
30
+
31
+ ```
32
+ repo: <nombre> → <repo web url>
33
+ branch: <branch> → <branch url> ← link principal (legible)
34
+ commit: <sha> → <commit url> ← ANCLA durable (sobrevive al borrado de branch)
35
+ version: <v> (<ac_hash>) → ✅ al día | ⚠️ atrasado
36
+ autor: <dev>
37
+ ```
38
+
39
+ **Los links se derivan de git, sin API del forge ni `--pr`:**
40
+ - repo/branch/commit salen de `git remote get-url origin` + `git rev-parse`.
41
+ - La URL web es **específica del forge** (GitHub `/tree/` `/commit/`; GitLab `/-/tree/`
42
+ `/-/commit/`; Bitbucket `/src/` `/commits/`): `dai` mapea forge→esquema por el host
43
+ del remoto.
44
+
45
+ **Branch + commit-ancla:** la branch es el link legible, pero se borra al mergear; el
46
+ commit es permanente. Guardar los dos evita que el router quede en 404.
47
+
48
+ ## Consecuencias
49
+
50
+ - ✅ Trazabilidad completa sin API del forge ni flags manuales: todo se deriva de git.
51
+ - ✅ El router (§2.5) siempre tiene un link vivo (el commit) → nunca dead-link.
52
+ - ✅ `dai ls` es offline y read-only → sirve de base barata para todo lo demás.
53
+ - ⚠️ Construir la URL web es forge-específico → lógica a testear (SSH/HTTPS, 3 forges).
54
+ - ⚠️ `dai stamp` (write) y `dai check` (read US viva) dependen del **adaptador de PM**
55
+ (`getAdapter`, ya implementado). Para el backend `md`, `stamp --format md` emite el bloque para
56
+ pegar a mano (mismo fallback que `grill-user-story`).
57
+
58
+ ## Alternativas consideradas
59
+
60
+ - **Link a la PR/MR** — descartado: no es derivable localmente sin API del forge, y en
61
+ modo distribuido genera fricción (`--pr`). La branch+commit se derivan de git solo.
62
+ - **Solo la branch** — descartado: la branch se borra al mergear → 404. El commit es la
63
+ ancla durable.
64
+ - **Solo el commit** — viable pero menos legible; la branch le da contexto humano.
65
+ Guardamos los dos.
@@ -0,0 +1,59 @@
1
+ # ADR-0006 — Distribución y licencia
2
+
3
+ - **Estado:** aceptado
4
+ - **Fecha:** 2026-07-03
5
+ - **Decide:** autor / mantenedor
6
+
7
+ ## Contexto
8
+
9
+ `dai` va a distribuirse para que **la comunidad lo use y lo mejore**. Hay que fijar
10
+ dos cosas: bajo qué **licencia** se libera, y por qué **canales** se distribuye. El
11
+ CLI es Node **cero dependencias**, lo que abre canales que no todos los proyectos
12
+ tienen (correr sin `npm install`).
13
+
14
+ ## Decisión
15
+
16
+ ### Licencia: GPLv3 (`GPL-3.0-or-later`)
17
+
18
+ El objetivo es *libre + que la comunidad ayude a mejorarla*. La garantía **legal**
19
+ más fuerte de eso es el **copyleft**: quien distribuya un `dai` modificado debe
20
+ publicar sus cambios bajo la misma licencia. La GPL convierte "las mejoras vuelven"
21
+ en cláusula, no en deseo.
22
+
23
+ El downside típico de la GPL **no aplica** acá: `dai` es un **CLI que se ejecuta**,
24
+ no una librería que se embebe. Usar `dai` sobre tu código —aunque sea propietario y
25
+ comercial— **no genera ninguna obligación**; el copyleft solo se activa si alguien
26
+ **forkea y redistribuye** una versión modificada. Y *libre ≠ gratis*: se puede
27
+ cobrar por uso, soporte o desarrollo sobre `dai`.
28
+
29
+ - SPDX: **`GPL-3.0-or-later`** (recomendación FSF: "v3 o posterior"). Si se prefiere
30
+ fijar solo v3, cambiar a `GPL-3.0-only`.
31
+ - El texto íntegro va en `LICENSE` (copia verbatim de gnu.org).
32
+ - Los **docs/metodología** quedan cubiertos por la misma licencia por ahora; a
33
+ futuro podrían migrar a **CC BY-SA** (el copyleft equivalente para texto).
34
+
35
+ ### Distribución
36
+
37
+ - **npm público** como canal principal (el CLI es cero-dep → `npx dai …` anda sin
38
+ instalar nada).
39
+ - **git-clone + `install.sh`** y **tarball** como fallback para **redes corporativas
40
+ cerradas** (proxy/firewall que bloquea el registry).
41
+ - Se saca `"private": true` del `package.json` para habilitar la publicación.
42
+
43
+ ## Consecuencias
44
+
45
+ - ✅ Los forks públicos de `dai` quedan abiertos para siempre → el commons crece.
46
+ - ✅ Cualquier empresa puede *usar* `dai` sin obligaciones (es un CLI).
47
+ - ✅ El canal cero-dep + fallback cubre tanto factories abiertas como orgs cerradas.
48
+ - ⚠️ `dai` no se podrá **embeber** como librería dentro de software propietario. Si
49
+ alguna vez hace falta eso, se evaluaría relicenciar una parte como LGPL/MIT.
50
+ - ⚠️ Publicar en npm hace el código **público** — nada de secretos en el repo (ya lo
51
+ cubre `.gitignore` + `.env`).
52
+
53
+ ## Alternativas consideradas
54
+
55
+ - **MIT / Apache-2.0 (permisivas)** — máxima adopción y fricción cero, pero **no**
56
+ obligan a devolver mejoras: se depende de la buena voluntad. Descartadas frente al
57
+ objetivo explícito de "que la comunidad ayude a mejorarla".
58
+ - **AGPLv3** — extiende el copyleft al uso como servicio en red. Overkill para un CLI
59
+ local; se descarta salvo que aparezca un caso SaaS.
@@ -0,0 +1,63 @@
1
+ # ADR-0007 — Modelo de autenticación
2
+
3
+ - **Estado:** aceptado
4
+ - **Fecha:** 2026-07-03
5
+ - **Decide:** lead / arquitecto + mantenedor
6
+
7
+ ## Contexto
8
+
9
+ `dai` y sus skills tocan **tres** sistemas externos: los repos de código (git), el
10
+ forge (GitHub/GitLab, para comentar PRs), y el tracker (Jira/ClickUp). Cada uno se
11
+ autentica distinto. Ahora que hay tokens en juego (`dai forge`, adaptador de PM),
12
+ hay que fijar un modelo de auth **antes** de seguir sumando credenciales — para no
13
+ terminar con contraseñas hardcodeadas o secretos en un commit.
14
+
15
+ Principio rector: **least privilege, sin contraseñas, secretos nunca versionados.**
16
+
17
+ ## Decisión
18
+
19
+ ### Tres credenciales, tres mecanismos (no se mezclan)
20
+
21
+ | Sistema | Acción | Credencial | Dónde vive |
22
+ |---|---|---|---|
23
+ | **git** | clone / fetch / push | **SSH key** (ssh-agent) | `~/.ssh` — **nunca** en `.env` ni en el repo |
24
+ | **forge** | leer/comentar PR/MR | **token scopeado** (`GITHUB_TOKEN` / `GITLAB_TOKEN`) | `.env` (gitignored) o secret store del CI |
25
+ | **tracker** | leer/escribir US y cobertura | **api_key** (`DAI_JIRA_TOKEN` / `DAI_CLICKUP_TOKEN`) | `.env` o secret store del CI |
26
+
27
+ ### Reglas
28
+
29
+ 1. **Nada de contraseñas.** Ni para git (SSH), ni para las APIs (tokens scopeados y
30
+ revocables). Prohibido el patrón `https://user:password@host`.
31
+ 2. **git es SSH.** El transporte de git (incluido lo que haga un agente o el CLI)
32
+ usa SSH. Comentar una PR **no** se hace por SSH (SSH solo mueve objetos git): eso
33
+ es API del forge → token.
34
+ 3. **Least privilege.** El token del forge se limita al scope mínimo (PRs/notes), no
35
+ un PAT con acceso total. Igual para el tracker.
36
+ 4. **Secretos fuera del repo.** Solo en `.env` (gitignored) o el secret store del CI.
37
+ Nunca en el código, ni en `implements.yaml`, ni en un commit. `.env.example`
38
+ documenta los **nombres** de las variables, jamás los valores.
39
+ 5. **Dos caras (ADR-0002).** Las **skills** usan el **MCP** del asistente (que guarda
40
+ sus propias credenciales); el **CLI** usa los **tokens del `.env`**. Nunca se
41
+ comparten ni se filtra uno al otro.
42
+ 6. **Variables de entorno ganan.** Un token exportado en la shell/CI pisa al `.env`
43
+ (para que el CI inyecte secretos sin escribir archivos).
44
+
45
+ ## Consecuencias
46
+
47
+ - ✅ Superficie de secretos mínima y auditable: SSH keys + tokens scopeados, cero
48
+ contraseñas.
49
+ - ✅ `.gitignore` + `.env.example` ya hacen cumplir "secretos fuera del repo".
50
+ - ✅ Rotar/revocar es trivial: son tokens, no contraseñas de cuenta.
51
+ - ⚠️ Requiere que cada dev tenga su SSH key configurada (ssh-agent) — es el costo de
52
+ no usar contraseñas. Se documenta en el onboarding.
53
+ - ⚠️ En el CI hay que cargar los tokens desde su secret store, no desde un `.env`
54
+ commiteado (que no existe).
55
+
56
+ ## Alternativas consideradas
57
+
58
+ - **Contraseña / PAT embebido en la URL de git** — descartado: viola "sin
59
+ contraseñas", y termina en el `~/.git-credentials` o en un remoto commiteado.
60
+ - **Un único super-token para todo** — descartado: rompe least privilege; si se
61
+ filtra, se filtra todo. Un token por sistema y por scope.
62
+ - **Que el CLI use el MCP del asistente** — imposible: el CLI corre standalone, no
63
+ tiene acceso al MCP. Por eso el CLI usa tokens propios (dos caras).
@@ -0,0 +1,19 @@
1
+ # ADRs — decisiones de fondo de la metodología
2
+
3
+ Registro de las decisiones estructurales de `dai`. Cada ADR es **inmutable**: si una
4
+ decisión cambia, se escribe un ADR nuevo que supersede al viejo. Molde en
5
+ [`templates/adr.md`](../../templates/adr.md).
6
+
7
+ | # | Decisión | Estado |
8
+ |---|---|---|
9
+ | [0001](0001-contrato-ac-hash.md) | El contrato del `ac_hash` (normalización + SHA-256, tres momentos) | aceptado |
10
+ | [0002](0002-agnostico-del-asistente.md) | La metodología es agnóstica del asistente (Claude / Copilot) | aceptado |
11
+ | [0003](0003-deteccion-y-estampado-son-comandos.md) | La detección y el estampado son comandos (`dai check` / `dai stamp`), no infraestructura | aceptado |
12
+ | [0004](0004-ubicacion-y-schema-implements.md) | Ubicación (co-localizado + glob) y schema del `implements.yaml` | aceptado |
13
+ | [0005](0005-superficie-comandos-y-stamp.md) | Superficie de comandos (`ls`/`check`/`stamp`) y contenido del stamp (branch + commit-ancla) | aceptado |
14
+ | [0006](0006-distribucion-y-licencia.md) | Distribución (npm + fallback) y licencia (GPLv3) | aceptado |
15
+ | [0007](0007-modelo-de-autenticacion.md) | Modelo de auth: SSH para git, tokens scopeados para forge/tracker, sin contraseñas | aceptado |
16
+
17
+ > Estas son las decisiones que cierran las "Decisiones abiertas" de
18
+ > [`METODOLOGIA.md §7`](../METODOLOGIA.md) y las enmiendas al
19
+ > [`MANIFIESTO.md`](../MANIFIESTO.md).
@@ -0,0 +1,33 @@
1
+ # Paso 1 — Refinamiento: de la idea vaga a la US testeable
2
+
3
+ ← vuelve a [`SCRUM-CON-IA.md`](../SCRUM-CON-IA.md)
4
+
5
+ ## En qué consiste en detalle
6
+
7
+ El PO llega con una idea (a veces un ticket de una línea). Antes de escribir specs,
8
+ la IA hace dos cosas, en orden:
9
+
10
+ 1. **Gate 0** (`grill-intent`) — desafía el *problema*, no la solución. Veredicto:
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
14
+ construcción** (INVEST + Gherkin) y la publica en el tracker.
15
+
16
+ ## Herramientas
17
+
18
+ - `/grill-intent` → `openspec/intents/<fecha-slug>/intent.md`
19
+ - `/grill-user-story` → US en formato [`formato-us.md`](../../templates/formato-us.md),
20
+ publicada en Jira/ClickUp (o `.md` de fallback).
21
+ - Gate de entrada: [`definition-of-ready.md`](../../templates/definition-of-ready.md).
22
+
23
+ ## Qué firma el humano
24
+
25
+ El PO **responde y decide**. La IA no inventa requerimientos: los saca a preguntas
26
+ ([Art. 4](../MANIFIESTO.md#art-4)). El PO es dueño del contenido funcional.
27
+
28
+ ## Antipatrones
29
+
30
+ - **US vaga** ("como usuario quiero un botón") → no pasa el pulido.
31
+ - **Criterio no testeable** ("buena experiencia") → se rechaza (Art. 3).
32
+ - **Solución prefijada** en la US (endpoints, tablas) → eso es CÓMO, va después (Art. 1).
33
+ - **Saltearse el Gate 0** → se construye lo que no había que construir.
@@ -0,0 +1,27 @@
1
+ # Paso 2 — Planning: derivar el CÓMO desde la US
2
+
3
+ ← vuelve a [`SCRUM-CON-IA.md`](../SCRUM-CON-IA.md)
4
+
5
+ ## En qué consiste en detalle
6
+
7
+ El equipo elige qué US entran al sprint (prioridad + capacidad). Para cada una, el
8
+ dev corre OpenSpec sobre la US: `opsx:explore` (entiende specs + código) y luego
9
+ `opsx:propose`, que **genera** el `design.md`, el `tasks.md` y las deltas de
10
+ `specs/`. El dev valida y ajusta — no acepta a ciegas.
11
+
12
+ ## Herramientas
13
+
14
+ - `opsx:explore` → mapa de specs y código relevante.
15
+ - `opsx:propose` → `proposal.md` + `design.md` + `tasks.md` + `specs/`.
16
+
17
+ ## Qué firma el humano
18
+
19
+ El **equipo** decide capacidad y prioridad. El **dev** valida el design y las tareas
20
+ propuestas — son suyas, nacen del CÓMO ([Art. 1](../MANIFIESTO.md#art-1)), no bajadas desde arriba.
21
+
22
+ ## Antipatrones
23
+
24
+ - **Tareas inventadas por fuera del que implementa** → pierden sentido técnico.
25
+ - **Estimar a ciegas** una US que no cumple el DoR → primero se pule (paso 1).
26
+ - **US demasiado grande** que no entra en el sprint → se parte (INVEST), no se fuerza.
27
+ - **Aceptar el design generado sin leerlo** → el dev es responsable del CÓMO.
@@ -0,0 +1,32 @@
1
+ # Paso 3 — Rama: atar el código al QUÉ desde el commit uno
2
+
3
+ ← vuelve a [`SCRUM-CON-IA.md`](../SCRUM-CON-IA.md)
4
+
5
+ ## En qué consiste en detalle
6
+
7
+ El dev arranca la implementación **atándola al QUÉ**: la branch y el `implements.yaml`
8
+ salen del mismo ID del tracker, así el link no puede quedar mal tipeado.
9
+
10
+ ## Herramientas
11
+
12
+ ```bash
13
+ dai link-us ABC-482 --us us.md
14
+ # → branch feature/ABC-482-<slug>
15
+ # → openspec/changes/<change>/implements.yaml (con el ac_hash ya calculado)
16
+ ```
17
+
18
+ - Convención de rama: [`branch-naming.md`](../../governance/branch-naming.md).
19
+ - Schema del link: [ADR-0004](../adr/0004-ubicacion-y-schema-implements.md).
20
+ - El `ac_hash` lo calcula `dai ac-hash` ([ADR-0001](../adr/0001-contrato-ac-hash.md)).
21
+
22
+ ## Qué firma el humano
23
+
24
+ El dev **elige qué US agarra**. El resto es mecánico y determinista (el CLI), no
25
+ criterio humano — por eso el key **no se tipea a mano** ([Art. 8](../MANIFIESTO.md#art-8), Art. 9).
26
+
27
+ ## Antipatrones
28
+
29
+ - **Tipear el key en la branch o el yaml a mano** → error que rompe la trazabilidad.
30
+ - **Branch sin `implements.yaml`** en trabajo de producto → no hay link.
31
+ - **Escribir la cobertura inversa a mano** → se deriva con `dai stamp` (Art. 10).
32
+ - **Una branch para varias US** → una US = una capacidad = un `implements.yaml`.
@@ -0,0 +1,35 @@
1
+ # Paso 4 — TDD: test primero, en vertical slices
2
+
3
+ ← vuelve a [`SCRUM-CON-IA.md`](../SCRUM-CON-IA.md)
4
+
5
+ ## En qué consiste en detalle
6
+
7
+ El CÓMO se construye con **test primero**, un comportamiento a la vez:
8
+
9
+ ```
10
+ RED → escribes UN test que falla (un criterio de aceptación)
11
+ GREEN → el código mínimo para que pase
12
+ REFACTOR → limpias, con los tests en verde
13
+ ```
14
+
15
+ *Vertical slices* (un test → una implementación → repetir), **no** horizontal
16
+ (todos los tests, después todo el código).
17
+
18
+ ## Herramientas
19
+
20
+ - Skill [`tdd`](../../skills/tdd/SKILL.md) — el loop red-green-refactor y qué es un
21
+ buen test.
22
+
23
+ ## Qué firma el humano
24
+
25
+ El dev **decide qué comportamientos importa testear** (no se testea todo) y revisa
26
+ cada slice. La IA escribe el test como spec ejecutable, el dev valida.
27
+
28
+ ## Antipatrones
29
+
30
+ - **Horizontal slicing** (todos los tests juntos) → tests de la *forma imaginada*, no
31
+ del comportamiento real.
32
+ - **Testear lo interno** (mocks de colaboradores, métodos privados) → el test se rompe
33
+ al refactorizar aunque el comportamiento no cambió. Testea por la **interfaz pública**.
34
+ - **Codear primero, testear "si queda tiempo"** → vibe coding ([Art. 7](../MANIFIESTO.md#art-7)).
35
+ - **Refactorizar en rojo** → primero llega a verde.
@@ -0,0 +1,32 @@
1
+ # Paso 5 — Smoke: el flujo entero, verde
2
+
3
+ ← vuelve a [`SCRUM-CON-IA.md`](../SCRUM-CON-IA.md)
4
+
5
+ ## En qué consiste en detalle
6
+
7
+ Antes de cerrar la US, se corre un **smoke end-to-end**: ejercita el flujo completo
8
+ —happy path + los guards principales— para confirmar que no se rompió nada grueso.
9
+ No reemplaza a los tests unitarios (paso 4); los complementa a nivel sistema.
10
+
11
+ ```
12
+ ✓ happy path → resultado esperado
13
+ ✓ guard 1 → rechazado como corresponde
14
+ ✓ guard 2 → rechazado como corresponde
15
+ SMOKE OK
16
+ ```
17
+
18
+ ## Herramientas
19
+
20
+ - Skills de smoke por dominio (p. ej. `smoke-<módulo>`), armadas por el equipo.
21
+
22
+ ## Qué firma el humano
23
+
24
+ El dev **confirma que el escenario refleja el uso real**. Un smoke que no toca el
25
+ flujo que importa da falsa confianza.
26
+
27
+ ## Antipatrones
28
+
29
+ - **Smoke manual** que se olvida o se saltea bajo presión → automatizarlo (idealmente
30
+ en el pipeline, ver retro).
31
+ - **Smoke que no ejercita los guards** → pasa en verde y esconde el bug.
32
+ - **Confundir smoke con suite completa** → el smoke es grueso y rápido, a propósito.