- Split crypto: crypto-node.ts (node:crypto) · crypto-web.ts GENUINO
(subtle+getRandomValues, cero node:crypto en su grafo; sin subtle LANZA
AuthConfigError {port:'crypto'} — el fallback silencioso web→node MUERE:
quien quiera node lo pide) · crypto-test.ts queda solo el determinista.
- Entry $svrs/auth/testing: las 12 factorías test/mock salen del entry de
producción (index.ts conserva scrypt, db y los dos cryptos reales). Guard
de producción compartido adapters/production-warning.ts (warn única
indexada POR MENSAJE — memory-store conserva su semántica exacta y su
API vía alias de tipo); constante nueva en $libs/auth/consts. 7 suites
migradas al entry nuevo. svrs/index.ts NO reexporta testing (a propósito).
- verifyPassword (scrypt): guard temprano de longitud
(> PASSWORD_MAX_LENGTH ⇒ {ok:false} sin ejecutar scrypt — anti-DoS; el
camino de signIn no pasaba por la política de longitudes) y pre-check de
longitudes ante timingSafeEqual ({ok:false} en vez del RangeError de
node con params inconsistentes).
- test/server-boundary.test.ts: censo real de importadores de $svrs/auth
en arts/uix/web (6218 ficheros inspeccionados, umbral anti-vacío, los
hits de docs son template literals blanqueados y el matcher se
auto-testea con fixtures). La convención *.server.ts NO se introduce:
decisión de framework del AUTOR, dicha en el handoff.
- Docs: authExample del docs-site deja de enseñar el hasher de test como
receta (scrypt + crypto explícito); README de auth corrige logr→logger /
timr→timer.
- Tests nuevos: scrypt roundtrip/longitud/params corruptos/needsRehash ·
cryptos web+node · entry testing con su warn. Suite auth 67/67 (14
ficheros); check estable en 71.
Deudas NOMBRADAS (no ampliadas): scryptAsync puede lanzar con params que
node rechace de raíz (catch amplio taparía fallos reales) · README:103
sigue optimista sobre validación en signIn (la política solo corre en
signUp/reset; el guard del hasher tapa el DoS).
Ejecutado por agente Opus 5 sobre medición previa citada; sesión
coordinando y verificando (index limpio, testing poblado, guards en sitio,
suite re-corrida).
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Rediseño dirigido por el usuario sobre un banco de mockups con el orbe REAL
corriendo dentro. Seis frentes, todos con maquinaria existente:
ANILLO DE CUSTODIA (parte nueva `Aura.Ring`, morfo+soma+eidos)
El estado se lee como FORMA y no solo como tinte: raíl punteado en reposo,
arco que respira al ofrecerse, segmentos = pasos del plan (laten), dos arcos
enfrentados y QUIETOS esperando tu revisión (la quietud lo separa de acting),
arco que gira actuando, anillo cerrado + pulso saliente cuando te necesita.
Envuelve al Indicator (es su marco de referencia, no un hermano posicionado a
mano). El movimiento continuo son loops REGISTRADOS (data-animation-style),
nunca @keyframes de receta (R-4.5) — vienen con su puerta de reduced-motion,
donde el dash sigue distinguiendo el estado. El attr va en los hijos del SVG,
jamás en la parte: motionAttrs() estampa además data-state, del morfo ahí.
EL ORBE ES UN CONTORNO
`thickness` en el efecto orb; el hueco es real (alfa propia) sobre cualquier
fondo. Se va la rama claro/oscuro y el parámetro backgroundColor: el shader
mezclaba con el fondo y derivaba el alfa del canal máximo, o sea pintaba un
disco OPACO del color de la superficie justo en el centro (en claro un círculo
relleno; en oscuro el azul del seed). Y la receta deja de pintar su disco en
cuanto monta el canvas (:has(canvas)) — solo sobrevive donde no hay render
vivo: SSR, tests, effect={false}, sin WebGL.
COLOR = TOKENS DE ROL, PINTADO Y NO ROTADO
colorA/colorB/colorDeep (solid / solid-hover / element) resueltos con
eidos.resolveToken y pasados como hex, que es el seam que el propio arte
documenta. El hue-delta anterior se medía en OKLCH y se aplicaba en YIQ: risk
salía VERDE junto a su propio anillo naranja.
ONION EN EL IDIOMA DEL ORBE
Prop `look="solid" | "luminous"` (defecto solid: nadie más se entera). En
luminous el sector no tiene relleno — filo de luz (pasada borrosa + nítida) y
etiqueta en el color del sector; la cuña sigue siendo área táctil. El trigger
con snippet propio va BARE: sin disco, sin sombra FAB y sin el salto del hover
(el orbe ES el trigger, no su contenido). Medio anillo bottom-center y radios
44/40. El halo respira (loop pulse) y en commit-select da UNA pasada de ping
pivotando en el centro real del menú — la firma genérica de commit anima
box-shadow, que sobre un path de SVG no hace nada.
DESENLACES EXPRESADOS (el hueco real: un fallo era indistinguible de un éxito)
Tres eventos terminales con intent INTRÍNSECO — delegate-return (fulfill) /
-aborted (sin intent: un decline es ausencia, no pérdida) / -failed (loss) —
en vez de un intent dinámico, que no tiene dónde vivir: TriggerOptions no
lleva intent y el fromProp del morfo ata a un prop PÚBLICO, no a estado de
máquina. Puerto `runs?` opcional en AuraAgentSource porque activeRun ya es
null al cerrar (§0: sin él, anuncio genérico). Primeras firmas de la familia
delegate en el registro; la de loss es MOVIMIENTO (return-recoil: retirada +
descenso), no tinte — no estrena ningún hue.
MAPA SEMÁNTICO DE COLOR (demo)
Un hue = un significado en toda la superficie: gris=sin agencia ·
naranja=tu revisión · morado=él actúa · rojo=escalated (exclusivo) ·
teal=tu sí. El anillo de autoridad reusa los colores de la custodia con el
MISMO sentido (Review=risk porque vivirás en reviewing; Auto=primary porque
actúa) y los declines pasan a neutral — canon: el intent de un cancel es
`absent`. Además el anillo en reposo DELEGA (las tres autoridades abren el
run) y se cierra por transición, no siempre que no hay run.
Dos guardas del framework corrigieron el diseño por el camino:
- BK-FRAME-NO-INTENT rechazó dar intent a una familia de marco sin
justificación escrita (excepción A-1): queda el intentRationale — el motor
no emite nada y no hay evento evaluable que enmarcar, así que el retorno
consolidado es el ÚNICO sitio expresivo del desenlace.
- fallbackTarget gana sobre el target del morfo (contrato de TriggerOptions):
el sello caía en el provider. Los terminales pasan el Ring cuando existe.
Verificado en Chrome real (ventana delante: en segundo plano el navegador
congela rAF y ResizeObserver y las medidas mienten): seis estados en claro y
oscuro, y un error de transporte REAL apuntando a un puerto muerto →
delegate-return-failed · loss · return-recoil sobre el Ring · región
«Agente: falló — control devuelto».
Tests 478 (morfo 114 · soma/aura 11, +5 casos de desenlace · eidos 353),
eidos-lint 0 invalid / 0 class-hooks nuevos, morfo:vocabulary limpio,
check en los 73 errores ajenos preexistentes.
Pendiente (handoff actualizado): la jerarquía tipográfica del Status (D1
llevaba dos líneas y solo se hizo el anillo) · el pulso de commit-select se
corta si el consumidor cierra el anillo al elegir (necesita retención tipo
Presence) · D5 la superficie de composición del encargo, decisión abierta.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
La composición que pidió el usuario: el orb es el trigger central de un
OnionMenu placement="center" y las afordancias de custodia aparecen como
sectores contextuales — reviewing→Authorize/Reject, escalated→Approve/Deny,
activo→Stop — sin fila de botones. El anillo se abre SOLO mientras la
custodia espera a un humano, con re-aserción (un cierre externo sin
resolver re-abre: el efecto lee onionOpen como dependencia); por click en
el centro mientras actúa; se pliega al devolver el control.
App-land por doctrina (agent.md §7): el framework da estados + afordancias
(Aura) y componentes (OnionMenu); el app da forma a la superficie de
review. Patrón documentado en el README de aura (§Patrón).
E2E verificado en Chrome real contra qwen3-coder: la escalada real por
doc.clear abre el anillo con el orb rojo al centro → Deny en el sector →
returned(aborted, user-cancel) + «Agente: terminó — control devuelto» +
documento intacto.
check 0 propios · smoke agnt PASS.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
La demo usaba el adaptador sin documentar cómo se configura. Nueva sección
«Configuring the transport»: qué es el puerto (turn = un intercambio de
cable), adapters fuera del barrel, ejemplo dev-directo vs prod-proxy
(topología de credenciales), tabla completa de opciones (baseUrl · model ·
headers · request · fetch) y qué POSEE el adaptador como traducción de
dialecto (SSE→v1, sanitización de ids, re-pairing de tool_calls, split por
id en servidores que reutilizan index 0, error de cable → transport-error).
README del arte: opciones inline en la entrada del adaptador.
check 0 propios · smoke agnt PASS.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
La respuesta a «¿está pensando?» no se improvisa — es Aura, el componente
del eje construido para ello. La sección real de la página agnt bootea un
uix standalone mínimo (createActiveUix + Soma + ActiveEidos + eidos css):
legítimo porque un app compone ambos tiers, y la demo ES el app.
- Motor llama → createActiveAgent (mismas opciones bus+journal); activeRun
reactivo satisface AuraAgentSource; stream vía .engine.onEvent
- <Aura {agent}> con Indicator (orb $scene) + Status + Region + Cancel;
authorize/escalation quedan como afordancias app-level (doctrina §7)
- Verificado sobre el run real de qwen3-coder: «Inactivo» → «Propone un
plan» → announcement «Agente: terminó — control devuelto» en la Region,
doc mutado, answer en es; Cancel = Button disabled-en-idle; consola 0
check 0 propios · agent 30/30 · smoke agnt PASS.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
El bus como eje del agente a nivel de app, cerrado en tres direcciones:
observar (agent.*), reaccionar (orca) e INICIAR — hecho de dominio → acción
orca → App.agent.start({initiative:'system'}) con clamp auto→review por
construcción. Nunca command-events. Sección doctrinal + ejemplo en la página.
Adaptador real `$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 bidireccional de capability ids con puntos, y
re-pairing de tool_calls al reproducir el transcript (memoria por callId).
Fix cazado en vivo: Ollama reutiliza index:0 para todas las calls del
stream — una call nueva se detecta por id distinto, jamás por index (los
args concatenados producían invalid-args en motor + 400 en el replay).
Demo viva en /active/docs/agnt contra qwen3-coder:30b real: capacidades
doc.* tipadas (sium), read snapshot-por-turno, streaming, escalada
irreversible. Ciclo completo verificado en navegador: 3 acts, 2 turnos,
doc mutado, respuesta en es, rastro entero en bus (correlationId=runId).
agent 30/30 · smoke agnt PASS · check 0 propios.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Auditoría punto-a-punto contra los README de bus y orca (12/13 conforme).
La no-conformidad real: `goal` viajaba en AgentRunBusPayload, contra la
higiene documentada de ambos (bus: «pasa correlationId y que el suscriptor
resuelva el contexto sensible del módulo»; orca: «no unnecessary private
data — la acción lo resuelve del módulo al ejecutar la acción»).
- AgentRunBusPayload = SOLO metadata (runId/initiative/autonomy/state/
outcome/reason/acts/turns); el suscriptor resuelve vía App.agent.run(runId)
- spine test prueba el patrón: 'goal' in payload === false + resolución
desde el módulo con el orca REAL
- página agnt: nota de higiene + recomendación configureEvent(
'agent.run.state', { queuePolicy: ORCA_QUEUE_REPLACE_QUEUED }) para el
evento frecuente (doctrina de colas de orca)
- PLAN-agent F4a: acta de la auditoría de conformidad
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Auditoría del track (encargo): divergencias firmadas-sin-implementar
corregidas y el marco de integración INDEPENDIENTE del componente — el agente
como servicio del app, no como demo de un componente.
Fixes de decisiones firmadas (con tests):
- C3/D-AG.7: la iniciativa autónoma (system/scheduled) clampa auto→review —
un run que el usuario no pidió jamás se auto-autoriza.
- D-AG.5: presupuesto de contexto (maxContextBytes) con FIFO-trim byte-based
(el goal sobrevive; resumen semántico diferido) + log del recorte.
- F4c: tope por-arg (maxArgBytes) → invalid-args tipado.
- D-AG.6d: schema Standard-Schema del resultado (`result?`); un mismatch
vuelve como recoverable para auto-corrección y no cuenta como act.
Integración app (patrón session EXACTO):
- El arte posee el vocabulario `agent.*` (consts) + bus-helpers tipados que
publican con bus INYECTADO (type-only $libs/bus): run.opened/state/
escalated/closed + act.applied, con source='agent' y correlationId=runId —
la costura causal ligera (una delegación correlaciona de punta a punta).
- defineActiveAgent cablea core.bus (junto a timers/logger).
- Reacciones vía orca APP-LAND (el invariante intacto): probado con
EngineOrca REAL reaccionando a agent.run.closed en integration.test.
- Página del arte /active/docs/agnt (la convención que faltaba): sección
Delegation en nav; artículo + playground VIVO con los 4 motores puros
reales (bus log en vivo, journal WAL, contador orca, kill switch,
compuertas deterministas) — cero componentes, integración pura de app.
Gates: agent 26/26 · smoke agnt PASS · check 0 propios · verificado en
navegador (pane + Chrome real): ciclo completo, orca archiva runs, kill
switch reactivo.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>