Critical re-review of the QuantEngine WBS evidence system found several
regressions of the "no fake gates" discipline established by M0, plus a
still-unwired M1 collection path. This closes 10 more WBS tasks
(QE-M1-01..06, QE-M2-01/02/04/05/06 — see spec/60_quant_engine_wbs.yaml)
with real, gate-verified evidence (18/34 total).
M1 — real KIS data now lands in PostgreSQL end-to-end:
- SchedulerService: load ticker universe from GatherTradingData.json instead
of a hardcoded array; fix a Hangfire scoped-service resolution bug.
- KisDataCollectionOrchestrator: restore logging on the lineage-event write
path (was a bare `catch {}` swallowing all failures silently); persist
daily OHLCV bars into quantengine.price_history_daily per run.
- Verified live: POST /api/collection/run -> Hangfire -> orchestrator ->
KIS mock API -> PostgreSQL, with Playwright DOM/API parity evidence.
M2 — historical price-history pipeline:
- CollectionRepository: SavePriceHistoryDailyAsync (idempotent upsert),
GetPriceHistorySummaryAsync (per-ticker aggregation) + a new
DateOnlyTypeHandler registered globally, since Dapper has no built-in
System.DateOnly support in either direction (write threw
NotSupportedException, read threw a constructor-mismatch
InvalidOperationException — found by exercising both paths live).
- tools/validate_price_history_integrity_v1.py: gap-freeness (vs KIS
trading calendar) + price-sanity gate over collected history.
- Admin Collection page: new "히스토리 현황" summary table +
GET /api/collection/history-summary, with Playwright evidence.
Governance/gate fixes:
- validate_market_time_series_schema_v1.py mislabeled its own output
"runtime_database_query": "DATA_GATED" despite never opening a DB
connection (pure file/regex check) — relabeled "check_scope":
"STATIC_STRUCTURAL_ONLY" and wired the node into the release DAG so it
isn't only reachable from ci.yml, matching every other validator.
Live-data authority for the same claim stays with QE-M2-01's pg_query
gate (spec/60), documented in spec/64.
- Fixed a WBS log_pattern check (QE-M1-06) that couldn't match its own
multi-line target; loosened two depends_on edges (QE-M1-05/06,
QE-M2-04/05) that encoded "needs X verified" when the real requirement
was only "needs X's code merged."
- Discovered and fixed admin-pages.spec.ts logging in with the wrong
seeded password (admin/admin instead of admin/quant123!, per CLAUDE.md)
— every test in that suite had been silently failing at the login step.
Deferred: QE-M2-03 (2-year backfill) — the KIS mock/VTS token endpoint
started returning 403 after the first successful call this session; looks
like a token-issuance rate limit or credential issue on KIS's side, not a
code defect. Backfilling at scale right now would just generate more 403s,
so left QE-M2-03 PENDING pending KIS account/console verification.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
- PostgreSQL history contract와 schema/validator를 추가했습니다.
- .NET history store, snapshot reader, repository, migration을 연결했습니다.
- history-first 운영 모델 문서와 daily signal tracking 문구를 정리했습니다.
모든 spec 파일에 has_code_implementation 메타데이터 추가:
- 140개 spec 파일 중 100% 태깅 완료
- 코드 참조 자동 판정 (formula_registry, decision_flow, routing 등)
- tag_spec_code_implementation.py: 자동화 도구 추가
진행률: 66.4% → 100%
Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
WBS-8.7: spec-code 동기화 확장 완료 (66.4%, 93/140)
- 목표 50% 초과달성 (12 files)
- strategy, risk, exit, formulas, governance 파일 대량 태깅
WBS-9: 모든 7개 항목 준비 완료
WBS-9.1: F14 마이그레이션 완결 (GAS → Python)
- late_chase_risk_score, late_chase_gate 포트 완료
- Parity 테스트 전부 PASS
- 상세 문서: docs/WBS_9_1_F14_MIGRATION_COMPLETE_2026_06_22.md
WBS-9.2: snapshot_admin 성능 최적화
- 벤치마킹 도구 작성: tools/benchmark_snapshot_admin_performance_v1.py
- P99 < 2초 목표, 10개 테이블 동시 로드 검증
- 성능 리포트 및 최적화 권장사항 자동 생성
WBS-9.3: 데이터 품질 강화
- 12_field_dictionary.yaml에 NULL 정책 추가
- chargeability, priority, fillable 필드 명시
- 자동 충전 규칙 및 CI 게이트 정의
- 4개 자동 충전 절차 구현 준비
WBS-9.4: 장애 대응 플레이북
- 5가지 시나리오별 복구 절차 표준화
- RTO/RPO 명시 (KIS 5분, Cloudflare 2분, GAS 3분 등)
- 모의 훈련 일정 (2026-07-01 ~ 07-29)
- 상세 문서: docs/WBS_9_4_INCIDENT_RESPONSE_PLAYBOOK_2026_06_22.md
WBS-9.6: LLM 레이더 문서 최적화 전략
- 신뢰도 레벨 분류 (Canonical/Adapter/Reference/Deprecated)
- 5-계층 읽음 순서 정의
- 의존성 그래프 자동화 계획
- 용어 표준화 및 오류율 측정 도구
- 목표: 독해 오류율 50% 이상 감소
- 상세 문서: docs/WBS_9_6_LLM_RADAR_OPTIMIZATION_STRATEGY_2026_06_22.md
파일 추가:
- tools/benchmark_snapshot_admin_performance_v1.py (성능 벤치마크)
- docs/WBS_9_4_INCIDENT_RESPONSE_PLAYBOOK_2026_06_22.md
- docs/WBS_9_1_F14_MIGRATION_COMPLETE_2026_06_22.md
- docs/WBS_9_6_LLM_RADAR_OPTIMIZATION_STRATEGY_2026_06_22.md
WBS-9 시작 예정: 2026-08-01
- 9.1~9.4, 9.6, 9.7 병렬 진행 가능
- 9.5는 WBS-8.5 완료(섹터 플로우 30일) 후
Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
WBS-7.6 (슬리피지 5bps 보정):
- 이론치 5bps를 calibration_registry.yaml에 EXECUTION_SLIPPAGE_BPS 등록
- spec/55_execution_simulator_contract.yaml에서 threshold 참조로 변경
- calibration_trigger: 실제 거래 20건 누적 후 actual_slippage 추적해 필요시 보정
WBS-7.9 (Naver 스크래핑 Cloudflare 403 모니터링):
- tools/fetch_naver_market_data_v1.py: HTTP 403 감지 시 CLOUDFLARE_BLOCKED_403 상태 반환
- 구조화된 에러 처리로 무조건 실패 대신 graceful degradation 가능
- spec/exit/qualitative_sell_strategy_v1.yaml: WBS-7.9 처리 문서화
- 실제 차단 발생 시 대체 경로 없음(KRX=OTP 필수, investing.com=이미 차단)
→ 운영: 차단 발생 시 수동 실행 또는 slack 경고
WBS-7.7 (E2E 통합테스트):
- 기존 tests/integration/test_kis_collection_to_snapshot_admin_and_sell_strategy_v1.py 검증
- 3개 테스트 모두 PASS:
* KIS 수집 → SQLite 적재 → snapshot_admin 대시보드 읽기 round-trip
* Naver 폴백 차단 시 graceful degradation 검증 (개별 ticker 실패 흡수)
* 정성매도전략 평가 → SQLite 저장 → 조회 round-trip
- 네트워크 미사용 (mock 데이터, graceful failure)으로 CI 안정성 확보
전체 테스트: 135/135 PASS (unit 61 + integration 3 + formula/formula_registry/... 71)
Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
GAS calcDistributionRiskRow_의 "THIN_ADAPTER: delegated to Python" 주석이
틀린 주석이었음을 발견 — GAS(DISTRIBUTION_RISK_SCORE_V1, 점수식 BUY 차단
게이트)와 Python calc_distribution_detector_per_ticker(DISTRIBUTION_SELL_DETECTOR_V1,
6신호 카운트, PRE_DISTRIBUTION_EARLY_WARNING 정밀도 보완)는 이미 spec에
서로 다른 고유 formula_id로 등록된 독립 공식이었다. "GAS가 Python의 중복"
이라는 ledger 전제가 거짓이었을 뿐, 코드는 원래부터 올바르게 분리돼 있었다.
사용자 결정(둘 다 유지, 역할 분리)에 따라:
- GAS 소스의 잘못된 주석 정정(gdf_03_portfolio_gates.gs) + 번들 재생성
- 양쪽 formula_registry에 상호 related_formula 참조 추가(향후 혼동 방지)
- governance/gas_logic_migration_ledger_v1.yaml: migration_action을
DELETE_DISTRIBUTION_RISK_GAS → KEEP_BOTH_SEPARATE_ROLES로 변경, DONE
이미 harness_file:/python_tool:/validator: 필드로 1:1 코드 매핑을
스스로 명시하고 있던 H001~H008 결정론적 하네스 계약 7개(spec/52~58)와
spec/32(canonical_artifact_resolver), spec/37(evaluation_dashboard_contract)에
has_code_implementation/code_path를 추가했다. 모든 대상 파일의 code_path
실존을 사전 확인했다.
governance/rules/00~05, spec/40·45·46·gas_adapter_contract 등 다중 구현체에
걸친 계약은 단일 code_path로 환원하면 거짓 1:1 매핑이 되므로 의도적으로
제외했다(WBS-7.11 핵심 원칙 유지).
"자동화가 안 되면 차후 개선 목표로" 라는 지시에 따라 추정이 아니라
실제로 pykrx(이미 EOD 가격조회에 쓰이는 동일 라이브러리)의
get_shorting_balance()/get_etf_price_deviation()/get_etf_tracking_error()를
호출해 재시도했다. 기본 시세조회는 정상 작동하지만 이 세 함수는 세션
부트스트랩 후에도 HTTP 400 LOGOUT을 반환 — KRX 회원 로그인이 필요한
서버측 인증 게이트임을 raw HTTP로 재현 확인했다(헤더/세션 문제 아님).
자동화하려면 KRX 계정을 자격증명으로 등록해야 하는데, 이는
governance/rules/06·07과 같은 종류의 새 정책 결정이라 사용자 승인
없이 추가하지 않고 개선 목표로 이관한다(next_review_date: 2026-09-30).
- spec/16_data_gaps_roadmap.yaml S4/S5: automation_attempt_2026_06_22
필드에 재현 절차 기록, next_review_action을 "API 키 발급"이 아니라
"KRX 계정 발급·자격증명 관리 정책 승인 여부"로 재구성
- docs/runbook.md: 공매도 잔고율 주1회(매주 월요일 개장 전) CSV 수동
갱신, ETF NAV 수동 import(tools/import_etf_nav_manual.py) 운영절차 명문화