Skip to content

feat(engine): integrate contradiction strategy and implement brain state sync#13

Merged
Harikeshav-R merged 9 commits into
mainfrom
feat/engine/contradiction-integration
Feb 27, 2026
Merged

feat(engine): integrate contradiction strategy and implement brain state sync#13
Harikeshav-R merged 9 commits into
mainfrom
feat/engine/contradiction-integration

Conversation

@Harikeshav-R

Copy link
Copy Markdown
Owner

Description

This PR implements the end-to-end integration of the Contradiction Strategy into the ArbOS project. It bridges the gap between the Tier 2 Brain Service (logic discovery) and the Tier 3 Rust Engine (high-frequency execution).

Key Changes:

  • Python Brain Service (Tier 2):
    • New Endpoint: Implemented the /state endpoint in main.py which serves the current synchronized graph state (implications, partitions, and contradictions).
    • Mapping Fix: Added critical logic to resolve Polymarket condition_ids into actual clob_token_ids (YES tokens). This ensures the Rust Engine can correctly track assets using U256 identifiers instead of failing on string hashes.
    • Models: Defined BrainStatePayload and its constituent mapping models in models.py.
  • Rust Engine (Tier 3):
    • Actor Integration: Updated EngineActor in actor.rs to fetch and parse contradictions during the sync_brain_state loop.
    • Execution Logic: Implemented evaluate_contradictions, which leverages the ContradictionStrategy to detect arbitrage opportunities when mutually exclusive markets violate the $P(A) + P(B) \le 1.0$ constraint.
    • Strategy Wiring: Enabled the contradiction module in strategies/mod.rs and removed the "unwired" legacy comments.
    • Testing: Added test_engine_actor_triggers_contradiction_arb to actor.rs to verify that the engine correctly generates an ArbSignal when a contradiction is detected.

Type of change

  • New feature (non-breaking change which adds functionality)

How Has This Been Tested?

  • Unit Tests (Python): Ran uv run pytest, verifying that the new models and /state endpoint logic do not regression existing graph or API tests (50 passed).
  • Unit Tests (Rust): Ran cargo test, specifically validating the new engine loop logic and existing strategy checks (14 passed).
  • Integration/Compatibility: Verified that the Python JSON payload for /state is correctly deserialized by the Rust serde implementation and that the Token ID mapping allows the engine to successfully match orderbook updates to graph edges.

Checklist:

  • My code follows the style guidelines of this project
  • I have performed a self-review of my own code
  • I have commented my code, particularly in hard-to-understand areas
  • I have made corresponding changes to the documentation
  • My changes generate no new warnings
  • I have added tests that prove my feature works
  • New and existing unit tests pass locally with my changes

- Introduced a new `/state` endpoint in `main.py` to return the synchronized graph state for use by the Rust Engine.
  - Includes metadata for asset end timestamps, implications, contradictions, and partition mappings.
- Added `BrainStatePayload`, `ImplicationMapping`, `PartitionMapping`, and `ContradictionMapping` models in `models.py` to structure graph state data.
- Integrated logic to fetch:
  - Conditional token mappings and asset end timestamps based on active markets.
  - Implications and contradictions using relationship graph data.
  - Partition mappings for mutually exclusive market groups, with deterministic condition IDs based on asset hashes.
- Enhanced consistency and compatibility between the Brain Service and the Rust Engine by providing a complete state snapshot in a structured payload.

This addition facilitates efficient polling and synchronization with the Rust Engine while maintaining flexibility for future extensions.
- Added `ContradictionMapping` to `BrainStatePayload` for state synchronization.
- Defined `ContradictionMapping` struct and implemented parsing logic (`parse_contradictions`).
- Extended `EngineActor` with `contradiction_edges` for storing mutually exclusive asset relationships.
- Implemented `evaluate_contradictions` in `EngineActor` to identify and execute profitable contradiction opportunities.
  - Logic includes validation of weights, gas fees, and profit margins.
- Updated book handlers to trigger contradiction evaluations alongside implications and partitions.
- Adjusted asset frequency tracking and expiry validation logic to account for contradiction mapping (`compute_tracked_assets`).
- Added comprehensive unit test for contradiction evaluation flow (`test_engine_actor_triggers_contradiction_arb`).
- Updated documentation in `strategies/mod.rs` to mark `ContradictionStrategy` as integrated.

This implementation connects the Tier-3 contradiction strategy with the runtime, enabling evaluation and execution of mutually exclusive market inconsistencies.
Copilot AI review requested due to automatic review settings February 27, 2026 22:38

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Integrates Tier-2 Brain “contradiction” discovery with the Tier-3 Rust engine by adding a /state graph-sync payload and wiring contradiction evaluation into the engine’s execution loop.

Changes:

  • Added Brain /state endpoint and payload models for implications, partitions, contradictions, and asset end timestamps.
  • Wired contradiction mappings into the Rust EngineActor sync loop and added runtime evaluation for contradiction arbs.
  • Updated strategy module wiring/comments and added a Rust unit test for contradiction triggering.

Reviewed changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated 10 comments.

File Description
services/brain/models.py Adds Pydantic models for the new /state payload contract.
services/brain/main.py Implements /state endpoint to emit synchronized graph state + token/timestamp mapping.
crates/engine/src/strategies/mod.rs Updates strategy module comment to reflect contradiction strategy wiring.
crates/engine/src/actor.rs Extends payload parsing for contradictions, tracks contradiction edges, evaluates contradiction arbs, and adds a unit test.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread services/brain/main.py
Comment thread services/brain/main.py
Comment thread services/brain/main.py
Comment thread services/brain/main.py
Comment thread crates/engine/src/actor.rs
Comment thread crates/engine/src/actor.rs
Comment thread crates/engine/src/actor.rs Outdated
Comment thread services/brain/main.py Outdated
Comment thread crates/engine/src/actor.rs
Comment thread crates/engine/src/actor.rs Outdated
…diction evaluation

- Renamed `condition_id` to `asset_id` across the contradiction evaluation flow in `EngineActor` to ensure consistent terminology and logic.
- Fixed incorrect usage of `vwap_ask` for bid-related calculations; replaced with `vwap_bid` to align with strategy logic.
- Updated sizing calculation to use `sum_bids` instead of the highest price, ensuring a more precise allocation of liquidity.
- Adjusted asset frequency computation to add directional constraints, ensuring order and correctness when processing parent-child pairs.
- Updated test order book parameters to match bid/ask logic corrections and reflect valid cases for evaluation.

These changes improve the accuracy and readability of the contradiction evaluation and support the intended strategy behavior while addressing inconsistencies in asset handling and computational logic.
…ence-based partitioning

- Enhanced error handling in `_graph_manager` by adding detailed warnings during end_date parsing failures, including `condition_id`, `end_date`, and error details.
- Introduced confidence-based logic in partition group mapping:
  - Built a lookup table for mutually exclusive relationship confidences.
  - Integrated minimum confidence calculation for grouped partitions.
  - Updated deterministic hashing to include a `v1_` prefix for future migrations.
- Improved confidence tracking for partitions, applying calculated values instead of a hardcoded `1.0`.

These changes increase the clarity of logged issues, improve partition grouping accuracy, and lay the foundation for future versioned hashing enhancements.

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 4 out of 4 changed files in this pull request and generated 6 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread crates/engine/src/actor.rs
Comment thread crates/engine/src/strategies/mod.rs
Comment thread services/brain/main.py
Comment thread services/brain/main.py Outdated
Comment thread services/brain/main.py
Comment thread crates/engine/src/actor.rs Outdated
…tion handling

- Added `asset_to_partition` mapping in `EngineActor` to enable O(1) partition lookups for assets.
- Refactored `market_outcomes` and `market_expected_outcome_counts` to use `String` keys instead of `B256` for consistent data handling across the actor.
- Updated partition-related methods (`get_partition_bids`, `is_partition_exhaustively_tradable`, `check_and_send_partition`) to adopt the new `asset_to_partition` logic.
- Enhanced `parse_partitions` to generate `asset_to_partition` mapping alongside market outcomes and expected outcomes.
- Deferred order book ejection during contradiction evaluation for correct processing of peer execution.
- Improved code clarity and reduced redundancy in partition and contradiction evaluation logic.

These changes improve the engine's partition-handling performance, simplify the data structure interface, and ensure more robust execution in complex asset scenarios.
@Harikeshav-R Harikeshav-R requested a review from Copilot February 27, 2026 23:09

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 4 out of 4 changed files in this pull request and generated 5 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread crates/engine/src/actor.rs
Comment thread crates/engine/src/actor.rs Outdated
Comment thread services/brain/main.py
Comment thread services/brain/main.py Outdated
Comment thread services/brain/models.py
… improve partition bid handling

- **Engine Updates:**
  - Updated `get_partition_bids` and `is_partition_exhaustively_tradable` methods to use `&str` instead of `String` for `partition_id` parameters, enhancing performance with borrowed references.
  - Added `BRAIN_API_KEY` retrieval and included it as a header in API client requests, securing communication with the Brain service.

- **Brain Service Enhancements:**
  - Secured the `/state` endpoint with admin-level authentication via `Depends(_verify_admin)`.
  - Added environment variable check for `ADMIN_API_KEY` in test setups.
  - Expanded testing for `/state`:
    - Verified missing authentication response (`401 Unauthorized`).
    - Verified proper response with valid API key and mocked graph data.

- **Model Enhancements:**
  - Introduced and tested new Brain state models:
    - `ImplicationMapping`, `PartitionMapping`, `ContradictionMapping`, and `BrainStatePayload`.
  - Confirmed compatibility and correctness of structured state payload serialization.

These changes improve the Rust engine's partition handling and ensure secure, robust collaboration between the Brain service and the Rust Engine.
@Harikeshav-R Harikeshav-R requested a review from Copilot February 27, 2026 23:21

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 6 out of 6 changed files in this pull request and generated 3 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread services/brain/models.py
Comment thread crates/engine/src/actor.rs Outdated
Comment thread crates/engine/src/actor.rs
- Updated `brain_api_key` retrieval to require `ADMIN_API_KEY` instead of `BRAIN_API_KEY`.
- Added error handling to ensure `ADMIN_API_KEY` is present and properly configured to avoid runtime issues during state synchronization.

This change improves security and robustness for engine-to-brain communication.
@Harikeshav-R Harikeshav-R requested a review from Copilot February 27, 2026 23:30

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 6 out of 6 changed files in this pull request and generated 3 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread services/brain/main.py Outdated
Comment thread crates/engine/src/actor.rs Outdated
Comment thread crates/engine/src/actor.rs Outdated
…stency

- Renamed `market_outcomes` to `partition_outcomes` for alignment with partition-centric terminology.
- Updated `market_expected_outcome_counts` to `partition_expected_outcome_counts`, ensuring consistent field naming across the codebase.
- Refactored relevant methods and logic to match the updated terminology (`get_partition_bids`, `parse_partitions`, etc.).
- Improved environment variable handling for `ADMIN_API_KEY` during API requests to avoid errors when the variable is missing or empty.
- Updated the Brain service to use `len(group_tokens)` for outcome count calculation in `PartitionMapping`, ensuring correctness.

This refactor standardizes field names, improves clarity, and ensures accuracy in partition-based handling within the Engine and related services.

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 6 out of 6 changed files in this pull request and generated 3 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread services/brain/main.py Outdated
Comment on lines +549 to +551
# 3. Partitions
partitions_lists = await _graph_manager.get_partition_groups()
partitions = []

Copilot AI Feb 27, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

/state builds partitions from _graph_manager.get_partition_groups() (connected components of MUTUALLY_EXCLUSIVE edges). Connected components don’t guarantee a fully mutually-exclusive (clique) set, and they also don’t imply the set is exhaustive, but downstream PartitionStrategy assumes exhaustiveness when shorting the full basket. Consider only emitting partitions when Tier 2 can assert exhaustiveness (or at least when the ME subgraph is a clique), otherwise keep these as contradictions-only.

Copilot uses AI. Check for mistakes.
Comment thread services/brain/main.py Outdated
Comment on lines +494 to +498
# 1. Fetch metadata (tokens and timestamps)
result = await session.execute(
select(Market.condition_id, Market.end_date, Market.clob_token_ids)
.where(Market.active.is_(True), Market.closed.is_(False))
)

Copilot AI Feb 27, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This query pulls all active, open markets on every /state poll, then materializes the full result set with result.all(). Since the engine syncs every 60s, this can become a steady DB load as the market table grows. Consider caching condition_id -> yes_token/end_ts in-memory with an expiry, or restricting the query to only condition_ids that appear in the current graph edges/partition groups.

Copilot uses AI. Check for mistakes.
Comment thread services/brain/main.py
Comment on lines +525 to +531
for rel in implications_dicts:
parent_token = condition_to_yes_token.get(rel["parent_condition_id"])
child_token = condition_to_yes_token.get(rel["child_condition_id"])

if not parent_token or not child_token:
continue

Copilot AI Feb 27, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When a relationship references a condition_id that isn’t present in condition_to_yes_token (e.g., inactive/closed market, stale relationship), it’s silently dropped. That makes graph/engine mismatches hard to diagnose. Consider logging (at least debug/warn with counts) when relationships are skipped due to missing token mappings.

Copilot uses AI. Check for mistakes.
… refined partition processing

- **Performance Enhancements:**
  - Added condition-based filtering to database queries, ensuring only relevant `condition_ids` are processed to reduce data overhead.
  - Optimized implication and partition logic by pre-collecting `condition_ids` to streamline metadata queries.

- **Partition Handling Improvements:**
  - Excluded partitions with incomplete token mappings or invalid configurations (e.g., non-cliques).
  - Refined confidence calculations to consider minimum confidence across relationships while ensuring clique validation.

- **Logging Enhancements:**
  - Added detailed debug-level logs for skipped relationships and partitions, highlighting reasons such as missing tokens or invalid configurations.

These updates enhance the `/state` endpoint with better performance, more reliable partition processing, and improved visibility into processing behaviors.
@Harikeshav-R Harikeshav-R merged commit a1d325c into main Feb 27, 2026
4 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants