From 0ab83c528a03bb6406af05969cc9c1086af7f09e Mon Sep 17 00:00:00 2001 From: Codex Date: Wed, 17 Jun 2026 10:53:12 +0200 Subject: [PATCH] =?UTF-8?q?VIOLET=20OA:=20partial=20spec=20PASS=207=20?= =?UTF-8?q?=E2=80=94=20V5=20selection=20+=20multi-asset=20slots=20+=20capi?= =?UTF-8?q?tal=20allocation?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit VIOLET_PART_SPEC_OA_TODO_PASS7.md — the V5 ladder layer as six independent units extending contracts_v3 (AssetRank/SlotState/CapitalAllocation/SlotPolicy): 31. Selection contracts + SlotPolicy. 32. ARS ranking pipeline (faithful to AlphaAssetSelector.rank_assets + OB Sub-1 ±5/10% + IRP alignment filter + stablecoin exclusion). 33. Multi-asset slot manager (max_slots, assignment by rank, hysteresis anti-churn, no double-occ). 34. Capital allocation across slots (BLUE notional = base_fraction × conviction × capital; no invented normalization). 35. Selection→slot→intent multi-asset DARK flow harness. 36. Ranking bit-identity @gate vs the real AlphaAssetSelector. NOTE (CRITICAL #1): the disappointing live parity (pick-match 1.5%, no-pick 86%, sizing near- identical when aligned) implicates THIS selection/timing layer. PASS 7 PINS the ranking math bit-for-bit (Task 36), which narrows the live-parity suspect to timing/join — but the live-aggregate root-cause stays Claude's job (not this pass). Faithful to AlphaAssetSelector / BIBLE §5; cite kernel file:line. New-file-only under selection/. Standing ready for PASS 8–9. Added PASS 7 to the review queue in VIOLET_TODO_CRITICAL.md. Co-Authored-By: Claude Opus 4.8 --- prod/docs/VIOLET_PART_SPEC_OA_TODO_PASS7.md | 175 ++++++++++++++++++++ prod/docs/VIOLET_TODO_CRITICAL.md | 6 + 2 files changed, 181 insertions(+) create mode 100644 prod/docs/VIOLET_PART_SPEC_OA_TODO_PASS7.md diff --git a/prod/docs/VIOLET_PART_SPEC_OA_TODO_PASS7.md b/prod/docs/VIOLET_PART_SPEC_OA_TODO_PASS7.md new file mode 100644 index 00000000..3de05878 --- /dev/null +++ b/prod/docs/VIOLET_PART_SPEC_OA_TODO_PASS7.md @@ -0,0 +1,175 @@ +# VIOLET — partial spec for another agent, PASS 7 (OA TODO): V5 SELECTION + MULTI-ASSET SLOTS + CAPITAL ALLOCATION + +Date: 2026-06-17. Continues PASS 1–6 (same V0→V6 plan). PASS 7 is the **V5** layer of the ladder: +faithful IRP/ARS asset RANKING, MULTI-ASSET SLOT management (concurrent positions), and CAPITAL +ALLOCATION across slots. Everything DARK and as independent, separately-testable units sharing the +`contracts_v3` vocabulary. + +**⚠️ Relevance to CRITICAL #1 (read `VIOLET_TODO_CRITICAL.md`).** The disappointing live parity +(pick-match 1.5%, no-pick 86%, **but sizing near-identical when assets align**) points squarely at +SELECTION/TIMING, i.e. THIS layer. PASS 7 BUILDS the faithful selection machinery and pins the +ranking bit-for-bit to BLUE's `AlphaAssetSelector` (Task 36). That is COMPLEMENTARY to — not a +substitute for — the live-aggregate parity root-cause, which remains **Claude's** job (the live +join/alignment in `parity_report.py` is the other suspect). Do NOT attempt the live root-cause +here; build the units + the unit-level bit-identity pin. + +**Read first (authoritative references — READ ONLY):** +- `nautilus_dolphin/nautilus_dolphin/nautilus/alpha_asset_selector.py` — `AlphaAssetSelector.rank_assets` + (IRP selection, ARS scoring, BIBLE §5) — the ranking authority. +- `prod/docs/SYSTEM_BIBLE.md` §5 (selection), §490 "OB Sub-1: ARS adjusted ±5%/10% by per-asset OB + depth quality before sorting", §735 OB sub-systems. (BIBLE is directionally right but can be + outdated — verify against the kernel code.) +- `prod/clean_arch/violet/alpha_wrappers.py` (`VioletAssetSelector`, the single-pick wrapper) + + `decision_engine.py` (how a pick + `ars_score` flow today) + `sizing.py` (notional model) — READ, + do NOT edit (in-flight). +- ENGINE_KWARGS selection knobs (`nautilus_event_trader.py:127+`): `use_asset_selection=True`, + `min_irp_alignment=0.0` ("gold spec: no IRP filter"), `max_slots` (launcher venue config). +- Stablecoin exclusion: `decision_engine.STABLECOIN_SYMBOLS` (must match BLUE's set). + +--- + +## 0. HARD RULES (identical to PASS 1–6 — summarized) +- **Never edit shared files** (`prod/nautilus_event_trader.py`, `clean_arch/dita_v2/**`, + `dita/decision.py`, `nautilus_dolphin/**`, `blue_parity.py`, `prod/bingx/leverage.py`). READ only. +- **VIOLET DARK** — selection/slots/allocation are pure logic over scan + factor inputs; no orders, + no venue, no service/HZ control. +- **V-TYPES on all new code**; faithful poison-guards only; NO arbitrary caps. +- **NEW-FILE-ONLY** under `prod/clean_arch/violet/selection/` (+ extend `contracts_v3.py`). Do NOT + modify in-flight files (`alpha_wrappers.py`, `decision_engine.py`, `sizing.py`, + `live_blue_source.py`, the PASS-5/6 exec files, `cadence.py`, `clock.py`). READ + IMPORT them. + +## 0a. COMMIT / BRANCH POLICY (3 shared-index collisions on 2026-06-16 — non-negotiable) +Own `git worktree` (`git worktree add ../vp-oa7 -b agent/oa-violet7`) strongly preferred. Else +never `git add -A`; `git commit -F msg -- ` with explicit pathspec; verify +`git show --stat --format="" HEAD` lists ONLY your files. One commit/task, prefix `VIOLET OA:`, +Co-Authored-By trailer. Tests on `/home/dolphin/siloqy_env/bin/python3`. `git grep` only. + +--- + +## I. SHARED INTERFACE EXTENSIONS (add to `contracts_v3.py`; never fork a parallel type) +Reuse PASS-3..6 types. ADD the selection/slot vocabulary (all `StrictModel` / `Annotated`): +1. **`AssetRank`** — `asset: Symbol`, `ars_score: float (finite)`, + `ob_adjusted_score: float (finite)`, `irp_alignment: float`, `irp_passed: bool`, `rank: int (ge=0)`, + `excluded_reason: str = ""` (e.g. "STABLECOIN"/"IRP_FILTER"/"" ). +2. **`SlotState`** — `slot_id: int (ge=0)`, `asset: Optional[Symbol]`, `status: str` + ("FREE"/"HELD"/"PENDING"), `held_since_ns: Optional[MonoNs]`. +3. **`CapitalAllocation`** — `slot_id: int`, `asset: Symbol`, `allocated_capital: float (ge=0)`, + `notional_fraction: float (ge=0)`, `conviction_leverage: float (ge=0)`. +4. **`SlotPolicy`** — `max_slots: Annotated[int, Field(ge=1)]`, + `hysteresis_bars: Annotated[int, Field(ge=0)]` (anti-churn), `allow_reentry: bool`. + +If a task needs another field, ADD it here and note it. + +--- + +## TASK 31 — Selection contracts + SlotPolicy +**Why.** The shared selection/slot vocabulary everything else imports. +**Affected files (NEW):** extend `contracts_v3.py` (the §I types); +`prod/clean_arch/violet/selection/__init__.py`; +`prod/clean_arch/violet/selection/test_violet_selection_contracts.py`. +**Pass criteria.** All types construct + poison-reject (non-finite scores, negative capital, +max_slots ≥ 1); `excluded_reason` enumerated values documented. No edits outside the new/extended files. + +## TASK 32 — ARS ranking pipeline (faithful to AlphaAssetSelector + OB Sub-1 + IRP filter) +**Why.** The heart of selection: reproduce BLUE's full ranking — ARS score → OB Sub-1 adjustment → +IRP alignment filter → stablecoin exclusion → sort. The single-pick `VioletAssetSelector` covers +part of this; PASS 7 builds the FULL multi-asset ranking on top WITHOUT editing it. +**Affected files (NEW):** `prod/clean_arch/violet/selection/rank_pipeline.py`, +`prod/clean_arch/violet/selection/test_violet_rank_pipeline.py`. +**Interface/approach.** `rank_assets(market_data: dict[Symbol, list[float]], *, regime_direction: +int, ob_market=None, min_irp_alignment: float, stablecoins: frozenset[str]) -> list[AssetRank]`: +- Compute the base ARS exactly as `AlphaAssetSelector` (WRAP/transcribe — cite file:line). +- **OB Sub-1** (BIBLE §490): adjust ARS ±5%/10% by per-asset OB depth quality BEFORE sorting (read + the kernel for the exact factors/percentages; if `ob_market` is None, skip the adjustment, as the + no-OB path does). +- **IRP alignment filter:** drop assets with alignment < `min_irp_alignment` (default 0.0 = no + filter, per gold spec) → mark `irp_passed`/`excluded_reason`. +- **Stablecoin exclusion:** any asset in `stablecoins` → excluded (must equal + `decision_engine.STABLECOIN_SYMBOLS`; assert in test). +- Sort descending by `ob_adjusted_score`; assign `rank`. Pure function, deterministic, V-TYPES out. +**Pass criteria.** On crafted market data the ranked order + ARS/ob_adjusted scores match a direct +`AlphaAssetSelector` computation; stablecoins always excluded; IRP filter respected; OB-off path +equals base ARS. No edits outside the 2 files. + +## TASK 33 — Multi-asset slot manager (max_slots, assignment, hysteresis) +**Why.** BLUE/VIOLET hold up to `max_slots` concurrent positions; the slot manager decides which +ranked assets occupy slots, with no double-occupancy and anti-churn hysteresis. +**Affected files (NEW):** `prod/clean_arch/violet/selection/slot_manager.py`, +`prod/clean_arch/violet/selection/test_violet_slot_manager.py`. +**Interface/approach.** `SlotManager(policy: SlotPolicy)` holding `list[SlotState]`. `assign(ranked: +list[AssetRank], held: dict[Symbol, OpenPositionView], now_ns) -> list[SlotState]`: keep currently +HELD assets in their slots; fill FREE slots from the top of `ranked` (excluding already-held and +excluded assets); never assign the same asset to two slots; respect `hysteresis_bars` (do not evict +a freshly-taken slot to chase a higher rank within the hysteresis window). READ how BLUE/the trader +manages `max_slots` (launcher venue config + engine) and transcribe the rule; if BLUE is +single-slot today (`max_slots=1`), the manager must still be correct + generalize to N. +**Pass criteria.** Held assets retained; free slots filled by rank; no double-occupancy; hysteresis +prevents churn; max_slots respected. Hypothesis: |HELD slots| ≤ max_slots always; no asset in two +slots. No edits outside the 2 files. + +## TASK 34 — Capital allocation across slots +**Why.** Turn slot occupancy + conviction into per-slot capital + notional, honoring BLUE's sizing +convention (notional = base_fraction × conviction × capital) and the margin-study findings. +**Affected files (NEW):** `prod/clean_arch/violet/selection/capital_allocator.py`, +`prod/clean_arch/violet/selection/test_violet_capital_allocator.py`. +**Interface/approach.** First READ how BLUE allocates capital across concurrent slots (shared pool +vs per-slot; the margin study `blue_margin_envelope_study` + `sizing.py` are the references — +notional = 0.20 × conviction × capital; capital under-utilized at 1 slot was DELIBERATE). Define +`allocate(slots: list[SlotState], convictions: dict[Symbol, float], *, capital: float, base_fraction: +float) -> list[CapitalAllocation]` reproducing that convention EXACTLY (cite the source). Do NOT +invent a normalization BLUE doesn't do. +**Pass criteria.** Per-slot notional == base_fraction × conviction × capital (the documented model); +sum-of-notionals behavior matches BLUE's (shared-capital, not artificially normalized, unless BLUE +normalizes — verify); poison guards reject non-finite/negative. Cite the allocation source. No edits +outside the 2 files. + +## TASK 35 — Selection→slot→intent multi-asset flow harness (DARK) +**Why.** Compose the V5 path end-to-end: `rank_pipeline` → `slot_manager` → `capital_allocator` → +(existing sizing) → `ExecIntent` per occupied slot (PASS-4 Task 17), DARK. +**Affected files (NEW):** `prod/clean_arch/violet/selection/multi_asset_flow.py`, +`prod/clean_arch/violet/selection/test_violet_multi_asset_flow.py`. +**Interface/approach.** `run_selection_cycle(market_data, held, *, factors, capital, policy, ...) -> +list[ExecIntent]` wiring the four units. Reuse `sizing.VioletSizer` for conviction (import, don't +fork). DARK: emits intents, never orders. Deterministic. +**Pass criteria.** A multi-asset scenario yields one intent per occupied slot with correct +asset/qty/notional; held assets not re-entered (unless `allow_reentry`); max_slots respected +end-to-end; deterministic. No edits outside the 2 files. + +## TASK 36 — Ranking bit-identity gate vs the real AlphaAssetSelector +**Why.** Pin the ranking to BLUE's actual `AlphaAssetSelector` over a sampled grid — the unit-level +parity that, once green, removes selection-math as a suspect for CRITICAL #1 (leaving timing/join as +the remaining live-aggregate suspect for Claude). +**Affected files (NEW):** `prod/clean_arch/violet/selection/test_violet_rank_parity_gate.py`; gate +report → `prod/VIOLET_dev/reports/violet_rank_parity_.json`. +**Interface/approach.** Over many synthetic universes (varied asset counts, price histories, +directions, with/without OB), assert `rank_pipeline.rank_assets` produces the SAME ordering + the +SAME ARS/ob_adjusted scores (`==`) as a direct `AlphaAssetSelector` run on the same inputs. Record +mismatch count (must be 0). +**Pass criteria (`@pytest.mark.gate`).** ≥ 200 universes, zero ranking/score mismatches; report +archived. If mismatches appear, that IS a finding — report them, do not loosen. No edits outside the +new file. + +--- + +## Composition map +``` +contracts_v3 (+AssetRank/SlotState/CapitalAllocation/SlotPolicy) + 32 rank_pipeline(market, ob, irp, stables) → [AssetRank] (faithful to AlphaAssetSelector + OB Sub-1) + 33 slot_manager(ranked, held, policy) → [SlotState] (max_slots, hysteresis, no double-occ) + 34 capital_allocator(slots, convictions, cap)→ [CapitalAllocation] (BLUE notional convention) + 35 multi_asset_flow: 32→33→34→ sizing → [ExecIntent] (DARK V5 cycle) + 36 rank_parity_gate: rank_pipeline == AlphaAssetSelector (bit-identity) ← narrows CRITICAL #1 +``` +Integration (running the V5 cycle on the live reactor, wiring intents to the PASS-5/6 exec stack) is +the OWNER's job later. + +## Recommended order +**31 (contracts) → 32 (rank pipeline) → 36 (rank parity gate) → 33 (slots) → 34 (allocation) → 35 +(flow harness)**. 36 right after 32 so the ranking is pinned before building on it. + +## Still NOT in scope (operator/owner only, or Claude) +- **The live BLUE↔VIOLET aggregate parity root-cause (CRITICAL #1)** — Claude's job; this pass only + pins ranking-math + builds V5 units. +- **Alpha re-timing / sub-second actuation of entries** — VBT re-certification (research), not a unit. +- **DARK soak start; V4 live execution; HZ-bridge; VIBRISS.** +- Any edit to in-flight / shared files in §0. diff --git a/prod/docs/VIOLET_TODO_CRITICAL.md b/prod/docs/VIOLET_TODO_CRITICAL.md index ec5094c1..21c61bf9 100644 --- a/prod/docs/VIOLET_TODO_CRITICAL.md +++ b/prod/docs/VIOLET_TODO_CRITICAL.md @@ -70,6 +70,12 @@ QUIRK-INJECTION gate that flips PASS-5's QuirkProfile flags ON and proves each h the quirk. Mirrors PINK's production fixes (pink_direct.py). Real-key smoke still MANDATORY before V4-live; review when done. +**PASS 7**: `VIOLET_PART_SPEC_OA_TODO_PASS7.md` (issued 2026-06-17) — V5 selection (faithful +ARS/IRP ranking + OB Sub-1), multi-asset slot manager, capital allocation, multi-asset flow, and a +ranking bit-identity gate vs AlphaAssetSelector. NOTE: this layer is the suspected locus of CRITICAL +#1 — PASS 7 PINS the ranking math (narrowing the suspect to timing/join), but the live-aggregate +root-cause stays Claude's job. Review when done. + **Action:** review each pass for correctness, BLUE-algo compliance, V-TYPES, no-shared-edits, real (non-vacuous) tests. **Owner: Claude (me), later.**