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:
Codex
2026-06-16 21:44:03 +02:00
parent 2f5ce55967
commit 0f3d7650c3
4 changed files with 233 additions and 4 deletions

View 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.