# before_0_1 > Lo que hay que **cerrar, incluir o verificar** antes de etiquetar > `0.1.0`. Construido sobre las evidencias del repo a fecha de hoy y los > hallazgos del audit. Un par de bloqueantes son políticas / hygiene que > pesan más que cualquier hallazgo técnico individual. --- ## 1. Qué significa `0.1` aquí (definición operativa) `0.1` no es _production-ready_. Es la versión que **un equipo externo puede probar sin sorpresas grandes**, sabiendo que la API pública no romperá silenciosamente durante la línea `0.1.x`. Esto fija el listón: - API pública de los 9 roots always-present **congelada** durante `0.1.x`. - Las 5 factorías scoped (`Sium`, `Session`, `Connections`, `Auth`, `Permissions`) pueden iterar pero deben respetar deprecation policy. - Sin bugs de seguridad conocidos en flujos hot. - Repo aceptable para un PR externo: licencia, README, contributing, CI. - Docs suficientes para enviar una feature sin leer el código fuente. - Build estático funciona end-to-end (no solo el typecheck). Lo que **no** entra en `0.1`: MFA en producción, OAuth con todos los proveedores, todos los módulos con docs profundas, métricas / telemetría, ejemplos reales más allá de las páginas `/test`. --- ## 2. Estado real verificado hoy Antes de listar gaps, lo que ya está cerrado (corroborado leyendo el repo, los tests y los gates locales): - **Tests reales**: 108 archivos / 1208 tests verdes. - **Typecheck**: `npm run check` 0/0/0. - **Build estático**: `npm run build` verde. - **Gate completo**: `npm run test:all` verde (`check` + `test` + `build` + `test:static` + `test:bundle`). - **Bundle smoke**: `createActiveApp({})` está medido con Vite/OXC en `scripts/bundle-smoke.mjs`; baseline actual ~65 KB gzip, presupuesto `0.1` en 70 KB gzip configurable con `ACTIVE_BUNDLE_GZIP_LIMIT_KB`. - **Refactor wave** documentada en `NEXT_STEPS.md` ha resuelto parcialmente varios de mis hallazgos del audit: - **C2/C3** (Auth → Permissions/Cache invalidation) — cableado a través de `arts/aapp/integrations/auth-cache.ts`. _A verificar_ con tests de race cross-actor que el flujo real cierra el gap. - **C1** (perm race cross-actor) — el cliente perm se ha partido en `client-cache.ts` / `client-keys.ts` / `client-snapshot.ts`. _A verificar_ que `pending` se invalida en `hydrate` / cambio de scope. - Cobertura: `auth + sess + perm + cach` ya tienen test de integración cruzada. - **Brand brief** (`BRAND.md`) escrito y assets estáticos añadidos. - **Documentación interna** (`/active`): shell + landing + Get Started, páginas para todos los módulos bajo `docs/`, sección de capa servidor (`$svrs`), seguridad, versionado y guía para AI agents. La profundidad por módulo sigue siendo desigual y es trabajo pendiente. Lo que **sigue abierto** sale en §3. --- ## 3. Bloqueantes duros para `0.1` Cada bloqueante lleva una _Acceptance criteria_ verificable. ### 3.1 Repo hygiene Estado actual: | Pieza | Estado | Evidencia | | ------------------ | ------- | --------------------------------------------------------------------------------------------- | | `LICENSE` | Cerrado | Existe y coincide con `package.json` (`UNLICENSED`). | | `README.md` | Cerrado | Incluye tagline, quick start, módulos, desarrollo, seguridad y link a `BRAND.md`. | | `SECURITY.md` | Cerrado | Política de reporte y threat model resumido. | | `CONTRIBUTING.md` | Cerrado | Setup, verificación, layout, constants-first, logging/diagnostics y deprecation policy. | | `CHANGELOG.md` | Cerrado | Sigue Keep a Changelog y abre `0.1.0` como target. | | `.github/` | Cerrado | CI, bug report, feature request y PR template. | | `.gitignore` | Cerrado | Ignora `tmp-active-docs-*.log` y estado local de IDE/herramientas sin ignorar auditorías/docs. | | `package.json` | Cerrado | `license`, `engines.node`, `repository`, `bugs` y `homepage` presentes. | Queda como higiene manual: no commitear directorios personales (`.claude/`, `.opencode/`, `.idea/`) ni logs temporales ya ignorados. ### 3.2 Seguridad Varios puntos del audit ya están cerrados en código y tests. Mantenerlos aquí como evidencias evita que el checklist vuelva a arrastrar deuda antigua: | ID | Estado | Evidencia | | --- | -------- | ------------------------------------------------------------------------------------------------------ | | S1 | Cerrado | `rate-limit.test.ts`; password, recovery y OAuth llaman `enforceAuthRateLimit(...)`. | | S2 | Cerrado | `oauth-pkce.test.ts`; `completeOAuth` entrega `codeVerifier` al provider y valida el challenge. | | S3 | Cerrado | `engine-password.test.ts`; `verifyMfaChallenge` no está en la superficie estable de `EngineAuth`. | | S4 | Cerrado | Auth y Cache memory adapters emiten warning productivo con tests; `svrs/perm` no tiene memory adapter. | | S5 | Cerrado | `AUTH_COOKIE_POLICY.SAME_SITE` es `strict`; `csrf.test.ts` lo cubre. | | S6 | Cerrado | `client-http.test.ts` cubre in-flight decisions y batch/what tras cambio de actor/scope. | | ID | Bloqueante | Acceptance | | --- | ------------------------------ | ------------------------------------------------------------------------------------------------------ | | S7 | Cerrado | `SECURITY.md` documenta cookie scopes, CSRF flow, refresh rotation, OAuth state binding, MFA actual y actor/tenant model. | ### 3.3 Correctitud / API | ID | Estado | Evidencia | | --- | ------- | -------------------------------------------------------------------------------------------------------------- | | A1 | Cerrado | `AUTH_METHOD_*` / `PERMISSION_METHOD_*` se usan en `ensureLive`; tests verifican mensajes post-dispose. | | A2 | Cerrado | `active-app.test.ts` incluye snapshot de superficie de roots y factories scoped actuales. | | A4 | Cerrado | `AuthRateLimitPort` se exporta porque S1 está cableado y cubierto por tests. | | A5 | Cerrado | Mono Lang está documentado como passthrough tipado amplio; warnings DEV pasan por `Logger` bajo `lang.mono`. | | ID | Bloqueante | Acceptance | | --- | ------------------------------------ | ----------------------------------------------------------------------------------------------------------- | | A3 | Cerrado | `CONTRIBUTING.md` describe `@deprecated`, warning runtime, `__EXPERIMENTAL_*` y ventana mínima de una minor. | ### 3.4 Documentación mínima `/active` ya tiene rutas para todos los módulos, pero la profundidad sigue siendo desigual. Para `0.1`: | Bloqueante | Acceptance | | ----------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------- | | Los **9 roots always-present** con docs reales (no stub). | `App, Lang, Logger, Formats, Frontend, Dom, Storage, Http, Timers, Cache` tienen sección Overview / Quick start / API / Limits / Testing. | | Las 5 factorías scoped pueden ser stub si llevan una nota "shape final en `0.2`". | El stub indica explícitamente qué partes de su API no están comprometidas. | | `SECURITY.md` (cubre S7) **enlazado** desde sidebar de `/active`. | Item en la sección `Get Started` con ruta `/active/security`. | | Migration / versioning policy publicada. | Página `/active/get-started/versioning` o sección dentro de Composition. | ### 3.5 Build y tooling | Pieza | Estado | Evidencia | | ---------------------- | ------- | -------------------------------------------------------------------------------------------------- | | Build estático | Cerrado | `npm run build` está incluido en `test:all` y fue verificado localmente. | | CI en GitHub Actions | Cerrado | `.github/workflows/ci.yml` ejecuta typecheck, tests, build, static smoke y bundle smoke. | | Scripts npm completos | Cerrado | `test:typecheck`, `test:static`, `test:bundle` y `test:all` existen. | | Reproducibilidad | Cerrado | `package-lock.json`, `.nvmrc` y `engines.node >=22` presentes. | | Bundle size sanity | Cerrado | `scripts/bundle-smoke.mjs` verifica `createActiveApp({})` contra `ACTIVE_BUNDLE_GZIP_LIMIT_KB`. | > `npm run lint` existe, pero sigue siendo deuda global pre-`0.1`; CI no > lo ejecuta hasta que el árbol completo quede limpio. La regla mientras > tanto es no añadir deuda nueva en archivos tocados. ### 3.6 Marca y assets Estado actual: | Pieza | Estado | Evidencia | | --------------------------- | ------- | ----------------------------------------------------------------------------------------- | | `static/favicon.svg` | Cerrado | SVG presente. | | `favicon-16/32/48.png` | Cerrado | PNGs presentes. | | `apple-touch-icon.png` | Cerrado | Icono 180 presente. | | `icon-192/512.png` | Cerrado | Iconos PWA presentes. | | `icon-maskable-512.png` | Cerrado | Icono maskable presente. | | `og-image.png` | Cerrado | Imagen OG presente. | | `app.html` | Cerrado | Theme color, description, OG tags, favicons, apple-touch-icon y manifest enlazados. | | `manifest.webmanifest` | Cerrado | Manifest presente con iconos. | Queda como revisión manual: abrir `/active` en navegador real y comprobar contraste/legibilidad de sidebar, code blocks y callouts en tema claro/oscuro. --- ## 4. Bloqueantes blandos (pueden caer en `0.1.1`–`0.1.x`) Son hallazgos del audit con impacto real pero acotables a un parche: - M4 (refactor `validateOptionalField` en sess) — limpieza; no rompe nada. - M5 (acoplamiento `aapp` ↔ `stor` en mensajes de log) — se puede pulir más tarde sin tocar la superficie pública. - M9 (body-scroll-lock con scheduling propio en vez de delegar a `timr`) — optimización; no afecta la API. - M10 (HTTP recompone headers en cada retry) — perf, no semántica. - M14 (sess `BroadcastChannel` ignora el `event` recibido y vuelve a leer storage) — documentar como diseño y seguir. - m1–m15 (menores: docs faltantes, magic strings residuales, refactors cosméticos). Estos pueden entrar como issues etiquetados `0.1.x` y resolverse de manera incremental. --- ## 5. Fuera de alcance para `0.1` (explícito) Para evitar que el sprint se infle, dejar fuera y comunicarlo: - MFA real (TOTP, WebAuthn, recovery codes). - OAuth provider catalog (GitHub, Google, etc.) — solo el motor + un proveedor de ejemplo. - Métricas / telemetría / OpenTelemetry export. - Server-side rendering completo del docs site (es estático). - Componentes UI prefabricados (eso vive _encima_ de los artefactos). - Internacionalización del propio docs site (English-only en `0.1`). - Distribución por `npm publish` — `0.1` puede vivir solo como repo template / submódulo / vendoring. Decidir si publicar es objetivo. --- ## 6. Verificación pre-tag (un solo comando) Antes de etiquetar `0.1.0`, todo esto debe pasar en CI y local: ```sh # 1. Gate completo automatizado npm run test:all # → check + tests + build + static smoke + bundle smoke # 2. Tipos, si se quiere aislar el paso npm run check # → 0 errors / 0 warnings # 3. Suite, si se quiere aislar el paso npm test # → 0 failed; assert >= 1208 tests # 4. Build estático, si se quiere aislar el paso npm run build # → produce build/ sin errores # 5. Bundle smoke, si se quiere aislar el paso npm run test:bundle # → createActiveApp({}) <= 70 KB gzip por defecto # 6. Static smoke, si se quiere aislar el paso tras build npm run test:static # → rutas/docs/assets críticos existen en build/ ``` Y, cuando se quiera verificar el sitio servido: ```sh npm run preview curl -fsS http://localhost:4173/active | grep -q "active" curl -fsS http://localhost:4173/test/ecosystem | grep -q "ecosystem" ``` `npm run lint` debe ejecutarse antes del tag, pero hoy todavía representa una limpieza global separada. No debe bloquear el gate automático hasta que esa deuda esté cerrada. Y manual: - [ ] Abrir `/active` y `/test/ecosystem` en Chromium, Firefox, Safari desktop. **No console errors. No layout shifts grandes.** - [ ] `App.dispose()` se llama dos veces seguidas → no throw, no warn. - [ ] Cambio de locale a `ar` aplica `dir="rtl"` y propaga a Formats. - [ ] Sign-in → sign-out limpia perm cache y session bridge. - [ ] Refresh durante revoke → no resucita la sesión. - [ ] 404 en una ruta `/active/docs/` → muestra fallback. - [ ] Tema oscuro: contraste suficiente en sidebar activo, code blocks, callouts. --- ## 7. Orden sugerido Dos sprints serios bastan si nadie se desvía. **Sprint A — Seguridad y correctitud** Cerrado para el estado actual: S1, S2, S3, S4, S5, S6, S7, A1, A2, A3, A4 y A5. **Sprint B — Hygiene, docs y release (1 semana)** 1. Repo hygiene: LICENSE, README, CONTRIBUTING, SECURITY, CHANGELOG, `.github/` con CI básica. 2. A2/A3 — snapshot tests de superficie + política de deprecación escrita. **Cerrado para la superficie actual**; mantenerlo actualizado con cada miembro público nuevo. 3. Completar los 9 roots always-present en `/active/docs`. 4. Marca: ejecutar al menos `favicon.svg` + `favicon-32/16` + `og-image.png` + meta tags en `app.html`. 5. Build estático, static smoke y bundle smoke verificados en CI. 6. Tag `0.1.0` con changelog real. --- ## 8. Decisiones abiertas (necesitan criterio humano antes de avanzar) 1. **¿Se publica en npm o se distribuye como repo / template?** Cambia la forma de empaquetar (`exports`, `files`, `sideEffects` granular). 2. **¿`AuthRateLimitPort` se cablea ahora o se posterga?** Si se posterga, sacarlo del barrel hasta `0.2`. 3. **¿MFA en `0.1` o explicitamente en `0.2`?** Hoy está stubbed; un stub que lanza no debe estar en la superficie pública. 4. **¿`mono-lang` es público o interno?** Si público, se documenta y se asume el cast laxo; si interno, se quita del barrel. 5. **¿La doc de los 5 factorías scoped (`Sess`, `Auth`, `Perm`, `Conn`, `Sium`) llega a `0.1` profunda o stub?** Mi recomendación: `Auth`, `Sess` y `Perm` profundas (son las que un consumidor pisa en onboarding); `Conn` y `Sium` pueden quedar como stubs marcados. 6. **¿Adapter Static es el target final?** Si hay plan de SSR (auth server-side real), conviene cambiar a `adapter-node` antes de `0.1` para no romper consumidores en `0.1.x`. 7. **¿La API de `App.Cache.invalidate({tags})` queda como contrato estable?** Se merece ser parte del primer snapshot test de superficie porque cae en el camino crítico de `Auth`. --- ## 9. Métricas de "listo" Cuando todo lo anterior pase, el repo debería poder responder _sí_ a: - "¿Un dev externo clona, sigue el README y arranca `/active` en < 5 min?" - "¿Existe un punto de contacto claro para reportar un fallo de seguridad?" - "¿Hay manera de saber qué cambia entre `0.1.0` y `0.1.1` sin leer commits?" - "¿La superficie de los 9 roots always-present está documentada con una garantía explícita de no-break en la línea `0.1.x`?" - "¿Si elimino los assets de marca, queda algo identificable en el navegador?" (Hoy: no, `static/` solo tiene `robots.txt`). Si las cinco respuestas son sí, etiqueta `0.1.0`.