Compare commits
8 Commits
wkt/live_c
...
main
| Author | SHA1 | Date |
|---|---|---|
|
|
7c8c1c4cb6 | |
|
|
45d0f003fc | |
|
|
f148fbcc23 | |
|
|
00e7ca45f6 | |
|
|
4880f0d3c6 | |
|
|
7b7ecb6747 | |
|
|
899e3ed992 | |
|
|
e9cf1d7379 |
|
|
@ -5,11 +5,7 @@ description: >
|
||||||
across distributed actor systems. Apply when
|
across distributed actor systems. Apply when
|
||||||
adding profiling, debugging perf regressions, or
|
adding profiling, debugging perf regressions, or
|
||||||
optimizing hot paths in piker code.
|
optimizing hot paths in piker code.
|
||||||
compatibility: >
|
user-invocable: false
|
||||||
Requires a piker checkout and Python profiling work.
|
|
||||||
metadata:
|
|
||||||
author: goodboy
|
|
||||||
version: "1.0"
|
|
||||||
---
|
---
|
||||||
|
|
||||||
# Piker Profiling Subsystem
|
# Piker Profiling Subsystem
|
||||||
|
|
@ -5,11 +5,7 @@ description: >
|
||||||
ethos. Apply when communicating with piker devs,
|
ethos. Apply when communicating with piker devs,
|
||||||
writing commit messages, code review comments, or
|
writing commit messages, code review comments, or
|
||||||
any collaborative interaction.
|
any collaborative interaction.
|
||||||
compatibility: >
|
user-invocable: false
|
||||||
Harness-independent communication guidance.
|
|
||||||
metadata:
|
|
||||||
author: goodboy
|
|
||||||
version: "1.0"
|
|
||||||
---
|
---
|
||||||
|
|
||||||
# Piker Slang & Communication Style
|
# Piker Slang & Communication Style
|
||||||
|
|
@ -47,7 +47,7 @@ that's why it's like 1000x faster ya know?"
|
||||||
- Wrap all code symbols: `function()`,
|
- Wrap all code symbols: `function()`,
|
||||||
`ClassName`, `field_name`
|
`ClassName`, `field_name`
|
||||||
- File paths: `piker/ui/_remote_ctl.py`
|
- File paths: `piker/ui/_remote_ctl.py`
|
||||||
- Commands: `git status`, `piker store shm`
|
- Commands: `git status`, `piker store ldshm`
|
||||||
|
|
||||||
**Explain like you're pair programming:**
|
**Explain like you're pair programming:**
|
||||||
```
|
```
|
||||||
|
|
@ -5,12 +5,7 @@ description: >
|
||||||
for piker's UI. Apply when optimizing graphics
|
for piker's UI. Apply when optimizing graphics
|
||||||
performance, adding new chart annotations, or
|
performance, adding new chart annotations, or
|
||||||
working with `QGraphicsItem` subclasses.
|
working with `QGraphicsItem` subclasses.
|
||||||
compatibility: >
|
user-invocable: false
|
||||||
Requires a piker checkout with PyQtGraph and Qt source
|
|
||||||
available for inspection.
|
|
||||||
metadata:
|
|
||||||
author: goodboy
|
|
||||||
version: "1.0"
|
|
||||||
---
|
---
|
||||||
|
|
||||||
# PyQtGraph Rendering Optimization
|
# PyQtGraph Rendering Optimization
|
||||||
|
|
@ -6,12 +6,7 @@ description: >
|
||||||
with OHLCV arrays, timestamp lookups, gap
|
with OHLCV arrays, timestamp lookups, gap
|
||||||
detection, or any array/dataframe operations in
|
detection, or any array/dataframe operations in
|
||||||
piker.
|
piker.
|
||||||
compatibility: >
|
user-invocable: false
|
||||||
Requires a piker checkout with NumPy and optionally
|
|
||||||
Polars.
|
|
||||||
metadata:
|
|
||||||
author: goodboy
|
|
||||||
version: "1.0"
|
|
||||||
---
|
---
|
||||||
|
|
||||||
# Timeseries Optimization: NumPy & Polars
|
# Timeseries Optimization: NumPy & Polars
|
||||||
|
|
@ -66,14 +61,11 @@ ts_array = np.array(timestamps)
|
||||||
# binary search for all timestamps at once
|
# binary search for all timestamps at once
|
||||||
indices = np.searchsorted(time_arr, ts_array)
|
indices = np.searchsorted(time_arr, ts_array)
|
||||||
|
|
||||||
# bounds check before indexing: searchsorted may return
|
# bounds check and exact match verification
|
||||||
# len(time_arr) for values above the final timestamp
|
valid_mask = (
|
||||||
in_bounds = indices < len(time_arr)
|
(indices < len(array))
|
||||||
valid_mask = np.zeros(indices.shape, dtype=bool)
|
&
|
||||||
valid_mask[in_bounds] = (
|
(time_arr[indices] == ts_array)
|
||||||
time_arr[indices[in_bounds]]
|
|
||||||
==
|
|
||||||
ts_array[in_bounds]
|
|
||||||
)
|
)
|
||||||
|
|
||||||
valid_indices = indices[valid_mask]
|
valid_indices = indices[valid_mask]
|
||||||
|
|
@ -10,34 +10,30 @@ here.
|
||||||
- Project/import: `piker`
|
- Project/import: `piker`
|
||||||
- Test root: `tests/`
|
- Test root: `tests/`
|
||||||
- Supported Python: `>=3.12,<3.14`
|
- Supported Python: `>=3.12,<3.14`
|
||||||
- Preferred verified environment: worktree-local `.venv`.
|
- Preferred complete environment: worktree-local `py313` inside the current
|
||||||
- The testing group includes pytest and the locked `pytest-qt==4.5.0`.
|
`nix develop` shell
|
||||||
- Verify the interpreter, local package resolution, and dependency versions
|
- The flake shell pins CPython 3.13 and sets
|
||||||
before running tests.
|
`UV_PROJECT_ENVIRONMENT=py313`.
|
||||||
|
- Verify the interpreter, package resolution, and dependency import before
|
||||||
|
running tests. A bare `py313` may lack the Qt binding supplied by Nix.
|
||||||
|
|
||||||
This worktree's environment was provisioned with:
|
Use an already-provisioned `py313` only when `import piker` succeeds:
|
||||||
|
|
||||||
```text
|
```text
|
||||||
env UV_PROJECT_ENVIRONMENT=.venv uv sync --group testing --frozen
|
py313/bin/python -m pytest -p no:xonsh
|
||||||
```
|
```
|
||||||
|
|
||||||
Do not rerun provisioning without approval. Use the already-provisioned
|
If direct environment paths are unavailable, an existing uv environment can
|
||||||
environment directly:
|
be used without changing it, subject to the same import check:
|
||||||
|
|
||||||
```text
|
```text
|
||||||
.venv/bin/python -m pytest
|
UV_PROJECT_ENVIRONMENT=py313 uv run --frozen --no-sync python -m pytest -p no:xonsh
|
||||||
```
|
```
|
||||||
|
|
||||||
If direct environment paths are unavailable, use uv without changing the
|
Ask before running provisioning commands such as:
|
||||||
environment, subject to the same import check:
|
|
||||||
|
|
||||||
```text
|
|
||||||
env UV_PROJECT_ENVIRONMENT=.venv uv run --frozen --no-sync python -m pytest
|
|
||||||
```
|
|
||||||
|
|
||||||
Ask before entering or provisioning alternate environments such as:
|
|
||||||
|
|
||||||
```text
|
```text
|
||||||
|
UV_PROJECT_ENVIRONMENT=py313 uv sync --dev --all-extras --no-group lint
|
||||||
nix develop
|
nix develop
|
||||||
nix-shell default.nix
|
nix-shell default.nix
|
||||||
```
|
```
|
||||||
|
|
@ -46,41 +42,43 @@ nix-shell default.nix
|
||||||
X11 shell. Do not use `develop.nix` for current testing; it retains the old
|
X11 shell. Do not use `develop.nix` for current testing; it retains the old
|
||||||
Python 3.11, Poetry, and Qt 5 stack.
|
Python 3.11, Poetry, and Qt 5 stack.
|
||||||
|
|
||||||
Do not enter `nix develop` without approval: its shell hook may provision its
|
The current root-checkout `py313` resolves `piker` locally but fails
|
||||||
own configured environment. Plain `uv sync` does not include the testing
|
`import piker` outside Nix because PyQtGraph cannot import PyQt or PySide. Do
|
||||||
group; use `--group testing` when provisioning is explicitly authorized. The
|
not treat that environment as test-ready and do not enter `nix develop`
|
||||||
`dbs` dependency group is also absent from normal dev-shell provisioning.
|
without approval: its shell hook may recreate and sync `py313`.
|
||||||
|
|
||||||
|
Plain `uv sync` does not include the testing group. The `dbs` dependency group
|
||||||
|
is also absent from normal dev-shell provisioning.
|
||||||
|
|
||||||
## Commands
|
## Commands
|
||||||
|
|
||||||
Base command in the preferred environment:
|
Base command in the preferred environment:
|
||||||
|
|
||||||
```text
|
```text
|
||||||
.venv/bin/python -m pytest
|
py313/bin/python -m pytest -p no:xonsh
|
||||||
```
|
```
|
||||||
|
|
||||||
The comments-only `pytest.ini` has been deleted. The authoritative
|
The explicit `-p no:xonsh` is required. The tracked comments-only
|
||||||
`[tool.pytest.ini_options]` in `pyproject.toml` sets `testpaths = ["tests"]`,
|
`pytest.ini` takes precedence over `pyproject.toml`, so the intended
|
||||||
`addopts = "-p no:xonsh"`, and `qt_api = "pyqt6"`; do not repeat
|
`addopts = "-p no:xonsh"` and `testpaths = ["tests"]` are inactive.
|
||||||
`-p no:xonsh` in ordinary commands. Still pass a test path or node ID when a
|
Always pass a test path or node ID explicitly.
|
||||||
deterministic scope is required.
|
|
||||||
|
|
||||||
Package-resolution check that does not import Piker's dependencies:
|
Package-resolution check that does not import Piker's dependencies:
|
||||||
|
|
||||||
```text
|
```text
|
||||||
.venv/bin/python -c 'import importlib.util, pathlib, sys; root = pathlib.Path.cwd().resolve(); spec = importlib.util.find_spec("piker"); mod = pathlib.Path(spec.origin).resolve(); print(sys.executable); print(mod); assert mod.is_relative_to(root)'
|
py313/bin/python -c 'import importlib.util, pathlib, sys; root = pathlib.Path.cwd().resolve(); spec = importlib.util.find_spec("piker"); mod = pathlib.Path(spec.origin).resolve(); print(sys.executable); print(mod); assert mod.is_relative_to(root)'
|
||||||
```
|
```
|
||||||
|
|
||||||
Dependency import check, required before collection or execution:
|
Dependency import check, required before collection or execution:
|
||||||
|
|
||||||
```text
|
```text
|
||||||
.venv/bin/python -c 'from importlib.metadata import version; import pathlib, piker, pytestqt, sys; root = pathlib.Path.cwd().resolve(); mod = pathlib.Path(piker.__file__).resolve(); qt_ver = version("pytest-qt"); print(sys.executable); print(mod); print(qt_ver); assert mod.is_relative_to(root); assert qt_ver == "4.5.0"'
|
py313/bin/python -c 'import pathlib, piker, sys; root = pathlib.Path.cwd().resolve(); mod = pathlib.Path(piker.__file__).resolve(); print(sys.executable); print(mod); assert mod.is_relative_to(root)'
|
||||||
```
|
```
|
||||||
|
|
||||||
Safe core collection check:
|
Safe core collection check:
|
||||||
|
|
||||||
```text
|
```text
|
||||||
.venv/bin/python -m pytest -q --collect-only tests/test_watchlists.py tests/test_accounting.py tests/test_services.py tests/test_ems.py tests/test_feeds.py tests/test_cli.py
|
py313/bin/python -m pytest -p no:xonsh -q --collect-only tests/test_watchlists.py tests/test_accounting.py tests/test_services.py tests/test_ems.py tests/test_feeds.py tests/test_cli.py
|
||||||
```
|
```
|
||||||
|
|
||||||
Default first-pass flags are `-q -x --tb=short --no-header` unless the user
|
Default first-pass flags are `-q -x --tb=short --no-header` unless the user
|
||||||
|
|
@ -88,7 +86,7 @@ requests otherwise. For actor-heavy tests, use one file or node per process
|
||||||
with an outer timeout:
|
with an outer timeout:
|
||||||
|
|
||||||
```text
|
```text
|
||||||
timeout -k 5 300 .venv/bin/python -m pytest -q <one-file-or-node>
|
timeout -k 5 300 py313/bin/python -m pytest -p no:xonsh -q <one-file-or-node>
|
||||||
```
|
```
|
||||||
|
|
||||||
If an actor-heavy command exits `124` or `143`, retry that exact command once
|
If an actor-heavy command exits `124` or `143`, retry that exact command once
|
||||||
|
|
@ -113,8 +111,6 @@ Deterministic or local first-pass targets:
|
||||||
- `tests/test_ib_method_proxy.py`
|
- `tests/test_ib_method_proxy.py`
|
||||||
- `tests/test_history_backfill.py`
|
- `tests/test_history_backfill.py`
|
||||||
- `tests/test_ldshm.py`
|
- `tests/test_ldshm.py`
|
||||||
- `tests/test_dpi_font.py`
|
|
||||||
- `tests/test_gap_overlays.py`
|
|
||||||
- `tests/test_accounting.py::test_account_file_default_empty`
|
- `tests/test_accounting.py::test_account_file_default_empty`
|
||||||
- `tests/test_services.py::test_runtime_boot`
|
- `tests/test_services.py::test_runtime_boot`
|
||||||
- `tests/test_services.py::test_datad_spawn`
|
- `tests/test_services.py::test_datad_spawn`
|
||||||
|
|
@ -132,6 +128,7 @@ Require explicit authorization before running:
|
||||||
fixtures plus possible live symcache generation;
|
fixtures plus possible live symcache generation;
|
||||||
- `tests/test_accounting.py::test_ib_account_with_duplicated_mktids` - active
|
- `tests/test_accounting.py::test_ib_account_with_duplicated_mktids` - active
|
||||||
broker/account configuration and state writes;
|
broker/account configuration and state writes;
|
||||||
|
- `tests/test_dpi_font.py` - Qt/UI import and user-config side effects;
|
||||||
- `tests/test_docker_services.py` - optional dependencies and containers;
|
- `tests/test_docker_services.py` - optional dependencies and containers;
|
||||||
- `tests/test_questrade.py` - obsolete credentialed imports.
|
- `tests/test_questrade.py` - obsolete credentialed imports.
|
||||||
|
|
||||||
|
|
@ -172,12 +169,9 @@ whole suite supports UDS merely because the Tractor plugin exposes it.
|
||||||
`tests/_inputs/account.binance.paper.toml` are used in place. Accounting
|
`tests/_inputs/account.binance.paper.toml` are used in place. Accounting
|
||||||
contexts can write them on exit. Inspect `git diff -- tests/_inputs` after
|
contexts can write them on exit. Inspect `git diff -- tests/_inputs` after
|
||||||
any selected accounting case.
|
any selected accounting case.
|
||||||
- `tests/conftest.py` selects PyQt6 defaults and owns temporary
|
- Importing `tests/test_dpi_font.py` constructs module-global font objects
|
||||||
`XDG_CONFIG_HOME` and `XDG_CONFIG_DIRS` trees before importing Piker or Qt.
|
before fixtures can isolate config. If explicitly requested, isolate
|
||||||
`--headless` force-selects Qt's `offscreen` platform at that same early
|
`XDG_CONFIG_HOME` before Python starts and use the proper Qt/Nix shell.
|
||||||
point, overriding compositor values inherited from a development shell.
|
|
||||||
A pytest config cleanup restores the caller environment even when only
|
|
||||||
collection runs. The `qapp_args` fixture only supplies `piker-tests`.
|
|
||||||
- Piker and the installed Tractor pytest plugin do not provide a
|
- Piker and the installed Tractor pytest plugin do not provide a
|
||||||
repository-local process or socket reaper. Never apply historical broad
|
repository-local process or socket reaper. Never apply historical broad
|
||||||
`pkill -f tractor._child` guidance automatically.
|
`pkill -f tractor._child` guidance automatically.
|
||||||
|
|
@ -187,60 +181,6 @@ whole suite supports UDS merely because the Tractor plugin exposes it.
|
||||||
unlinks exact surviving names before failing the leaking test. It never
|
unlinks exact surviving names before failing the leaking test. It never
|
||||||
scans `/dev/shm` or unlinks attachments created by another process.
|
scans `/dev/shm` or unlinks attachments created by another process.
|
||||||
|
|
||||||
## Qt/UI Tier
|
|
||||||
|
|
||||||
The pytest process defaults to `QT_QPA_PLATFORM=offscreen` only when the
|
|
||||||
caller has not selected a platform. Development shells can select a real
|
|
||||||
compositor such as Wayland. Pass `--headless` on every automated Qt run to
|
|
||||||
force `offscreen` before imports and avoid opening desktop windows. Without
|
|
||||||
`--headless`, an explicit caller platform wins. `PYTEST_QT_API` defaults to
|
|
||||||
PyQt6, the authoritative pytest config selects `qt_api = "pyqt6"`, and
|
|
||||||
`pytest-qt==4.5.0` is locked.
|
|
||||||
|
|
||||||
Root conftest setup assigns temporary `XDG_CONFIG_HOME` and `XDG_CONFIG_DIRS`
|
|
||||||
trees before importing Piker or Qt. This keeps import-cached Piker paths and
|
|
||||||
Qt user/system settings below test-owned storage. The session `qapp_args`
|
|
||||||
fixture uses `piker-tests` as the application argument. Deterministic
|
|
||||||
offscreen Qt tests are normal local targets; they are not opt-in merely
|
|
||||||
because they import Qt or might otherwise read user config.
|
|
||||||
|
|
||||||
`tests/ui/conftest.py` reuses pytest-qt's session `QApplication` and applies
|
|
||||||
an autouse function guard. After pytest-qt closes registered widgets, the
|
|
||||||
guard checks and restores top-level widgets, `ViewBox.AllViews`,
|
|
||||||
`ViewBox.NamedViews`, `pyqtgraph.CONFIG_OPTIONS`, Piker config paths,
|
|
||||||
`QSettings`, and `quitOnLastWindowClosed()`. Register every test-owned widget
|
|
||||||
with `qtbot.addWidget()` so a surviving object is reported as a leak.
|
|
||||||
|
|
||||||
Exact verified gap-overlay commands:
|
|
||||||
|
|
||||||
```text
|
|
||||||
.venv/bin/python -m pytest --headless -q --collect-only tests/ui/test_harness.py tests/test_gap_overlays.py
|
|
||||||
.venv/bin/python -m pytest --headless -q -x --tb=short --no-header tests/ui/test_harness.py tests/test_gap_overlays.py
|
|
||||||
.venv/bin/python -m pytest --headless -q -x --tb=short --no-header tests/ui/test_harness.py
|
|
||||||
.venv/bin/python -m pytest --headless -q --collect-only tests/test_gap_overlays.py
|
|
||||||
.venv/bin/python -m pytest --headless -q -x --tb=short --no-header tests/test_gap_overlays.py
|
|
||||||
```
|
|
||||||
|
|
||||||
The combined collection command collected 11 tests. The combined headless
|
|
||||||
command passed all 11 in 2.00s, including the UI platform assertion, with one
|
|
||||||
upstream Tractor `trio.Event` boolean-use deprecation warning.
|
|
||||||
|
|
||||||
- Let `qtbot` own every widget registered with `qtbot.addWidget()` through
|
|
||||||
teardown. Do not manually close or delete the same widget a second time.
|
|
||||||
- Keep production `MainWindow` out of this tier: its `closeEvent()` sends
|
|
||||||
`SIGINT` to the pytest process.
|
|
||||||
- A real compositor is an explicit process override, for example:
|
|
||||||
|
|
||||||
```text
|
|
||||||
QT_QPA_PLATFORM=wayland .venv/bin/python -m pytest -q -x --tb=short --no-header tests/test_gap_overlays.py
|
|
||||||
QT_QPA_PLATFORM=xcb .venv/bin/python -m pytest -q -x --tb=short --no-header tests/test_gap_overlays.py
|
|
||||||
```
|
|
||||||
|
|
||||||
Real-compositor, visual, manual, and live UI tests remain opt-in. Announce
|
|
||||||
them before execution and obtain explicit authorization. Never omit
|
|
||||||
`--headless` from an automated Qt run merely because a compositor is
|
|
||||||
available.
|
|
||||||
|
|
||||||
## Test Layout
|
## Test Layout
|
||||||
|
|
||||||
```text
|
```text
|
||||||
|
|
@ -253,7 +193,6 @@ tests/
|
||||||
test_dpi_font.py Qt DPI/font behavior
|
test_dpi_font.py Qt DPI/font behavior
|
||||||
test_ems.py actor, EMS, and paper-position behavior
|
test_ems.py actor, EMS, and paper-position behavior
|
||||||
test_feeds.py live Binance/Kraken feeds and shared memory
|
test_feeds.py live Binance/Kraken feeds and shared memory
|
||||||
test_gap_overlays.py typed gap logic, offscreen Qt, and Tractor IPC
|
|
||||||
test_ib_history.py deterministic IB history request formatting
|
test_ib_history.py deterministic IB history request formatting
|
||||||
test_ib_method_proxy.py deterministic IB asyncio proxy routing
|
test_ib_method_proxy.py deterministic IB asyncio proxy routing
|
||||||
test_history_backfill.py deterministic history/SHM orchestration
|
test_history_backfill.py deterministic history/SHM orchestration
|
||||||
|
|
@ -264,7 +203,6 @@ tests/
|
||||||
test_storage_audit.py read-only NativeDB audit and JSON CLI
|
test_storage_audit.py read-only NativeDB audit and JSON CLI
|
||||||
test_backfill_audit_snippet.py
|
test_backfill_audit_snippet.py
|
||||||
disposable xonsh qualification helpers
|
disposable xonsh qualification helpers
|
||||||
ui/ repeated-session Qt isolation and leak proofs
|
|
||||||
test_watchlists.py deterministic watchlist JSON operations
|
test_watchlists.py deterministic watchlist JSON operations
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
@ -282,9 +220,7 @@ tests/
|
||||||
| `piker/storage/cli.py` SHM null-slot guard | `tests/test_ldshm.py` | synthetic timestamps, no SHM mutation |
|
| `piker/storage/cli.py` SHM null-slot guard | `tests/test_ldshm.py` | synthetic timestamps, no SHM mutation |
|
||||||
| `piker/config.py` | `test_account_file_default_empty` | root-network test has a known mismatch |
|
| `piker/config.py` | `test_account_file_default_empty` | root-network test has a known mismatch |
|
||||||
| `piker/accounting/` | targeted accounting node | some cases use live/configured state |
|
| `piker/accounting/` | targeted accounting node | some cases use live/configured state |
|
||||||
| root/UI test fixtures | `tests/ui/test_harness.py` | same-process Qt and config restoration |
|
| `piker/ui/_style.py`, `piker/ui/qt.py` | `tests/test_dpi_font.py` | GUI/config-isolated opt-in |
|
||||||
| `piker/ui/_gaps.py`, `_annotate.py`, `_display.py`, `_interaction.py`, `_remote_ctl.py` | `tests/test_gap_overlays.py` | offscreen PyQt6 plus one local Tractor actor |
|
|
||||||
| `piker/ui/_style.py`, `piker/ui/qt.py` | `tests/test_dpi_font.py` | deterministic offscreen Qt |
|
|
||||||
| `piker/service/_actor_runtime.py`, `_registry.py`, `_mngr.py` | `test_runtime_boot` | then `test_datad_spawn` |
|
| `piker/service/_actor_runtime.py`, `_registry.py`, `_mngr.py` | `test_runtime_boot` | then `test_datad_spawn` |
|
||||||
| `piker/service/`, `piker/data/_daemon.py` | `test_datad_spawn` | feed lifecycle cases are live |
|
| `piker/service/`, `piker/data/_daemon.py` | `test_datad_spawn` | feed lifecycle cases are live |
|
||||||
| `piker/data/feed.py`, `flows.py`, `_sharedmem.py`, `_sampling.py` | collect first | feed execution needs live permission |
|
| `piker/data/feed.py`, `flows.py`, `_sharedmem.py`, `_sampling.py` | collect first | feed execution needs live permission |
|
||||||
|
|
@ -294,28 +230,26 @@ tests/
|
||||||
| Docker/service adapters | `tests/test_docker_services.py` | optional deps and containers |
|
| Docker/service adapters | `tests/test_docker_services.py` | optional deps and containers |
|
||||||
| project, lock, or Nix files | import check and safe collection | full collection is not safe by default |
|
| project, lock, or Nix files | import check and safe collection | full collection is not safe by default |
|
||||||
|
|
||||||
Prefer deterministic filesystem/config and offscreen Qt tests, then local
|
Prefer deterministic filesystem/config tests, then local actor-runtime nodes,
|
||||||
actor-runtime nodes, then explicitly approved live broker, visual UI, or
|
then explicitly approved live broker, GUI, or container coverage.
|
||||||
container coverage.
|
|
||||||
|
|
||||||
## Quick Checks
|
## Quick Checks
|
||||||
|
|
||||||
```text
|
```text
|
||||||
.venv/bin/python -c 'import importlib.util, pathlib, sys; root = pathlib.Path.cwd().resolve(); spec = importlib.util.find_spec("piker"); mod = pathlib.Path(spec.origin).resolve(); print(sys.executable); print(mod); assert mod.is_relative_to(root)'
|
py313/bin/python -c 'import importlib.util, pathlib, sys; root = pathlib.Path.cwd().resolve(); spec = importlib.util.find_spec("piker"); mod = pathlib.Path(spec.origin).resolve(); print(sys.executable); print(mod); assert mod.is_relative_to(root)'
|
||||||
.venv/bin/python -c 'from importlib.metadata import version; import pathlib, piker, pytestqt, sys; root = pathlib.Path.cwd().resolve(); mod = pathlib.Path(piker.__file__).resolve(); qt_ver = version("pytest-qt"); print(sys.executable); print(mod); print(qt_ver); assert mod.is_relative_to(root); assert qt_ver == "4.5.0"'
|
py313/bin/python -c 'import pathlib, piker, sys; root = pathlib.Path.cwd().resolve(); mod = pathlib.Path(piker.__file__).resolve(); print(sys.executable); print(mod); assert mod.is_relative_to(root)'
|
||||||
.venv/bin/python -m pytest --headless -q --collect-only tests/test_gap_overlays.py
|
py313/bin/python -m pytest -p no:xonsh -q tests/test_watchlists.py
|
||||||
.venv/bin/python -m pytest --headless -q -x --tb=short --no-header tests/test_gap_overlays.py
|
py313/bin/python -m pytest -p no:xonsh -q tests/test_accounting.py::test_account_file_default_empty
|
||||||
.venv/bin/python -m pytest -q tests/test_watchlists.py
|
timeout -k 5 300 py313/bin/python -m pytest -p no:xonsh -q tests/test_services.py::test_runtime_boot
|
||||||
.venv/bin/python -m pytest -q tests/test_accounting.py::test_account_file_default_empty
|
timeout -k 5 300 py313/bin/python -m pytest -p no:xonsh -q tests/test_services.py::test_datad_spawn
|
||||||
timeout -k 5 300 .venv/bin/python -m pytest -q tests/test_services.py::test_runtime_boot
|
timeout -k 5 300 py313/bin/python -m pytest -p no:xonsh -q tests/test_ems.py::test_ems_err_on_bad_broker
|
||||||
timeout -k 5 300 .venv/bin/python -m pytest -q tests/test_services.py::test_datad_spawn
|
|
||||||
timeout -k 5 300 .venv/bin/python -m pytest -q tests/test_ems.py::test_ems_err_on_bad_broker
|
|
||||||
```
|
```
|
||||||
|
|
||||||
## Known Outcomes
|
## Known Outcomes
|
||||||
|
|
||||||
- The verified `.venv` import check resolves `piker` beneath this worktree and
|
- The current root-checkout `py313` fails `import piker` outside the Nix shell
|
||||||
imports the locked `pytest-qt` 4.5.0.
|
with `ImportError: PyQtGraph requires one of PyQt5, PyQt6, PySide2 or
|
||||||
|
PySide6`. This is an incomplete environment, not an application regression.
|
||||||
- `tests/test_accounting.py::test_root_conf_networking_section` currently
|
- `tests/test_accounting.py::test_root_conf_networking_section` currently
|
||||||
expects `network.tsdb`, which is absent from the tracked config template.
|
expects `network.tsdb`, which is absent from the tracked config template.
|
||||||
Match the current `KeyError: 'tsdb'` before classifying it as the known
|
Match the current `KeyError: 'tsdb'` before classifying it as the known
|
||||||
|
|
@ -0,0 +1 @@
|
||||||
|
{"version": 1, "backend": "neutral"}
|
||||||
|
|
@ -1,12 +0,0 @@
|
||||||
{
|
|
||||||
"permissions": {
|
|
||||||
"allow": [
|
|
||||||
"Bash(chmod:*)",
|
|
||||||
"Bash(/tmp/piker_commits.txt)",
|
|
||||||
"Bash(python:*)",
|
|
||||||
"Bash(ls:*)"
|
|
||||||
],
|
|
||||||
"deny": [],
|
|
||||||
"ask": []
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,155 +0,0 @@
|
||||||
---
|
|
||||||
name: piker-conc-expert
|
|
||||||
description: >
|
|
||||||
Distributed-runtime and structured-concurrency
|
|
||||||
expertise for piker's `tractor` actor-tree. Apply
|
|
||||||
when working on daemon/service architecture, actor
|
|
||||||
spawning/discovery, cross-actor RPC (ctx/stream
|
|
||||||
eps), `to_asyncio` integration, cancellation
|
|
||||||
semantics, or debugging hangs/wedges/skews in the
|
|
||||||
actor system.
|
|
||||||
compatibility: >
|
|
||||||
Requires a piker checkout and familiarity with Python,
|
|
||||||
trio, and tractor.
|
|
||||||
metadata:
|
|
||||||
author: goodboy
|
|
||||||
version: "1.0"
|
|
||||||
---
|
|
||||||
|
|
||||||
# Piker Concurrency & Runtime Expertise
|
|
||||||
|
|
||||||
The distilled mental model for piker's distributed
|
|
||||||
runtime: a `trio`-structured actor tree supervised by
|
|
||||||
`tractor` (pinned to git main) where every long-lived
|
|
||||||
subsystem is a named daemon-actor talking over
|
|
||||||
ctx/stream IPC.
|
|
||||||
|
|
||||||
## Actor tree & daemon taxonomy
|
|
||||||
|
|
||||||
```
|
|
||||||
pikerd root supervisor + registry
|
|
||||||
├── datad.<broker> feed bus, shm writers, tsp
|
|
||||||
│ history, symbol search
|
|
||||||
├── brokerd.<broker> live order-ctl ONLY; lazily
|
|
||||||
│ spawned by emsd, credentialed
|
|
||||||
├── emsd dark-clearing + order routing
|
|
||||||
│ └── paperboi.<broker> sim-clearing (paper mode)
|
|
||||||
└── samplerd singleton OHLC clock/increment
|
|
||||||
```
|
|
||||||
|
|
||||||
Key invariants:
|
|
||||||
- `datad` hosts all `piker.data.validate._eps['datad']`
|
|
||||||
eps; `brokerd` only the `['brokerd']` (order-ctl)
|
|
||||||
ones. The `_eps` table in `piker/data/validate.py`
|
|
||||||
is the authoritative contract; `get_eps(mod, kind)`
|
|
||||||
introspects a backend's support.
|
|
||||||
- `brokerd.<broker>` is booted in EXACTLY one place:
|
|
||||||
`open_brokerd_dialog()` in `piker/clearing/_ems.py`
|
|
||||||
(with a `portal:` override for the `piker ledger`
|
|
||||||
ad-hoc actor). Chart-only + paper sessions run with
|
|
||||||
ZERO brokerd procs. Never add a data-path spawn!
|
|
||||||
- backends declare per-daemon-kind submods via
|
|
||||||
`_datad_mods`/`_brokerd_mods` in their
|
|
||||||
`__init__.py` (fallback: `__enable_modules__`).
|
|
||||||
|
|
||||||
## Daemon lifecycle conventions
|
|
||||||
|
|
||||||
Every daemon-kind follows the same trio of fns (see
|
|
||||||
`piker/brokers/_daemon.py` + `piker/data/_daemon.py`
|
|
||||||
as the canonical pair):
|
|
||||||
|
|
||||||
- `_setup_persistent_<kind>()`: a `@tractor.context`
|
|
||||||
"lifetime fixture" run via
|
|
||||||
`Services.start_service_task()`; does console-log
|
|
||||||
setup ONCE for the actor, allocs any actor-global
|
|
||||||
state (eg. datad's `_FeedsBus`), then
|
|
||||||
`await ctx.started()` + `trio.sleep_forever()`.
|
|
||||||
- `<kind>_init()`: builds `enable_modules` + actor
|
|
||||||
name `f'<kind>.{brokername}'` and copies backend
|
|
||||||
`_spawn_kwargs` (CRITICAL: `ib` needs
|
|
||||||
`infect_asyncio=True` in EVERY daemon-kind).
|
|
||||||
- `spawn_<kind>()` + `maybe_spawn_<kind>()`: thin
|
|
||||||
wrappers over `Services.actor_n.start_actor()` and
|
|
||||||
`piker.service.maybe_spawn_daemon()` (registry
|
|
||||||
find-or-spawn w/ per-service-name locking).
|
|
||||||
|
|
||||||
Caps-sec model: `enable_modules` gates RPC entry ONLY
|
|
||||||
— python imports are unrestricted in-proc. Keep each
|
|
||||||
daemon's enable set minimal; the (credentialed)
|
|
||||||
`brokerd` must never RPC-enable `piker.data.*` feed
|
|
||||||
mods.
|
|
||||||
|
|
||||||
## Actor-local state: the #1 split hazard
|
|
||||||
|
|
||||||
Module-globals and instance caches are PER-ACTOR.
|
|
||||||
Anything that "just worked" because two subsystems
|
|
||||||
shared a process will break when they're split into
|
|
||||||
sibling actors. Canonical example: `ib`'s
|
|
||||||
`Client._contracts` was warmed by feed-side
|
|
||||||
`get_mkt_info()` in-proc; post datad/brokerd-split
|
|
||||||
the trading actor must warm it itself (eagerly at
|
|
||||||
`open_trade_dialog()` startup for open pps/orders +
|
|
||||||
lazily per order request via
|
|
||||||
`symbols.cache_contract()`).
|
|
||||||
|
|
||||||
When moving code across actor boundaries ALWAYS audit:
|
|
||||||
- module-global registries (`feed._bus`,
|
|
||||||
`_accounts2clients`, `_client_cache`, ..)
|
|
||||||
- `@async_lifo_cache`/`maybe_open_context` caches
|
|
||||||
(NOTE: `async_lifo_cache` keys on POSITIONAL args
|
|
||||||
only; a cache-hit SKIPS the fn body and thus any
|
|
||||||
side-effect writes!)
|
|
||||||
- logging handler placement (see gotchas.md)
|
|
||||||
|
|
||||||
## tractor primitives as used here
|
|
||||||
|
|
||||||
- `@tractor.context` eps: `await ctx.started(val)`
|
|
||||||
unblocks the caller w/ `val`; long-lived eps then
|
|
||||||
`ctx.open_stream()` or `sleep_forever()`.
|
|
||||||
- discovery: `tractor.find_actor()` via
|
|
||||||
`piker.service.find_service()`;
|
|
||||||
`wait_for_actor(name, registry_addr=...)`;
|
|
||||||
`query_actor(name, regaddr=...)` yields
|
|
||||||
`(sockaddr, portal)`. Addrs are wrapped
|
|
||||||
`tractor.discovery._addr.Address` types — use
|
|
||||||
`wrap_address()` to normalize raw tuples and
|
|
||||||
`.unwrap()` for comparisons.
|
|
||||||
- runtime-vars: `_runtime_vars['piker_vars']` is
|
|
||||||
inherited down the spawn tree; used eg. for
|
|
||||||
`piker_test_dir` config isolation — read LAZILY at
|
|
||||||
use-time, never at import time (subactors only get
|
|
||||||
vars post runtime-boot).
|
|
||||||
- cancellation semantics (modern tractor): a
|
|
||||||
`ContextCancelled` whose `.canceller` is your own
|
|
||||||
actor is ABSORBED (clean exit, nothing raised);
|
|
||||||
single-exc groups collapse (`collapse_eg`) so eg.
|
|
||||||
a KBI propagates bare. Exc attrs:
|
|
||||||
`RemoteActorError.boxed_type` (not `.type`).
|
|
||||||
|
|
||||||
## `to_asyncio` (infect-asyncio) integration
|
|
||||||
|
|
||||||
For `ib` (and `deribit`) the backend client runs on
|
|
||||||
an embedded `asyncio` loop via
|
|
||||||
`tractor.to_asyncio.open_channel_from()` +
|
|
||||||
`LinkedTaskChannel`.
|
|
||||||
|
|
||||||
Rules learned the hard way:
|
|
||||||
- a shared req/resp channel MUST correlate responses
|
|
||||||
to requests (see `MethodProxy._run_method()`'s
|
|
||||||
`mid` protocol in `piker/brokers/ib/api.py`):
|
|
||||||
caller cancellation (eg. `move_on_after` timeouts)
|
|
||||||
otherwise orphans a response and silently skews
|
|
||||||
every later result off-by-one.
|
|
||||||
- the aio-side relay must catch + ship back ALL
|
|
||||||
(non-cancel) exceptions as `{'exception': err}`
|
|
||||||
resps; an escaping error kills the relay task ->
|
|
||||||
channel -> proxy nursery -> the whole dialog,
|
|
||||||
bypassing every caller-side guard.
|
|
||||||
- `TrioTaskExited` ("child asyncio task is still
|
|
||||||
running?") on teardown is a known wart family;
|
|
||||||
prefer upstream `tractor` fixes over piker-side
|
|
||||||
bandaids.
|
|
||||||
|
|
||||||
See [gotchas.md](gotchas.md) for the symptom->cause
|
|
||||||
registry and [debug-recipes.md](debug-recipes.md) for
|
|
||||||
forensics techniques.
|
|
||||||
|
|
@ -1,100 +0,0 @@
|
||||||
# Debug recipes: actor-system forensics
|
|
||||||
|
|
||||||
Field-tested techniques for diagnosing hangs, wedges
|
|
||||||
and cross-actor state bugs WITHOUT a debugger attached
|
|
||||||
(or when `py-spy` ain't installed).
|
|
||||||
|
|
||||||
## Wedged actor triage (no REPL)
|
|
||||||
|
|
||||||
1. find the tree:
|
|
||||||
`ps -eo pid,etime,args | grep -E 'pytest|tractor._child'`
|
|
||||||
— long-`etime` `tractor._child` procs w/ a stuck
|
|
||||||
parent = wedge.
|
|
||||||
2. kernel state:
|
|
||||||
`cat /proc/<pid>/wchan` + `status | grep -E
|
|
||||||
'State|Threads'` — `do_epoll_wait` + sleeping =
|
|
||||||
idle event loop, NOT cpu-spin.
|
|
||||||
3. **the money read** — socket queues:
|
|
||||||
`ss -tnp | grep <pid>`
|
|
||||||
- `Recv-Q > 0` on the parent-IPC conn = the actor
|
|
||||||
STOPPED CONSUMING its msg loop (runtime bug),
|
|
||||||
parent is waiting on it.
|
|
||||||
- zero external (api/ws) conns = wedged before/
|
|
||||||
without provider IO; don't blame the network.
|
|
||||||
- `CLOSE-WAIT` lingerers = unclean peer teardown.
|
|
||||||
4. cleanup: `pkill -f tractor._child` (NB: in
|
|
||||||
compound shell cmds `pkill`'s exit code poisons
|
|
||||||
`&&` chains — run it standalone).
|
|
||||||
|
|
||||||
## Hang-proof test gating
|
|
||||||
|
|
||||||
- per-suite, never combined (cross-suite session
|
|
||||||
state interacts w/ the 2nd-boot wedge):
|
|
||||||
`timeout -k 5 300 python -m pytest tests/<one>.py -q`
|
|
||||||
- rc 124/143 = hang-kill -> retry ONCE before
|
|
||||||
investigating.
|
|
||||||
- isolate a flaky test w/ a 3x loop; ~50% hit-rate
|
|
||||||
signatures match the known 2nd-boot wedge (see
|
|
||||||
gotchas.md).
|
|
||||||
|
|
||||||
## Regression vs pre-existing attribution
|
|
||||||
|
|
||||||
When a failure appears mid-refactor:
|
|
||||||
1. `git stash -u` (or checkout the file subset) and
|
|
||||||
re-run the EXACT failing case at baseline.
|
|
||||||
2. if baseline can't even run, selectively revert
|
|
||||||
ONLY the suspect layer:
|
|
||||||
`git diff <files> > /tmp/x.patch;
|
|
||||||
git checkout <files>` -> test ->
|
|
||||||
`git apply /tmp/x.patch`.
|
|
||||||
3. flake-rate compare (3x runs) beats single-shot
|
|
||||||
conclusions.
|
|
||||||
|
|
||||||
## Off-by-one / stale IPC resp detection
|
|
||||||
|
|
||||||
Mismatched query->result content in logs (resp
|
|
||||||
payload obviously for a prior request) = shared
|
|
||||||
req/resp channel w/o correlation + a cancelled
|
|
||||||
caller. Grep the ep for `move_on_after`/`fail_after`
|
|
||||||
around proxied calls. Fix = req-id (`mid`) tagging,
|
|
||||||
never "just a lock" (cancellation still orphans).
|
|
||||||
|
|
||||||
## Logging-chain audits
|
|
||||||
|
|
||||||
When records double-print or go bare (see gotchas.md):
|
|
||||||
|
|
||||||
```python
|
|
||||||
import logging
|
|
||||||
l = logging.getLogger('piker.brokers.ib.broker')
|
|
||||||
while l:
|
|
||||||
print(l.name, l.level, l.handlers, l.propagate)
|
|
||||||
l = l.parent
|
|
||||||
```
|
|
||||||
|
|
||||||
Exactly ONE stderr handler should exist in the chain,
|
|
||||||
attached by the actor's daemon fixture.
|
|
||||||
|
|
||||||
## Live actor-tree smoke (headless)
|
|
||||||
|
|
||||||
Boot against an ALT registry port so a user's running
|
|
||||||
stack is untouched; script in a REAL file (tractor
|
|
||||||
children re-exec `__main__` from path — stdin scripts
|
|
||||||
crash w/ `FileNotFoundError: .../<stdin>`):
|
|
||||||
|
|
||||||
```python
|
|
||||||
async with maybe_open_pikerd(
|
|
||||||
registry_addrs=[('127.0.0.1', 6979)],
|
|
||||||
):
|
|
||||||
async with open_feed(['xbtusdt.kraken']) as feed:
|
|
||||||
assert await check_for_service('datad.kraken')
|
|
||||||
assert not await check_for_service(
|
|
||||||
'brokerd.kraken'
|
|
||||||
)
|
|
||||||
```
|
|
||||||
|
|
||||||
## In-proc fail-fast unit checks
|
|
||||||
|
|
||||||
Spawn-path guards that raise BEFORE touching the
|
|
||||||
runtime can be tested w/ a bare `trio.run()` (eg
|
|
||||||
`spawn_brokerd('kucoin')` raising the datad-only
|
|
||||||
error) — no pikerd needed.
|
|
||||||
|
|
@ -1,116 +0,0 @@
|
||||||
# Known gotchas: symptom -> cause -> fix
|
|
||||||
|
|
||||||
A registry of distributed-runtime failure modes hit
|
|
||||||
(and diagnosed) in the field; check here FIRST when a
|
|
||||||
log/traceback matches.
|
|
||||||
|
|
||||||
## "Can not order ..., no qualified contract cached"
|
|
||||||
|
|
||||||
- **Symptom**: `RuntimeError` from
|
|
||||||
`ib.api.Client.submit_limit()` w/ empty
|
|
||||||
`Client._contracts` in `brokerd.ib`.
|
|
||||||
- **Cause**: per-actor cache never warmed; feed-side
|
|
||||||
qualification now lives in `datad.ib`.
|
|
||||||
- **Fix(ed)**: eager warmup at `open_trade_dialog()`
|
|
||||||
start + lazy per-order `get_mkt_info()` +
|
|
||||||
`cache_contract()` (writes BOTH `mkt.bs_fqme` and
|
|
||||||
`mkt.fqme` keys; different consumers read each!).
|
|
||||||
|
|
||||||
## Search returns results for the WRONG pattern
|
|
||||||
|
|
||||||
- **Symptom**: fqme search for 'gld' returns nvda
|
|
||||||
results; next query returns the prior query's set.
|
|
||||||
- **Cause**: `MethodProxy` channel off-by-one — a
|
|
||||||
caller cancelled (search `move_on_after` timeout)
|
|
||||||
after sending its request orphans the response;
|
|
||||||
every later caller consumes the previous resp.
|
|
||||||
- **Fix(ed)**: `mid` req-id correlation in
|
|
||||||
`_run_method()` + relay; stale resps are dropped w/
|
|
||||||
a "Dropping stale method-resp" warning. If that
|
|
||||||
warning spams, some caller is being cancelled
|
|
||||||
mid-call habitually — find + fix its timeout.
|
|
||||||
|
|
||||||
## One bad request crashes a whole dialog/actor
|
|
||||||
|
|
||||||
- **Symptom**: `TrioTaskExited` storm + nursery
|
|
||||||
teardown after a single method error (eg ambiguous
|
|
||||||
contract `AttributeError`).
|
|
||||||
- **Cause**: exception escaped the aio-side relay
|
|
||||||
loop (`open_aio_client_method_relay()`) killing
|
|
||||||
channel + proxy nursery; caller-side `try/except`
|
|
||||||
CANNOT catch it.
|
|
||||||
- **Fix(ed)**: relay catches `Exception` -> ships
|
|
||||||
`{'exception': err, 'mid': ...}` resp; order
|
|
||||||
handler converts to EMS `BrokerdError` msgs.
|
|
||||||
|
|
||||||
## Ambiguous ib contracts -> `NoneType` attr errors
|
|
||||||
|
|
||||||
- **Symptom**: `'NoneType' object has no attribute
|
|
||||||
'primaryExchange'` in `find_contracts()`.
|
|
||||||
- **Cause**: `qualifyContractsAsync()` returns `None`
|
|
||||||
entries for ambiguous (eg venue-less stonk fqme
|
|
||||||
matching multiple listings: 'gld' -> ARCA/USD +
|
|
||||||
VENTURE/CAD).
|
|
||||||
- **Fix(ed)**: filter `None`s + raise descriptive
|
|
||||||
`ValueError` ("use 'gld.arca.ib'").
|
|
||||||
|
|
||||||
## Double-printed log records (same task id, 2x)
|
|
||||||
|
|
||||||
- **Symptom**: every record from some subsys printed
|
|
||||||
twice w/ identical task ids.
|
|
||||||
- **Cause**: stderr handlers attached at TWO levels
|
|
||||||
of one logger-propagation chain (eg daemon fixture
|
|
||||||
on `piker.brokers.ib` + an ep calling
|
|
||||||
`get_console_log(name=__name__)` on the child).
|
|
||||||
tractor's handler-dedup only checks the SAME
|
|
||||||
logger, not ancestors.
|
|
||||||
- **Rule**: console handlers are attached ONCE per
|
|
||||||
actor in the `_setup_persistent_*()` fixture; eps
|
|
||||||
needing a different level use `log.setLevel()`
|
|
||||||
ONLY, never `get_console_log()`.
|
|
||||||
|
|
||||||
## Bare/non-colorized log lines
|
|
||||||
|
|
||||||
- **Symptom**: records w/ no timestamp/actor prefix.
|
|
||||||
- **Cause**: NO handler anywhere in the emitting
|
|
||||||
logger's chain -> stdlib `logging.lastResort`. Post
|
|
||||||
actor-splits, a daemon fixture may only cover its
|
|
||||||
own subsys subtree (eg datad's `piker.data.*` but
|
|
||||||
not the backend's `piker.brokers.<broker>.*`).
|
|
||||||
- **Fix(ed)**: `_setup_persistent_datad()` enables
|
|
||||||
BOTH `piker.data.<broker>` and
|
|
||||||
`piker.brokers.<broker>` subtrees.
|
|
||||||
|
|
||||||
## 2nd in-proc runtime boot wedges (~50%)
|
|
||||||
|
|
||||||
- **Symptom**: test hangs when one test proc boots a
|
|
||||||
2nd `pikerd` (eg `test_multi_fill_positions`'s
|
|
||||||
persistence re-check); a zombie `*.{broker}` child
|
|
||||||
lingers w/ unread bytes in its parent-IPC Recv-Q.
|
|
||||||
- **Cause**: pre-existing `tractor`-main runtime
|
|
||||||
teardown bug (confirmed independent of piker-layer
|
|
||||||
changes via revert-testing 2026-06).
|
|
||||||
- **Mitigation**: run suites per-file wrapped in
|
|
||||||
`timeout -k 5 300 ...`; retry once on rc 124/143.
|
|
||||||
Do NOT chase as a regression of unrelated changes.
|
|
||||||
|
|
||||||
## ib client-id collisions post-split
|
|
||||||
|
|
||||||
- **Symptom**: 2nd ib daemon burns the full
|
|
||||||
conn-timeout retry cycle connecting to gw/tws.
|
|
||||||
- **Cause**: `datad.ib` + `brokerd.ib` both default
|
|
||||||
`client_id=6116` w/ linear `+i` retries.
|
|
||||||
- **Fix(ed)**: role-based offsets in
|
|
||||||
`load_aio_clients()`: datad +16, ad-hoc (test/cli)
|
|
||||||
actors +32.
|
|
||||||
|
|
||||||
## `async_lifo_cache` skipped side-effects
|
|
||||||
|
|
||||||
- **Symptom**: a fn's cache-write side effect
|
|
||||||
(eg `get_mkt_info()` -> `_contracts`) missing for
|
|
||||||
a 2nd client/proxy.
|
|
||||||
- **Cause**: cache keys on POSITIONAL args only; a
|
|
||||||
hit skips the body entirely.
|
|
||||||
- **Rule**: never rely on cached-fn side effects;
|
|
||||||
perform required writes explicitly at the call
|
|
||||||
site (eg `cache_contract()` after `get_mkt_info`).
|
|
||||||
|
|
@ -0,0 +1 @@
|
||||||
|
../../.agents/skills/piker-profiling
|
||||||
|
|
@ -0,0 +1 @@
|
||||||
|
../../.agents/skills/piker-slang
|
||||||
|
|
@ -0,0 +1 @@
|
||||||
|
../../.agents/skills/pyqtgraph-optimization
|
||||||
|
|
@ -0,0 +1 @@
|
||||||
|
../../.agents/skills/timeseries-optimization
|
||||||
|
|
@ -107,14 +107,11 @@ ENV/
|
||||||
.git/
|
.git/
|
||||||
|
|
||||||
# any commit-msg gen tmp files
|
# any commit-msg gen tmp files
|
||||||
.claude/*_commit_*.md
|
|
||||||
.claude/*_commit*.toml
|
|
||||||
|
|
||||||
# ai.skillz/commit-msg
|
|
||||||
.claude/skills/commit-msg/msgs/
|
.claude/skills/commit-msg/msgs/
|
||||||
.claude/skills/commit-msg/conf.toml
|
.claude/skills/commit-msg/conf.toml
|
||||||
.claude/git_commit_msg_LATEST.md
|
.claude/git_commit_msg_LATEST.md
|
||||||
.opencode/skills/commit-msg/SKILL.md
|
.claude/*_commit_*.md
|
||||||
|
.claude/*_commit*.toml
|
||||||
|
|
||||||
# nix develop --profile .nixdev
|
# nix develop --profile .nixdev
|
||||||
.nixdev*
|
.nixdev*
|
||||||
|
|
@ -137,6 +134,26 @@ gitea/
|
||||||
# LLM conversations that should remain private
|
# LLM conversations that should remain private
|
||||||
docs/conversations/
|
docs/conversations/
|
||||||
|
|
||||||
|
# BEGIN ai.skillz: direct:symlink:claude:gish
|
||||||
|
/.claude/skills/gish
|
||||||
|
# END ai.skillz: direct:symlink:claude:gish
|
||||||
|
|
||||||
|
# BEGIN ai.skillz: direct:symlink:opencode:gish
|
||||||
|
/.opencode/skills/gish
|
||||||
|
# END ai.skillz: direct:symlink:opencode:gish
|
||||||
|
|
||||||
|
# BEGIN ai.skillz: runtime:open-wkt
|
||||||
|
/wkts/
|
||||||
|
# END ai.skillz: runtime:open-wkt
|
||||||
|
|
||||||
|
# BEGIN ai.skillz: direct:symlink:claude:open-wkt
|
||||||
|
/.claude/skills/open-wkt
|
||||||
|
# END ai.skillz: direct:symlink:claude:open-wkt
|
||||||
|
|
||||||
|
# BEGIN ai.skillz: direct:symlink:opencode:open-wkt
|
||||||
|
/.opencode/skills/open-wkt
|
||||||
|
# END ai.skillz: direct:symlink:opencode:open-wkt
|
||||||
|
|
||||||
# BEGIN ai.skillz: direct:symlink:claude:run-tests
|
# BEGIN ai.skillz: direct:symlink:claude:run-tests
|
||||||
/.claude/skills/run-tests/SKILL.md
|
/.claude/skills/run-tests/SKILL.md
|
||||||
# END ai.skillz: direct:symlink:claude:run-tests
|
# END ai.skillz: direct:symlink:claude:run-tests
|
||||||
|
|
@ -145,10 +162,6 @@ docs/conversations/
|
||||||
/.opencode/skills/run-tests/SKILL.md
|
/.opencode/skills/run-tests/SKILL.md
|
||||||
# END ai.skillz: direct:symlink:opencode:run-tests
|
# END ai.skillz: direct:symlink:opencode:run-tests
|
||||||
|
|
||||||
# BEGIN ai.skillz: direct:symlink:opencode:command:run-tests
|
|
||||||
/.opencode/commands/run-tests.md
|
|
||||||
# END ai.skillz: direct:symlink:opencode:command:run-tests
|
|
||||||
|
|
||||||
# BEGIN ai.skillz: direct:symlink:claude:close-wkt
|
# BEGIN ai.skillz: direct:symlink:claude:close-wkt
|
||||||
/.claude/skills/close-wkt
|
/.claude/skills/close-wkt
|
||||||
# END ai.skillz: direct:symlink:claude:close-wkt
|
# END ai.skillz: direct:symlink:claude:close-wkt
|
||||||
|
|
@ -157,9 +170,23 @@ docs/conversations/
|
||||||
/.opencode/skills/close-wkt
|
/.opencode/skills/close-wkt
|
||||||
# END ai.skillz: direct:symlink:opencode:close-wkt
|
# END ai.skillz: direct:symlink:opencode:close-wkt
|
||||||
|
|
||||||
|
# BEGIN ai.skillz: runtime:code-review
|
||||||
|
.ai/code-review/reports/
|
||||||
|
# END ai.skillz: runtime:code-review
|
||||||
|
|
||||||
|
# BEGIN ai.skillz: direct:symlink:claude:code-review
|
||||||
|
/.claude/skills/code-review
|
||||||
|
# END ai.skillz: direct:symlink:claude:code-review
|
||||||
|
|
||||||
|
# BEGIN ai.skillz: direct:symlink:opencode:code-review
|
||||||
|
/.opencode/skills/code-review
|
||||||
|
# END ai.skillz: direct:symlink:opencode:code-review
|
||||||
|
|
||||||
# BEGIN ai.skillz: runtime:code-review-changes
|
# BEGIN ai.skillz: runtime:code-review-changes
|
||||||
|
.ai/state/review/
|
||||||
.claude/review_context.md
|
.claude/review_context.md
|
||||||
.claude/review_regression.md
|
.claude/review_regression.md
|
||||||
|
.claude/review_replies/
|
||||||
# END ai.skillz: runtime:code-review-changes
|
# END ai.skillz: runtime:code-review-changes
|
||||||
|
|
||||||
# BEGIN ai.skillz: direct:symlink:claude:code-review-changes
|
# BEGIN ai.skillz: direct:symlink:claude:code-review-changes
|
||||||
|
|
@ -171,8 +198,10 @@ docs/conversations/
|
||||||
# END ai.skillz: direct:symlink:opencode:code-review-changes
|
# END ai.skillz: direct:symlink:opencode:code-review-changes
|
||||||
|
|
||||||
# BEGIN ai.skillz: runtime:commit-msg
|
# BEGIN ai.skillz: runtime:commit-msg
|
||||||
|
.ai/state/commit-msg/
|
||||||
|
.ai/state/migrations/
|
||||||
|
.ai/commit-msg/conf.toml
|
||||||
.claude/skills/commit-msg/msgs/
|
.claude/skills/commit-msg/msgs/
|
||||||
.claude/skills/commit-msg/conf.toml
|
|
||||||
.claude/git_commit_msg_LATEST.md
|
.claude/git_commit_msg_LATEST.md
|
||||||
# END ai.skillz: runtime:commit-msg
|
# END ai.skillz: runtime:commit-msg
|
||||||
|
|
||||||
|
|
@ -184,6 +213,14 @@ docs/conversations/
|
||||||
/.opencode/skills/commit-msg/SKILL.md
|
/.opencode/skills/commit-msg/SKILL.md
|
||||||
# END ai.skillz: direct:symlink:opencode:commit-msg
|
# END ai.skillz: direct:symlink:opencode:commit-msg
|
||||||
|
|
||||||
|
# BEGIN ai.skillz: direct:symlink:claude:commit-plan
|
||||||
|
/.claude/skills/commit-plan
|
||||||
|
# END ai.skillz: direct:symlink:claude:commit-plan
|
||||||
|
|
||||||
|
# BEGIN ai.skillz: direct:symlink:opencode:commit-plan
|
||||||
|
/.opencode/skills/commit-plan
|
||||||
|
# END ai.skillz: direct:symlink:opencode:commit-plan
|
||||||
|
|
||||||
# BEGIN ai.skillz: direct:symlink:claude:dep-supersede-scan
|
# BEGIN ai.skillz: direct:symlink:claude:dep-supersede-scan
|
||||||
/.claude/skills/dep-supersede-scan
|
/.claude/skills/dep-supersede-scan
|
||||||
# END ai.skillz: direct:symlink:claude:dep-supersede-scan
|
# END ai.skillz: direct:symlink:claude:dep-supersede-scan
|
||||||
|
|
@ -192,13 +229,29 @@ docs/conversations/
|
||||||
/.opencode/skills/dep-supersede-scan
|
/.opencode/skills/dep-supersede-scan
|
||||||
# END ai.skillz: direct:symlink:opencode:dep-supersede-scan
|
# END ai.skillz: direct:symlink:opencode:dep-supersede-scan
|
||||||
|
|
||||||
# BEGIN ai.skillz: direct:symlink:claude:gish
|
# BEGIN ai.skillz: direct:symlink:claude:resolve-conflicts
|
||||||
/.claude/skills/gish
|
/.claude/skills/resolve-conflicts
|
||||||
# END ai.skillz: direct:symlink:claude:gish
|
# END ai.skillz: direct:symlink:claude:resolve-conflicts
|
||||||
|
|
||||||
# BEGIN ai.skillz: direct:symlink:opencode:gish
|
# BEGIN ai.skillz: direct:symlink:opencode:resolve-conflicts
|
||||||
/.opencode/skills/gish
|
/.opencode/skills/resolve-conflicts
|
||||||
# END ai.skillz: direct:symlink:opencode:gish
|
# END ai.skillz: direct:symlink:opencode:resolve-conflicts
|
||||||
|
|
||||||
|
# BEGIN ai.skillz: direct:symlink:claude:git-mgmt
|
||||||
|
/.claude/skills/git-mgmt
|
||||||
|
# END ai.skillz: direct:symlink:claude:git-mgmt
|
||||||
|
|
||||||
|
# BEGIN ai.skillz: direct:symlink:opencode:git-mgmt
|
||||||
|
/.opencode/skills/git-mgmt
|
||||||
|
# END ai.skillz: direct:symlink:opencode:git-mgmt
|
||||||
|
|
||||||
|
# BEGIN ai.skillz: direct:symlink:claude:harness-perf
|
||||||
|
/.claude/skills/harness-perf
|
||||||
|
# END ai.skillz: direct:symlink:claude:harness-perf
|
||||||
|
|
||||||
|
# BEGIN ai.skillz: direct:symlink:opencode:harness-perf
|
||||||
|
/.opencode/skills/harness-perf
|
||||||
|
# END ai.skillz: direct:symlink:opencode:harness-perf
|
||||||
|
|
||||||
# BEGIN ai.skillz: direct:symlink:claude:inter-skill-review
|
# BEGIN ai.skillz: direct:symlink:claude:inter-skill-review
|
||||||
/.claude/skills/inter-skill-review
|
/.claude/skills/inter-skill-review
|
||||||
|
|
@ -208,18 +261,13 @@ docs/conversations/
|
||||||
/.opencode/skills/inter-skill-review
|
/.opencode/skills/inter-skill-review
|
||||||
# END ai.skillz: direct:symlink:opencode:inter-skill-review
|
# END ai.skillz: direct:symlink:opencode:inter-skill-review
|
||||||
|
|
||||||
# BEGIN ai.skillz: runtime:open-wkt
|
# BEGIN ai.skillz: direct:symlink:claude:opencode-cleaning
|
||||||
.claude/wkts/
|
/.claude/skills/opencode-cleaning
|
||||||
claude_wkts
|
# END ai.skillz: direct:symlink:claude:opencode-cleaning
|
||||||
# END ai.skillz: runtime:open-wkt
|
|
||||||
|
|
||||||
# BEGIN ai.skillz: direct:symlink:claude:open-wkt
|
# BEGIN ai.skillz: direct:symlink:opencode:opencode-cleaning
|
||||||
/.claude/skills/open-wkt
|
/.opencode/skills/opencode-cleaning
|
||||||
# END ai.skillz: direct:symlink:claude:open-wkt
|
# END ai.skillz: direct:symlink:opencode:opencode-cleaning
|
||||||
|
|
||||||
# BEGIN ai.skillz: direct:symlink:opencode:open-wkt
|
|
||||||
/.opencode/skills/open-wkt
|
|
||||||
# END ai.skillz: direct:symlink:opencode:open-wkt
|
|
||||||
|
|
||||||
# BEGIN ai.skillz: direct:symlink:claude:plan-io
|
# BEGIN ai.skillz: direct:symlink:claude:plan-io
|
||||||
/.claude/skills/plan-io
|
/.claude/skills/plan-io
|
||||||
|
|
@ -230,6 +278,8 @@ claude_wkts
|
||||||
# END ai.skillz: direct:symlink:opencode:plan-io
|
# END ai.skillz: direct:symlink:opencode:plan-io
|
||||||
|
|
||||||
# BEGIN ai.skillz: runtime:pr-msg
|
# BEGIN ai.skillz: runtime:pr-msg
|
||||||
|
.ai/state/pr-msg/
|
||||||
|
.ai/pr-msg/conf.toml
|
||||||
.claude/skills/pr-msg/msgs/
|
.claude/skills/pr-msg/msgs/
|
||||||
.claude/skills/pr-msg/pr_msg_LATEST.md
|
.claude/skills/pr-msg/pr_msg_LATEST.md
|
||||||
# END ai.skillz: runtime:pr-msg
|
# END ai.skillz: runtime:pr-msg
|
||||||
|
|
@ -262,14 +312,6 @@ claude_wkts
|
||||||
/.opencode/skills/py-codestyle
|
/.opencode/skills/py-codestyle
|
||||||
# END ai.skillz: direct:symlink:opencode:py-codestyle
|
# END ai.skillz: direct:symlink:opencode:py-codestyle
|
||||||
|
|
||||||
# BEGIN ai.skillz: direct:symlink:claude:resolve-conflicts
|
|
||||||
/.claude/skills/resolve-conflicts
|
|
||||||
# END ai.skillz: direct:symlink:claude:resolve-conflicts
|
|
||||||
|
|
||||||
# BEGIN ai.skillz: direct:symlink:opencode:resolve-conflicts
|
|
||||||
/.opencode/skills/resolve-conflicts
|
|
||||||
# END ai.skillz: direct:symlink:opencode:resolve-conflicts
|
|
||||||
|
|
||||||
# BEGIN ai.skillz: runtime:taken-export
|
# BEGIN ai.skillz: runtime:taken-export
|
||||||
.ai/taken/exports/
|
.ai/taken/exports/
|
||||||
# END ai.skillz: runtime:taken-export
|
# END ai.skillz: runtime:taken-export
|
||||||
|
|
@ -290,18 +332,163 @@ claude_wkts
|
||||||
/.opencode/skills/yt-url-lookup
|
/.opencode/skills/yt-url-lookup
|
||||||
# END ai.skillz: direct:symlink:opencode:yt-url-lookup
|
# END ai.skillz: direct:symlink:opencode:yt-url-lookup
|
||||||
|
|
||||||
# BEGIN ai.skillz: direct:symlink:claude:command:branch-in-new-terminal
|
# BEGIN ai.skillz: direct:symlink:opencode:command:run-tests
|
||||||
/.claude/commands/branch-in-new-terminal.md
|
/.opencode/commands/run-tests.md
|
||||||
# END ai.skillz: direct:symlink:claude:command:branch-in-new-terminal
|
# END ai.skillz: direct:symlink:opencode:command:run-tests
|
||||||
|
|
||||||
# BEGIN ai.skillz: runtime:branch-in-new-terminal
|
# BEGIN ai.skillz: direct:symlink:opencode:command:code-review
|
||||||
.claude/.current_session
|
/.opencode/commands/code-review.md
|
||||||
# END ai.skillz: runtime:branch-in-new-terminal
|
# END ai.skillz: direct:symlink:opencode:command:code-review
|
||||||
|
|
||||||
|
# BEGIN ai.skillz: direct:symlink:opencode:command:code-review-changes
|
||||||
|
/.opencode/commands/code-review-changes.md
|
||||||
|
# END ai.skillz: direct:symlink:opencode:command:code-review-changes
|
||||||
|
|
||||||
# BEGIN ai.skillz: direct:symlink:opencode:command:commit-msg
|
# BEGIN ai.skillz: direct:symlink:opencode:command:commit-msg
|
||||||
/.opencode/commands/commit-msg.md
|
/.opencode/commands/commit-msg.md
|
||||||
# END ai.skillz: direct:symlink:opencode:command:commit-msg
|
# END ai.skillz: direct:symlink:opencode:command:commit-msg
|
||||||
|
|
||||||
|
# BEGIN ai.skillz: direct:symlink:opencode:command:commit-plan
|
||||||
|
/.opencode/commands/commit-plan.md
|
||||||
|
# END ai.skillz: direct:symlink:opencode:command:commit-plan
|
||||||
|
|
||||||
|
# BEGIN ai.skillz: direct:symlink:opencode:command:opencode-cleaning
|
||||||
|
/.opencode/commands/opencode-cleaning.md
|
||||||
|
# END ai.skillz: direct:symlink:opencode:command:opencode-cleaning
|
||||||
|
|
||||||
|
# BEGIN ai.skillz: direct:symlink:opencode:command:pr-msg
|
||||||
|
/.opencode/commands/pr-msg.md
|
||||||
|
# END ai.skillz: direct:symlink:opencode:command:pr-msg
|
||||||
|
|
||||||
# BEGIN ai.skillz: direct:symlink:opencode:command:taken-export
|
# BEGIN ai.skillz: direct:symlink:opencode:command:taken-export
|
||||||
/.opencode/commands/taken-export.md
|
/.opencode/commands/taken-export.md
|
||||||
# END ai.skillz: direct:symlink:opencode:command:taken-export
|
# END ai.skillz: direct:symlink:opencode:command:taken-export
|
||||||
|
|
||||||
|
# BEGIN ai.skillz: direct:symlink:claude:code-nav-refs
|
||||||
|
/.claude/skills/code-nav-refs
|
||||||
|
# END ai.skillz: direct:symlink:claude:code-nav-refs
|
||||||
|
|
||||||
|
# BEGIN ai.skillz: direct:symlink:opencode:code-nav-refs
|
||||||
|
/.opencode/skills/code-nav-refs
|
||||||
|
# END ai.skillz: direct:symlink:opencode:code-nav-refs
|
||||||
|
|
||||||
|
# BEGIN ai.skillz: direct:symlink:opencode:command:gish
|
||||||
|
/.opencode/commands/gish.md
|
||||||
|
# END ai.skillz: direct:symlink:opencode:command:gish
|
||||||
|
|
||||||
|
# BEGIN ai.skillz: direct:symlink:opencode:command:resolve-conflicts
|
||||||
|
/.opencode/commands/resolve-conflicts.md
|
||||||
|
# END ai.skillz: direct:symlink:opencode:command:resolve-conflicts
|
||||||
|
|
||||||
|
# BEGIN ai.skillz: direct:symlink:opencode:command:git-mgmt
|
||||||
|
/.opencode/commands/git-mgmt.md
|
||||||
|
# END ai.skillz: direct:symlink:opencode:command:git-mgmt
|
||||||
|
|
||||||
|
# BEGIN ai.skillz: direct:symlink:opencode:command:open-wkt
|
||||||
|
/.opencode/commands/open-wkt.md
|
||||||
|
# END ai.skillz: direct:symlink:opencode:command:open-wkt
|
||||||
|
|
||||||
|
# BEGIN ai.skillz: direct:symlink:opencode:command:close-wkt
|
||||||
|
/.opencode/commands/close-wkt.md
|
||||||
|
# END ai.skillz: direct:symlink:opencode:command:close-wkt
|
||||||
|
|
||||||
|
# BEGIN ai.skillz: direct:symlink:opencode:command:dep-supersede-scan
|
||||||
|
/.opencode/commands/dep-supersede-scan.md
|
||||||
|
# END ai.skillz: direct:symlink:opencode:command:dep-supersede-scan
|
||||||
|
|
||||||
|
# BEGIN ai.skillz: direct:symlink:opencode:command:harness-perf
|
||||||
|
/.opencode/commands/harness-perf.md
|
||||||
|
# END ai.skillz: direct:symlink:opencode:command:harness-perf
|
||||||
|
|
||||||
|
# BEGIN ai.skillz: direct:symlink:opencode:command:yt-url-lookup
|
||||||
|
/.opencode/commands/yt-url-lookup.md
|
||||||
|
# END ai.skillz: direct:symlink:opencode:command:yt-url-lookup
|
||||||
|
# BEGIN ai.skillz: direct:symlink:agents:gish
|
||||||
|
/.agents/skills/gish
|
||||||
|
# END ai.skillz: direct:symlink:agents:gish
|
||||||
|
|
||||||
|
# BEGIN ai.skillz: direct:symlink:agents:resolve-conflicts
|
||||||
|
/.agents/skills/resolve-conflicts
|
||||||
|
# END ai.skillz: direct:symlink:agents:resolve-conflicts
|
||||||
|
|
||||||
|
# BEGIN ai.skillz: direct:symlink:agents:git-mgmt
|
||||||
|
/.agents/skills/git-mgmt
|
||||||
|
# END ai.skillz: direct:symlink:agents:git-mgmt
|
||||||
|
|
||||||
|
# BEGIN ai.skillz: direct:symlink:agents:open-wkt
|
||||||
|
/.agents/skills/open-wkt
|
||||||
|
# END ai.skillz: direct:symlink:agents:open-wkt
|
||||||
|
|
||||||
|
# BEGIN ai.skillz: direct:symlink:agents:run-tests
|
||||||
|
/.agents/skills/run-tests
|
||||||
|
# END ai.skillz: direct:symlink:agents:run-tests
|
||||||
|
|
||||||
|
# BEGIN ai.skillz: direct:symlink:agents:close-wkt
|
||||||
|
/.agents/skills/close-wkt
|
||||||
|
# END ai.skillz: direct:symlink:agents:close-wkt
|
||||||
|
|
||||||
|
# BEGIN ai.skillz: direct:symlink:agents:code-review
|
||||||
|
/.agents/skills/code-review
|
||||||
|
# END ai.skillz: direct:symlink:agents:code-review
|
||||||
|
|
||||||
|
# BEGIN ai.skillz: direct:symlink:agents:code-nav-refs
|
||||||
|
/.agents/skills/code-nav-refs
|
||||||
|
# END ai.skillz: direct:symlink:agents:code-nav-refs
|
||||||
|
|
||||||
|
# BEGIN ai.skillz: direct:symlink:agents:code-review-changes
|
||||||
|
/.agents/skills/code-review-changes
|
||||||
|
# END ai.skillz: direct:symlink:agents:code-review-changes
|
||||||
|
|
||||||
|
# BEGIN ai.skillz: direct:symlink:agents:commit-msg
|
||||||
|
/.agents/skills/commit-msg
|
||||||
|
# END ai.skillz: direct:symlink:agents:commit-msg
|
||||||
|
|
||||||
|
# BEGIN ai.skillz: direct:symlink:agents:commit-plan
|
||||||
|
/.agents/skills/commit-plan
|
||||||
|
# END ai.skillz: direct:symlink:agents:commit-plan
|
||||||
|
|
||||||
|
# BEGIN ai.skillz: direct:symlink:agents:dep-supersede-scan
|
||||||
|
/.agents/skills/dep-supersede-scan
|
||||||
|
# END ai.skillz: direct:symlink:agents:dep-supersede-scan
|
||||||
|
|
||||||
|
# BEGIN ai.skillz: direct:symlink:agents:harness-perf
|
||||||
|
/.agents/skills/harness-perf
|
||||||
|
# END ai.skillz: direct:symlink:agents:harness-perf
|
||||||
|
|
||||||
|
# BEGIN ai.skillz: direct:symlink:agents:inter-skill-review
|
||||||
|
/.agents/skills/inter-skill-review
|
||||||
|
# END ai.skillz: direct:symlink:agents:inter-skill-review
|
||||||
|
|
||||||
|
# BEGIN ai.skillz: direct:symlink:agents:opencode-cleaning
|
||||||
|
/.agents/skills/opencode-cleaning
|
||||||
|
# END ai.skillz: direct:symlink:agents:opencode-cleaning
|
||||||
|
|
||||||
|
# BEGIN ai.skillz: direct:symlink:agents:plan-io
|
||||||
|
/.agents/skills/plan-io
|
||||||
|
# END ai.skillz: direct:symlink:agents:plan-io
|
||||||
|
|
||||||
|
# BEGIN ai.skillz: direct:symlink:agents:pr-msg
|
||||||
|
/.agents/skills/pr-msg
|
||||||
|
# END ai.skillz: direct:symlink:agents:pr-msg
|
||||||
|
|
||||||
|
# BEGIN ai.skillz: direct:symlink:agents:prompt-io
|
||||||
|
/.agents/skills/prompt-io
|
||||||
|
# END ai.skillz: direct:symlink:agents:prompt-io
|
||||||
|
|
||||||
|
# BEGIN ai.skillz: direct:symlink:agents:py-codestyle
|
||||||
|
/.agents/skills/py-codestyle
|
||||||
|
# END ai.skillz: direct:symlink:agents:py-codestyle
|
||||||
|
|
||||||
|
# BEGIN ai.skillz: direct:symlink:agents:taken-export
|
||||||
|
/.agents/skills/taken-export
|
||||||
|
# END ai.skillz: direct:symlink:agents:taken-export
|
||||||
|
|
||||||
|
# BEGIN ai.skillz: direct:symlink:agents:yt-url-lookup
|
||||||
|
/.agents/skills/yt-url-lookup
|
||||||
|
# END ai.skillz: direct:symlink:agents:yt-url-lookup
|
||||||
|
|
||||||
|
# BEGIN ai.skillz: workflow-state
|
||||||
|
/.ai/state/
|
||||||
|
/.ai/commit-msg/conf.toml
|
||||||
|
/.ai/pr-msg/conf.toml
|
||||||
|
# END ai.skillz: workflow-state
|
||||||
|
|
|
||||||
19
ai/README.md
19
ai/README.md
|
|
@ -17,18 +17,6 @@ track new integration ideas and proposals in
|
||||||
| Tool | Directory | Status |
|
| Tool | Directory | Status |
|
||||||
|------|-----------|--------|
|
|------|-----------|--------|
|
||||||
| [Claude Code](https://github.com/anthropics/claude-code) | [`claude-code/`](claude-code/) | active |
|
| [Claude Code](https://github.com/anthropics/claude-code) | [`claude-code/`](claude-code/) | active |
|
||||||
| [OpenCode](https://opencode.ai/) | [`opencode/`](opencode/) | active |
|
|
||||||
|
|
||||||
## Shared Skills
|
|
||||||
|
|
||||||
Repo-specific skills use the portable Agent Skills
|
|
||||||
frontmatter subset and live under `.claude/skills/` as a
|
|
||||||
single source. Claude Code discovers that directory
|
|
||||||
natively, and OpenCode discovers the same project skills
|
|
||||||
without copies or generated wrappers.
|
|
||||||
|
|
||||||
Harness-specific command files should only delegate to a
|
|
||||||
shared skill. They must not duplicate the skill body.
|
|
||||||
|
|
||||||
## Adding a New Integration
|
## Adding a New Integration
|
||||||
|
|
||||||
|
|
@ -44,7 +32,7 @@ ai/
|
||||||
├── README.md # <- you are here
|
├── README.md # <- you are here
|
||||||
├── claude-code/
|
├── claude-code/
|
||||||
│ └── README.md
|
│ └── README.md
|
||||||
├── opencode/
|
├── opencode/ # future
|
||||||
│ └── README.md
|
│ └── README.md
|
||||||
└── <your-tool>/
|
└── <your-tool>/
|
||||||
└── README.md
|
└── README.md
|
||||||
|
|
@ -57,7 +45,6 @@ ai/
|
||||||
- Each integration doc should describe **what**
|
- Each integration doc should describe **what**
|
||||||
the skill does, **how** to invoke it, and any
|
the skill does, **how** to invoke it, and any
|
||||||
**output** artifacts it produces
|
**output** artifacts it produces
|
||||||
- Keep docs concise; link to the shared skill source files
|
- Keep docs concise; link to the actual skill
|
||||||
|
source files (under `.claude/skills/`, etc.)
|
||||||
rather than duplicating content
|
rather than duplicating content
|
||||||
- Keep skill bodies harness-neutral; isolate slash-command
|
|
||||||
syntax and permissions in each harness integration
|
|
||||||
|
|
|
||||||
|
|
@ -1,17 +1,15 @@
|
||||||
# Claude Code Integration
|
# Claude Code Integration
|
||||||
|
|
||||||
[Claude Code](https://github.com/anthropics/claude-code)
|
[Claude Code](https://github.com/anthropics/claude-code)
|
||||||
integration for piker's shared coding-harness skills.
|
skills and workflows for piker development.
|
||||||
|
|
||||||
## Skills
|
## Skills
|
||||||
|
|
||||||
| Skill | Invocable | Description |
|
| Skill | Invocable | Description |
|
||||||
|-------|-----------|-------------|
|
|-------|-----------|-------------|
|
||||||
| [`commit-msg`](#commit-msg) | `/commit-msg` | Generate piker-style commit messages |
|
| [`commit-msg`](#commit-msg) | `/commit-msg` | Generate piker-style commit messages |
|
||||||
| `piker-conc-expert` | auto | Actor-tree and structured-concurrency invariants |
|
|
||||||
| `piker-profiling` | auto | `Profiler` API patterns for perf work |
|
| `piker-profiling` | auto | `Profiler` API patterns for perf work |
|
||||||
| `piker-slang` | auto | Communication style + slang guide |
|
| `piker-slang` | auto | Communication style + slang guide |
|
||||||
| `py-codestyle` | auto | Python source conventions |
|
|
||||||
| `pyqtgraph-optimization` | auto | Batch rendering patterns |
|
| `pyqtgraph-optimization` | auto | Batch rendering patterns |
|
||||||
| `timeseries-optimization` | auto | NumPy/Polars perf patterns |
|
| `timeseries-optimization` | auto | NumPy/Polars perf patterns |
|
||||||
|
|
||||||
|
|
@ -19,10 +17,8 @@ Skills marked **auto** are background knowledge
|
||||||
applied automatically when Claude detects relevance.
|
applied automatically when Claude detects relevance.
|
||||||
Only `commit-msg` is user-invoked via slash command.
|
Only `commit-msg` is user-invoked via slash command.
|
||||||
|
|
||||||
Portable skill source files live under
|
Skill source files live under
|
||||||
`.claude/skills/<skill-name>/SKILL.md` and are shared with
|
`.claude/skills/<skill-name>/SKILL.md`.
|
||||||
OpenCode. Claude-specific behavior belongs in command or
|
|
||||||
settings files, not the shared skill bodies.
|
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|
@ -88,7 +84,8 @@ description context. Examples:
|
||||||
**Footer** (always):
|
**Footer** (always):
|
||||||
```
|
```
|
||||||
(this patch was generated in some part by
|
(this patch was generated in some part by
|
||||||
`claude-code` using `<model>` (`<provider>`))
|
[`claude-code`][claude-code-gh])
|
||||||
|
[claude-code-gh]: https://github.com/anthropics/claude-code
|
||||||
```
|
```
|
||||||
|
|
||||||
### Output Files
|
### Output Files
|
||||||
|
|
@ -97,8 +94,7 @@ After generation, the commit message is written to:
|
||||||
|
|
||||||
```
|
```
|
||||||
.claude/
|
.claude/
|
||||||
├── skills/commit-msg/msgs/
|
├── <timestamp>_<hash>_commit_msg.md # archived
|
||||||
│ └── <timestamp>_<hash>_commit_msg.md
|
|
||||||
└── git_commit_msg_LATEST.md # latest
|
└── git_commit_msg_LATEST.md # latest
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
@ -106,10 +102,18 @@ Where `<timestamp>` is ISO-8601 with seconds and
|
||||||
`<hash>` is the first 7 chars of the current
|
`<hash>` is the first 7 chars of the current
|
||||||
`HEAD` commit.
|
`HEAD` commit.
|
||||||
|
|
||||||
Use the latest file with an editor review before commit:
|
Use the latest file to feed into `git commit`:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
git commit --edit --file .claude/git_commit_msg_LATEST.md
|
git commit -F .claude/git_commit_msg_LATEST.md
|
||||||
|
```
|
||||||
|
|
||||||
|
Or review/edit before committing:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cat .claude/git_commit_msg_LATEST.md
|
||||||
|
# edit if needed, then:
|
||||||
|
git commit -F .claude/git_commit_msg_LATEST.md
|
||||||
```
|
```
|
||||||
|
|
||||||
### Examples
|
### Examples
|
||||||
|
|
@ -124,32 +128,56 @@ Add `MktPair.fqme` property for symbol resolution
|
||||||
Factor `.claude/skills/` into proper subdirs
|
Factor `.claude/skills/` into proper subdirs
|
||||||
|
|
||||||
Deats,
|
Deats,
|
||||||
- use portable Agent Skills frontmatter
|
- `commit_msg/` -> `commit-msg/` w/ enhanced
|
||||||
- keep harness commands as thin delegates
|
frontmatter
|
||||||
- share supporting references across harnesses
|
- all background skills set `user-invocable: false`
|
||||||
|
- content split into supporting files
|
||||||
|
|
||||||
(this patch was generated in some part by
|
(this patch was generated in some part by
|
||||||
`claude-code` using `<model>` (`<provider>`))
|
[`claude-code`][claude-code-gh])
|
||||||
|
[claude-code-gh]: https://github.com/anthropics/claude-code
|
||||||
```
|
```
|
||||||
|
|
||||||
### Shared Frontmatter
|
### Frontmatter Reference
|
||||||
|
|
||||||
Skills use the Agent Skills fields understood by both
|
The skill's `SKILL.md` uses these Claude Code
|
||||||
Claude Code and OpenCode:
|
frontmatter fields:
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
---
|
---
|
||||||
name: commit-msg
|
name: commit-msg
|
||||||
description: >
|
description: >
|
||||||
Generate piker-style git commit messages. Use when...
|
Generate piker-style git commit messages...
|
||||||
compatibility: Requires git.
|
argument-hint: "[optional-scope-or-description]"
|
||||||
metadata:
|
disable-model-invocation: true
|
||||||
author: goodboy
|
allowed-tools:
|
||||||
version: "1.0"
|
- Bash(git *)
|
||||||
|
- Read
|
||||||
|
- Grep
|
||||||
|
- Glob
|
||||||
|
- Write
|
||||||
---
|
---
|
||||||
```
|
```
|
||||||
|
|
||||||
Live git context is gathered by the skill at execution
|
| Field | Purpose |
|
||||||
time. Claude-only dynamic interpolation and tool-policy
|
|-------|---------|
|
||||||
frontmatter are intentionally excluded so another harness
|
| `argument-hint` | Shows hint in autocomplete |
|
||||||
can execute the same workflow.
|
| `disable-model-invocation` | Only user can trigger via `/commit-msg` |
|
||||||
|
| `allowed-tools` | Tools the skill can use |
|
||||||
|
|
||||||
|
### Dynamic Context
|
||||||
|
|
||||||
|
The skill injects live data at invocation time
|
||||||
|
via `!`backtick`` syntax in the `SKILL.md`:
|
||||||
|
|
||||||
|
```markdown
|
||||||
|
## Current staged changes
|
||||||
|
!`git diff --staged --stat`
|
||||||
|
|
||||||
|
## Recent commit style reference
|
||||||
|
!`git log --oneline -10`
|
||||||
|
```
|
||||||
|
|
||||||
|
This means the staged diff stats and recent log
|
||||||
|
are always fresh when the skill runs -- no stale
|
||||||
|
context.
|
||||||
|
|
|
||||||
|
|
@ -1,143 +0,0 @@
|
||||||
# Split `brokerd.<broker>` into trading-only `brokerd` + new `datad.<broker>`
|
|
||||||
|
|
||||||
## Context
|
|
||||||
|
|
||||||
Today a single `brokerd.<broker>` actor hosts BOTH concerns:
|
|
||||||
|
|
||||||
- **data feed service tasks**: the `_FeedsBus` + `open_feed_bus()` ep (`piker/data/feed.py:464`), per-symbol `allocate_persistent_feed()` tasks (shm writers via `sample_and_broadcast()`, history backfill via `piker.tsp`), plus backend eps `stream_quotes`, `open_history_client`, `open_symbol_search`, `get_mkt_info` from `piker/brokers/<backend>/feed.py`/`symbols.py`,
|
|
||||||
- **live order-control tasks**: `open_trade_dialog()` from `piker/brokers/<backend>/broker.py`, driven by `emsd`.
|
|
||||||
|
|
||||||
The codebase already anticipates this split: `piker/data/validate.py:70-91` groups backend eps into `'datad'` vs `'brokerd'` kinds, `piker/brokers/ib/__init__.py:62-70` already declares `_brokerd_mods`/`_datad_mods`, and `piker/brokers/_daemon.py:62` carries the literal TODO *"rename the daemon to datad prolly once we split up broker vs. data tasks into separate actors?"*. This work executes that split.
|
|
||||||
|
|
||||||
**User-decided constraints:**
|
|
||||||
|
|
||||||
- `datad.<broker>` is a **sibling** of `brokerd.<broker>` under `pikerd`, spawned via the existing `Services` + `maybe_spawn_daemon()` machinery (`piker/service/_daemon.py:46`).
|
|
||||||
- **Hard cutover, staged by layer** — no dual-mode runtime flag; every stage lands fully working.
|
|
||||||
- Post-split `brokerd` is **trading-only and lazily spawned solely by emsd's** `open_brokerd_dialog` path; UI/CLI/feed code never spawns it. Chart-only and paper sessions run with **zero** brokerd processes.
|
|
||||||
|
|
||||||
## Target topology
|
|
||||||
|
|
||||||
```
|
|
||||||
pikerd
|
|
||||||
├── datad.ib feed bus, shm writers, tsp history, symbol search
|
|
||||||
├── brokerd.ib open_trade_dialog only (EMS-spawned, lazy)
|
|
||||||
├── emsd
|
|
||||||
│ └── paperboi.ib (paper mode; opens its feed via datad)
|
|
||||||
└── samplerd
|
|
||||||
```
|
|
||||||
|
|
||||||
## Key verified facts (load-bearing)
|
|
||||||
|
|
||||||
- `feed.portals` has exactly ONE trading consumer: `piker/clearing/_ems.py:671` (`portal = feed.portals[brokermod]` → handed to `open_brokerd_dialog`). This is the single coupling forcing feed + trading into one actor.
|
|
||||||
- `assert 'brokerd' in servicename` at `piker/data/feed.py:502` is the only actor-name assert in the tree.
|
|
||||||
- `piker ledger` (`piker/accounting/cli.py:100-157`) is a hidden consumer: it calls `broker_init()` directly, spawns its own ad-hoc actor, enters `_setup_persistent_brokerd`, then calls `open_brokerd_dialog(brokermod, portal, ...)` **with an explicit portal** — the new signature must keep a `portal:` override param.
|
|
||||||
- kraken's feed→broker coupling is mild: `kraken/broker.py:77-81` imports `NoBsWs`/`open_autorecon_ws` (really from `piker.data._web_bs`) and `stream_messages` (pure parser) from `feed.py`. In-process imports only — `enable_modules` gates RPC, not imports. No live shared state; each actor opens its own WS.
|
|
||||||
- ib: default `client_id=6116` (`ib/api.py:1320`) with linear retry `clientId=client_id + i` (`:1403`). Two ib actors connecting concurrently will collide → needs a role-based id offset. Both daemons need `_spawn_kwargs={'infect_asyncio': True}` (copied by both init fns).
|
|
||||||
- binance has no `symbols.py` (`get_mkt_info`/`open_symbol_search` live in `binance/feed.py`); kucoin/questrade/robinhood are flat single-file with NO `__enable_modules__`; deribit has no `broker.py`.
|
|
||||||
- `tests/test_services.py:80,185` assert `brokerd` actor names incl. the paper-mode flow asserting `brokerd.kraken` spawns (`:229,:237`) — must invert post-split.
|
|
||||||
- `_root_modules` (`piker/service/_actor_runtime.py:156`) must gain the new datad daemon mod so `pikerd_portal.run(spawn_datad, ...)` resolves.
|
|
||||||
- `piker/brokers/core.py:175` `symbol_search` does `portal.run(search_w_brokerd)` where the target fn lives in `piker.brokers.core` → that mod must stay RPC-enabled in datad.
|
|
||||||
|
|
||||||
## Module decision
|
|
||||||
|
|
||||||
New file **`piker/data/_daemon.py`** hosts all datad machinery (`_setup_persistent_datad`, `datad_init`, `spawn_datad`, `maybe_spawn_datad`, `_datad_service_mods`). Mirrors the `piker.brokers._daemon` / `piker.data._sampling` (samplerd) per-subsystem convention and satisfies the existing TODO at `brokers/_daemon.py:49` ("move this def to the `.data` subpkg"). `piker.brokers._daemon` keeps brokerd-only code, slimmed. Do NOT over-DRY the two ~40-line init fns into a shared factory yet (samplerd precedent accepts the duplication).
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Stage 0 — prep: backend module grouping + ep introspection (no topology change)
|
|
||||||
|
|
||||||
1. `piker/data/validate.py`: add a `get_eps(mod, kind) -> dict[str, Callable]` helper returning the backend's defined eps for a daemon-kind from `_eps` (missing eps excluded). Used later by both init fns + fail-fast checks.
|
|
||||||
2. Declare daemon-kind module groups in each split backend's `__init__.py`, keeping `__enable_modules__` as the (deduped) union so behavior is unchanged:
|
|
||||||
- `kraken`: `_brokerd_mods = ['api', 'broker']`, `_datad_mods = ['api', 'feed', 'symbols']`
|
|
||||||
- `binance`: `_brokerd_mods = ['api', 'broker']`, `_datad_mods = ['api', 'feed']`
|
|
||||||
- `deribit`: `_brokerd_mods = []`, `_datad_mods = ['api', 'feed']`
|
|
||||||
- `ib`: adjust existing groups so each includes `'api'`
|
|
||||||
- flat backends (kucoin etc.): no attrs — init fns fall back to enabling just `modpath` (existing behavior).
|
|
||||||
3. Hygiene: `kraken/broker.py:77-81` imports `NoBsWs`/`open_autorecon_ws` from `piker.data._web_bs` directly (keep the `stream_messages` import from `.feed`).
|
|
||||||
|
|
||||||
**Gate**: full pytest green, zero behavior change.
|
|
||||||
|
|
||||||
## Stage 1 — introduce `datad` daemon machinery (additive)
|
|
||||||
|
|
||||||
New `piker/data/_daemon.py`:
|
|
||||||
|
|
||||||
- `_datad_service_mods: list[str]` — datad-always-enabled mods (successor to the data side of `_data_mods` from `brokers/_daemon.py:52`): `['piker.brokers.core', 'piker.brokers.data', 'piker.data', 'piker.data.feed', 'piker.data._sampling', 'piker.data._daemon']`.
|
|
||||||
- `_setup_persistent_datad(ctx, brokername, loglevel)` — `@tractor.context` fixture; logging boilerplate (as `_setup_persistent_brokerd:81-88`), then allocates the actor-global feed bus exactly as the brokerd fixture does today (`brokers/_daemon.py:105-121`): `assert not feed._bus`, open service nursery, `feed.get_feed_bus(brokername, service_nursery)`, `ctx.started()`, `sleep_forever()`.
|
|
||||||
- `datad_init(brokername, ...)` — mirrors `broker_init()` (`brokers/_daemon.py:132`): actor name `f'datad.{brokername}'`, copies backend `_spawn_kwargs` (**critical for ib infect_asyncio**), builds `enable_modules` from `getattr(brokermod, '_datad_mods', getattr(brokermod, '__enable_modules__', []))`.
|
|
||||||
- `spawn_datad(brokername, ...)` — mirrors `spawn_brokerd()` (`brokers/_daemon.py:202`): `Services.actor_n.start_actor(dname, enable_modules=_datad_service_mods + backend_mods, ...)` + `Services.start_service_task(dname, portal, _setup_persistent_datad, ...)`.
|
|
||||||
- `maybe_spawn_datad(brokername, ...)` — wraps `maybe_spawn_daemon(service_name=f'datad.{brokername}', service_task_target=spawn_datad, ...)` exactly like `maybe_spawn_brokerd` (`brokers/_daemon.py:256`).
|
|
||||||
|
|
||||||
Supporting edits:
|
|
||||||
|
|
||||||
- `piker/service/_actor_runtime.py:156`: add `'piker.data._daemon'` to `_root_modules` (keep `'piker.brokers._daemon'`).
|
|
||||||
- `piker/service/__init__.py`: re-export `spawn_datad`/`maybe_spawn_datad` next to the brokerd ones (`:56-57`).
|
|
||||||
- `tests/test_services.py`: new `test_datad_spawn` — `open_test_pikerd` + `maybe_spawn_datad('kraken')` + `ensure_service('datad.kraken')`. (Do NOT route a feed through it yet — `open_feed_bus`'s assert still says brokerd.)
|
|
||||||
|
|
||||||
**Gate**: suite green + new spawn test; nothing routes through datad yet.
|
|
||||||
|
|
||||||
## Stage 2 — clearing layer: emsd self-spawns brokerd (decouple from `feed.portals`)
|
|
||||||
|
|
||||||
Sequenced BEFORE the feed cutover so live trading works at every boundary (otherwise `feed.portals` would hand emsd a datad portal).
|
|
||||||
|
|
||||||
`piker/clearing/_ems.py`:
|
|
||||||
|
|
||||||
1. `open_brokerd_dialog()` (`:336`) new signature: `(brokermod, exec_mode, fqme=None, portal: tractor.Portal|None = None, loglevel=None)`. Internals: keep trades-ep detection (`:400-417`); acquire the brokerd actor ONLY when a live ep will actually open, via a small inner `@acm _acquire_live_portal()` that yields the passed `portal` if given (the `piker ledger` path) else `async with maybe_spawn_brokerd(brokermod.name, loglevel=loglevel)` — **the single place brokerd boots post-split**. Move the eager `portal.open_context(trades_endpoint, ...)` construction (`:425`) inside that block; the paper short-circuit (`:432`) never touches it.
|
|
||||||
2. `Router.maybe_open_brokerd_dialog()` (`:581`) — drop the `portal` param; `Router.open_trade_relays()` (`:640`) — delete `portal = feed.portals[brokermod]` (`:671`) and the pass-through (`:685`).
|
|
||||||
3. `piker/accounting/cli.py:144`: switch to keyword form `open_brokerd_dialog(brokermod, exec_mode=..., portal=portal, loglevel=...)`.
|
|
||||||
|
|
||||||
Pre-cutover this is a pure refactor: emsd's `maybe_spawn_brokerd` just *finds* the already-running brokerd via the registry.
|
|
||||||
|
|
||||||
**Gate**: `tests/test_ems.py` + services suite green; manual paper order on kraken; `piker ledger` smoke.
|
|
||||||
|
|
||||||
## Stage 3 — feed layer hard cutover to datad
|
|
||||||
|
|
||||||
1. `piker/data/feed.py`: import `maybe_spawn_datad` (replacing `maybe_spawn_brokerd`, `:56-58`); `open_feed()` `:895` → `maybe_spawn_datad(...)` (rename `brokerd_ctxs` → `datad_ctxs`); `open_feed_bus()` `:502` → `assert 'datad' in servicename`; comment sweep.
|
|
||||||
2. `piker/brokers/_daemon.py` `_setup_persistent_brokerd()`: slim to trading-only fixture — logging setup, `ctx.started()`, `sleep_forever()`. Drop the bus alloc, `assert not feed._bus`, the service nursery (backend `open_trade_dialog` ctxs own their task trees), the `eg.ExceptionGroup` handler, and the stale `_FeedsBus` TYPE_CHECKING import. (`piker ledger`'s ad-hoc actor enters this same slimmed fixture — exactly what it needs.)
|
|
||||||
3. Repoint remaining data-flavored spawn sites `maybe_spawn_brokerd` → `maybe_spawn_datad`:
|
|
||||||
- `piker/ui/_app.py:40,57` (symbol search; optionally rename `install_brokerd_search` → `install_datad_search`, def at `piker/data/feed.py:766`)
|
|
||||||
- `piker/brokers/core.py:33,175` (`symbol_search`)
|
|
||||||
- `piker/brokers/cli.py:38,190,320` (`brokercheck`, `record`)
|
|
||||||
- `piker/ui/cli.py:30,72,121` (legacy kivy monitor/optschain) + best-effort `piker/ui/kivy/option_chain.py:498` `wait_for_actor('brokerd')` → `'datad'`
|
|
||||||
4. `tests/test_services.py`: `:80,:185` `actor_name = 'datad'`; paper-mode test asserts `datad.kraken` + `paperboi.kraken` + `emsd` AND adds the headline negative check: `assert 'brokerd.kraken' not in services.service_tasks`.
|
|
||||||
|
|
||||||
**Gate**: full suite with inverted assertions; manual: chart on binance/kraken shows `datad.<broker>` in `piker services` and NO brokerd; paper order fills; symbol search works; history backfill sane.
|
|
||||||
|
|
||||||
## Stage 4 — caps-sec slimming, validation, ib client-id
|
|
||||||
|
|
||||||
1. `piker/brokers/_daemon.py`: delete `_data_mods` (`:52`); `spawn_brokerd()` `:236` → `enable_modules=tractor_kwargs.pop('enable_modules')`; `broker_init()` `:184` reads `getattr(brokermod, '_brokerd_mods', getattr(brokermod, '__enable_modules__', []))`. Resulting brokerd enable set has no `piker.data.*` at all.
|
|
||||||
2. Fail-fast ep validation via Stage-0 `validate.get_eps()`: `broker_init` raises a clear error when `get_eps(mod, 'brokerd')` is empty (e.g. "kucoin is datad-only — use paper mode"); `datad_init` warns analogously.
|
|
||||||
3. ib client-id mitigation in `load_aio_clients()` (`ib/api.py:~1316`): role-based offset when `client_id` is the 6116 default (e.g. `+16` when `'datad' in tractor.current_actor().name`), optionally configurable via `brokers.toml` keys.
|
|
||||||
4. Docs/comment sweep: resolve `brokers/_daemon.py:62` TODO, `piker/cli/__init__.py:253` TODO, daemon list in `piker/service/__init__.py:21` docstring.
|
|
||||||
|
|
||||||
**Gate**: full suite; audit greps clean: `grep -rn maybe_spawn_brokerd piker/` hits only `clearing/_ems.py`, `service/__init__.py`, `brokers/_daemon.py`; no spawn-path `'brokerd'` literals left in `piker/data`, `piker/ui`, `piker/brokers/cli.py`.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Risk register
|
|
||||||
|
|
||||||
| Risk | Sev | Mitigation |
|
|
||||||
|---|---|---|
|
|
||||||
| ib: `datad.ib` + `brokerd.ib` both connect to TWS/gw; `client_id=6116` collision burns `connect_timeout` retries | High (live ib only) | Stage 4 role-based id offset; both daemons inherit `infect_asyncio` via `_spawn_kwargs` copy in both init fns |
|
|
||||||
| `piker ledger` ad-hoc actor path silently broken by signature change | Med | `portal:` override kept on `open_brokerd_dialog` (Stage 2); explicit smoke test |
|
|
||||||
| datad-only backends (kucoin/deribit) → useless brokerd spawn | Low | already covered: `open_brokerd_dialog` forces `exec_mode='paper'` when no trades ep (`_ems.py:413-417`) BEFORE the lazy spawn; Stage 4 fail-fast |
|
|
||||||
| brokerd in-process symbology/ledger needs (ib `broker.py` imports `.symbols`; kraken uses `stream_messages`) | None | verified pure in-process imports; `enable_modules` gates RPC only |
|
|
||||||
| paper-mode test asserts brokerd spawns (`test_services.py:237`) | Low | Stage 3 deliberately inverts it |
|
|
||||||
| doubled per-broker clients (HTTP/WS, symcache loads) | Low | each actor already opens its own WS today; symcache is disk-read-mostly |
|
|
||||||
|
|
||||||
## Verification (per stage gates above, plus end-to-end)
|
|
||||||
|
|
||||||
- `pytest tests/test_services.py tests/test_feeds.py tests/test_ems.py` at every stage (kraken/binance public endpoints, no creds needed).
|
|
||||||
- Manual smoke matrix post-Stage-3: `pikerd -l info` + `piker chart btcusdt.spot.binance` → `piker services` shows `datad.binance`, no brokerd; submit paper order → `paperboi.binance` appears, still no brokerd; symbol search; `piker ledger <broker>.paper`.
|
|
||||||
- If ib creds/gateway available: live ib chart + small live order to exercise dual-actor client-id path (Stage 4).
|
|
||||||
|
|
||||||
## Critical files
|
|
||||||
|
|
||||||
- **new** `piker/data/_daemon.py` — all datad machinery
|
|
||||||
- `piker/brokers/_daemon.py` — slimmed brokerd fixture/init/spawn
|
|
||||||
- `piker/data/feed.py` — spawn cutover + actor-name assert
|
|
||||||
- `piker/clearing/_ems.py` — emsd lazy brokerd spawn (`open_brokerd_dialog`, `Router`)
|
|
||||||
- `piker/service/_actor_runtime.py`, `piker/service/__init__.py` — root mods + re-exports
|
|
||||||
- `piker/data/validate.py` — `get_eps()` helper
|
|
||||||
- backend `__init__.py`s (kraken/binance/deribit/ib) — `_datad_mods`/`_brokerd_mods`
|
|
||||||
- `piker/accounting/cli.py` — keyword-form dialog call
|
|
||||||
- `tests/test_services.py` — inverted + new assertions
|
|
||||||
|
|
@ -1,51 +0,0 @@
|
||||||
# OpenCode Integration
|
|
||||||
|
|
||||||
[OpenCode](https://opencode.ai/) uses piker's shared
|
|
||||||
repo-specific skills directly from `.claude/skills/`.
|
|
||||||
There is no second copy of each skill to keep in sync.
|
|
||||||
|
|
||||||
## Available Skills
|
|
||||||
|
|
||||||
| Skill | Activation | Specialization |
|
|
||||||
|-------|------------|----------------|
|
|
||||||
| `commit-msg` | `/commit-msg` or explicit request | Piker commit-message style and artifacts |
|
|
||||||
| `piker-conc-expert` | automatic | `tractor` actor topology, RPC, and cancellation |
|
|
||||||
| `piker-profiling` | automatic | Cross-actor `Profiler` instrumentation |
|
|
||||||
| `piker-slang` | automatic | Project communication style |
|
|
||||||
| `py-codestyle` | automatic | Python source conventions |
|
|
||||||
| `pyqtgraph-optimization` | automatic | Batched Qt graphics rendering |
|
|
||||||
| `timeseries-optimization` | automatic | NumPy and Polars timeseries performance |
|
|
||||||
|
|
||||||
OpenCode's project command lives at
|
|
||||||
`.opencode/commands/commit-msg.md`. It delegates to the
|
|
||||||
shared `commit-msg` skill and only supplies command
|
|
||||||
arguments; workflow logic remains in the skill.
|
|
||||||
|
|
||||||
A user-local skill with the same name may override a repo
|
|
||||||
skill. Treat `opencode debug skill` as authoritative when
|
|
||||||
diagnosing which source is active.
|
|
||||||
|
|
||||||
## Verify Discovery
|
|
||||||
|
|
||||||
From the repository root:
|
|
||||||
|
|
||||||
```console
|
|
||||||
opencode debug skill
|
|
||||||
opencode debug config
|
|
||||||
```
|
|
||||||
|
|
||||||
`opencode debug skill` should list the piker skills from
|
|
||||||
the project checkout. Restart OpenCode after changing a
|
|
||||||
skill or command because configuration-time files are not
|
|
||||||
hot-reloaded into an active session.
|
|
||||||
|
|
||||||
## Portability Rules
|
|
||||||
|
|
||||||
- Use only portable Agent Skills frontmatter in shared
|
|
||||||
`SKILL.md` files.
|
|
||||||
- Keep harness-specific command syntax under
|
|
||||||
`.opencode/commands/`.
|
|
||||||
- Detect the active harness and model at runtime; do not
|
|
||||||
hardcode Claude Code attribution in shared workflows.
|
|
||||||
- Keep supporting references beside each shared skill so
|
|
||||||
relative links resolve in every harness.
|
|
||||||
|
|
@ -1,59 +0,0 @@
|
||||||
---
|
|
||||||
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.
|
|
||||||
|
|
@ -1,46 +0,0 @@
|
||||||
---
|
|
||||||
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.
|
|
||||||
|
|
@ -1,53 +0,0 @@
|
||||||
---
|
|
||||||
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.
|
|
||||||
|
|
@ -1,56 +0,0 @@
|
||||||
---
|
|
||||||
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).
|
|
||||||
|
|
@ -1,54 +0,0 @@
|
||||||
---
|
|
||||||
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.
|
|
||||||
|
|
@ -1,46 +0,0 @@
|
||||||
---
|
|
||||||
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.
|
|
||||||
|
|
@ -1,47 +0,0 @@
|
||||||
---
|
|
||||||
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.
|
|
||||||
|
|
@ -1,60 +0,0 @@
|
||||||
---
|
|
||||||
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").
|
|
||||||
|
|
@ -1,47 +0,0 @@
|
||||||
---
|
|
||||||
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.
|
|
||||||
|
|
@ -1,43 +0,0 @@
|
||||||
---
|
|
||||||
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.
|
|
||||||
|
|
@ -1,48 +0,0 @@
|
||||||
---
|
|
||||||
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.
|
|
||||||
|
|
@ -1,54 +0,0 @@
|
||||||
---
|
|
||||||
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.
|
|
||||||
|
|
@ -1,43 +0,0 @@
|
||||||
---
|
|
||||||
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.
|
|
||||||
|
|
@ -1,41 +0,0 @@
|
||||||
---
|
|
||||||
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`
|
|
||||||
|
|
@ -1,66 +0,0 @@
|
||||||
---
|
|
||||||
model: claude-fable-5[1m]
|
|
||||||
service: claude
|
|
||||||
session: 32d15f9a-b2d3-4c26-bdc9-190219141a25
|
|
||||||
timestamp: 2026-06-10T17:33:09Z
|
|
||||||
git_ref: datad_service
|
|
||||||
diff_cmd: git log -1 -p --follow -- ai/prompt-io/claude/20260610T173309Z_f15f8178_prompt_io.md
|
|
||||||
scope: docs
|
|
||||||
substantive: true
|
|
||||||
raw_file: 20260610T173309Z_f15f8178_prompt_io.raw.md
|
|
||||||
---
|
|
||||||
|
|
||||||
## Prompt
|
|
||||||
|
|
||||||
The session-initiating instruction, verbatim (this doc
|
|
||||||
IS its "mega detailed plan" deliverable):
|
|
||||||
|
|
||||||
> 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 atttempt to factor our current
|
|
||||||
> brokerd service daemon into 2 daemons:
|
|
||||||
>
|
|
||||||
> - a brokerd which only hosts live/paper trading
|
|
||||||
> endoint tasks as defined namely within all
|
|
||||||
> piker/brokers/<backend>/broker.py mods
|
|
||||||
> - a new `datad` subdaemon which in a separate
|
|
||||||
> subactor serves all the data feed service tasks
|
|
||||||
> namely delivered by endpoints in
|
|
||||||
> piker/brokers/<backend>/feed.py (or similar for
|
|
||||||
> less mature backends) and as more rigorously
|
|
||||||
> defined by the validation machinery in
|
|
||||||
> piker.data.validate.
|
|
||||||
>
|
|
||||||
> give me a mega detailed plan on how to approach
|
|
||||||
> this, and a staged approach for the implementation.
|
|
||||||
|
|
||||||
Plan-shaping user decisions (in-session Q&A): sibling
|
|
||||||
topology under `pikerd`; hard cutover staged by layer;
|
|
||||||
trading-only EMS-lazy-spawned `brokerd`. The human
|
|
||||||
staged the doc copy into `ai/claude-code/plans/` and
|
|
||||||
requested this commit after the 7 implementation
|
|
||||||
commits landed.
|
|
||||||
|
|
||||||
## Response summary
|
|
||||||
|
|
||||||
The staged design doc for the `brokerd` -> (`datad` +
|
|
||||||
`brokerd`) split: context, target supervision topology,
|
|
||||||
load-bearing verified facts, per-stage file-level
|
|
||||||
changes with gates, risk register and an end-to-end
|
|
||||||
verification matrix. Produced via 3 parallel explore
|
|
||||||
agents + 1 architect agent + human Q&A before any code
|
|
||||||
was written; all 7 implementation commits in this
|
|
||||||
branch reference its stages in their provenance
|
|
||||||
entries.
|
|
||||||
|
|
||||||
## Files changed
|
|
||||||
|
|
||||||
- `ai/claude-code/plans/datad_service.md` — the design
|
|
||||||
plan doc (human-staged copy of the AI-authored plan)
|
|
||||||
|
|
||||||
## Human edits
|
|
||||||
|
|
||||||
None to the doc content — committed as generated. NB:
|
|
||||||
the implementation deviated from the plan-as-written in
|
|
||||||
4 places, see the raw file's deviation log.
|
|
||||||
|
|
@ -1,51 +0,0 @@
|
||||||
---
|
|
||||||
model: claude-fable-5[1m]
|
|
||||||
service: claude
|
|
||||||
timestamp: 2026-06-10T17:33:09Z
|
|
||||||
git_ref: datad_service
|
|
||||||
diff_cmd: git log -1 -p --follow -- ai/prompt-io/claude/20260610T173309Z_f15f8178_prompt_io.md
|
|
||||||
---
|
|
||||||
|
|
||||||
NOTE: diff-ref mode entry; the AI output here is the
|
|
||||||
committed doc itself (a design plan, not code) so no
|
|
||||||
verbatim copy is duplicated:
|
|
||||||
|
|
||||||
> `git log -1 -p --follow -- ai/claude-code/plans/datad_service.md`
|
|
||||||
|
|
||||||
## Implementation deviation log
|
|
||||||
|
|
||||||
Where the landed 7-commit series differs from the plan
|
|
||||||
as written (recorded for reviewer transparency; the
|
|
||||||
plan doc is committed unmodified):
|
|
||||||
|
|
||||||
1. Commit ordering: the `pytest` config-dir isolation
|
|
||||||
fix lands BEFORE the `tractor`-API drift port. The
|
|
||||||
plan's stage gates assumed a runnable+isolated test
|
|
||||||
baseline; per-commit gating exposed that without
|
|
||||||
isolation the paper-EMS test reads the user's real
|
|
||||||
(polluted) `account.kraken.paper.toml` and reddens.
|
|
||||||
2. The plan's "stage 0: full pytest green" gate
|
|
||||||
required first repairing pre-existing branch
|
|
||||||
breakage vs `tractor` git `main` (boot
|
|
||||||
`AttributeError`, stale discovery/exc/position
|
|
||||||
APIs) — that repair became its own commit
|
|
||||||
("Port service+tests to latest `tractor` APIs")
|
|
||||||
rather than plan-stage work.
|
|
||||||
3. Stage-4 fail-fast placement: the plan said
|
|
||||||
`broker_init()` raises on brokerd-ep-less backends;
|
|
||||||
implementation moved the raise to `spawn_brokerd()`
|
|
||||||
since `piker ledger` calls `broker_init()` directly
|
|
||||||
even for paper accounts on datad-only backends.
|
|
||||||
4. `brokers/_daemon.py` change grouping: the
|
|
||||||
import-cleanup hunks (`exceptiongroup`, `_FeedsBus`
|
|
||||||
type-only import) landed with the caps-sec slim
|
|
||||||
commit instead of the fixture-slim commit, keeping
|
|
||||||
each intermediate tree import-clean without
|
|
||||||
sub-hunk surgery.
|
|
||||||
|
|
||||||
Also of record: the plan's "Verification" matrix was
|
|
||||||
executed as written (per-suite gates each stage, the
|
|
||||||
headless datad-feed smoke, the kucoin fail-fast unit
|
|
||||||
check); the known pre-existing ~50% second-runtime-boot
|
|
||||||
test wedge was characterized and excluded as a
|
|
||||||
regression via revert-testing.
|
|
||||||
|
|
@ -1,60 +0,0 @@
|
||||||
---
|
|
||||||
model: claude-fable-5[1m]
|
|
||||||
service: claude
|
|
||||||
session: 32d15f9a-b2d3-4c26-bdc9-190219141a25
|
|
||||||
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
|
|
||||||
scope: code
|
|
||||||
substantive: true
|
|
||||||
raw_file: 20260610T213549Z_f084e899_prompt_io.raw.md
|
|
||||||
---
|
|
||||||
|
|
||||||
## Prompt
|
|
||||||
|
|
||||||
User bug report from live `ib` testing of the
|
|
||||||
(datad|brokerd)-split branch:
|
|
||||||
|
|
||||||
> ok doing some testing and noticing live orders do not
|
|
||||||
> work otb, pikerd show this on live submission,
|
|
||||||
> [pdb traceback: `RuntimeError("Can not order
|
|
||||||
> {symbol}, no live feed?")` at `ib/api.py:1152`
|
|
||||||
> `submit_limit()` with `self._contracts == {}` in the
|
|
||||||
> `brokerd.ib` actor + a `TrioTaskExited` teardown
|
|
||||||
> cascade]
|
|
||||||
|
|
||||||
Follow-up user direction fixing the design intent:
|
|
||||||
|
|
||||||
> i think the main thing here is that [brokerd] should
|
|
||||||
> be able to always submit orders without a live feed
|
|
||||||
> being up and registered in the same subactor right?
|
|
||||||
|
|
||||||
## Response summary
|
|
||||||
|
|
||||||
Root cause: pre-split the feed code populated the
|
|
||||||
actor-local `Client._contracts` cache (via
|
|
||||||
`get_mkt_info()` writing `mkt.bs_fqme` keys) in the
|
|
||||||
SAME process as order submission; post-split the
|
|
||||||
trading actor's client is never warmed. Fix: lazily
|
|
||||||
qualify + cache the contract per order request in
|
|
||||||
`handle_order_requests()` by running the same
|
|
||||||
`get_mkt_info(fqme, proxy=...)` ep the feed side uses,
|
|
||||||
plus per-order error relay (`BrokerdError`) so one bad
|
|
||||||
submission can't crash the whole trades dialog (the
|
|
||||||
`TrioTaskExited` storm was teardown cascade from the
|
|
||||||
original raise).
|
|
||||||
|
|
||||||
## Files changed
|
|
||||||
|
|
||||||
- `piker/brokers/ib/broker.py` — thread `proxies` into
|
|
||||||
`handle_order_requests()`; lazy contract qualify on
|
|
||||||
cache-miss; guard `submit_limit()` w/ `BrokerdError`
|
|
||||||
relay; uncomment the (anticipatory) `get_mkt_info`
|
|
||||||
import
|
|
||||||
- `piker/brokers/ib/api.py` — fix the non-f-string
|
|
||||||
raise msg + document the new qualification contract
|
|
||||||
|
|
||||||
## Human edits
|
|
||||||
|
|
||||||
None — committed as generated. Live `ib` order retest
|
|
||||||
performed by the human post-commit.
|
|
||||||
|
|
@ -1,57 +0,0 @@
|
||||||
---
|
|
||||||
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).
|
|
||||||
|
|
@ -1,34 +0,0 @@
|
||||||
# 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.
|
|
||||||
|
|
@ -1,64 +0,0 @@
|
||||||
---
|
|
||||||
model: gpt-5.6-sol
|
|
||||||
provider: openai
|
|
||||||
service: opencode
|
|
||||||
session: ses_0799212ebffe42arY96czXn89F
|
|
||||||
timestamp: 2026-07-21T20:52:28Z
|
|
||||||
git_ref: 58ffe487
|
|
||||||
scope: config
|
|
||||||
substantive: true
|
|
||||||
raw_file: 20260721T205228Z_58ffe487_prompt_io.raw.md
|
|
||||||
---
|
|
||||||
|
|
||||||
## Prompt
|
|
||||||
|
|
||||||
The user asked to scan Claude's repo-local skills and
|
|
||||||
documentation, summarize their specializations, and then
|
|
||||||
rework repo-specific skills for use across coding
|
|
||||||
harnesses, particularly OpenCode. The user intends to
|
|
||||||
choose one of Claude's unfinished tasks afterward.
|
|
||||||
|
|
||||||
## Response summary
|
|
||||||
|
|
||||||
Standardized the tracked piker skills on portable Agent
|
|
||||||
Skills frontmatter, made `commit-msg` harness-aware,
|
|
||||||
documented OpenCode discovery and command delegation, and
|
|
||||||
fixed an unsafe `np.searchsorted()` example found during
|
|
||||||
the audit. Preserved the existing `.claude` artifact path
|
|
||||||
as a shared legacy location to avoid breaking established
|
|
||||||
commit workflows.
|
|
||||||
|
|
||||||
## Files changed
|
|
||||||
|
|
||||||
- `.claude/skills/commit-msg/SKILL.md` - portable,
|
|
||||||
harness-aware commit-message workflow
|
|
||||||
- `.claude/skills/commit-msg/style-guide-reference.md` -
|
|
||||||
generic coding-harness attribution
|
|
||||||
- `.claude/skills/piker-conc-expert/SKILL.md` - portable
|
|
||||||
frontmatter
|
|
||||||
- `.claude/skills/piker-profiling/SKILL.md` - portable
|
|
||||||
frontmatter
|
|
||||||
- `.claude/skills/piker-slang/SKILL.md` - portable
|
|
||||||
frontmatter
|
|
||||||
- `.claude/skills/pyqtgraph-optimization/SKILL.md` -
|
|
||||||
portable frontmatter
|
|
||||||
- `.claude/skills/timeseries-optimization/SKILL.md` -
|
|
||||||
portable frontmatter and safe search bounds handling
|
|
||||||
- `ai/README.md` - shared-skill integration model
|
|
||||||
- `ai/claude-code/README.md` - cross-harness Claude Code
|
|
||||||
documentation
|
|
||||||
- `ai/opencode/README.md` - OpenCode usage and discovery
|
|
||||||
documentation
|
|
||||||
- `.opencode/commands/commit-msg.md` - thin OpenCode
|
|
||||||
command delegating to the shared skill
|
|
||||||
- `ai/prompt-io/opencode/README.md` - OpenCode provenance
|
|
||||||
policy
|
|
||||||
- `ai/prompt-io/opencode/20260721T205228Z_58ffe487_prompt_io.raw.md`
|
|
||||||
- unedited response record
|
|
||||||
- `ai/prompt-io/opencode/20260721T205228Z_58ffe487_prompt_io.md`
|
|
||||||
- provenance metadata and summary
|
|
||||||
|
|
||||||
## Human edits
|
|
||||||
|
|
||||||
None - generated changes have not yet been reviewed or
|
|
||||||
edited by the human.
|
|
||||||
|
|
@ -1,33 +0,0 @@
|
||||||
---
|
|
||||||
model: gpt-5.6-sol
|
|
||||||
provider: openai
|
|
||||||
service: opencode
|
|
||||||
timestamp: 2026-07-21T20:52:28Z
|
|
||||||
git_ref: 58ffe487
|
|
||||||
diff_cmd: git diff HEAD~1..HEAD
|
|
||||||
---
|
|
||||||
|
|
||||||
The repo-local skill inventory contains seven domains:
|
|
||||||
commit-message generation, actor-runtime concurrency,
|
|
||||||
distributed profiling, project communication style,
|
|
||||||
Python source style, PyQtGraph rendering, and NumPy/Polars
|
|
||||||
timeseries optimization.
|
|
||||||
|
|
||||||
I converted the six tracked repo-specific skills to the
|
|
||||||
portable Agent Skills frontmatter subset so Claude Code
|
|
||||||
and OpenCode can load the same source files. The
|
|
||||||
commit-message workflow now gathers live git context at
|
|
||||||
execution time, uses runtime harness/model attribution,
|
|
||||||
preserves human-owned task state, and keeps the existing
|
|
||||||
message artifact paths for compatibility.
|
|
||||||
|
|
||||||
I added OpenCode integration documentation and updated
|
|
||||||
the shared and Claude Code docs to describe a single
|
|
||||||
cross-harness skill source with thin harness commands.
|
|
||||||
During validation I also corrected an out-of-bounds
|
|
||||||
`np.searchsorted()` example in the timeseries skill.
|
|
||||||
|
|
||||||
The unfinished artifacts found during the scan are a
|
|
||||||
shared-memory migration plan and a gap-annotation
|
|
||||||
performance handoff. The earlier datad split plan appears
|
|
||||||
implemented and is now captured by the concurrency skill.
|
|
||||||
|
|
@ -1,41 +0,0 @@
|
||||||
---
|
|
||||||
model: gpt-5.6-sol
|
|
||||||
provider: openai
|
|
||||||
service: opencode
|
|
||||||
session: ses_0799212ebffe42arY96czXn89F
|
|
||||||
timestamp: 2026-07-21T21:50:55Z
|
|
||||||
git_ref: c6ec3d41
|
|
||||||
scope: docs
|
|
||||||
substantive: true
|
|
||||||
raw_file: 20260721T215055Z_c6ec3d41_prompt_io.raw.md
|
|
||||||
---
|
|
||||||
|
|
||||||
## Prompt
|
|
||||||
|
|
||||||
The user asked to boot a plan to continue work on the
|
|
||||||
time-series gap checker and bug fixing of the history
|
|
||||||
backfiller. The user authorized prompt-I/O capture for the
|
|
||||||
plan documentation after the repository audit.
|
|
||||||
|
|
||||||
## Response summary
|
|
||||||
|
|
||||||
Produced a bounded repair plan based on current source,
|
|
||||||
historical issue caches, existing profiling notes, and a
|
|
||||||
test-coverage audit. The plan prioritizes reproducible
|
|
||||||
correctness failures and storage durability before venue
|
|
||||||
classification, annotation performance, or manual repair
|
|
||||||
UX.
|
|
||||||
|
|
||||||
## Files changed
|
|
||||||
|
|
||||||
- `plans/opencode/gap-checker-backfiller-repair.md` -
|
|
||||||
phased implementation and verification plan
|
|
||||||
- `ai/prompt-io/opencode/20260721T215055Z_c6ec3d41_prompt_io.raw.md`
|
|
||||||
- unedited response record
|
|
||||||
- `ai/prompt-io/opencode/20260721T215055Z_c6ec3d41_prompt_io.md`
|
|
||||||
- provenance metadata and response summary
|
|
||||||
|
|
||||||
## Human edits
|
|
||||||
|
|
||||||
None - generated plan has not yet been edited by the
|
|
||||||
human.
|
|
||||||
|
|
@ -1,26 +0,0 @@
|
||||||
---
|
|
||||||
model: gpt-5.6-sol
|
|
||||||
provider: openai
|
|
||||||
service: opencode
|
|
||||||
timestamp: 2026-07-21T21:50:55Z
|
|
||||||
git_ref: c6ec3d41
|
|
||||||
diff_cmd: git diff HEAD~1..HEAD
|
|
||||||
---
|
|
||||||
|
|
||||||
> `git diff -- plans/opencode/gap-checker-backfiller-repair.md`
|
|
||||||
|
|
||||||
Generated a phased implementation plan for continuing
|
|
||||||
piker's gap checker and history backfiller repairs. The
|
|
||||||
plan separates data correctness from annotation
|
|
||||||
performance and orders work by dependency: deterministic
|
|
||||||
tests, canonical frame/gap normalization, structured
|
|
||||||
backfill completion, non-destructive atomic NativeDB
|
|
||||||
writes, exact null repair, provider/venue classification,
|
|
||||||
annotation vectorization, and crash qualification.
|
|
||||||
|
|
||||||
The plan is grounded in current code paths, local issue
|
|
||||||
caches `#62`, `#71`, and `#75`, and the existing 1,285-gap
|
|
||||||
profiling handoff. It records confirmed present defects,
|
|
||||||
design invariants, per-phase acceptance gates, test
|
|
||||||
commands, commit boundaries, and explicitly deferred UX
|
|
||||||
and provider work.
|
|
||||||
|
|
@ -1,46 +0,0 @@
|
||||||
---
|
|
||||||
model: gpt-5.6-sol
|
|
||||||
provider: openai
|
|
||||||
service: opencode
|
|
||||||
session: ses_0799212ebffe42arY96czXn89F
|
|
||||||
timestamp: 2026-07-22T00:13:57Z
|
|
||||||
git_ref: 16f3cd6f
|
|
||||||
scope: code
|
|
||||||
substantive: true
|
|
||||||
raw_file: 20260722T001357Z_16f3cd6f_prompt_io.raw.md
|
|
||||||
---
|
|
||||||
|
|
||||||
## Prompt
|
|
||||||
|
|
||||||
Continue the gap-checker and history-backfiller repair plan. Start
|
|
||||||
with deterministic analysis characterization, then fix canonical
|
|
||||||
sorting, dedupe-derived columns, positive gap detection, and null
|
|
||||||
grouping.
|
|
||||||
|
|
||||||
During review, the user challenged the replacement null-grouping
|
|
||||||
algorithm because its initial tests did not assert exact endpoints.
|
|
||||||
The user explicitly required retaining detailed, human-oriented
|
|
||||||
algorithm documentation such as the existing ASCII segment map.
|
|
||||||
|
|
||||||
## Response summary
|
|
||||||
|
|
||||||
Added deterministic analysis regressions and corrected normalization
|
|
||||||
so sorting and duplicate resolution precede derived-column
|
|
||||||
calculation. Unified null grouping for NumPy and Polars inputs,
|
|
||||||
documented its exact inclusive-boundary contract with an adapted
|
|
||||||
visual map, and verified all small null layouts against an independent
|
|
||||||
state-machine oracle. Retained sorted smart-dedupe output.
|
|
||||||
|
|
||||||
## Files changed
|
|
||||||
|
|
||||||
- `piker/tsp/_anal.py` - canonical gap and documented null grouping
|
|
||||||
- `piker/tsp/_dedupe_smart.py` - sorted duplicate resolution
|
|
||||||
- `tests/test_tsp_analysis.py` - exact and exhaustive regressions
|
|
||||||
- `ai/prompt-io/opencode/20260722T001357Z_16f3cd6f_prompt_io.raw.md`
|
|
||||||
- unedited response record
|
|
||||||
- `ai/prompt-io/opencode/20260722T001357Z_16f3cd6f_prompt_io.md`
|
|
||||||
- provenance metadata and response summary
|
|
||||||
|
|
||||||
## Human edits
|
|
||||||
|
|
||||||
None - generated changes have not yet been edited by the human.
|
|
||||||
|
|
@ -1,40 +0,0 @@
|
||||||
---
|
|
||||||
model: gpt-5.6-sol
|
|
||||||
provider: openai
|
|
||||||
service: opencode
|
|
||||||
timestamp: 2026-07-22T00:13:57Z
|
|
||||||
git_ref: 16f3cd6f
|
|
||||||
diff_cmd: git diff HEAD~1..HEAD
|
|
||||||
---
|
|
||||||
|
|
||||||
> `git diff HEAD~1..HEAD -- piker/tsp/_anal.py`
|
|
||||||
|
|
||||||
Generated canonical gap and null-segment normalization. Derived
|
|
||||||
datetime and delta columns are recomputed after final sorting and
|
|
||||||
duplicate resolution, and negative deltas no longer become ordinary
|
|
||||||
gaps.
|
|
||||||
|
|
||||||
NumPy and Polars null grouping share one implementation while
|
|
||||||
retaining the human-oriented visual map of contiguous zero runs. The
|
|
||||||
documented contract defines absolute inclusive endpoints, margin
|
|
||||||
expansion, frame boundary clamping, contiguous-index validation, and
|
|
||||||
requested-column selection.
|
|
||||||
|
|
||||||
> `git diff HEAD~1..HEAD -- piker/tsp/_dedupe_smart.py`
|
|
||||||
|
|
||||||
Adjusted smart dedupe to honor sorted output and resolve duplicate
|
|
||||||
timestamps without retaining stale order.
|
|
||||||
|
|
||||||
> `git diff HEAD~1..HEAD -- tests/test_tsp_analysis.py`
|
|
||||||
|
|
||||||
Added deterministic synthetic OHLCV coverage for sorted dedupe, fresh
|
|
||||||
derived columns, and positive gap detection. Null grouping is checked
|
|
||||||
against readable endpoint examples and an independent state-machine
|
|
||||||
oracle over every layout through six rows, three margin widths, and
|
|
||||||
both NumPy and Polars inputs.
|
|
||||||
|
|
||||||
Verification generated with the patch:
|
|
||||||
|
|
||||||
`timeout -k 5 30 python -m pytest -q tests/test_tsp_analysis.py`
|
|
||||||
|
|
||||||
Result: 11 passed.
|
|
||||||
|
|
@ -1,36 +0,0 @@
|
||||||
---
|
|
||||||
model: gpt-5.6-sol
|
|
||||||
provider: openai
|
|
||||||
service: opencode
|
|
||||||
session: ses_0799212ebffe42arY96czXn89F
|
|
||||||
timestamp: 2026-07-22T00:13:58Z
|
|
||||||
git_ref: 16f3cd6f
|
|
||||||
scope: code
|
|
||||||
substantive: true
|
|
||||||
raw_file: 20260722T001358Z_16f3cd6f_prompt_io.raw.md
|
|
||||||
---
|
|
||||||
|
|
||||||
## Prompt
|
|
||||||
|
|
||||||
Continue the structured backfill phase after the analysis regressions.
|
|
||||||
Characterize provider exhaustion and genuinely empty frames, then remove
|
|
||||||
completion paths that can hang after child-task exit.
|
|
||||||
|
|
||||||
## Response summary
|
|
||||||
|
|
||||||
Removed orphan-prone completion events from the structured nursery flow
|
|
||||||
and checked empty provider frames before indexing timestamp endpoints.
|
|
||||||
Added deterministic timeout-bounded regressions for both exit paths.
|
|
||||||
|
|
||||||
## Files changed
|
|
||||||
|
|
||||||
- `piker/tsp/_history.py` - structured completion and empty-frame fixes
|
|
||||||
- `tests/test_history_backfill.py` - deterministic exit regressions
|
|
||||||
- `ai/prompt-io/opencode/20260722T001358Z_16f3cd6f_prompt_io.raw.md`
|
|
||||||
- unedited response record
|
|
||||||
- `ai/prompt-io/opencode/20260722T001358Z_16f3cd6f_prompt_io.md`
|
|
||||||
- provenance metadata and response summary
|
|
||||||
|
|
||||||
## Human edits
|
|
||||||
|
|
||||||
None - generated changes have not yet been edited by the human.
|
|
||||||
|
|
@ -1,25 +0,0 @@
|
||||||
---
|
|
||||||
model: gpt-5.6-sol
|
|
||||||
provider: openai
|
|
||||||
service: opencode
|
|
||||||
timestamp: 2026-07-22T00:13:58Z
|
|
||||||
git_ref: 16f3cd6f
|
|
||||||
diff_cmd: git diff HEAD~1..HEAD
|
|
||||||
---
|
|
||||||
|
|
||||||
> `git diff HEAD~1..HEAD -- piker/tsp/_history.py`
|
|
||||||
|
|
||||||
Removed redundant completion events whose consumers waited only after
|
|
||||||
their owning nurseries had joined. Added empty provider-frame handling
|
|
||||||
before timestamp endpoint indexing so provider exhaustion exits cleanly.
|
|
||||||
|
|
||||||
> `git diff HEAD~1..HEAD -- tests/test_history_backfill.py`
|
|
||||||
|
|
||||||
Added bounded, actor-free regressions for `DataUnavailable` and empty
|
|
||||||
provider-frame completion.
|
|
||||||
|
|
||||||
Verification generated with the patch:
|
|
||||||
|
|
||||||
`timeout -k 5 60 python -m pytest -q tests/test_history_backfill.py`
|
|
||||||
|
|
||||||
Result: 2 passed.
|
|
||||||
|
|
@ -1,39 +0,0 @@
|
||||||
---
|
|
||||||
model: gpt-5.6-sol
|
|
||||||
provider: openai
|
|
||||||
service: opencode
|
|
||||||
session: ses_0799212ebffe42arY96czXn89F
|
|
||||||
timestamp: 2026-07-22T02:41:33Z
|
|
||||||
git_ref: 3a4f6737
|
|
||||||
scope: code
|
|
||||||
substantive: true
|
|
||||||
raw_file: 20260722T024133Z_3a4f6737_prompt_io.raw.md
|
|
||||||
---
|
|
||||||
|
|
||||||
## Prompt
|
|
||||||
|
|
||||||
The user challenged the analysis commit message's claim that only
|
|
||||||
positive sample-step gaps are detected and asked whether out-of-order
|
|
||||||
timestamps were simply ignored. After confirming the missing separate
|
|
||||||
reporting path, the user instructed the agent to implement the fix.
|
|
||||||
|
|
||||||
## Response summary
|
|
||||||
|
|
||||||
Separated missing-history gaps from timestamp-ordering errors without
|
|
||||||
changing the existing `dedupe()` return shape. Added a structured
|
|
||||||
detector and made normalization warn before sorting removes evidence of
|
|
||||||
duplicates or reversed timestamps.
|
|
||||||
|
|
||||||
## Files changed
|
|
||||||
|
|
||||||
- `piker/tsp/_anal.py` - ordering detector and dedupe reporting
|
|
||||||
- `piker/tsp/__init__.py` - public detector export
|
|
||||||
- `tests/test_tsp_analysis.py` - exact ordering-error regression
|
|
||||||
- `ai/prompt-io/opencode/20260722T024133Z_3a4f6737_prompt_io.raw.md`
|
|
||||||
- unedited response record
|
|
||||||
- `ai/prompt-io/opencode/20260722T024133Z_3a4f6737_prompt_io.md`
|
|
||||||
- provenance metadata and response summary
|
|
||||||
|
|
||||||
## Human edits
|
|
||||||
|
|
||||||
None - generated changes have not yet been edited by the human.
|
|
||||||
|
|
@ -1,30 +0,0 @@
|
||||||
---
|
|
||||||
model: gpt-5.6-sol
|
|
||||||
provider: openai
|
|
||||||
service: opencode
|
|
||||||
timestamp: 2026-07-22T02:41:33Z
|
|
||||||
git_ref: 3a4f6737
|
|
||||||
diff_cmd: git diff HEAD~1..HEAD
|
|
||||||
---
|
|
||||||
|
|
||||||
> `git diff HEAD~1..HEAD -- piker/tsp/_anal.py`
|
|
||||||
|
|
||||||
Added `detect_time_ordering_errors()` to return non-positive timestamp
|
|
||||||
steps as structured rows. `dedupe()` now warns with those rows before
|
|
||||||
sorting and duplicate removal erase the original ordering evidence.
|
|
||||||
|
|
||||||
> `git diff HEAD~1..HEAD -- piker/tsp/__init__.py`
|
|
||||||
|
|
||||||
Exported the ordering detector through the public TSP package.
|
|
||||||
|
|
||||||
> `git diff HEAD~1..HEAD -- tests/test_tsp_analysis.py`
|
|
||||||
|
|
||||||
Changed the negative-delta regression to verify exact predecessor,
|
|
||||||
timestamp, and delta values, confirm exclusion from missing-history
|
|
||||||
gaps, and require explicit normalization reporting.
|
|
||||||
|
|
||||||
Verification generated with the patch:
|
|
||||||
|
|
||||||
- `tests/test_tsp_analysis.py`: 11 passed
|
|
||||||
- Ruff: passed
|
|
||||||
- `git diff --check`: passed
|
|
||||||
|
|
@ -1,43 +0,0 @@
|
||||||
---
|
|
||||||
model: gpt-5.6-sol
|
|
||||||
provider: openai
|
|
||||||
service: opencode
|
|
||||||
session: ses_0799212ebffe42arY96czXn89F
|
|
||||||
timestamp: 2026-07-22T02:41:34Z
|
|
||||||
git_ref: 3a4f6737
|
|
||||||
scope: code
|
|
||||||
substantive: true
|
|
||||||
raw_file: 20260722T024134Z_3a4f6737_prompt_io.raw.md
|
|
||||||
---
|
|
||||||
|
|
||||||
## Prompt
|
|
||||||
|
|
||||||
The user asked why the in-progress `piker/storage` changes were omitted
|
|
||||||
from the earlier commit plan. After receiving an inventory of unfinished
|
|
||||||
Phase 3 requirements, the user instructed the agent to complete the work.
|
|
||||||
|
|
||||||
## Response summary
|
|
||||||
|
|
||||||
Finished non-destructive, atomic NativeDB updates and integrated them
|
|
||||||
with history startup and reverse backfill. Expanded tests through two
|
|
||||||
adversarial review rounds that caught and corrected cross-client lock
|
|
||||||
blocking, stale temp indexing, discontinuous persisted indexes, startup
|
|
||||||
snapshot races, missing latest-frame persistence, notification wedges,
|
|
||||||
and mutable/truncated SHM persistence.
|
|
||||||
|
|
||||||
## Files changed
|
|
||||||
|
|
||||||
- `piker/storage/__init__.py` - incremental storage contract
|
|
||||||
- `piker/storage/nativedb.py` - validated atomic merge persistence
|
|
||||||
- `piker/storage/marketstore/__init__.py` - non-duplicate update mode
|
|
||||||
- `piker/tsp/_history.py` - provider-delta and startup persistence
|
|
||||||
- `tests/test_storage_nativedb.py` - NativeDB durability regressions
|
|
||||||
- `tests/test_history_backfill.py` - persistence lifecycle regressions
|
|
||||||
- `ai/prompt-io/opencode/20260722T024134Z_3a4f6737_prompt_io.raw.md`
|
|
||||||
- unedited response record
|
|
||||||
- `ai/prompt-io/opencode/20260722T024134Z_3a4f6737_prompt_io.md`
|
|
||||||
- provenance metadata and response summary
|
|
||||||
|
|
||||||
## Human edits
|
|
||||||
|
|
||||||
None - generated changes have not yet been edited by the human.
|
|
||||||
|
|
@ -1,43 +0,0 @@
|
||||||
---
|
|
||||||
model: gpt-5.6-sol
|
|
||||||
provider: openai
|
|
||||||
service: opencode
|
|
||||||
timestamp: 2026-07-22T02:41:34Z
|
|
||||||
git_ref: 3a4f6737
|
|
||||||
diff_cmd: git diff HEAD~1..HEAD
|
|
||||||
---
|
|
||||||
|
|
||||||
> `git diff HEAD~1..HEAD -- piker/storage/__init__.py piker/storage/nativedb.py piker/storage/marketstore/__init__.py`
|
|
||||||
|
|
||||||
Added an incremental storage update contract. NativeDB now validates
|
|
||||||
canonical numeric OHLCV data, serializes writers both actor-locally and
|
|
||||||
through cancellable filesystem locks, merges with incoming-wins seam
|
|
||||||
resolution, regenerates contiguous indexes, reopens and validates a
|
|
||||||
same-directory temporary parquet, fsyncs it, atomically replaces the
|
|
||||||
target, fsyncs the directory, and publishes cache only after replacement.
|
|
||||||
|
|
||||||
NativeDB indexing ignores lock and crash-left temporary files.
|
|
||||||
MarketStore uses its non-duplicate write mode for incremental updates.
|
|
||||||
|
|
||||||
> `git diff HEAD~1..HEAD -- piker/tsp/_history.py`
|
|
||||||
|
|
||||||
Separated full provider deltas from capacity-truncated SHM pushes.
|
|
||||||
Backfill persists before SHM mutation, publishes bounded notifications,
|
|
||||||
and delays latest-frame publication until the concurrent pre-update
|
|
||||||
storage snapshot completes.
|
|
||||||
|
|
||||||
> `git diff HEAD~1..HEAD -- tests/test_storage_nativedb.py tests/test_history_backfill.py`
|
|
||||||
|
|
||||||
Added deterministic coverage for merge preservation, conflict policy,
|
|
||||||
atomic failures, reopened-candidate validation, cache consistency,
|
|
||||||
schema and timestamp invariants, contiguous index regeneration,
|
|
||||||
separate series, stale temp indexing, cancellable file-lock contention,
|
|
||||||
full provider-delta persistence, latest-frame ordering, and bounded
|
|
||||||
notification teardown.
|
|
||||||
|
|
||||||
Verification generated with the patch:
|
|
||||||
|
|
||||||
- deterministic analysis/backfill/storage set: 31 passed
|
|
||||||
- Ruff: passed
|
|
||||||
- `git diff --check`: passed
|
|
||||||
- final adversarial review: no findings
|
|
||||||
|
|
@ -1,32 +0,0 @@
|
||||||
---
|
|
||||||
model: openai/gpt-5.6-sol
|
|
||||||
service: opencode
|
|
||||||
session: ses_092a25886ffeT0nrIrdkMEcgJK
|
|
||||||
timestamp: 2026-07-24T22:01:56Z
|
|
||||||
git_ref: flake_update
|
|
||||||
scope: config
|
|
||||||
substantive: true
|
|
||||||
raw_file: 20260724T220156Z_43d7a3ed_prompt_io.raw.md
|
|
||||||
---
|
|
||||||
|
|
||||||
## Prompt
|
|
||||||
|
|
||||||
After committing Piker's provider-neutral deployment, the user asked to
|
|
||||||
extract Piker-specialized `/run-tests` content from the historical
|
|
||||||
`wkt/run_tests_skill` implementation into the new deployment.
|
|
||||||
|
|
||||||
## Response summary
|
|
||||||
|
|
||||||
Create a repository-owned `test-harness-reference.md` for the canonical Run
|
|
||||||
base. Revalidate historical commands and assumptions against current pytest,
|
|
||||||
uv/Nix environments, tests, fixtures, and Tractor runtime behavior, retaining
|
|
||||||
only current Piker-specific guidance.
|
|
||||||
|
|
||||||
## Files changed
|
|
||||||
|
|
||||||
- `.claude/skills/run-tests/test-harness-reference.md` - define Piker's safe
|
|
||||||
commands, opt-in boundaries, mappings, known outcomes, and runtime notes.
|
|
||||||
|
|
||||||
## Human edits
|
|
||||||
|
|
||||||
None at generation time; pending human review.
|
|
||||||
|
|
@ -1,32 +0,0 @@
|
||||||
---
|
|
||||||
model: openai/gpt-5.6-sol
|
|
||||||
service: opencode
|
|
||||||
timestamp: 2026-07-24T22:01:56Z
|
|
||||||
git_ref: flake_update
|
|
||||||
diff_cmd: git diff HEAD~1..HEAD
|
|
||||||
---
|
|
||||||
|
|
||||||
The user asked to extract useful Piker-specific `/run-tests` behavior from
|
|
||||||
`wkt/run_tests_skill` after committing the provider-neutral deployment.
|
|
||||||
|
|
||||||
> `git diff HEAD~1..HEAD -- .claude/skills/run-tests/test-harness-reference.md`
|
|
||||||
|
|
||||||
Generate a repository-owned harness reference rather than restoring the old
|
|
||||||
standalone `SKILL.md`. Preserve verified Piker-specific environment, command,
|
|
||||||
scope, fixture, test-layout, change-mapping, known-outcome, and Tractor-runtime
|
|
||||||
details while leaving shared execution and cleanup policy in the canonical
|
|
||||||
`ai.skillz` base.
|
|
||||||
|
|
||||||
Repository inspection found that the historical skill needs correction:
|
|
||||||
|
|
||||||
- the comments-only `pytest.ini` shadows `pyproject.toml` pytest options, so
|
|
||||||
`-p no:xonsh` must be explicit;
|
|
||||||
- no marker-based offline suite exists, and several live/GUI/container tests
|
|
||||||
are unsafe defaults;
|
|
||||||
- skipped Docker and Questrade modules can fail during import before marks;
|
|
||||||
- actor timeout retry remains relevant only for the exact timed-out command;
|
|
||||||
- `py313` and frozen no-sync `uv run` are the current local environment paths.
|
|
||||||
|
|
||||||
Validate with checkout import resolution, safe collection, and deterministic
|
|
||||||
watchlist/accounting tests. Do not run live broker, GUI, container,
|
|
||||||
credentialed, or user-config-dependent cases during harness verification.
|
|
||||||
|
|
@ -1,40 +0,0 @@
|
||||||
---
|
|
||||||
model: gpt-5.6-sol
|
|
||||||
provider: openai
|
|
||||||
service: opencode
|
|
||||||
session: unavailable
|
|
||||||
timestamp: 2026-07-27T20:47:11Z
|
|
||||||
git_ref: 84a6d47b
|
|
||||||
scope: code
|
|
||||||
substantive: true
|
|
||||||
raw_file: 20260727T204711Z_84a6d47b_prompt_io.raw.md
|
|
||||||
---
|
|
||||||
|
|
||||||
## Prompt
|
|
||||||
|
|
||||||
The user identified that `backfiller_deep_fixes` introduced persistent
|
|
||||||
`.parquet.lock` files, questioned whether Parquet or Arrow already handled
|
|
||||||
writer coordination, and clarified that piker's `tractor` structured
|
|
||||||
concurrency design already provides single-writer ownership through the
|
|
||||||
persistent `datad` feed task. The user then asked to open the backfiller
|
|
||||||
worktree and resolve the redundant locking.
|
|
||||||
|
|
||||||
## Response summary
|
|
||||||
|
|
||||||
Removed redundant actor-local and filesystem locking while preserving
|
|
||||||
atomic crash-safe Parquet replacement. Replaced the synthetic contention
|
|
||||||
test with regressions for the actual cross-branch failure: writes create
|
|
||||||
no lock sidecars, and legacy lock artifacts are ignored during indexing.
|
|
||||||
|
|
||||||
## Files changed
|
|
||||||
|
|
||||||
- `piker/storage/nativedb.py` - rely on `datad` writer ownership
|
|
||||||
- `tests/test_storage_nativedb.py` - lock-sidecar regressions
|
|
||||||
- `ai/prompt-io/opencode/20260727T204711Z_84a6d47b_prompt_io.raw.md`
|
|
||||||
- unedited response record
|
|
||||||
- `ai/prompt-io/opencode/20260727T204711Z_84a6d47b_prompt_io.md`
|
|
||||||
- provenance metadata and response summary
|
|
||||||
|
|
||||||
## Human edits
|
|
||||||
|
|
||||||
None - generated changes have not been edited by the human.
|
|
||||||
|
|
@ -1,30 +0,0 @@
|
||||||
---
|
|
||||||
model: gpt-5.6-sol
|
|
||||||
provider: openai
|
|
||||||
service: opencode
|
|
||||||
timestamp: 2026-07-27T20:47:11Z
|
|
||||||
git_ref: 84a6d47b
|
|
||||||
diff_cmd: git diff HEAD~1..HEAD
|
|
||||||
---
|
|
||||||
|
|
||||||
> `git diff HEAD~1..HEAD -- piker/storage/nativedb.py`
|
|
||||||
|
|
||||||
Removed actor-local and filesystem writer locks from NativeDB. The
|
|
||||||
persistent `datad` feed task already owns writes for each series, while
|
|
||||||
its timeframe children write distinct files. NativeDB retains validated
|
|
||||||
temporary writes, file and directory synchronization, and atomic target
|
|
||||||
replacement for crash durability. The exact `.parquet` suffix filter is
|
|
||||||
retained so legacy lock sidecars are harmless.
|
|
||||||
|
|
||||||
> `git diff HEAD~1..HEAD -- tests/test_storage_nativedb.py`
|
|
||||||
|
|
||||||
Removed the synthetic cross-client lock-contention test. Added regression
|
|
||||||
coverage proving replacement and incremental writes create no lock
|
|
||||||
sidecars. Extended indexing coverage with the legacy
|
|
||||||
`.parquet.lock` artifact that caused upstream `flake_update` to crash.
|
|
||||||
|
|
||||||
Verification generated with the patch:
|
|
||||||
|
|
||||||
- NativeDB and history regression set: 20 passed
|
|
||||||
- Ruff: passed
|
|
||||||
- `git diff --check`: passed
|
|
||||||
|
|
@ -1,42 +0,0 @@
|
||||||
---
|
|
||||||
model: gpt-5.6-sol
|
|
||||||
provider: openai
|
|
||||||
service: opencode
|
|
||||||
session: ses_0799212ebffe42arY96czXn89F
|
|
||||||
timestamp: 2026-07-27T21:24:54Z
|
|
||||||
git_ref: 689df816
|
|
||||||
scope: code
|
|
||||||
substantive: true
|
|
||||||
raw_file: 20260727T212454Z_689df816_prompt_io.raw.md
|
|
||||||
---
|
|
||||||
|
|
||||||
## Prompt
|
|
||||||
|
|
||||||
The user reran the known IB FQME on `backfiller_deep_fixes` and reported
|
|
||||||
that `publish_latest_frame()` still failed because NativeDB required an
|
|
||||||
`index` absent from IB's provider frame. The user called out the missed
|
|
||||||
tabular schema boundary and requested an actual end-to-end test suite
|
|
||||||
rather than storage fakes.
|
|
||||||
|
|
||||||
## Response summary
|
|
||||||
|
|
||||||
Repaired the IB-provider-to-NativeDB boundary by canonicalizing durable
|
|
||||||
fields and mapping reloads into provider-specific SHM buffers. Added a
|
|
||||||
local actor/SHM/Parquet integration regression covering first startup and
|
|
||||||
restart, plus focused conversion and timestamp-coercion tests. Two review
|
|
||||||
rounds found and resolved restart hydration and fractional-time hazards.
|
|
||||||
|
|
||||||
## Files changed
|
|
||||||
|
|
||||||
- `piker/storage/nativedb.py` - canonical storage and SHM field mapping
|
|
||||||
- `piker/tsp/_anal.py` - name-based Polars-to-NumPy conversion
|
|
||||||
- `tests/test_history_backfill.py` - actor/SHM/Parquet integration test
|
|
||||||
- `tests/test_storage_nativedb.py` - schema conversion regressions
|
|
||||||
- `ai/prompt-io/opencode/20260727T212454Z_689df816_prompt_io.raw.md`
|
|
||||||
- unedited response record
|
|
||||||
- `ai/prompt-io/opencode/20260727T212454Z_689df816_prompt_io.md`
|
|
||||||
- provenance metadata and response summary
|
|
||||||
|
|
||||||
## Human edits
|
|
||||||
|
|
||||||
None - generated changes have not been edited by the human.
|
|
||||||
|
|
@ -1,34 +0,0 @@
|
||||||
---
|
|
||||||
model: gpt-5.6-sol
|
|
||||||
provider: openai
|
|
||||||
service: opencode
|
|
||||||
timestamp: 2026-07-27T21:24:54Z
|
|
||||||
git_ref: 689df816
|
|
||||||
diff_cmd: git diff HEAD~1..HEAD
|
|
||||||
---
|
|
||||||
|
|
||||||
> `git diff HEAD~1..HEAD -- piker/storage/nativedb.py piker/tsp/_anal.py`
|
|
||||||
|
|
||||||
Normalized index-less provider frames to NativeDB's canonical names,
|
|
||||||
order, and dtypes before merge and publication. Provider-only columns
|
|
||||||
are excluded from durable files, derived indexes are regenerated, and
|
|
||||||
fractional timestamps are rejected before integer conversion. Added a
|
|
||||||
canonical field map for hydrating provider-specific SHM buffers while
|
|
||||||
leaving provider-only fields at their defaults. Changed Polars-to-NumPy
|
|
||||||
conversion to select columns by field name rather than position.
|
|
||||||
|
|
||||||
> `git diff HEAD~1..HEAD -- tests/test_history_backfill.py tests/test_storage_nativedb.py`
|
|
||||||
|
|
||||||
Added deterministic coverage using IB's actual provider dtype and a real
|
|
||||||
local `tractor` root actor, IB-typed shared-memory buffers, NativeDB,
|
|
||||||
Parquet persistence, first-start publication, and restart hydration.
|
|
||||||
Added focused regressions for reordered/extra Polars columns and
|
|
||||||
fractional timestamp rejection.
|
|
||||||
|
|
||||||
Verification generated with the patch:
|
|
||||||
|
|
||||||
- NativeDB and history integration set: 23 passed
|
|
||||||
- Ruff: passed
|
|
||||||
- `git diff --check`: passed
|
|
||||||
- second adversarial review: no findings
|
|
||||||
- no live gateway or network tests run
|
|
||||||
|
|
@ -1,41 +0,0 @@
|
||||||
---
|
|
||||||
model: gpt-5.6-sol
|
|
||||||
provider: openai
|
|
||||||
service: opencode
|
|
||||||
session: ses_0799212ebffe42arY96czXn89F
|
|
||||||
timestamp: 2026-07-27T21:59:06Z
|
|
||||||
git_ref: 689df816
|
|
||||||
scope: code
|
|
||||||
substantive: true
|
|
||||||
raw_file: 20260727T215906Z_689df816_prompt_io.raw.md
|
|
||||||
---
|
|
||||||
|
|
||||||
## Prompt
|
|
||||||
|
|
||||||
After the actor/SHM/Parquet integration test exposed a stale SHM triplet,
|
|
||||||
the user requested leak-cleaner machinery in the pytest harness using
|
|
||||||
Tractor's existing ownership and lifetime patterns.
|
|
||||||
|
|
||||||
## Response summary
|
|
||||||
|
|
||||||
Added creator-scoped SHM leak tracking to pytest without scanning
|
|
||||||
`/dev/shm` or treating attachments as owned. The fixture cooperates with
|
|
||||||
normal Tractor teardown, verifies POSIX object identity before fallback
|
|
||||||
cleanup, restores process-local token state, and fails after cleaning a
|
|
||||||
leak. Regressions cover the exact pre-actor-registration allocation window,
|
|
||||||
positional creators, and external attachment safety.
|
|
||||||
|
|
||||||
## Files changed
|
|
||||||
|
|
||||||
- `tests/conftest.py` - creator-scoped SHM leak tracking fixture
|
|
||||||
- `tests/test_shm_cleanup.py` - ownership and failure-window regressions
|
|
||||||
- `.claude/skills/run-tests/test-harness-reference.md`
|
|
||||||
- document current-process SHM cleanup behavior
|
|
||||||
- `ai/prompt-io/opencode/20260727T215906Z_689df816_prompt_io.raw.md`
|
|
||||||
- unedited response record
|
|
||||||
- `ai/prompt-io/opencode/20260727T215906Z_689df816_prompt_io.md`
|
|
||||||
- provenance metadata and response summary
|
|
||||||
|
|
||||||
## Human edits
|
|
||||||
|
|
||||||
None - generated changes have not been edited by the human.
|
|
||||||
|
|
@ -1,25 +0,0 @@
|
||||||
---
|
|
||||||
model: gpt-5.6-sol
|
|
||||||
provider: openai
|
|
||||||
service: opencode
|
|
||||||
timestamp: 2026-07-27T21:59:06Z
|
|
||||||
git_ref: 689df816
|
|
||||||
diff_cmd: git diff HEAD~1..HEAD
|
|
||||||
---
|
|
||||||
|
|
||||||
> `git diff HEAD~1..HEAD -- tests/conftest.py tests/test_shm_cleanup.py .claude/skills/run-tests/test-harness-reference.md`
|
|
||||||
|
|
||||||
Added function-scoped SHM ownership tracking around Tractor's test-process
|
|
||||||
factory. The fixture records only successful creators, removes ownership
|
|
||||||
records during normal Tractor teardown, verifies POSIX object identity
|
|
||||||
before fallback unlink, restores the token-cache baseline, and fails after
|
|
||||||
cleaning any leak. Regressions reproduce allocation failure before actor
|
|
||||||
lifetime registration and prove external attachments remain untouched.
|
|
||||||
|
|
||||||
Verification generated with the patch:
|
|
||||||
|
|
||||||
- SHM cleanup regressions: 2 passed
|
|
||||||
- combined SHM, NativeDB, and history set: 25 passed
|
|
||||||
- Ruff: passed
|
|
||||||
- `git diff --check`: passed
|
|
||||||
- final adversarial review: no findings
|
|
||||||
|
|
@ -1,42 +0,0 @@
|
||||||
---
|
|
||||||
model: gpt-5.6-sol
|
|
||||||
provider: openai
|
|
||||||
service: opencode
|
|
||||||
session: 24fb9765-a550-4570-8350-f0fc9b7e17db
|
|
||||||
timestamp: 2026-07-28T00:32:47Z
|
|
||||||
git_ref: ed85721c
|
|
||||||
scope: code
|
|
||||||
substantive: true
|
|
||||||
raw_file: 20260728T003247Z_ed85721c_prompt_io.raw.md
|
|
||||||
---
|
|
||||||
|
|
||||||
## Prompt
|
|
||||||
|
|
||||||
Build a safe xonsh workflow for qualifying NativeDB and reverse-backfill
|
|
||||||
correctness against a known gappy IB chart, beginning with
|
|
||||||
`mnq.cme.20260918`. Cover baseline, fresh, restart, append, and expansion
|
|
||||||
testing through implementation, adversarial review, and verification.
|
|
||||||
|
|
||||||
## Response summary
|
|
||||||
|
|
||||||
Implemented a private disposable xonsh qualification workflow. Evidence is
|
|
||||||
tied to a fixed case, report checksum, snapshot checksum, worktree import,
|
|
||||||
and phase metadata. Added explicit path and symlink safety, source
|
|
||||||
replacement handling, xonsh child environments, and lifecycle preservation
|
|
||||||
comparisons.
|
|
||||||
|
|
||||||
## Files changed
|
|
||||||
|
|
||||||
- `snippets/nativedb_backfill_audit.xsh` - disposable qualification helpers
|
|
||||||
- `docs/manual_backfill_qualification.rst` - operator lifecycle runbook
|
|
||||||
- `tests/test_backfill_audit_snippet.py` - xonsh and comparison regressions
|
|
||||||
- `.claude/skills/run-tests/test-harness-reference.md`
|
|
||||||
- qualification test-harness guidance
|
|
||||||
- `ai/prompt-io/opencode/20260728T003247Z_ed85721c_prompt_io.raw.md`
|
|
||||||
- unedited response record
|
|
||||||
- `ai/prompt-io/opencode/20260728T003247Z_ed85721c_prompt_io.md`
|
|
||||||
- provenance metadata and response summary
|
|
||||||
|
|
||||||
## Human edits
|
|
||||||
|
|
||||||
None - generated changes have not been edited by the human.
|
|
||||||
|
|
@ -1,32 +0,0 @@
|
||||||
---
|
|
||||||
model: gpt-5.6-sol
|
|
||||||
provider: openai
|
|
||||||
service: opencode
|
|
||||||
timestamp: 2026-07-28T00:32:47Z
|
|
||||||
git_ref: ed85721c
|
|
||||||
diff_cmd: git diff HEAD~1..HEAD
|
|
||||||
---
|
|
||||||
|
|
||||||
> `git diff HEAD~1..HEAD -- snippets/nativedb_backfill_audit.xsh docs/manual_backfill_qualification.rst tests/test_backfill_audit_snippet.py .claude/skills/run-tests/test-harness-reference.md`
|
|
||||||
|
|
||||||
Added sourceable xonsh helpers that create a private disposable root, bind
|
|
||||||
child processes to the reviewed worktree, capture checksum-bound phase
|
|
||||||
evidence, safely seed and clear test history, and compare lifecycle
|
|
||||||
preservation.
|
|
||||||
|
|
||||||
The workflow rejects path traversal, pre-existing symlinks, output
|
|
||||||
collisions, mismatched case/report/snapshot evidence, and same-phase
|
|
||||||
comparison. The accompanying runbook covers known-bad replay, fresh
|
|
||||||
backfill, restart, append, gap triage, and expansion cases.
|
|
||||||
|
|
||||||
Verification generated with the patch:
|
|
||||||
|
|
||||||
- xonsh qualification helper regressions: passed
|
|
||||||
- xonsh sourceability: passed
|
|
||||||
- Ruff: passed
|
|
||||||
- `git diff --check`: passed
|
|
||||||
|
|
||||||
Adversarial review drove additional evidence binding, worktree executable,
|
|
||||||
environment propagation, source replacement, and descriptor-level safety
|
|
||||||
fixes. Residual concurrent mutation risk is stated explicitly in the private
|
|
||||||
disposable-root runbook.
|
|
||||||
|
|
@ -1,40 +0,0 @@
|
||||||
---
|
|
||||||
model: gpt-5.6-sol
|
|
||||||
provider: openai
|
|
||||||
service: opencode
|
|
||||||
session: 24fb9765-a550-4570-8350-f0fc9b7e17db
|
|
||||||
timestamp: 2026-07-28T00:50:34Z
|
|
||||||
git_ref: ed85721c
|
|
||||||
scope: code
|
|
||||||
substantive: true
|
|
||||||
raw_file: 20260728T005034Z_ed85721c_prompt_io.raw.md
|
|
||||||
---
|
|
||||||
|
|
||||||
## Prompt
|
|
||||||
|
|
||||||
Add reusable read-only tooling to qualify raw NativeDB Parquet against a
|
|
||||||
known gappy IB chart, beginning with `mnq.cme.20260918`. Preserve malformed
|
|
||||||
evidence and distinguish structural validity from unclassified positive
|
|
||||||
gaps without opening or mutating the storage runtime.
|
|
||||||
|
|
||||||
## Response summary
|
|
||||||
|
|
||||||
Implemented raw Parquet audit reporting with human and JSON output, bounded
|
|
||||||
cadence details, exact integer arithmetic, strict status, collision-safe
|
|
||||||
snapshot capture, and source path protections. Regressions cover malformed
|
|
||||||
schema and values, timestamp precision, gap arithmetic, corrupt bytes,
|
|
||||||
copy failures, symlinks, traversal, and read-only CLI behavior.
|
|
||||||
|
|
||||||
## Files changed
|
|
||||||
|
|
||||||
- `piker/storage/_audit.py` - raw Parquet audit and snapshot implementation
|
|
||||||
- `piker/storage/cli.py` - `piker store audit` command
|
|
||||||
- `tests/test_storage_audit.py` - audit and CLI regressions
|
|
||||||
- `ai/prompt-io/opencode/20260728T005034Z_ed85721c_prompt_io.raw.md`
|
|
||||||
- unedited response record
|
|
||||||
- `ai/prompt-io/opencode/20260728T005034Z_ed85721c_prompt_io.md`
|
|
||||||
- provenance metadata and response summary
|
|
||||||
|
|
||||||
## Human edits
|
|
||||||
|
|
||||||
None - generated changes have not been edited by the human.
|
|
||||||
|
|
@ -1,27 +0,0 @@
|
||||||
---
|
|
||||||
model: gpt-5.6-sol
|
|
||||||
provider: openai
|
|
||||||
service: opencode
|
|
||||||
timestamp: 2026-07-28T00:50:34Z
|
|
||||||
git_ref: ed85721c
|
|
||||||
diff_cmd: git diff HEAD~1..HEAD
|
|
||||||
---
|
|
||||||
|
|
||||||
> `git diff HEAD~1..HEAD -- piker/storage/_audit.py piker/storage/cli.py tests/test_storage_audit.py`
|
|
||||||
|
|
||||||
Added a raw, read-only NativeDB Parquet audit with human and JSON output,
|
|
||||||
bounded cadence evidence, exact integer arithmetic, pre-parse snapshot
|
|
||||||
capture, and strict qualification status.
|
|
||||||
|
|
||||||
The command rejects unsafe FQME paths, symlinked sources and outputs,
|
|
||||||
destination collisions, non-regular source nodes, malformed canonical
|
|
||||||
schema, non-finite values, invalid timestamps, noncanonical indexes, and
|
|
||||||
sub-period cadence. Copy-failure cleanup preserves source bytes while
|
|
||||||
completed corrupt snapshots remain available for diagnosis.
|
|
||||||
|
|
||||||
Verification generated with the patch:
|
|
||||||
|
|
||||||
- storage audit and CLI regressions: passed
|
|
||||||
- Ruff: passed
|
|
||||||
- `git diff --check`: passed
|
|
||||||
- final adversarial review: no findings
|
|
||||||
|
|
@ -1,39 +0,0 @@
|
||||||
---
|
|
||||||
model: gpt-5.6-sol
|
|
||||||
provider: openai
|
|
||||||
service: opencode
|
|
||||||
session: 24fb9765-a550-4570-8350-f0fc9b7e17db
|
|
||||||
timestamp: 2026-07-28T23:27:18Z
|
|
||||||
git_ref: ed85721c
|
|
||||||
scope: code
|
|
||||||
substantive: true
|
|
||||||
raw_file: 20260728T232718Z_ed85721c_prompt_io.raw.md
|
|
||||||
---
|
|
||||||
|
|
||||||
## Prompt
|
|
||||||
|
|
||||||
Diagnose the live `pikerd` failure where backfill publication raised
|
|
||||||
`ValueError: OHLCV timestamps must be finite and positive` while merging the
|
|
||||||
known gappy MNQ NativeDB baseline with fresh IB history. Determine whether to
|
|
||||||
commit the pending audit stack or iterate first.
|
|
||||||
|
|
||||||
## Response summary
|
|
||||||
|
|
||||||
Traced the primary failure through `publish_latest_frame()` to
|
|
||||||
`NativeStorageClient.update_ohlcv()`. The incoming frame was valid, but the
|
|
||||||
canonicalized persisted baseline retained its epoch-zero row and caused the
|
|
||||||
merged frame to fail validation. Added persisted-row repair before merge and
|
|
||||||
a regression using the observed legacy schema characteristics.
|
|
||||||
|
|
||||||
## Files changed
|
|
||||||
|
|
||||||
- `piker/storage/nativedb.py` - drop non-positive persisted rows during merge
|
|
||||||
- `tests/test_storage_nativedb.py` - live MNQ failure-shape regression
|
|
||||||
- `ai/prompt-io/opencode/20260728T232718Z_ed85721c_prompt_io.raw.md`
|
|
||||||
- unedited response record
|
|
||||||
- `ai/prompt-io/opencode/20260728T232718Z_ed85721c_prompt_io.md`
|
|
||||||
- provenance metadata and response summary
|
|
||||||
|
|
||||||
## Human edits
|
|
||||||
|
|
||||||
None - generated changes have not been edited by the human.
|
|
||||||
|
|
@ -1,27 +0,0 @@
|
||||||
---
|
|
||||||
model: gpt-5.6-sol
|
|
||||||
provider: openai
|
|
||||||
service: opencode
|
|
||||||
timestamp: 2026-07-28T23:27:18Z
|
|
||||||
git_ref: ed85721c
|
|
||||||
diff_cmd: git diff HEAD~1..HEAD
|
|
||||||
---
|
|
||||||
|
|
||||||
> `git diff HEAD~1..HEAD -- piker/storage/nativedb.py tests/test_storage_nativedb.py`
|
|
||||||
|
|
||||||
Fixed incremental NativeDB updates against legacy persisted history with
|
|
||||||
non-positive timestamps. Incoming provider frames remain strictly validated,
|
|
||||||
while merge repair discards invalid persisted rows before concat, dedupe,
|
|
||||||
ordering, canonical-index rewrite, and atomic publication.
|
|
||||||
|
|
||||||
The regression reproduces the observed MNQ baseline shape: one epoch-zero
|
|
||||||
row, noncanonical absolute indexes, extra derived columns, and a valid fresh
|
|
||||||
IB frame. It proves the invalid row is removed while all valid old and new
|
|
||||||
bars survive with canonical indexes.
|
|
||||||
|
|
||||||
Verification generated with the patch:
|
|
||||||
|
|
||||||
- NativeDB regressions: 18 passed
|
|
||||||
- history backfill regressions: 6 passed
|
|
||||||
- focused Ruff: passed
|
|
||||||
- `git diff --check`: passed
|
|
||||||
|
|
@ -1,40 +0,0 @@
|
||||||
---
|
|
||||||
model: gpt-5.6-sol
|
|
||||||
provider: openai
|
|
||||||
service: opencode
|
|
||||||
session: 24fb9765-a550-4570-8350-f0fc9b7e17db
|
|
||||||
timestamp: 2026-07-29T03:41:06Z
|
|
||||||
git_ref: 922a5df8
|
|
||||||
scope: code
|
|
||||||
substantive: true
|
|
||||||
raw_file: 20260729T034106Z_922a5df8_prompt_io.raw.md
|
|
||||||
---
|
|
||||||
|
|
||||||
## Prompt
|
|
||||||
|
|
||||||
Diagnose the live IB reverse-fill failure where
|
|
||||||
`reqHistoricalDataAsync()` raised API error 10314 because its end date,
|
|
||||||
time, or timezone was invalid.
|
|
||||||
|
|
||||||
## Response summary
|
|
||||||
|
|
||||||
Traced the failure to `Client.bars()`, where an unfinished EST conversion
|
|
||||||
left the original datetime for `ib_async` to serialize as
|
|
||||||
`YYYYMMDD HH:MM:SS UTC`. Converted aware boundaries explicitly to UTC and
|
|
||||||
passed IB's accepted `YYYYMMDD-HH:MM:SS` string while retaining a blank
|
|
||||||
latest-request boundary. Added exact request-argument regressions.
|
|
||||||
|
|
||||||
## Files changed
|
|
||||||
|
|
||||||
- `piker/brokers/ib/api.py` - explicit UTC-dash history boundary format
|
|
||||||
- `tests/test_ib_history.py` - IB request-format regressions
|
|
||||||
- `.claude/skills/run-tests/test-harness-reference.md`
|
|
||||||
- deterministic IB history test mapping
|
|
||||||
- `ai/prompt-io/opencode/20260729T034106Z_922a5df8_prompt_io.raw.md`
|
|
||||||
- unedited response record
|
|
||||||
- `ai/prompt-io/opencode/20260729T034106Z_922a5df8_prompt_io.md`
|
|
||||||
- provenance metadata and response summary
|
|
||||||
|
|
||||||
## Human edits
|
|
||||||
|
|
||||||
None - generated changes have not been edited by the human.
|
|
||||||
|
|
@ -1,25 +0,0 @@
|
||||||
---
|
|
||||||
model: gpt-5.6-sol
|
|
||||||
provider: openai
|
|
||||||
service: opencode
|
|
||||||
timestamp: 2026-07-29T03:41:06Z
|
|
||||||
git_ref: 922a5df8
|
|
||||||
diff_cmd: git diff HEAD~1..HEAD
|
|
||||||
---
|
|
||||||
|
|
||||||
> `git diff HEAD~1..HEAD -- piker/brokers/ib/api.py tests/test_ib_history.py .claude/skills/run-tests/test-harness-reference.md`
|
|
||||||
|
|
||||||
Fixed IB reverse-history requests to serialize aware end boundaries with
|
|
||||||
IB's explicit UTC-dash syntax, `YYYYMMDD-HH:MM:SS`. This bypasses
|
|
||||||
`ib_async`'s trailing-`UTC` representation, which the live Gateway rejected
|
|
||||||
with API error 10314, and removes the unfinished EST comparison breakpoint.
|
|
||||||
|
|
||||||
The regression captures the exact `reqHistoricalDataAsync()` argument for
|
|
||||||
latest, stdlib-aware, Pendulum UTC, and America/New_York inputs.
|
|
||||||
|
|
||||||
Verification generated with the patch:
|
|
||||||
|
|
||||||
- IB history request regressions: 4 passed
|
|
||||||
- focused Ruff: passed
|
|
||||||
- `git diff --check`: passed
|
|
||||||
- adversarial review: no findings
|
|
||||||
|
|
@ -1,40 +0,0 @@
|
||||||
---
|
|
||||||
model: gpt-5.6-sol
|
|
||||||
provider: openai
|
|
||||||
service: opencode
|
|
||||||
session: 24fb9765-a550-4570-8350-f0fc9b7e17db
|
|
||||||
timestamp: 2026-07-29T04:17:23Z
|
|
||||||
git_ref: ce33deb6
|
|
||||||
scope: code
|
|
||||||
substantive: true
|
|
||||||
raw_file: 20260729T041723Z_ce33deb6_prompt_io.raw.md
|
|
||||||
---
|
|
||||||
|
|
||||||
## Prompt
|
|
||||||
|
|
||||||
Diagnose why the chart still showed a zero first OHLCV row after the
|
|
||||||
epoch-zero timestamp repair, causing auto-y-ranging to include zero.
|
|
||||||
|
|
||||||
## Response summary
|
|
||||||
|
|
||||||
Audited live 60s and 1s NativeDB files and found one exact 60s first-slot
|
|
||||||
sentinel at epoch 60 with a completely zero OHLCV payload. Added narrowly
|
|
||||||
scoped read and merge repair, matching incoming validation, sentinel-only
|
|
||||||
startup handling, canonical reindexing, and explicit audit classification.
|
|
||||||
Preserved modern all-zero bars as unclassified evidence rather than assuming
|
|
||||||
all zero-priced instruments are corrupt.
|
|
||||||
|
|
||||||
## Files changed
|
|
||||||
|
|
||||||
- `piker/storage/nativedb.py` - first-slot sentinel repair and validation
|
|
||||||
- `piker/storage/_audit.py` - sentinel classification and zero-row evidence
|
|
||||||
- `tests/test_storage_nativedb.py` - hydration, merge, and boundary regressions
|
|
||||||
- `tests/test_storage_audit.py` - sentinel and modern-zero audit regressions
|
|
||||||
- `ai/prompt-io/opencode/20260729T041723Z_ce33deb6_prompt_io.raw.md`
|
|
||||||
- unedited response record
|
|
||||||
- `ai/prompt-io/opencode/20260729T041723Z_ce33deb6_prompt_io.md`
|
|
||||||
- provenance metadata and response summary
|
|
||||||
|
|
||||||
## Human edits
|
|
||||||
|
|
||||||
None - generated changes have not been edited by the human.
|
|
||||||
|
|
@ -1,31 +0,0 @@
|
||||||
---
|
|
||||||
model: gpt-5.6-sol
|
|
||||||
provider: openai
|
|
||||||
service: opencode
|
|
||||||
timestamp: 2026-07-29T04:17:23Z
|
|
||||||
git_ref: ce33deb6
|
|
||||||
diff_cmd: git diff HEAD~1..HEAD
|
|
||||||
---
|
|
||||||
|
|
||||||
> `git diff HEAD~1..HEAD -- piker/storage/nativedb.py piker/storage/_audit.py tests/test_storage_nativedb.py tests/test_storage_audit.py`
|
|
||||||
|
|
||||||
Fixed the remaining legacy first-slot sentinel observed in live MNQ 60s
|
|
||||||
history: `time=60` with zero open, high, low, close, and volume. NativeDB now
|
|
||||||
repairs the exact sentinel before read hydration and merge, reindexes the
|
|
||||||
filtered view, and persists the repaired frame on the next valid update.
|
|
||||||
|
|
||||||
The repair remains narrowly scoped. Modern all-zero OHLC bars stay valid for
|
|
||||||
spreads or synthetic instruments, null-containing malformed rows still fail
|
|
||||||
validation, new writes can not recreate the first-slot sentinel, and a file
|
|
||||||
containing only sentinels loads as no history so fresh backfill can proceed.
|
|
||||||
|
|
||||||
The raw audit reports total all-zero price rows, classifies first-slot
|
|
||||||
sentinels as structural violations, and leaves later all-zero rows visible as
|
|
||||||
unclassified warnings.
|
|
||||||
|
|
||||||
Verification generated with the patch:
|
|
||||||
|
|
||||||
- NativeDB, audit, history, xonsh, and IB regressions: 61 passed
|
|
||||||
- focused Ruff: passed
|
|
||||||
- `git diff --check`: passed
|
|
||||||
- final adversarial review: no findings
|
|
||||||
|
|
@ -1,34 +0,0 @@
|
||||||
---
|
|
||||||
model: openai/gpt-5.6-sol
|
|
||||||
service: opencode
|
|
||||||
session: 6409e3bb-1a9a-4ada-b6c4-c554115143e9
|
|
||||||
timestamp: 2026-07-29T18:54:06Z
|
|
||||||
git_ref: d359b1cb
|
|
||||||
scope: code
|
|
||||||
substantive: true
|
|
||||||
raw_file: 20260729T185406Z_d359b1cb_prompt_io.raw.md
|
|
||||||
---
|
|
||||||
|
|
||||||
## Prompt
|
|
||||||
|
|
||||||
The user reported that QQQ 60-second zeros appeared as a flat line after
|
|
||||||
reload, clarified that the outstanding concern was the prior `ldshm`
|
|
||||||
failure, and instructed the agent to implement the more focused fix.
|
|
||||||
|
|
||||||
## Response summary
|
|
||||||
|
|
||||||
Changed `ldshm` to classify invalid SHM snapshots before downstream
|
|
||||||
analysis. Cadence is inferred only from observed finite positive steps;
|
|
||||||
buffers containing non-finite or non-positive timestamps, or lacking a
|
|
||||||
positive cadence, are skipped rather than partially replacement-written
|
|
||||||
or reloaded. Added deterministic helper and command-level regressions.
|
|
||||||
|
|
||||||
## Files changed
|
|
||||||
|
|
||||||
- `piker/storage/cli.py` - inspect cadence and reject invalid SHM snapshots before mutation.
|
|
||||||
- `tests/test_ldshm.py` - cover QQQ-like zeros, corrupt timestamps, cadence selection, degenerate buffers, and mutation prevention.
|
|
||||||
- `.claude/skills/run-tests/test-harness-reference.md` - register the deterministic regression target.
|
|
||||||
|
|
||||||
## Human edits
|
|
||||||
|
|
||||||
None - generated output remains uncommitted.
|
|
||||||
|
|
@ -1,58 +0,0 @@
|
||||||
---
|
|
||||||
model: openai/gpt-5.6-sol
|
|
||||||
service: opencode
|
|
||||||
timestamp: 2026-07-29T18:54:06Z
|
|
||||||
git_ref: d359b1cb
|
|
||||||
diff_cmd: git diff HEAD~1..HEAD
|
|
||||||
---
|
|
||||||
|
|
||||||
The user clarified that the QQQ 60-second chart now displayed a flat
|
|
||||||
forward-filled segment, then asked whether the previously reported
|
|
||||||
`piker store ldshm` failure had been fixed. After being told it had not,
|
|
||||||
the user instructed: "ok but i read above you have a more focussed fix
|
|
||||||
todo now? so have at it!"
|
|
||||||
|
|
||||||
The implementation focused on the exact failure boundary. It does not
|
|
||||||
filter invalid rows into a partial replacement and does not mutate live
|
|
||||||
SHM. Instead, `ldshm` inspects one captured Polars snapshot, infers its
|
|
||||||
cadence from observed finite positive timestamp steps, and skips the
|
|
||||||
entire buffer before analysis, persistence, or reload when any timestamp
|
|
||||||
is non-finite or non-positive.
|
|
||||||
|
|
||||||
> `git diff HEAD~1..HEAD -- piker/storage/cli.py`
|
|
||||||
|
|
||||||
Generated `_shm_period_and_invalid_count()` and integrated its result in
|
|
||||||
`ldshm`. The helper selects the most frequent observed positive step,
|
|
||||||
using the smallest observed step as the deterministic tie-break. Short
|
|
||||||
or cadence-degenerate buffers are skipped. Invalid snapshots are logged
|
|
||||||
and cannot reach deduplication, NativeDB replacement, or SHM reload.
|
|
||||||
|
|
||||||
> `git diff HEAD~1..HEAD -- tests/test_ldshm.py`
|
|
||||||
|
|
||||||
Generated deterministic regressions for the QQQ-shaped interior zero
|
|
||||||
run, observed-step cadence selection, all invalid timestamp classes,
|
|
||||||
short and degenerate buffers, and command-level prevention of dedupe,
|
|
||||||
storage writes, and reload. The command-level test uses an immutable
|
|
||||||
Polars snapshot and failing spies, without live SHM mutation or timing.
|
|
||||||
|
|
||||||
> `git diff HEAD~1..HEAD -- .claude/skills/run-tests/test-harness-reference.md`
|
|
||||||
|
|
||||||
Added the deterministic `ldshm` regression target and its change-to-test
|
|
||||||
mapping to the repository test harness reference.
|
|
||||||
|
|
||||||
Verification output:
|
|
||||||
|
|
||||||
```text
|
|
||||||
.......................................................... [100%]
|
|
||||||
58 passed in 0.70s
|
|
||||||
```
|
|
||||||
|
|
||||||
`git diff --check` passed. Ruff was unavailable in the worktree's
|
|
||||||
existing environment. Three adversarial review passes found and drove
|
|
||||||
fixes for partial-replacement data loss, invented median timeframes,
|
|
||||||
mixed SHM observations, and pre-guard null-analysis failures. The final
|
|
||||||
review reported no remaining findings.
|
|
||||||
|
|
||||||
The patch intentionally does not claim that `ldshm` is safe to run as a
|
|
||||||
general concurrent repair writer. It handles invalid live snapshots by
|
|
||||||
refusing mutation rather than weakening NativeDB validation.
|
|
||||||
|
|
@ -1,37 +0,0 @@
|
||||||
---
|
|
||||||
model: openai/gpt-5.6-sol
|
|
||||||
service: opencode
|
|
||||||
session: 253ade33-07ba-45b5-8839-be35d17ec164
|
|
||||||
timestamp: 2026-07-29T20:40:46Z
|
|
||||||
git_ref: ad6c560f
|
|
||||||
scope: code
|
|
||||||
substantive: true
|
|
||||||
raw_file: 20260729T204046Z_ad6c560f_prompt_io.raw.md
|
|
||||||
---
|
|
||||||
|
|
||||||
## Prompt
|
|
||||||
|
|
||||||
The user reported that the QQQ 1-second chart still contained a gap after
|
|
||||||
the `ldshm` fix, asked the agent to inspect it, and authorized continued
|
|
||||||
implementation after a short pause and shutdown of the live workspace.
|
|
||||||
|
|
||||||
## Response summary
|
|
||||||
|
|
||||||
Diagnosed a 653-row active RT SHM null reservation caused by inclusive IB
|
|
||||||
reverse-query overlaps and startup repair orchestration. Prevented extra
|
|
||||||
physical SHM overlap rows, serialized and bounded IB history recovery,
|
|
||||||
made blank/error responses terminate, and constrained synthetic repair to
|
|
||||||
valid interior timestamp boundaries. Added deterministic concurrency and
|
|
||||||
data-layout regressions.
|
|
||||||
|
|
||||||
## Files changed
|
|
||||||
|
|
||||||
- `piker/brokers/ib/feed.py` - bound and serialize IB history reset/retry behavior.
|
|
||||||
- `piker/tsp/_history.py` - prevent SHM overlap skew and safely finalize null repair.
|
|
||||||
- `tests/test_ib_history.py` - cover blank, cancellation, reset, and pacing interleavings.
|
|
||||||
- `tests/test_history_backfill.py` - cover overlap and null-repair invariants.
|
|
||||||
- `.claude/skills/run-tests/test-harness-reference.md` - register deterministic coverage.
|
|
||||||
|
|
||||||
## Human edits
|
|
||||||
|
|
||||||
None - generated output remains uncommitted.
|
|
||||||
|
|
@ -1,72 +0,0 @@
|
||||||
---
|
|
||||||
model: openai/gpt-5.6-sol
|
|
||||||
service: opencode
|
|
||||||
timestamp: 2026-07-29T20:40:46Z
|
|
||||||
git_ref: ad6c560f
|
|
||||||
diff_cmd: git diff HEAD~1..HEAD
|
|
||||||
---
|
|
||||||
|
|
||||||
The user reported that QQQ still displayed a gap on the 1-second chart
|
|
||||||
after the focused `ldshm` fix and asked the agent to inspect it. The user
|
|
||||||
then paused and resumed implementation while shutting down the live piker
|
|
||||||
trading workspace.
|
|
||||||
|
|
||||||
Read-only live inspection found the active datad generation held 653
|
|
||||||
contiguous zero-time rows in QQQ's 1-second RT SHM, while durable Parquet
|
|
||||||
contained no zero rows. The run occupied absolute indexes 168148 through
|
|
||||||
168800 between timestamps 1785348398 and 1785349051. The stale actor
|
|
||||||
generation and active 60-second history were separately identified.
|
|
||||||
|
|
||||||
> `git diff HEAD~1..HEAD -- piker/tsp/_history.py`
|
|
||||||
|
|
||||||
Generated history changes that exclude each inclusive reverse-query
|
|
||||||
endpoint already present in SHM while retaining the full provider frame
|
|
||||||
for NativeDB merge. Startup null repair now runs after reverse backfill,
|
|
||||||
uses bounded UI notifications, handles provider no-data without an
|
|
||||||
interactive pause, fills only exact interior zero groups, and refuses
|
|
||||||
synthetic timestamps unless both valid boundaries establish the expected
|
|
||||||
cadence.
|
|
||||||
|
|
||||||
> `git diff HEAD~1..HEAD -- piker/brokers/ib/feed.py`
|
|
||||||
|
|
||||||
Generated IB history reset changes that make blank responses complete,
|
|
||||||
bound repeated cancellation and reset failures per request, serialize
|
|
||||||
timeout and pacing farm resets with one actor-global Trio lock, carry
|
|
||||||
explicit reset results, and coordinate pacing handoff with queued timeout
|
|
||||||
waiters.
|
|
||||||
|
|
||||||
> `git diff HEAD~1..HEAD -- tests/test_history_backfill.py`
|
|
||||||
|
|
||||||
Generated regressions for inclusive endpoint exclusion, full NativeDB
|
|
||||||
provider deltas, strict synthetic gap boundaries, empty-provider local
|
|
||||||
fallback, bounded notifications, and preservation of valid margin rows.
|
|
||||||
|
|
||||||
> `git diff HEAD~1..HEAD -- tests/test_ib_history.py`
|
|
||||||
|
|
||||||
Generated deterministic regressions for blank IB responses, cancellation
|
|
||||||
limits, stalled reset cancellation, pacing reset failure limits,
|
|
||||||
cross-request reset serialization, timeout-to-pacing handoff, and
|
|
||||||
successful handoff timeout restart.
|
|
||||||
|
|
||||||
> `git diff HEAD~1..HEAD -- .claude/skills/run-tests/test-harness-reference.md`
|
|
||||||
|
|
||||||
Registered the deterministic history-backfill target and expanded the IB
|
|
||||||
history mapping to include `feed.py`.
|
|
||||||
|
|
||||||
Verification output:
|
|
||||||
|
|
||||||
```text
|
|
||||||
........................................................................ [ 93%]
|
|
||||||
..... [100%]
|
|
||||||
77 passed in 2.12s
|
|
||||||
```
|
|
||||||
|
|
||||||
`git diff --check` passed. Multiple adversarial review rounds identified
|
|
||||||
and drove fixes for unbounded IB empty/cancellation/reset paths, stale
|
|
||||||
reset ownership, actor-global failure poisoning, concurrent farm resets,
|
|
||||||
double-counted pacing handoffs, physical endpoint overlap, and unsafe
|
|
||||||
synthetic timestamp boundaries. Final review reported no findings.
|
|
||||||
|
|
||||||
Live validation was intentionally deferred because the user shut down the
|
|
||||||
trading workspace. A fresh datad/chart startup is required to regenerate
|
|
||||||
SHM and verify that QQQ no longer contains the 653-row null run.
|
|
||||||
|
|
@ -1,41 +0,0 @@
|
||||||
---
|
|
||||||
model: openai/gpt-5.6-sol
|
|
||||||
service: opencode
|
|
||||||
session: ses_0799212ebffe42arY96czXn89F
|
|
||||||
timestamp: 2026-07-31T16:52:15Z
|
|
||||||
git_ref: 0846cbd4
|
|
||||||
scope: code
|
|
||||||
substantive: true
|
|
||||||
raw_file: 20260731T165215Z_0846cbd4_prompt_io.raw.md
|
|
||||||
---
|
|
||||||
|
|
||||||
## Prompt
|
|
||||||
|
|
||||||
Evaluate and update `piker store` so bare groups and endpoints immediately
|
|
||||||
show help; prepare for eventual optional fuzzy selection in `anal` and
|
|
||||||
`ldshm`; aggregate recent time-series diagnostics into CLI endpoints. The
|
|
||||||
user selected the safe-foundation scope.
|
|
||||||
|
|
||||||
## Response summary
|
|
||||||
|
|
||||||
Added immediate help UX, exact NativeDB and SHM identities, read-only
|
|
||||||
`series` and `shm` diagnostics, selector-ready exact SHM names, and robust
|
|
||||||
discovery/attachment. Fixed related `ldshm` option and no-match failures.
|
|
||||||
Deferred optional `fzf` and mutation-default changes.
|
|
||||||
|
|
||||||
## Files changed
|
|
||||||
|
|
||||||
- `piker/storage/cli.py` - help UX and read-only series/SHM diagnostics.
|
|
||||||
- `piker/storage/nativedb.py` - canonical compound series identities.
|
|
||||||
- `piker/tsp/_history.py` - exact SHM discovery and dtype resolution.
|
|
||||||
- `piker/data/_sharedmem.py` - attach-only existing-segment helper.
|
|
||||||
- `piker/tsp/__init__.py` - SHM identity helper exports.
|
|
||||||
- `tests/test_store_cli.py` - command UX and endpoint regressions.
|
|
||||||
- `tests/test_ldshm.py` - SHM diagnostics and operational regressions.
|
|
||||||
- `tests/test_storage_nativedb.py` - series parsing/index regressions.
|
|
||||||
- `docs/manual_backfill_qualification.rst` - triage command documentation.
|
|
||||||
- `.claude/skills/run-tests/test-harness-reference.md` - test mapping.
|
|
||||||
|
|
||||||
## Human edits
|
|
||||||
|
|
||||||
None - generated output remains uncommitted.
|
|
||||||
|
|
@ -1,93 +0,0 @@
|
||||||
---
|
|
||||||
model: openai/gpt-5.6-sol
|
|
||||||
service: opencode
|
|
||||||
timestamp: 2026-07-31T16:52:15Z
|
|
||||||
git_ref: 0846cbd4
|
|
||||||
diff_cmd: git diff HEAD~1..HEAD
|
|
||||||
---
|
|
||||||
|
|
||||||
The user requested an evaluation and possible update of `piker store`,
|
|
||||||
including immediate help output when a group or endpoint is invoked with
|
|
||||||
no arguments. The user also proposed eventual optional `fzf` selection for
|
|
||||||
`anal` and `ldshm`, and authorized aggregating the recent time-series and
|
|
||||||
SHM debugging work into CLI endpoints. After reviewing three scopes, the
|
|
||||||
user selected the recommended safe foundation rather than implementing
|
|
||||||
interactive fuzzy selection or changing mutation defaults immediately.
|
|
||||||
|
|
||||||
> `git diff HEAD~1..HEAD -- piker/storage/cli.py`
|
|
||||||
|
|
||||||
Generated no-argument help behavior for the `store` group and every
|
|
||||||
endpoint. Added read-only `series` and `shm` commands, JSON and Rich output,
|
|
||||||
exact `--shm-name` plumbing, SHM cadence/invalid/order/gap summaries, and
|
|
||||||
safe corrupt-epoch formatting. Fixed existing `ldshm` no-write/no-reload
|
|
||||||
control flow and no-match debugger behavior.
|
|
||||||
|
|
||||||
> `git diff HEAD~1..HEAD -- piker/storage/nativedb.py`
|
|
||||||
|
|
||||||
Generated canonical `NativeSeriesRef` parsing and deterministic listing.
|
|
||||||
Changed the internal index to preserve `(fqme, period)` identities while
|
|
||||||
keeping unique-FQME compatibility listing and cardinality. Hardened
|
|
||||||
malformed, sidecar, Unicode-period, symlink, and traversal handling.
|
|
||||||
|
|
||||||
> `git diff HEAD~1..HEAD -- piker/tsp/_history.py`
|
|
||||||
|
|
||||||
Generated exact `ShmBufferRef` parsing and stable discovery, replacing
|
|
||||||
unsafe substring globbing. Added dtype resolution that mirrors history
|
|
||||||
allocation, exact-ref attachment, disappearance handling, and optional
|
|
||||||
exact-name iteration.
|
|
||||||
|
|
||||||
> `git diff HEAD~1..HEAD -- piker/data/_sharedmem.py`
|
|
||||||
|
|
||||||
Generated attach-only SHM access which never creates a segment when a
|
|
||||||
discovered object disappears.
|
|
||||||
|
|
||||||
> `git diff HEAD~1..HEAD -- piker/tsp/__init__.py`
|
|
||||||
|
|
||||||
Exported selector-ready SHM identity, parsing, listing, and dtype helpers.
|
|
||||||
|
|
||||||
> `git diff HEAD~1..HEAD -- tests/test_store_cli.py`
|
|
||||||
|
|
||||||
Generated command-level help, exact durable-series JSON, read-only SHM JSON,
|
|
||||||
and unknown exact-name regressions.
|
|
||||||
|
|
||||||
> `git diff HEAD~1..HEAD -- tests/test_ldshm.py`
|
|
||||||
|
|
||||||
Generated SHM identity, summary, ordering, dtype, forged-name, disabled
|
|
||||||
mutation-flag, and gap-markup regressions.
|
|
||||||
|
|
||||||
> `git diff HEAD~1..HEAD -- tests/test_storage_nativedb.py`
|
|
||||||
|
|
||||||
Generated compound index, canonical parser, malformed filename, and dotted
|
|
||||||
FQME regressions.
|
|
||||||
|
|
||||||
> `git diff HEAD~1..HEAD -- docs/manual_backfill_qualification.rst`
|
|
||||||
|
|
||||||
Documented `store series` and `store shm` as separate read-only durable and
|
|
||||||
live-memory triage layers.
|
|
||||||
|
|
||||||
> `git diff HEAD~1..HEAD -- .claude/skills/run-tests/test-harness-reference.md`
|
|
||||||
|
|
||||||
Registered the deterministic storage CLI UX target and mapping.
|
|
||||||
|
|
||||||
Verification output:
|
|
||||||
|
|
||||||
```text
|
|
||||||
........................................................................ [ 71%]
|
|
||||||
............................. [100%]
|
|
||||||
101 passed in 1.72s
|
|
||||||
```
|
|
||||||
|
|
||||||
Real `piker store` and `piker store audit` invocations printed complete
|
|
||||||
help without `--help`, exiting with Click's normal no-args help status 2.
|
|
||||||
`git diff --check` passed. Ruff was unavailable in the existing worktree
|
|
||||||
environment.
|
|
||||||
|
|
||||||
Adversarial review drove fixes for provider dtype reconstruction, observed
|
|
||||||
versus expected cadence, exact SHM grammar, discovery races, Typer direct
|
|
||||||
defaults, malformed NativeDB periods, compound cardinality compatibility,
|
|
||||||
undefined `ldshm` reload payloads, no-match debugger hangs, ordering
|
|
||||||
corruption reporting, and dtype precedence. Final review found no issues.
|
|
||||||
|
|
||||||
Optional external `fzf` or built-in numbered selection remains deferred.
|
|
||||||
The exact series and SHM identities added here are the intended foundation
|
|
||||||
for that later patch.
|
|
||||||
|
|
@ -1,39 +0,0 @@
|
||||||
---
|
|
||||||
model: openai/gpt-5.6-sol
|
|
||||||
service: opencode
|
|
||||||
session: ses_0799212ebffe42arY96czXn89F
|
|
||||||
timestamp: 2026-08-01T01:53:21Z
|
|
||||||
git_ref: 74ea2152
|
|
||||||
scope: code
|
|
||||||
substantive: true
|
|
||||||
raw_file: 20260801T015321Z_74ea2152_prompt_io.raw.md
|
|
||||||
---
|
|
||||||
|
|
||||||
## Prompt
|
|
||||||
|
|
||||||
Make `piker store ls` default to all NativeDB series as a compact counterpart
|
|
||||||
to detailed `series`, with sensible no-flag output and a visible help
|
|
||||||
description. Consolidate SHM inspection and repair under canonical `shm`,
|
|
||||||
because attachment to volatile segments is implied, and make inspection the
|
|
||||||
safe default while retaining explicit persistence and reload controls.
|
|
||||||
|
|
||||||
## Response summary
|
|
||||||
|
|
||||||
Replaced backend-oriented `ls` with compact NativeDB discovery and made both
|
|
||||||
listing commands default to all series. Consolidated SHM behavior under a
|
|
||||||
read-only-by-default `shm` command, guarded explicit repair options, updated
|
|
||||||
executable references and docs, and added command regressions.
|
|
||||||
|
|
||||||
## Files changed
|
|
||||||
|
|
||||||
- `piker/storage/cli.py` - listing defaults and unified SHM command modes.
|
|
||||||
- `tests/test_store_cli.py` - listing, help, and SHM mode regressions.
|
|
||||||
- `tests/test_ldshm.py` - explicit persistence-path regressions.
|
|
||||||
- `docs/manual_backfill_qualification.rst` - revised safe CLI workflow.
|
|
||||||
- `snippets/claude_debug_helper.py` - explicit SHM persistence commands.
|
|
||||||
- `.claude/skills/run-tests/test-harness-reference.md` - safety and test map.
|
|
||||||
- `.claude/skills/piker-slang/examples.md` - canonical command example.
|
|
||||||
|
|
||||||
## Human edits
|
|
||||||
|
|
||||||
None - generated output incorporates the user's design refinements.
|
|
||||||
|
|
@ -1,78 +0,0 @@
|
||||||
---
|
|
||||||
model: openai/gpt-5.6-sol
|
|
||||||
service: opencode
|
|
||||||
timestamp: 2026-08-01T01:53:21Z
|
|
||||||
git_ref: 74ea2152
|
|
||||||
diff_cmd: git diff HEAD~1..HEAD
|
|
||||||
---
|
|
||||||
|
|
||||||
The user requested command-surface refinements after reviewing the new
|
|
||||||
storage CLI. Bare `ls` should default to all series and act as a compact
|
|
||||||
form of detailed `series`; commands should produce sensible default output
|
|
||||||
without requiring trigger flags; and `ls` needed a parent-help description.
|
|
||||||
The user first proposed folding read-only SHM inspection into `ldshm -r`,
|
|
||||||
then clarified that `shm` is the better canonical command because attaching
|
|
||||||
to volatile segments is implied by the resource name.
|
|
||||||
|
|
||||||
The resulting design uses `piker store ls` as a compact NativeDB FQME and
|
|
||||||
period view, while `piker store series` reports each exact sub-series with
|
|
||||||
size and path details. Both default to all records and accept an optional
|
|
||||||
FQME substring.
|
|
||||||
|
|
||||||
`piker store shm FQME` is read-only by default. Persistence and reload enter
|
|
||||||
the prior repair workflow only through explicit `--write-parquet` and
|
|
||||||
`--reload-parquet-to-shm` flags. Reload requires persistence, and read-only
|
|
||||||
formatting flags are rejected in repair mode instead of being ignored.
|
|
||||||
|
|
||||||
> `git diff HEAD~1..HEAD -- piker/storage/cli.py`
|
|
||||||
|
|
||||||
Generated shared NativeDB payload collection, compact and detailed output,
|
|
||||||
numeric period ordering, default-all semantics, the canonical `shm` command,
|
|
||||||
safe mode dispatch, explicit repair validation, and debugger propagation in
|
|
||||||
read-only mode.
|
|
||||||
|
|
||||||
> `git diff HEAD~1..HEAD -- tests/test_store_cli.py`
|
|
||||||
|
|
||||||
Generated regressions for no-flag listing, parent-help descriptions, numeric
|
|
||||||
period display, default read-only SHM JSON, reload dependencies, and repair
|
|
||||||
versus read-only option conflicts.
|
|
||||||
|
|
||||||
> `git diff HEAD~1..HEAD -- tests/test_ldshm.py`
|
|
||||||
|
|
||||||
Adjusted persistence regressions for the renamed command and explicit repair
|
|
||||||
entry while preserving the historical failure rationale.
|
|
||||||
|
|
||||||
> `git diff HEAD~1..HEAD -- docs/manual_backfill_qualification.rst`
|
|
||||||
|
|
||||||
Documented compact versus detailed NativeDB discovery, default read-only SHM
|
|
||||||
inspection, and the explicitly mutating repair invocation.
|
|
||||||
|
|
||||||
> `git diff HEAD~1..HEAD -- snippets/claude_debug_helper.py`
|
|
||||||
|
|
||||||
Updated executable debug helper commands to select explicit SHM persistence.
|
|
||||||
|
|
||||||
> `git diff HEAD~1..HEAD -- .claude/skills/run-tests/test-harness-reference.md`
|
|
||||||
|
|
||||||
Updated operational safety guidance and SHM regression mappings.
|
|
||||||
|
|
||||||
> `git diff HEAD~1..HEAD -- .claude/skills/piker-slang/examples.md`
|
|
||||||
|
|
||||||
Updated the command example to the canonical `shm` spelling.
|
|
||||||
|
|
||||||
Verification output:
|
|
||||||
|
|
||||||
```text
|
|
||||||
........................................................................ [ 69%]
|
|
||||||
................................ [100%]
|
|
||||||
104 passed in 5.77s
|
|
||||||
```
|
|
||||||
|
|
||||||
Real command-help rendering was checked for the parent group, `ls`, `series`,
|
|
||||||
and `shm`. Real read-only `ls` and `series --json` output was also exercised
|
|
||||||
against the configured NativeDB. `git diff --check` passed.
|
|
||||||
|
|
||||||
Adversarial review identified and drove fixes for lexicographic period
|
|
||||||
ordering, stale runbook safety wording, ignored mode-specific options, and an
|
|
||||||
explicit-default `--max-gaps 10` validation bypass. Final review found no
|
|
||||||
remaining issues. Real OS-backed SHM attachment and successful repair/reload
|
|
||||||
remain integration-level validation concerns.
|
|
||||||
|
|
@ -1,33 +0,0 @@
|
||||||
---
|
|
||||||
model: openai/gpt-5.6-sol
|
|
||||||
service: opencode
|
|
||||||
session: ses_0799212ebffe42arY96czXn89F
|
|
||||||
timestamp: 2026-08-05T19:50:01Z
|
|
||||||
git_ref: f0f3c806
|
|
||||||
scope: code
|
|
||||||
substantive: true
|
|
||||||
raw_file: 20260805T195001Z_f0f3c806_prompt_io.raw.md
|
|
||||||
---
|
|
||||||
|
|
||||||
## Prompt
|
|
||||||
|
|
||||||
Inspect the completed NVDA 60s SHM backfill before workspace restart, explain
|
|
||||||
the persistent zero region, and continue fixing the indexing logic so sparse
|
|
||||||
IB history does not leave physical null reservations.
|
|
||||||
|
|
||||||
## Response summary
|
|
||||||
|
|
||||||
Captured a 42,720-row live SHM null span whose valid margins shared the same
|
|
||||||
timestamp. Replaced wall-clock row reservation with actual provider-boundary
|
|
||||||
placement, fixed stale SHM first-index, endpoint insertion and field-map
|
|
||||||
semantics, published the final storage prepend, and added a full multi-frame
|
|
||||||
`tsdb_backfill()` regression using a real `ShmArray`.
|
|
||||||
|
|
||||||
## Files changed
|
|
||||||
|
|
||||||
- `piker/tsp/_history.py` - contiguous provider and NativeDB prepends.
|
|
||||||
- `tests/test_history_backfill.py` - sparse multi-frame SHM regression.
|
|
||||||
|
|
||||||
## Human edits
|
|
||||||
|
|
||||||
None - generated output incorporates the user's live observations.
|
|
||||||
|
|
@ -1,71 +0,0 @@
|
||||||
---
|
|
||||||
model: openai/gpt-5.6-sol
|
|
||||||
service: opencode
|
|
||||||
timestamp: 2026-08-05T19:50:01Z
|
|
||||||
git_ref: f0f3c806
|
|
||||||
diff_cmd: git diff HEAD~1..HEAD
|
|
||||||
---
|
|
||||||
|
|
||||||
The user reported that a completed NVDA 60s backfill left a large zero
|
|
||||||
region in live SHM and asked for immediate inspection before restarting the
|
|
||||||
workspace. The captured buffer contained 42,720 invalid rows at absolute
|
|
||||||
indexes `3065895..3108614`. The valid rows on both sides had the identical
|
|
||||||
timestamp `1781271360`, proving the region was an erroneous physical-index
|
|
||||||
reservation rather than a real temporal gap.
|
|
||||||
|
|
||||||
The user then asked the agent to continue fixing the backfill logic.
|
|
||||||
|
|
||||||
> `git diff HEAD~1..HEAD -- piker/tsp/_history.py`
|
|
||||||
|
|
||||||
Removed wall-clock-based SHM reservation from `tsdb_backfill()`. Reverse
|
|
||||||
provider frames now extend the visible `ShmArray._first` boundary on every
|
|
||||||
prepend, beginning exactly at the current first index after inclusive query
|
|
||||||
endpoints are removed. Added `_prepend_tsdb_history()` to trim storage rows
|
|
||||||
against the actual earliest provider timestamp and prepend them directly
|
|
||||||
adjacent only after reverse provider retrieval completes.
|
|
||||||
|
|
||||||
This preserves sparse venue history as ordinal samples rather than treating
|
|
||||||
every elapsed calendar period as a physical SHM row. It also prevents the
|
|
||||||
old `_first + 1` insertion point from overwriting the earliest published bar.
|
|
||||||
|
|
||||||
> `git diff HEAD~1..HEAD -- tests/test_history_backfill.py`
|
|
||||||
|
|
||||||
Added a full `tsdb_backfill()` regression modeled on the live NVDA failure.
|
|
||||||
It uses a real `ShmArray`, NativeDB's field map, two inclusive reverse-provider
|
|
||||||
frames, and overlapping stored history. Assertions prove the complete
|
|
||||||
timestamp sequence is contiguous and lossless, contains no non-positive
|
|
||||||
timestamps, sends complete provider frames to durable storage, and notifies
|
|
||||||
chart/FSP consumers after the final storage prepend.
|
|
||||||
|
|
||||||
Live evidence captured before workspace restart:
|
|
||||||
|
|
||||||
```text
|
|
||||||
rows 1575296 first_index 1568233 last_index 3143528
|
|
||||||
invalid_count 42720
|
|
||||||
left boundary
|
|
||||||
[(3065893, 1781271300, 204.03, 204.82)
|
|
||||||
(3065894, 1781271360, 204.81, 204.72)
|
|
||||||
(3065895, 0, 0. , 0. )]
|
|
||||||
right boundary
|
|
||||||
[(3108614, 0, 0. , 0. )
|
|
||||||
(3108615, 1781271360, 204.81, 205.44)
|
|
||||||
(3108616, 1781271420, 205.46, 205.48)]
|
|
||||||
```
|
|
||||||
|
|
||||||
Verification output:
|
|
||||||
|
|
||||||
```text
|
|
||||||
........................................................................ [ 68%]
|
|
||||||
................................. [100%]
|
|
||||||
105 passed in 4.80s
|
|
||||||
```
|
|
||||||
|
|
||||||
Adversarial review caught stale `_first` semantics and an off-by-one
|
|
||||||
insertion point in the initial patch. The first live restart then exposed an
|
|
||||||
undefined `time_key` local at the new `tsdb_backfill()` call site, which
|
|
||||||
crashed `datad.ib` and propagated to the chart as `RemoteActorError`. The
|
|
||||||
helper now derives the source timestamp field from its field map, and the
|
|
||||||
test enters the full enclosing lifecycle so the original `NameError` can not
|
|
||||||
recur unnoticed. A final review also drove explicit publication after stored
|
|
||||||
history is prepended and deterministic final-stage synchronization. Final
|
|
||||||
review found no remaining issues; another live restart remains pending.
|
|
||||||
|
|
@ -1,36 +0,0 @@
|
||||||
---
|
|
||||||
model: openai/gpt-5.6-sol
|
|
||||||
service: opencode
|
|
||||||
session: ses_0799212ebffe42arY96czXn89F
|
|
||||||
timestamp: 2026-08-11T20:58:26Z
|
|
||||||
git_ref: 06d5ea5d
|
|
||||||
scope: code
|
|
||||||
substantive: true
|
|
||||||
raw_file: 20260811T205826Z_06d5ea5d_prompt_io.raw.md
|
|
||||||
---
|
|
||||||
|
|
||||||
## Prompt
|
|
||||||
|
|
||||||
Diagnose and fix an IB live-order failure where lazy NVDA contract
|
|
||||||
qualification raised `tractor.trionics.Lagged` after the order reached
|
|
||||||
`brokerd.ib`. Determine whether recent history changes or cancelled symbol
|
|
||||||
searches caused the stale state.
|
|
||||||
|
|
||||||
## Response summary
|
|
||||||
|
|
||||||
Traced the failure to competing consumers of a one-slot Trio broadcast, not
|
|
||||||
the recent SHM change or stale asyncio client state. Replaced broadcast
|
|
||||||
fan-out with one response/status demultiplexer, retained request-ID
|
|
||||||
correlation, handled cancellation and teardown, documented the task/channel
|
|
||||||
ownership model, warned on diagnostic metadata eviction, and added
|
|
||||||
deterministic proxy regressions.
|
|
||||||
|
|
||||||
## Files changed
|
|
||||||
|
|
||||||
- `piker/brokers/ib/api.py` - sole-reader IB proxy response routing.
|
|
||||||
- `tests/test_ib_method_proxy.py` - status, concurrency, cancellation and EOF regressions.
|
|
||||||
- `.claude/skills/run-tests/test-harness-reference.md` - proxy test mapping.
|
|
||||||
|
|
||||||
## Human edits
|
|
||||||
|
|
||||||
None - generated output follows the user's live failure diagnosis.
|
|
||||||
|
|
@ -1,66 +0,0 @@
|
||||||
---
|
|
||||||
model: openai/gpt-5.6-sol
|
|
||||||
service: opencode
|
|
||||||
timestamp: 2026-08-11T20:58:26Z
|
|
||||||
git_ref: 06d5ea5d
|
|
||||||
diff_cmd: git diff HEAD~1..HEAD
|
|
||||||
---
|
|
||||||
|
|
||||||
The user reported that certain IB order entries might have broken and
|
|
||||||
provided a live failure for a first NVDA sell order. EMS delivered the
|
|
||||||
request to `brokerd.ib`, but lazy `get_mkt_info('nvda.nasdaq')` contract
|
|
||||||
qualification failed in `MethodProxy._run_method()` with:
|
|
||||||
|
|
||||||
```text
|
|
||||||
tractor.trionics._broadcast.Lagged:
|
|
||||||
Task `piker.brokers.ib.broker.handle_order_requests` overrun and
|
|
||||||
dropped `0` values
|
|
||||||
```
|
|
||||||
|
|
||||||
The user suspected a cancelled symbol-search task might have left stale
|
|
||||||
asyncio state. Cancellation can leave an orphaned method response, but the
|
|
||||||
observed failure was stale Trio broadcast state. `open_client_proxy()`
|
|
||||||
broadcast a one-slot `LinkedTaskChannel` to an always-running IB status relay
|
|
||||||
and an idle method receiver. Status traffic advanced only the relay, so the
|
|
||||||
first method call for an uncached symbol entered an already-lagged receiver.
|
|
||||||
Orders for eagerly cached contracts bypassed this path.
|
|
||||||
|
|
||||||
The immediately preceding sparse-history commit did not modify IB order,
|
|
||||||
symbol, or proxy code; it exposed no direct dependency on this failure.
|
|
||||||
|
|
||||||
> `git diff HEAD~1..HEAD -- piker/brokers/ib/api.py`
|
|
||||||
|
|
||||||
Generated a sole-reader message demultiplexer for each IB client proxy.
|
|
||||||
`relay_client_proxy_messages()` owns every asyncio-to-Trio receive, handles
|
|
||||||
status/error traffic, and dispatches `mid`-tagged responses into per-call
|
|
||||||
`MethodProxy` wait slots. Cancelled calls remove their pending slot, causing
|
|
||||||
late responses to be logged and dropped without skewing later calls. Clean
|
|
||||||
channel EOF is accepted during normal proxy teardown.
|
|
||||||
|
|
||||||
Follow-up review restored the masked reconnect TODO and per-message case
|
|
||||||
rationale, documented the one-reader/many-writer task hierarchy and separate
|
|
||||||
per-proxy channels, and added a warning with request method metadata when the
|
|
||||||
bounded unresolved-request diagnostic table evicts its oldest entry.
|
|
||||||
|
|
||||||
> `git diff HEAD~1..HEAD -- tests/test_ib_method_proxy.py`
|
|
||||||
|
|
||||||
Generated deterministic regressions for idle status traffic before first
|
|
||||||
qualification, two concurrent calls with reverse-order responses, cancelled
|
|
||||||
calls with late responses followed by a successful call, and graceful
|
|
||||||
channel EOF. Every synchronization wait is timeout-bounded.
|
|
||||||
|
|
||||||
> `git diff HEAD~1..HEAD -- .claude/skills/run-tests/test-harness-reference.md`
|
|
||||||
|
|
||||||
Registered the deterministic IB method-proxy target and source mapping.
|
|
||||||
|
|
||||||
Verification output:
|
|
||||||
|
|
||||||
```text
|
|
||||||
........................ [100%]
|
|
||||||
25 passed, 4 warnings in 3.44s
|
|
||||||
```
|
|
||||||
|
|
||||||
The warnings are existing Tractor/Trio deprecations from the EMS test.
|
|
||||||
Adversarial review drove a clean-EOF guard and bounded polling. Final review
|
|
||||||
found no actionable issues. Live IB order validation remains pending and
|
|
||||||
requires restarting `brokerd.ib`.
|
|
||||||
|
|
@ -1,43 +0,0 @@
|
||||||
---
|
|
||||||
model: openai/gpt-5.6-sol
|
|
||||||
service: opencode
|
|
||||||
session: unavailable
|
|
||||||
timestamp: 2026-08-14T03:27:16Z
|
|
||||||
git_ref: 2aa66c2c
|
|
||||||
scope: code
|
|
||||||
substantive: true
|
|
||||||
raw_file: 20260814T032716Z_2aa66c2c_prompt_io.raw.md
|
|
||||||
---
|
|
||||||
|
|
||||||
## Prompt
|
|
||||||
|
|
||||||
Prototype chart-actor-owned gap overlays from the current backfiller tip,
|
|
||||||
with actor-local startup and UI toggling. Preserve remote annotation IPC and
|
|
||||||
make the gap-specific path strict and `msgspec`-typed.
|
|
||||||
|
|
||||||
## Response summary
|
|
||||||
|
|
||||||
Adds a chart-local controller and vectorized SHM detector, starts historical
|
|
||||||
gap overlays with display state, toggles the focused timeframe through the
|
|
||||||
existing input loop and exposes the same renderer through a strict Tractor
|
|
||||||
payload context. Keeps all legacy remote annotation commands and separates
|
|
||||||
local graphics from each remote context's teardown ownership.
|
|
||||||
|
|
||||||
## Files changed
|
|
||||||
|
|
||||||
- `piker/ui/_gaps.py` - typed messages, detection and local controller.
|
|
||||||
- `piker/ui/_remote_ctl.py` - IPC clients and chart-actor endpoints.
|
|
||||||
- `piker/ui/_display.py` - actor-local startup integration.
|
|
||||||
- `piker/ui/_interaction.py` - focused `Ctrl+G` toggle.
|
|
||||||
- `piker/ui/_widget.py` - controller reference.
|
|
||||||
- `piker/ui/_annotate.py` - safe FQME-aware repositioning.
|
|
||||||
- `piker/tsp/_annotate.py` - typed annotation-client reference.
|
|
||||||
- `piker/storage/cli.py` - renamed annotation client context.
|
|
||||||
- `tests/test_gap_overlays.py` - detector and schema regression.
|
|
||||||
- `tests/test_ldshm.py` - renamed annotation-client test seams.
|
|
||||||
- `plans/opencode/chart-local-gap-overlays.md` - architecture and landing plan.
|
|
||||||
|
|
||||||
## Human edits
|
|
||||||
|
|
||||||
None - the work remains an uncommitted disposable-worktree prototype for
|
|
||||||
human review and live chart qualification.
|
|
||||||
|
|
@ -1,72 +0,0 @@
|
||||||
---
|
|
||||||
model: openai/gpt-5.6-sol
|
|
||||||
service: opencode
|
|
||||||
timestamp: 2026-08-14T03:27:16Z
|
|
||||||
git_ref: 2aa66c2c
|
|
||||||
diff_cmd: git diff HEAD~1..HEAD
|
|
||||||
---
|
|
||||||
|
|
||||||
## Prompt
|
|
||||||
|
|
||||||
The user asked what work had been done so far, then authorized autonomous
|
|
||||||
work while AFK. The target was to scheme and prototype an actor-local gap
|
|
||||||
annotator from the `backfiller_deep_fixes` tip without mutating existing
|
|
||||||
branches. The user then clarified twice that the annotation IPC API must
|
|
||||||
remain available and should become more rigorous and `msgspec`-typed rather
|
|
||||||
than being removed.
|
|
||||||
|
|
||||||
## Generated code
|
|
||||||
|
|
||||||
> `git diff HEAD~1..HEAD -- piker/ui/_gaps.py`
|
|
||||||
|
|
||||||
Adds tagged gap request/reply structs, render-ready gap specs, vectorized
|
|
||||||
OHLCV timestamp-gap detection and chart-local overlay ownership.
|
|
||||||
|
|
||||||
> `git diff HEAD~1..HEAD -- piker/ui/_remote_ctl.py`
|
|
||||||
|
|
||||||
Adds strict Tractor gap IPC, `AnnotClient` stream mapping/locking and
|
|
||||||
owner-scoped endpoint cleanup while retaining the legacy annotation endpoint.
|
|
||||||
|
|
||||||
> `git diff HEAD~1..HEAD -- piker/ui/_display.py`
|
|
||||||
|
|
||||||
Starts the local 60-second overlay after display-state registration.
|
|
||||||
|
|
||||||
> `git diff HEAD~1..HEAD -- piker/ui/_interaction.py`
|
|
||||||
|
|
||||||
Routes `Ctrl+G` from the focused chart's existing async input loop directly
|
|
||||||
to the local controller.
|
|
||||||
|
|
||||||
> `git diff HEAD~1..HEAD -- piker/ui/_widget.py`
|
|
||||||
|
|
||||||
Stores the chart actor's local controller reference.
|
|
||||||
|
|
||||||
> `git diff HEAD~1..HEAD -- piker/ui/_annotate.py`
|
|
||||||
|
|
||||||
Keeps redraw repositioning isolated by FQME and synchronizes arrow geometry.
|
|
||||||
|
|
||||||
> `git diff HEAD~1..HEAD -- piker/tsp/_annotate.py piker/storage/cli.py`
|
|
||||||
|
|
||||||
Renames the remote annotation control type and context manager to the
|
|
||||||
client-oriented `AnnotClient` / `open_annot_client` interface.
|
|
||||||
|
|
||||||
> `git diff HEAD~1..HEAD -- tests/test_gap_overlays.py`
|
|
||||||
|
|
||||||
Adds deterministic detector, directional payload-schema, typed error and
|
|
||||||
msgpack roundtrip regressions.
|
|
||||||
|
|
||||||
> `git diff HEAD~1..HEAD -- tests/test_ldshm.py`
|
|
||||||
|
|
||||||
Updates storage CLI test seams for the renamed annotation client context.
|
|
||||||
|
|
||||||
## Generated architecture output
|
|
||||||
|
|
||||||
> `git diff HEAD~1..HEAD -- plans/opencode/chart-local-gap-overlays.md`
|
|
||||||
|
|
||||||
Documents ownership, startup, UI, strict IPC, refresh and branch landing
|
|
||||||
semantics.
|
|
||||||
|
|
||||||
## Verification output
|
|
||||||
|
|
||||||
Source resolution points to this worktree. The targeted regression passes,
|
|
||||||
Ruff reports no changed-file findings, `compileall` succeeds, `git diff
|
|
||||||
--check` succeeds and Tractor's strict gap payload decoder initializes.
|
|
||||||
|
|
@ -1,39 +0,0 @@
|
||||||
---
|
|
||||||
model: openai/gpt-5.6-sol
|
|
||||||
service: opencode
|
|
||||||
session: unavailable
|
|
||||||
timestamp: 2026-08-17T22:20:36Z
|
|
||||||
git_ref: f65df6a1
|
|
||||||
scope: code
|
|
||||||
substantive: true
|
|
||||||
raw_file: 20260817T222036Z_f65df6a1_prompt_io.raw.md
|
|
||||||
---
|
|
||||||
|
|
||||||
## Prompt
|
|
||||||
|
|
||||||
Add end-to-end coverage for chart-local gap annotations in the existing
|
|
||||||
gap-overlay worktree without disturbing concurrent manual backfiller testing
|
|
||||||
in the root checkout.
|
|
||||||
|
|
||||||
## Response summary
|
|
||||||
|
|
||||||
Adds real offscreen Qt and real Tractor actor integration coverage. The tests
|
|
||||||
drive startup registration, PyQtGraph insertion/removal, focused Ctrl-G input,
|
|
||||||
history-prepend repositioning, duplicate-FQME chart identity, typed endpoint
|
|
||||||
exchange and cancellation with stale-response recovery. Defects exposed by
|
|
||||||
those tests are fixed in manager cleanup, Qt geometry notification and PyQt6
|
|
||||||
event routing.
|
|
||||||
|
|
||||||
## Files changed
|
|
||||||
|
|
||||||
- `piker/ui/_gaps.py` - correct PyQtGraph ownership and bounds behavior.
|
|
||||||
- `piker/ui/_annotate.py` - notify Qt before reposition geometry changes.
|
|
||||||
- `piker/ui/_display.py` - expose deterministic startup registration.
|
|
||||||
- `piker/ui/_interaction.py` - focus toggles and PyQt6 event registration.
|
|
||||||
- `tests/test_gap_overlays.py` - real Qt and Tractor integration coverage.
|
|
||||||
- `plans/opencode/chart-local-gap-overlays.md` - update coverage boundaries.
|
|
||||||
- `plans/opencode/chart-local-gap-overlays.summary.md` - update test totals.
|
|
||||||
|
|
||||||
## Human edits
|
|
||||||
|
|
||||||
None - the changes remain uncommitted for human review.
|
|
||||||
|
|
@ -1,59 +0,0 @@
|
||||||
---
|
|
||||||
model: openai/gpt-5.6-sol
|
|
||||||
service: opencode
|
|
||||||
timestamp: 2026-08-17T22:20:36Z
|
|
||||||
git_ref: f65df6a1
|
|
||||||
diff_cmd: git diff f65df6a1..HEAD
|
|
||||||
---
|
|
||||||
|
|
||||||
## Prompt
|
|
||||||
|
|
||||||
The user asked whether the chart-local gap annotation feature had complete
|
|
||||||
end-to-end coverage, then requested implementation in the existing gap-overlay
|
|
||||||
worktree while manual NativeDB/backfiller qualification continued in the root
|
|
||||||
checkout. The user initially declined a tests-only Prompt-IO entry. Real Qt
|
|
||||||
and Tractor integration tests then exposed production lifecycle and PyQt6
|
|
||||||
event-routing defects, making the resulting patch substantive code work and
|
|
||||||
requiring this full provenance entry.
|
|
||||||
|
|
||||||
## Generated code
|
|
||||||
|
|
||||||
> `git diff HEAD~1..HEAD -- piker/ui/_gaps.py`
|
|
||||||
|
|
||||||
Removes manager-owned graphics through their `PlotItem`, retains owning-plot
|
|
||||||
registrations, and excludes pixel-sized gap arrows from automatic data bounds.
|
|
||||||
|
|
||||||
> `git diff HEAD~1..HEAD -- piker/ui/_annotate.py`
|
|
||||||
|
|
||||||
Moves Qt geometry-change notification ahead of rectangle and arrow mutation so
|
|
||||||
scene spatial indexing follows history-prepend repositioning.
|
|
||||||
|
|
||||||
> `git diff HEAD~1..HEAD -- piker/ui/_display.py`
|
|
||||||
|
|
||||||
Extracts `_register_gap_overlays()` as the deterministic chart startup seam
|
|
||||||
which registers display states and renders default historical gap layers.
|
|
||||||
|
|
||||||
> `git diff HEAD~1..HEAD -- piker/ui/_interaction.py`
|
|
||||||
|
|
||||||
Adds focused-chart toggle routing, updates the gap keyboard path to PyQt6 event
|
|
||||||
enums, and keeps unrelated cached chart states untouched.
|
|
||||||
|
|
||||||
> `git diff HEAD~1..HEAD -- tests/test_gap_overlays.py`
|
|
||||||
|
|
||||||
Adds offscreen real-Qt manager, startup, keyboard, cached-chart and reposition
|
|
||||||
coverage plus a real Tractor actor endpoint/client dialog with deterministic
|
|
||||||
cancellation and stale-response recovery.
|
|
||||||
|
|
||||||
## Generated architecture output
|
|
||||||
|
|
||||||
> `git diff HEAD~1..HEAD -- plans/opencode/chart-local-gap-overlays.md plans/opencode/chart-local-gap-overlays.summary.md`
|
|
||||||
|
|
||||||
Records the automated integration boundary and remaining broker-backed manual
|
|
||||||
qualification requirements.
|
|
||||||
|
|
||||||
## Verification output
|
|
||||||
|
|
||||||
The source-isolated non-actor and related suites pass 24 tests with one actor
|
|
||||||
case deselected. The isolated actor case passes with one upstream Tractor/Trio
|
|
||||||
deprecation warning. Ruff, compileall, import resolution and whitespace checks
|
|
||||||
pass. Independent review reports no remaining P1/P2 findings.
|
|
||||||
|
|
@ -1,44 +0,0 @@
|
||||||
---
|
|
||||||
model: openai/gpt-5.6-sol
|
|
||||||
service: opencode
|
|
||||||
session: unavailable
|
|
||||||
timestamp: 2026-08-31T00:57:12Z
|
|
||||||
git_ref: 09ddcf50
|
|
||||||
scope: tests
|
|
||||||
substantive: true
|
|
||||||
raw_file: 20260831T005712Z_09ddcf50_prompt_io.raw.md
|
|
||||||
---
|
|
||||||
|
|
||||||
## Prompt
|
|
||||||
|
|
||||||
Deeply evaluate Piker's lacking suites and build a comprehensive plan for
|
|
||||||
non-mocked, human-driven E2E coverage, beginning with the pytest-qt plan on
|
|
||||||
`chart_local_gapper`. Work in `/open-wkt`, build the first feasible GUI test
|
|
||||||
slice, add minimal adjacent CLI and Qt guide docs, keep the `/run-tests`
|
|
||||||
reference current, and stop before the stated Eastern deadline.
|
|
||||||
|
|
||||||
## Response summary
|
|
||||||
|
|
||||||
Audits the existing suite and human-facing surfaces, creates a risk-ranked
|
|
||||||
cross-interface E2E plan, activates pytest-qt, migrates the real-Qt gap suite
|
|
||||||
to pytest-qt widget ownership, and records verified commands and minimal user
|
|
||||||
guides. Full `MainWindow` E2E remains deferred behind safe shutdown, guest
|
|
||||||
outcome, symbol-session ownership, and deterministic provider seams.
|
|
||||||
|
|
||||||
## Files changed
|
|
||||||
|
|
||||||
- `pyproject.toml`, `uv.lock`, `pytest.ini` - activate pytest-qt config.
|
|
||||||
- `tests/conftest.py` - establish the Qt process and settings contract.
|
|
||||||
- `tests/test_gap_overlays.py` - migrate real widgets to `qtbot` ownership.
|
|
||||||
- `piker/cli/README.rst` - add the minimal command-line guide.
|
|
||||||
- `piker/ui/README.rst` - add the minimal chart UI guide.
|
|
||||||
- `plans/opencode/human-facing-e2e-coverage.md` - persist the suite plan.
|
|
||||||
- `.claude/skills/run-tests/test-harness-reference.md` - record verified
|
|
||||||
test commands and boundaries.
|
|
||||||
|
|
||||||
## Human edits
|
|
||||||
|
|
||||||
The human requires isolated worktree execution, adjacent guide-style docs,
|
|
||||||
continuous `/run-tests` reference maintenance, non-mocked Qt interactions,
|
|
||||||
and a hard time cutoff. These constraints materially determine the patch
|
|
||||||
scope and defer unsafe full-window work.
|
|
||||||
|
|
@ -1,45 +0,0 @@
|
||||||
---
|
|
||||||
model: openai/gpt-5.6-sol
|
|
||||||
service: opencode
|
|
||||||
timestamp: 2026-08-31T00:57:12Z
|
|
||||||
git_ref: 09ddcf50
|
|
||||||
diff_cmd: git diff HEAD
|
|
||||||
---
|
|
||||||
|
|
||||||
## Generated changes
|
|
||||||
|
|
||||||
> `git diff HEAD -- pyproject.toml pytest.ini uv.lock`
|
|
||||||
|
|
||||||
Activates pytest-qt with PyQt6 through the repository's authoritative
|
|
||||||
pytest configuration and locks pytest-qt 4.5.0.
|
|
||||||
|
|
||||||
> `git diff HEAD -- tests/conftest.py tests/test_gap_overlays.py`
|
|
||||||
|
|
||||||
Selects the offscreen PyQt6 test process before Qt imports, isolates Qt
|
|
||||||
configuration, migrates real chart-gap widgets to pytest-qt ownership,
|
|
||||||
and removes the conflicting manual widget teardown path.
|
|
||||||
|
|
||||||
> `git diff HEAD -- piker/cli/README.rst piker/ui/README.rst`
|
|
||||||
|
|
||||||
Adds minimal adjacent guides for the installed command and Qt chart
|
|
||||||
interfaces without freezing volatile subsystem details.
|
|
||||||
|
|
||||||
> `git diff HEAD -- plans/opencode/human-facing-e2e-coverage.md`
|
|
||||||
|
|
||||||
Records the evidence-based test-suite audit and phased human-facing E2E
|
|
||||||
strategy, distinguishing component, application, system, and live
|
|
||||||
qualification boundaries.
|
|
||||||
|
|
||||||
> `git diff HEAD -- .claude/skills/run-tests/test-harness-reference.md`
|
|
||||||
|
|
||||||
Records the verified environment, commands, Qt ownership rules, current
|
|
||||||
tier boundaries, and test outcomes.
|
|
||||||
|
|
||||||
## Verification
|
|
||||||
|
|
||||||
- Local package and pytest-qt 4.5.0 import check passes.
|
|
||||||
- Nine gap-overlay tests collect.
|
|
||||||
- The targeted file passes: 9 tests, one upstream Tractor warning.
|
|
||||||
- A duplicated same-process run passes: 18 tests, two equivalent
|
|
||||||
upstream Tractor warnings.
|
|
||||||
- `git diff --check` passes.
|
|
||||||
|
|
@ -1,64 +0,0 @@
|
||||||
---
|
|
||||||
model: openai/gpt-5.6-sol
|
|
||||||
service: opencode
|
|
||||||
session: d3e773b1-63ab-44da-a30f-33bc8a05e778
|
|
||||||
timestamp: 2026-08-31T21:56:40Z
|
|
||||||
git_ref: 233fa590
|
|
||||||
scope: code
|
|
||||||
substantive: true
|
|
||||||
raw_file: 20260831T215640Z_233fa590_prompt_io.raw.md
|
|
||||||
---
|
|
||||||
|
|
||||||
## Prompt
|
|
||||||
|
|
||||||
Continue Phase 1 of the human-facing E2E foundation from the existing
|
|
||||||
worktree state: establish robust pytest-qt isolation and leak proofs,
|
|
||||||
use real QtBot Ctrl-G input, replace arbitrary actor sleeps with typed
|
|
||||||
deterministic synchronization, keep the test-harness reference current,
|
|
||||||
and verify the work end to end. Preserve the user's staged snapshot,
|
|
||||||
with permission to unstage if useful. After implementation, unstage
|
|
||||||
the snapshot and prepare a complete multi-commit plan.
|
|
||||||
|
|
||||||
## Response summary
|
|
||||||
|
|
||||||
Establishes import-time XDG isolation with exact pytest cleanup, adds
|
|
||||||
same-process QApplication and mutable-state restoration proofs, and
|
|
||||||
migrates Ctrl-G to real QtBot input. An explicit `--headless` option
|
|
||||||
forces offscreen execution before imports even inside the Wayland
|
|
||||||
development shell. The real input sequence exposed and fixed
|
|
||||||
modifier-only event handling in the production keyboard path. The real
|
|
||||||
Tractor regression now uses a typed receipt and explicit cancellation
|
|
||||||
barrier instead of timing and logger instrumentation.
|
|
||||||
|
|
||||||
## Files changed
|
|
||||||
|
|
||||||
- `tests/conftest.py` - own and restore process XDG config roots before
|
|
||||||
importing Piker or Qt.
|
|
||||||
- `tests/ui/conftest.py` - guard and restore mutable Qt, PyQtGraph,
|
|
||||||
QSettings, filesystem, and Piker config state after each UI test.
|
|
||||||
- `tests/ui/test_harness.py` - prove shared QApplication reuse,
|
|
||||||
isolation, sentinel preservation, and leak-free teardown.
|
|
||||||
- `piker/ui/_interaction.py` - ignore modifier-only chord events before
|
|
||||||
action dispatch.
|
|
||||||
- `tests/test_gap_overlays.py` - use real QtBot Ctrl-G and a typed,
|
|
||||||
deterministic real-actor cancellation barrier.
|
|
||||||
- `.claude/skills/run-tests/test-harness-reference.md` - document the
|
|
||||||
verified fixture contract, commands, and results.
|
|
||||||
|
|
||||||
## Human edits
|
|
||||||
|
|
||||||
The human directed continuation of the existing Phase 1 scope,
|
|
||||||
authorized `nix develop` for runtime verification, requested Prompt-IO
|
|
||||||
capture, and stated that the current staged snapshot may be unstaged if
|
|
||||||
needed. After an unannounced test run opened real Wayland windows, the
|
|
||||||
human identified the problem and required an explicit headless mode,
|
|
||||||
while preserving separately authorized real-window coverage. This
|
|
||||||
material correction added `--headless`, offscreen platform proof, and
|
|
||||||
the rule that real-compositor runs must be announced and explicitly
|
|
||||||
authorized. The staged snapshot was preserved; subsequent fixes and
|
|
||||||
these provenance files initially remained unstaged. The human later
|
|
||||||
explicitly requested a mixed reset before commit-plan generation.
|
|
||||||
During review of the first staged boundary, the human required a TODO
|
|
||||||
for a public config-path API and detailed rationale around each UI
|
|
||||||
teardown check. The agent applied both changes and added authorized
|
|
||||||
responses to the persisted local Tuicr session.
|
|
||||||
|
|
@ -1,52 +0,0 @@
|
||||||
---
|
|
||||||
model: openai/gpt-5.6-sol
|
|
||||||
service: opencode
|
|
||||||
timestamp: 2026-08-31T21:56:40Z
|
|
||||||
git_ref: 233fa590
|
|
||||||
diff_cmd: git diff HEAD
|
|
||||||
---
|
|
||||||
|
|
||||||
## Generated changes
|
|
||||||
|
|
||||||
> `git diff HEAD -- tests/conftest.py tests/ui/conftest.py tests/ui/test_harness.py`
|
|
||||||
|
|
||||||
Moves XDG user and system config isolation ahead of Piker and Qt
|
|
||||||
imports, guarantees process-environment restoration through pytest
|
|
||||||
cleanup, and adds repeated-session proofs for one shared
|
|
||||||
`QApplication`. The function-scoped UI guard restores QSettings,
|
|
||||||
Piker config paths, PyQtGraph options and view registries, Qt window
|
|
||||||
state, and exact test-owned files while preserving process sentinels.
|
|
||||||
An early `--headless` option force-selects `offscreen` even when the
|
|
||||||
development shell exports Wayland, and the test asserts the effective
|
|
||||||
Qt platform.
|
|
||||||
|
|
||||||
> `git diff HEAD -- piker/ui/_interaction.py tests/test_gap_overlays.py`
|
|
||||||
|
|
||||||
Routes Ctrl-G through a shown and focused real widget with
|
|
||||||
`QtBot.keyPress()`. The production input handler now ignores the
|
|
||||||
modifier-only events emitted by real key chords. Replaces a timed
|
|
||||||
Tractor cancellation window and patched logger with a typed stream
|
|
||||||
receipt, explicit task-completion event, and correlated stale-response
|
|
||||||
proof across a real child actor.
|
|
||||||
|
|
||||||
> `git diff HEAD -- .claude/skills/run-tests/test-harness-reference.md`
|
|
||||||
|
|
||||||
Records the verified early-XDG lifecycle, same-process UI isolation
|
|
||||||
contract, leak checks, targeted commands, layout, and current results.
|
|
||||||
|
|
||||||
## Verification
|
|
||||||
|
|
||||||
- Local package and pytest-qt 4.5.0 resolve in the approved
|
|
||||||
`nix develop` environment.
|
|
||||||
- The combined UI and gap-overlay scope collects 11 tests.
|
|
||||||
- Both UI isolation tests pass; a duplicated same-process run reports
|
|
||||||
six passing cases.
|
|
||||||
- The real QtBot Ctrl-G test passes after exercising Qt's standalone
|
|
||||||
Control event before G.
|
|
||||||
- The real Tractor actor test passes with no arbitrary sleep or
|
|
||||||
monkeypatched synchronization.
|
|
||||||
- The combined target passes: 11 tests and one upstream Tractor
|
|
||||||
`trio.Event.__bool__` deprecation warning.
|
|
||||||
- The final combined run passes with `--headless`, and the harness
|
|
||||||
proves `QApplication.platformName()` is `offscreen`.
|
|
||||||
- Python static compilation and `git diff --check` pass.
|
|
||||||
|
|
@ -1,59 +0,0 @@
|
||||||
---
|
|
||||||
model: openai/gpt-5.6-sol
|
|
||||||
service: opencode
|
|
||||||
session: ses_faae5c497ffeS0ofaTEfbRo2LP
|
|
||||||
timestamp: 2026-09-03T20:54:04Z
|
|
||||||
git_ref: aadfd1cf
|
|
||||||
scope: code
|
|
||||||
substantive: true
|
|
||||||
raw_file: 20260903T205404Z_aadfd1cf_prompt_io.raw.md
|
|
||||||
---
|
|
||||||
|
|
||||||
## Prompt
|
|
||||||
|
|
||||||
Continue from the completed replay handoff when next steps are clear.
|
|
||||||
Honor the prior decision to park replay and begin the live-backend-first
|
|
||||||
chart E2E roadmap with the Phase A Qt/Trio lifecycle seam. First perform
|
|
||||||
the approved exhaustive local scan, then create
|
|
||||||
`wkt/live_chart_qtractor` from exact Phase 1 commit `aadfd1cf` and
|
|
||||||
implement nonblocking startup, structured shutdown, observable readiness
|
|
||||||
and completion, and provider-independent lifecycle coverage without new
|
|
||||||
interlayer mocks.
|
|
||||||
|
|
||||||
## Response summary
|
|
||||||
|
|
||||||
Creates the isolated worktree after classifying two stale historical
|
|
||||||
lifecycle experiments as related but not reusable. Extracts
|
|
||||||
`start_qtractor()` and `QtractorSession`, replaces process-wide SIGINT on
|
|
||||||
window close with owned Trio cancellation, publishes application
|
|
||||||
readiness at the full `_async_main()` startup boundary, and preserves
|
|
||||||
`run_qtractor()` as the blocking Qt-loop owner which unwraps the guest
|
|
||||||
outcome. A headless regression proves two sequential real Tractor
|
|
||||||
runtimes start and stop cleanly under one pytest-owned Qt application.
|
|
||||||
|
|
||||||
## Files changed
|
|
||||||
|
|
||||||
- `piker/ui/_exec.py` - add nonblocking session startup, lifecycle
|
|
||||||
signals, owned cancellation, outcome capture, Qt cleanup, and the
|
|
||||||
blocking CLI adapter.
|
|
||||||
- `piker/ui/_window.py` - inject structured shutdown and remove normal
|
|
||||||
window-close SIGINT while cleaning the global zoom filter.
|
|
||||||
- `piker/ui/_app.py` - publish readiness after all application startup
|
|
||||||
scopes are live.
|
|
||||||
- `tests/ui/test_qtractor.py` - prove repeated real-Tractor lifecycle
|
|
||||||
startup and close under pytest-qt.
|
|
||||||
|
|
||||||
## Human edits
|
|
||||||
|
|
||||||
The human chose exhaustive local discovery specifically to catch prior
|
|
||||||
Qt/Trio experiments, confirmed the replay branch had been pushed to
|
|
||||||
Gitea for backup, and directed continuation without another planning
|
|
||||||
pause. The inherited human-approved roadmap parks replay, prioritizes a
|
|
||||||
real Kraken chart, forbids additional interlayer mocks without a concrete
|
|
||||||
regression, and fixes `aadfd1cf` as this worktree's base. The human also
|
|
||||||
explicitly authorized the focused headless test through `nix develop`;
|
|
||||||
no real-compositor run was authorized or performed. During final review,
|
|
||||||
the human corrected nonconforming boolean layout, requested local type
|
|
||||||
annotations wherever helper return types were not obvious at the binding,
|
|
||||||
and replaced silent Qt disconnect suppression with Piker-style exception
|
|
||||||
logging.
|
|
||||||
|
|
@ -1,59 +0,0 @@
|
||||||
---
|
|
||||||
model: openai/gpt-5.6-sol
|
|
||||||
service: opencode
|
|
||||||
timestamp: 2026-09-03T20:54:04Z
|
|
||||||
git_ref: aadfd1cf
|
|
||||||
diff_cmd: git diff HEAD
|
|
||||||
---
|
|
||||||
|
|
||||||
## Generated changes
|
|
||||||
|
|
||||||
> `git diff HEAD -- piker/ui/_exec.py piker/ui/_window.py`
|
|
||||||
|
|
||||||
Extracts nonblocking `start_qtractor()` from the blocking CLI adapter.
|
|
||||||
The returned `QtractorSession` exposes the production window and central
|
|
||||||
widget, the Trio token and cancellation scope, readiness and completion
|
|
||||||
Qt signals, the final `outcome.Outcome`, Qt-loop ownership, and an
|
|
||||||
idempotent structured shutdown request. Caller-owned Qt application
|
|
||||||
state and installed callbacks are restored when the guest completes.
|
|
||||||
`MainWindow.closeEvent()` retains geometry persistence but delegates
|
|
||||||
runtime teardown through the injected callback instead of sending
|
|
||||||
process-wide SIGINT.
|
|
||||||
|
|
||||||
> `git diff HEAD -- piker/ui/_app.py`
|
|
||||||
|
|
||||||
Publishes application readiness only after initial symbol loading,
|
|
||||||
order-mode startup, search registration, provider-search task startup,
|
|
||||||
input handler entry, and startup-status removal.
|
|
||||||
|
|
||||||
> `git diff HEAD -- tests/ui/test_qtractor.py`
|
|
||||||
|
|
||||||
Adds a provider-independent lifecycle regression which runs two real
|
|
||||||
Tractor root runtimes in sequence on pytest's unique registry. Real
|
|
||||||
window-close events drive structured cancellation while signal, outcome,
|
|
||||||
task-finalization, global-window, runtime, and shared-QApplication
|
|
||||||
assertions prove restartable teardown without an interlayer fake.
|
|
||||||
|
|
||||||
Human review then brought the generated Python into project style:
|
|
||||||
boolean connectives use dedicated vertical lines, opaque helper returns
|
|
||||||
and control-flow targets carry local annotations, and Qt disconnect
|
|
||||||
failures are logged instead of silently suppressed.
|
|
||||||
|
|
||||||
## Verification
|
|
||||||
|
|
||||||
- Ruff passes for all four changed Python files.
|
|
||||||
- Python static compilation and `git diff --check` pass.
|
|
||||||
- The first focused run exposed the test widget's missing production
|
|
||||||
`on_win_resize()` contract; the narrow test widget was corrected.
|
|
||||||
- The focused lifecycle regression passes with two sequential real
|
|
||||||
Tractor sessions.
|
|
||||||
- The combined UI harness and lifecycle run passes: 3 tests and two
|
|
||||||
upstream Tractor `Registrar.uid` deprecation warnings.
|
|
||||||
- A post-pass attempt to disconnect a pre-existing Qt signal proxy
|
|
||||||
segfaulted during PyQt teardown and was fully reverted; it is not part
|
|
||||||
of this patch. The restored lifecycle regression passes again.
|
|
||||||
- All automated Qt execution used `--headless` and the offscreen
|
|
||||||
platform.
|
|
||||||
- The approved `nix develop` shell hook unexpectedly provisioned the
|
|
||||||
ignored worktree-local `py313/` environment; no tracked dependency or
|
|
||||||
lock files changed.
|
|
||||||
|
|
@ -0,0 +1,34 @@
|
||||||
|
---
|
||||||
|
model: openai/gpt-5.6-sol
|
||||||
|
service: opencode
|
||||||
|
session: unavailable
|
||||||
|
timestamp: 2026-09-07T21:40:00Z
|
||||||
|
git_ref: 9115d24
|
||||||
|
scope: config
|
||||||
|
substantive: true
|
||||||
|
raw_file: 20260907T214000Z_9115d24_prompt_io.raw.md
|
||||||
|
---
|
||||||
|
|
||||||
|
## Prompt
|
||||||
|
|
||||||
|
Deploy the provider-neutral `.agents` skill tree for Codex first and
|
||||||
|
then migrate Piker's workflow state without losing archived helpers.
|
||||||
|
|
||||||
|
## Response summary
|
||||||
|
|
||||||
|
Deployed 21 ignored `.agents/skills` links, copied 132 legacy runtime
|
||||||
|
files into `.ai/state`, selected the neutral backend, and preserved the
|
||||||
|
original archive and staged `ruff.toml` change.
|
||||||
|
|
||||||
|
## Files changed
|
||||||
|
|
||||||
|
- `.gitignore` - ignore shared links and generated neutral state.
|
||||||
|
- `.ai/workflow-state.json` - select the neutral backend.
|
||||||
|
- `.ai/commit-msg/style-guide-reference.md` - port commit guidance.
|
||||||
|
- `.ai/run-tests/test-harness-reference.md` - port test guidance.
|
||||||
|
|
||||||
|
## Human edits
|
||||||
|
|
||||||
|
The human prioritized immediate Codex deployment and directed helper
|
||||||
|
archives to migrate as opaque runtime data instead of blocking the
|
||||||
|
operation. No direct source-line edits were made by the human.
|
||||||
|
|
@ -0,0 +1,15 @@
|
||||||
|
---
|
||||||
|
model: openai/gpt-5.6-sol
|
||||||
|
service: opencode
|
||||||
|
timestamp: 2026-09-07T21:40:00Z
|
||||||
|
git_ref: 9115d24
|
||||||
|
diff_cmd: git diff HEAD~1..HEAD
|
||||||
|
---
|
||||||
|
|
||||||
|
Deploy all shared `ai.skillz` skills through `.agents/skills` for
|
||||||
|
Codex, then migrate Piker's generated workflow state from the legacy
|
||||||
|
Claude layout to provider-neutral `.ai/state` storage.
|
||||||
|
|
||||||
|
Preserve every legacy source and the existing staged `ruff.toml`
|
||||||
|
change. Commit only the neutral backend selection, repository guidance,
|
||||||
|
ignore rules, and this provenance record.
|
||||||
|
|
@ -0,0 +1,37 @@
|
||||||
|
---
|
||||||
|
model: openai/gpt-5.6-sol
|
||||||
|
service: opencode
|
||||||
|
session: unavailable
|
||||||
|
timestamp: 2026-09-08T04:31:34Z
|
||||||
|
git_ref: f148fbcc
|
||||||
|
scope: config
|
||||||
|
substantive: true
|
||||||
|
raw_file: 20260908T043134Z_f148fbcc_prompt_io.raw.md
|
||||||
|
---
|
||||||
|
|
||||||
|
## Prompt
|
||||||
|
|
||||||
|
Audit tracked legacy skill files under `.claude/`, then migrate Piker's
|
||||||
|
repository-specific skills into the provider-neutral discovery tree.
|
||||||
|
Keep Claude compatibility and remove stale Claude-local configuration.
|
||||||
|
|
||||||
|
## Response summary
|
||||||
|
|
||||||
|
Moves four Piker-specific skill packages to `.agents/skills/`, retains
|
||||||
|
Claude discovery through relative adapter links, and drops two stale
|
||||||
|
tracked Claude-local files.
|
||||||
|
|
||||||
|
## Files changed
|
||||||
|
|
||||||
|
- `.agents/skills/piker-*/` - provider-neutral Piker skill sources.
|
||||||
|
- `.claude/skills/piker-*` - relative Claude compatibility links.
|
||||||
|
- `.claude/settings.local.json` - remove tracked local permissions.
|
||||||
|
- `.claude/skills/commit-msg/style-guide-reference.md` - remove the
|
||||||
|
superseded legacy copy now represented under `.ai/commit-msg/`.
|
||||||
|
|
||||||
|
## Human edits
|
||||||
|
|
||||||
|
The human identified that repository-specific skills were not migrated
|
||||||
|
by the shared `ai.skillz` deployment, selected `.agents/skills/` as the
|
||||||
|
neutral source, and requested that the migration land in PR 93 before
|
||||||
|
following up on the generic migration tooling.
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue