From 1a2b50072238ea72186d99b3ec951fc9511100aa Mon Sep 17 00:00:00 2001 From: Hermes Agent Date: Fri, 14 Aug 2026 15:58:39 +0900 Subject: [PATCH] docs(proofline): specify issue 58 completion evidence --- .proofline/criteria/ac-0009.md | 16 +++++ .proofline/criteria/ac-0010.md | 16 +++++ .proofline/criteria/ac-0011.md | 16 +++++ .proofline/criteria/ac-0012.md | 16 +++++ .proofline/criteria/ac-0013.md | 16 +++++ .proofline/identities.json | 2 +- .../evidence/implementation-complete.md | 53 ++++++++++++++ .../evidence/implementation-progress.md | 70 +++++++++++++++++++ .proofline/lines/line-0003/req-0003.md | 57 +++++++++++++++ 9 files changed, 261 insertions(+), 1 deletion(-) create mode 100644 .proofline/criteria/ac-0009.md create mode 100644 .proofline/criteria/ac-0010.md create mode 100644 .proofline/criteria/ac-0011.md create mode 100644 .proofline/criteria/ac-0012.md create mode 100644 .proofline/criteria/ac-0013.md create mode 100644 .proofline/lines/line-0003/evidence/implementation-complete.md create mode 100644 .proofline/lines/line-0003/evidence/implementation-progress.md create mode 100644 .proofline/lines/line-0003/req-0003.md diff --git a/.proofline/criteria/ac-0009.md b/.proofline/criteria/ac-0009.md new file mode 100644 index 0000000..7d49359 --- /dev/null +++ b/.proofline/criteria/ac-0009.md @@ -0,0 +1,16 @@ +--- +id: "ac-0009" +status: active +--- + +# 주문 timeout 기본값과 입력 검증 + +## Criterion + +매수·매도 intent가 `timeout_sec`를 생략하거나 `null`로 전달하면 인스턴스의 `default_order_timeout_sec`를 사용하고, 인스턴스 기본값도 없으면 hard fallback `3600`초를 effective timeout으로 저장해야 한다. 전략 timeout과 인스턴스 기본값은 bool·문자열·실수를 포함한 비정수 값을 허용하지 않는 strict integer `1..3600` 범위여야 한다. 전략 입력이 이 계약을 위반하면 clamp 또는 주문 제출 없이 `bad_request`로 거부하고, 인스턴스 설정이 위반하면 daemon이 주문 실행 전에 설정 오류로 시작에 실패해야 한다. 경계값 `1`과 `3600`은 매수·매도 모두 허용해야 한다. + +## Verification + +- 성공 조건: 매수·매도에서 생략과 `null`이 instance override 또는 `3600`으로 저장되고, explicit integer `1`, 중간값과 `3600`이 그대로 승인된다. +- 실패·경계 조건: bool, 문자열, 실수, `0`, 음수와 `3601` 이상은 묵시적 변환·clamp·slot admission·broker submission 없이 거부되며, 잘못된 daemon 설정은 startup config error가 된다. +- 검사 방법: `tests/application/test_order_timeout_reconciliation.py`의 direct/wire/config 경계 테스트와 `tests/application/test_execution_policy_handler.py`, `tests/application/test_execution_policy.py`의 매수·매도 회귀를 실행한다. diff --git a/.proofline/criteria/ac-0010.md b/.proofline/criteria/ac-0010.md new file mode 100644 index 0000000..be0f3a6 --- /dev/null +++ b/.proofline/criteria/ac-0010.md @@ -0,0 +1,16 @@ +--- +id: "ac-0010" +status: active +--- + +# 원주문 timeout 기준점과 주문일 영속성 + +## Criterion + +주문 dispatch 시 effective `timeout_sec`, immutable UTC `order_submitted_at`과 그 시각에서 산출한 KST `order_date`를 슬롯에 원자적으로 영속화해야 한다. 일반 `updated_at` 변경, polling, cancel bookkeeping과 broker order ID resolution은 이 anchor를 변경하지 않아야 하며 terminal 전이에서만 정리해야 한다. daemon 재시작과 KST 날짜 rollover 뒤에도 저장된 제출 시각으로 동일 deadline을 계산하고 저장된 원주문 날짜로 KIS 주문을 조회해야 한다. migration 이전 legacy pending row의 원주문 metadata가 없으면 `created_at`·`updated_at` 또는 현재 날짜로 추정하지 않고 fail-closed unresolved로 남겨야 하며, in-memory와 PostgreSQL 저장소는 같은 column·CAS·보존 동작을 제공해야 한다. + +## Verification + +- 성공 조건: dispatch, cancel outcome, `replace_dispatch`, 반복 poll과 repository 재생성 뒤에도 anchor가 동일하고, 다음 KST 날짜의 poll도 원주문 날짜를 조회한다. terminal 전이에서는 anchor와 cancel metadata가 계약대로 정리된다. +- 실패·경계 조건: migration이 legacy row에 날짜를 backfill하거나 metadata 없는 일반 주문이 현재 날짜 KIS 조회·terminal 전이·cancel·ledger 기록을 수행하면 FAIL이다. mutable timestamp가 deadline 또는 조회일을 이동시켜도 FAIL이다. +- 검사 방법: migration SQL discovery, `tests/application/test_order_timeout_reconciliation.py`의 migration·restart·rollover·legacy adversarial tests, `tests/adapters/persistence/test_postgresql_slot_repository_parity.py`와 PostgreSQL integration test를 실행한다. diff --git a/.proofline/criteria/ac-0011.md b/.proofline/criteria/ac-0011.md new file mode 100644 index 0000000..b13f4d6 --- /dev/null +++ b/.proofline/criteria/ac-0011.md @@ -0,0 +1,16 @@ +--- +id: "ac-0011" +status: active +--- + +# timeout 취소와 terminal 주문상태 권위 + +## Criterion + +주문의 effective timeout 도달은 슬롯을 강제 terminal state로 전환하는 조건이 아니라 취소/reconciliation을 시작하는 조건이어야 한다. 실행 루프는 취소 전에 원주문 날짜로 최신 주문 상태를 조회하고, 이미 전량체결·전량취소·terminal reject가 확인되면 해당 terminal 경로를 우선 적용해야 한다. cancel API의 `REQUESTED`, `REJECTED`, `UNKNOWN`은 모두 nonterminal이며, 슬롯의 최종 상태와 체결수량은 KIS 주문조회 terminal evidence 및 broker 잔고에 의해서만 확정해야 한다. 주문 row 없음은 bounded visibility grace 또는 그 이후 unresolved로 구분하되 어느 경우에도 row 부재만으로 terminal 상태를 추론하지 않아야 한다. + +## Verification + +- 성공 조건: timeout 이전에는 cancel이 없고, timeout 이후 nonterminal 주문에만 cancel을 요청한다. cancel과 전량체결 경합에서는 체결 경로가 우선하며 cancel 응답만으로 슬롯이 해제되지 않는다. +- 실패·경계 조건: 로컬 timeout, cancel `REQUESTED/REJECTED/UNKNOWN`, HTTP transport 결과, KIS message code 또는 주문 row 부재가 단독으로 슬롯 terminal 전이·보유량 0·ledger 체결을 만들면 FAIL이다. +- 검사 방법: `tests/application/test_order_timeout_reconciliation.py`, `tests/application/test_execution_cancel.py`, `tests/adapters/broker/test_kis_cancel.py`와 KIS submission recovery virtual integration을 실행하여 poll-before-cancel, original-date authority, visibility grace와 full-fill race를 검증한다. diff --git a/.proofline/criteria/ac-0012.md b/.proofline/criteria/ac-0012.md new file mode 100644 index 0000000..f2e6ce1 --- /dev/null +++ b/.proofline/criteria/ac-0012.md @@ -0,0 +1,16 @@ +--- +id: "ac-0012" +status: active +--- + +# 미확정 취소의 fail-closed 재조정과 경보 + +## Criterion + +cancel `REQUESTED`, `REJECTED`, `UNKNOWN` 또는 visibility grace 이후 terminal 미확정 상태에서는 슬롯을 pending/reconciliation으로 유지하고 daemon 재시작 뒤에도 authoritative polling을 계속해야 한다. `REQUESTED`는 blind retry하지 않아야 하며, `REJECTED` 또는 `UNKNOWN` 재시도는 KIS 조회가 주문을 여전히 open으로 확인한 경우에만 CAS 보호된 최대 시도 횟수와 bounded exponential backoff 안에서 허용해야 한다. `REJECTED`·`UNKNOWN`이 terminal 미확정이거나, `REQUESTED` 후 authoritative poll 결과가 `unknown` 또는 `order_not_visible_unresolved`이면 CRITICAL alarm으로 알려야 한다. 동일 프로세스의 같은 slot·state·attempt alarm은 중복 폭주를 막고 새 프로세스에서는 재발행할 수 있어야 한다. alarm은 allowlist metadata만 포함하고 raw KIS payload, exception·credential·token·connection string을 포함하지 않아야 한다. + +## Verification + +- 성공 조건: rejected/unknown이 pending을 유지하고 CRITICAL alarm을 발행하며, open-confirmed evidence와 backoff·attempt 조건을 모두 만족한 경우에만 한정 재시도가 일어난다. requested 후 `unknown` 또는 `order_not_visible_unresolved` 반복 poll의 alarm은 프로세스 내 1회로 dedupe되고 restart 모사에서는 재발행된다. requested 상태에서 주문이 open으로 확인된 경우에는 pending과 no-retry를 유지하되 unresolved alarm을 요구하지 않는다. +- 실패·경계 조건: open evidence 없는 accepted/missing/unknown에서 추가 cancel이 발생하거나, requested를 재시도하거나, 최대 시도·CAS를 우회하거나, alarm에 raw payload·민감 fixture가 포함되거나, 미확정 주문의 슬롯이 재사용 가능 상태가 되면 FAIL이다. +- 검사 방법: `tests/application/test_order_timeout_reconciliation.py`의 requested dedupe/restart 및 rejected/unknown open-confirmed bounded retry tests와 alarm emitter contract를 실행하고 rendered log·alarm fields를 점검한다. diff --git a/.proofline/criteria/ac-0013.md b/.proofline/criteria/ac-0013.md new file mode 100644 index 0000000..78a4c9d --- /dev/null +++ b/.proofline/criteria/ac-0013.md @@ -0,0 +1,16 @@ +--- +id: "ac-0013" +status: active +--- + +# 장마감 자동취소와 체결 경합의 슬롯·원장 정합성 + +## Criterion + +KIS 주문조회가 장마감 자동취소의 terminal evidence를 제공하면 무체결 초기 매수는 `PENDING_BUY → INACTIVE`, 무체결 증액 매수는 broker 기존 보유량 기준 `PENDING_BUY → HOLDING`으로 전환해야 한다. 매수 부분체결 후 잔량취소는 체결분을 deterministic execution identity로 ledger에 exactly-once 기록하고 broker 잔고 기준으로 `HOLDING`을 확정해야 한다. 매도 무체결 또는 부분체결 후 잔량취소는 broker 잔고에 따라 `HOLDING` 또는 기존 terminal sell 경계를 적용해야 하며, 취소 flag와 전량체결이 경합하면 전량체결 경로를 우선해야 한다. 반복 polling·outbox 재처리·daemon 재시작은 슬롯수량이나 ledger 체결을 중복시키지 않아야 한다. + +## Verification + +- 성공 조건: 초기/증액 매수 무체결, 매수·매도 부분체결, 전량체결 race가 각각 정해진 슬롯 상태·broker-authoritative 수량·ledger 결과를 만들고 동일 execution의 반복 처리에도 ledger item은 하나다. +- 실패·경계 조건: 부분체결을 전량취소로 소실하거나, 전량체결을 취소로 rollback하거나, 로컬 추정수량을 broker 잔고보다 우선하거나, 동일 체결을 중복 ledger 기록하거나, terminal evidence 없이 상태를 확정하면 FAIL이다. +- 검사 방법: `tests/application/test_execution_cancel.py`, `tests/application/test_execution_ledger.py`, `tests/adapters/broker/test_kis_cancel.py`와 `tests/application/test_order_timeout_reconciliation.py`를 실행하여 zero/partial/full race, broker balance authority와 deterministic ledger idempotency를 검증한다. diff --git a/.proofline/identities.json b/.proofline/identities.json index e53e86e..42fa78c 100644 --- a/.proofline/identities.json +++ b/.proofline/identities.json @@ -1,5 +1,5 @@ { "schema_version": 1, "next_line_number": 4, - "next_ac_number": 9 + "next_ac_number": 14 } diff --git a/.proofline/lines/line-0003/evidence/implementation-complete.md b/.proofline/lines/line-0003/evidence/implementation-complete.md new file mode 100644 index 0000000..2810dc1 --- /dev/null +++ b/.proofline/lines/line-0003/evidence/implementation-complete.md @@ -0,0 +1,53 @@ +# 구현 완료 evidence + +이 파일은 ProofLine canonical lifecycle artifact가 아닌 GitHub issue comment 원문 evidence입니다. + +- Source URL: https://github.com/fourblocks2020/trex-core/issues/58#issuecomment-5290331952 +- Comment ID: `5290331952` +- Author: `genichin` +- Created at: `2026-08-14T06:41:15Z` +- Updated at: `2026-08-14T06:41:15Z` +- Original body SHA-256: `10ea8235709eda917a9e64a6434a4f01ac9cd630ea965ce48d6134f0a4e0c22e` +- Captured from GitHub API: `2026-08-14` + +## Original Comment Body + + +## 구현 완료 + +승인된 #58 범위의 주문 timeout·장마감 자동취소·부분체결 reconciliation 구현과 독립 검증을 완료했습니다. + +### 구현 내용 + +- 매수·매도 주문 timeout 생략 또는 `null` 시 3,600초 fallback 적용 +- 전략 및 인스턴스 timeout을 strict integer `1..3600`으로 검증하고 잘못된 값은 주문 제출 전에 거부 +- 원주문 제출 시각·KST 주문일·effective timeout을 일반 `updated_at`과 분리하여 영속화하고 재시작·날짜 rollover 후에도 보존 +- 취소 `REQUESTED`/`REJECTED`/`UNKNOWN`을 nonterminal로 유지하고 KIS 주문조회를 terminal authority로 사용 +- legacy 주문 metadata 미확인 시 현재 날짜를 추정하지 않고 poll·terminal 전이·cancel·ledger 처리를 차단하는 fail-closed 경로 구현 +- authoritative open evidence가 있는 `REJECTED`/`UNKNOWN`에만 bounded backoff retry를 허용하고 blind retry 차단 +- 무체결·부분체결·전량체결 경합, ledger exactly-once, alarm dedupe 및 restart 재발행 회귀 테스트 보강 +- PostgreSQL migration 및 in-memory/PostgreSQL persistence parity, 데이터 모델·interface contract 갱신 + +### 검증 결과 + +집중·전체 테스트와 독립 read-only QC를 모두 통과했으며, 신규 차단 finding은 없습니다. + +- 최종 HEAD: `843df1d6f1a642282039a57d0de4ca85204d6bee` +- 팀장 focused suite: `114 passed, 1 skipped` +- 독립 QC focused suite: `148 passed, 1 skipped` +- 전체 suite: `1,040 passed, 51 skipped` +- Ruff: `All checks passed!` +- `proofline validate`: exit `0` +- `git diff --check` 및 commit/worktree immutability 확인: 통과 +- 독립 QC: **PASS**, `mutation=false`, 신규 finding 없음 +- legacy adversarial probe: broker poll·cancel·slot transition·ledger 기록 모두 0, pending 유지 및 sanitized CRITICAL alarm 확인 + +### 비차단 후속 권고 + +- `TREX_POSTGRESQL_TEST_DSN`이 준비되면 PostgreSQL migration/repository integration 41건을 실제 DB에서 재실행 +- `TREX_RABBITMQ_TEST_URL`이 준비되면 RabbitMQ integration 9건을 재실행 +- 안전한 KIS sandbox credential이 준비되면 sandbox integration 1건을 재실행 + +> 현재 상태는 **격리 브랜치의 로컬 구현·검증·커밋 완료**입니다. push·PR·main 반영·배포·릴리스 완료를 의미하지 않습니다. + + diff --git a/.proofline/lines/line-0003/evidence/implementation-progress.md b/.proofline/lines/line-0003/evidence/implementation-progress.md new file mode 100644 index 0000000..8feaa27 --- /dev/null +++ b/.proofline/lines/line-0003/evidence/implementation-progress.md @@ -0,0 +1,70 @@ +# 구현 진행 상황 evidence + +이 파일은 ProofLine canonical lifecycle artifact가 아닌 GitHub issue comment 원문 evidence입니다. + +- Source URL: https://github.com/fourblocks2020/trex-core/issues/58#issuecomment-5290005799 +- Comment ID: `5290005799` +- Author: `genichin` +- Created at: `2026-08-14T05:55:12Z` +- Updated at: `2026-08-14T06:38:38Z` +- Original body SHA-256: `471c6b3b5a70a1632e6e1d4076014a2cf967ffb45bba8ff3bffe122fee39e037` +- Captured from GitHub API: `2026-08-14` + +## Original Comment Body + + +## 구현 진행 상황 + +**상태:** 🟢 구현·검증 완료 + +### 구현 계획 및 작업 목록 + +- [x] **1. 구현 기준선과 영향 범위 확인** + - 승인된 #58 본문을 변경 범위의 기준으로 고정 + - timeout 계산, 주문 제출정보 영속화, KIS 주문조회, 취소상태, alarm 및 migration 경로 확인 +- [x] **2. 기본 timeout 및 입력 검증 구현** + - timeout 생략 또는 `null`이면 매수·매도 모두 3,600초 적용 + - 전략 payload와 인스턴스 설정은 `1..3600`초만 허용 + - 범위 밖 값은 clamp하지 않고 주문 제출 전에 명시적으로 거부 +- [x] **3. 원주문 시각·날짜 영속화와 재시작 복구 구현** + - timeout 기준점과 KIS 주문 조회일을 일반 `updated_at`과 분리 + - 날짜가 넘어가거나 daemon이 재시작돼도 원주문 날짜로 상태 조회 +- [x] **4. 장마감 취소 실패 후 fail-closed reconciliation 구현** + - 취소 API의 `REQUESTED/REJECTED/UNKNOWN`을 terminal 상태로 오인하지 않음 + - terminal broker evidence 전까지 슬롯 재사용 금지 + - 불명확 상태에서 CRITICAL alarm 발생 + - 주문조회로 open 상태를 확인한 경우에만 bounded retry를 허용하고 blind retry 금지 +- [x] **5. 자동취소·부분체결·경합 처리 회귀 보강** + - 무체결 자동취소 + - 부분체결 후 잔량취소와 ledger exactly-once + - 취소와 전량체결 경합 + - 날짜 rollover 및 daemon 재시작 + - 주문 row 미가시성 +- [x] **6. 검증 및 독립 리뷰** + - 관련 집중 테스트 + - 전체 테스트와 lint/정적 검사 + - ProofLine repository validation + - 구현자와 분리된 독립 코드 리뷰 + +### 진행 원칙 + +- 체크박스는 해당 작업이 실제 완료되고 관련 검증이 통과한 뒤에만 갱신합니다. +- 진행 기록은 이 댓글을 계속 수정하여 누적합니다. +- 승인된 구현 계획의 제품 의미나 범위를 변경해야 하면 구현을 중지하고 사용자 승인을 요청합니다. +- 실제 주문, 운영계좌 변경, 배포, release, main push 또는 PR 생성은 이번 작업에 포함하지 않습니다. + +### 진행 기록 + +- 구현 시작: #58의 확정된 Discovery 범위와 OQ 결정 4건을 기준선으로 채택했습니다. +- 기준선/영향 분석 완료: 기본값 `None`, `updated_at` 기반 timeout, KIS 현재일 조회, cancel-state retry 차단 및 신규 persistence migration 필요성을 확인했습니다. +- 격리 작업공간 생성: `feat/issue-58-order-timeout-reconciliation` (`482b00e` 기준). +- 변경 전 기준선 검증 완료: 전체 테스트 `995 passed, 51 skipped`, Ruff/ProofLine/diff check 통과. +- 1차 구현 인스턴스가 핵심 코드·migration·synthetic test를 작성하고 focused suite `95 passed`를 확인했습니다. 전체 검증·커밋 전 실행 한도에 도달하여 동일 worktree에서 후속 인스턴스로 인계했습니다. +- 후속 검수·보완 완료: strict integer 입력, legacy migration fail-closed, 원주문일 rollover, cancel alarm 중복 억제 및 open-evidence 기반 bounded retry를 반영했고 focused suite `141 passed`를 확인했습니다. +- 회귀 보강 완료: wire/config 경계, migration, 재시작, KIS rollover/row 미가시성, 자동취소 및 기존 partial/full-fill·ledger 경로를 포함한 focused suite `154 passed`. +- 구현 commit 생성: `147873cb5d5280a99872aeca0e9b44942b41b3df`. 팀장 재검증에서 핵심 focused `60 passed`, 전체 `1,038 passed, 51 skipped`, Ruff/ProofLine/diff/show check 통과. 환경 의존 integration 51건은 당시 설정 부재로 skip됐습니다. 1차 독립 QC는 FAIL로 반려됐습니다: legacy row의 현재 날짜 fallback으로 인한 terminal 오인 위험과 `REQUESTED` 후 terminal 미확정 CRITICAL 누락을 보완 중입니다. 최종 검증은 미완료입니다. +- QC 보완 commit `843df1d6f1a642282039a57d0de4ca85204d6bee` 생성: legacy metadata 없는 주문의 현재일 조회·terminal 오인을 차단하고, `REQUESTED` 후 terminal unresolved CRITICAL/dedupe를 추가했습니다. post-fix 팀장 검증은 focused `114 passed, 1 skipped`, 전체 `1,040 passed, 51 skipped`, Ruff/ProofLine/diff/show check 통과. 독립 재-QC 진행 중입니다. +- 독립 재-QC 최종 **PASS** (`mutation=false`): focused `148 passed, 1 skipped`, 전체 `1,040 passed, 51 skipped`, Ruff/ProofLine/diff check 통과. legacy adversarial probe에서 broker poll/cancel/transition/ledger가 모두 0이고 pending 및 sanitized CRITICAL alarm을 확인했습니다. skip은 PostgreSQL 41건(DSN 없음), RabbitMQ 9건(URL 없음), KIS sandbox 1건(credential 없음)입니다. 신규 finding은 없습니다. +- 최종 HEAD `843df1d6f1a642282039a57d0de4ca85204d6bee`, worktree clean. push/PR/main 반영/실제 주문/배포는 수행하지 않았습니다. + + diff --git a/.proofline/lines/line-0003/req-0003.md b/.proofline/lines/line-0003/req-0003.md new file mode 100644 index 0000000..81f0c9c --- /dev/null +++ b/.proofline/lines/line-0003/req-0003.md @@ -0,0 +1,57 @@ +--- +id: "req-0003" +status: approved +discovery: "dcy-0003" +criteria: + create: + - "ac-0009" + - "ac-0010" + - "ac-0011" + - "ac-0012" + - "ac-0013" + update: [] + retire: [] + satisfy: [] +--- + +# 주문 기본 timeout 상한과 장마감 자동취소·부분체결 reconciliation + +## Objective + +모든 매수·매도 주문에 최대 3,600초의 실행 timeout을 적용하고, timeout 이후에도 KIS의 authoritative 주문 상태가 확인될 때까지 슬롯을 fail-closed로 보호한다. 원주문 시각·주문일을 영속화하여 날짜 rollover와 daemon 재시작 뒤에도 동일 주문을 재조정하며, 장마감 자동취소와 무체결·부분체결·전량체결 경합을 슬롯 및 ledger에 멱등하게 반영한다. + +## Scope + +- 매수·매도 intent의 timeout 생략 또는 `null`, 인스턴스 기본값 override, 전략·설정 입력 경계와 주문 제출 전 거부를 정의한다. +- effective timeout, immutable 주문 제출 시각과 KST 원주문 날짜를 슬롯 저장소에 영속화하고 in-memory/PostgreSQL 구현 및 migration의 동작을 일치시킨다. +- timeout을 슬롯 terminal 전이가 아닌 취소/reconciliation 시작 조건으로 사용하고, 원주문 날짜를 사용하는 KIS 주문조회를 terminal authority로 유지한다. +- 취소 `REQUESTED`, `REJECTED`, `UNKNOWN`과 주문 row 미가시성을 nonterminal로 처리하며, open 주문 evidence가 있을 때만 제한된 취소 재시도를 허용한다. +- 미확정 주문은 pending 상태로 유지하고 sanitized CRITICAL alarm을 중복 폭주 없이 발행하며, daemon 재시작 뒤 reconciliation을 계속한다. +- KIS 장마감 자동취소의 무체결·부분체결·전량체결 경합을 broker 잔고와 deterministic execution identity에 따라 슬롯 및 ledger에 반영한다. +- repository-local synthetic KIS fixture와 application·adapter·persistence 회귀 테스트로 매수·매도, 날짜 rollover, 재시작, visibility grace, retry와 멱등성을 검증한다. + +## Constraints + +- timeout은 `1..3600`의 strict integer만 허용하며 범위 밖 또는 다른 타입을 clamp하거나 묵시적으로 변환하지 않는다. +- KIS cancel 응답이나 로컬 시간 경과만으로 체결·취소·보유량 0 또는 슬롯 재사용 가능 상태를 추론하지 않는다. +- legacy pending row에 authoritative 원주문 metadata가 없으면 현재 날짜를 추정하지 않고 네트워크 조회·terminal 전이·cancel·ledger 기록을 차단한다. +- account, token, credential, connection string, raw KIS payload와 exception 본문 등 민감하거나 비허용인 값을 alarm·로그·fixture·evidence에 포함하지 않는다. +- portfolio-hub, strategy daemon 및 다른 TREX 서비스의 wire/HTTP 계약을 변경하지 않는다. + +### Current Implementation Assessment + +- 이 문서는 이미 구현된 GitHub issue #58을 현재 ProofLine schema에 사후 명세화한 것이다. 이는 과거 구현이 ProofLine delivery chronology를 따랐다는 뜻이 아니다. +- 현재 구현 기준은 local commit `843df1d6f1a642282039a57d0de4ca85204d6bee`이며, issue evidence에는 전체 `1,040 passed, 51 skipped`, 독립 read-only QC `PASS`가 기록되어 있다. +- 환경 의존 PostgreSQL 41건, RabbitMQ 9건, KIS sandbox 1건은 설정·credential 부재로 skip되었다. 이는 active AC의 규범적 상태와 별개인 비차단 검증 공백이다. +- 이 REQ의 `approved`와 AC의 `active`는 현재 specification authority를 나타내며 push, PR, main 반영, deployment, release 또는 formal lifecycle closure를 의미하지 않는다. + +## Non-Goals + +- KIS 거래소의 주문 유효기간·장마감 자동취소 정책 변경 +- 전략의 매수·매도 조건, 가격·slippage·주문수량 정책 변경 +- portfolio-hub ledger schema 또는 다른 TREX 서비스 계약 변경 +- 운영계좌 실제 주문·취소, 운영 데이터 수정 또는 기존 pending 슬롯의 자동 사후 정리 +- issue #45의 KIS account snapshot fallback 및 장 시작 REST 장애 복구 +- terminal broker evidence 없는 유예시간 기반 강제 슬롯 해제 +- timeout 범위 밖 값을 clamp하는 호환 동작 +- push, PR, main 반영, 배포, release 또는 lifecycle closure