Bus y ask

Mensajes de una vía entre sesiones, y la pregunta bloqueante que levanta un worker cuando la decisión no es suya.

Qué es#

Dos formas de que las sesiones se hablen, y no son intercambiables.

El bus es de una vía. msg_send necesita un cuerpo, una identidad (from_session / from_agent) y un destino. Elige el destino según lo que sepas:

Argumento de destino Alcanza a
to_session y/o to_agent Ese asiento exacto
to_worker Un id de worker: estable entre recogidas y relanzamientos, a diferencia del id de sesión
to_role parent (el Chair), child o sibling, dentro del mismo proyecto
to_project Un id de proyecto registrado: el Chair en curso de ese proyecto

Los cuerpos son telegráficos; kind suele ser note, handoff o alert. El resto del bus son msg_inbox, msg_ack, msg_stale (alertas que nadie levantó), msg_peers y msg_roster. Los humanos tienen los mismos verbos bajo orch msg.

Un ask bloquea. Cuando la decisión no es tuya y no puedes seguir sin ella, levantas uno en vez de adivinar:

ask { question, options?, context?, timeout_sec?, to_session?, to_project? }

Se sostiene hasta que alguien responda o venza el tiempo — timeout_sec es 600 por defecto. Cuando se dan options[], esas cadenas son las únicas respuestas aceptadas, sin distinguir mayúsculas; cualquier otra se rechaza en vez de registrarse. La primera respuesta gana y una segunda recibe un rechazo claro.

Levantar un ask también deja un alert en la bandeja del Chair nombrando el id y pasa por el fan-out de notificaciones configurado. El Chair puede notarlo en msg_inbox, pero responde con ask_answer — o lo hace un humano, desde una terminal:

orch ask list
orch ask answer <id> --answer "…"

La respuesta a un "¿cómo resolviste X?" entre proyectos puede llevar un symbol_ref{project, path, line, symbol} — en lugar de un cuerpo pegado. orch lo valida contra el índice antes de aceptarlo: el símbolo tiene que resolver bajo ese proyecto y ser de alcance shared. Quien preguntó obtiene el texto con code_snippet.

Por qué existe#

Porque "el agente se quedó callado" y "el agente decidió por su cuenta" son ambos fallas, y un mensaje de una vía no las distingue. Un ask vuelve explícita la espera y, más importante, vuelve explícito el timeout: el silencio no es un estado en el que orch te vaya a dejar.

worker ---- ask -----> Chair            el worker bloquea
worker <- respuesta -- Chair            la primera respuesta gana
worker <-- timeout ---  (nadie)         fila marcada "timeout", el error nombra la pregunta

Un ask vencido queda registrado, no tragado: el estado de la fila pasa a timeout, la herramienta devuelve un error que nombra la pregunta, y a un Chair que responde tarde se le avisa que llegó tarde. El worker decide entonces por su cuenta — y lo dice en verify_report.

Cómo se relaciona con el resto#

  • Solo el Chair puede lanzar. Un worker que necesita más manos le escribe al Chair con to_role=parent; no hace fan-out. Ver Chair y workers.
  • Los agentes se coordinan únicamente por este bus. Sockets de proveedor y chats paralelos quedan fuera: un bus paralelo es invisible para el board, el roster y el recolector.
  • Un mensaje handoff con el veredicto de una línea es parte de cómo reporta una sesión cerrada, junto con el board y la página de sesión.

Aquí no hay nada que ejecutar#

Los verbos existen bajo orch msg y orch ask para un humano en una terminal, pero el camino normal es un agente llamando a la herramienta MCP. Lo más probable es que te encuentres con el bus como un orch ask list cuando un worker te está esperando.