Compare commits
7 Commits
14e6a319ed
...
f15f8178a3
| Author | SHA1 | Date |
|---|---|---|
|
|
f15f8178a3 | |
|
|
eee19de090 | |
|
|
59d5d9a66d | |
|
|
6418121923 | |
|
|
119d2c0495 | |
|
|
bc6e18d7b4 | |
|
|
4485f2b9ce |
|
|
@ -0,0 +1,59 @@
|
||||||
|
---
|
||||||
|
model: claude-fable-5[1m]
|
||||||
|
service: claude
|
||||||
|
session: 32d15f9a-b2d3-4c26-bdc9-190219141a25
|
||||||
|
timestamp: 2026-06-10T17:08:59Z
|
||||||
|
git_ref: datad_service
|
||||||
|
diff_cmd: git log -1 -p --follow -- ai/prompt-io/claude/20260610T170859Z_75cefe10_prompt_io.md
|
||||||
|
scope: code
|
||||||
|
substantive: true
|
||||||
|
raw_file: 20260610T170859Z_75cefe10_prompt_io.raw.md
|
||||||
|
---
|
||||||
|
|
||||||
|
## Prompt
|
||||||
|
|
||||||
|
Session-initiating instruction (driving all 7 commits in
|
||||||
|
this series):
|
||||||
|
|
||||||
|
> ok i want you to become the distributed runtime and
|
||||||
|
> concurrency expert for this project - namely acquire
|
||||||
|
> a deep understanding of tractor and how it's used.
|
||||||
|
> then i want you to attempt to factor our current
|
||||||
|
> brokerd service daemon into 2 daemons: a brokerd
|
||||||
|
> which only hosts live/paper trading endpoint tasks
|
||||||
|
> [..] a new `datad` subdaemon which in a separate
|
||||||
|
> subactor serves all the data feed service tasks [..]
|
||||||
|
> give me a mega detailed plan on how to approach this,
|
||||||
|
> and a staged approach for the implementation.
|
||||||
|
|
||||||
|
Proximate driver for THIS commit: during the approved
|
||||||
|
plan's stage-0 test gate the agent discovered test
|
||||||
|
subactors were writing into the user's REAL
|
||||||
|
`~/.config/piker/accounting/` files (a bogus paper fill
|
||||||
|
landed in `account.kraken.paper.toml`) because the old
|
||||||
|
test-dir override in `config.get_app_dir()` was
|
||||||
|
commented out and could never work in spawned
|
||||||
|
subactors anyway. Fix applied autonomously under the
|
||||||
|
approved plan; no explicit per-fix user prompt.
|
||||||
|
|
||||||
|
## Response summary
|
||||||
|
|
||||||
|
Restore `pytest` config-dir isolation by resolving the
|
||||||
|
per-test tmp dir lazily (at conf-path access time) from
|
||||||
|
`tractor` runtime-vars, which propagate down the actor
|
||||||
|
tree; route all conf-path derivation through
|
||||||
|
`config.get_conf_dir()` so the override is effective in
|
||||||
|
every (sub)actor.
|
||||||
|
|
||||||
|
## Files changed
|
||||||
|
|
||||||
|
- `piker/config.py` — add `_maybe_use_test_dir()`;
|
||||||
|
hook in `get_conf_dir()`; route `get_conf_path()` +
|
||||||
|
`load()` mkdir through it
|
||||||
|
- `piker/accounting/_ledger.py` — derive ledger dir
|
||||||
|
via `config.get_conf_dir()` (not the global)
|
||||||
|
- `piker/accounting/_pos.py` — same for account files
|
||||||
|
|
||||||
|
## Human edits
|
||||||
|
|
||||||
|
None — committed as generated.
|
||||||
|
|
@ -0,0 +1,46 @@
|
||||||
|
---
|
||||||
|
model: claude-fable-5[1m]
|
||||||
|
service: claude
|
||||||
|
timestamp: 2026-06-10T17:08:59Z
|
||||||
|
git_ref: datad_service
|
||||||
|
diff_cmd: git log -1 -p --follow -- ai/prompt-io/claude/20260610T170859Z_75cefe10_prompt_io.md
|
||||||
|
---
|
||||||
|
|
||||||
|
NOTE: diff-ref mode entry (code committed in the same
|
||||||
|
commit as this log); backfilled from the live dev
|
||||||
|
session transcript per the `/prompt-io` skill rules.
|
||||||
|
|
||||||
|
> `git log -1 -p --follow -- piker/config.py`
|
||||||
|
|
||||||
|
Generated: `config._maybe_use_test_dir()` — lazily
|
||||||
|
reads `piker_test_dir` from
|
||||||
|
`tractor.runtime._state._runtime_vars['piker_vars']`
|
||||||
|
(pre-loaded by `open_piker_runtime()` from the
|
||||||
|
`tests.conftest._open_test_pikerd()` overrides) and
|
||||||
|
calls `_override_config_dir()` when set. Hooked at the
|
||||||
|
top of `get_conf_dir()`; `get_conf_path()` and
|
||||||
|
`load()`'s dir-creation rerouted through
|
||||||
|
`get_conf_dir()`.
|
||||||
|
|
||||||
|
> `git log -1 -p --follow -- piker/accounting/_ledger.py`
|
||||||
|
> `git log -1 -p --follow -- piker/accounting/_pos.py`
|
||||||
|
|
||||||
|
Generated: ledger/account dir derivation switched from
|
||||||
|
the `config._config_dir` module global to
|
||||||
|
`config.get_conf_dir()` + `mkdir(parents=True,
|
||||||
|
exist_ok=True)` for nested tmp-dir creation.
|
||||||
|
|
||||||
|
Key diagnostic reasoning (verbatim from session):
|
||||||
|
|
||||||
|
The old (commented-out) `get_app_dir()` override gated
|
||||||
|
on `'pytest' in sys.modules` which can NEVER work in
|
||||||
|
spawned subactors (fresh procs, no pytest import); as
|
||||||
|
a result test `paperboi`/daemon actors were writing
|
||||||
|
into the user's REAL `~/.config/piker/accounting/`
|
||||||
|
files. Evidence: `account.kraken.paper.toml` gained a
|
||||||
|
single 0.001 xbtusdt clear stamped 2026-06-09T18:47Z
|
||||||
|
(a test fill), and `trades_kraken_paper.toml` (252B)
|
||||||
|
contained only that fill. The resolution must be
|
||||||
|
checked lazily at config-path access time (NOT import
|
||||||
|
time) since sub-actors only receive runtime-vars once
|
||||||
|
their `tractor` runtime has fully booted.
|
||||||
|
|
@ -0,0 +1,53 @@
|
||||||
|
---
|
||||||
|
model: claude-fable-5[1m]
|
||||||
|
service: claude
|
||||||
|
session: 32d15f9a-b2d3-4c26-bdc9-190219141a25
|
||||||
|
timestamp: 2026-06-10T17:10:22Z
|
||||||
|
git_ref: datad_service
|
||||||
|
diff_cmd: git log -1 -p --follow -- ai/prompt-io/claude/20260610T171022Z_4485f2b9_prompt_io.md
|
||||||
|
scope: code
|
||||||
|
substantive: true
|
||||||
|
raw_file: 20260610T171022Z_4485f2b9_prompt_io.raw.md
|
||||||
|
---
|
||||||
|
|
||||||
|
## Prompt
|
||||||
|
|
||||||
|
Same session-initiating `brokerd`-split instruction (see
|
||||||
|
`20260610T170859Z_75cefe10_prompt_io.md`). Proximate
|
||||||
|
driver: the approved plan's per-stage test gates could
|
||||||
|
not run AT ALL — the branch base was broken vs.
|
||||||
|
`tractor` git `main` (`AttributeError: 'tuple' object
|
||||||
|
has no attribute 'unwrap'` at `pikerd` boot, stale
|
||||||
|
`arbiter_sockaddr`/`.type`/`.size` API refs). The agent
|
||||||
|
fixed forward autonomously to (re)establish the gate
|
||||||
|
baseline, continuing the `repair_tests` branch lineage
|
||||||
|
(verified already merged in ancestry via `git cherry`
|
||||||
|
during a user-requested branch-overlap survey).
|
||||||
|
|
||||||
|
## Response summary
|
||||||
|
|
||||||
|
Port the service layer + test suites to current
|
||||||
|
`tractor` APIs: addr-type normalization in
|
||||||
|
`open_pikerd()`, `query_actor()`/`wait_for_actor()`
|
||||||
|
kwarg renames, modern self-cancel absorption semantics
|
||||||
|
in the cancel-method test harness, exc/position attr
|
||||||
|
renames, a paper-EMS startup-budget bump and a syntax
|
||||||
|
fix in `.deribit.api`.
|
||||||
|
|
||||||
|
## Files changed
|
||||||
|
|
||||||
|
- `piker/service/_actor_runtime.py` — `wrap_address()`
|
||||||
|
normalize before `.unwrap()` in `open_pikerd()`
|
||||||
|
- `piker/service/_registry.py` — `check_for_service()`
|
||||||
|
-> `query_actor(regaddr=)` + 2-tuple yield +
|
||||||
|
`open_registry(addrs=)`
|
||||||
|
- `piker/brokers/deribit/api.py` — missing comma in
|
||||||
|
`tractor.trionics` import tuple
|
||||||
|
- `tests/test_services.py` — `registry_addr=` kwarg,
|
||||||
|
raddr unwraps, cancel-semantics harness rewrite,
|
||||||
|
`fail_after` 9 -> 19s
|
||||||
|
- `tests/test_ems.py` — `.boxed_type`, `pp.cumsize`
|
||||||
|
|
||||||
|
## Human edits
|
||||||
|
|
||||||
|
None — committed as generated.
|
||||||
|
|
@ -0,0 +1,56 @@
|
||||||
|
---
|
||||||
|
model: claude-fable-5[1m]
|
||||||
|
service: claude
|
||||||
|
timestamp: 2026-06-10T17:10:22Z
|
||||||
|
git_ref: datad_service
|
||||||
|
diff_cmd: git log -1 -p --follow -- ai/prompt-io/claude/20260610T171022Z_4485f2b9_prompt_io.md
|
||||||
|
---
|
||||||
|
|
||||||
|
NOTE: diff-ref mode entry (code committed in the same
|
||||||
|
commit as this log); backfilled from the live dev
|
||||||
|
session transcript per the `/prompt-io` skill rules.
|
||||||
|
|
||||||
|
> `git log -1 -p --follow -- piker/service/_actor_runtime.py`
|
||||||
|
|
||||||
|
Generated: normalize each registry addr via
|
||||||
|
`tractor.discovery._addr.wrap_address()` before
|
||||||
|
`.unwrap()`-ing for the `accept_addrs` bind check —
|
||||||
|
entries may be raw `tuple`s when passed in from (test)
|
||||||
|
client code. Import-path precedent taken from
|
||||||
|
`piker/cli/__init__.py:336`.
|
||||||
|
|
||||||
|
> `git log -1 -p --follow -- piker/service/_registry.py`
|
||||||
|
|
||||||
|
Generated: `check_for_service()` ported to
|
||||||
|
`tractor.query_actor(name, regaddr=...)` (kwarg was
|
||||||
|
`arbiter_sockaddr=`), unpacking the new
|
||||||
|
`(sockaddr, portal)` yield, and passing the
|
||||||
|
now-required `open_registry(addrs=Registry.addrs)`.
|
||||||
|
|
||||||
|
> `git log -1 -p --follow -- tests/test_services.py`
|
||||||
|
> `git log -1 -p --follow -- tests/test_ems.py`
|
||||||
|
> `git log -1 -p --follow -- piker/brokers/deribit/api.py`
|
||||||
|
|
||||||
|
Key diagnostic reasoning (verbatim from session):
|
||||||
|
|
||||||
|
- the "DID NOT RAISE ContextCancelled" failure: in this
|
||||||
|
test the client actor IS pikerd (in-proc), and
|
||||||
|
current `tractor` main absorbs a `ContextCancelled`
|
||||||
|
whose canceller is your own actor — self-requested
|
||||||
|
cancels now exit cleanly instead of raising; the
|
||||||
|
'sigint' variant propagates a bare collapsed
|
||||||
|
`KeyboardInterrupt` rather than a
|
||||||
|
`BaseExceptionGroup`.
|
||||||
|
- the hard-coded `trio.fail_after(9)` startup budget is
|
||||||
|
marginal — full stack boot (pikerd -> emsd ->
|
||||||
|
brokerd.kraken -> paperboi + live kraken symbology
|
||||||
|
fetch) occasionally exceeds 9s -> bumped to 19s.
|
||||||
|
- `RemoteActorError.type` -> `.boxed_type`;
|
||||||
|
`Position.size` -> `.cumsize` (the paper engine
|
||||||
|
populates `BrokerdPosition.size` from `pp.cumsize`).
|
||||||
|
- overlap survey (user-requested): all of the
|
||||||
|
`repair_tests` branch commits are already in this
|
||||||
|
stack's ancestry; this commit finishes that branch's
|
||||||
|
port mission (its f4c4f1e2 fixed `conftest.py`'s
|
||||||
|
`arbiter_sockaddr` usage; this fixes the remaining
|
||||||
|
`test_services.py` + `check_for_service()` sites).
|
||||||
|
|
@ -0,0 +1,54 @@
|
||||||
|
---
|
||||||
|
model: claude-fable-5[1m]
|
||||||
|
service: claude
|
||||||
|
session: 32d15f9a-b2d3-4c26-bdc9-190219141a25
|
||||||
|
timestamp: 2026-06-10T17:11:05Z
|
||||||
|
git_ref: datad_service
|
||||||
|
diff_cmd: git log -1 -p --follow -- ai/prompt-io/claude/20260610T171105Z_bc6e18d7_prompt_io.md
|
||||||
|
scope: code
|
||||||
|
substantive: true
|
||||||
|
raw_file: 20260610T171105Z_bc6e18d7_prompt_io.raw.md
|
||||||
|
---
|
||||||
|
|
||||||
|
## Prompt
|
||||||
|
|
||||||
|
Same session-initiating `brokerd`-split instruction (see
|
||||||
|
`20260610T170859Z_75cefe10_prompt_io.md`); this is the
|
||||||
|
approved plan's "stage 0" prep. Plan-shaping user
|
||||||
|
decisions captured via in-session Q&A:
|
||||||
|
|
||||||
|
- `datad.<broker>` topology: sibling of
|
||||||
|
`brokerd.<broker>` under `pikerd` (vs. child
|
||||||
|
subactor).
|
||||||
|
- migration: hard cutover, staged by layer (no
|
||||||
|
dual-mode runtime flag).
|
||||||
|
- post-split `brokerd` scope: trading-only +
|
||||||
|
EMS-lazy-spawned (charts/CLI never touch it).
|
||||||
|
|
||||||
|
## Response summary
|
||||||
|
|
||||||
|
Declare per-daemon-kind backend submod groups
|
||||||
|
(`_datad_mods`/`_brokerd_mods`) in the split-style
|
||||||
|
backends, keyed to the pre-existing
|
||||||
|
`piker.data.validate._eps` contract; add a
|
||||||
|
`validate.get_eps()` introspection helper; ws-import
|
||||||
|
hygiene in `.kraken.broker`. Zero behavior change
|
||||||
|
(`__enable_modules__` unions unchanged).
|
||||||
|
|
||||||
|
## Files changed
|
||||||
|
|
||||||
|
- `piker/data/validate.py` — add `get_eps()`
|
||||||
|
- `piker/brokers/kraken/__init__.py` — mod groups
|
||||||
|
- `piker/brokers/binance/__init__.py` — mod groups
|
||||||
|
(note: no `symbols.py`; search eps live in `.feed`)
|
||||||
|
- `piker/brokers/deribit/__init__.py` — datad-only
|
||||||
|
groups (no `broker.py` yet)
|
||||||
|
- `piker/brokers/ib/__init__.py` — add `'api'` to the
|
||||||
|
pre-existing `_datad_mods`
|
||||||
|
- `piker/brokers/kraken/broker.py` — import
|
||||||
|
`NoBsWs`/`open_autorecon_ws` from
|
||||||
|
`piker.data._web_bs` directly
|
||||||
|
|
||||||
|
## Human edits
|
||||||
|
|
||||||
|
None — committed as generated.
|
||||||
|
|
@ -0,0 +1,46 @@
|
||||||
|
---
|
||||||
|
model: claude-fable-5[1m]
|
||||||
|
service: claude
|
||||||
|
timestamp: 2026-06-10T17:11:05Z
|
||||||
|
git_ref: datad_service
|
||||||
|
diff_cmd: git log -1 -p --follow -- ai/prompt-io/claude/20260610T171105Z_bc6e18d7_prompt_io.md
|
||||||
|
---
|
||||||
|
|
||||||
|
NOTE: diff-ref mode entry (code committed in the same
|
||||||
|
commit as this log); backfilled from the live dev
|
||||||
|
session transcript per the `/prompt-io` skill rules.
|
||||||
|
|
||||||
|
> `git log -1 -p --follow -- piker/data/validate.py`
|
||||||
|
|
||||||
|
Generated: `get_eps(mod, kind) -> dict[str, Callable]`
|
||||||
|
returning the daemon-kind's ep funcs defined by a
|
||||||
|
backend mod, keyed by ep name, missing eps excluded;
|
||||||
|
sourced from the existing `_eps` grouping table
|
||||||
|
(`'middleware' | 'datad' | 'brokerd'`).
|
||||||
|
|
||||||
|
> `git log -1 -p --follow -- piker/brokers/kraken/__init__.py`
|
||||||
|
> `git log -1 -p --follow -- piker/brokers/binance/__init__.py`
|
||||||
|
> `git log -1 -p --follow -- piker/brokers/deribit/__init__.py`
|
||||||
|
> `git log -1 -p --follow -- piker/brokers/ib/__init__.py`
|
||||||
|
> `git log -1 -p --follow -- piker/brokers/kraken/broker.py`
|
||||||
|
|
||||||
|
Key exploration findings driving the design (from the
|
||||||
|
planning phase, 3 parallel explore agents + 1 architect
|
||||||
|
agent):
|
||||||
|
|
||||||
|
- the codebase already anticipated this split:
|
||||||
|
`validate._eps` groups eps into 'datad' vs 'brokerd'
|
||||||
|
kinds and `ib/__init__.py` already declared
|
||||||
|
`_brokerd_mods`/`_datad_mods`; `brokers/_daemon.py`
|
||||||
|
carried the literal TODO "rename the daemon to datad
|
||||||
|
prolly once we split up broker vs. data tasks into
|
||||||
|
separate actors?".
|
||||||
|
- the feared kraken feed<->broker "shared ws state"
|
||||||
|
hazard is mild: `NoBsWs`/`open_autorecon_ws`
|
||||||
|
originate in `piker.data._web_bs` (re-exported via
|
||||||
|
`.kraken.feed`); only `stream_messages` is feed-local
|
||||||
|
and it's a pure parser — in-process imports only,
|
||||||
|
each actor opens its own ws conn.
|
||||||
|
- `enable_modules` gates RPC entry, NOT python imports,
|
||||||
|
so backend trading mods may keep importing feed-side
|
||||||
|
helpers in-process post-split.
|
||||||
|
|
@ -0,0 +1,47 @@
|
||||||
|
---
|
||||||
|
model: claude-fable-5[1m]
|
||||||
|
service: claude
|
||||||
|
session: 32d15f9a-b2d3-4c26-bdc9-190219141a25
|
||||||
|
timestamp: 2026-06-10T17:11:42Z
|
||||||
|
git_ref: datad_service
|
||||||
|
diff_cmd: git log -1 -p --follow -- ai/prompt-io/claude/20260610T171142Z_119d2c04_prompt_io.md
|
||||||
|
scope: code
|
||||||
|
substantive: true
|
||||||
|
raw_file: 20260610T171142Z_119d2c04_prompt_io.raw.md
|
||||||
|
---
|
||||||
|
|
||||||
|
## Prompt
|
||||||
|
|
||||||
|
Same session-initiating `brokerd`-split instruction (see
|
||||||
|
`20260610T170859Z_75cefe10_prompt_io.md`); this is the
|
||||||
|
approved plan's "stage 1": introduce the `datad` daemon
|
||||||
|
machinery additively (nothing routes through it yet).
|
||||||
|
User-decided constraint applied: `datad.<broker>` is a
|
||||||
|
SIBLING of `brokerd.<broker>` under `pikerd`, spawned
|
||||||
|
via the existing `Services` + `maybe_spawn_daemon()`
|
||||||
|
machinery.
|
||||||
|
|
||||||
|
## Response summary
|
||||||
|
|
||||||
|
New `piker/data/_daemon.py` hosting the
|
||||||
|
`datad.<broker>` feed-only daemon-actor: lifetime
|
||||||
|
fixture owning the actor-global `_FeedsBus`, init/spawn
|
||||||
|
fns mirroring `.brokers._daemon` conventions and the
|
||||||
|
`samplerd` sub-daemon precedent, plus root-mod
|
||||||
|
registration, `piker.service` re-exports and a spawn
|
||||||
|
test.
|
||||||
|
|
||||||
|
## Files changed
|
||||||
|
|
||||||
|
- `piker/data/_daemon.py` — NEW:
|
||||||
|
`_setup_persistent_datad()`, `datad_init()`,
|
||||||
|
`spawn_datad()`, `maybe_spawn_datad()`,
|
||||||
|
`_datad_service_mods`
|
||||||
|
- `piker/service/_actor_runtime.py` — add
|
||||||
|
`piker.data._daemon` to `_root_modules`
|
||||||
|
- `piker/service/__init__.py` — re-export spawn eps
|
||||||
|
- `tests/test_services.py` — add `test_datad_spawn`
|
||||||
|
|
||||||
|
## Human edits
|
||||||
|
|
||||||
|
None — committed as generated.
|
||||||
|
|
@ -0,0 +1,60 @@
|
||||||
|
---
|
||||||
|
model: claude-fable-5[1m]
|
||||||
|
service: claude
|
||||||
|
timestamp: 2026-06-10T17:11:42Z
|
||||||
|
git_ref: datad_service
|
||||||
|
diff_cmd: git log -1 -p --follow -- ai/prompt-io/claude/20260610T171142Z_119d2c04_prompt_io.md
|
||||||
|
---
|
||||||
|
|
||||||
|
NOTE: diff-ref mode entry (code committed in the same
|
||||||
|
commit as this log); backfilled from the live dev
|
||||||
|
session transcript per the `/prompt-io` skill rules.
|
||||||
|
|
||||||
|
> `git log -1 -p --follow -- piker/data/_daemon.py`
|
||||||
|
|
||||||
|
Generated symbols + key design decisions:
|
||||||
|
|
||||||
|
- `_datad_service_mods: list[str]` — datad-always
|
||||||
|
enabled mods, the data-side successor to the old
|
||||||
|
`piker.brokers._daemon._data_mods` set; kept minimal
|
||||||
|
per the caps-sec model.
|
||||||
|
- `_setup_persistent_datad()` — `@tractor.context`
|
||||||
|
lifetime fixture: console-log setup then allocates
|
||||||
|
the actor-global feed bus via
|
||||||
|
`feed.get_feed_bus(brokername, service_nursery)`
|
||||||
|
exactly as the old brokerd fixture did, pinned open
|
||||||
|
with `ctx.started()` + `sleep_forever()`.
|
||||||
|
- `datad_init()` — actor name `f'datad.{brokername}'`;
|
||||||
|
copies backend `_spawn_kwargs` (CRITICAL for `ib`'s
|
||||||
|
`infect_asyncio=True`); builds `enable_modules` from
|
||||||
|
`getattr(brokermod, '_datad_mods',
|
||||||
|
getattr(brokermod, '__enable_modules__', []))` as
|
||||||
|
the flat-backend fallback.
|
||||||
|
- `spawn_datad()` — `Services.actor_n.start_actor()` +
|
||||||
|
`Services.start_service_task()` exactly mirroring
|
||||||
|
`spawn_brokerd()`; dedup-composes enable mods via
|
||||||
|
`list(dict.fromkeys(...))`.
|
||||||
|
- `maybe_spawn_datad()` — wraps `maybe_spawn_daemon(
|
||||||
|
service_name=f'datad.{brokername}', ...)`.
|
||||||
|
|
||||||
|
> `git log -1 -p --follow -- piker/service/_actor_runtime.py`
|
||||||
|
> `git log -1 -p --follow -- piker/service/__init__.py`
|
||||||
|
> `git log -1 -p --follow -- tests/test_services.py`
|
||||||
|
|
||||||
|
Design rationale (verbatim from session):
|
||||||
|
|
||||||
|
- `_root_modules` must gain `piker.data._daemon` so
|
||||||
|
`pikerd_portal.run(spawn_datad, ...)` resolves in
|
||||||
|
the root.
|
||||||
|
- the `Services`-based impl style deliberately mirrors
|
||||||
|
`spawn_brokerd()` so the eventual `tractor.hilevel`
|
||||||
|
`ServiceMngr` port (see the `service_mng_to_tractor`
|
||||||
|
branch's d8c21d44 prep, surfaced by the
|
||||||
|
user-requested branch-overlap survey) lands
|
||||||
|
symmetrically on both spawn fns.
|
||||||
|
- mod placement (`piker/data/_daemon.py` vs.
|
||||||
|
generalizing `piker.brokers._daemon`) follows the
|
||||||
|
per-subsystem daemon-mod convention
|
||||||
|
(`.clearing._ems`, `.data._sampling`) and resolves
|
||||||
|
the existing TODO at `brokers/_daemon.py:49` ("move
|
||||||
|
this def to the `.data` subpkg").
|
||||||
|
|
@ -0,0 +1,47 @@
|
||||||
|
---
|
||||||
|
model: claude-fable-5[1m]
|
||||||
|
service: claude
|
||||||
|
session: 32d15f9a-b2d3-4c26-bdc9-190219141a25
|
||||||
|
timestamp: 2026-06-10T17:12:26Z
|
||||||
|
git_ref: datad_service
|
||||||
|
diff_cmd: git log -1 -p --follow -- ai/prompt-io/claude/20260610T171226Z_64181219_prompt_io.md
|
||||||
|
scope: code
|
||||||
|
substantive: true
|
||||||
|
raw_file: 20260610T171226Z_64181219_prompt_io.raw.md
|
||||||
|
---
|
||||||
|
|
||||||
|
## Prompt
|
||||||
|
|
||||||
|
Same session-initiating `brokerd`-split instruction (see
|
||||||
|
`20260610T170859Z_75cefe10_prompt_io.md`); this is the
|
||||||
|
approved plan's "stage 2": decouple the clearing layer
|
||||||
|
from `feed.portals` BEFORE the feed cutover so live
|
||||||
|
trading works at every stage boundary. User-decided
|
||||||
|
constraint applied: post-split `brokerd` is
|
||||||
|
trading-only and spawned LAZILY only by `emsd`'s
|
||||||
|
`open_brokerd_dialog()` path.
|
||||||
|
|
||||||
|
## Response summary
|
||||||
|
|
||||||
|
Kill the single coupling forcing feed + trading eps
|
||||||
|
into one actor (`Router.open_trade_relays()` pulling
|
||||||
|
its trades portal from `feed.portals[brokermod]`):
|
||||||
|
`open_brokerd_dialog()` now (maybe) spawns/finds
|
||||||
|
`brokerd.<broker>` itself and ONLY when a live
|
||||||
|
trades-ep will actually open; paper mode never touches
|
||||||
|
it. Pre-cutover this is a pure refactor (registry
|
||||||
|
lookup finds the same feed-spawned daemon).
|
||||||
|
|
||||||
|
## Files changed
|
||||||
|
|
||||||
|
- `piker/clearing/_ems.py` — `open_brokerd_dialog()`
|
||||||
|
re-sig + inner `acquire_live_portal()`;
|
||||||
|
`Router.maybe_open_brokerd_dialog()` drops `portal`
|
||||||
|
param; `open_trade_relays()` drops the
|
||||||
|
`feed.portals` lookup
|
||||||
|
- `piker/accounting/cli.py` — keyword-form `portal=`
|
||||||
|
override kept for the `piker ledger` ad-hoc actor
|
||||||
|
|
||||||
|
## Human edits
|
||||||
|
|
||||||
|
None — committed as generated.
|
||||||
|
|
@ -0,0 +1,43 @@
|
||||||
|
---
|
||||||
|
model: claude-fable-5[1m]
|
||||||
|
service: claude
|
||||||
|
timestamp: 2026-06-10T17:12:26Z
|
||||||
|
git_ref: datad_service
|
||||||
|
diff_cmd: git log -1 -p --follow -- ai/prompt-io/claude/20260610T171226Z_64181219_prompt_io.md
|
||||||
|
---
|
||||||
|
|
||||||
|
NOTE: diff-ref mode entry (code committed in the same
|
||||||
|
commit as this log); backfilled from the live dev
|
||||||
|
session transcript per the `/prompt-io` skill rules.
|
||||||
|
|
||||||
|
> `git log -1 -p --follow -- piker/clearing/_ems.py`
|
||||||
|
|
||||||
|
Generated: new `open_brokerd_dialog()` signature
|
||||||
|
`(brokermod, exec_mode, fqme=None, portal=None,
|
||||||
|
loglevel=None)` with an inner `@acm
|
||||||
|
acquire_live_portal()` that yields the caller-provided
|
||||||
|
`portal` override (the `piker ledger` path) else
|
||||||
|
`maybe_spawn_brokerd(brokermod.name)` — designated THE
|
||||||
|
one place a live, credentialed `brokerd.<broker>` gets
|
||||||
|
booted post-split. The eager
|
||||||
|
`portal.open_context(trades_endpoint, ...)`
|
||||||
|
construction moved inside that block so the paper
|
||||||
|
short-circuit never acquires a live portal.
|
||||||
|
|
||||||
|
> `git log -1 -p --follow -- piker/accounting/cli.py`
|
||||||
|
|
||||||
|
Key analysis (verbatim from session):
|
||||||
|
|
||||||
|
- `feed.portals` had exactly ONE trading consumer:
|
||||||
|
`piker/clearing/_ems.py:671` (`portal =
|
||||||
|
feed.portals[brokermod]`) — the single coupling
|
||||||
|
forcing feed + trading into one actor.
|
||||||
|
- `piker ledger` (`accounting/cli.py:100-157`) is a
|
||||||
|
hidden consumer: it calls `broker_init()` directly,
|
||||||
|
spawns its own ad-hoc actor and passes the portal
|
||||||
|
positionally — the new signature must keep an
|
||||||
|
explicit `portal:` override param for this path.
|
||||||
|
- stage sequencing: clearing decouple lands BEFORE the
|
||||||
|
feed cutover, otherwise `feed.portals` would hand
|
||||||
|
emsd a `datad` portal and live `open_trade_dialog`
|
||||||
|
RPC would fail.
|
||||||
|
|
@ -0,0 +1,48 @@
|
||||||
|
---
|
||||||
|
model: claude-fable-5[1m]
|
||||||
|
service: claude
|
||||||
|
session: 32d15f9a-b2d3-4c26-bdc9-190219141a25
|
||||||
|
timestamp: 2026-06-10T17:12:59Z
|
||||||
|
git_ref: datad_service
|
||||||
|
diff_cmd: git log -1 -p --follow -- ai/prompt-io/claude/20260610T171259Z_59d5d9a6_prompt_io.md
|
||||||
|
scope: code
|
||||||
|
substantive: true
|
||||||
|
raw_file: 20260610T171259Z_59d5d9a6_prompt_io.raw.md
|
||||||
|
---
|
||||||
|
|
||||||
|
## Prompt
|
||||||
|
|
||||||
|
Same session-initiating `brokerd`-split instruction (see
|
||||||
|
`20260610T170859Z_75cefe10_prompt_io.md`); this is the
|
||||||
|
approved plan's "stage 3": the feed-layer hard cutover
|
||||||
|
(user-decided: no dual-mode runtime flag, each stage
|
||||||
|
lands fully working).
|
||||||
|
|
||||||
|
## Response summary
|
||||||
|
|
||||||
|
The topology flip: all data-feed consumers route to
|
||||||
|
`datad.<broker>`; the `brokerd` lifetime fixture slims
|
||||||
|
to trading-only; UI/CLI data-flavoured spawn sites
|
||||||
|
repointed; test expectations inverted incl. an explicit
|
||||||
|
negative assert that paper sessions spawn NO
|
||||||
|
`brokerd.<broker>`.
|
||||||
|
|
||||||
|
## Files changed
|
||||||
|
|
||||||
|
- `piker/data/feed.py` — `open_feed()` ->
|
||||||
|
`maybe_spawn_datad()`; `open_feed_bus()` actor-name
|
||||||
|
assert -> `'datad'`; `install_brokerd_search` ->
|
||||||
|
`install_datad_search`; comment sweep
|
||||||
|
- `piker/brokers/_daemon.py` —
|
||||||
|
`_setup_persistent_brokerd()` slimmed (feed-bus
|
||||||
|
alloc moved to the datad fixture)
|
||||||
|
- `piker/ui/_app.py`, `piker/ui/cli.py`,
|
||||||
|
`piker/brokers/core.py`, `piker/brokers/cli.py`,
|
||||||
|
`piker/ui/kivy/option_chain.py` — spawn-site
|
||||||
|
repoints
|
||||||
|
- `tests/test_services.py` — datad assertions + the
|
||||||
|
no-`brokerd.kraken` negative check
|
||||||
|
|
||||||
|
## Human edits
|
||||||
|
|
||||||
|
None — committed as generated.
|
||||||
|
|
@ -0,0 +1,54 @@
|
||||||
|
---
|
||||||
|
model: claude-fable-5[1m]
|
||||||
|
service: claude
|
||||||
|
timestamp: 2026-06-10T17:12:59Z
|
||||||
|
git_ref: datad_service
|
||||||
|
diff_cmd: git log -1 -p --follow -- ai/prompt-io/claude/20260610T171259Z_59d5d9a6_prompt_io.md
|
||||||
|
---
|
||||||
|
|
||||||
|
NOTE: diff-ref mode entry (code committed in the same
|
||||||
|
commit as this log); backfilled from the live dev
|
||||||
|
session transcript per the `/prompt-io` skill rules.
|
||||||
|
|
||||||
|
> `git log -1 -p --follow -- piker/data/feed.py`
|
||||||
|
|
||||||
|
Generated: `open_feed()` spawn cutover with the
|
||||||
|
`maybe_spawn_datad` import done "relative-direct" from
|
||||||
|
`._daemon` — NOT via `piker.service` — to dodge a
|
||||||
|
partial-init cycle: when `piker.data.feed` loads as
|
||||||
|
part of `piker.service.__init__` executing its own
|
||||||
|
`piker.data._daemon` import, the service pkg is
|
||||||
|
mid-init and its `maybe_spawn_datad` binding does not
|
||||||
|
exist yet. The `open_feed_bus()` local-state sanity
|
||||||
|
assert flips `'brokerd' in servicename` ->
|
||||||
|
`'datad' in servicename` (the only actor-name assert
|
||||||
|
in the tree, verified by grep).
|
||||||
|
|
||||||
|
> `git log -1 -p --follow -- piker/brokers/_daemon.py`
|
||||||
|
|
||||||
|
Generated: `_setup_persistent_brokerd()` slimmed to
|
||||||
|
console-log setup + pinned-open ctx; drops the bus
|
||||||
|
alloc, the `assert not feed._bus`, the service nursery
|
||||||
|
(backend `open_trade_dialog()` ctxs own their task
|
||||||
|
trees) and the `eg.ExceptionGroup` handler. The
|
||||||
|
`piker ledger` ad-hoc actor enters this same slimmed
|
||||||
|
fixture — exactly what it needs.
|
||||||
|
|
||||||
|
> `git log -1 -p --follow -- piker/ui/_app.py`
|
||||||
|
> `git log -1 -p --follow -- piker/ui/cli.py`
|
||||||
|
> `git log -1 -p --follow -- piker/brokers/core.py`
|
||||||
|
> `git log -1 -p --follow -- piker/brokers/cli.py`
|
||||||
|
> `git log -1 -p --follow -- piker/ui/kivy/option_chain.py`
|
||||||
|
> `git log -1 -p --follow -- tests/test_services.py`
|
||||||
|
|
||||||
|
Verification (from session): per-suite gates green at
|
||||||
|
this commit (services 5-passed incl. the new negative
|
||||||
|
assert, feeds 3-passed); a headless live smoke
|
||||||
|
(`maybe_open_pikerd` + `open_feed(['xbtusdt.kraken'])`
|
||||||
|
on an alt registry port) confirmed quotes flowing via
|
||||||
|
`datad.kraken` + `samplerd` with `check_for_service(
|
||||||
|
'brokerd.kraken') is None`. Known pre-existing flake
|
||||||
|
documented: `test_multi_fill_positions`' second
|
||||||
|
in-proc runtime boot wedges ~50% (zombie subactor w/
|
||||||
|
unread parent-IPC bytes); reproduced with the split
|
||||||
|
fully reverted so NOT a regression of this work.
|
||||||
|
|
@ -0,0 +1,43 @@
|
||||||
|
---
|
||||||
|
model: claude-fable-5[1m]
|
||||||
|
service: claude
|
||||||
|
session: 32d15f9a-b2d3-4c26-bdc9-190219141a25
|
||||||
|
timestamp: 2026-06-10T17:13:44Z
|
||||||
|
git_ref: datad_service
|
||||||
|
diff_cmd: git log -1 -p --follow -- ai/prompt-io/claude/20260610T171344Z_eee19de0_prompt_io.md
|
||||||
|
scope: code
|
||||||
|
substantive: true
|
||||||
|
raw_file: 20260610T171344Z_eee19de0_prompt_io.raw.md
|
||||||
|
---
|
||||||
|
|
||||||
|
## Prompt
|
||||||
|
|
||||||
|
Same session-initiating `brokerd`-split instruction (see
|
||||||
|
`20260610T170859Z_75cefe10_prompt_io.md`); this is the
|
||||||
|
approved plan's final "stage 4": caps-sec slimming of
|
||||||
|
the (live, credentialed) trading actor + the `ib`
|
||||||
|
dual-daemon `client_id` collision mitigation flagged in
|
||||||
|
the plan's risk register.
|
||||||
|
|
||||||
|
## Response summary
|
||||||
|
|
||||||
|
`brokerd` loses ALL `piker.data.*` (feed) RPC mods;
|
||||||
|
spawn fails fast for datad-only backends with a "use
|
||||||
|
paper-mode" error; `ib`'s default api-gw `client_id`
|
||||||
|
gets a per-daemon-kind offset so `datad.ib` +
|
||||||
|
`brokerd.ib` don't collide on connect.
|
||||||
|
|
||||||
|
## Files changed
|
||||||
|
|
||||||
|
- `piker/brokers/_daemon.py` — `_data_mods` -> minimal
|
||||||
|
`_brokerd_service_mods`; `broker_init()` reads
|
||||||
|
`_brokerd_mods` (fallback `__enable_modules__`);
|
||||||
|
`spawn_brokerd()` fail-fast via `validate.get_eps()`
|
||||||
|
- `piker/brokers/ib/api.py` — role-based `client_id`
|
||||||
|
offset in `load_aio_clients()`
|
||||||
|
- `piker/cli/__init__.py` — resolved "expose datad"
|
||||||
|
TODO
|
||||||
|
|
||||||
|
## Human edits
|
||||||
|
|
||||||
|
None — committed as generated.
|
||||||
|
|
@ -0,0 +1,41 @@
|
||||||
|
---
|
||||||
|
model: claude-fable-5[1m]
|
||||||
|
service: claude
|
||||||
|
timestamp: 2026-06-10T17:13:44Z
|
||||||
|
git_ref: datad_service
|
||||||
|
diff_cmd: git log -1 -p --follow -- ai/prompt-io/claude/20260610T171344Z_eee19de0_prompt_io.md
|
||||||
|
---
|
||||||
|
|
||||||
|
NOTE: diff-ref mode entry (code committed in the same
|
||||||
|
commit as this log); backfilled from the live dev
|
||||||
|
session transcript per the `/prompt-io` skill rules.
|
||||||
|
|
||||||
|
> `git log -1 -p --follow -- piker/brokers/_daemon.py`
|
||||||
|
|
||||||
|
Generated: the fail-fast originally landed in
|
||||||
|
`broker_init()` but was relocated to `spawn_brokerd()`
|
||||||
|
mid-implementation after realizing `piker ledger`
|
||||||
|
calls `broker_init()` directly even for paper accounts
|
||||||
|
on datad-only backends (would have crashed the cli);
|
||||||
|
the service-spawn path is the correct enforcement
|
||||||
|
seam. Error text:
|
||||||
|
|
||||||
|
Backend 'kucoin' offers NO `brokerd` (live
|
||||||
|
order-control) eps!? It is likely a datad-only
|
||||||
|
provider, use paper-mode for clearing instead.
|
||||||
|
|
||||||
|
(verified live via a `trio.run()` unit check.)
|
||||||
|
|
||||||
|
> `git log -1 -p --follow -- piker/brokers/ib/api.py`
|
||||||
|
|
||||||
|
Generated: in `load_aio_clients()`, when `client_id`
|
||||||
|
is the 6116 default: `datad`-named actors offset +16
|
||||||
|
(disjoint from `brokerd`'s linear `client_id + i`
|
||||||
|
retry range), other non-`brokerd` (ad-hoc test/cli)
|
||||||
|
actors +32. Rationale from the plan's risk register:
|
||||||
|
post-split BOTH per-broker daemons connect to the same
|
||||||
|
TWS/gw endpoint; a shared default id collides and
|
||||||
|
burns up to `connect_timeout * retries` (90s) in
|
||||||
|
retry cycles.
|
||||||
|
|
||||||
|
> `git log -1 -p --follow -- piker/cli/__init__.py`
|
||||||
|
|
@ -0,0 +1,34 @@
|
||||||
|
# AI Prompt I/O Log — claude
|
||||||
|
|
||||||
|
This directory tracks prompt inputs and model
|
||||||
|
outputs for AI-assisted development using
|
||||||
|
`claude` (claude-code CLI).
|
||||||
|
|
||||||
|
## Policy
|
||||||
|
|
||||||
|
Prompt logging follows the
|
||||||
|
[NLNet generative AI policy][nlnet-ai].
|
||||||
|
All substantive AI contributions are logged
|
||||||
|
with:
|
||||||
|
- Model name and version
|
||||||
|
- Timestamps
|
||||||
|
- The prompts that produced the output
|
||||||
|
- Unedited model output (`.raw.md` files)
|
||||||
|
|
||||||
|
[nlnet-ai]: https://nlnet.nl/foundation/policies/generativeAI/
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
|
||||||
|
Entries are created by the `/prompt-io` skill
|
||||||
|
or automatically via `/commit-msg` integration.
|
||||||
|
|
||||||
|
Each commit carrying AI-generated changes links
|
||||||
|
to its provenance entry via a `Prompt-IO:`
|
||||||
|
commit-msg trailer; entries use "diff-ref mode"
|
||||||
|
(pointers into `git log -p` instead of verbatim
|
||||||
|
code copies) to avoid duplicating committed
|
||||||
|
code.
|
||||||
|
|
||||||
|
Human contributors remain accountable for all
|
||||||
|
code decisions. AI-generated content is never
|
||||||
|
presented as human-authored work.
|
||||||
Loading…
Reference in New Issue