You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

550 lines
20 KiB

# Auditoria Codex - ecosistema Active + Orca
Fecha: 2026-05-04
Workspace: `G:\dev\svelte\active`
## Alcance
Se audito el estado actual del ecosistema con foco en el nuevo modulo
`src/arts/orca` y sus puntos de acoplamiento con:
- `src/arts/active-app`
- `src/arts/bus`
- `src/arts/session`
- `src/arts/cache`
- `src/arts/perm`
- `src/arts/connection`
- documentacion publica en `src/arts/*/README.md` y pagina activa generada.
No se modifico codigo existente. El arbol ya tenia cambios previos en:
- `src/arts/orca/consts.ts`
- `src/arts/orca/result.ts`
- `src/arts/orca/types.ts`
Esos cambios parecen corregir parte de la deriva de comentarios `v0.1+` respecto a
timeout/fatal/gates/compensation, pero no cierran todos los problemas.
## Veredicto
`orca` esta bien orientado arquitectonicamente. La decision fuerte, y la que
realmente eleva el ecosistema, es mover las reacciones inter-modulo a una capa de
orquestacion declarativa situada en `active-app`, no dentro de `cache`, `perm`,
`session` o `connection`. Eso reduce acoplamiento y permite testear flujos
compuestos como objetos de ejecucion (`OrcaRunResult`).
El modulo, sin embargo, ya ha crecido mas rapido que su contrato. El motor actual
implementa gates, timeouts de accion, compensacion, transacciones, payloads en
tokens, fan-in y politicas de cola. La documentacion mezcla tres versiones a la
vez: boceto conceptual, v0 inicial y estado real. Antes de seguir expandiendo
`orca`, conviene congelar el contrato real y eliminar ambiguedades.
Estado de pruebas focalizadas:
```txt
npx vitest run src/arts/orca/test src/arts/active-app/test/presets.test.ts
Test Files 4 passed
Tests 169 passed
```
## Hallazgos P1
### 1. Liberacion de trace no es segura con runs paralelos
Referencia:
- `src/arts/orca/engine-orca.ts:928`
- `src/arts/orca/engine-orca.ts:931`
- `src/arts/orca/engine-orca.ts:935`
`maybeReleaseTrace()` borra `traceStates` si no quedan eventos en cola. El propio
comentario reconoce que no sabe si hay runs en vuelo del mismo trace. Eso era
defendible con ejecucion estrictamente secuencial, pero ya existe
`ORCA_QUEUE_PARALLEL`. Si dos eventos derivados del mismo trace corren en
paralelo, el primero que termine puede borrar el estado de trace mientras el otro
sigue vivo.
Impacto:
- Los contadores `maxDepth`, `maxEventsPerTrace`, `repeatedEventLimit` y
`dedupeKey` pueden resetearse antes de tiempo.
- Un loop por eventos derivados puede saltarse la proteccion si el trace se borra
mientras quedan runs paralelos activos.
- La trazabilidad de un flujo enterprise deja de ser confiable justo en el modo
mas peligroso: paralelo.
Recomendacion:
- Mantener `traceInFlightCount` por `traceId`.
- Incrementarlo en `spawnRun()`.
- Decrementarlo en el `finally` de `executeRun()`.
- Liberar el trace solo cuando `queuedCount(traceId) === 0` e
`inFlightCount(traceId) === 0`.
- Anadir test: dos eventos derivados con `ORCA_QUEUE_PARALLEL` en el mismo trace;
el primero termina, el segundo emite otro evento repetido y el guard sigue
aplicando.
### 2. `provides` no limita `emits`, asi que la validacion puede mentir
Referencia:
- `src/arts/orca/types.ts:421`
- `src/arts/orca/types.ts:424`
- `src/arts/orca/types.ts:425`
- `src/arts/orca/engine-orca.ts:1117`
- `src/arts/orca/engine-orca.ts:1124`
El contrato dice que `provides` es lo que una accion puede producir, y
`validate()` usa `provides` para detectar tokens imposibles. Pero el runtime
acepta cualquier token que venga en `result.emits`, aunque no este declarado en
`provides`.
Impacto:
- `validate()` no es una garantia fuerte; es una estimacion basada en intencion.
- Una accion puede desbloquear otra con un token que el grafo no declaraba.
- Un typo en `emits` puede cambiar el pipeline sin que `validate()` lo vea.
- El futuro `setupOrca()` tipado pierde parte de su sentido si el runtime permite
emisiones fuera de esquema.
Recomendacion:
- En modo dev, lanzar o registrar `CONFIGURATION_INVALID` cuando una accion emite
un token no declarado en `provides`.
- En modo prod, al menos registrar diagnostic `orca.configuration.invalid` o
descartar el token no declarado segun opcion.
- Documentar excepcion solo si se decide permitir tokens dinamicos, pero entonces
`validate()` debe llamarse "best effort", no "static graph validation".
### 3. `ORCA_QUEUE_REPLACE` no es `replace-current`, solo reemplaza queued
Referencia:
- `src/arts/orca/consts.ts:73`
- `src/arts/orca/engine-orca.ts:420`
- `src/arts/orca/engine-orca.ts:421`
- `src/arts/orca/engine-orca.ts:422`
- `src/arts/orca/README.md:439`
- `src/arts/orca/README.md:1444`
Hay dos semanticas distintas usando el mismo nombre mental:
- Una seccion del README describe `replace` como "aborta el run activo y empieza
uno nuevo", estilo `takeLatest`.
- El motor implementa "reemplaza solo entradas queued; no aborta in-flight".
- Otra seccion posterior del README ya reconoce esta realidad.
Impacto:
- Para formularios, busquedas, navegacion o cambio de identidad, un usuario puede
esperar "ultima intencion gana", pero el run anterior seguira ejecutandose.
- Si la accion vieja muta cache/conexiones despues de la nueva, puede pisar estado.
- El nombre `replace` es ambiguo para usuarios que vienen de saga/Rx/RTK.
Recomendacion:
- Renombrar la politica actual a algo explicito: `ORCA_QUEUE_REPLACE_QUEUED` o
`ORCA_QUEUE_LATEST_QUEUED`.
- Reservar `ORCA_QUEUE_REPLACE_CURRENT` / `ORCA_QUEUE_TAKE_LATEST` para la
variante fuerte que aborta in-flight.
- Si se mantiene el nombre actual, borrar del README cualquier promesa de abortar
el run activo.
### 4. IDs de run/event/trace usan `Date.now()` y `Math.random()` fuera de `timr`
Referencia:
- `src/arts/orca/engine-orca.ts:1513`
- `src/arts/orca/engine-orca.ts:1514`
- `src/arts/orca/engine-orca.ts:1517`
- `src/arts/orca/engine-orca.ts:1518`
- `src/arts/orca/engine-orca.ts:1521`
- `src/arts/orca/engine-orca.ts:1522`
- `src/arts/orca/README.md:841`
El README establece que `orca` no debe usar `Date.now()` ni `setTimeout()`
directamente. Los timestamps del envelope ya pasan por `timers.clock.now()`, pero
los IDs de run/event/trace no.
Impacto:
- Tests y replay no son plenamente deterministas.
- En SSR/hydration o tests con clocks controlados, los IDs no siguen el tiempo
simulado.
- La disciplina "todo tiempo via timr" queda rota justo en el modulo que quiere
ser trazable.
Recomendacion:
- Anadir `idFactory` a `EngineOrcaOptions` o tres factories separadas:
`runIdFactory`, `eventIdFactory`, `traceIdFactory`.
- Default: contador monotono con prefijo, alimentado por `timers.clock.now()` si
se quiere incluir tiempo.
- Tests: factory determinista para snapshots.
### 5. `setupOrca()` esta documentado como API recomendada pero no existe
Referencia:
- `src/arts/orca/README.md:235`
- `src/arts/orca/README.md:241`
- `src/arts/orca/README.md:271`
- `src/arts/orca/README.md:284`
- `src/arts/orca/README.md:1271`
- `src/arts/orca/index.ts`
El README recomienda `setupOrca()` para apps grandes y muestra ejemplos, pero no
hay export ni implementacion en `src/arts/orca`.
Impacto:
- La documentacion invita a usar una API inexistente.
- El usuario no sabe si debe usar `App.Orca.onEvent()` directo, presets o un
setup tipado futuro.
- La promesa de validacion fuerte de tokens/eventos queda sin soporte.
Recomendacion:
- O implementar un `setupOrca()` minimo, aunque solo envuelva `onEvent` con
declaracion de eventos/tokens/actions.
- O mover esa seccion a "Futuro / v0.1" y dejar claro que v0 real es
`createEngineOrca()` + `App.Orca.onEvent()`.
### 6. La integracion con `connection` no esta cerrada y la documentacion promete mas de lo que existe
Referencia:
- `src/arts/active-app/presets/standard.ts:28`
- `src/arts/active-app/presets/index.ts:5`
- `src/arts/active-app/service-factories/connections.ts:9`
- `src/arts/connection/README.md:83`
- `src/arts/connection/README.md:93`
- `src/arts/connection/README.md:100`
- `src/arts/connection/session-wiring.ts:27`
`applyStandardOrca()` solo registra presets de cache y perm. No hay preset para
`connections.reauthenticateAll()` ni para `connections.closeAll()` en cambios de
identidad/revoke/expire. A la vez, la documentacion de `connection` habla de
`autoReauthOn: 'standard'` y de escuchar `SESSION_EVENT_IDENTITY_CHANGED`.
Ademas, `defineActiveConnections()` ya no inyecta `bus` ni `session`; el comentario
dice que identidad debe venir por orca preset o por una `session` manual, pero ese
preset no existe.
Impacto:
- Una app que siga la documentacion puede creer que las conexiones se reautentican
al cambiar de usuario, pero con `applyStandardOrca(App)` no ocurre.
- El caso critico que motivo `orca` ("chat conectado con credenciales del usuario
anterior") sigue sin preset estandar.
- `connection` conserva un mecanismo interno de `session-wiring` que compite
conceptualmente con la nueva regla: los artefactos publican/reciben eventos; la
app orquesta reacciones.
Recomendacion:
- Crear preset en `active-app/presets`:
`applyConnectionsReauthOnIdentityChange(App)`.
- Definir si el estandar hace `reauthenticateAll()` o `closeAll()` cuando no hay
credencial nueva.
- Actualizar `applyStandardOrca()` para incluir conexiones cuando `App.connections`
exista.
- Decidir si `connection.session-wiring` queda como modo local/manual o se depreca
a favor del preset de `orca`.
## Hallazgos P2
### 7. `runActionWithTimeout()` aborta de forma cooperativa, pero la accion puede seguir mutando estado
Referencia:
- `src/arts/orca/engine-orca.ts:1042`
- `src/arts/orca/engine-orca.ts:1052`
- `src/arts/orca/engine-orca.ts:1056`
- `src/arts/orca/engine-orca.ts:1058`
- `src/arts/orca/engine-orca.ts:1070`
El timeout hace `actionController.abort()` y resuelve `orcaTimeout(timeoutMs)`, pero
la promesa original de la accion sigue viva si la accion no respeta `ctx.signal`.
Esto es normal en JS, pero debe tratarse como contrato de seguridad.
Impacto:
- Una accion timeout puede mutar cache, conexiones o permisos despues de que el run
ya haya tomado otra decision.
- Los tests pueden pasar porque el resultado es `timeout`, pero el side-effect
tardio queda fuera del trace.
Recomendacion:
- Documentar que toda accion async debe comprobar `ctx.signal.aborted` antes y
despues de awaits relevantes.
- Anadir helper `ctx.throwIfAborted()` o `orcaAbortIfSignaled(ctx)`.
- Anadir test: accion con timeout que intenta mutar despues; demostrar que el
patron recomendado lo evita.
### 8. La cola es global para eventos no-parallel, aunque el contrato se lee como per-event
Referencia:
- `src/arts/orca/engine-orca.ts:526`
- `src/arts/orca/engine-orca.ts:527`
- `src/arts/orca/engine-orca.ts:529`
- `src/arts/orca/engine-orca.ts:531`
`canStartRun()` serializa globalmente todos los eventos no-parallel:
`nonParallelInFlight === 0`. Eso significa que un evento lento de `cache` puede
bloquear un evento no relacionado de `perm`, `connection` o cualquier feature.
Impacto:
- Semantica mas conservadora y lenta de lo que sugiere "queue policy per event".
- Posible cuello de botella en apps grandes con flujos independientes.
- Si esta decision es intencional, falta nombrarla como "single lane".
Recomendacion:
- Decidir explicitamente:
- Modelo A: serializacion global por defecto, documentada como garantia simple.
- Modelo B: serializacion por evento, con concurrencia entre eventos distintos.
- Si se mantiene A, renombrar/comentar como `globalSerialLane`.
- Si se pasa a B, usar `inFlightByEvent` para bloquear solo el mismo evento.
### 9. `commit()` congela el grafo; eso choca con features lazy si no se documenta como modo prod
Referencia:
- `src/arts/orca/types.ts:711`
- `src/arts/orca/types.ts:723`
- `src/arts/orca/engine-orca.ts:1275`
- `src/arts/orca/test/engine-orca.test.ts:4013`
El comportamiento actual esta claro en codigo y tests: despues de `commit()`,
`onEvent()` y `configureEvent()` lanzan `OrcaFrozenError`. Esto no es un bug por
si mismo, pero tensiona el objetivo de registrar acciones desde features
lazy-loaded.
Impacto:
- Si una app llama `App.Orca.commit()` durante bootstrap, una ruta lazy ya no puede
registrar sus acciones al cargar.
- HMR/devtools pueden quedar bloqueados si no se separa "validar" de "sellar".
Recomendacion:
- Documentar `commit()` como opcion production/seal, no como paso obligatorio.
- Considerar `validate()` para dev y `commit()` solo para builds donde el grafo es
completo al arrancar.
- Si se quiere lazy + freeze, introducir versionado por evento: cada run usa un
snapshot, pero el registro global puede crecer entre runs.
### 10. `ctx.emit()` es correcto, pero la atribucion via `bus.publish()` depende de AsyncLocalStorage
Referencia:
- `src/arts/orca/engine-orca.ts:133`
- `src/arts/orca/engine-orca.ts:204`
- `src/arts/orca/engine-orca.ts:864`
- `src/arts/orca/als.ts`
- `src/arts/orca/README.md:606`
- `src/arts/orca/README.md:621`
- `src/arts/orca/README.md:1470`
El diseno correcto es claro: modulo -> `bus.publish()`, accion -> `ctx.emit()`.
El motor intenta interceptar `bus.publish()` dentro de acciones mediante
AsyncLocalStorage cuando esta disponible. En navegador puede no estar disponible,
por lo que el mismo `bus.publish()` dentro de una accion puede ser hijo en Node y
root event en browser.
Impacto:
- Trazas distintas entre SSR/tests Node y browser.
- Reentry guards no aplican igual si un evento derivado sale como root.
Recomendacion:
- Mantener la regla dura: las acciones usan `ctx.emit()` siempre.
- Tratar la interceptacion ALS como bonus diagnostico, no como contrato.
- Anadir lint/documentacion: no usar `App.Bus.publish()` dentro de una accion de
`orca` salvo que se quiera crear root event explicito.
### 11. `engine-orca.ts` ya es un monolito de responsabilidades
Referencia:
- `src/arts/orca/engine-orca.ts` (~58 KB)
El engine concentra registro, cola, trace state, reentry, ejecucion de waves,
timeouts, compensation, validation, ID generation, diagnostics y public API.
Impacto:
- Dificulta revisar invariantes delicadas como "trace cleanup + parallel".
- Hace mas probable que futuras features (`runTimeoutMs`, `setupOrca`, inspector)
entren sin frontera clara.
- Ya contradice la direccion del ecosistema de reducir monolitos (`connection.ts`
se venia refactorizando por el mismo motivo).
Recomendacion de split:
- `queue.ts`: enqueue, policies, drain, in-flight counters.
- `trace.ts`: envelope, trace state, reentry guards, release.
- `runner.ts`: stages, waves, action execution, status precedence.
- `timeouts.ts`: action timeout helpers y timer keys.
- `compensation.ts`: LIFO compensation / transaction compensation.
- `validation.ts`: validate/commit helpers.
- `ids.ts`: factories deterministas.
- `engine-orca.ts`: composicion publica.
### 12. Los presets usan action ids y tokens inline/locales
Referencia:
- `src/arts/active-app/presets/cache-clear-on-identity-change.ts:6`
- `src/arts/active-app/presets/cache-clear-on-identity-change.ts:7`
- `src/arts/active-app/presets/cache-clear-on-revoke.ts:6`
- `src/arts/active-app/presets/cache-clear-on-revoke.ts:7`
- `src/arts/active-app/presets/perm-invalidate-on-identity-change.ts:6`
- `src/arts/active-app/presets/perm-invalidate-on-identity-change.ts:7`
Los eventos del ecosistema ya estan centralizados como constantes, pero los
`ACTION_ID` y `TOKEN_*` de presets quedan como strings locales no exportados.
Impacto:
- No se pueden reutilizar en tests de integracion, docs, inspector `/test/orca`
o setup tipado.
- Rompe la regla emergente: "eventos, tokens y action ids como constantes".
- El inspector no puede mostrar nombres canonicos importables.
Recomendacion:
- Crear `src/arts/active-app/presets/consts.ts` o exportar desde cada preset:
`APP_ORCA_ACTION_CACHE_CLEAR_ON_IDENTITY_CHANGE`,
`APP_ORCA_TOKEN_CACHE_CLEARED_ON_IDENTITY_CHANGE`, etc.
- Usar nombres de constantes en README y pagina docs.
## Hallazgos P3
### 13. Header de `engine-orca.ts` esta obsoleto
Referencia:
- `src/arts/orca/engine-orca.ts:24`
- `src/arts/orca/engine-orca.ts:25`
- `src/arts/orca/engine-orca.ts:26`
El comentario inicial dice que `after`, `unless`, `abortOn`,
`actionTimeoutMs` y `compensate` se aceptan pero se ignoran. El motor ya los
implementa.
Impacto:
- La siguiente persona que lea el archivo empieza con un mapa mental falso.
- Ya se corrigieron comentarios en `types.ts`, `consts.ts` y `result.ts`, pero el
comentario mas importante del motor sigue atrasado.
Recomendacion:
- Actualizar el bloque de cabecera para describir el estado real.
- Evitar version tags contradictorios dentro del codigo; mover roadmap al README.
### 14. El README de `orca` mezcla contrato actual, boceto y roadmap en un solo flujo
Referencia:
- `src/arts/orca/README.md:511`
- `src/arts/orca/README.md:1411`
- `src/arts/orca/README.md:1506`
- `src/arts/orca/README.md:1522`
Ejemplo claro: una seccion dice que en v0 los tokens son flags sin payload; otra
seccion posterior dice que los tokens con payload ya estan implementados. Esto no
es solo estetico: afecta al modo en que un desarrollador modela acciones.
Impacto:
- La documentacion no sirve como contrato normativo.
- Los lectores no saben si estan viendo la version deseada o la version real.
Recomendacion:
- Reestructurar README en tres bloques cerrados:
- "Contrato actual implementado"
- "Patrones recomendados"
- "Roadmap / no implementado"
- Eliminar del contrato actual cualquier API no exportada (`setupOrca`) o moverla
a roadmap.
- Mantener una tabla "Feature -> estado -> archivo/test".
### 15. Falta una prueba compuesta del caso que motivo `orca`: cambio de usuario con cache/perm/connection
Referencias:
- `src/arts/active-app/test/presets.test.ts`
- `src/arts/orca/test/engine-orca.test.ts`
Hay buena cobertura unitaria de `orca` y presets basicos. Falta el escenario
ecosistema que debe probar el valor real:
1. Usuario A abre sesion.
2. Chat/conexion usa credencial A.
3. Cache actor-scoped guarda datos de A.
4. Perm calcula snapshot de A.
5. Cambia a usuario B.
6. Orca ejecuta clear cache, invalidate perm y reauth/close connection.
7. Ningun dato/credencial de A queda observable.
Impacto:
- El sistema puede estar correcto por modulo pero fallar justo en composicion.
- El caso "chat con credenciales antiguas" sigue sin prueba de regresion.
Recomendacion:
- Crear test de integracion en `src/arts/active-app/test/ecosystem-orca.test.ts`
o equivalente.
- Usar fakes de cache/perm/connection con counters y credenciales capturadas.
- Verificar orden por `OrcaRunResult`: cache -> perm -> connection si se decide
dependencia via tokens.
## Observaciones positivas
- `App.Bus`, `App.Timers` y `App.Orca` ya son core siempre presentes en
`createActiveApp()`, y `Orca` es inerte hasta registrar acciones. Esa decision
encaja con el diseno enterprise sin obligar a cada app a crear singletons
manuales.
- Los presets viven en `active-app/presets`, no dentro de los artefactos. Esto es
correcto: `cache` no debe conocer `session`; `perm` no debe conocer `auth`;
`orca` no debe conocer modulos.
- `ActiveOrca` es un wrapper fino y razonable: estado reactivo, sin meter logica
del engine en Svelte.
- La suite focalizada de `orca` ya es grande: 169 tests entre engine/active/result
y presets. Para un modulo recien nacido, eso es muy buena base.
- `ctx.signal` existe en `OrcaActionContext`; eso habilita cancelacion cooperativa
y es la direccion correcta.
## Recomendacion de orden de trabajo
1. Corregir P1.1: trace cleanup con runs paralelos.
2. Cerrar P1.2: `provides` debe ser contrato real o `validate()` debe declararse
best-effort.
3. Resolver P1.3: renombrar/split de `replace` para evitar semantica ambigua.
4. Sustituir `Date.now()`/`Math.random()` por factories deterministas.
5. Decidir `setupOrca()`: implementarlo minimo o moverlo fuera de v0.
6. Crear preset de `connection` y test compuesto usuario A -> usuario B.
7. Reordenar README para separar implementado/recomendado/roadmap.
8. Refactorizar `engine-orca.ts` por responsabilidades antes de anadir run/stage
timeout, inspector visual o setup tipado.
## Conclusion
`orca` merece seguir. No es "otro bus": es el sitio correcto para convertir
flujos inter-modulo en artefactos trazables y testeables. Pero precisamente por
eso no puede permitirse ambiguedad en nombres, timeouts, tokens y concurrencia.
El ecosistema esta cruzando una frontera importante: de librerias coherentes a
runtime de aplicacion. La prioridad ahora no es meter mas features, sino hacer
que el contrato de `orca` sea tan fiable como su idea.

Powered by TurnKey Linux.