Skip to content

Wait for Myra to become routable before drafting new agents - #698

Merged
TheGreatAxios merged 6 commits into
mainfrom
cl-7543-wait-for-myra-to-become-routable-before-drafting-new-agents
Sep 10, 2026
Merged

Wait for Myra to become routable before drafting new agents#698
TheGreatAxios merged 6 commits into
mainfrom
cl-7543-wait-for-myra-to-become-routable-before-drafting-new-agents

Conversation

@TheGreatAxios

Copy link
Copy Markdown
Contributor

Closes #696

Linear: CL-7543

Problem

Creating a new agent could fail with a generic "Something went wrong" + reference ID: the one-shot drafting path provisions a temporary Myra run and sends its first drafting message immediately, but the run's sidecar may not be registered with the hub yet. The send dies with a plain "agent is unreachable" error that matches none of the draft route's typed drafting failures, escapes as an unhandled throw, and surfaces to the user as an HTTP 500 — before the agent-definition create request is ever made.

Fix

  • The one-shot send now goes through the existing bounded deliverWhenRoutable helper from @corbits/workflows — the same pattern the webhook launch path uses: send once, poll the hub's live routing table until the address is routable (250 ms poll, 20 s deadline), then send exactly once more.
  • Residual unreachability (deadline expiry) rejects with a new OneShotRunUnreachableError wrapping the cause, which the draft route maps to the canonical 422 drafting_failed envelope with the standard user-facing message — never a bare 500.
  • The hub wiring passes isRoutable from the same routing-table source the webhook launch path uses.
  • The run's settle/undeploy still runs exactly once on every exit path; non-unreachable send failures still reject as-is with no retry.

Test plan

  • bun test packages/agent-directory: 259 passing, including new cases for retry-once-after-routable (exactly 2 sends, single undeploy), never-routable expiry (typed rejection, single settle), mid-wait flip after several polls, non-unreachable errors rejecting untouched, and the 422 route mapping.
  • bun run typecheck, bun run lint, bun run check:structural all exit 0; full pre-push gate (format, lint, typecheck, unit matrix) green locally with Postgres up via docker compose -f docker-compose.test.yml.

@linear-code

linear-code Bot commented Sep 9, 2026

Copy link
Copy Markdown

CL-7543

@TheGreatAxios
TheGreatAxios force-pushed the cl-7543-wait-for-myra-to-become-routable-before-drafting-new-agents branch from b0d05f9 to f16b13d Compare September 9, 2026 23:47
A freshly provisioned run's sidecar takes several seconds to boot and
register with the hub, so the opening drafting mail can land in that
gap and fail with a plain 'agent is unreachable' error. Cover the
bounded wait-and-retry behavior the one-shot send must gain, the typed
rejection when the wait expires without the address ever becoming
routable, and the draft route mapping that typed failure to the
canonical 422 drafting_failed envelope. A non-unreachable send error
must still reject as-is with no retry.

OneShotRunUnreachableError is defined here inert so this commit
typechecks standalone; the implementation change wires the send path
to reject with it.
A freshly provisioned run's sidecar takes several seconds to boot and
register with the hub, so the opening drafting mail could land in that
gap, fail with a plain 'agent is unreachable' error, and escape the
draft route's typed-failure map as an HTTP 500.

The one-shot send now goes through the same bounded
deliverWhenRoutable helper the webhook launch path uses: send once,
poll the hub's live routing table until the address is routable, then
send exactly once more. Residual unreachability rejects with
OneShotRunUnreachableError wrapping the cause, which the draft route
maps to the canonical 422 drafting_failed envelope; every other send
failure still rejects as-is. The run's settle/undeploy still runs
exactly once on every exit path.
The webhook launch deps and the planner one-shot runner deps each
inlined the same lambda reading the sidecar routing table. Hoist it to
one named local in createHub and pin the shared wiring with a source
scan in the style of the crypto-provider cache wiring test, so a
regression replacing either path with a constant predicate fails.
The reply timer can settle and tear down the run while the routable
wait is still polling; a send failure arriving after that is a phantom
for an already-gone run and is now dropped instead of reported.

An unreachable-shaped cause is now distinguishable from any other send
failure: it settles as planning-run-send-unreachable and reports under
agent-directory.one-shot.send-unreachable, so a wait that expired is
greppable in the error log without new telemetry plumbing.

Also correct the OneShotRunUnreachableError wording — the address may
well have become routable mid-poll with the retried send failing, so
'never became routable' overclaimed — fix the isRoutable JSDoc to
describe send-once, poll, retry-once accurately, rename tests that
promised coverage they did not deliver, pin that the runner consults
isRoutable with the launched run's address, pin that the reply timer
beats the wait and that no send follows the teardown, and yield the
poll loop to timers with real sleeps so timer-dependent tests are not
starved.
The bounded retry and the typed 422 drafting failure both hinge on the
vendor session service throwing an error whose message contains 'agent
is unreachable' and on the substring classifier sniffing exactly that.
A source-pinning scan fails loudly if either side drifts; the vendor
file itself is never touched.
The contract scan previously accepted any mention of 'agent is
unreachable' anywhere in the vendored session service, including its
doc comments — a drift of the thrown message alone would have left the
pin green while the classifier stopped matching real vendor failures.
Match the throw expression itself instead.
@TheGreatAxios
TheGreatAxios force-pushed the cl-7543-wait-for-myra-to-become-routable-before-drafting-new-agents branch from 0db68d7 to d6ab1ba Compare September 10, 2026 00:44
@TheGreatAxios
TheGreatAxios merged commit 9fe8d65 into main Sep 10, 2026
46 of 48 checks passed
@TheGreatAxios
TheGreatAxios deleted the cl-7543-wait-for-myra-to-become-routable-before-drafting-new-agents branch September 10, 2026 05:16
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Wait for Myra to become routable before drafting new agents

1 participant