Files
foxhunt/TYPE_GOVERNANCE.md
jgrusewski ea9d8f2c88 🚨 ARCHITECTURAL DISASTER: THREE Competing Type Sources Discovered
## Critical Investigation Results

**DISASTER CONFIRMED**: Agents discovered THREE type sources instead of ONE:
1. foxhunt-common-types/ (SHOULD NOT EXIST - still active!)
2. trading_engine/src/types/ (massive duplication)
3. common/src/types.rs (depends on competing crate)

## Evidence of Violations
- foxhunt-common-types still in workspace members (line 86)
- common/Cargo.toml depends on foxhunt-common-types (line 48)
- 48+ duplicate type definitions across OrderSide, OrderStatus, OrderType
- Compilation failures due to competing imports

## Immediate Action Required
- Choose ONE canonical source
- DELETE foxhunt-common-types completely
- Consolidate ALL types to single source
- Fix THREE-WAY import chaos

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-09-26 15:33:34 +02:00

9.1 KiB

TYPE GOVERNANCE - Foxhunt HFT System

🚨 CRITICAL: TYPE OWNERSHIP AND GOVERNANCE RULES

Last Updated: 2025-01-24
Status: MANDATORY - All developers must follow these rules

🔒 THE GOLDEN RULE

THERE CAN BE ONLY ONE CANONICAL DEFINITION OF EACH TYPE

Every type in the Foxhunt HFT system has exactly one canonical definition. All other usages MUST import from the canonical source. Local redefinitions are STRICTLY FORBIDDEN.

🎯 TYPE OWNERSHIP HIERARCHY

1. Core Business Types - CANONICAL SOURCE: trading_engine/src/types/

Type Canonical Location Import Path
OrderSide trading_engine/src/types/basic.rs use trading_engine::types::prelude::*;
OrderStatus trading_engine/src/types/basic.rs use trading_engine::types::prelude::*;
OrderType trading_engine/src/types/basic.rs use trading_engine::types::prelude::*;
Price trading_engine/src/types/basic.rs use trading_engine::types::prelude::*;
Quantity trading_engine/src/types/basic.rs use trading_engine::types::prelude::*;
Symbol trading_engine/src/types/basic.rs use trading_engine::types::prelude::*;
Order trading_engine/src/types/basic.rs use trading_engine::types::prelude::*;
Position trading_engine/src/types/basic.rs use trading_engine::types::prelude::*;
Trade trading_engine/src/types/basic.rs use trading_engine::types::prelude::*;
Fill trading_engine/src/types/basic.rs use trading_engine::types::prelude::*;
Decimal trading_engine/src/types/financial.rs use trading_engine::types::prelude::*;

2. Asset Types - CANONICAL SOURCE: trading_engine/src/types/assets.rs

Type Canonical Location Import Path
AssetType trading_engine/src/types/assets.rs use trading_engine::types::prelude::*;
AssetClass trading_engine/src/types/assets.rs use trading_engine::types::prelude::*;
UnifiedAsset trading_engine/src/types/assets.rs use trading_engine::types::prelude::*;

3. Event Types - CANONICAL SOURCE: trading_engine/src/types/events.rs

Type Canonical Location Import Path
OrderEvent trading_engine/src/types/events.rs use trading_engine::types::prelude::*;
FillEvent trading_engine/src/types/events.rs use trading_engine::types::prelude::*;
PositionEvent trading_engine/src/types/events.rs use trading_engine::types::prelude::*;
MarketEvent trading_engine/src/types/events.rs use trading_engine::types::prelude::*;

4. Configuration Types - CANONICAL SOURCE: crates/config/src/

Type Canonical Location Import Path
ServiceConfig crates/config/src/schemas.rs use config::*;
ConfigManager crates/config/src/manager.rs use config::*;
ModelConfig crates/config/src/schemas.rs use config::*;

5. Infrastructure Types - May remain in respective crates

  • Database connection types in database/src/
  • Network types in individual service crates
  • Service-specific internal types (NOT shared between services)

🚫 FORBIDDEN PATTERNS

NEVER DO THESE:

// ❌ DON'T: Local type redefinition
pub enum OrderSide {
    Buy, Sell
}

// ❌ DON'T: Direct external imports bypassing prelude
use rust_decimal::Decimal;

// ❌ DON'T: Type aliases for core types
pub type MyOrderSide = OrderSide;

// ❌ DON'T: Duplicate enums with different names
pub enum Side { Buy, Sell }  // This duplicates OrderSide

// ❌ DON'T: Partial re-exports without full prelude
pub use trading_engine::types::basic::OrderSide;

// ❌ DON'T: Creating foxhunt-* prefixed crates for types
// Don't create: foxhunt-types, foxhunt-core-types, etc.

CORRECT PATTERNS:

// ✅ DO: Import from prelude
use trading_engine::types::prelude::*;

// ✅ DO: Use canonical types directly
let order = Order::market(symbol, OrderSide::Buy, quantity);
let price = Decimal::new(12345, 2);  // From prelude

// ✅ DO: Service-specific types that don't conflict
pub struct TradingServiceConfig {
    // Service-specific configuration
}

// ✅ DO: Proper error handling with canonical types
fn process_order(order: Order) -> Result<Trade, OrderError> {
    // Implementation using canonical types
}

📋 IMPORT STANDARDS

All Crates Must Follow These Import Patterns:

1. Services (trading_service, backtesting_service, ml_training_service)

// Standard imports for all services
use trading_engine::types::prelude::*;
use config::*;  // For configuration types only

// Specific imports if needed
use trading_engine::events::TradingEvent;
use trading_engine::operations::OrderOperations;

2. TLI (Terminal Interface)

// TLI is a pure client - minimal imports
use trading_engine::types::prelude::*;

// gRPC client types (generated)
use foxhunt::tli::*;
use foxhunt::config::*;

3. Test Files

// Tests use canonical types
use trading_engine::types::prelude::*;

// Test framework
use tests::framework::*;

// NO local type redefinition in tests

4. Data Crates (data, ml-data, risk-data)

// Data crates import canonical types
use trading_engine::types::prelude::*;

// Repository-specific types only if truly unique
pub struct DataRepositoryConfig {
    // Data-layer specific configuration
}

🛠️ ENFORCEMENT MECHANISMS

1. Clippy Lints (.clippy.toml)

# Forbid duplicate type definitions
forbid-duplicate-types = "deny"
unnecessary-type-alias = "deny"
redundant-type-definition = "deny"

2. CI Validation Script

The CI pipeline runs scripts/validate_type_governance.sh which:

  • Scans for duplicate type definitions
  • Ensures all services import from prelude
  • Validates no forbidden patterns exist
  • Checks import consistency

3. Code Review Requirements

All PRs must pass type governance validation:

  • No duplicate type definitions
  • Proper imports from prelude
  • No forbidden patterns used
  • Type governance documentation updated if needed

🔧 MIGRATION GUIDE

For Existing Code with Duplicate Types:

  1. Identify the canonical definition (usually in trading_engine/src/types/)
  2. Remove local duplicate definitions
  3. Add prelude import: use trading_engine::types::prelude::*;
  4. Update all usages to use canonical types
  5. Test compilation with cargo check --workspace

Example Migration:

// ❌ BEFORE: Local duplicate
pub enum OrderSide { Buy, Sell }

impl SomeService {
    fn process(side: OrderSide) {
        // ...
    }
}

// ✅ AFTER: Using canonical types
use trading_engine::types::prelude::*;

impl SomeService {
    fn process(side: OrderSide) {  // Now uses canonical OrderSide
        // ...
    }
}

📊 CURRENT STATE ANALYSIS

Critical Issues Found:

Type Duplicates Found Files Affected
OrderSide 19 definitions TLI, tests, services, market-data
OrderStatus 15 definitions TLI, trading_engine, tests, services
OrderType 14 definitions TLI, trading_engine, tests, services

Immediate Action Required:

  1. Remove all duplicate OrderSide, OrderStatus, OrderType definitions
  2. Replace with canonical imports from prelude
  3. Validate all affected crates compile correctly
  4. Update any generated code that creates duplicates

🎯 VALIDATION COMMANDS

# Check for duplicate type definitions
./scripts/check_duplicate_types.sh

# Validate all services use prelude correctly
cargo check --workspace

# Run type governance validation
./scripts/validate_type_governance.sh

# Check import patterns
rg "pub enum (OrderSide|OrderStatus|OrderType)" --type rust

# Verify prelude usage
rg "use trading_engine::types::prelude::\*" --type rust

📝 DEVELOPER CHECKLIST

Before committing any code:

  • I have not created any duplicate type definitions
  • I use trading_engine::types::prelude::* for core types
  • I use config::* for configuration types only
  • I have not created local type aliases for core types
  • I have not imported external types that bypass the prelude
  • All tests use canonical types from prelude
  • My code compiles with cargo check --workspace

🚨 VIOLATIONS AND CONSEQUENCES

Type governance violations are treated as critical issues:

  1. Immediate: PR rejected, must fix before merge
  2. Recurring: Code review escalation to architecture team
  3. Systematic: Developer training on type system required

📞 GETTING HELP

When in doubt:

  1. Check the canonical type location in this document
  2. Look at trading_engine/src/types/prelude.rs for available types
  3. Follow existing patterns in the codebase
  4. Ask on the team chat: "What's the canonical way to use [type]?"

Remember: Type governance prevents architectural debt and ensures system reliability. Every developer is responsible for maintaining these standards.