pumuki 6.3.72 → 6.3.73

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 (53) hide show
  1. package/CHANGELOG.md +20 -0
  2. package/VERSION +1 -1
  3. package/docs/README.md +1 -1
  4. package/docs/operations/RELEASE_NOTES.md +12 -1
  5. package/docs/product/USAGE.md +2 -5
  6. package/docs/tracking/plan-curso-pumuki-stack-my-architecture.md +56 -105
  7. package/integrations/gate/governanceActionCatalog.ts +230 -0
  8. package/integrations/git/runPlatformGate.ts +9 -1
  9. package/integrations/git/runPlatformGateFacts.ts +1 -7
  10. package/integrations/git/runPlatformGateOutput.ts +36 -27
  11. package/integrations/lifecycle/adapter.templates.json +3 -0
  12. package/integrations/lifecycle/audit.ts +101 -0
  13. package/integrations/lifecycle/cli.ts +80 -8
  14. package/integrations/lifecycle/doctor.ts +64 -1
  15. package/integrations/lifecycle/governanceNextAction.ts +164 -0
  16. package/integrations/lifecycle/governanceObservationSnapshot.ts +288 -0
  17. package/integrations/lifecycle/index.ts +2 -0
  18. package/integrations/lifecycle/status.ts +29 -2
  19. package/integrations/mcp/autoExecuteAiStart.ts +86 -84
  20. package/integrations/mcp/preFlightCheck.ts +41 -5
  21. package/integrations/platform/detectPlatforms.ts +37 -0
  22. package/package.json +8 -1
  23. package/scripts/build-ruralgo-s1-evidence-pack.ts +85 -0
  24. package/scripts/consumer-menu-matrix-baseline-report-lib.ts +38 -13
  25. package/scripts/consumer-postinstall-resolve-args.cjs +38 -0
  26. package/scripts/consumer-postinstall.cjs +10 -1
  27. package/scripts/framework-menu-consumer-actions-lib.ts +4 -28
  28. package/scripts/framework-menu-consumer-preflight-hints.ts +2 -5
  29. package/scripts/framework-menu-consumer-preflight-render.ts +6 -0
  30. package/scripts/framework-menu-consumer-preflight-run.ts +19 -0
  31. package/scripts/framework-menu-consumer-preflight-types.ts +8 -0
  32. package/scripts/framework-menu-consumer-runtime-actions.ts +6 -86
  33. package/scripts/framework-menu-consumer-runtime-audit.ts +2 -36
  34. package/scripts/framework-menu-consumer-runtime-lib.ts +0 -2
  35. package/scripts/framework-menu-consumer-runtime-types.ts +1 -3
  36. package/scripts/framework-menu-evidence-summary-lib.ts +0 -1
  37. package/scripts/framework-menu-evidence-summary-read.ts +5 -57
  38. package/scripts/framework-menu-evidence-summary-severity.ts +1 -3
  39. package/scripts/framework-menu-evidence-summary-types.ts +0 -7
  40. package/scripts/framework-menu-gate-lib.ts +0 -9
  41. package/scripts/framework-menu-layout-data.ts +0 -5
  42. package/scripts/framework-menu-matrix-baseline-lib.ts +14 -15
  43. package/scripts/framework-menu-matrix-canary-lib.ts +1 -22
  44. package/scripts/framework-menu-matrix-evidence-lib.ts +0 -1
  45. package/scripts/framework-menu-matrix-evidence-types.ts +1 -13
  46. package/scripts/framework-menu-matrix-runner-lib.ts +0 -35
  47. package/scripts/framework-menu-system-notifications-macos.ts +0 -4
  48. package/scripts/framework-menu.ts +0 -3
  49. package/scripts/pumuki-full-surface-smoke-lib.ts +37 -0
  50. package/scripts/pumuki-full-surface-smoke.ts +261 -0
  51. package/scripts/pumuki-smoke-installed-wrapper.cjs +31 -0
  52. package/scripts/ruralgo-s1-evidence-pack-lib.ts +200 -0
  53. package/scripts/framework-menu-consumer-runtime-evidence-classic.ts +0 -140
package/CHANGELOG.md CHANGED
@@ -6,14 +6,34 @@ This project follows [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
6
6
 
7
7
  ## [Unreleased]
8
8
 
9
+ ## [6.3.73] - 2026-04-14
10
+
11
+ ### Added
12
+
13
+ - **Consola S1 de governance**: `status`, `doctor`, menú consumer, hooks y MCP empiezan a hablar el mismo vocabulario operativo con `governance truth`, `reason_code`, `instruction` y `next_action`, apoyados en `integrations/lifecycle/governanceObservationSnapshot.ts`, `integrations/lifecycle/governanceNextAction.ts` y `integrations/gate/governanceActionCatalog.ts`.
14
+ - **Paquete ejecutable de evidencia RuralGo**: nuevo script `validation:ruralgo-s1-evidence-pack` para generar un paquete determinista de comandos shell + capturas MCP orientado a validar `PUMUKI-INC-071/073/076` en el consumer real.
15
+ - **Lifecycle audit**: `integrations/lifecycle/audit.ts` y el wiring de CLI vuelven a formar parte de la línea release para no perder la superficie útil ya publicada en `6.3.72`.
16
+ - **Full surface smoke / consumer postinstall helpers**: se preservan `scripts/pumuki-full-surface-smoke.ts`, `scripts/pumuki-smoke-installed-wrapper.cjs` y `scripts/consumer-postinstall-resolve-args.cjs` para mantener la barra local y el contrato de instalación del consumidor.
17
+
18
+ ### Changed
19
+
20
+ - **PRE_WRITE / hooks / MCP**: el contrato canónico de governance converge en torno al mismo catálogo compartido; hooks muestran `reason_code`, `instruction` y `next_action`, y MCP expone también `reason_code` + `next_action` en `pre_flight_check`.
21
+ - **Evidence pack con semver exacta**: cuando el paquete se genera con una versión publicada, el comando `PRE_WRITE` queda fijado a esa semver; solo degrada a `pumuki@latest` en contextos locales o no publicados.
22
+ - **Línea release saneada**: `6.3.73` conserva el mínimo funcional ya publicado en `6.3.72` (audit lifecycle, postinstall resolver, platform detection y smoke de superficie) y añade encima la Slice S1 de governance.
23
+
9
24
  ## [6.3.72] - 2026-04-11
10
25
 
11
26
  ### Fixed
12
27
 
28
+ - **Tests `cli` (macOS):** la suite `integrations/lifecycle/__tests__/cli.test.ts` activaba **`emitGateBlockedNotification`** real en escenarios PRE_WRITE **strict** (p. ej. `OPENSPEC_MISSING`), lo que podía **bloquear** `npm test` indefinidamente al abrir notificación/diálogo del sistema. Los tests fijan **`PUMUKI_DISABLE_SYSTEM_NOTIFICATIONS=1`** en `beforeEach` y restauran el env en `afterEach` (misma variable que el producto ya documenta para desactivar notificaciones).
13
29
  - **macOS notificaciones en `gate.blocked`**: por defecto vuelve a mostrarse el **banner** de Notification Center además del modal interactivo cuando el modal está activo. Antes, si el modal (Swift/AppleScript) no llegaba a mostrarse desde un hook en un repo consumidor, podía no verse **ninguna** notificación. Opt-in al comportamiento previo (solo modal, sin banner duplicado): `PUMUKI_MACOS_GATE_BLOCKED_BANNER_DEDUPE=1`.
30
+ - **Consumer repin + MCP (IDE-agnóstico)**: el `postinstall` del paquete ejecuta **`pumuki install --with-mcp --agent=repo`** por defecto, actualizando **`.pumuki/adapter.json`** (hooks + comandos MCP stdio) sin depender de Cursor ni de ningún IDE. La plantilla `repo` usa **`json-merge`** para no pisar claves extra del consumidor. Opt-out: `PUMUKI_POSTINSTALL_SKIP_MCP=1`. Opt-in a ficheros de IDE en postinstall: `PUMUKI_POSTINSTALL_MCP_AGENT=cursor|claude|codex`.
31
+ - **macOS diálogo `gate.blocked` (Swift)**: el helper deja de usar un `NSPanel` flotante personalizado y pasa a **`NSAlert.runModal()`**, de modo que **Desactivar / Silenciar 30 min / Mantener activas** respondan de forma fiable a clics y teclado (el panel flotante podía no entregar eventos según foco de otras apps, p. ej. el IDE).
14
32
 
15
33
  ### Added
16
34
 
35
+ - **Smoke de superficie CLI**: `npm run smoke:pumuki-surface` (~29 invocaciones) y `smoke:pumuki-surface-installed` con `PUMUKI_SMOKE_REPO_ROOT` + `PUMUKI_SMOKE_BIN_STRATEGY=installed` para validar el bin bajo `node_modules/pumuki` del consumidor. Ver `docs/validation/README.md`.
36
+ - **Barra local sin GitHub Actions**: `npm run validation:local-merge-bar` (`typecheck` + smoke + `npm test`) como sustituto operativo cuando la org no tiene cuota útil de Actions.
17
37
  - **Tarball npm**: el paquete publicado incluye también `AGENTS.md`, `CHANGELOG.md` y `docs/tracking/plan-curso-pumuki-stack-my-architecture.md` (listados en `package.json` → `files`), de modo que la misma versión en **npm** / **jsDelivr** / `node_modules` expone contrato de agentes, historial de release y el plan formativo del curso Pumuki sin depender solo de GitHub.
18
38
  - **Menú consumer (`npm run framework:menu`)**: opciones `11` (solo **staged**), `12` (solo **unstaged**: `git diff` + untracked), `13` (**staged + unstaged** con política **PRE_COMMIT** sobre el working tree), `14` (**todo el repo trackeado** sin preflight). Ejecutan el motor de gate **sin preflight** consumer. Nuevo alcance de hechos `unstaged` y `GitService.getUnstagedFacts`.
19
39
  - **Vista “classic” en consola**: segundo panel tras el resumen consumer con severidades coloreadas (enterprise + legacy), hasta 45 hallazgos ordenados, filas **platform** si existen en la evidencia, y nota sobre heurística `Other`. Variable `PUMUKI_MENU_VINTAGE_REPORT=0` para desactivar.
package/VERSION CHANGED
@@ -1 +1 @@
1
- v6.3.64
1
+ v6.3.73
package/docs/README.md CHANGED
@@ -67,7 +67,7 @@ Mapa corto y humano de la documentación oficial de Pumuki.
67
67
  - `docs/tracking/`
68
68
  - Seguimiento permitido y solo el imprescindible.
69
69
  - Espejo operativo de producto y consumidores: `docs/tracking/plan-activo-de-trabajo.md` (unica fuente de verdad para ese ambito).
70
- - Curso Pumuki (Stack My Architecture): diseño pedagógico + seguimiento de entrega en `docs/tracking/plan-curso-pumuki-stack-my-architecture.md` (no sustituye al plan activo).
70
+ - Iniciativa formativa (curso Pumuki en Stack My Architecture): `docs/tracking/plan-curso-pumuki-stack-my-architecture.md` (no sustituye al plan activo).
71
71
  - Regla hard: solo puede existir una tarea `🚧` en cada documento de seguimiento que lo use.
72
72
 
73
73
  ## Fuera de `docs/`
@@ -6,12 +6,23 @@ This file keeps only the operational highlights and rollout notes that matter wh
6
6
 
7
7
  ## 2026-04 (CLI stability and macOS notifications)
8
8
 
9
+ ### 2026-04-14 (v6.3.73)
10
+
11
+ - **S1 governance console**: `status`, `doctor`, menú consumer, hooks y MCP comparten ya la misma semántica de governance (`governance truth`, `reason_code`, `instruction`, `next_action`).
12
+ - **RuralGo evidence pack**: nuevo `npm run validation:ruralgo-s1-evidence-pack -- --consumer-root <repo> --package-version <semver>` para preparar la validación real de `PUMUKI-INC-071/073/076`.
13
+ - **Sin regresión de 6.3.72**: esta release preserva `lifecycle audit`, `consumer postinstall resolve args`, `detectPlatforms` y `full surface smoke`, en vez de volver a una base `6.3.71`.
14
+ - **Rollout**: publicar `pumuki@6.3.73`, repinear primero RuralGo y ejecutar el evidence pack con la semver publicada antes de mover ningún `INC` a `FIXED`.
15
+
9
16
  ### 2026-04-11 (v6.3.72)
10
17
 
11
18
  - **Tarball npm**: `package.json` → `files` incluye `AGENTS.md`, `CHANGELOG.md` y `docs/tracking/plan-curso-pumuki-stack-my-architecture.md` para lectura canónica vía npm / jsDelivr sin depender solo del repo Git.
12
19
  - **`gate.blocked` (macOS)**: banner de Notification Center **y** modal por defecto (evita cero notificaciones si el modal no llega a mostrarse desde un hook); dedupe opcional: `PUMUKI_MACOS_GATE_BLOCKED_BANNER_DEDUPE=1`.
20
+ - **Modal Swift**: `NSAlert.runModal()` en lugar de panel flotante para que los botones del diálogo respondan de forma fiable.
21
+ - **Postinstall consumer**: por defecto `pumuki install --with-mcp --agent=repo` y fusión conservadora en `.pumuki/adapter.json` (`json-merge`); opt-out `PUMUKI_POSTINSTALL_SKIP_MCP=1`.
22
+ - **Validación local**: `smoke:pumuki-surface` / `smoke:pumuki-surface-installed` y `validation:local-merge-bar` (sin depender de minutos de Actions). Detalle en `docs/validation/README.md`.
23
+ - **Tests en macOS:** `integrations/lifecycle/__tests__/cli.test.ts` evita notificaciones reales del sistema (`PUMUKI_DISABLE_SYSTEM_NOTIFICATIONS` en hooks) para que `npm test` / la barra local no queden colgados en PRE_WRITE strict.
13
24
  - **Menú / matriz consumer**: opciones motor `11–14`, matriz baseline alineada, vista classic opcional, etc. (ver `CHANGELOG.md`).
14
- - **Rollout**: `pumuki@6.3.72`; `pumuki doctor --json` + repin en consumidores (p. ej. RuralGO).
25
+ - **Rollout**: `pumuki@6.3.72`; `npm publish` cuando el tarball incluya lo anterior; luego `pumuki doctor --json` + repin en consumidores (p. ej. RuralGO).
15
26
 
16
27
  ### 2026-04-06 (v6.3.71)
17
28
 
@@ -130,10 +130,7 @@ Use `A` to switch to `Advanced` mode (full options), and `C` to return to `Consu
130
130
  Advanced mode options include short inline contextual help.
131
131
  Consumer mode is now a minimal read-only shell:
132
132
 
133
- - `1/2/3/4` are the canonical gate flows with **consumer preflight** before evaluation (labels state scope and PRE_COMMIT vs PRE_PUSH).
134
- - `11/12/13/14` run the **engine** with **no preflight**: staged only, unstaged only (index→working tree + untracked), full working tree under **PRE_COMMIT**, or **all tracked files** (full repo). They write `.ai_evidence.json` on **PRE_COMMIT** engine runs like other menu audits.
135
- - After each successful evidence read, the menu prints a **second panel** (“Classic evidence view”) with **ANSI-colored** enterprise/legacy severity counts, optional **platform** rows from `snapshot.platforms`, and a longer ranked violation list. Disable with `PUMUKI_MENU_VINTAGE_REPORT=0`.
136
- - Options **2** and **4** (PRE_PUSH): if outcome is **PASS** or **WARN**, a short hint explains that a **tracked** `.ai_evidence.json` may **not** be rewritten on disk; use `PUMUKI_PRE_PUSH_ALWAYS_WRITE_TRACKED_EVIDENCE=1` for local debugging.
133
+ - `1/2/3/4` are the canonical read-only gate flows
137
134
  - `8` exports the same evidence snapshot in markdown form
138
135
  - `5/6/7/9` remain available only as `Legacy Read-Only Diagnostics`
139
136
 
@@ -252,7 +249,7 @@ Stage mapping:
252
249
  If a scope is empty, the menu prints an explicit operational hint (`Scope vacío`), so `PASS` with zero findings is distinguishable from a clean repository scan.
253
250
 
254
251
  System notifications (macOS) can be enabled from advanced menu option `31` (persisted in `.pumuki/system-notifications.json`).
255
- On non-macOS platforms, the same payloads are written to **stderr** by default (visible in the terminal) because there is no native banner API. Set `PUMUKI_DISABLE_STDERR_NOTIFICATIONS=1` to silence that path (delivery reports `unsupported-platform` on those OSes). On macOS, set `PUMUKI_NOTIFICATION_STDERR_MIRROR=1` to duplicate **any** notification payload to stderr in addition to the system notification. For **`gate.blocked`** specifically, stderr mirroring is **on by default** when the macOS path reports success (so a failed push/commit still prints a `[pumuki]` block in the terminal even if the banner does not appear); disable only that default with `PUMUKI_DISABLE_GATE_BLOCKED_STDERR_MIRROR=1`. The **blocked modal** (Swift floating / AppleScript) with **Desactivar / Silenciar 30 min / Mantener activas** is **on by default** whenever notifications are enabled and `blockedDialogEnabled` is omitted in `.pumuki/system-notifications.json`. Turn it off with `"blockedDialogEnabled": false` or `PUMUKI_MACOS_BLOCKED_DIALOG=0`. **`gate.blocked`** now emits **both** the Notification Center banner (`osascript`) **and** the interactive modal by default, so consumers (e.g. hooks in other repos) still get a visible banner if the modal cannot attach to a GUI session. To restore the previous “modal only” behaviour and suppress the duplicate banner, set `PUMUKI_MACOS_GATE_BLOCKED_BANNER_DEDUPE=1`. If you see **no** notifications at all: confirm `PUMUKI_DISABLE_SYSTEM_NOTIFICATIONS` is unset, delete or fix `.pumuki/system-notifications.json` (absent file defaults to enabled), and ensure the terminal app is allowed to show notifications in **System Settings → Notifications**.
252
+ On non-macOS platforms, the same payloads are written to **stderr** by default (visible in the terminal) because there is no native banner API. Set `PUMUKI_DISABLE_STDERR_NOTIFICATIONS=1` to silence that path (delivery reports `unsupported-platform` on those OSes). On macOS, set `PUMUKI_NOTIFICATION_STDERR_MIRROR=1` to duplicate **any** notification payload to stderr in addition to the system notification. For **`gate.blocked`** specifically, stderr mirroring is **on by default** when the macOS path reports success (so a failed push/commit still prints a `[pumuki]` block in the terminal even if the banner does not appear); disable only that default with `PUMUKI_DISABLE_GATE_BLOCKED_STDERR_MIRROR=1`. The **blocked modal** (Swift floating / AppleScript) with **Desactivar / Silenciar 30 min / Mantener activas** is **on by default** whenever notifications are enabled and `blockedDialogEnabled` is omitted in `.pumuki/system-notifications.json`. Turn it off with `"blockedDialogEnabled": false` or `PUMUKI_MACOS_BLOCKED_DIALOG=0`. Ensure the terminal app is allowed to show notifications in **System Settings → Notifications**.
256
253
  Blocked notifications now use a native Swift floating modal (bottom-right) by default, with AppleScript fallback.
257
254
  Override mode with `PUMUKI_MACOS_BLOCKED_DIALOG_MODE=auto|swift-floating|applescript`.
258
255
  Custom skills import is available in advanced menu option `33` (writes `/.pumuki/custom-rules.json`).
@@ -1,111 +1,62 @@
1
- # Diseño pedagógico y seguimiento — Curso Pumuki (Stack My Architecture)
1
+ # Seguimiento — Curso Pumuki (Stack My Architecture)
2
2
 
3
- Este documento define **qué debe aprender una persona**, **en qué orden**, **cómo se comprueba** y **qué confusiones hay que romper**. El seguimiento de repos y build va **al final**; no sustituye el diseño.
3
+ Iniciativa formativa: quinto curso del ecosistema Stack My Architecture. **No** sustituye el espejo operativo de producto en [`plan-activo-de-trabajo.md`](./plan-activo-de-trabajo.md).
4
4
 
5
- No sustituye el espejo de producto en [`plan-activo-de-trabajo.md`](./plan-activo-de-trabajo.md).
5
+ ## Leyenda
6
6
 
7
- ## Leyenda operativa
8
-
9
- - ✅ Entregado en repo curso + coherente con USAGE/INSTALLATION
10
- - 🚧 Única tarea activa (máx. 1)
7
+ - Cerrado
8
+ - 🚧 En construccion (maximo 1)
11
9
  - ⏳ Pendiente
12
10
  - ⛔ Bloqueado
13
11
 
14
- ---
15
-
16
- ## 1. Para quién es y qué problema resuelve
17
-
18
- **Quién:** desarrollador o tech lead que debe **vivir** con hooks, CI y (a veces) agentes; no auditor de slides.
19
-
20
- **Problema:** en la práctica mezcla *SDD*, *gate*, *MCP*, *evidencia* y *menú*; cuando algo bloquea no sabe **qué capa** falló ni **qué comando** la inspecciona.
21
-
22
- **Éxito del curso:** tras cerrarlo, en un repo real puede (1) nombrar el **stage** y el **scope** de un fallo, (2) leer **`.ai_evidence.json`** y relacionarlo con stderr, (3) distinguir **enforcement** (hooks/CI) de **lectura/agente** (MCP), (4) ejecutar el **flujo SDD mínimo** sin confundirlo con “arreglar reglas”, (5) instalar, actualizar o **retirar** Pumuki sin dejar hooks huérfanos.
23
-
24
- Si eso no se cumple, el curso falla aunque el HTML sea bonito.
25
-
26
- ---
27
-
28
- ## 2. Modelo mental único (todo el curso orbita aquí)
29
-
30
- Una sola frase que el alumno debe poder repetir:
31
-
32
- **Hechos del diff/código reglas efectivas decisión del gate por stageregistro en evidencia v2.1.**
33
-
34
- Todo lo demás (menú, MCP, notificaciones, `doctor`) es **acceso** a ese mismo pipeline o **comodidad**; no es un segundo producto.
35
-
36
- ---
37
-
38
- ## 3. Confusiones que el material debe desmontar de forma explícita
39
-
40
- Cada unidad del curso debe tener al menos un párrafo “**no confundas**” o un mini escenario:
41
-
42
- | Confusión típica | Verdad operativa |
43
- |------------------|------------------|
44
- | “Sin MCP no hay Pumuki” | Los **hooks y CI** son el enforcement; MCP es **opcional** para IDE/agente. |
45
- | “SDD es lo mismo que el gate” | SDD/OpenSpec gobierna el **cambio**; el gate evalúa **código + política + evidencia** en un **scope** concreto. |
46
- | “`openspec` en el PATH basta” | Pumuki usa OpenSpec **repo-local** (`node_modules/.bin`). |
47
- | “PRE_COMMIT limpio push seguro” | **PRE_PUSH** mira otro **scope** (`upstream..HEAD`). |
48
- | “El menú es la fuente de verdad” | El menú **orquesta** diagnósticos; la fuente de verdad es **policy + stage + evidencia**. |
49
- | “Borrar el paquete limpia el repo” | `npm uninstall pumuki` **no** quita hooks/lifecycle; hace falta **`pumuki remove`** / flujo documentado. |
50
-
51
- Si el Markdown del curso no nombra estas líneas, el plan pedagógico sigue vacío aunque haya tablas de check.
52
-
53
- ---
54
-
55
- ## 4. Secuencia didáctica (orden de primera lectura)
56
-
57
- El repo del curso incluye la **columna vertebral en prosa** `00-preparacion/03-recorrido-cero-a-cien-pumuki.md` (0→100 % sin saltos) y el **proyecto guiado** `02-modulos/13-proyecto-guiado-de-la-a-la-z.md` (fases A–M con criterios de hecho). Esta tabla U0–U10 sigue siendo el contrato de **outcomes**; esas piezas son el **relato** y el **laboratorio** que los materializan.
58
-
59
- El **mapa completo** (`00-mapa-completo-del-producto.md`) es **referencia** para quien ya perdió el hilo; la **primera pasada** debe seguir esta secuencia para no cargar conceptos antes de tiempo.
60
-
61
- | Orden | Unidad | Objetivo observable (el alumno demuestra…) | Actividad mínima en lab | Criterio de dominio |
62
- |-------|--------|---------------------------------------------|-------------------------|----------------------|
63
- | U0 | Preparación + versión + lab | Que existe documentación canónica y un repo donde ensayar | Abrir USAGE e INSTALLATION; fijar versión mínima `pumuki` | Explica en una frase dónde miente un “funciona en mi máquina” sin `doctor` |
64
- | U1 | Contrato + stages + cobertura | Qué pregunta **cada** stage y qué es `unevaluated_rule_ids` | Un `pre-commit` / `pre-push` y leer evidencia | Predice scope antes de ejecutar y acierta al comparar con JSON |
65
- | U2 | Instalación y primer verde | Postinstall, `bootstrap` vs `install`, `pathExecutionHazard` | `doctor --json` antes/después de un cambio reversible | Usa `alignmentCommand` o workaround sin improvisar |
66
- | U3 | Ciclo de vida completo | Diferencia `npm uninstall`, `pumuki uninstall`, `pumuki remove`, `update --latest` | Simular retirada en rama de prueba | Lista qué queda en disco tras cada comando |
67
- | U4 | Evidencia | Dónde se escribe, cuándo **no** se reescribe (PRE_PUSH trackeado), restage PRE_COMMIT | Diff de `.ai_evidence.json` entre stages | Explica un caso “hook modificó archivo” sin pánico |
68
- | U5 | Menú interactivo | Consumer vs Advanced; 1–4/8/9; matrix; variables UI | Correr `pumuki-framework` y una opción de cada familia | Enlaza opción de menú con **stage** y **scope** equivalentes |
69
- | U6 | MCP | Evidence vs enterprise; HTTP vs stdio; recibo PRE_WRITE | Levantar o inspeccionar config en `.pumuki/adapter.json` | Explica por qué el gate puede pasar con MCP caído |
70
- | U7 | SDD/OpenSpec | Flujo diario: `sdd status`, `session`, `validate`; catálogo de códigos | Abrir sesión de cambio y validar un stage | Clasifica un JSON de bloqueo en “falta OpenSpec” vs “falta sesión” |
71
- | U8 | Notificaciones y watch | macOS vs stderr; `system-notifications.json`; anti-spam de `watch` | Una sesión `watch --once` o documentada | Elige variable correcta para silenciar o espejar |
72
- | U9 | Perfiles, Governance, monorepo | Cuándo bajar de enterprise; prefijos de scope; parity | (Según perfil del equipo) | Justifica un perfil sin autoboicot |
73
- | U10 | Cierre | Checklist operativa propia del equipo | Checklist escrita a partir del curso | Puede enseñar el modelo mental §2 a otra persona en 3 minutos |
74
-
75
- **Regla:** ninguna fila U1–U10 puede considerarse “hecha” solo con un enlace a USAGE; debe existir **narrativa + comando + actividad + criterio** en el Markdown del curso.
76
-
77
- ---
78
-
79
- ## 5. Qué el curso no debe intentar (límites)
80
-
81
- - Sustituir el curso **SDD** (OpenSpec, Kanban del cambio) ni el **Governance** (AGENTS, cultura): solo **enganchar** Pumuki a ellos.
82
- - Sustituir tests de producto, revisión humana ni criterios de negocio.
83
- - Prometer “cero lectura de USAGE”: USAGE sigue siendo norma; el curso debe **enseñar** lo mismo con **menor fricción**, no duplicar mal.
84
-
85
- ---
86
-
87
- ## 6. Estado de entrega en el repo (operativo, subordinado al §4)
88
-
89
- | Unidad §4 | Estado en `stack-my-architecture-pumuki` |
90
- |-----------|-------------------------------------------|
91
- | U0–U2 | ✅ Base + módulo 2; ciclo de vida **completo** en **08** |
92
- | U3 | ✅ `02-modulos/08-ciclo-de-vida-install-uninstall-actualizacion.md` |
93
- | U4 | ✅ `02-modulos/09-evidencia-por-stage-y-ai-evidence-json.md` |
94
- | U5 | ✅ `02-modulos/10-menu-interactivo-matrix-y-preflight.md` |
95
- | U6 | ✅ `02-modulos/11-mcp-enforcement-vs-lectura-agente.md` |
96
- | U7 | ✅ Módulo **04** ampliado (§4.6–4.8 + criterio dominio) |
97
- | U8 | ✅ `02-modulos/12-notificaciones-macos-stderr-y-watch.md` |
98
- | U9–U10 | ✅ Revisar checklist **07** frente a criterios §4 en próxima iteración |
99
-
100
- | Task | Estado |
101
- |------|--------|
102
- | Implementar U3–U8 en `.md` + `FILE_ORDER` + validación | ✅ |
103
- | CHANGELOG curso + rebuild HTML + sync hub local | ✅ (incl. CSS lectura **0.3.1**) |
104
- | Push hub + deploy Vercel (ver curso en prod) | 🚧 |
105
-
106
- ---
107
-
108
- ## 7. Auditoría técnica (no confundir con evaluación del alumno)
109
-
110
- - `python3 scripts/validate-course-structure.py` y `check-links.py` en repo curso.
111
- - Publicación hub según tu script; URL `/pumuki/` 200.
12
+ ## Regla de uso
13
+
14
+ - Solo puede existir **una** tarea `🚧` a la vez en este documento.
15
+ - Actualizar estados al cerrar fases o al desbloquear dependencias.
16
+ - Repos objetivo: `stack-my-architecture-pumuki` (curso), `stack-my-architecture-hub` (publicación), enlaces en `stack-my-architecture-governance` y `stack-my-architecture-SDD`.
17
+ - Producto de referencia: repo `ast-intelligence-hooks` (paquete npm `pumuki`). Documentación canónica: `README.md`, `docs/product/USAGE.md`, `docs/product/INSTALLATION.md`.
18
+
19
+ ## Contexto
20
+
21
+ - **Objetivo:** curso dedicado a Pumuki como capa de enforcement (`Facts → Rules → Gate → evidencia v2.1`) en repos reales, sin re-enseñar OpenSpec ni ADR (remite a cursos SDD y Governance).
22
+ - **`courseId` propuesto:** `stack-my-architecture-pumuki` (alinear con hub y progress sync).
23
+ - **Versión mínima `pumuki` (MVP):** `>= 6.3.71` (ajustar al publicar el curso si hay release posterior).
24
+ - **Lab de práctica:** variante o fork de **GovernanceKit** (Governance) o **HelpdeskSDD** (SDD); documentado en `00-preparacion/02-lab-governancekit-helpdesksdd.md` del repo del curso.
25
+
26
+ ## Estado actual
27
+
28
+ - **Cierre local y release gate:** `build-hub.sh --mode strict` + smoke runtime en verde.
29
+ - **Origen en GitHub:** el repo **`stack-my-architecture-hub`** tiene en **`main`** la carpeta estática **`pumuki/`** y el pipeline `build-hub` que la genera (sincronizado con remoto; despliegue a producción con el workflow cuando toque).
30
+ - **Repo Pumuki (ramas):** la documentación del curso en este repositorio está integrada en **`develop`** (**PR #746**, merge `428f10d`). La rama **`main`** del producto va **muy por detrás** de `develop` (del orden de **~600** commits a fecha de integración del plan); promover `develop` `main` es un **release de producto** aparte, no parte del cierre de este plan formativo.
31
+ - **GitHub Actions:** la org **no** dispone de cuota útil para Actions → el **Hub Production Release Gate** en CI **no** se usa como gate; publicación y comprobaciones **en local** con `./scripts/publish-architecture-stack.sh` en el repo del hub (Vercel CLI + mismos scripts).
32
+ - **Publicación Vercel:** deploy del proyecto `stack-my-architecture-hub` con verificación de rutas contra el alias **`https://stack-my-architecture-hub.vercel.app`** (incluye `/pumuki/` 200). El script `publish-architecture-stack.sh` infiere la base desde `Aliased:` (o `SMA_PUBLISH_VERIFY_BASE_URL`) y escribe **`.runtime/publish-verify-base.url`** para alinear `post-deploy-checks.sh` con la URL verificada (localmente o cuando Actions vuelva a estar disponible).
33
+ - Si **`https://architecture-stack.vercel.app`** debe exponer el mismo árbol estático que el hub, sincroniza proyecto/CNAME según tu setup (nota emitida por el script al publicar).
34
+
35
+ ## Prioridad ordenada (fases y tareas)
36
+
37
+ | Fase | Task | Estado | Notas |
38
+ |------|------|--------|--------|
39
+ | 0 | Crear repo `stack-my-architecture-pumuki` + README + estructura carpetas | ✅ | Repo bajo `stack-my-architecture/stack-my-architecture-pumuki` |
40
+ | 0 | Definir `courseId` y versión mínima `pumuki` | | `stack-my-architecture-pumuki`, `>= 6.3.71` |
41
+ | 0 | Elegir proyecto lab (GovernanceKit vs HelpdeskSDD) | ✅ | Documentado en preparación del curso |
42
+ | 1 | Redactar roadmap semanal/módulos (`01-roadmap/`) | | |
43
+ | 1 | Módulos 1–7 MVP (lecciones + enlaces USAGE/README Pumuki) | | `02-modulos/` + referencias npm/docs producto |
44
+ | 2 | Integración hub: ruta `/pumuki` + `build-hub.sh` + launcher | | `stack-hub --course pumuki`, assets desde ios parcheados |
45
+ | 2 | Assistant `courseId` + smoke | | `_hub-platform.js`, `hub-app.js`, README hub + ejemplo curl |
46
+ | 3 | Enlaces desde Governance y SDD | | Semana 8 checkpoint + SDD semana 8 |
47
+ | 3 | (Opcional) Anexo iOS/Android Arquitecto/Maestría | | `00-core-mobile/04-calidad-pr-ready.md` iOS y Android |
48
+ | 4 | Scripts validación curso + primera publicación | ✅ | Curso: validate + check-links; hub: publish strict + `/pumuki/` 200 en alias hub |
49
+
50
+ ## Criterios de cierre por fase
51
+
52
+ - **Fase 0:** repo clonable, README con prerequisitos y convenciones, scripts mínimos ejecutables.
53
+ - **Fase 1:** siete módulos enlazados a docs oficiales Pumuki; roadmap con orden de lectura.
54
+ - **Fase 2:** `build-hub` genera ruta servible; `stack-hub --course pumuki` documentado.
55
+ - **Fase 3:** enlaces mergeados en repos Governance y SDD (y opcional iOS/Android).
56
+ - **Fase 4:** checklist publicación + versión `pumuki` fijada en lecciones y CHANGELOG del curso.
57
+
58
+ ## Auditoría y release (Fase 4)
59
+
60
+ - Ejecutar en el repo del curso: `scripts/validate-course-structure.py`, `scripts/check-links.py`.
61
+ - Publicación hub: modo `strict` en `Hub Production Release Gate`; verificación de rutas incluye `/pumuki/` en `publish-architecture-stack.sh`.
62
+ - Tras cada release npm relevante de Pumuki, revisar versión mínima en `00-preparacion/` y en este plan.
@@ -0,0 +1,230 @@
1
+ import type { AiGateStage } from './evaluateAiGate';
2
+
3
+ export type GovernanceCatalogNextAction = {
4
+ kind: 'info' | 'run_command';
5
+ message: string;
6
+ command?: string;
7
+ };
8
+
9
+ export type GovernanceCatalogAction = {
10
+ reason_code: string;
11
+ instruction: string;
12
+ next_action: GovernanceCatalogNextAction;
13
+ };
14
+
15
+ const PRE_WRITE_VALIDATE_COMMAND =
16
+ 'npx --yes --package pumuki@latest pumuki sdd validate --stage=PRE_WRITE --json';
17
+
18
+ export const buildGovernanceValidateCommand = (stage: AiGateStage): string =>
19
+ PRE_WRITE_VALIDATE_COMMAND.replace('PRE_WRITE', stage);
20
+
21
+ export const buildGovernancePolicyReconcileCommand = (stage: AiGateStage): string =>
22
+ `npx --yes --package pumuki@latest pumuki policy reconcile --strict --json && ${buildGovernanceValidateCommand(stage)}`;
23
+
24
+ const buildFallbackAction = (code: string): GovernanceCatalogAction => ({
25
+ reason_code: code,
26
+ instruction: 'Corrige el bloqueante primario y vuelve a ejecutar la validación del stage actual.',
27
+ next_action: {
28
+ kind: 'info',
29
+ message: 'Corrige el bloqueante primario y vuelve a ejecutar el mismo comando.',
30
+ },
31
+ });
32
+
33
+ export const resolveGovernanceCatalogAction = (params: {
34
+ code: string;
35
+ stage?: AiGateStage;
36
+ fallback?: GovernanceCatalogAction;
37
+ }): GovernanceCatalogAction => {
38
+ const stage = params.stage ?? 'PRE_WRITE';
39
+ const validateCommand = buildGovernanceValidateCommand(stage);
40
+ switch (params.code) {
41
+ case 'READY':
42
+ return {
43
+ reason_code: 'READY',
44
+ instruction: 'Puedes continuar con la siguiente slice mínima y volver a validar al cerrar.',
45
+ next_action: {
46
+ kind: 'info',
47
+ message: 'Gate en verde. Continúa con la implementación.',
48
+ },
49
+ };
50
+ case 'EVIDENCE_INVALID_OR_CHAIN':
51
+ return {
52
+ reason_code: 'EVIDENCE_INVALID_OR_CHAIN',
53
+ instruction: 'Regenera la evidencia canónica antes de continuar.',
54
+ next_action: {
55
+ kind: 'run_command',
56
+ message: 'Regenera o corrige la evidencia canónica (.ai_evidence.json) y vuelve a validar governance.',
57
+ command: validateCommand,
58
+ },
59
+ };
60
+ case 'AI_GATE_BLOCKED':
61
+ return {
62
+ reason_code: 'AI_GATE_BLOCKED',
63
+ instruction: 'Corrige primero el bloqueo principal del gate antes de continuar.',
64
+ next_action: {
65
+ kind: 'run_command',
66
+ message: 'Revalida el stage tras corregir la evidencia y el bloqueo principal.',
67
+ command: validateCommand,
68
+ },
69
+ };
70
+ case 'SDD_SESSION_MISSING':
71
+ return {
72
+ reason_code: 'SDD_SESSION_MISSING',
73
+ instruction: 'Abre una sesión SDD válida antes de seguir trabajando.',
74
+ next_action: {
75
+ kind: 'run_command',
76
+ message: 'Abre la sesión SDD del cambio activo y vuelve a validar.',
77
+ command: 'npx --yes --package pumuki@latest pumuki sdd session --open --change=<id>',
78
+ },
79
+ };
80
+ case 'SDD_SESSION_INVALID':
81
+ case 'SDD_SESSION_INVALID_OR_EXPIRED':
82
+ return {
83
+ reason_code: 'SDD_SESSION_INVALID_OR_EXPIRED',
84
+ instruction: 'Refresca o reabre la sesión SDD antes de seguir trabajando.',
85
+ next_action: {
86
+ kind: 'run_command',
87
+ message: 'Refresca la sesión SDD y vuelve a validar governance.',
88
+ command: 'npx --yes --package pumuki@latest pumuki sdd session --refresh --ttl-minutes=90',
89
+ },
90
+ };
91
+ case 'PRE_PUSH_UPSTREAM_MISSING':
92
+ return {
93
+ reason_code: 'PRE_PUSH_UPSTREAM_MISSING',
94
+ instruction: 'Configura el upstream remoto antes de continuar con PRE_PUSH.',
95
+ next_action: {
96
+ kind: 'run_command',
97
+ message: 'Configura tracking remoto para la rama actual.',
98
+ command: 'git push --set-upstream origin <branch>',
99
+ },
100
+ };
101
+ case 'PRE_PUSH_UPSTREAM_MISALIGNED':
102
+ return {
103
+ reason_code: 'PRE_PUSH_UPSTREAM_MISALIGNED',
104
+ instruction: 'Alinea el upstream remoto con la rama actual antes de continuar.',
105
+ next_action: {
106
+ kind: 'run_command',
107
+ message: 'Reconfigura el upstream remoto de la rama actual.',
108
+ command: 'git branch --unset-upstream && git push --set-upstream origin <branch>',
109
+ },
110
+ };
111
+ case 'GITFLOW_PROTECTED_BRANCH':
112
+ case 'GITFLOW_PROTECTED_BRANCH_CONTEXT':
113
+ return {
114
+ reason_code: 'GITFLOW_PROTECTED_BRANCH_CONTEXT',
115
+ instruction: 'Sal de la rama protegida y mueve el trabajo a feature/* o refactor/*.',
116
+ next_action: {
117
+ kind: 'run_command',
118
+ message: 'Crea una rama válida de trabajo antes de seguir.',
119
+ command: 'git checkout -b feature/<descripcion-kebab-case>',
120
+ },
121
+ };
122
+ case 'POLICY_STAGE_NOT_STRICT':
123
+ return {
124
+ reason_code: 'POLICY_STAGE_NOT_STRICT',
125
+ instruction: 'Reconcilia policy/skills en modo estricto antes de seguir.',
126
+ next_action: {
127
+ kind: 'run_command',
128
+ message: 'Converge policy-as-code y revalida el stage actual.',
129
+ command: buildGovernancePolicyReconcileCommand(stage),
130
+ },
131
+ };
132
+ case 'SKILLS_CONTRACT_SURFACE_INCOMPLETE':
133
+ case 'EVIDENCE_SKILLS_CONTRACT_INCOMPLETE':
134
+ return {
135
+ reason_code: 'SKILLS_CONTRACT_SURFACE_INCOMPLETE',
136
+ instruction: 'Materializa el lock/sources de skills antes de dar governance efectiva.',
137
+ next_action: {
138
+ kind: 'run_command',
139
+ message: 'Reconcilia policy/skills y vuelve a validar governance.',
140
+ command: buildGovernancePolicyReconcileCommand(stage),
141
+ },
142
+ };
143
+ case 'ADAPTER_WIRING_MISSING':
144
+ return {
145
+ reason_code: 'ADAPTER_WIRING_MISSING',
146
+ instruction: 'Instala el adaptador canónico si quieres wiring explícito de IDE/MCP.',
147
+ next_action: {
148
+ kind: 'run_command',
149
+ message: 'Genera `.pumuki/adapter.json` desde la instalación canónica.',
150
+ command: 'npx --yes --package pumuki@latest pumuki install --with-mcp',
151
+ },
152
+ };
153
+ case 'EVIDENCE_STALE':
154
+ case 'EVIDENCE_BRANCH_MISMATCH':
155
+ case 'EVIDENCE_SNAPSHOT_WARN':
156
+ return {
157
+ reason_code: params.code === 'EVIDENCE_SNAPSHOT_WARN' ? 'EVIDENCE_SNAPSHOT_WARN' : 'EVIDENCE_STALE',
158
+ instruction: 'Refresca evidencia y revisa hallazgos WARN antes de continuar.',
159
+ next_action: {
160
+ kind: 'run_command',
161
+ message: 'Revalida el stage actual y revisa findings WARN.',
162
+ command: validateCommand,
163
+ },
164
+ };
165
+ case 'ACTIVE_RULE_IDS_EMPTY_FOR_CODE_CHANGES_HIGH':
166
+ case 'EVIDENCE_ACTIVE_RULE_IDS_EMPTY_FOR_CODE_CHANGES':
167
+ return {
168
+ reason_code: 'EVIDENCE_ACTIVE_RULE_IDS_EMPTY_FOR_CODE_CHANGES',
169
+ instruction: 'Reconcilia policy/skills en modo estricto y revalida el stage actual.',
170
+ next_action: {
171
+ kind: 'run_command',
172
+ message: 'Converge policy-as-code y vuelve a validar cobertura de active_rule_ids para reglas activas.',
173
+ command: buildGovernancePolicyReconcileCommand(stage),
174
+ },
175
+ };
176
+ case 'EVIDENCE_PLATFORM_SKILLS_SCOPE_INCOMPLETE':
177
+ case 'EVIDENCE_PLATFORM_SKILLS_BUNDLES_MISSING':
178
+ return {
179
+ reason_code: params.code,
180
+ instruction: 'Completa cobertura de skills por plataforma y vuelve a validar.',
181
+ next_action: {
182
+ kind: 'run_command',
183
+ message: 'Completa bundles/prefijos de skills requeridos y revalida el stage actual.',
184
+ command: validateCommand,
185
+ },
186
+ };
187
+ case 'EVIDENCE_PLATFORM_CRITICAL_SKILLS_RULES_MISSING':
188
+ case 'EVIDENCE_CROSS_PLATFORM_CRITICAL_ENFORCEMENT_INCOMPLETE':
189
+ return {
190
+ reason_code: params.code,
191
+ instruction: 'Reconcilia policy/skills en modo estricto para enforcement crítico y revalida.',
192
+ next_action: {
193
+ kind: 'run_command',
194
+ message: 'Materializa reglas críticas de plataforma y vuelve a validar el stage actual.',
195
+ command: buildGovernancePolicyReconcileCommand(stage),
196
+ },
197
+ };
198
+ case 'EVIDENCE_PREWRITE_WORKTREE_OVER_LIMIT':
199
+ case 'EVIDENCE_PREWRITE_WORKTREE_WARN':
200
+ return {
201
+ reason_code: params.code,
202
+ instruction: 'Particiona el worktree en slices atómicos antes de continuar.',
203
+ next_action: {
204
+ kind: 'run_command',
205
+ message: 'Reduce el worktree pendiente y revalida el stage actual.',
206
+ command: `git status --short && git add -p && ${validateCommand}`,
207
+ },
208
+ };
209
+ case 'SKILLS_SKILLS_FRONTEND_NO_SOLID_VIOLATIONS':
210
+ return {
211
+ reason_code: 'SKILLS_SKILLS_FRONTEND_NO_SOLID_VIOLATIONS',
212
+ instruction: 'Aplica refactor incremental por componente/hook y vuelve a validar.',
213
+ next_action: {
214
+ kind: 'info',
215
+ message: 'Aplica refactor incremental: extrae 1 componente/hook por commit y vuelve a ejecutar el gate.',
216
+ },
217
+ };
218
+ case 'GOVERNANCE_ATTENTION':
219
+ return {
220
+ reason_code: 'GOVERNANCE_ATTENTION',
221
+ instruction: 'Revisa governance truth y corrige el primer hueco del contrato antes de continuar.',
222
+ next_action: {
223
+ kind: 'info',
224
+ message: 'Revisa governance truth, corrige el primer gap visible y vuelve a validar.',
225
+ },
226
+ };
227
+ default:
228
+ return params.fallback ?? buildFallbackAction(params.code);
229
+ }
230
+ };
@@ -1372,7 +1372,15 @@ export async function runPlatformGate(params: {
1372
1372
 
1373
1373
  if (gateOutcome === 'BLOCK') {
1374
1374
  if (params.silent !== true) {
1375
- dependencies.printGateFindings(findingsWithWaiver);
1375
+ const renderStage =
1376
+ params.policy.stage === 'PRE_PUSH'
1377
+ ? 'PRE_PUSH'
1378
+ : params.policy.stage === 'CI'
1379
+ ? 'CI'
1380
+ : 'PRE_COMMIT';
1381
+ dependencies.printGateFindings(findingsWithWaiver, {
1382
+ stage: renderStage,
1383
+ });
1376
1384
  }
1377
1385
  return 1;
1378
1386
  }
@@ -19,10 +19,6 @@ export type GateScope =
19
19
  kind: 'workingTree';
20
20
  extensions?: string[];
21
21
  }
22
- | {
23
- kind: 'unstaged';
24
- extensions?: string[];
25
- }
26
22
  | {
27
23
  kind: 'range';
28
24
  fromRef: string;
@@ -31,6 +27,7 @@ export type GateScope =
31
27
  };
32
28
 
33
29
  const DEFAULT_EXTENSIONS = ['.swift', '.ts', '.tsx', '.js', '.jsx', '.kt', '.kts'];
30
+ export const DEFAULT_FACT_FILE_EXTENSIONS = DEFAULT_EXTENSIONS;
34
31
 
35
32
  export const countScannedFilesFromFacts = (facts: ReadonlyArray<Fact>): number => {
36
33
  const contentPaths = new Set<string>();
@@ -70,9 +67,6 @@ export const resolveFactsForGateScope = async (params: {
70
67
  if (params.scope.kind === 'workingTree') {
71
68
  return params.git.getStagedAndUnstagedFacts(extensions);
72
69
  }
73
- if (params.scope.kind === 'unstaged') {
74
- return params.git.getUnstagedFacts(extensions);
75
- }
76
70
 
77
71
  return getFactsForCommitRange({
78
72
  fromRef: params.scope.fromRef,