| **D-AG.1b** | Factory feature-scoped `defineActiveAgent(...)` a nivel app (patrón auth/session); NADA en ActiveUix v1; promoción a accessor `uix.agent` con el consumidor canónico (precedente scene-D4) |
| **D-AG.1c** | Adaptadores de proveedor en `$agent/adapters/*` fuera del barrel (precedente `$logger/adapters`); **ScriptedAgentTransport determinista first-class** (tests sin mocks, demos estáticas) |
| **D-AG.2a** | Protocolo de eventos PROPIO espejo de AG-UI (5 categorías: run · deltas · tool-calls · estado · custom), nombres alineados con el canon; AG-UI = baseline de paridad (patrón ethereal) |
| **D-AG.2b** | El streaming lo posee cada adaptador (fetch+ReadableStream/SSE local); `$http`/`$connection` intactos |
| **D-AG.2c** | Estado = snapshot-por-turno v1; categoría snapshot/delta RESERVADA tipada; JSON Patch en la generalización |
Enmiendas menores a D-AG.2 aceptadas en triage (no alteran lo firmado, se
firman con el bloque §3): dirección tipada del canal de estado [F7], mapeo
wire de review/elicitación como confirmation-tool [F3e], versionado de
protocolo y manifiestos en el handshake del run [F12].
## §3 · Decisiones A FIRMAR (consolidadas del triage)
> Cada bloque es una decisión firmable. ⚖️ marca las bifurcaciones con
> alternativas reales donde hace falta TU elección; el resto lleva la forma
> recomendada ya consensuada por la revisión cruzada.
### D-AG.3 — Modelo de dominio y sesión [N1 · G1 · C1 · C3 · F2]
Nace CON el árbol de manifiestos (no después). Audita: manifiesto ↔ API
pública real (drift tipado) · tier de madurez declarado [F1a] · veracidad de
reversibilidad por-efecto (review-always para APIs de reemplazo destructivo)
[F5a] · **calidad model-facing** (descriptions no vacías, args descritos,
clases de fallo declaradas — determina si el modelo usa bien las capacidades)
[F12] · anti-falsificación de actor (ningún sitio del canon construye
contextos a mano) [F6b] · no-bypass (todo act mapea a puerta emisora).
## §4 · Secuencia de fases
> Regla heredada del precedente blocks/scene: decisiones firmadas ANTES de
> código; guard en la misma fase que crea la superficie que vigila; doctrina
> con gate propio.
| Fase | Contenido | Verifica / guard |
| --- | --- | --- |
| **F0 · Doctrina** ✅ (doc) | `docs/architecture/agent.md` ESCRITA + registrada en el índice: capítulo comparativo (matriz 6 refs + bibliografía de seguridad) · tesis+principios · dominio+máquina de estados · contrato de participación · **fila §0** · actor primitivo (⚖️2) · autorización · a11y · amenazas. **Corrección**: la fila §0 vive en la DOCTRINA (§4 del doc), no en `src/uix/contracts.ts` — el agente es un arte APP-level (D-AG.1b), no una capa UIX; su degradación se verifica en la suite del arte (`arts:check`) cuando F1 cree `arts/agent`, no en el boundary-test de UIX | `docs:check` ✅ 0/0 · (degradación → `arts:check` en F1) |
| **F1 · Motor mínimo** ✅ (2026-07-21) | **ENTREGADO** — `src/libs/actor` (ActorToken branded + sentinel `USER_ACTOR`) · `src/arts/agent` (24º arte, alias `$agent`): `EngineAgent` (máquina D-AG.4 completa — suggest/review/auto, escalated con reason+timeout, returned outcome-tipado, cancelled pre-autorización, kill switch, autorización journaled incluso auto; loop D-AG.5 — acts secuenciales, fallos→verbos, unknown-capability acotado, idempotencia por callId, presupuestos acts/turns/wall-clock, AbortSignal; techo por origen no-confiable F8b; acuñación de actor con registro privado WeakMap — forjados resuelven a null) + `ActiveAgent` (sesión reactiva, contrato ActiveEngine, `activeRun` para Aura) + puerto `AgentTransport` + protocolo v1 (`protocol.ts`: 5 categorías + dirección tipada + reservas state/elicitación + versionado) + `ScriptedAgentTransport` (`$agent/adapters/scripted`, fuera del barrel) + journal WAL (memory + webStorage, detección de huérfanos) + puerto de trazas OTel (run=trace, call=span, label no-autoritativa) + emisor sium→JSON Schema (`toJsonSchema`, nota de promoción a $sium al 2º consumidor) + costura `actor?` en `TriggerOptions→SemanticSignal` (runtime copia verbatim; sema no resuelve) + **`defineActiveAgent`** (service-factory app-level D-AG.1b: adapta el `ActiveTimers` del core al puerto `AgentTimersPort` + logger del core — cero setTimeout a pelo en runtime; tests con puerto manual determinista + flush `settle()` nombrado). | ✅ suite 18/18 · ✅ arts:check 0/0 (24 arts) · ✅ portabilidad (Engine sin DOM/runes) · ✅ anti-forja testeado · ✅ sema 178/178 · check: 0 errores propios |
| **F2 · Piloto palabras** | ESTE track entrega: capacidad tipada contra la API de palabras + OCC (_version) + write-scope + journal. El TRACK PALABRAS entrega su lado (4 ejes F-B firmados allí, puertas mudas promocionadas, `api.transact`, concurrencia espacial). Corre contra ScriptedAgentTransport | run end-to-end en demo estática · un run = un undo · Playwright |
| **F3 · Semántica + superficies** ✅ CERRADA (2026-07-22) | `allowedFamilies` delegate en el 1er componente actuado (→ REUBICADO a F2: su hogar natural es el piloto, el primer componente actuado real) · **Aura** (dueña de sustain-processing; live region; reduce static-frame) · ~~review-card~~**DESCARTADA como componente** (anclaje dev-tools; resolución 2026-07-22 con el usuario: framework = estados del ciclo expresados + afordancias authorize/reject/cancel — que Aura YA da — + semántica de «propuesto por otro actor»; el CONTENIDO de la review es del APP en su propio dominio; una tarjeta-diff es legítima a nivel de una app concreta, jamás canon — doctrina «The review surface» en agent.md §7) · pack sema de los eventos de superficie (resuelto: family-default, decisión firmada de capa 1). **Progreso 2026-07-21 — Aura fases 0–1 ✅**: decisión de pertenencia (SOMA; compose-first: orb=$scene en eidos, cancel=Button asChild, región propia espejo de Announce) + **morfo `aura.ts`** — EL PRIMER morfo del repo con eventos familia `delegate` (delegate-offer · delegate-escalate untilAction · delegate-return, los tres con requiresLiveRegion) + `sustain-processing` stateBound (dueña Aura, target indicator) + 5 partes (provider/indicator/status/**region** role=status aria-live=polite aria-atomic/cancel trigger) + texts (estados + anuncios atribuidos «Agent: …») + `expression: 'family-default'` (el perfil bajo de delegate es decisión firmada de capa 1; la modulación por intent de §F6 es visual → eidos/scene). Verificado: morfo:vocabulary limpio (solo WARN preexistente de cropper) · esquemas 114/114. Gotcha de convención: la clave de `stateRef` debe ser un VALOR representativo del vocabulario declarado (precedente progress/file-upload), no un nombre conceptual. **Fase 2 soma ✅ (2026-07-21)**: `soma/components/aura/` completo — provider raíz con puerto estructural `AuraAgentSource` (duck-type de ActiveAgent; soma NO importa $agent — degradación total: sin agente = idle válido), watcher de transiciones en constructor ($effect + untrack, cero write-loops), mapeo custody-of-control (authorized→acting; terminales→idle), `sustain-processing` stateBound con clearSignal al salir + guard de carrera (si el run avanzó antes de resolver el emit), `delegate-escalate` untilAction + clear en resolución, `delegate-return` = anuncio único consolidado atribuido en la Region PROPIA (role=status/polite/atomic — sin doble anuncio por la vía compartida), cancel() = salida global (disabled en idle, aria-label langs) + 5 wrappers + types + exports + README + catálogo `langs/components/aura.ts` (es/en) registrado + barrel soma. **Test 6/6** con `EngineSemantic({visual:false})` REAL (la degradación explícita del §0) — prueba emits/persistencias/clears de verdad; contracts sweep verde (solo los 2 fallos AJENOS preexistentes); svelte-check 0 errores propios. **Fases 4–5 eidos+recipe ✅ (2026-07-21)**: `eidos/components/aura/` completo — root `<Aura>` (data-size responsive sm/md/lg) · `<Aura.Indicator>` = el orb: **aurora `$scene` real** montada con el patrón de ciudadanía del pack (engine por superficie DOM WeakMap — eidos NO importa $packs, frontera dura), params modulados por estado según §F6 (velocidad/amplitud/hue: idle .35/.45 neutral → acting 1.2/1 primary → escalated 1.7/1.15 **threat**; reviewing **risk** — mapeo canon de intents), colores vía `eidos.resolveToken('--color-{role}-solid')` (jamás getComputedStyle), fallback = gradiente radial CSS del recipe (ES el render bajo reduced-motion static-frame del engine / SSR / effect off — la presencia nunca desaparece) · `<Aura.Cancel>` compone `<Button>` vía child/asChild (defaults diferidos al Button canónico — regla de la casa, sin ghost/neutral hardcodeado) · Status/Region passthrough · recipe `aura.css` sin @keyframes (R-4.5: el movimiento es del scene) + región sr-only + tokens `aura` en base.ts (orb-size por talla, tinte por estado en slots de rol re-tintables por tema). **Gates**: generate:eidos-css <20><>
| **F4a · Marco de integración APP** ✅ (2026-07-22) | **Auditoría completa del track** (encargo del usuario: divergencias + marco independiente del componente). Divergencias CAZADAS y CORREGIDAS (4 firmadas sin implementar): initiative→techo (C3: system/scheduled clampa auto→review) · presupuesto de contexto D-AG.5 (maxContextBytes, FIFO-trim byte-based, el goal sobrevive; resumen diferido) · tope por-arg F4c (maxArgBytes→invalid-args tipado) · schema de resultado D-AG.6d (`result?` Standard-Schema; mismatch = recoverable, no cuenta como act). Divergencias ESTRUCTURALES resueltas: **integración bus** (patrón session EXACTO: el arte posee el vocabulario `agent.*` en consts + bus-helpers tipados publican con bus INYECTADO; `defineActiveAgent` cablea `core.bus`; source='agent', **correlationId=runId** = la costura causal ligera sin el retrofit de 6 costuras) · **orca app-land** (el APP registra acciones sobre `agent.run.closed/escalated` — invariante intacto; probado con orca REAL) · **página del arte `/active/docs/agnt`** (convención de la casa que faltaba: sección Delegation en nav, artículo + **playground VIVO** con los 4 motores puros reales compuestos en página — bus log en vivo, journal WAL, contador orca, kill switch reactivo, compuertas deterministas). Gates: agent 26/26 (integration.test: spine motor→bus→orca real + los 4 fixes) · smoke agnt PASS · check 0 propios · verificado en pane + Chrome real (ciclo completo, orca archiva, kill oculta drivers). Divergencias DIFERIDAS con disposición: resumen semántico de contexto (F5) · superseded producido por OCC (F2, lado componente) · wiring identity.locale←prefs (F4 con uix.agent) · journal por defecto en factory (app decide vehículo). **Auditoría de conformidad bus/orca ✅ (2026-07-22, pregunta del usuario)**: contraste punto-a-punto contra los README de ambos — conforme en 12/13 (module-events consts+types+bus-helpers = patrón documentado literal · envelope correlationId · Rule 5 payloads planos clonables · eventos-como-constantes · module→bus/action→ctx.emit · artifacts-no-consumen-orca · Rule 7 N/A a module events). **1 no-conformidad real corregida**: `goal` (contenido del usuario) viajaba en `AgentRunBusPayload` — viola higiene de credenciales del bus («pasa correlationId y que el suscriptor resuelva del módulo») y §Events de orca («no unnecessary private data — la acción resuelve del módulo al ejecutar»). Fix: payload = SOLO metadata; el suscriptor resuelve vía `App.agent.run(runId)` (testeado en el spine con orca real: `'goal' in payload === false` + resolución del módulo). Página agnt documenta la higiene + recomendación `configureEvent('agent.run.state', { queuePolicy: ORCA_QUEUE_REPLACE_QUEUED })` (evento frecuente → doctrina de colas de orca; constante verificada). **Carril de INICIATIVA documentado (2026-07-22, pregunta del usuario «¿el bus como eje?»)**: el bus es eje en TRES direcciones — observar (vocabulario `agent.*`) · reaccionar (orca) · **iniciar** (hecho de dominio → acción orca → `App.agent.start({initiative:'system'})` → clamp auto→review por construcción); lo que NO es: vehículo de la delegación (capacidades=handlers no clonables, turnos=request/response del protocolo, contenido en el módulo). Sección «The bus as the initiative axis» + ejemplo en la página. **Adaptador REAL `openai-chat` (2026-07-22)**: `$agent/adapters/openai-chat` (fuera del barrel, D-AG.1c) — dialecto OpenAI chat-completions (Ollama/llama.cpp/LM Studio/proxy), SSE→protocolo v1, sanitización de nombres con puntos (ida y vuelta), **re-pairing de `tool_calls`** al reproducir el transcript (el motor no anota los tool_calls del assistant — memoria por callId en el adaptador), fetch inyectable. **Fix cazado en vivo**: Ollama reutiliza `index:0` para TODAS las calls del stream → call nueva se detecta por `id` distinto (no por index), `call-end` por call arrancada; sin el fix los args se concatenaban (JSON inválido → invalid-args en motor + 400 en replay). Tests 4 (protocol
| **F5 · Reservas** (cada una con gate propio, ninguna en v1) | deltas JSON Patch · skills semánticas (6g) · modo ambiental (si D-AG.3 lo firma dentro) · sub-runs/A2A · multiusuario · `svrs/agent` (solo si un consumidor real exige autoridad de servidor — respeta «transport app-land») | — |
| ⚖️2 | Propagación causal del actor (D-AG.8) | ✅ FIRMADO: híbrido — token opaco de actor como baggage del envelope causal (comparte primitivo con la traza OTel); F1 solo el primitivo, retrofit ~6 costuras diferido a F3+ |
| ⚖️3 | Fallo a mitad de secuencia (D-AG.4) | ✅ FIRMADO: rollback-a-inicio default; parcial por-capacidad |