Fix unmanaged reconciliation review blockers
Co-authored-by: genichin <4282227+genichin@users.noreply.github.com>
This commit is contained in:
co-authored by
genichin
parent
f9284d1de8
commit
591db7adb7
@@ -0,0 +1,18 @@
|
||||
---
|
||||
id: "ac-0029"
|
||||
status: active
|
||||
---
|
||||
|
||||
# Durable unmanaged-position lifecycle, authority boundary, and operator audit
|
||||
|
||||
## Criterion
|
||||
|
||||
`trex-core`는 broker-only unmanaged holding을 `(instance_key, symbol)` keyed durable lifecycle state로 추적해야 한다. State는 `quantity`, `first_seen_at`, `last_seen_at`, `quantity_changed_at`, `resolved_at`, lifecycle state와 latest non-secret operator disposition/evidence를 제공해야 한다. `reconcile_core_holdings()`는 authoritative full-balance snapshot에서만 unresolved active rows의 absence를 `resolved`로 전이할 수 있으며, marker가 없거나 projected/partial balance인 broker reader는 resolve authority가 없다. 동일 active lifecycle에서 같은 수량 반복 관측은 새 lifecycle alarm/audit를 만들지 않고 `last_seen_at`만 갱신해야 한다. 운영자 disposition은 explicit evidence-backed command로만 기록되고 audit trail에 append되어야 하며, current state 조회와 audit 조회 모두 inspectable해야 한다. 이 기능은 broker 주문, slot/ledger mutation, warning 자동 삭제 또는 manual-holding cause inference를 수행해서는 안 된다.
|
||||
|
||||
## Verification
|
||||
|
||||
- Identity/lifecycle: 같은 symbol을 서로 다른 `instance_key`에서 독립 row로 저장하고, first detect → same-qty repeat → quantity change → authoritative absence resolved → re-detect reopen 순서를 InMemory/PostgreSQL parity tests로 검증한다.
|
||||
- Authority boundary: missing marker, `False`, exception-throwing marker, ownership/projected broker, broker read failure 각각에서 active unmanaged row가 resolved 되지 않음을 검증한다. Explicit authoritative broker만 absence resolution을 수행해야 한다.
|
||||
- Runtime wiring: production broker provider/daemon/snapshot scheduler tests에서 주문용 projected broker와 unmanaged reconciliation용 authoritative full-balance reader가 분리 주입되는지 고정한다.
|
||||
- Operator audit: CLI/parser/store tests에서 `unmanaged list`, evidence-required `unmanaged record`, symbol별 `unmanaged audit`를 검증하고 audit actor가 caller-supplied arbitrary string이 아니라 trusted local identity에서 결정됨을 확인한다.
|
||||
- Safety boundary: any unmanaged lifecycle path에서 broker order submit/cancel, slot create/mutate, synthetic ledger write, warning auto-clear가 발생하지 않음을 existing regression surface와 focused tests로 유지한다.
|
||||
@@ -1,5 +1,5 @@
|
||||
{
|
||||
"schema_version": 1,
|
||||
"next_line_number": 10,
|
||||
"next_ac_number": 29
|
||||
"next_line_number": 11,
|
||||
"next_ac_number": 30
|
||||
}
|
||||
|
||||
@@ -0,0 +1,26 @@
|
||||
---
|
||||
id: "dcy-0010"
|
||||
status: confirmed
|
||||
---
|
||||
|
||||
# Durable unmanaged-position lifecycle
|
||||
|
||||
## Problem
|
||||
|
||||
현재 `reconcile_core_holdings()`는 broker 계정에만 존재하고 대상 `instance_key`의 managed slot·ledger에 없는 종목을 `unmanaged_position` warning/log로만 표면화한다. 이 상태는 매 주기 반복 관측되어도 최초 감지, 수량 변경, 해제, 운영자 triage 여부를 durable하게 구분하지 못한다. 또한 ownership projection이 켜진 KIS 경로에서는 전략용 projected balance가 manual/타 instance 보유를 제거하므로, reconciliation이 실제 broker-only unmanaged position을 아예 보지 못할 수 있다.
|
||||
|
||||
## Evidence
|
||||
|
||||
- GitHub issue [#85](https://github.com/fourblocks2020/trex-core/issues/85)는 unmanaged identity를 `(instance_key, symbol)`로 격리하고, 최초 감지·수량 변경·해제와 마지막 broker 관측 시각을 durable하게 보존하며, 같은 수량 반복 관측의 로그/알림 폭주를 억제할 것을 요구한다.
|
||||
- Issue 본문은 운영자가 broker evidence와 함께 managed inclusion, approved exception, investigating disposition을 기록할 수 있어야 하고, broker 조회 실패 또는 partial/projected balance 부재를 quantity 0이나 resolved로 해석해서는 안 된다고 명시한다.
|
||||
- 현재 ownership wrapper `get_balance()`는 strategy ownership projection만 반환하므로 unmanaged/manual holdings를 숨긴다. 따라서 production wiring은 주문용 projected broker와 별도로 authoritative full-balance reader를 reconciliation에 주입해야 한다.
|
||||
- 현행 문서 `docs/interface-contract.md`와 `docs/runtime-flows.md`는 broker-only 분류가 persistence나 DB schema를 바꾸지 않는다고 적고 있어, 새 durable lifecycle contract를 소유하는 승인된 AC가 필요하다.
|
||||
|
||||
## Scope
|
||||
|
||||
- 이 Line은 broker-only `unmanaged_position`을 `(instance_key, symbol)` keyed durable lifecycle state로 저장하고, `quantity`, `first_seen_at`, `last_seen_at`, `quantity_changed_at`, `resolved_at`, lifecycle state 및 non-secret operator evidence를 조회 가능하게 하는 contract를 다룬다.
|
||||
- Reconciliation은 authoritative full-balance snapshot에서만 부재 해제를 수행한다. Marker가 없거나 projected/partial balance인 reader는 detect/update에는 사용할 수 있어도 resolve authority를 갖지 않는다.
|
||||
- Ownership-aware trading broker는 그대로 주문/전략 조회에 사용하되, unmanaged reconciliation 입력은 별도의 authoritative balance reader를 사용한다.
|
||||
- 동일 active lifecycle에서 반복 같은 수량 관측은 `last_seen_at`만 갱신하고 새 detect/change alarm·audit를 만들지 않는다. Resolved 후 재탐지되면 새 active lifecycle로 reopen되며 이전 operator disposition 현재값은 carry-over 하지 않는다.
|
||||
- 운영자 disposition은 explicit command와 evidence reference를 요구하고 audit trail에 append된다. CLI는 current state와 audit trail을 둘 다 조회 가능해야 한다.
|
||||
- 이 Line은 broker 주문, slot 생성, synthetic ledger backfill, warning 자동 삭제 또는 manual holdings의 원인 추정을 도입하지 않는다.
|
||||
@@ -0,0 +1,3 @@
|
||||
---
|
||||
id: "line-0010"
|
||||
---
|
||||
@@ -0,0 +1,40 @@
|
||||
---
|
||||
id: "req-0010"
|
||||
status: approved
|
||||
discovery: "dcy-0010"
|
||||
criteria:
|
||||
create:
|
||||
- "ac-0029"
|
||||
update: []
|
||||
retire: []
|
||||
satisfy: []
|
||||
---
|
||||
|
||||
# Durable unmanaged-position lifecycle
|
||||
|
||||
## Objective
|
||||
|
||||
`trex-core`는 broker 계정에 존재하지만 대상 `instance_key`의 managed slot·ledger가 소유하지 않는 종목을 stateless warning이 아니라 durable unmanaged-position lifecycle로 추적해야 한다. Lifecycle은 authoritative broker balance를 근거로 `(instance_key, symbol)`별 최초 감지, 수량 변경, 마지막 관측, 해제, 운영자 disposition과 audit를 구분해야 하며, 반복 같은 수량 관측의 로그/알림 폭주를 억제해야 한다.
|
||||
|
||||
## Scope
|
||||
|
||||
- Unmanaged identity는 `(instance_key, symbol)`이며 다른 instance/account의 같은 symbol과 섞이지 않는다.
|
||||
- Persistent state는 최소 `symbol`, `quantity`, `first_seen_at`, `last_seen_at`, `quantity_changed_at`, `resolved_at`, lifecycle state와 latest non-secret operator evidence/disposition을 제공한다.
|
||||
- `reconcile_core_holdings()`는 authoritative broker snapshot에서 broker-only holding을 처음 보면 `detected`, 수량이 바뀌면 `quantity_changed`, 이전 active row가 authoritative snapshot에서 사라지면 `resolved`로 기록한다. 같은 수량 반복 관측은 state의 `last_seen_at`만 갱신한다.
|
||||
- Broker 조회 실패, missing authoritative marker, projected ownership balance, filtered/partial reader 또는 self-report failure는 resolved authority가 아니다. 이런 입력 부재를 quantity 0이나 resolved로 해석하지 않는다.
|
||||
- Runtime wiring은 주문/전략용 broker projection과 unmanaged reconciliation용 authoritative full-balance reader를 분리한다.
|
||||
- 운영자 disposition은 explicit command와 `evidence_ref`를 요구하고 audit trail에 append한다. Caller-supplied arbitrary actor string은 현재 계약에 포함하지 않고 trusted local CLI identity만 기록한다.
|
||||
- Resolved row가 다시 나타나면 `first_seen_at`은 유지하되 새 active lifecycle로 reopen한다. Audit history는 남기고 current operator disposition/evidence는 reset한다.
|
||||
- Query surface는 current state list와 symbol별 audit trail을 모두 제공한다.
|
||||
|
||||
## Constraints
|
||||
|
||||
- 이 기능은 slot 생성, slot 상태 변경, warning 자동 삭제, synthetic BUY ledger, broker order submit/cancel 또는 manual holdings 원인 추정을 수행하지 않는다.
|
||||
- `managed_non_holding_divergence`와 기존 reconcile warning lifecycle·clear authority는 유지한다.
|
||||
- Normative Design Documents: 없음. 이 REQ와 AC-0029가 normative specification을 소유한다.
|
||||
|
||||
## Non-Goals
|
||||
|
||||
- Broker statement ingestion, manual holding 원인 판정, 자동 편입/자동 정정
|
||||
- AMQP/portfolio-hub external wire 변경
|
||||
- Ledger remediation, slot lifecycle 재설계, ownership model 변경
|
||||
Reference in New Issue
Block a user