ozali 0.4.1 → 0.6.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.
@@ -64,3 +64,55 @@ histórico apunta a un commit exacto.
64
64
 
65
65
  El contrato concreto de qué se espeja a Engram, cuándo, y el algoritmo de `ozali sync` está en
66
66
  [skill/references/engram-convention.md](../skill/references/engram-convention.md) (§3 y §6).
67
+
68
+ ## Engram Cloud: réplica en tiempo real (opt-in)
69
+
70
+ Además del git-sync, ozali soporta **Engram Cloud** — un servidor central que replica la memoria
71
+ del equipo **en tiempo real** (autosync), sin necesidad de commit/push manual.
72
+
73
+ ### Modelo: cloud-first, git-sync como backup
74
+
75
+ ```
76
+ dev A guarda memoria → autosync → cloud → dev B (autosync recibe)
77
+
78
+ git-sync (backup/secondary, repos de conocimiento)
79
+ ```
80
+
81
+ - **Cloud-first**: la réplica es automática e invisible. El repo de conocimiento sigue siendo
82
+ el backup offline y el canal para docs (que no van a cloud).
83
+ - **Sin cloud**: todo funciona igual con git-sync manual (`ozali sync` + `--push`/`--import`).
84
+
85
+ ### Onboarding de equipo (un dev nuevo en 1 paso)
86
+
87
+ Cuando un dev nuevo hace `ozali init` en un repo que ya tiene `.ozali/cloud.json` (commiteable,
88
+ sin secretos), el CLI detecta la cloud del equipo y ofrece conectarse automáticamente:
89
+
90
+ ```
91
+ $ ozali init
92
+ ✓ Engram Cloud del equipo detectado (servidor: https://engram.mi-empresa.com)
93
+ → Proyecto: "ozali"
94
+ → ¿Conectarte a la memoria del equipo? [sí/no]
95
+ → token: ****
96
+ → Recibiendo memoria del equipo…
97
+ → autosync activo (invisible)
98
+ → Listo.
99
+ ```
100
+
101
+ ### Despliegue del servidor
102
+
103
+ Ver [docs/deploy-cloud-vps.md](deploy-cloud-vps.md) (VPS genérico con docker-compose) y
104
+ [docs/deploy-cloud-gcloud.md](deploy-cloud-gcloud.md) (Google Cloud: Cloud Run o GCE VM).
105
+
106
+ ### Comandos cloud
107
+
108
+ | Comando | Qué hace |
109
+ |---|---|
110
+ | `ozali sync --cloud` | Push manual a cloud |
111
+ | `ozali sync --cloud --import` | Pull desde cloud (onboarding inverso) |
112
+ | `ozali cloud status` | Estado + último sync + upgrade |
113
+ | `ozali cloud upgrade` | doctor → repair → bootstrap |
114
+ | `ozali cloud dashboard` | Abre el dashboard web |
115
+ | `ozali cloud config` | Re-configura servidor/token |
116
+
117
+ Detalle del contrato de memoria cloud (scope, idioma, conflictos, troubleshooting) en
118
+ [skill/references/engram-convention.md](../skill/references/engram-convention.md) §8.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ozali",
3
- "version": "0.4.1",
3
+ "version": "0.6.0",
4
4
  "description": "Bootstrap interactivo de IA por equipo: calibra el proyecto, genera la skill de ejecución (cdk) con TDD/SDD, y mantiene memoria de equipo (Engram) con histórico aislado.",
5
5
  "type": "module",
6
6
  "bin": {
@@ -12,6 +12,7 @@
12
12
  "files": [
13
13
  "cli/",
14
14
  "skill/",
15
+ "skill-commit/",
15
16
  "templates/",
16
17
  "docs/",
17
18
  "README.md",
package/skill/SKILL.md CHANGED
@@ -30,6 +30,7 @@ produce documentación, la calibración, el plan y los artefactos de la skill `c
30
30
 
31
31
  ```
32
32
  Fase 0 Identidad y registro → quién corre ozali (git/sesión)
33
+ Fase 0.5 Pre-flight de cdk → ¿existe cdk? ¿versión de contrato vigente? migrar si toca
33
34
  Fase 1 Detección fuente de verdad → ¿existe AI.md/.ai o IA.md/.ia?
34
35
  Fase 2 Generación conocimiento → si falta, evaluar el proyecto y generar AI.md + .ai/
35
36
  Fase 3 Validación + ajustes → ¿coincide con la estructura real? ajustes mínimos
@@ -69,6 +70,45 @@ Guarda estos valores; se reutilizan en Fase 6 y en la documentación.
69
70
 
70
71
  ---
71
72
 
73
+ ## Fase 0.5 — Pre-flight de `cdk` (versión de contrato + migración)
74
+
75
+ > Esta fase resuelve el caso de **un repo que ya tiene `cdk` instalada**: en vez de omitirla,
76
+ > `ozali` decide si está **al día**, **desactualizada** o **ausente**, y actúa en consecuencia.
77
+ > La **versión de contrato vigente** y las reglas de migración están en
78
+ > [`references/cdk-contract.md`](references/cdk-contract.md) — es la **fuente de verdad única**.
79
+
80
+ 1. **Lee la versión de contrato vigente `N`** del marcador `CDK_CONTRACT_VERSION` en
81
+ [`references/cdk-contract.md`](references/cdk-contract.md).
82
+ 2. **Busca el `cdk` instalado**: `.claude/skills/cdk/SKILL.md` (proyecto), luego
83
+ `~/.claude/skills/cdk/SKILL.md` (global). Si existe, lee `cdk_contract_version` de su frontmatter.
84
+ 3. **Decide y registra** la decisión (se usa en las Fases 5 y 6):
85
+
86
+ | Estado del `cdk` instalado | Decisión |
87
+ |---|---|
88
+ | **No existe** | `GENERAR` — flujo normal: continúa el bootstrap hasta el GATE (Fase 5) y genera `cdk` en la Fase 6, estampando `cdk_contract_version: N`. |
89
+ | **Existe sin `cdk_contract_version`** (cdk legado) o con valor **`< N`** | `MIGRAR` — **migración automática** (sin GATE), ver abajo. |
90
+ | **Existe con `cdk_contract_version == N`** | `AL_DÍA` — no regenerar. Infórmalo y continúa el bootstrap solo para refrescar la calibración/documentación si el usuario lo pide. |
91
+
92
+ 4. **Migración automática (`MIGRAR`)** — aplica los deltas del changelog de
93
+ [`references/cdk-contract.md`](references/cdk-contract.md) sobre el `cdk` instalado, **sin** pasar
94
+ por el GATE, porque preserva el `cdk` del usuario y solo actualiza el contrato:
95
+ - **Elimina toda referencia a `copsis-commit`** y reemplázala por **`ozali-commit`** (la skill de
96
+ commit vigente, instalada en `.claude/skills/ozali-commit/`).
97
+ - Aplica el resto de deltas del changelog (recall-first, telemetría, etc. según la versión).
98
+ - **Estampa** `cdk_contract_version: N` en el frontmatter del `cdk`.
99
+ - **Preserva** intactos `.ozali/docs/cdk/` (histórico por hito) y los planes congelados
100
+ (`02-plan-aprobado.md`).
101
+ - **Reporta** al usuario, en texto, qué cambió (referencias migradas, secciones actualizadas,
102
+ versión nueva).
103
+ - **Excepción → GATE:** si un delta exige **regeneración estructural** (reescribir subagentes,
104
+ cambiar el harness, rehacer el wiring de TDD), eso **no** es migración automática: preséntalo en
105
+ el plan del GATE (Fase 5) y regénéralo en la Fase 6.
106
+
107
+ > Sin `cdk` previo, esta fase no hace nada salvo registrar `GENERAR`. La calibración (Fase 3.5) y el
108
+ > resto del flujo continúan igual.
109
+
110
+ ---
111
+
72
112
  ## Fase 1 — Detección de la fuente de verdad
73
113
 
74
114
  Busca en la raíz del repositorio, aceptando **ambas nomenclaturas**:
@@ -217,6 +257,9 @@ Solo tras la aprobación de la Fase 5. Genera:
217
257
  - declarar en el frontmatter una **description con triggers ricos** (verbos y sustantivos
218
258
  que el usuario usaría: "crea", "genera", "corrige", "refactoriza", método, clase,
219
259
  endpoint, componente…) para mejorar la auto-invocación de la skill;
260
+ - **estampar en el frontmatter** `cdk_contract_version: N`, con `N` = la versión de contrato
261
+ vigente de [`references/cdk-contract.md`](references/cdk-contract.md). Esto permite que el
262
+ pre-flight (Fase 0.5) y `ozali doctor`/`ozali update` sepan si el `cdk` está al día;
220
263
  - declarar que ayuda a **generar código** (nuevo componente, fix de bug, análisis de impacto)
221
264
  respetando la fuente de verdad y los estándares del proyecto;
222
265
  - orquestar los 8 subagentes según la fase del trabajo;
@@ -249,9 +292,11 @@ Solo tras la aprobación de la Fase 5. Genera:
249
292
  resumen técnico, `state`) con naming determinista, según
250
293
  [`references/engram-convention.md`](references/engram-convention.md), y al **iniciar** un
251
294
  hito hacer `mem_search` del proyecto/hito para recuperar contexto previo;
252
- - en el **cierre del hito**, invocar la skill **`ozali-commit`** para generar el commit
253
- summary (feature→`feat`, bugfix→`fix`, hotfix→`hotfix`, refactor→`refactor`; scope = módulo
254
- del hito). El GATE del mensaje es independiente del GATE del plan.
295
+ - en el **cierre del hito**, invocar la skill **`ozali-commit`** (instalada por el CLI en
296
+ `.claude/skills/ozali-commit/`; **nunca** `copsis-commit`, nombre heredado de versiones
297
+ anteriores) para generar el commit summary (feature→`feat`, bugfix→`fix`, hotfix→`hotfix`,
298
+ refactor→`refactor`; scope = módulo del hito). El GATE del mensaje es independiente del GATE
299
+ del plan.
255
300
  2. `.claude/agents/<rol>.md` — un subagente real por cada uno de los 8 roles, con su system
256
301
  prompt y herramientas, según [`references/agents-blueprint.md`](references/agents-blueprint.md).
257
302
  3. `.claude/skills/cdk/verify-structure.mjs` — **harness del analista**: script Node sin
@@ -0,0 +1,72 @@
1
+ <!-- CDK_CONTRACT_VERSION: 1 -->
2
+
3
+ # Contrato de la skill `cdk` — versión y migración
4
+
5
+ Esta es la **fuente de verdad única** de la versión del contrato con el que `ozali` genera (y
6
+ mantiene) la skill `cdk`. La lee el **agente** (en la Fase 0.5 y la Fase 6 de
7
+ [`../SKILL.md`](../SKILL.md)) y la parsea el **CLI** (`ozali doctor`/`ozali update`) del paquete.
8
+ Para subir el contrato: incrementa el número del marcador `CDK_CONTRACT_VERSION` de arriba y la
9
+ prosa de abajo, y agrega una entrada al changelog.
10
+
11
+ > **Versión de contrato vigente: `1`**
12
+
13
+ El número vive en **un solo lugar** (el marcador HTML de la primera línea, formato
14
+ `CDK_CONTRACT_VERSION: <entero>`). No lo dupliques en otros archivos.
15
+
16
+ ---
17
+
18
+ ## Cómo se usa la versión
19
+
20
+ - El `cdk` generado **debe estampar** su versión de contrato en el frontmatter de su `SKILL.md`:
21
+
22
+ ```yaml
23
+ ---
24
+ name: cdk
25
+ description: <triggers ricos…>
26
+ cdk_contract_version: 1
27
+ ---
28
+ ```
29
+
30
+ - En el **pre-flight** (Fase 0.5 de `ozali`), el agente compara la versión estampada en el `cdk`
31
+ instalado contra esta versión vigente **N**:
32
+
33
+ | Estado del `cdk` instalado | Acción |
34
+ |---|---|
35
+ | No existe | Generar `cdk` por el flujo normal (GATE Fase 5 → Fase 6), estampando `cdk_contract_version: N`. |
36
+ | Existe **sin** `cdk_contract_version`, o con un valor **< N** | **Desactualizado → migración automática** (sin GATE): aplica los deltas del changelog, estampa `N` y reporta los cambios. Si el delta exige **regeneración estructural** de subagentes, eso sí pasa por el GATE de la Fase 5. |
37
+ | Existe con `cdk_contract_version == N` | Al día → no regenerar; solo informarlo. |
38
+
39
+ > Un `cdk` **sin** el campo `cdk_contract_version` es un `cdk` **legado** (generado por una versión
40
+ > anterior de `ozali`). Trátalo como versión `0`: siempre desactualizado.
41
+
42
+ ---
43
+
44
+ ## Regla de migración (todas las versiones)
45
+
46
+ Al migrar un `cdk` legado o desactualizado, **siempre**:
47
+
48
+ 1. **Elimina toda referencia a `copsis-commit`** (nombre heredado de versiones anteriores) y
49
+ **reemplázala por `ozali-commit`** — la skill de commit vigente que `ozali init`/`ozali update`
50
+ instalan en `.claude/skills/ozali-commit/`.
51
+ 2. **Preserva** el histórico por hito (`.ozali/docs/cdk/`) y los planes congelados
52
+ (`02-plan-aprobado.md`): la migración del contrato **nunca** los borra ni reescribe.
53
+ 3. **Estampa** `cdk_contract_version: N` en el frontmatter del `cdk` migrado.
54
+ 4. **Reporta** al usuario, en texto, qué cambió (referencias migradas, secciones actualizadas,
55
+ versión nueva).
56
+
57
+ ---
58
+
59
+ ## Changelog del contrato
60
+
61
+ ### v1 — contrato base
62
+ Un `cdk` conforme a la v1 debe:
63
+
64
+ - Estampar `cdk_contract_version: 1` en su frontmatter.
65
+ - En el **cierre de hito**, invocar la skill **`ozali-commit`** (nunca `copsis-commit`) para
66
+ generar el commit summary convencional (feature→`feat`, bugfix→`fix`, hotfix→`hotfix`,
67
+ refactor→`refactor`; scope = módulo del hito).
68
+ - Operar **recall-first** (reusar memoria de Engram antes de releer/re-analizar) según
69
+ [`engram-convention.md`](engram-convention.md) §7.
70
+ - Espejar a Engram los artefactos clave del hito y escribir la telemetría de tokens
71
+ (`.ozali/metrics/token-metrics.json`, que lee `ozali doctor`).
72
+ - Respetar la calibración de Strict TDD (Fase 3.5) y el 🛑 GATE del plan.
@@ -269,3 +269,81 @@ artefacto, menos cuesta recuperarlo después.
269
269
  agresivo con recall-first (resume antes, evita relecturas grandes).
270
270
 
271
271
  > `savedByRecall` = estimación de relectura evitada por reusar memoria (ver plantilla `06-uso-tokens`).
272
+
273
+ ---
274
+
275
+ ## 8. Cloud: réplica de equipo en tiempo real
276
+
277
+ Engram Cloud es una **capa opt-in** que replica la memoria del equipo a un servidor central,
278
+ **adicional al git-sync**. Con autosync activo, la réplica es **automática e invisible**: los devs
279
+ no necesitan correr `ozali sync` manualmente para compartir memoria.
280
+
281
+ ### 8.1 Modelo: cloud-first, git-sync como backup
282
+
283
+ ```
284
+ dev A guarda memoria → autosync → cloud → dev B (autosync recibe)
285
+
286
+ git-sync (backup/secondary)
287
+ ```
288
+
289
+ - **Cloud-first**: la réplica es en tiempo real (autosync). El repo de conocimiento sigue siendo
290
+ el backup offline (ver [team-history](../../docs/team-history.md)).
291
+ - **Sin cloud**: todo funciona igual, solo que el sync es manual (`ozali sync` + `--push`/`--import`).
292
+
293
+ ### 8.2 Cómo se comparten las memorias vía cloud
294
+
295
+ 1. Un dev guarda una observación con `mem_save` (scope: project, español — ver §1.5).
296
+ 2. El autosync la replica al servidor cloud automáticamente.
297
+ 3. El autosync del otro dev la recibe y la importa a su store local.
298
+ 4. Ambos devs pueden buscarla con `mem_search`.
299
+
300
+ > **Scope + idioma siguen siendo obligatorios** (§1.5): `scope: project` siempre en español,
301
+ > `scope: personal` cualquier idioma. Cloud no cambia esta regla — solo acelera el transporte.
302
+
303
+ ### 8.3 Archivos de configuración
304
+
305
+ | Archivo | Commiteable | Contiene | Propósito |
306
+ |---|---|---|---|
307
+ | `.ozali/cloud.json` | **Sí** (no lleva secretos) | server, project, enrolled, dashboard URL | Que un dev nuevo detecte la cloud del equipo al hacer `ozali init` |
308
+ | `~/.engram/cloud_token` | No (local) | El token de auth | Persistencia del token entre sesiones |
309
+ | `.claude/settings.json` (env) | Sí | `ENGRAM_CLOUD_AUTOSYNC=1`, `ENGRAM_CLOUD_TOKEN` | Autosync en el MCP del agente |
310
+
311
+ > El token **nunca** se commitea. `.ozali/cloud.json` solo tiene metadatos sin secretos.
312
+
313
+ ### 8.4 Comandos cloud del CLI
314
+
315
+ | Comando | Qué hace |
316
+ |---|---|
317
+ | `ozali init` → detecta `.ozali/cloud.json` | Onboarding: conecta al dev nuevo en 1 paso (Fase 1) |
318
+ | `ozali sync --cloud` | Push manual a cloud (además del git-sync) |
319
+ | `ozali sync --cloud --import` | Pull desde cloud (onboarding inverso) |
320
+ | `ozali cloud status` | Estado de enrollment + último sync + upgrade pipeline |
321
+ | `ozali cloud upgrade` | Flujo completo: doctor → repair --apply → bootstrap |
322
+ | `ozali cloud repair` | `engram cloud upgrade repair --apply` |
323
+ | `ozali cloud dashboard` | Abre el dashboard web en el navegador |
324
+ | `ozali cloud config` | Re-configura servidor/token |
325
+ | `ozali audit --conflicts` | Lista conflictos de memoria pendientes |
326
+ | `ozali audit --conflicts --stats` | Estadísticas de conflictos |
327
+
328
+ ### 8.5 Conflictos: qué son y cómo resolverlos
329
+
330
+ Cuando dos devs guardan memorias que el sistema detecta como **potencialmente conflictivas**
331
+ (misma `topic_key`, contenido divergente), Engram Cloud las marca como conflictos pendientes.
332
+
333
+ - `ozali doctor` avisa si hay conflictos pendientes (`pending > 0`).
334
+ - `ozali audit --conflicts` los lista.
335
+ - El agente los resuelve con `mem_judge` (ver protocolo de conflict surfacing en las
336
+ instrucciones del MCP de Engram): `related`, `compatible`, `scoped`, `conflicts_with`,
337
+ `supersedes`, `not_conflict`.
338
+ - `ozali audit --conflicts --judged` muestra los ya resueltos.
339
+
340
+ ### 8.6 Troubleshooting cloud
341
+
342
+ | `reason_code` | Significado | Acción |
343
+ |---|---|---|
344
+ | `blocked_unenrolled` | El proyecto no está enrolado en el servidor | `ozali init` o `ozali cloud config` |
345
+ | `transport_failed` | No se pudo conectar al servidor | Verifica URL, red, firewall |
346
+ | `bootstrap_verified` (upgrade) | Todo OK, no necesita upgrade | — |
347
+ | otro (upgrade) | El proyecto requiere upgrade de esquema | `ozali cloud upgrade` |
348
+
349
+ > `ozali doctor` parsea estos códigos y muestra warnings específicos.
@@ -0,0 +1,81 @@
1
+ ---
2
+ name: ozali-commit
3
+ description: Genera un "commit summary" convencional (feat/fix/hotfix/refactor) con prefijo, scope y descripción a partir de los cambios EN STAGE y commitea tras tu aprobación. Úsala cuando el usuario quiera "commitea", "haz el commit", "genera el mensaje de commit", "cierra el hito con commit", o cuando otra skill (p. ej. cdk) cierre un hito. Sucesora de copsis-commit.
4
+ ---
5
+
6
+ # Skill: ozali-commit
7
+
8
+ `ozali-commit` produce el **mensaje de commit** de un cambio siguiendo
9
+ [Conventional Commits](https://www.conventionalcommits.org/) y lo **commitea tras tu aprobación**.
10
+ Es la skill de commit vigente del ecosistema `ozali` (sucede a la antigua `copsis-commit`).
11
+
12
+ `cdk` la invoca en el **cierre de cada hito**, pero también puedes usarla suelta en cualquier repo.
13
+
14
+ > **Regla de oro:** nunca commitea sin tu aprobación explícita (🛑 **GATE de mensaje**). El GATE del
15
+ > mensaje es **independiente** del GATE del plan de `cdk`.
16
+
17
+ > **Cero dependencias:** usa `git` directo (ya habilitado en el perfil base de permisos de ozali:
18
+ > `Bash(git add *)`, `Bash(git commit *)`, `Bash(git status)`, `Bash(git diff *)`,
19
+ > `Bash(git log *)`). No requiere herramientas externas.
20
+
21
+ ---
22
+
23
+ ## Flujo
24
+
25
+ ### 1. Inspecciona el stage
26
+ - `git status --short` — qué hay staged vs sin stage.
27
+ - `git diff --cached` — el contenido **EN STAGE** (la fuente de verdad del mensaje).
28
+ - Si **no hay nada en stage**: dilo y pregunta si quieres que haga `git add` de archivos concretos
29
+ (o `git add -A`). **No** hagas `add -A` por tu cuenta sin confirmación.
30
+ - Lee el commit anterior con `git log -1 --pretty=%s` para mantener el estilo del repo.
31
+
32
+ ### 2. Determina el tipo y el scope
33
+ A partir del diff EN STAGE, clasifica el cambio:
34
+
35
+ | Tipo | Cuándo |
36
+ |---|---|
37
+ | `feat` | nueva funcionalidad / capacidad |
38
+ | `fix` | corrección de bug |
39
+ | `hotfix` | corrección urgente en caliente |
40
+ | `refactor` | reestructura sin cambiar comportamiento |
41
+ | `docs` | solo documentación |
42
+ | `test` | solo pruebas |
43
+ | `chore` | mantenimiento (deps, config, build) |
44
+
45
+ - **Scope** = módulo/área tocada del repo (derívalo de las rutas en stage; ej. `cobranza`, `cli`,
46
+ `auth`). Si abarca varias áreas, usa la más representativa o un scope general.
47
+ - Si la skill que invoca aporta tipo/scope (p. ej. `cdk` mapea feature→`feat`, bugfix→`fix`,
48
+ hotfix→`hotfix`, refactor→`refactor`), **respétalos**.
49
+
50
+ ### 3. Redacta el mensaje
51
+ Formato: `tipo(scope): descripción en imperativo, ≤ 72 chars`. Cuerpo opcional (qué/por qué, no el
52
+ cómo). No inventes cambios que no estén en el diff. Idioma: el del repo (mira `git log`).
53
+
54
+ ```
55
+ feat(cobranza): agrega validación de RFC en alta de cotización
56
+
57
+ - valida formato y dígito verificador antes de persistir
58
+ - cubre el caso de RFC genérico (XAXX010101000)
59
+ ```
60
+
61
+ ### 4. 🛑 GATE de mensaje
62
+ Presenta el mensaje completo **como texto visible** y espera aprobación. Si el usuario pide ajustes,
63
+ itera. **No commitees** hasta el "ok".
64
+
65
+ ### 5. Commitea
66
+ Tras la aprobación:
67
+ ```bash
68
+ git commit -m "tipo(scope): descripción" [-m "cuerpo…"]
69
+ ```
70
+ - Commitea **solo lo que está en stage** (no añadas archivos no aprobados).
71
+ - **No** hagas `git push` (es destructivo/saliente y está denegado por defecto): si el usuario lo
72
+ quiere, recuérdaselo para que lo haga él.
73
+ - Reporta el hash corto resultante (`git rev-parse --short HEAD`).
74
+
75
+ ---
76
+
77
+ ## Notas
78
+ - Si el repo usa una convención propia (gitmoji, prefijos de ticket), detéctala desde `git log` y
79
+ síguela.
80
+ - Si el cambio es demasiado grande/heterogéneo para un solo mensaje coherente, **sugiere** dividir
81
+ en varios commits (pero no lo hagas sin aprobación).