# Bounded IB recovery candidate Prepared 2026-10-22 on `wkt/land_ib_recovery`, in the main checkout `/home/goodboy/repos/piker`. Base: `dc618229bd8c9c90aa3160e26677b553a7d472c7`. Changes are unstaged and uncommitted. No acceptance is implied. ## Patch selection and provenance Keep these existing landing commits: | Commit | Reason | | --- | --- | | `4133f073` and its ancestors | Packaging, Nix, runtime API and pin work | | `e8e0730a` | Correlate MethodProxy requests and responses | | `7bef50b0` | One response reader, per-request waiters | | `d1571ddf` | Propagate daemon-handler exceptions | | `dc618229` | Isolate cached feed stream consumers | Proposed separate implementation boundaries, in this order: 1. Back out the code and original test from `635314c757c74a1cd95c5cf3dc7dfd03be984b00`. This restores the direct-owner `_quote_streams` implementation. Retain the historical prompt records. Replace the removed mocked-cache regression with the real-bridge restart reproducer. This backout is not a claim that arbitrary concurrent direct callers have safe broadcast ownership. 2. Backport **only** `piker/brokers/ib/feed.py` from `0846cbd4a4197e47415689cf5e9d146ba3174c32`. Retain its seven history-adapter regressions in `tests/test_ib_history.py`. This includes reset serialization, completion/result signalling and bounded cancellation/failure. It does not include the original SHM/storage orchestration patch. 3. Backport **only** `piker/brokers/ib/feed.py` from `1da9b760a3bc6b96501110cab2b5d09846d42a1d`. Retain `test_empty_history_preserves_request_boundary` and its six cases. This preserves no-data request boundaries and wakes the waiter. It does not include the original history-layer endpoint/filtering changes. Add the real-bridge history recovery case after these adapter changes are present. 4. Import the code and original regression from `12b0d66e854247e92cb5a8668be71d816c72d856`. Add a separate real-broadcaster/production-loop regression. 5. Remove the single-null-sample debugger stop in `get_null_segs()`. This is a local UX cleanup retaining the existing `None` result. It does not backport the null-grouping/deduplication rewrite in `976db6c33c4b8ed07eee3047226417d3928d9cca`. 6. Record cross-boundary regression results and live qualification evidence, distinguishing the known callback failure from passes. All three imported source commits were authored by `goodboy `; preserve that authorship and the full source SHA when committing each partial backport. Use explicit partial-backport wording, not a whole-commit cherry claim. New real-runtime tests are this session's additional work. The current aggregate working diff contains these boundaries in the same feed file. Staging that entire file would combine the first three boundaries. Reconstruct/stage the original per-source patches in the above order when preparing commits. ## Quote-cache history correction `4af885d90f6e4bcfa963f2f7a1d40436d3c928f3` and landing commit `635314c757c74a1cd95c5cf3dc7dfd03be984b00` have the same stable patch ID: `bc54892c25e957be112b135bb9e383ec4dd123c5`. They are equivalent replays, not different implementations. `wkt/ib_downstream_pin_eval@e929fdc2` lacks that quote-cache change and retains direct ownership. The original qualification did not validate the combination assembled for the landing. After this candidate's edits, `piker/brokers/ib/feed.py` matches the source at `1da9b760` byte-for-byte. Compared with the evaluated tip, only the later schedule/reservation APIs are absent. The EMS code patch has the same stable patch ID as the original `12b0d66e` EMS code patch: `50fee047e94fd67c8d9feab66859fbe3ab25b64c`. ## Real-runtime evidence `tests/test_ib_quote_restart.py` uses real TCP Tractor actors, an asyncio-infected child, the installed pinned Tractor bridge, production Piker quote setup, and real IB/eventkit ticker events. Only the external IB connection/input is replaced with replay data. Before the quote-cache backout, cancellation after ticker delivery raised `RemoteActorError[TrioTaskExited]` through `maybe_open_context()` / `_Cache.run_ctx` teardown, matching the reported fatal path. After the backout: - Two quote generations finish; each subscription is cancelled, each asyncio producer is done and each ticker handler removed. - A second RPC repeats the sequence in the same actor successfully. - The strict callback-cleanliness case still fails: Tractor's `signal_trio_when_done()` raises `TrioTaskExited` into asyncio's exception handler even though the Trio consumer recovers. The history integration case keeps `Client.bars()`, MethodProxy, both relays, `get_bars()`, `wait_on_data_reset()` and `data_reset_hack()` real. It replaces external contract discovery, IB history replies and VNC input. A real IB error event announces farm recovery. The replay rejects retries before recovery and proves one reset followed by completion for both 1s and 60s data. The new EMS case runs the production dark-clearing loop over a real Tractor broadcaster: both EMS and a sibling receive a tick, EMS cancellation removes only its subscription, and the sibling continues with an unchanged strict lag policy. ## Verification Unique selected cases: **38 passed, 1 failed**. The failure is intentionally visible, not skipped or xfailed. Run from the checkout's working Nix environment: ```xsh timeout -k 5 45 py313/bin/python -m pytest -p no:xonsh -q -x --tb=short tests/test_ib_history.py tests/test_ems_broadcast.py tests/test_ib_method_proxy.py tests/test_feed_broadcast.py timeout -k 5 45 py313/bin/python -m pytest -p no:xonsh -q --tb=short tests/test_ib_quote_restart.py timeout -k 5 45 py313/bin/python -m pytest -p no:xonsh -q -x --tb=short tests/test_logging.py tests/test_startup.py timeout -k 5 45 py313/bin/python -m pytest -p no:xonsh -q -x --tb=short tests/test_services.py::test_runtime_boot git diff --check ``` The adapter/proxy/feed/EMS selection initially passed 21 cases; the added real EMS case then passed with its imported case. The bridge file passed two cases and failed callback cleanliness. Logging/startup passed 13 cases; runtime boot passed one with the existing `Registrar.uid` deprecation warning. The agent shell inherited another project's environment and lacked native libraries. Tests used the existing Piker `py313` via `/tmp/nix-shell.zfKbeB/opencode/piker_test_env.py`, which supplies libraries from the pinned flake's existing Qt dependency closure, excluding Nix Qt itself and glibc. No environment sync or shellHook ran. Piker resolved to this checkout; Tractor resolved to its installed package in `py313`. Workflow-state preparation initially reported changed legacy files/modes after migration. On 2026-10-23 the human authorized reconciliation. Inspection found only two missing legacy guidance snapshots; the neutral copies matched their saved hashes and modes. Restoring those local snapshots resolved preparation without changing archived messages or the original migration receipt. ## Human live qualification, 2026-10-23 The human ran these journeys with the installed Tractor pin, the existing IB Gateway and pre-existing NativeDB. The agent did not operate the broker connection, VNC, orders or database. - Initial QQQ startup/backfill recovered after pacing error 162 with one reset attempt, then displayed live updates. The reset waiter appears to have timed out; the log did not establish an acknowledged farm reset or live quote-stream restart. - Sequential chart exits and reattachment preserved all four daemon PIDs; a read-only process/listener check confirmed this. - The overlapping two-chart journey used `pikerd@961108`, `brokerd.ib@964765`, `samplerd@965900` and `emsd@969015`. B started at 08:16:31; C at 08:17:33. B closed at 08:18:11, replacement B started at 08:18:24 and had FSPs up by 08:18:28, then C closed at 08:18:37. The human reported the exercise worked; survivor updates are a manual observation, while timestamps and unchanged daemon identities corroborate overlap and service reuse. - Startup in that journey hit the explicit single-null-sample breakpoint several times before the charts overlapped. The small debugger cleanup above was applied afterward; this live run does not itself verify that later edit. - Departing charts still report cancellation groups and an FSP receiver-close `ClosedResourceError`, followed by the Qt close handler's self-SIGINT. Peer-disconnected final result warnings remain contained in the persistent services. - Daemon SIGINT at 08:19:43 reproduced cached shared-client teardown: `load_clients_for_trio()` / `_Cache.run_ctx` promoted `TrioTaskExited` through `open_trade_dialog()` and entered PDB. After the human continued, all three children were reported exited with status 0 and the root terminated at 08:19:45. Cancellation-only RPC error reporting and late cancel-ack diagnostics also remain. The human explicitly accepted deferring this daemon teardown fix from #94 and requested loud attribution for the bounded backports. This is an operational smoke result, not clean-shutdown coverage. ## Downstream reconciliation requirements Before landing #94, the human wants an easy replay of the downstream histories intended to follow it. Rehearse against the agreed #94 tree in disposable worktrees, then inspect range-diffs, final code and relevant regressions. This note does not authorize rewriting the original branches or changing acceptance markers. - `0846cbd4` and `1da9b760` are partial backports. Their imported adapter hunks may already be present, but their history/SHM/storage changes and omitted integration tests remain necessary downstream. Never drop either whole source commit merely because `feed.py` matches or its adapter hunk becomes empty. - `12b0d66e` has source-equivalent EMS code and its imported test, plus an additional local real-broadcaster test. Preserve that extra regression when resolving test-file overlap. - The quote-cache backout intentionally restores direct ownership for this landing. Reintroducing original `4af885d9` downstream requires qualifying cached-owner teardown with the matching Tractor revision; the backout is not a permanent ownership design. - The local single-null breakpoint removal retains legacy behavior. Prefer the full downstream `976db6c3` algorithm when it is replayed; preserving this `return None` guard would lose that later fix. - Real-bridge tests and manual qualification notes are local work, not evidence that omitted portions of the source commits landed. Commit messages must name full source SHAs, original authorship, imported paths/tests, omissions, local additions and replay guidance. Use explicit partial-backport language for adapter subsets; do not claim a full cherry-pick or reuse the source's broader fix claims. ## Remaining decision This candidate removes the reproduced fatal quote-restart propagation and imports existing reset fixes. The human exercised live QQQ startup, backfill and concurrent chart consumer lifetimes. Completion-callback and teardown errors remain; the human accepts them as follow-ups outside the bounded #94 landing. The storage/SHM portions of the downstream fixes are not covered by the adapter backport or its integration tests. `ddac3553` is Deribit-specific and omitted. Qt lifecycle commit `1a2d4893` stays a separate follow-up. Further Tractor teardown changes or storage imports require reassessing the bounded landing rather than silently expanding this candidate.