VIOLET V3.4d: launcher OB-persistence + boost/beta prior; OB-feed/HZ-bridge/coordination doc
Launcher shadow path now keeps the persistent state BLUE keeps across scans (faithful, not per-scan single-shot): ONE OBFeatureEngine wired lazily on first assets and kept for the service lifetime, reading BLUE's EXTANT published OBF feed via HZOBProvider (read-only HZ entry-listener cache — NO new OB storage; provider is the swap seam for a future direct BingX/3rd-party OB stream); per-scan ob_bar_idx into step_live/get_market; and prior_boost_beta carried across scans (stale exf keeps the prior). shadow_decision_step threads ob_engine + bar_idx + prior into source_live_blue_sizing_factors; build_shadow_live_source seeds the state + a default ob_engine_factory (injectable for tests). TODO_HZBRIDGE markers added at all 3 VIOLET->Hazelcast touch points: per operator the upcoming dolphinng5_predict/hzbridge must become the sanctioned HZ connection (silent client-death / lockup / dropout mitigation) — refactor ASAP once it ships. Doc VIOLET_OB_FEED_AND_AGENT_COORDINATION.md: OB-feed sourcing doctrine, HZ-bridge TODO, and the multi-agent worktree + doctrine/release/status scheme (prompted by the shared-index incidents where agents' staged files cross-contaminate commits). 6 launcher tests (+wired-once/bar_idx-increments, +prior-carries). violet-only; partial commit (only my 4 paths) to avoid sweeping a concurrent agent's staged files. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
87
prod/docs/VIOLET_OB_FEED_AND_AGENT_COORDINATION.md
Normal file
87
prod/docs/VIOLET_OB_FEED_AND_AGENT_COORDINATION.md
Normal file
@@ -0,0 +1,87 @@
|
||||
# VIOLET — OB feed sourcing, HZ Bridge, and multi-agent coordination
|
||||
|
||||
Date: 2026-06-16. Operator-driven decisions captured during the V3.4c/d review.
|
||||
|
||||
## 1. OB feed sourcing doctrine
|
||||
|
||||
**VIOLET consumes BLUE's EXTANT published OBF feed — it does NOT store OB data.**
|
||||
|
||||
- `live_blue_source._source_ob_market` and `shadow_live_factors._default_ob_engine_factory`
|
||||
use BLUE's OWN `HZOBProvider` (`nautilus_dolphin/.../hz_ob_provider.py`) + `OBFeatureEngine`,
|
||||
wired exactly as BLUE's `_wire_obf` (nautilus_event_trader.py:4967-4980).
|
||||
- `HZOBProvider` is a **read-only Hazelcast entry-listener cache**: it subscribes to the
|
||||
`asset_*_ob` shards BLUE already publishes and keeps only the latest snapshot per asset in
|
||||
memory. Verified: **no writes, no persistence, no new exchange WS**. OB raw data is the
|
||||
heaviest disk load in the system; VIOLET adds ZERO to it by reading the published shards.
|
||||
- `OBFeatureEngine` keeps an in-memory lookback window only (no disk). The launcher holds
|
||||
ONE engine for the service lifetime (`shadow["ob_engine"]`), stepping a per-scan `bar_idx`,
|
||||
so OB accumulation matches BLUE across scans (a fresh per-scan engine has no history).
|
||||
|
||||
**Swap seam for future multi-exchange OB.** The `OBProvider` behind `OBFeatureEngine` is the
|
||||
single swap point. To run a SEPARATE OB stream (e.g. BingX testnet / a third-party venue,
|
||||
which has genuinely different OB than the Binance reference), replace `HZOBProvider` with a
|
||||
direct-WS provider feeding the SAME `OBFeatureEngine` — no other code changes. This is
|
||||
specced/reasonable and the design already accommodates it.
|
||||
|
||||
**Cadence compliance (VIOLET's whole point — faster-than-OBF, event-driven).** Two regimes:
|
||||
- NOW (shadow / parity): match BLUE, which samples OB at the OBF cadence (~1s native). You
|
||||
cannot be *more* faithful than BLUE's own OB sampling, so reading the published shards is
|
||||
correct for parity. `HZOBProvider` is itself a PUSH entry-listener (not polling), which is
|
||||
already event-driven and aligned with the reactor model.
|
||||
- LATER (V5/V6 sub-second): when VIOLET wants OB faster than BLUE's OBF, it swaps in a direct
|
||||
WS OB provider (the seam above) on the reactor clock. That is a DELIBERATE VIOLET feature /
|
||||
divergence, gated separately — not a parity break of the current shadow stage.
|
||||
|
||||
## 2. HZ Bridge — TODO_HZBRIDGE (refactor ASAP when it ships)
|
||||
|
||||
An upcoming **Hazelcast Bridge** (`dolphinng5_predict/hzbridge`) will be the sanctioned way to
|
||||
connect to Hazelcast, mitigating the silent client-death / lockup / dropout class (see the
|
||||
`hz_client_death_investigation` memory + black-box dump work in BLUE). **All VIOLET raw
|
||||
`HazelcastClient` / `HZOBProvider` connections must route through the bridge once available.**
|
||||
In-code `TODO_HZBRIDGE` markers flag the three touch points:
|
||||
1. `shadow_live_factors.build_shadow_live_source` — the launcher's `client_factory`.
|
||||
2. `shadow_live_factors._default_ob_engine_factory` — `HZOBProvider`'s own connection.
|
||||
3. `live_blue_source` HZ_CLUSTER/HZ_HOST + `_source_ob_market` provider construction; the
|
||||
live-HZ smoke test.
|
||||
Refactor priority: ASAP after the bridge lands (or accelerate the bridge). Until then, VIOLET
|
||||
uses raw clients, accepting the known fragility (it is DARK, so a dropout loses shadow rows,
|
||||
never orders).
|
||||
|
||||
## 3. Multi-agent coordination (worktrees + doctrine/status)
|
||||
|
||||
Agents on this box: **Claude, CommandCode, Codex, Crush.** The 2026-06-16 incident — one
|
||||
agent's staged files swept into another's commit (a doc landed in the forbidden `dita_v2/`) —
|
||||
was caused by **multiple agents sharing ONE working tree + ONE `.git/index`**. `index.lock`
|
||||
serializes plumbing ops; it does NOT isolate logical work, and `git commit` commits the WHOLE
|
||||
index regardless of which files you `git add`. Careful add does not protect you — only
|
||||
isolation does.
|
||||
|
||||
**Target model (industry standard):**
|
||||
- **One `git worktree` per agent** over the shared object DB: each gets its own working dir +
|
||||
index + HEAD, so collisions are impossible.
|
||||
```
|
||||
git worktree add ../vp-claude -b agent/claude
|
||||
git worktree add ../vp-commandcode -b agent/commandcode
|
||||
git worktree add ../vp-codex -b agent/codex
|
||||
git worktree add ../vp-crush -b agent/crush
|
||||
```
|
||||
Each agent works ONLY in its own tree. (This is what the Claude Code harness's
|
||||
`isolation: "worktree"` already does for subagents.)
|
||||
- **Branch-per-agent → integrate via Gitea PRs.** Push agent branches to the Gitea remote
|
||||
(`hjnormey/siloqy`); merge to a canonical branch via review. `main`/`release` protected.
|
||||
- **Doctrine / release = a protected canonical branch + tags.** The LIVE working tree (the one
|
||||
BLUE/PINK actually run from) tracks the canonical branch only; tag doctrinal snapshots
|
||||
(`git tag release-YYYYMMDD`). Anything not on the canonical branch is WIP by definition —
|
||||
that answers "which files are doctrinal vs in-work".
|
||||
- **Agent work-status board = Gitea branch + PR list.** Each open PR / agent branch (with its
|
||||
ahead/behind + last-commit author) IS the status dashboard. Optionally a top-level
|
||||
`AGENT_WORKLOG.md` or the existing `.beads/` tracker for human-readable status.
|
||||
|
||||
**Critical secondary point:** this working tree is ALSO the live deployment path (BLUE runs
|
||||
`prod/nautilus_event_trader.py` from here). Agents editing it directly means WIP code sits in
|
||||
the live path — a stray restart could load half-finished edits. Worktrees fix this too:
|
||||
agents edit isolated trees; deployment becomes an explicit checkout/merge of the canonical
|
||||
branch onto the live tree.
|
||||
|
||||
Setup is operator-gated (it reorganizes how all four agents work + touches the live tree), so
|
||||
it is documented here for greenlight rather than executed unilaterally.
|
||||
Reference in New Issue
Block a user