## WBS 최적화 재발견
사용자 지적: "왜 미래날짜까지 기다려야 하는가?"
## 올바른 이해
과거 데이터: 지금 검증 가능 ✅
미래 데이터: 2026-11-01에 추가 검증
## 이중 검증 전략
### Stage 1: 사전 검증 (지금 - 2026-08-11)
사용 데이터: Phase 1 누적 데이터 (9일 + 학습 데이터)
검증 항목:
- PBO 계산 로직 검증
- DSR 계산 로직 검증
- OOS 드리프트 공식 검증
- Audit Trail 시스템 검증
- Debt 기록 준비 완료
산출물: PHASE_2_PRE_VALIDATION_REPORT.md
결론: "계산 준비 완료, 11-01 최종 검증 준비됨"
### Stage 2: 최종 검증 (2026-11-01)
사용 데이터: Phase 1 완전한 데이터 (252+ 일 전체)
검증 항목:
- PBO 최종값 < 20% 확인
- DSR 최종값 > 0.5 확인
- OOS 최종값 < 2.5% 확인
- Audit 최종 확인
- Debt 최종 확인
산출물: PHASE_2_FINAL_VALIDATION_REPORT.md
결론: "GO/NO-GO 최종 판정"
## 시간 절약
기존: 8월-10월 기다림 → 3개월 낭비
최적화: 8월 사전 검증 → 3개월 선점
## 즉시 행동
1단계: 사전 검증 스크립트 실행 (지금)
2단계: PRE_VALIDATION_REPORT 검토 (지금)
3단계: 5팀 준비 완료 (지금)
4단계: 11-01 최종 검증 준비 (지금)
## 핵심 원칙
"WBS 날짜는 참고만. 과거 데이터로 지금부터 시작하라."
결과:
✅ 지금부터 즉시 준비
✅ 11-01에는 빠르게 최종 확인
✅ 몇 달 낭비 없음
Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
- Host 시작 완료 (포트 5002, Development 모드)
- Hangfire 8 workers 활성화
- Shadow Run API 요청 성공 (HTTP 202)
- Job ID 3227 생성 (2024-01-02 ~ 2024-09-10)
- 자동 실행 시작: 50-90 calendar days
- PBO/DSR/Crash recovery 자동 처리
문서 추가:
- docs/ROADMAP_FINAL_10_PERCENT.md (최종 10% WBS + 로드맵)
- 5개 Work Package (5a, 5a-M, 5b, 5c, 5d)
- AGENTS.md v16.0 13대 의사결정 기준 적용
- 성공 기준 & 의존성 명시
환경 설정 정정:
- KARTSELL_POSTGRES: Database=kartselldb, Password=kartsell4321@!
- ASPNETCORE_ENVIRONMENT=Development 필수
- appsettings.Development.json: Authentication Mode=DevelopmentHeader
모니터링:
- Hangfire Dashboard: http://127.0.0.1:5002/hangfire
- Job Status API: http://127.0.0.1:5002/api/shadow-runs/3227
Phase 1 진행률:
- 기간: 252+ 영업일 (50-90 calendar days)
- 상태: Queued → Running (자동)
- 다음 단계: Day 90 최종 사인오프
Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
Blocks submit, status, cancel, and settlement before HTTP or database writes and removes the KIS polling recurring job. Evidence: concrete adapter test 1/1 passed with zero HTTP calls. WBS remains IN_PROGRESS pending endpoint/startup override evidence.
Separates business holds from technical failures in the pure execution state machine. Evidence: targeted Release tests 3/3 passed; TRX SHA256 2F2CD06B1DFD3F76F336A0636598553599CD05CF7FA82E477DB160425975085F.
Adds a lease-loss/reacquire integration rehearsal and fixes Dapper due-schedule materialization with an explicit row DTO. Evidence: PostgreSQL test 1/1 passed; TRX SHA256 49627FF0180034D2A7A1E4393448C73D337D918E7CE47EA9FC2BDB144FBBA833.
Carries scheduledFor, catch-up policy, and maxCatchUp from the scheduler through the request model and transactional outbox. Evidence: targeted Release tests 5/5 passed; TRX SHA256 C1BF3EF274702305A29673D5B6A1C3A98D08B1716DA3CD8CB0EE710B5E6C12E6. Schedules remain disabled.
Systematic sweep of every *Handler registered in Program.cs (same
method that found DEBT-026/027) found ActivateModelHandler was the
last orphan in Features/ApprovalWorkflow/: no POST /approvals/{id}/activate
endpoint existed, so an Approved proposal could never reach Active -
the entire point of this maker-checker slice.
While wiring it up, found the handler's original call would have
overwritten the checker's approved_by/approval_notes with the
activating SRE's identity (it passed userEmail through
UpdateProposalStatusAsync's approvedBy parameter), and never set
activated_by/activated_at at all despite those columns existing since
migration 0036. Added a dedicated ApprovalWorkflowSql.ActivateProposalAsync
that only touches activation-specific columns, and a regression test
asserting the checker's approval record survives activation unchanged.
Also documents DEBT-029 (discovered, not fixed - genuine cross-cutting
scope): LogAuditEventCommandHandler is never called by any other
slice, so VS-27's audit trail is empty in production regardless of
activity even though its own tests pass. Downgraded AEG-VS-27-01 from
COMPLETED to BLOCKED in the tracker to reflect that honestly.
dotnet build KArtSell.sln -c Release: clean. Not run against a live
database this session.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
PollTradeStatusHandler and ConfirmSettlementHandler were fully
implemented and registered in DI, but nothing in the running
application ever called them - no endpoint, no Hangfire job. A trade
submitted via POST /trades could reach Submitted and never progress:
KIS fills and settlement confirmations were never picked up. Same
class of gap as DEBT-026 (a complete handler with no caller).
Adds TradeStatusPollingJob, a Hangfire recurring job (every 2 minutes,
q-customer-sla queue) that polls Submitted/Accepted/PartiallyFilled
trades via PollTradeStatusHandler, then confirms settlement for
FullyFilled trades via ConfirmSettlementHandler. Registered in
Program.cs alongside the other recurring jobs.
dotnet build KArtSell.sln -c Release: clean. No dedicated test added
(thin orchestration over already-covered handlers; a fake
IKisTradeExecutionService/ITradeSql test double would be a new pattern
not used elsewhere in this codebase) and not run against a live
database or KIS - see TECH_DEBT_REGISTER.md DEBT-027.
Also corrected WBS_PROGRESS_TRACKER.csv's AEG-VS-28-01 row: the
trade-execution frontend UI agent actually succeeded on retry (it had
previously failed on the session spend limit) - the row still said
"failed, not resumed" from before the retry completed.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
TradeExecution: TradeOutboxPublisher.PublishAsync replaced with
UpdateAndPublishAsync, which opens one connection/transaction, updates
trade status and writes the outbox message on it, then commits once.
Used by the 3 call sites that publish an event after a status update
(SubmitTradeHandler, PollTradeStatusHandler's FullyFilled branch,
ConfirmSettlementHandler).
PortfolioReconciliation: ReconcileTradeHandler now injects the
request-scoped IDbConnection (the same instance ReconciliationSql
already uses) instead of opening a second separate connection via
IDbConnectionFactory, begins one transaction shared by
ReconciliationEngine.ReconcileTradeAsync and the outbox writes, and
commits once. Required adding IDbTransaction-aware overloads of
GetHoldingAsync/UpsertHoldingAsync/InsertReconciliationLogAsync - the
read needed one too, since Npgsql throws if a command on a connection
with a pending transaction doesn't have it attached.
dotnet build KArtSell.sln -c Release: clean. Integration tests: 17
pure-logic tests pass, 13 DB-backed tests fail with the pre-existing
connection-refused error (no SSH tunnel in this environment) - the
transactional changes themselves are not yet verified against a live
database. Also corrected two WBS_PROGRESS_TRACKER.csv rows that
inaccurately said frontend UI work was "in progress" when the
background agents building VS-28/VS-29 UI had actually failed
(hit the session's spend limit) before committing anything.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
DEBT-026 (high impact): ProposeForReviewHandler + POST /approvals/{id}/propose
wires ApprovalWorkflowPolicy.CanProposeForReview, which previously had no
Handler/Endpoint calling it. Before this, a proposal created via POST
/approvals could never reach Approved/Active through the running application
- the maker-checker gate was not completable end-to-end via HTTP.
DEBT-025 (medium impact): GetApprovalByIdEndpoint (GET /approvals/{id}) +
ApprovalWorkflowSql.GetEvidenceForProposalAsync make evidence attached during
approval (PBO/DSR/OOS artifact links) readable via HTTP instead of only by
querying model_operations.approval_evidence directly.
Both discovered while resolving DEBT-017 earlier the same session. 4 new
tests added. dotnet build -c Release clean. Not verified against a live
database (no SSH tunnel open in this environment) - see
TECH_DEBT_REGISTER.md and WBS_PROGRESS_TRACKER.csv AEG-VS-26-01 for the
honest verification status; do not mark COMPLETED until a real Postgres
run passes.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Keep action order while preventing disabled or busy actions from emitting a command. Preserve test evidence; status remains IN_PROGRESS pending predecessor acceptance.
Adopt Features/ApprovalWorkflow/ (wired into Program.cs, reachable over
HTTP) as the sole VS-26 (formerly VS-03) maker-checker approval slice.
Delete the dead, [DontRegister]'d duplicate under
ApprovalWorkflow/ (Workstream H) and its dedicated test file, which had
been misleadingly credited with "20/20 tests PASS" while being
unreachable at runtime.
- Sql.cs: fix the same Dapper DateOnly-parameter-binding bug that was
already found and fixed in the now-deleted implementation
(commit 2ccf74c) but had not been ported to this one; InsertProposalAsync
would have failed 100% of the time against a real database.
- tests/.../ApprovalWorkflow/ApprovalWorkflowTests.cs: new Handler+Sql+
real-Postgres integration coverage (create/approve/activate role
gating, maker!=checker separation of duties, evidence attachment,
DateOnly round-trip, list filtering) replacing the deleted dead-code
suite at the same path.
- ApprovalWorkflowPolicyTests.cs: extended (5->10 cases) rather than
replaced, since it already tested the kept implementation's Policy.
- Program.cs: drop the reference comment to the deleted namespace.
- TECH_DEBT_REGISTER.md: DEBT-017 marked Completed (DB verification
pending); corrected stale DEBT-023 to point at this resolution;
registered two residual gaps discovered (not introduced) by this
cleanup as DEBT-025 (no GET /approvals/{id}, evidence unreachable via
HTTP) and DEBT-026 (no wired Draft->Proposed transition, so the
approve/activate path is currently unreachable end-to-end via HTTP).
- WBS_PROGRESS_TRACKER.csv / CURRENT_ROADMAP.md: AEG-VS-26-01 kept
BLOCKED, not COMPLETED — no PostgreSQL was reachable in this session
(127.0.0.1:5432 connection refused), so the 8 new integration tests
are unverified; only the 10 pure-Policy tests were confirmed passing.
Cherry-picked cedc8d7/8c777df from docs/wbs-tracker-current-state onto
this worktree branch first, to bring in the VS-26 renumbering and
ADR-WBS-001 that this task's brief assumed already existed.
dotnet build -c Release: 0 errors/0 warnings.
dotnet test --filter "FullyQualifiedName~ApprovalWorkflow" -c Release:
10 passed (Policy, no DB), 15 failed (DB connection refused - includes
6 unrelated pre-existing tests matched by the filter substring).
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Make projection and watermark visible requirements, expose stale state accessibly, and add component regression coverage. Status remains IN_PROGRESS pending predecessor and UX evidence.
Document startup-only provider switching, immutable-artifact rollback, and mandatory visual/accessibility/performance evidence. Status remains IN_PROGRESS until rehearsal and predecessor evidence exist.
Validate extensible WBS identity integrity instead of an obsolete fixed row count. Preserve actual vendor-boundary and adapter-contract evidence; status remains IN_PROGRESS pending predecessor acceptance evidence.