"""AUTO-GENERATED from /schemas/*.json — do not edit by hand."""
# Regenerate: python3 scripts/codegen/generate_types.py
from __future__ import annotations
from typing import Any, Dict, List, Literal, Optional, Union
from pydantic import BaseModel, Field, ConfigDict

ConditionId = str
BuilderCode = Literal["0xb000000000000000000000000000000000000000000000000000000000003f7a"]
ChainId = Literal[137]
VerifyingContract = Literal["0x4D97DCd97eC945f40cF65F87097ACe5EA0476045"]
Stable = Literal["pUSD"]
ReasonCode = str
ScoreType = Literal["fair_value", "momentum", "expected_edge", "confidence", "custom"]
EnvelopeId = str
PortfolioId = str
StrategyId = str
ClusterId = str
ISO8601 = str
Decimal = str
Side = Literal["BUY", "SELL"]
OrderType = Literal["LIMIT", "MARKET", "POST_ONLY"]

class AuditEnvelope(BaseModel):
    model_config = ConfigDict(extra="forbid")
    """Receipt written for every state change a developer or auditor would care about. builderCode and reason code are NEVER masked."""
    envelope_id: EnvelopeId
    ts: ISO8601
    reason: ReasonCode
    builder_code: BuilderCode
    actor: Dict[str, Any]
    subject: Dict[str, Any]
    scope_snapshot: Optional[Dict[str, Any]] = None

class MarketScope_1(BaseModel):
    model_config = ConfigDict(extra="forbid")
    """Cluster binding (primary)"""
    mode: Literal["cluster"]
    clusters: List[ClusterId]

class MarketScope_2(BaseModel):
    model_config = ConfigDict(extra="forbid")
    """Manual list (fallback)"""
    mode: Literal["manual"]
    condition_ids: List[ConditionId]

MarketScope = Union[MarketScope_1, MarketScope_2]

class OrderIntent(BaseModel):
    model_config = ConfigDict(extra="forbid")
    """The artefact Strategy emits and Risk evaluates. Risk has no input until a Strategy has produced an OrderIntent. Risk MAY reshape (emits STRAT_RESHAPED_BY_RISK) or block; both paths are audited."""
    intent_id: str
    strategy_id: StrategyId
    portfolio_id: PortfolioId
    condition_id: ConditionId
    side: Side
    order_type: OrderType
    limit_price: Optional[Decimal] = None
    size_pusd: Decimal
    max_slippage_bps: Optional[int] = None
    ts: ISO8601
    signal_ref: Optional[str] = None

class PortfolioConfig(BaseModel):
    model_config = ConfigDict(extra="forbid")
    """Portfolio is the unit of account. Strategies, positions, signals and risk all hang off a Portfolio."""
    portfolio_id: PortfolioId
    label: str
    balance_pusd: Decimal
    guardrails: Dict[str, Any]
    bound_strategies: List[StrategyId]

class Signal(BaseModel):
    model_config = ConfigDict(extra="forbid")
    """A scored observation emitted by a Strategy bot for one market at one moment. Inputs to Risk are OrderIntents, not Signals. Signals are the upstream artefact a Strategy uses to decide whether to emit an OrderIntent."""
    signal_id: str
    strategy_id: StrategyId
    portfolio_id: PortfolioId
    condition_id: ConditionId
    score_type: ScoreType
    strategy_score: Decimal
    side: Side
    ts: ISO8601
    reason: Optional[ReasonCode] = None

class StrategyConfig(BaseModel):
    model_config = ConfigDict(extra="forbid")
    """What a strategy needs to launch. Portfolio binding + market scope + score contract + params. M2 ships momentum only."""
    strategy_id: StrategyId
    family: Literal["momentum"]
    target_portfolio: PortfolioId
    score_type: ScoreType
    market_scope: MarketScope
    params: Dict[str, Any]
    mode: Literal["docs-complete", "demo-wired", "limited_live", "wide_live"]

