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
handoffcon 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.