@@ -7,7 +7,7 @@ status: active
|
||||
|
||||
## Criterion
|
||||
|
||||
`case_code=B`(core slot↔KIS 수량 불일치) 또는 `case_code=C`(portfolio-hub↔KIS 수량 불일치) reconcile-warning이 활성인 `holding` slot은 `trex.slots.req.<instance>` 응답에서 제외해야 한다. 동일 slot의 B/C 원인은 서로 덮어쓰지 않고 동시에 보존하며, 응답에는 제외된 slot 수와 활성 case별 count를 포함한다. 신규 buy/sell intent는 같은 durable warning 원인 집합을 재확인하여 `reconcile_warned` 사유로 거부한다. warn-store를 읽지 못하거나 warning metadata가 비어 있거나 지원하지 않는 case를 포함하면 안전한 eligibility를 입증할 수 없으므로 slots RPC는 `degraded=true` / `reason="warn_store_unavailable"`, intent는 `reconcile_warning_unavailable`(조회 실패) 또는 `reconcile_warned`(empty/unsupported metadata)로 fail-closed 처리해야 한다. `sync`는 수량 일치 확인 후 B-case만 해제하고, `verify`는 instance+symbol 단위 KIS와 portfolio-hub 합계가 다시 일치한 경우 C-case만 해제하여 다른 활성 원인을 보존한다. C-case 수량 대조는 **instance_key + symbol 단위 합계**로 수행하며, 개별 portfolio 수량을 KIS 종목 합계와 직접 비교해서는 안 된다. 이 경로는 주문 submit/cancel, ledger write, slot lifecycle mutation을 유발하지 않아야 한다.
|
||||
`case_code=B`(core slot↔KIS 수량 불일치) 또는 `case_code=C`(portfolio-hub↔KIS 수량 불일치) reconcile-warning이 활성인 `holding` slot은 `trex.slots.req.<instance>` 응답에서 제외해야 한다. 동일 slot의 B/C 원인은 서로 덮어쓰지 않고 동시에 보존하며, 응답에는 제외된 slot 수와 활성 case별 count를 포함한다. 신규 buy/sell intent는 같은 durable warning 원인 집합을 재확인하여 `reconcile_warned` 사유로 거부한다. warn-store를 읽지 못하거나 warning metadata가 비어 있거나 지원하지 않는 case를 포함하면 안전한 eligibility를 입증할 수 없으므로 slots RPC는 `degraded=true` / `reason="warn_store_unavailable"`, intent는 `reconcile_warning_unavailable`(조회 실패) 또는 `reconcile_warned`(empty/unsupported metadata)로 fail-closed 처리해야 한다. B-case는 수량 일치 확인을 마친 operator `sync` 또는 AC-0032~AC-0034를 모두 만족해 qty·avg_price·audit·B warning clear가 한 transaction으로 commit된 `auto_reconcile`만 해제할 수 있다. `verify`는 instance+symbol 단위 KIS와 portfolio-hub 합계가 다시 일치한 경우 C-case만 해제하여 다른 활성 원인을 보존한다. C-case 수량 대조는 **instance_key + symbol 단위 합계**로 수행하며, 개별 portfolio 수량을 KIS 종목 합계와 직접 비교해서는 안 된다. 이 경로는 주문 submit/cancel, portfolio-hub 또는 ledger write, slot lifecycle mutation을 유발하지 않아야 한다.
|
||||
|
||||
## Verification
|
||||
|
||||
@@ -23,5 +23,6 @@ status: active
|
||||
- 해제 대상: HOLDING 뿐 아니라 모든 상태의 slot에 걸린 C-case 경고를 포함한다.
|
||||
- 해제 실패: 해제 도중 예외가 발생하면 `result='clear_failed'`를 반환하고 완전 성공으로 보고하지 않아야 한다(부분 성공 = 실패).
|
||||
- 시간이 지났다는 이유만으로 자동 해제하지 않음.
|
||||
- 자동 해제: AC-0032의 authoritative evidence와 eligibility를 통과하고 AC-0033 transaction이 성공한 경우에만 B-case를 해제한다. CAS 실패·불완전 evidence·write 실패에서는 B-case를 유지한다.
|
||||
- 비침습 조건: slots RPC 호출 전후로 slot 상태 전이, broker mutation, ledger write side effect가 없어야 한다.
|
||||
- AC-0022 우선순위: B 또는 C reconcile warning으로 제외된 slot에는 broker-authoritative `qty` 응답 형식(AC-0022)을 적용하지 않는다.
|
||||
|
||||
@@ -7,11 +7,11 @@ status: active
|
||||
|
||||
## Criterion
|
||||
|
||||
`trex-core`는 B-case(core slot quantity와 broker quantity 불일치)를 stable slot별로, C-case(같은 instance·symbol의 portfolio-hub `asset_quantity` 합계와 broker quantity 불일치)를 `instance_key + symbol`별로 하나의 durable notification lifecycle로 추적해야 한다. 새 mismatch와 동일 identity의 case별 비교 quantity tuple 변경은 sanitized `trex.alerts` detected/changed event를 각각 한 번 발행하고, 성공한 publish fingerprint를 process restart 뒤에도 보존하여 unchanged scheduler tick을 억제해야 한다. B-case는 operator `sync`, C-case는 operator `verify`의 authoritative durable warning clear에서만 resolved event를 한 번 발행해야 하며 scheduler 관찰만으로 recovery를 발행해서는 안 된다. Event는 lifecycle state, `instance_key`, `symbol`, `case_code`, broker quantity와 case별 비교 quantity를 포함하고 account number/hash, credential, token, DSN, raw payload와 exception 본문을 포함해서는 안 된다. Publish 성공 뒤에만 fingerprint를 전진시키고 publish 또는 notification-state persistence 실패는 reconciliation, warning set/clear, sync/verify, scheduler와 slot lifecycle을 중단하거나 바꾸지 않아야 한다. Resolved publish 실패 시 notification state가 writable이면 pending transition을 durable하게 보존하여 후속 retry opportunity에서 재발행한다. Notification-state persistence 자체가 실패하면 authoritative warning clear를 유지하고 event 유실 가능성을 sanitized log로 남긴다.
|
||||
`trex-core`는 B-case(core slot quantity와 broker quantity 불일치)를 stable slot별로, C-case(같은 instance·symbol의 portfolio-hub `asset_quantity` 합계와 broker quantity 불일치)를 `instance_key + symbol`별로 하나의 durable notification lifecycle로 추적해야 한다. 새 mismatch와 동일 identity의 case별 비교 quantity tuple 변경은 sanitized `trex.alerts` detected/changed event를 각각 한 번 발행하고, 성공한 publish fingerprint를 process restart 뒤에도 보존하여 unchanged scheduler tick을 억제해야 한다. B-case는 operator `sync` 또는 AC-0033 transaction이 성공한 `auto_reconcile`, C-case는 operator `verify`의 authoritative durable warning clear에서만 resolved event를 한 번 발행해야 하며 수량 일치의 단순 scheduler 관찰만으로 recovery를 발행해서는 안 된다. Event는 lifecycle state, `instance_key`, `symbol`, `case_code`, broker quantity와 case별 비교 quantity를 포함하고 account number/hash, credential, token, DSN, raw payload와 exception 본문을 포함해서는 안 된다. Publish 성공 뒤에만 fingerprint를 전진시키고 publish 또는 notification-state persistence 실패는 reconciliation, warning set/clear, sync/verify/auto_reconcile, scheduler와 slot lifecycle을 중단하거나 바꾸지 않아야 한다. Resolved publish 실패 시 notification state가 writable이면 pending transition을 durable하게 보존하여 후속 retry opportunity에서 재발행한다. Notification-state persistence 자체가 실패하면 authoritative warning clear를 유지하고 event 유실 가능성을 sanitized log로 남긴다.
|
||||
|
||||
## Verification
|
||||
|
||||
- 성공 조건: 새로운 B-case slot mismatch는 B detected event 한 건, 새로운 C-case symbol aggregate mismatch는 portfolio 수와 무관하게 C detected event 한 건을 만든다. 동일 fingerprint의 반복 tick은 추가 event를 만들지 않고 quantity tuple 변경은 changed event 한 건을 만든다. process restart 모사 뒤 unchanged mismatch는 억제되며, B `sync`와 C aggregate `verify` clear는 각 identity의 resolved event 한 건만 만든다.
|
||||
- 성공 조건: 새로운 B-case slot mismatch는 B detected event 한 건, 새로운 C-case symbol aggregate mismatch는 portfolio 수와 무관하게 C detected event 한 건을 만든다. 동일 fingerprint의 반복 tick은 추가 event를 만들지 않고 quantity tuple 변경은 changed event 한 건을 만든다. process restart 모사 뒤 unchanged mismatch는 억제되며, B `sync` 또는 성공한 `auto_reconcile`과 C aggregate `verify` clear는 각 identity의 resolved event 한 건만 만든다.
|
||||
- publish 실패 조건: transport failure에서는 detected/changed/resolved fingerprint가 전진하지 않아야 한다. detected/changed는 다음 동일 detection에서 재시도하고, resolved는 notification state가 writable한 경우 warning clear를 유지하면서 pending transition을 durable하게 보존해 후속 retry opportunity에서 재시도해야 한다. Notification-state persistence 실패도 business path를 중단하지 않아야 하며 resolved event 유실 가능성을 credential·DSN·raw exception 없는 log로 남겨야 한다.
|
||||
- 경계 조건: C-case 동일 symbol의 여러 portfolio/slot이 중복 event를 만들거나, scheduler의 단순 quantity 일치가 durable warning clear·resolved event를 만들거나, B slot 간 fingerprint가 섞이거나, restart 뒤 unchanged event가 재발행되거나, publish 전 fingerprint 기록으로 event가 유실되면 FAIL이다.
|
||||
- 보안·비변경 조건: 모든 lifecycle event의 allowlist fields와 rendered payload에 account number/hash, credential, token, DSN, raw KIS/portfolio-hub payload 및 exception 본문이 없어야 한다. 알림 전후 broker call mutation, portfolio-hub write, slot lifecycle/quantity mutation과 기존 AC-0023 blocking/clear semantics 변화가 없어야 한다.
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
---
|
||||
id: "ac-0032"
|
||||
status: active
|
||||
---
|
||||
|
||||
# B-case auto-reconcile authoritative evidence와 eligibility
|
||||
|
||||
## Criterion
|
||||
|
||||
`reconcile_core_holdings`는 하나의 성공한 broker balance snapshot에서 `broker_qty > 0`이고, 같은 scheduler refresh의 portfolio-hub item이 slot의 `instance_key`·`portfolio_id`·`symbol`과 일치하며 `asset_quantity == broker_qty`일 때만 B-case 자동 동기화를 검토한다. 별도 canonical cost-basis 응답은 같은 portfolio·symbol·current quantity를 증명하고, fetch 시각이 60초 이내이며, `data_completeness_warning`이 없고, 양의 finite `cost_basis_per_unit`과 수량×평단에 일치하는 양의 finite `total_cost_basis`를 제공해야 한다. 대상 slot은 `holding`, 미퇴역, broker dispatch/pending metadata 없음이어야 한다. 첫 구현에서 `inactive`, `pending_buy`, `pending_sell`, `error`, retired slot은 자동 동기화하지 않는다. 어느 evidence든 missing·stale·invalid·불일치이거나 read/set-warning가 실패하면 fail-closed하여 slot과 warning을 변경하지 않는다. Operator `sync`의 legacy/graceful-degrade 계약은 변경하지 않는다.
|
||||
|
||||
## Verification
|
||||
|
||||
- hub·broker 수량과 canonical cost-basis identity/current quantity가 모두 일치하는 holding만 통과한다.
|
||||
- hub/broker mismatch, cost-basis warning·stale·legacy-only·missing·non-finite·0 이하·identity mismatch·total mismatch는 모두 자동 변경 없이 B warning을 유지한다.
|
||||
- broker balance는 reconcile pass당 한 번만 읽고 판단과 write가 같은 snapshot을 사용한다.
|
||||
- pending/dispatch metadata, retired 또는 holding 외 상태는 fail-closed한다.
|
||||
- 기존 `sync_slot_to_broker`의 canonical/legacy diagnostics와 inactive onboarding 회귀 테스트는 그대로 통과한다.
|
||||
@@ -0,0 +1,18 @@
|
||||
---
|
||||
id: "ac-0033"
|
||||
status: active
|
||||
---
|
||||
|
||||
# Holding mirror qty·avg_price·B warning·audit 원자적 갱신
|
||||
|
||||
## Criterion
|
||||
|
||||
AC-0032를 통과한 자동 동기화는 instance advisory lock과 database transaction 안에서 관측한 slot identity/status/qty/avg_price 및 dispatch metadata를 CAS 재검증하고, `qty=broker_qty`, `avg_price=portfolio-hub cost_basis_per_unit` 갱신, `case_code=B` warning만 삭제, `actor=auto_reconcile`·`reason=hub_broker_matched_core_mirror_stale` transition audit 추가를 하나의 commit으로 수행해야 한다. Audit extra에는 allowlist된 before/after qty·avg_price와 hub/broker quantity, portfolio_id, symbol만 포함한다. CAS 실패, B warning 부재 또는 어느 write든 실패하면 네 변경 모두 없어야 한다. C/unknown warning과 다른 instance·symbol·slot은 보존한다. 같은 evidence 재실행은 no-op이며 audit를 중복 추가하지 않는다.
|
||||
|
||||
## Verification
|
||||
|
||||
- 성공 시 slot status는 holding으로 유지되고 qty·avg_price, B clear, audit 한 건이 함께 반영된다.
|
||||
- C와 기타 warning은 보존된다.
|
||||
- CAS race와 강제 예외에서 transaction rollback 후 slot·warning·audit가 모두 이전 상태다.
|
||||
- PostgreSQL 실제 transaction 테스트와 in-memory parity 테스트로 commit, rollback, isolation, idempotency를 검증한다.
|
||||
- broker order submit/cancel, portfolio-hub write, ledger/outbox write는 발생하지 않는다.
|
||||
@@ -0,0 +1,17 @@
|
||||
---
|
||||
id: "ac-0034"
|
||||
status: active
|
||||
---
|
||||
|
||||
# Auto-reconcile scheduler·daemon wiring과 오류 격리
|
||||
|
||||
## Criterion
|
||||
|
||||
Production daemon은 기존 portfolio-hub read adapter, authoritative reconciliation broker, slot persistence, durable warning/notification store를 `SnapshotScheduler`의 B-case auto-reconcile 경로에 명시적으로 연결해야 한다. Scheduler는 성공한 universe refresh의 items와 core-holding worker가 한 번 읽은 complete broker snapshot을 사용하며 ad-hoc broker/Hub write client 또는 legacy cost-basis fallback을 만들지 않는다. Auto-reconcile evidence/read/CAS/transaction 오류는 해당 slot을 `qty_warning`으로 유지하고 scheduler·다른 slot·C-case reconciliation을 중단하지 않는다. 성공 commit 뒤에만 B resolved notification을 발행하며 publish 실패의 pending retry·fingerprint·instance isolation 및 sanitized payload 계약은 AC-0024를 유지한다.
|
||||
|
||||
## Verification
|
||||
|
||||
- daemon assembly test가 read port, reconciliation broker, atomic store, warn/notification store의 production 연결을 확인한다.
|
||||
- scheduler test가 현재 refresh items 전달, broker 단일 read, auto-sync 성공/실패 격리와 다음 tick idempotency를 확인한다.
|
||||
- resolved notification은 commit/B clear 뒤 한 번 발생하고 publish 실패는 business commit을 되돌리지 않으며 pending retry된다.
|
||||
- synthetic 회귀: symbol `019685`, hub=broker=726, core=1452, canonical WAC≈2172.46829187에서 core만 726/WAC로 갱신되고 B만 해제되며 주문·Hub·ledger side effect가 없다.
|
||||
@@ -1,5 +1,5 @@
|
||||
{
|
||||
"schema_version": 1,
|
||||
"next_line_number": 10,
|
||||
"next_ac_number": 32
|
||||
"next_ac_number": 35
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user