# State Machine & Reconciliation

## 1. 목적

이 문서는 Phase 6 실행 엔진의 상태머신과 reconciliation 절차를 정의합니다.
실전 시스템에서 가장 위험한 문제는 **내부 상태와 브로커 상태가 어긋나는 것**이므로,
reconciliation은 보조 작업이 아니라 핵심 기능입니다.

## 2. 핵심 엔티티

### 2.1 Execution Session
하루의 운영 세션 단위.

필수 필드:
- `execution_session_id`
- `env`
- `trade_date`
- `mode` (`dry_run`, `paper`, `live`)
- `strategy_scope`
- `status`
- `started_at`
- `ended_at`

### 2.2 Order Plan
전략 후보를 실행 가능한 주문 계획으로 변환한 결과.

### 2.3 Order Intent
실제로 한 번 제출하려는 logical action.
예: entry, exit_half, exit_final, stop_exit, cancel_all.

### 2.4 Broker Order
브로커가 인식하는 주문.
하나의 Order Intent가 broker replace 과정에서 여러 broker order로 이어질 수 있다.

### 2.5 Position State
실제 체결 기반 포지션 상태.

## 3. 상위 상태머신

### 3.1 Candidate Execution State

```text
candidate_ready
-> planned
-> risk_checked
-> awaiting_approval
-> approved
-> entry_submitted
-> entry_working
-> entry_partially_filled
-> position_open
-> exit_pending
-> partially_exited
-> fully_closed
-> abandoned
-> error
```

### 3.2 Position Lifecycle

```text
no_position
-> opening
-> open
-> reducing
-> closed
-> orphaned
```

### 3.3 Session Lifecycle

```text
booting
-> pre_open_checks
-> active
-> soft_halt
-> hard_halt
-> closing
-> reconciliation
-> closed
-> failed
```

## 4. Event Sourcing 원칙

가능하면 상태를 직접 수정하기보다 event를 append하고 projection으로 현재 상태를 만든다.

필수 이벤트:
- candidate_loaded
- risk_decision_recorded
- approval_ticket_created
- approval_decided
- order_intent_created
- order_submitted
- order_acknowledged
- order_partially_filled
- order_filled
- order_cancel_requested
- order_cancelled
- order_replaced
- order_rejected
- position_opened
- position_reduced
- position_closed
- reconciliation_mismatch_detected
- reconciliation_resolved
- manual_operator_action
- session_halted
- session_resumed

## 5. Reconciliation 유형

### 5.1 주문 대사
비교 대상:
- 내부 open orders
- 브로커 open orders
- 최근 fill ledger

체크 항목:
- broker_order_id 누락
- client_order_id 중복
- 내부는 working인데 브로커엔 없음
- 브로커는 filled인데 내부는 accepted 상태
- cancel 요청 후 실제 잔존 여부

### 5.2 포지션 대사
비교 대상:
- 내부 position state
- 브로커 position snapshot

체크 항목:
- 수량 불일치
- 평균단가 불일치
- symbol 누락
- 브로커에만 존재하는 orphan position

### 5.3 세션 대사
- 장 종료 후 미처리 ticket 존재 여부
- 미완료 order intent 존재 여부
- kill switch 상태 복구 여부

## 6. Reconciliation 주기

- 장 시작 전: full sync
- 장중: 짧은 interval incremental sync
- submit/cancel/replace 직후: targeted sync
- 장 종료 후: final full sync
- 재시작 직후: mandatory full sync

## 7. 충돌 해결 규칙

원칙적으로 **브로커 체결 사실**을 가장 강한 truth로 본다.
다만 브로커 API 지연/일시 불일치가 있을 수 있으므로, 아래 우선순위를 따른다.

1. confirmed fill / position snapshot
2. fetch order by broker id
3. stream event
4. 내부 optimistic state

### 예시 1: submit timeout
- 내부 상태는 `submitted_pending_confirmation`
- 즉시 재제출하지 않는다.
- 먼저 client_order_id 기반 조회 또는 full reconciliation 수행

### 예시 2: cancel 요청 후 fill 도착
- fill 이벤트가 cancel보다 우선한다.
- 남은 수량만 취소되도록 재계산

### 예시 3: 프로세스 재시작
- 마지막 checkpoint 이후 미확정 intent를 모두 reconciliation queue에 올린다.
- broker 상태를 먼저 읽고 projection을 복구한 뒤에만 신규 주문 허용

## 8. Checkpoint / Recovery

다음은 checkpoint 대상이다.
- current session state
- active candidate executions
- open positions
- working orders
- latest broker cursor / stream cursor
- kill switch 상태
- approval pending 목록

복구 절차:
1. durable state load
2. broker full sync
3. mismatch resolution
4. projection rebuild
5. safe-to-trade 판단
6. 신규 주문 재개 여부 결정

## 9. 운영자 수동 개입

운영자가 브로커 화면에서 직접 주문/취소/청산한 경우를 고려해야 한다.
필수 규칙:
- manual action은 별도 event로 기록
- reconciliation 시 수동 개입 감지 시 operator note 요구
- 내부 상태는 브로커 상태로 수렴
- 수동 개입이 잦은 전략/구간은 별도 review 대상
