--- model: claude-fable-5[1m] service: claude timestamp: 2026-06-10T21:35:49Z git_ref: datad_service diff_cmd: git log -1 -p --follow -- ai/prompt-io/claude/20260610T213549Z_f084e899_prompt_io.md --- NOTE: diff-ref mode entry (code committed in the same commit as this log); recorded from the live debug session per the `/prompt-io` skill rules. > `git log -1 -p --follow -- piker/brokers/ib/broker.py` > `git log -1 -p --follow -- piker/brokers/ib/api.py` Key diagnostic chain (from session): - pdb showed `Client._contracts == {}` inside `brokerd.ib`'s `submit_limit()`; the cache has exactly TWO write sites: `Client.find_contracts()` (api.py, keys `f'{sym}.{exch}.ib'`) and `symbols.get_mkt_info()` (key `mkt.bs_fqme`, eg. 'nvda.nasdaq' — NO `.ib` suffix). - `BrokerdOrder.symbol` arrives as the bs_fqme form ('nvda.nasdaq') so ONLY the `get_mkt_info()` write site produces the key `submit_limit()` reads — ie. pre-split it was the feed's in-proc `get_mkt_info(sym, proxy=proxy)` call keeping orders working, NOT `find_contracts()`. - the existing TODO at `symbols.py:642-644` literally predicted this: "this is going to be problematic if/when we split out the datad vs. brokerd actors since the mktmap lookup table will now be inaccessible.." - instance identity verified: `proxy._aio_ns` IS the same `Client` obj as `_accounts2clients[account]` (both sourced from the `load_aio_clients()` cache via `open_client_proxies()`), so a brokerd-side `get_mkt_info(fqme, proxy=proxies[account])` warms exactly the dict `submit_limit()` reads. It also populates `client._cons2mkts` which the position-audit path (`broker.py` backup-table code) needs in this actor anyway. - the `TrioTaskExited` storm in the user's log (`recv_trade_updates`, `open_aio_client_method_relay` aio tasks) is teardown cascade: the raise crashed `handle_order_requests` -> nursery teardown ripped the trio sides of still-running aio relay tasks. Hence the added per-order try/except -> `BrokerdError` relay hardening so a single bad submission degrades to an EMS error msg instead of killing the backend's entire order-ctl dialog. Verification: `tests/test_services.py` (5 passed) + `tests/test_ems.py` (6 passed) regression-green; live `ib` submission retest delegated to the human (needs a running TWS/gw).