VIBRISS_PARAMETER_GOVERNANCE_SPEC §10.6: ob_cascade.count_threshold (currently cascade_count>0 = ONE asset widens every TP x1.40), tp_widen_factor, withdrawal_velocity_threshold as governance candidates; adaptive/Dynamic-TP threshold marked fit for VIBRISS governance; TP_FLOOR joint-policy reward requirement. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
6.8 KiB
Critical Violet Design: BLUE hydration bug
Date: 2026-06-11
Summary
This incident is a BLUE hydration / restore bug on the XTZUSDT short trade 863c21da.
The important facts are:
- The XTZ trade was real and opened at
2026-06-11 17:22:12.678265+00:00. - The trade did not close via TP, SL, or MAX_HOLD before hydration.
- The restore path later rebuilt the open slot from
position_stateandtrade_reconstruction. - The restored state had a chain-token mismatch, but the engine continued with the derived token instead of hard-failing.
- A later hydrate-time stop was recorded at
2026-06-11 18:35:52.789008+00:00withSTOP_LOSS. - The ledger shows the next trade was admitted while XTZ was still officially open, which violates the single-slot invariant.
Trade identity
- trade_id:
863c21da - asset:
XTZUSDT - side:
SHORT - entry price:
0.2276 - entry notional:
56484.4305702418 - leverage:
6.374647927191287 - entry bar:
238 - tp_base_pct:
0.002 - tp_effective_pct:
0.0019999655500463724
Ledger evidence
Open record
dolphin.trade_reconstruction contains the canonical open record:
- ts:
2026-06-11 17:22:12.911989 - event_type:
OPEN - event_id:
863c21da:open - chain_token:
26852fa25fb5cdaa3b4c354d5e3eea93e27bce0ebdcd0da896d4f981642eeeb2
The payload confirms:
entry_ts = 1781198532678265entry_bar = 238retraction_legs = 0realized_pnl_legs_total = 0.0chain_mode = LIVEchain_kind = ROOT
No close before hydrate
dolphin.trade_exit_legs has no rows for 863c21da.
dolphin.trade_events also has no close row for 863c21da.
So there is no official TP, SL, or MAX_HOLD exit recorded before the restore/hydration event.
Decision tape before hydrate
dolphin.v7_decision_events shows the trade was live and being evaluated:
2026-06-11 17:22:13.274556HOLD2026-06-11 17:22:23.124863HOLD2026-06-11 17:22:45.232894HOLD2026-06-11 17:23:28.274004HOLD2026-06-11 17:24:43.182413RETRACT / V7_RISK_DOMINANT
The best favorable excursion in the pre-hydrate tape was only about +0.065905094%, which is far below the fixed TP threshold.
Restore / hydration behavior
At restore time the engine logged:
chain token mismatch on restore: trade=863c21da stored=26852fa25fb5 derived=98875e225e9e — continuing with derived tokenposition_state RESTORED: XTZUSDT SHORT entry=0.2276 notional=56484 bars_held≈0 trade=863c21da
The restore path in prod/nautilus_event_trader.py does the following:
- reads
position_state - reconstructs
restored_entry_bar = max(0, self.bar_idx - stored_bars) - loads reconstruction data from
dolphin.trade_reconstruction - rebuilds chain state from the persisted payload
- if the stored chain token differs from the derived token, it logs the mismatch and continues with the derived token
Relevant code:
_chain_state_from_reconstruction(...)around lines3315-3348- restore from
position_statearound lines1944-2058
This is a validator, not a hard guardrail.
Single-slot violation
The next distinct open trade in the reconstruction ledger is:
- ts:
2026-06-11 17:50:50.420620 - trade_id:
43494ade - asset:
TRXUSDT - side:
SHORT
That means the system admitted a new trade while XTZ was still officially open in the ledger.
On a single-slot engine, that should not happen.
What would have happened without hydration
This is the conservative conclusion from the tape:
- The trade did not hit TP on the observed pre-hydrate tape.
- The trade did not have an official close row before hydration.
- The tape does not contain a clean uninterrupted decision path beyond the first pre-hydrate window.
The best-supported natural outcome from the observed tape is the live RETRACT state at 2026-06-11 17:24:43.182413, where the engine still considered the slot active and the trade had only reached bars_held = 14.
At that point:
current_price = 0.22765000000000002pnl_pct = -0.021968365reason = V7_RISK_DOMINANT
If that retract state had been executed immediately, the estimated trade PnL would have been:
-12.4087058758423USDT on the recorded notional- trade ROI:
-0.021968365%
The max-hold clock also would have forced a decision long before the 18:35 restore:
- trade-specific
market_state_max_hold_bars = 102 - live tape reached
bars_held = 14by17:24:43 - at an ~11 second cadence, the max-hold boundary would have arrived around
17:40-17:41
So the 18:35 stop-loss is not the natural continuation of the original entry. It is a restore-time artifact on top of a stale open slot.
What is observable is the hydrated-path close that actually got booked:
- exit ts:
2026-06-11 18:35:52.789008+00:00 - exit reason:
STOP_LOSS - exit price:
0.23526757499999998 - realized pnl_pct:
-0.033056485743551446 - realized net_pnl:
-1913.155101369921
That realized stop corresponds to:
- price move against the short of about
3.3056% - account-level ROI of about
-2.726636%using capital before exit (70165.39)
Root cause
The bug is the restore path itself:
- The open trade state was preserved in
trade_reconstruction. - The current
position_statesnapshot was lossy or stale enough to rehydrate withbars_held≈0. - The chain token mismatch was detected, but the code explicitly continues with the derived token.
- The engine therefore recovered continuity without enforcing strict equality between the live open chain and the reconstructed state.
That combination makes orphaned trades possible after a bad hydrate.
Operational impact
- The XTZ short remained open in the ledger with no formal close.
- The engine later allowed a new trade while the slot should still have been occupied.
- Capital accounting diverged from the true live slot history.
- The restore path masked the inconsistency instead of stopping the recovery.
Recommended fix direction
- Treat a chain-token mismatch on restore as a hard failure for BLUE when a live open slot exists.
- Preserve the original
entry_barand bar counter from the open-chain payload instead of reconstructing them from the currentposition_staterow when the two disagree materially. - Refuse to admit a new trade until the single-slot invariant is proven flat.
- Add a regression test for:
- open XTZ trade
- stale
position_state - chain-token mismatch
- no new trade admission while the open slot remains unresolved
Bottom line
XTZ was a real open trade.
It never got a clean pre-hydrate exit.
The restore path tolerated chain drift and rebuilt a misleading open state.
The best-supported no-freeze outcome is the 17:24 retract, roughly flat to slightly negative.
The realized hydrated-path loss was -3.3056485743551446% on the position and -2.726636% of capital before exit, but that is a restore artifact, not the natural end of the original trade.