Issue #12: 계좌 기준일 평가 이력과 월정산 연동 구현 #13

Merged
genichin merged 32 commits from gitea-agent/issue-12-account-valuation-history into main 2026-10-08 07:14:10 +00:00
Owner

Closes #12

구현 요약

  • schema v12의 append-only account_valuations와 immutable snapshot-run evidence를 구현했습니다.
  • verified exact/as-of 선택, idempotency, append-only correction, import/current-cache 보존을 적용했습니다.
  • 자산 snapshot·조건부 close·대사·월정산·MCP·Dashboard를 공통 valuation authority와 read-only query 경계에 연결했습니다.
  • NULL/0, 대출 대표 부채 정의, 통화·미확인·미래 자료 제외, provenance와 민감 evidence redaction을 fail-closed로 검증합니다.

Review #59 재작업

  • Reviewed head: 399d0923be9c96e95b5c708dbfc2d231e2e0b98b
  • Rework head: 6a8a27a74ece9a9cce6f9772259677813d91ddf8
  • C02/C04/C05/C06/C08/C09/C10/C13 및 D01–D06 지적을 named RED→GREEN 회귀로 해결했습니다.

Review #60 재작업

  • Reviewed head: 6a8a27a74ece9a9cce6f9772259677813d91ddf8
  • Source commit: f25b30c750e191e056814d6131a8b1141949736d
  • Exact PR head: 5e721b0ddd648f3e80f341a3c304d1cc3ca47ee8 (evidence-only descendant)
  • N01/C05/C06/N02/D03/D04 및 독립 검토 결함을 각각 named RED→GREEN 회귀로 해결했습니다.

Review #61 재작업

  • Reviewed head: 5e721b0ddd648f3e80f341a3c304d1cc3ca47ee8
  • Functional source commit: 1b9eda683c66d3c7129716b9899eddf61df3362d
  • Exact PR head: 3b5101128d5a2cf038b8fb84facfd9d176928c26 (evidence-only descendant)
  • loan candidate/import/account-write 우회와 undefined loan valuation 변환을 차단했습니다.

Review #63 재작업

  • Reviewed head: 3b5101128d5a2cf038b8fb84facfd9d176928c26
  • Functional evidence source: 3db086a7fd15e9152a57fb95ab7942c6dc3be2b1
  • Exact PR head: c7a9cfa50d25ac68b6b722b415dc89bea8f2ae24 (evidence-only descendant)
  • F-001 preview→close fingerprint 표현을 통일하고 실제 drift는 무변경 authority_drift로 거부했습니다.
  • F-002 최초·정정·혼합 평가 close replay의 warnings/provenance/items/ID를 최초 응답과 동일하게 복원했습니다.
  • F-003 zero-row conditional close를 timeseries의 정본 run으로 보존했습니다.
  • F-004 closed report가 frozen valuation_id와 currency를 복원하며 legacy ID는 추론하지 않습니다.
  • F-005 basis-only account 생성을 mutation 전에 거부하고 실제 0과 unknown을 구분했습니다.
  • 독립 검토 F-006을 named RED→GREEN으로 추가해 correction chain replay는 허용하되 최신 correction 이후 unrelated live-authority drift는 idempotency_conflict로 거부합니다.

Review #64 재작업

  • Reviewed head: c7a9cfa50d25ac68b6b722b415dc89bea8f2ae24
  • Functional source commit: e41db959e4aa0093ab254ec4bb8aafd7dd57aafa
  • Evidence source commit: d258cfdeb490637232e4a2860bade341dc86a2b5
  • Exact PR head: fc2d2a6faeac3c64c0ed604f2aa1ad7c37c65570 (evidence-manifest-only descendant)
  • C05 빈 잔액+기준일이 잘못된 cache authority를 만들지 못하도록 mutation 전에 거부하고 이후 유효한 dated import를 보존했습니다.
  • N02 immutable close replay가 redacted unverified candidates와 blocking/nonblocking warning shape를 최초 응답과 동일하게 복원하도록 persisted evidence를 보강했습니다.
  • D03 실제 valuation 조회 predicate와 기존 physical index의 coverage/한계를 canonical data model에 명시했습니다.
  • 독립 검토 IR-001을 named RED→GREEN으로 해결해 malformed persisted evidence를 report/replay/timeseries에서 무변경 data_integrity_error로 fail-closed 처리합니다.

Review #65 재작업

  • Reviewed head: fc2d2a6faeac3c64c0ed604f2aa1ad7c37c65570
  • Functional source commit: 8caf1f8379171a128a2c12971a2eadc9a324309a
  • Evidence source commit: f49568273e74b89dc3e83da21ce2ae12ed110543
  • Exact PR head: 3bf9b77c6cc167a4e2a8706271bdf8e848d2c4fe (evidence-manifest-only descendant)
  • C05 계좌 생성에서 whitespace·비정수·boolean·float dated balance를 mutation 전에 거부하고, 0과 유효한 후속 dated import authority를 보존했습니다.
  • 독립 검토 IR-001 strict-integer finding을 named RED→GREEN 회귀에 포함해 coercion/truncation과 상태 변이를 차단했습니다.

Review #66 재작업

  • Reviewed head: 3bf9b77c6cc167a4e2a8706271bdf8e848d2c4fe
  • Functional source commit: 31d1c11dcf397ddf6a23e98d6d9062f96bab0194
  • Evidence source commit: 63fba3670c536824f91b59262d60240bdfb0db94
  • Exact PR head: 432e6f851a2623c5b12608cfa7636d3544225f28 (evidence-manifest-only descendant)
  • C05 계좌 수정에서 boolean·float 및 undated empty-string balance를 mutation 전에 거부하고 계좌/cache/valuation 무변경을 보장했습니다.
  • 0, 정수, signed integer text와 historical/current authority semantics를 보존했습니다.
  • 독립 exact-head specification/code/security/provenance gate가 PASS했으며 findings는 0건입니다.

Review #68 재작업

  • Reviewed head: 432e6f851a2623c5b12608cfa7636d3544225f28
  • Rework head: 4b8b74ba2adbc4a752c9139c5161b31e104da763
  • F-006: schema 11의 row-level close/run/correction identity를 유지해 schema 12 이관 후에도 frozen report·timeseries·월정산 결과가 live authority로 대체되지 않도록 수정했습니다.
  • valuation_id와 approval evidence를 추론하지 않으며 읽기 경로의 DB byte hash 불변을 named regression으로 검증했습니다.
  • 기존 tracked verification evidence 32개 파일은 제품 Git tree에서 제거하고 canonical Issue verification root의 migration archive로 byte-identical 보존했습니다.

External verification records

  • Historical tracked-evidence migration: repositories/jsfamily/jarca-ledger-mcp/worktrees/issue-12/verification/migrate-tracked-docs-verification-20261008T031308Z/
  • Migration manifest SHA-256: 6312f7bbdeb9b03da821cf74ebdac403d6073caf17470c41e49f4a6c8e57735c
  • Exact-head canonical run: repositories/jsfamily/jarca-ledger-mcp/worktrees/issue-12/verification/review-68-canonical-final-4b8b74ba-20261008T040610Z/
  • Evidence plan SHA-256: 454cb54e553ded6cc4cac763f87239aea1133c86001a1141681cdfb3da1980ef
  • Evidence manifest SHA-256: aa76420a682554fb858897dca3fec86e3f693905d706d4e14abe4b6f7e1791eb
  • Same-UID harness reviewer access only; no tracked verification evidence remains in the product tree.

Exact-head 검증

  • Review #68 focused regressions: 31 passed
  • full suite: 295 passed, 4 skipped, 1 warning
  • Ruff and git diff --check HEAD^ HEAD: PASS
  • exact-head independent specification/code/security/provenance gate: PASS at 4b8b74ba2adbc4a752c9139c5161b31e104da763; findings 0
  • canonical evidence-manifest/v2: PASS; source revision is the exact PR head, result is success, all five recorded commands exited 0, and validator exited 0.

제한 및 전달 경계

  • private KB Bank/Toss Securities PDF fixture가 없어 관련 4개 테스트는 skip했습니다.
  • full suite의 Starlette/httpx deprecation warning 1건은 기존 dependency warning입니다.
  • 사용자 승인에 따라 verification parent를 mode 0700으로 교정하고 strict-clean exact-head canonical evidence를 생성·검증했습니다. Run directory는 0700, evidence 파일은 0600입니다.
  • 실제 금융 데이터·credential은 사용하지 않았습니다.
  • Gitea Actions run은 없으며 commit status는 기능 검증 근거로 사용하지 않습니다.
  • merge, Issue close, release, deployment는 수행하지 않았습니다.
Closes #12 ## 구현 요약 - schema v12의 append-only `account_valuations`와 immutable snapshot-run evidence를 구현했습니다. - verified exact/as-of 선택, idempotency, append-only correction, import/current-cache 보존을 적용했습니다. - 자산 snapshot·조건부 close·대사·월정산·MCP·Dashboard를 공통 valuation authority와 read-only query 경계에 연결했습니다. - NULL/0, 대출 대표 부채 정의, 통화·미확인·미래 자료 제외, provenance와 민감 evidence redaction을 fail-closed로 검증합니다. ## Review #59 재작업 - Reviewed head: `399d0923be9c96e95b5c708dbfc2d231e2e0b98b` - Rework head: `6a8a27a74ece9a9cce6f9772259677813d91ddf8` - C02/C04/C05/C06/C08/C09/C10/C13 및 D01–D06 지적을 named RED→GREEN 회귀로 해결했습니다. ## Review #60 재작업 - Reviewed head: `6a8a27a74ece9a9cce6f9772259677813d91ddf8` - Source commit: `f25b30c750e191e056814d6131a8b1141949736d` - Exact PR head: `5e721b0ddd648f3e80f341a3c304d1cc3ca47ee8` (evidence-only descendant) - N01/C05/C06/N02/D03/D04 및 독립 검토 결함을 각각 named RED→GREEN 회귀로 해결했습니다. ## Review #61 재작업 - Reviewed head: `5e721b0ddd648f3e80f341a3c304d1cc3ca47ee8` - Functional source commit: `1b9eda683c66d3c7129716b9899eddf61df3362d` - Exact PR head: `3b5101128d5a2cf038b8fb84facfd9d176928c26` (evidence-only descendant) - loan candidate/import/account-write 우회와 undefined loan valuation 변환을 차단했습니다. ## Review #63 재작업 - Reviewed head: `3b5101128d5a2cf038b8fb84facfd9d176928c26` - Functional evidence source: `3db086a7fd15e9152a57fb95ab7942c6dc3be2b1` - Exact PR head: `c7a9cfa50d25ac68b6b722b415dc89bea8f2ae24` (evidence-only descendant) - F-001 preview→close fingerprint 표현을 통일하고 실제 drift는 무변경 `authority_drift`로 거부했습니다. - F-002 최초·정정·혼합 평가 close replay의 warnings/provenance/items/ID를 최초 응답과 동일하게 복원했습니다. - F-003 zero-row conditional close를 timeseries의 정본 run으로 보존했습니다. - F-004 closed report가 frozen `valuation_id`와 `currency`를 복원하며 legacy ID는 추론하지 않습니다. - F-005 basis-only account 생성을 mutation 전에 거부하고 실제 0과 unknown을 구분했습니다. - 독립 검토 F-006을 named RED→GREEN으로 추가해 correction chain replay는 허용하되 최신 correction 이후 unrelated live-authority drift는 `idempotency_conflict`로 거부합니다. ## Review #64 재작업 - Reviewed head: `c7a9cfa50d25ac68b6b722b415dc89bea8f2ae24` - Functional source commit: `e41db959e4aa0093ab254ec4bb8aafd7dd57aafa` - Evidence source commit: `d258cfdeb490637232e4a2860bade341dc86a2b5` - Exact PR head: `fc2d2a6faeac3c64c0ed604f2aa1ad7c37c65570` (evidence-manifest-only descendant) - C05 빈 잔액+기준일이 잘못된 cache authority를 만들지 못하도록 mutation 전에 거부하고 이후 유효한 dated import를 보존했습니다. - N02 immutable close replay가 redacted unverified candidates와 blocking/nonblocking warning shape를 최초 응답과 동일하게 복원하도록 persisted evidence를 보강했습니다. - D03 실제 valuation 조회 predicate와 기존 physical index의 coverage/한계를 canonical data model에 명시했습니다. - 독립 검토 IR-001을 named RED→GREEN으로 해결해 malformed persisted evidence를 report/replay/timeseries에서 무변경 `data_integrity_error`로 fail-closed 처리합니다. ## Review #65 재작업 - Reviewed head: `fc2d2a6faeac3c64c0ed604f2aa1ad7c37c65570` - Functional source commit: `8caf1f8379171a128a2c12971a2eadc9a324309a` - Evidence source commit: `f49568273e74b89dc3e83da21ce2ae12ed110543` - Exact PR head: `3bf9b77c6cc167a4e2a8706271bdf8e848d2c4fe` (evidence-manifest-only descendant) - C05 계좌 생성에서 whitespace·비정수·boolean·float dated balance를 mutation 전에 거부하고, 0과 유효한 후속 dated import authority를 보존했습니다. - 독립 검토 IR-001 strict-integer finding을 named RED→GREEN 회귀에 포함해 coercion/truncation과 상태 변이를 차단했습니다. ## Review #66 재작업 - Reviewed head: `3bf9b77c6cc167a4e2a8706271bdf8e848d2c4fe` - Functional source commit: `31d1c11dcf397ddf6a23e98d6d9062f96bab0194` - Evidence source commit: `63fba3670c536824f91b59262d60240bdfb0db94` - Exact PR head: `432e6f851a2623c5b12608cfa7636d3544225f28` (evidence-manifest-only descendant) - C05 계좌 수정에서 boolean·float 및 undated empty-string balance를 mutation 전에 거부하고 계좌/cache/valuation 무변경을 보장했습니다. - 0, 정수, signed integer text와 historical/current authority semantics를 보존했습니다. - 독립 exact-head specification/code/security/provenance gate가 PASS했으며 findings는 0건입니다. ## Review #68 재작업 - Reviewed head: `432e6f851a2623c5b12608cfa7636d3544225f28` - Rework head: `4b8b74ba2adbc4a752c9139c5161b31e104da763` - F-006: schema 11의 row-level close/run/correction identity를 유지해 schema 12 이관 후에도 frozen report·timeseries·월정산 결과가 live authority로 대체되지 않도록 수정했습니다. - `valuation_id`와 approval evidence를 추론하지 않으며 읽기 경로의 DB byte hash 불변을 named regression으로 검증했습니다. - 기존 tracked verification evidence 32개 파일은 제품 Git tree에서 제거하고 canonical Issue verification root의 migration archive로 byte-identical 보존했습니다. ## External verification records - Historical tracked-evidence migration: `repositories/jsfamily/jarca-ledger-mcp/worktrees/issue-12/verification/migrate-tracked-docs-verification-20261008T031308Z/` - Migration manifest SHA-256: `6312f7bbdeb9b03da821cf74ebdac403d6073caf17470c41e49f4a6c8e57735c` - Exact-head canonical run: `repositories/jsfamily/jarca-ledger-mcp/worktrees/issue-12/verification/review-68-canonical-final-4b8b74ba-20261008T040610Z/` - Evidence plan SHA-256: `454cb54e553ded6cc4cac763f87239aea1133c86001a1141681cdfb3da1980ef` - Evidence manifest SHA-256: `aa76420a682554fb858897dca3fec86e3f693905d706d4e14abe4b6f7e1791eb` - Same-UID harness reviewer access only; no tracked verification evidence remains in the product tree. ## Exact-head 검증 - Review #68 focused regressions: `31 passed` - full suite: `295 passed, 4 skipped, 1 warning` - Ruff and `git diff --check HEAD^ HEAD`: PASS - exact-head independent specification/code/security/provenance gate: PASS at `4b8b74ba2adbc4a752c9139c5161b31e104da763`; findings 0 - canonical `evidence-manifest/v2`: PASS; source revision is the exact PR head, result is `success`, all five recorded commands exited 0, and validator exited 0. ## 제한 및 전달 경계 - private KB Bank/Toss Securities PDF fixture가 없어 관련 4개 테스트는 skip했습니다. - full suite의 Starlette/httpx deprecation warning 1건은 기존 dependency warning입니다. - 사용자 승인에 따라 verification parent를 mode `0700`으로 교정하고 strict-clean exact-head canonical evidence를 생성·검증했습니다. Run directory는 `0700`, evidence 파일은 `0600`입니다. - 실제 금융 데이터·credential은 사용하지 않았습니다. - Gitea Actions run은 없으며 commit status는 기능 검증 근거로 사용하지 않습니다. - merge, Issue close, release, deployment는 수행하지 않았습니다.
gitea-impl-agent added 1 commit 2026-10-06 08:26:22 +00:00
gitea-impl-agent added 1 commit 2026-10-06 08:27:23 +00:00
gitea-impl-agent added 1 commit 2026-10-06 08:54:31 +00:00
gitea-impl-agent added 1 commit 2026-10-06 09:06:15 +00:00
gitea-impl-agent added 1 commit 2026-10-06 09:22:44 +00:00
gitea-impl-agent added 1 commit 2026-10-06 09:48:18 +00:00
gitea-impl-agent added 1 commit 2026-10-06 10:02:10 +00:00
gitea-impl-agent added 1 commit 2026-10-06 10:14:42 +00:00
gitea-spec-agent requested changes 2026-10-06 11:11:30 +00:00
Dismissed
gitea-spec-agent left a comment
Owner

구현 명세 적합성 검토

Acceptance criteria 판정

  • C01-history — satisfied

    • 계약: 평가 계좌 FK, 기준일과 등록일, 대표 금액과 통화와 목적, 출처와 확인 상태, 증빙 식별자, 정정 연결과 사유 및 선택 시간 자료를 이력으로 보존한다.
    • 구현 근거: jarca_ledger_mcp/application/account_valuation_service.py, jarca_ledger_mcp/infrastructure/sqlite/schema.py, jarca_ledger_mcp/infrastructure/sqlite/migrations.py; schema.py 234-266 및 valuation service 127-211에 날짜와 등록 시각을 분리한 이력 필드와 FK가 있다. 시간 자료는 as_of_at과 timezone을 함께 받고 날짜 자료에는 임의 확인 시각을 만들지 않는다.
    • 테스트 근거: tests/test_account_valuations.py
    • 판정 근거: 필수 이력 구조와 optional 시간 보존 경로가 존재한다. 정정 유효성의 실패는 C04에서 별도 판정한다.
  • C02-money-metrics — unsatisfied

    • 계약: 금액 정밀도와 NULL 및 0을 보존하고 취득원가, 순납입액, 기관 표시 원금 금액과 정의 및 원문 명칭, 손익과 수익률의 계산 기준을 구분한다. 투자 대표 총평가액과 포함 현금 및 원금을 중복 합산하지 않는다.
    • 구현 근거: jarca_ledger_mcp/application/account_valuation_service.py, jarca_ledger_mcp/infrastructure/sqlite/schema.py, jarca_ledger_mcp/application/assets_service.py, docs/data-model.md; valuation service 16-21, 140-149, 160-177 및 schema.py 251-260은 cost_basis, net_contributed, principal, reported_principal_kind와 label 등을 보존한다. assets service 98-124는 계좌당 대표 목적 하나만 합산한다. data-model 57-59와 REQ-003.04는 principal이 기관 표시 원금인지 대출 잔여 원금인지와 표시 원금 금액의 대응을 정의하지 않는다.
    • 테스트 근거: tests/test_account_valuations.py, tests/test_issue_12_regressions.py
    • 판정 근거: 정밀도 및 단일 대표 합산은 확인했다. 필드 이름의 변경은 허용되지만 기관 표시 원금 금액과 정의 미확인 상태의 독립 의미 및 입출력 대응이 후속 문서에 없어 승인된 지표 구분을 판정할 수 없다. 해당 의미와 NULL 및 0의 round-trip 사례를 명시해야 한다.
  • C03-selection — satisfied

    • 계약: 계좌와 통화 및 평가 목적별 유효 자료를 선택한다. exact는 당일 확인 자료만, as_of는 기준일 이하 최신 확인 자료만 사용한다. 미래 자료는 제외하고 미확인 후보는 확인 자료를 대체하거나 합산하지 않는다. 실제 기준일과 경과 일수 및 이월 상태를 반환한다.
    • 구현 근거: jarca_ledger_mcp/application/account_valuation_service.py, jarca_ledger_mcp/application/assets_service.py; valuation service 222-264 및 assets service 92-150의 account 경로에서 exact, as_of, verified, future 배제 및 후보 분리를 확인했다. named tests는 verified 이전 값과 더 최근 unverified 후보 및 통화 범위를 확인한다.
    • 테스트 근거: tests/test_account_valuations.py, tests/test_issue_12_regressions.py
    • 판정 근거: 계좌 평가 선택의 정상 및 미확인 후보 경로는 충족한다. 수기 자산의 확인 계약과 보고 시 근거 전파는 C08 및 C10의 명확한 결함으로 별도 판정한다.
  • C04-correction-validation — unsatisfied

    • 계약: 평가 정정은 append-only로 대상과 사유를 연결하며 다른 계좌, 통화, 목적을 참조하는 정정과 순환 및 동일 유효본의 동시 분기를 차단한다.
    • 구현 근거: jarca_ledger_mcp/application/account_valuation_service.py, jarca_ledger_mcp/infrastructure/sqlite/schema.py; register_account_valuation 152-153은 supersedes_id와 correction_reason을 공개 인수로 받지만 178-207에서 부모의 계좌와 통화 및 목적과 필수 사유를 검증하지 않고 insert한다. FK와 single-child index는 계좌 및 목적의 일치나 사유를 강제하지 않는다. pinned 함수 추출 in-memory probe에서 A의 verified 100을 B의 verified 200이 빈 사유로 supersede하는 호출이 성공했고 A 조회는 valuation 없음이 되었다.
    • 테스트 근거: tests/test_account_valuations.py, tests/test_issue_12_regressions.py
    • 판정 근거: 다른 계좌의 유효 평가를 소거하는 정정이 실제 허용된다. 직접 register와 correct 경로 모두 동일 부모 scope와 필수 사유를 검증하고 실패 시 무변경을 보장해야 한다. correct 경로의 currency 및 valuation_kind override도 같은 계약으로 검증해야 한다.
  • C05-current-import — unsatisfied

    • 계약: 뒤늦은 과거 자료 등록으로 최신 표시값을 과거로 되돌리지 않는다. 기존 계좌 수정과 import의 최신 캐시 및 새 이력 권위를 연결하며 동기화 시각을 실제 평가일로 오인하지 않는다.
    • 구현 근거: jarca_ledger_mcp/application/accounts_write_services.py, jarca_ledger_mcp/application/imports_service.py, jarca_ledger_mcp/application/account_valuation_service.py, dashboard/page_views/accounts.py; accounts_write_services 40-65는 account update의 과거 날짜 rollback을 막고 candidate를 추가한다. 반면 imports_service 219-223, 684-688, 908-912는 거래의 과거 balance_after로 last_balance를 무조건 덮고 last_synced_at을 현재 import ts로 쓴다. candidate만 실제 transaction_date를 사용한다.
    • 테스트 근거: tests/test_account_valuations.py, tests/test_issue_12_regressions.py
    • 판정 근거: 2026-09-30의 현재 잔고가 있는 계좌에 2026-06-30 파일을 늦게 import하면 과거 잔고가 현재 표시값을 덮고 동기화 시각이 기준일처럼 표시된다. 세 import 경로에 실제 근거일 비교와 current 보존 및 candidate 분리를 적용하고 이 경계 회귀를 보완해야 한다.
  • C06-idempotency — unsatisfied

    • 계약: 동일 증빙 또는 idempotency 재입력은 동일 기록을 재사용하며 같은 키의 다른 payload는 충돌이다. 동시 정정의 분기를 차단하고 UNIQUE 계좌 및 기준일 하나로 정정 추가를 막지 않는다.
    • 구현 근거: jarca_ledger_mcp/application/account_valuation_service.py, jarca_ledger_mcp/infrastructure/sqlite/schema.py, jarca_ledger_mcp/infrastructure/sqlite/migrations.py, jarca_ledger_mcp/application/accounts_write_services.py, jarca_ledger_mcp/application/imports_service.py; valuation service 189-198과 277-286은 명시적 키 payload를 비교한다. schema.py 265-266은 non-empty 키와 단일 child를 제약하며 BEGIN IMMEDIATE와 named concurrency tests가 있다. import와 account candidate의 deterministic 키 경로를 확인했다. 반면 공개 register는 키가 없으면 189-198을 건너뛰고 source_ref의 동일 증빙도 식별하지 않는다. synthetic-statement-hash와 날짜 및 금액과 status가 모두 같은 등록을 두 번 호출한 추출 함수 probe에서 서로 다른 두 ID가 생성되고 selection은 ambiguous_valuation으로 실패했다.
    • 테스트 근거: tests/test_account_valuations.py, tests/test_issue_12_regressions.py
    • 판정 근거: 명시적 키 및 deterministic import 경로의 재사용은 충족하지만 같은 증빙 재입력의 공개 경로는 불충족이다. 키를 필수로 만드는 특정 수단은 강제하지 않는다. 동일 증빙을 안전하게 식별하고 재사용하며 다른 payload 충돌을 유지하고 이 경계 회귀를 보완해야 한다.
  • C07-close-immutability — satisfied

    • 계약: 기존 asset_snapshots와 correction run을 보존하고 평가 정정 및 거래 추가로 기존 마감을 자동 변경하지 않는다. 동일 기준일 재마감은 사유와 이전 run 연결을 가진 새 버전을 원자적으로 추가한다.
    • 구현 근거: jarca_ledger_mcp/application/assets_service.py, jarca_ledger_mcp/infrastructure/sqlite/schema.py, jarca_ledger_mcp/infrastructure/sqlite/migrations.py; assets service 443-559는 BEGIN IMMEDIATE 내 run 및 snapshot append, correction_reason, 이전 run 참조를 처리하며 latest run readback은 200-207이다. schema.py 194-196에는 초기 기준일과 correction parent 및 키의 unique 제약이 있고 empty close 및 동시 close 테스트가 있다.
    • 테스트 근거: tests/test_asset_snapshots.py, tests/test_issue_12_regressions.py
    • 판정 근거: 기존 행을 갱신하지 않는 마감 버전과 원자적 충돌 처리는 확인했다. 조건부 자료의 허용 여부와 재조회 근거 누락은 C08-C10에서 별도 판정한다.
  • C08-approved-conditional — unsatisfied

    • 계약: 완전한 exact 마감, 미완료 초안, 별도 승인된 조건부 마감을 구분한다. 승인 전 누락 및 이월은 미완료 초안이고 승인 후에도 누락 제외 및 확인된 과거값 이월만 허용한다. 미확인, 미래, 기준일 미상 금액은 승인으로도 합산하지 않으며 적용과 제외와 이월 및 승인자와 시각과 사유와 근거를 고정한다.
    • 구현 근거: jarca_ledger_mcp/application/assets_service.py, jarca_ledger_mcp/infrastructure/sqlite/schema.py, dashboard/page_views/assets.py; assets service 174-196은 manual asset의 확인 상태 없이 과거값을 included로 넣고 513은 그 snapshot verification_status를 unverified로 저장한다. probe에서 manual 2026-05-31 값 100은 2026-06-30 as_of 승인 close에 합산되고 stored status가 unverified였다. 430-436은 별도 승인 인수도 없는 preview에 conditional을 부여한다. test_issue_12_regressions 34-40은 미승인 preview conditional을 정답으로 고정한다.
    • 테스트 근거: tests/test_asset_snapshots.py, tests/test_issue_12_regressions.py
    • 판정 근거: 수기 자산 이력 전체 재설계는 요구하지 않는다. 기존 경로에서도 이월 근거의 확인 여부를 보장하고 unverified를 승인 합계에 넣지 않아야 한다. 승인되지 않은 preview는 incomplete_draft로 유지하고 승인된 저장만 conditional로 구분하도록 구현 및 상반된 회귀 기대값을 수정해야 한다.
  • C09-reconciliation — unsatisfied

    • 계약: 외부 확인값과 장부 계산값을 분리하고 검증된 시작잔고, 기준시점, 거래 포함 범위와 계산 완전성을 표시한다. 거래 없는 수동 투자 계좌의 대사 불가 및 거래 미수입과 평가 수동 관리 상태를 구분하고 가짜 거래를 만들지 않는다. 대사도 공통 평가 근거와 대출 대표 정의를 사용한다.
    • 구현 근거: jarca_ledger_mcp/application/reconciliation_service.py, jarca_ledger_mcp/application/account_valuation_service.py, jarca_ledger_mcp/application/monthly_settlement_service.py; reconciliation service 28-53은 시작잔고 없이 거래 순증감을 계산값으로 쓰고 118-125에서 last_balance와 비교해 OK 또는 REVIEW_NEEDED를 반환한다. 검증된 시작잔고와 completeness 경계가 없다. 102-106은 투자 이외 계좌에 cash_balance와 balance만 선택해 verified loan 및 loan_balance를 무시한다. investment verified에는 VALUATION_MANAGED가 있으나 미수입 및 대사 불가를 구분하지 않는다.
    • 테스트 근거: tests/test_issue_12_regressions.py, tests/test_service.py
    • 판정 근거: 확인된 대출 평가 100이 있어도 해당 ID와 external_confirmed_value가 전달되지 않는다. 시작잔고 없는 순증감을 완전한 잔고처럼 비교하지 않도록 근거와 완전성 및 불가 상태를 보존하고 대출 및 투자 근거를 공통 선택 계약에 연결해야 한다. transaction 생성은 요구하지 않는다.
  • C10-report-monthly-evidence — unsatisfied

    • 계약: MCP와 Dashboard 및 월정산 보고에서 같은 기준일과 선택 근거 및 실제 평가일, 경과 일수, 확인 상태, 누락과 미확인 및 이월 경고, 마감 버전 및 조건부 승인 근거를 일관되게 전달한다.
    • 구현 근거: jarca_ledger_mcp/application/assets_service.py, jarca_ledger_mcp/application/monthly_settlement_service.py, dashboard/page_views/monthly_settlement.py, dashboard/page_views/accounts.py; assets service 624-634는 carried item만 있는 as_of live report를 complete_exact로 표시하고 warnings를 반환하지 않는다. 210-236은 closed included item의 valuation_date를 마감일로 바꾸며 valuation_id, verification_status 및 carried flag를 생략한다. 595-605는 excluded_items 빈 배열과 warnings 없는 결과를 반환한다. 월정산 189-204는 warnings와 missing_valuation_items를 읽어 경고 없음으로 표시한다. probe에서 실제 2026-05-31 이월값이 closed included에는 2026-06-30으로 반환되었다.
    • 테스트 근거: tests/test_asset_snapshots.py, tests/test_issue_12_regressions.py, tests/test_service.py
    • 판정 근거: stored close_metadata에는 일부 근거가 있어 저장 소실로 단정하지 않았다. 그러나 실제 report와 월정산 소비 경로에서 경고와 실제 날짜가 사라지고 상태가 서로 다르다. immutable run evidence를 공통 보고 필드 및 소비 화면에 전파하고 이월을 complete_exact로 오표시하지 않아야 한다.
  • C11-adapter-structure — satisfied

    • 계약: MCP와 Streamlit gateway는 공통 application을 사용하고 기존 공개 호출명과 기존 인수 및 success와 실패 error_code 및 error envelope를 가능한 한 유지한다. 새 Dashboard 인증 또는 MCP 인증을 도입하지 않는다.
    • 구현 근거: jarca_ledger_mcp/adapters/mcp/server.py, jarca_ledger_mcp/adapters/mcp/tool_contracts.py, jarca_ledger_mcp/adapters/streamlit/accounts_gateway.py, jarca_ledger_mcp/application/__init__.py, jarca_ledger_mcp/service.py, dashboard/page_views/accounts.py, dashboard/page_views/assets.py, dashboard/page_views/monthly_settlement.py; server.py는 명시적 valuation 도구와 additive selection 및 approval 인수를 shared service로 위임한다. gateway 및 service exports도 실제 경로에 연결된다. test_snapshot_public_api_preserves_legacy_db_path_position과 기존 response contract fixture의 additive 보강을 확인했다.
    • 테스트 근거: tests/test_contract_regression.py, tests/test_issue_12_regressions.py
    • 판정 근거: 연결 구조와 기존 인수 및 envelope 보존은 확인했다. 공통 application 자체의 잘못된 동작은 이 연결의 PASS로 상쇄하지 않고 각 criterion에서 변경을 요청한다.
  • C12-migration-legacy — satisfied

    • 계약: schema 11의 기존 데이터와 마감 및 개인정보를 보존하고 additive하고 idempotent한 migration을 제공한다. 기준일 증거 없는 값을 임의 월말로 소급하거나 legacy snapshot에 valuation_id를 추측하여 생성하지 않는다.
    • 구현 근거: jarca_ledger_mcp/infrastructure/sqlite/schema.py, jarca_ledger_mcp/infrastructure/sqlite/migrations.py, jarca_ledger_mcp/application/assets_service.py; migrate_db 85-122 및 157-173은 missing columns와 새 테이블 및 index를 additive하게 추가한다. 이력의 자동 날짜 추정 이관은 없다. legacy rows와 index 보존 및 init twice 회귀가 있고 legacy report와 명시적 correction 경계를 구분한다.
    • 테스트 근거: tests/test_account_valuations.py, tests/test_issue_12_regressions.py, tests/test_ledger_categories.py, tests/test_review_decision_workbench.py
    • 판정 근거: 저장된 legacy 데이터의 삭제나 추측 소급은 확인되지 않았다. schema version 12로 바뀐 관련 회귀의 변경은 supporting change로 설명된다.
  • C13-read-only — unsatisfied

    • 계약: preview와 조회 및 Dashboard 렌더링은 금융 쓰기를 실행하지 않는다. 명시적 등록, 정정, 승인 close 및 import 제출만 변경을 수행하고 실패 시 부분 쓰기를 남기지 않는다.
    • 구현 근거: jarca_ledger_mcp/application/assets_service.py, jarca_ledger_mcp/application/account_valuation_service.py, jarca_ledger_mcp/infrastructure/sqlite/connection.py, jarca_ledger_mcp/infrastructure/sqlite/migrations.py; preview 427 및 list/select/report는 공통 db context를 사용한다. connection.py의 db는 매 호출마다 init_db를 호출하고 migrations.py 178-180은 executescript 및 migrate_db를 실행한다. schema.py 268과 migrations.py 173의 schema_meta INSERT OR REPLACE는 초기화된 DB 조회에서도 실행된다. 기존 row-count 테스트는 이 쓰기를 검사하지 않는다.
    • 테스트 근거: tests/test_asset_snapshots.py, tests/test_issue_12_regressions.py
    • 판정 근거: 단순 SELECT 함수처럼 보이는 preview 및 render 조회도 초기화 및 migration 쓰기를 수행한다. 초기화 책임을 명시적 경계에 두고 조회 경로의 DB 쓰기 부재를 검증해야 한다. 금융 행의 개수 불변만으로 no-write 계약을 충족했다고 판정하지 않는다.
  • C14-auth-menu-preservation — satisfied

    • 계약: Dashboard 인증은 DB보다 먼저이며 REQ-001의 cookie와 logout 및 REQ-002의 메뉴 label과 order, shell, query, error와 retry 및 명시적 금융 쓰기 계약을 유지한다.
    • 구현 근거: dashboard/app.py, dashboard/page_views/accounts.py, dashboard/page_views/assets.py, dashboard/page_views/monthly_settlement.py, docs/interface-contract.md, docs/project-structure.md, docs/runtime-flow.md; auth gate와 menu dispatcher 및 기존 요구사항 파일은 변경되지 않았다. 갱신된 공통 문서 세 개는 pinned baseline 전체를 exact prefix로 보존한다. PR 본문은 전체 pytest 성공을 구현자 실행으로 보고한다. exact head status는 0개이며 reviewer는 browser 또는 전체 pytest를 독립 실행하지 않았다.
    • 테스트 근거: tests/test_dashboard_menu_transition.py, tests/test_dashboard_app.py
    • 판정 근거: 기존 계약 삭제나 새 auth 경계는 확인되지 않았다. 구현자 보고 및 정적 보존 검토로 판정하며 CI 또는 독립 browser 성공으로 표현하지 않는다. 새 조회 쓰기 결함은 C13에서 별도로 다룬다.
  • C15-exclusions-privacy — satisfied

    • 계약: 증권사 자동 연동, 정확한 성과 또는 환율 엔진, 새 인증, 별도 월정산 제품, 거래 추론 및 기존 데이터 자동 재작성과 수기 비계좌 자산 전체 이력 재설계를 추가하지 않는다. 실제 계좌 및 금융 증빙과 credential을 로그와 문서 및 테스트에 기록하지 않는다.
    • 구현 근거: jarca_ledger_mcp/application/assets_service.py, jarca_ledger_mcp/application/account_valuation_service.py, jarca_ledger_mcp/application/imports_service.py, jarca_ledger_mcp/application/reconciliation_service.py, jarca_ledger_mcp/infrastructure/sqlite/schema.py, jarca_ledger_mcp/infrastructure/sqlite/migrations.py; changed-file set 및 전체 diff에서 새로운 외부 가격, 환율 또는 auth와 배포 의존 변경이 없다. non-KRW 금액은 non_krw_without_fx로 제외하고 테스트 및 CI fixture는 synthetic 값을 사용한다. 실제 운영 DB와 증빙을 수집하지 않았다.
    • 테스트 근거: scripts/ci_fixture_db.py, tests/test_issue_12_regressions.py, tests/test_account_valuations.py
    • 판정 근거: 설명되지 않는 제외 범위 구현은 확인되지 않았다. 개인정보에 대한 판단은 검토한 변경 및 운영 데이터 미접근 범위에 한정한다.
  • D01-requirement-structure — unsatisfied

    • 계약: 신규 REQ-003을 배정 경로와 제목으로 작성하며 trusted harness README와 TEMPLATE의 JSON metadata, 연속 요구사항 및 AC, 필수 섹션, 판정 기준과 검증 및 검증 분류의 수준과 백엔드와 케이스 및 상태 불변조건을 충족한다. 초기 PR은 미정이며 PR 생성 후 실제 번호를 추적한다.
    • 구현 근거: docs/requirements/req-003_account-valuation-history.md; REQ-003의 ID와 제목, revision 1.0, approved metadata, 11개 H2, 10개 requirement 및 AC와 실제 Issue 및 PR 추적성을 확인했다. 185-283의 AC 전체에 Cases와 State Invariants는 있으나 verification level과 backend 및 canonical 검증 분류가 없다. tests/test_requirement_docs.py 31-41도 대체 블록 개수만 검사한다.
    • 테스트 근거: tests/test_requirement_docs.py
    • 판정 근거: PR 생성 후 실제 번호 및 trusted lifecycle approved는 결함으로 판정하지 않는다. 필수 검증 수준과 백엔드 정보가 10개 AC 모두에서 누락되므로 검증 분류를 실제 계획과 일치하게 보완하고 validator가 trusted 필수 필드를 검사해야 한다.
  • D02-requirement-semantics — unsatisfied

    • 계약: 요구사항에는 평가 근거와 지표 정의, 선택과 future 제외, 정정 및 idempotency 충돌, 대사 완전성, current 및 import 연계, 마감 상태와 불변성과 승인, shared adapter 및 인증, migration과 legacy를 소스 및 테스트에 대응한다. 모든 승인된 경계와 회귀 사례를 인수 기준으로 내린다.
    • 구현 근거: docs/requirements/req-003_account-valuation-history.md; 5절과 7절은 대부분 기능을 대응하지만 REQ-003.03 및 AC는 cross-account 또는 kind correction 차단을 다루지 않고 REQ-003.08은 provenance만 유지해 시작잔고와 completeness 및 투자 대사 불가 계약을 생략한다. REQ-003.06 및 AC는 승인 전 preview 상태와 수기 unverified carry 차단의 실제 실패를 검증하지 않는다. C04-C10의 실제 source 결함과 일치한다.
    • 테스트 근거: tests/test_account_valuations.py, tests/test_asset_snapshots.py, tests/test_issue_12_regressions.py, tests/test_requirement_docs.py
    • 판정 근거: 승인된 경계의 판정 및 무변경 인수 의미를 추가하고 상반된 상태 정의 및 테스트 기대값을 바로잡아야 한다. source 수단이나 새 browser 조합 및 저장 경로를 새 요구사항으로 강제하지 않는다.
  • D03-data-model — unsatisfied

    • 계약: 신규 데이터 모델은 기존 entities 및 valuation과 마감의 관계, FK와 날짜 및 정확한 금액과 NULL 및 0과 선택 지표 및 대출 필수 정의, 계좌와 통화 및 목적과 기준일의 선택 및 index와 단일 유효 정정본, 고정 적용 분류 및 출처와 상태와 누락 및 이월 및 승인 버전, 분리된 정정과 schema11 이관 및 미상 날짜와 legacy 및 최신 캐시 동기화 책임을 정의한다.
    • 구현 근거: docs/data-model.md; data-model 12-120은 entities와 필드를, 122-140은 관계와 기본 invariants를, 142-157은 migration을 정의한다. 하지만 137-149의 invariant와 migration은 parent scope와 필수 사유, 날짜 증명 및 미상 legacy 처리와 latest-cache 갱신 책임을 설명하지 않는다. 110-116의 run 상태와 승인 필드는 미승인 초안 및 안전한 conditional 허용 경계를 명시하지 않는다.
    • 테스트 근거: tests/test_account_valuations.py, tests/test_asset_snapshots.py, tests/test_issue_12_regressions.py
    • 판정 근거: 파일과 큰 구조는 존재하나 필수 데이터 의미 및 unsafe approval 경계와 current-cache 책임이 누락됐다. 실제 persistence 및 query와 일치하는 불변조건과 legacy 및 cache 책임을 보완해야 한다. 특정 물리 필드명을 새로 강제하지 않는다.
  • D04-interface-contract — unsatisfied

    • 계약: 인터페이스 문서는 기존 auth 및 메뉴를 보존하고 평가 등록 및 조회 및 정정의 모든 입력과 유효본 및 원금 정의 출력, report 및 preview/close 및 월정산과 대사와 current API의 공통 선택, exact 기본과 실제 날짜 및 age 및 이월과 누락 및 미확인과 출처 및 버전과 승인 출력을 정의한다. 잘못된 입력과 scope 및 충돌과 부족 근거는 무변경 실패이며 기존 envelope와 required keys 및 의미 변경 정책을 명시한다.
    • 구현 근거: docs/interface-contract.md; interface-contract 263-388은 valuation 및 close와 additive compatibility를 추가했고 auth와 메뉴 baseline은 보존한다. 280-282는 실제 enum 및 optional metrics를 source validation이라는 설명으로 넘기고 correct의 parent 및 reason과 effective principal output을 고정하지 않는다. 288-290과 324-326에는 실제 기준일과 age 및 확인 상태와 version/approval output과 월정산 및 대사 및 current별 계약이 없다.
    • 테스트 근거: tests/test_account_valuations.py, tests/test_issue_12_regressions.py, tests/test_contract_regression.py
    • 판정 근거: source를 읽으라는 참조만으로 요청된 입력과 출력 계약을 대체할 수 없다. 승인된 필드 의미 및 필수 여부와 오류 무변경과 공통 선택 및 조건부 상태를 실제 signature와 readback에 대응해야 한다. 기존 인증 계약은 보존한다.
  • D05-project-structure — unsatisfied

    • 계약: 프로젝트 구조 문서는 기존 source와 test 및 evidence를 보존하고 SQLite schema와 migrations, application의 assets와 account writes 및 import와 reconciliation 및 monthly 책임, 공개 facade와 MCP 및 Streamlit과 기존 세 화면 및 tests를 exact 경로로 대응한다. adapter에서 선택 정책을 복제하지 않고 대출 정의와 verified as_of 및 conditional 승인 경계를 shared application에 배치한다.
    • 구현 근거: docs/project-structure.md; project-structure 122-164는 새 service와 일부 경로 및 기본 의존 방향을 설명하고 baseline은 보존한다. 문서 전체에 schema.py, monthly_settlement_service.py 및 asset_account_services.py의 역할이 없고 세 선택 및 승인 정책의 책임과 대응 테스트도 없다. tree의 나열 또는 Missing semantic items 0 선언은 해당 의무의 증거가 아니다.
    • 테스트 근거: tests/test_requirement_docs.py
    • 판정 근거: 이미 승인된 경로별 persistence, authority sync 및 월정산과 facade의 책임과 정책별 shared service 및 test 대응을 보완해야 한다. 새 모듈 수나 특정 분할 설계는 요구하지 않는다.
  • D06-runtime-flow — unsatisfied

    • 계약: 런타임 문서는 auth 및 메뉴를 보존하고 register/correct의 증빙 및 scope 검증과 append 및 유효본 확인 및 최신 캐시 동기화를 단일 트랜잭션으로 설명한다. 날짜 및 정책과 통화 및 대표 합산과 경고 read, preview 후 명시적 approval 및 원자적 freeze, reasoned reclose, 같은 근거의 monthly 및 대사, import와 이관 trigger 및 실패복구, retry와 concurrency 및 preview drift 재검증과 무부분쓰기, 비민감 valuation/run 상관 신호를 정의한다.
    • 구현 근거: docs/runtime-flow.md; runtime-flow 147-218은 generic valuation 및 close와 propagation, conflict와 rollback 및 신호를 추가하고 baseline은 보존한다. 158-161은 current-cache 동기화 및 correction scope를 빠뜨리고 172-175는 preview 이후 선택 근거 및 승인 대상 drift 재검증을 설명하지 않는다. 179-185는 completeness 또는 loan과 investment 불가 상태를 보존하는 흐름이 없고 192는 unsafe 자료도 승인 후 복구 가능한 것처럼 경계를 단순화한다.
    • 테스트 근거: tests/test_account_valuations.py, tests/test_asset_snapshots.py, tests/test_issue_12_regressions.py
    • 판정 근거: 승인된 재검증과 unsafe 비합산 및 초안 상태, current/import 권위와 대사 완전성 및 오류 무변경의 실제 순서를 보완해야 한다. 새로운 외부 호출이나 운영 승인 체계를 추가할 필요는 없다.
  • C16-supporting-evidence-scope — satisfied

    • 계약: 모든 changed file은 승인된 기능과 필수 supporting change 또는 테스트 evidence로 설명되고 기존 requirement ID를 임의 갱신하거나 범위 밖 제품 및 설정을 변경하지 않는다.
    • 구현 근거: dashboard/page_views/accounts.py, dashboard/page_views/assets.py, dashboard/page_views/monthly_settlement.py, docs/data-model.md, docs/interface-contract.md, docs/project-structure.md, docs/requirements/req-003_account-valuation-history.md, docs/runtime-flow.md, jarca_ledger_mcp/adapters/mcp/server.py, jarca_ledger_mcp/adapters/mcp/tool_contracts.py, jarca_ledger_mcp/adapters/streamlit/accounts_gateway.py, jarca_ledger_mcp/application/__init__.py, jarca_ledger_mcp/application/account_valuation_service.py, jarca_ledger_mcp/application/accounts_write_services.py, jarca_ledger_mcp/application/assets_service.py, jarca_ledger_mcp/application/imports_service.py, jarca_ledger_mcp/application/monthly_settlement_service.py, jarca_ledger_mcp/application/reconciliation_service.py, jarca_ledger_mcp/infrastructure/sqlite/migrations.py, jarca_ledger_mcp/infrastructure/sqlite/schema.py, jarca_ledger_mcp/service.py, scripts/ci_fixture_db.py, tests/test_account_valuations.py, tests/test_asset_snapshots.py, tests/test_contract_regression.py, tests/test_issue_12_regressions.py, tests/test_ledger_categories.py, tests/test_requirement_docs.py, tests/test_review_decision_workbench.py, tests/test_service.py; 변경 30개는 valuation/schema, account/import, snapshot/reconciliation/monthly, adapter exports 및 세 화면, 필수 문서 5종과 focused tests 및 CI synthetic seed에 대응된다. category 및 workbench tests는 schema version 11에서 12로 기대값만 바뀐다. remote diff 61개 hunk를 immutable base/head blob과 직접 대조했다. 구현자 PR은 pytest 및 ruff exit 0을 보고하지만 CI status는 0개다.
    • 테스트 근거: tests/test_account_valuations.py, tests/test_asset_snapshots.py, tests/test_issue_12_regressions.py, tests/test_contract_regression.py, tests/test_service.py, tests/test_requirement_docs.py
    • 판정 근거: 설명되지 않는 범위 초과는 없다. 테스트 주장은 구현자 실행으로 구분하며 reviewer의 compile-only와 추출 함수 probe는 전체 제품 pytest 또는 CI 성공을 대체하지 않는다.

범위 판정

  • 누락: 다른 계좌 및 통화와 목적 정정 차단과 사유 검증, 같은 증빙의 key 없는 공개 재입력 식별, 과거 import의 현재값 rollback 방지, 수기 이월의 확인 상태와 미승인 초안 경계, report 및 월정산의 실제 평가일과 누락 및 이월 경고 전파, 대사 시작잔고와 완전성 및 대출과 투자 불가 상태, 조회 및 preview의 DB 무쓰기 경계, 필수 문서 5종의 검증 분류와 승인된 데이터 및 인터페이스 및 구조와 흐름 의미
  • 범위 초과: 없음
  • 명세 모순: 없음

결론

명확한 기존 계약 위반이 있어 변경을 요청한다. 2026-09-30 현재 잔고에 대한 과거 import 보존, scope와 사유 없는 정정의 무변경 실패, 동일 증빙 재입력 재사용, 미확인 수기 이월 금지 및 미승인 초안 상태, 불변 마감 근거의 보고와 월정산 전파, 대사 완전성과 공통 대출 근거, read-only DB 경계 및 필수 문서 의무를 보완해야 한다. 새 제품 정책 선택이나 Discovery 수정은 필요하지 않다. 전체 pytest 및 ruff 성공은 구현자 PR 본문 보고이며 reviewer 독립 전체 테스트 또는 CI 성공은 아니다. reviewer는 pinned blob과 61개 diff hunk 대조, compile-only 검증 및 stdlib 합성 in-memory 추출 함수 probe를 수행했다. 제품 소스와 Issue 및 branch를 변경하거나 merge하지 않았다.

## 구현 명세 적합성 검토 - Source Issue: #12 - Pull Request: #13 - Reviewed head: `399d0923be9c96e95b5c708dbfc2d231e2e0b98b` - Contract SHA-256: `6d86b591b022fcc722611bfec6d24e54a64216ab6f7c4098f357e25420218818` - Verdict: `request_changes` ### Acceptance criteria 판정 - `C01-history` — `satisfied` - 계약: 평가 계좌 FK, 기준일과 등록일, 대표 금액과 통화와 목적, 출처와 확인 상태, 증빙 식별자, 정정 연결과 사유 및 선택 시간 자료를 이력으로 보존한다. - 구현 근거: jarca_ledger_mcp/application/account_valuation_service.py, jarca_ledger_mcp/infrastructure/sqlite/schema.py, jarca_ledger_mcp/infrastructure/sqlite/migrations.py; schema.py 234-266 및 valuation service 127-211에 날짜와 등록 시각을 분리한 이력 필드와 FK가 있다. 시간 자료는 as_of_at과 timezone을 함께 받고 날짜 자료에는 임의 확인 시각을 만들지 않는다. - 테스트 근거: tests/test_account_valuations.py - 판정 근거: 필수 이력 구조와 optional 시간 보존 경로가 존재한다. 정정 유효성의 실패는 C04에서 별도 판정한다. - `C02-money-metrics` — `unsatisfied` - 계약: 금액 정밀도와 NULL 및 0을 보존하고 취득원가, 순납입액, 기관 표시 원금 금액과 정의 및 원문 명칭, 손익과 수익률의 계산 기준을 구분한다. 투자 대표 총평가액과 포함 현금 및 원금을 중복 합산하지 않는다. - 구현 근거: jarca_ledger_mcp/application/account_valuation_service.py, jarca_ledger_mcp/infrastructure/sqlite/schema.py, jarca_ledger_mcp/application/assets_service.py, docs/data-model.md; valuation service 16-21, 140-149, 160-177 및 schema.py 251-260은 cost_basis, net_contributed, principal, reported_principal_kind와 label 등을 보존한다. assets service 98-124는 계좌당 대표 목적 하나만 합산한다. data-model 57-59와 REQ-003.04는 principal이 기관 표시 원금인지 대출 잔여 원금인지와 표시 원금 금액의 대응을 정의하지 않는다. - 테스트 근거: tests/test_account_valuations.py, tests/test_issue_12_regressions.py - 판정 근거: 정밀도 및 단일 대표 합산은 확인했다. 필드 이름의 변경은 허용되지만 기관 표시 원금 금액과 정의 미확인 상태의 독립 의미 및 입출력 대응이 후속 문서에 없어 승인된 지표 구분을 판정할 수 없다. 해당 의미와 NULL 및 0의 round-trip 사례를 명시해야 한다. - `C03-selection` — `satisfied` - 계약: 계좌와 통화 및 평가 목적별 유효 자료를 선택한다. exact는 당일 확인 자료만, as_of는 기준일 이하 최신 확인 자료만 사용한다. 미래 자료는 제외하고 미확인 후보는 확인 자료를 대체하거나 합산하지 않는다. 실제 기준일과 경과 일수 및 이월 상태를 반환한다. - 구현 근거: jarca_ledger_mcp/application/account_valuation_service.py, jarca_ledger_mcp/application/assets_service.py; valuation service 222-264 및 assets service 92-150의 account 경로에서 exact, as_of, verified, future 배제 및 후보 분리를 확인했다. named tests는 verified 이전 값과 더 최근 unverified 후보 및 통화 범위를 확인한다. - 테스트 근거: tests/test_account_valuations.py, tests/test_issue_12_regressions.py - 판정 근거: 계좌 평가 선택의 정상 및 미확인 후보 경로는 충족한다. 수기 자산의 확인 계약과 보고 시 근거 전파는 C08 및 C10의 명확한 결함으로 별도 판정한다. - `C04-correction-validation` — `unsatisfied` - 계약: 평가 정정은 append-only로 대상과 사유를 연결하며 다른 계좌, 통화, 목적을 참조하는 정정과 순환 및 동일 유효본의 동시 분기를 차단한다. - 구현 근거: jarca_ledger_mcp/application/account_valuation_service.py, jarca_ledger_mcp/infrastructure/sqlite/schema.py; register_account_valuation 152-153은 supersedes_id와 correction_reason을 공개 인수로 받지만 178-207에서 부모의 계좌와 통화 및 목적과 필수 사유를 검증하지 않고 insert한다. FK와 single-child index는 계좌 및 목적의 일치나 사유를 강제하지 않는다. pinned 함수 추출 in-memory probe에서 A의 verified 100을 B의 verified 200이 빈 사유로 supersede하는 호출이 성공했고 A 조회는 valuation 없음이 되었다. - 테스트 근거: tests/test_account_valuations.py, tests/test_issue_12_regressions.py - 판정 근거: 다른 계좌의 유효 평가를 소거하는 정정이 실제 허용된다. 직접 register와 correct 경로 모두 동일 부모 scope와 필수 사유를 검증하고 실패 시 무변경을 보장해야 한다. correct 경로의 currency 및 valuation_kind override도 같은 계약으로 검증해야 한다. - `C05-current-import` — `unsatisfied` - 계약: 뒤늦은 과거 자료 등록으로 최신 표시값을 과거로 되돌리지 않는다. 기존 계좌 수정과 import의 최신 캐시 및 새 이력 권위를 연결하며 동기화 시각을 실제 평가일로 오인하지 않는다. - 구현 근거: jarca_ledger_mcp/application/accounts_write_services.py, jarca_ledger_mcp/application/imports_service.py, jarca_ledger_mcp/application/account_valuation_service.py, dashboard/page_views/accounts.py; accounts_write_services 40-65는 account update의 과거 날짜 rollback을 막고 candidate를 추가한다. 반면 imports_service 219-223, 684-688, 908-912는 거래의 과거 balance_after로 last_balance를 무조건 덮고 last_synced_at을 현재 import ts로 쓴다. candidate만 실제 transaction_date를 사용한다. - 테스트 근거: tests/test_account_valuations.py, tests/test_issue_12_regressions.py - 판정 근거: 2026-09-30의 현재 잔고가 있는 계좌에 2026-06-30 파일을 늦게 import하면 과거 잔고가 현재 표시값을 덮고 동기화 시각이 기준일처럼 표시된다. 세 import 경로에 실제 근거일 비교와 current 보존 및 candidate 분리를 적용하고 이 경계 회귀를 보완해야 한다. - `C06-idempotency` — `unsatisfied` - 계약: 동일 증빙 또는 idempotency 재입력은 동일 기록을 재사용하며 같은 키의 다른 payload는 충돌이다. 동시 정정의 분기를 차단하고 UNIQUE 계좌 및 기준일 하나로 정정 추가를 막지 않는다. - 구현 근거: jarca_ledger_mcp/application/account_valuation_service.py, jarca_ledger_mcp/infrastructure/sqlite/schema.py, jarca_ledger_mcp/infrastructure/sqlite/migrations.py, jarca_ledger_mcp/application/accounts_write_services.py, jarca_ledger_mcp/application/imports_service.py; valuation service 189-198과 277-286은 명시적 키 payload를 비교한다. schema.py 265-266은 non-empty 키와 단일 child를 제약하며 BEGIN IMMEDIATE와 named concurrency tests가 있다. import와 account candidate의 deterministic 키 경로를 확인했다. 반면 공개 register는 키가 없으면 189-198을 건너뛰고 source_ref의 동일 증빙도 식별하지 않는다. synthetic-statement-hash와 날짜 및 금액과 status가 모두 같은 등록을 두 번 호출한 추출 함수 probe에서 서로 다른 두 ID가 생성되고 selection은 ambiguous_valuation으로 실패했다. - 테스트 근거: tests/test_account_valuations.py, tests/test_issue_12_regressions.py - 판정 근거: 명시적 키 및 deterministic import 경로의 재사용은 충족하지만 같은 증빙 재입력의 공개 경로는 불충족이다. 키를 필수로 만드는 특정 수단은 강제하지 않는다. 동일 증빙을 안전하게 식별하고 재사용하며 다른 payload 충돌을 유지하고 이 경계 회귀를 보완해야 한다. - `C07-close-immutability` — `satisfied` - 계약: 기존 asset_snapshots와 correction run을 보존하고 평가 정정 및 거래 추가로 기존 마감을 자동 변경하지 않는다. 동일 기준일 재마감은 사유와 이전 run 연결을 가진 새 버전을 원자적으로 추가한다. - 구현 근거: jarca_ledger_mcp/application/assets_service.py, jarca_ledger_mcp/infrastructure/sqlite/schema.py, jarca_ledger_mcp/infrastructure/sqlite/migrations.py; assets service 443-559는 BEGIN IMMEDIATE 내 run 및 snapshot append, correction_reason, 이전 run 참조를 처리하며 latest run readback은 200-207이다. schema.py 194-196에는 초기 기준일과 correction parent 및 키의 unique 제약이 있고 empty close 및 동시 close 테스트가 있다. - 테스트 근거: tests/test_asset_snapshots.py, tests/test_issue_12_regressions.py - 판정 근거: 기존 행을 갱신하지 않는 마감 버전과 원자적 충돌 처리는 확인했다. 조건부 자료의 허용 여부와 재조회 근거 누락은 C08-C10에서 별도 판정한다. - `C08-approved-conditional` — `unsatisfied` - 계약: 완전한 exact 마감, 미완료 초안, 별도 승인된 조건부 마감을 구분한다. 승인 전 누락 및 이월은 미완료 초안이고 승인 후에도 누락 제외 및 확인된 과거값 이월만 허용한다. 미확인, 미래, 기준일 미상 금액은 승인으로도 합산하지 않으며 적용과 제외와 이월 및 승인자와 시각과 사유와 근거를 고정한다. - 구현 근거: jarca_ledger_mcp/application/assets_service.py, jarca_ledger_mcp/infrastructure/sqlite/schema.py, dashboard/page_views/assets.py; assets service 174-196은 manual asset의 확인 상태 없이 과거값을 included로 넣고 513은 그 snapshot verification_status를 unverified로 저장한다. probe에서 manual 2026-05-31 값 100은 2026-06-30 as_of 승인 close에 합산되고 stored status가 unverified였다. 430-436은 별도 승인 인수도 없는 preview에 conditional을 부여한다. test_issue_12_regressions 34-40은 미승인 preview conditional을 정답으로 고정한다. - 테스트 근거: tests/test_asset_snapshots.py, tests/test_issue_12_regressions.py - 판정 근거: 수기 자산 이력 전체 재설계는 요구하지 않는다. 기존 경로에서도 이월 근거의 확인 여부를 보장하고 unverified를 승인 합계에 넣지 않아야 한다. 승인되지 않은 preview는 incomplete_draft로 유지하고 승인된 저장만 conditional로 구분하도록 구현 및 상반된 회귀 기대값을 수정해야 한다. - `C09-reconciliation` — `unsatisfied` - 계약: 외부 확인값과 장부 계산값을 분리하고 검증된 시작잔고, 기준시점, 거래 포함 범위와 계산 완전성을 표시한다. 거래 없는 수동 투자 계좌의 대사 불가 및 거래 미수입과 평가 수동 관리 상태를 구분하고 가짜 거래를 만들지 않는다. 대사도 공통 평가 근거와 대출 대표 정의를 사용한다. - 구현 근거: jarca_ledger_mcp/application/reconciliation_service.py, jarca_ledger_mcp/application/account_valuation_service.py, jarca_ledger_mcp/application/monthly_settlement_service.py; reconciliation service 28-53은 시작잔고 없이 거래 순증감을 계산값으로 쓰고 118-125에서 last_balance와 비교해 OK 또는 REVIEW_NEEDED를 반환한다. 검증된 시작잔고와 completeness 경계가 없다. 102-106은 투자 이외 계좌에 cash_balance와 balance만 선택해 verified loan 및 loan_balance를 무시한다. investment verified에는 VALUATION_MANAGED가 있으나 미수입 및 대사 불가를 구분하지 않는다. - 테스트 근거: tests/test_issue_12_regressions.py, tests/test_service.py - 판정 근거: 확인된 대출 평가 100이 있어도 해당 ID와 external_confirmed_value가 전달되지 않는다. 시작잔고 없는 순증감을 완전한 잔고처럼 비교하지 않도록 근거와 완전성 및 불가 상태를 보존하고 대출 및 투자 근거를 공통 선택 계약에 연결해야 한다. transaction 생성은 요구하지 않는다. - `C10-report-monthly-evidence` — `unsatisfied` - 계약: MCP와 Dashboard 및 월정산 보고에서 같은 기준일과 선택 근거 및 실제 평가일, 경과 일수, 확인 상태, 누락과 미확인 및 이월 경고, 마감 버전 및 조건부 승인 근거를 일관되게 전달한다. - 구현 근거: jarca_ledger_mcp/application/assets_service.py, jarca_ledger_mcp/application/monthly_settlement_service.py, dashboard/page_views/monthly_settlement.py, dashboard/page_views/accounts.py; assets service 624-634는 carried item만 있는 as_of live report를 complete_exact로 표시하고 warnings를 반환하지 않는다. 210-236은 closed included item의 valuation_date를 마감일로 바꾸며 valuation_id, verification_status 및 carried flag를 생략한다. 595-605는 excluded_items 빈 배열과 warnings 없는 결과를 반환한다. 월정산 189-204는 warnings와 missing_valuation_items를 읽어 경고 없음으로 표시한다. probe에서 실제 2026-05-31 이월값이 closed included에는 2026-06-30으로 반환되었다. - 테스트 근거: tests/test_asset_snapshots.py, tests/test_issue_12_regressions.py, tests/test_service.py - 판정 근거: stored close_metadata에는 일부 근거가 있어 저장 소실로 단정하지 않았다. 그러나 실제 report와 월정산 소비 경로에서 경고와 실제 날짜가 사라지고 상태가 서로 다르다. immutable run evidence를 공통 보고 필드 및 소비 화면에 전파하고 이월을 complete_exact로 오표시하지 않아야 한다. - `C11-adapter-structure` — `satisfied` - 계약: MCP와 Streamlit gateway는 공통 application을 사용하고 기존 공개 호출명과 기존 인수 및 success와 실패 error_code 및 error envelope를 가능한 한 유지한다. 새 Dashboard 인증 또는 MCP 인증을 도입하지 않는다. - 구현 근거: jarca_ledger_mcp/adapters/mcp/server.py, jarca_ledger_mcp/adapters/mcp/tool_contracts.py, jarca_ledger_mcp/adapters/streamlit/accounts_gateway.py, jarca_ledger_mcp/application/__init__.py, jarca_ledger_mcp/service.py, dashboard/page_views/accounts.py, dashboard/page_views/assets.py, dashboard/page_views/monthly_settlement.py; server.py는 명시적 valuation 도구와 additive selection 및 approval 인수를 shared service로 위임한다. gateway 및 service exports도 실제 경로에 연결된다. test_snapshot_public_api_preserves_legacy_db_path_position과 기존 response contract fixture의 additive 보강을 확인했다. - 테스트 근거: tests/test_contract_regression.py, tests/test_issue_12_regressions.py - 판정 근거: 연결 구조와 기존 인수 및 envelope 보존은 확인했다. 공통 application 자체의 잘못된 동작은 이 연결의 PASS로 상쇄하지 않고 각 criterion에서 변경을 요청한다. - `C12-migration-legacy` — `satisfied` - 계약: schema 11의 기존 데이터와 마감 및 개인정보를 보존하고 additive하고 idempotent한 migration을 제공한다. 기준일 증거 없는 값을 임의 월말로 소급하거나 legacy snapshot에 valuation_id를 추측하여 생성하지 않는다. - 구현 근거: jarca_ledger_mcp/infrastructure/sqlite/schema.py, jarca_ledger_mcp/infrastructure/sqlite/migrations.py, jarca_ledger_mcp/application/assets_service.py; migrate_db 85-122 및 157-173은 missing columns와 새 테이블 및 index를 additive하게 추가한다. 이력의 자동 날짜 추정 이관은 없다. legacy rows와 index 보존 및 init twice 회귀가 있고 legacy report와 명시적 correction 경계를 구분한다. - 테스트 근거: tests/test_account_valuations.py, tests/test_issue_12_regressions.py, tests/test_ledger_categories.py, tests/test_review_decision_workbench.py - 판정 근거: 저장된 legacy 데이터의 삭제나 추측 소급은 확인되지 않았다. schema version 12로 바뀐 관련 회귀의 변경은 supporting change로 설명된다. - `C13-read-only` — `unsatisfied` - 계약: preview와 조회 및 Dashboard 렌더링은 금융 쓰기를 실행하지 않는다. 명시적 등록, 정정, 승인 close 및 import 제출만 변경을 수행하고 실패 시 부분 쓰기를 남기지 않는다. - 구현 근거: jarca_ledger_mcp/application/assets_service.py, jarca_ledger_mcp/application/account_valuation_service.py, jarca_ledger_mcp/infrastructure/sqlite/connection.py, jarca_ledger_mcp/infrastructure/sqlite/migrations.py; preview 427 및 list/select/report는 공통 db context를 사용한다. connection.py의 db는 매 호출마다 init_db를 호출하고 migrations.py 178-180은 executescript 및 migrate_db를 실행한다. schema.py 268과 migrations.py 173의 schema_meta INSERT OR REPLACE는 초기화된 DB 조회에서도 실행된다. 기존 row-count 테스트는 이 쓰기를 검사하지 않는다. - 테스트 근거: tests/test_asset_snapshots.py, tests/test_issue_12_regressions.py - 판정 근거: 단순 SELECT 함수처럼 보이는 preview 및 render 조회도 초기화 및 migration 쓰기를 수행한다. 초기화 책임을 명시적 경계에 두고 조회 경로의 DB 쓰기 부재를 검증해야 한다. 금융 행의 개수 불변만으로 no-write 계약을 충족했다고 판정하지 않는다. - `C14-auth-menu-preservation` — `satisfied` - 계약: Dashboard 인증은 DB보다 먼저이며 REQ-001의 cookie와 logout 및 REQ-002의 메뉴 label과 order, shell, query, error와 retry 및 명시적 금융 쓰기 계약을 유지한다. - 구현 근거: dashboard/app.py, dashboard/page_views/accounts.py, dashboard/page_views/assets.py, dashboard/page_views/monthly_settlement.py, docs/interface-contract.md, docs/project-structure.md, docs/runtime-flow.md; auth gate와 menu dispatcher 및 기존 요구사항 파일은 변경되지 않았다. 갱신된 공통 문서 세 개는 pinned baseline 전체를 exact prefix로 보존한다. PR 본문은 전체 pytest 성공을 구현자 실행으로 보고한다. exact head status는 0개이며 reviewer는 browser 또는 전체 pytest를 독립 실행하지 않았다. - 테스트 근거: tests/test_dashboard_menu_transition.py, tests/test_dashboard_app.py - 판정 근거: 기존 계약 삭제나 새 auth 경계는 확인되지 않았다. 구현자 보고 및 정적 보존 검토로 판정하며 CI 또는 독립 browser 성공으로 표현하지 않는다. 새 조회 쓰기 결함은 C13에서 별도로 다룬다. - `C15-exclusions-privacy` — `satisfied` - 계약: 증권사 자동 연동, 정확한 성과 또는 환율 엔진, 새 인증, 별도 월정산 제품, 거래 추론 및 기존 데이터 자동 재작성과 수기 비계좌 자산 전체 이력 재설계를 추가하지 않는다. 실제 계좌 및 금융 증빙과 credential을 로그와 문서 및 테스트에 기록하지 않는다. - 구현 근거: jarca_ledger_mcp/application/assets_service.py, jarca_ledger_mcp/application/account_valuation_service.py, jarca_ledger_mcp/application/imports_service.py, jarca_ledger_mcp/application/reconciliation_service.py, jarca_ledger_mcp/infrastructure/sqlite/schema.py, jarca_ledger_mcp/infrastructure/sqlite/migrations.py; changed-file set 및 전체 diff에서 새로운 외부 가격, 환율 또는 auth와 배포 의존 변경이 없다. non-KRW 금액은 non_krw_without_fx로 제외하고 테스트 및 CI fixture는 synthetic 값을 사용한다. 실제 운영 DB와 증빙을 수집하지 않았다. - 테스트 근거: scripts/ci_fixture_db.py, tests/test_issue_12_regressions.py, tests/test_account_valuations.py - 판정 근거: 설명되지 않는 제외 범위 구현은 확인되지 않았다. 개인정보에 대한 판단은 검토한 변경 및 운영 데이터 미접근 범위에 한정한다. - `D01-requirement-structure` — `unsatisfied` - 계약: 신규 REQ-003을 배정 경로와 제목으로 작성하며 trusted harness README와 TEMPLATE의 JSON metadata, 연속 요구사항 및 AC, 필수 섹션, 판정 기준과 검증 및 검증 분류의 수준과 백엔드와 케이스 및 상태 불변조건을 충족한다. 초기 PR은 미정이며 PR 생성 후 실제 번호를 추적한다. - 구현 근거: docs/requirements/req-003_account-valuation-history.md; REQ-003의 ID와 제목, revision 1.0, approved metadata, 11개 H2, 10개 requirement 및 AC와 실제 Issue 및 PR 추적성을 확인했다. 185-283의 AC 전체에 Cases와 State Invariants는 있으나 verification level과 backend 및 canonical 검증 분류가 없다. tests/test_requirement_docs.py 31-41도 대체 블록 개수만 검사한다. - 테스트 근거: tests/test_requirement_docs.py - 판정 근거: PR 생성 후 실제 번호 및 trusted lifecycle approved는 결함으로 판정하지 않는다. 필수 검증 수준과 백엔드 정보가 10개 AC 모두에서 누락되므로 검증 분류를 실제 계획과 일치하게 보완하고 validator가 trusted 필수 필드를 검사해야 한다. - `D02-requirement-semantics` — `unsatisfied` - 계약: 요구사항에는 평가 근거와 지표 정의, 선택과 future 제외, 정정 및 idempotency 충돌, 대사 완전성, current 및 import 연계, 마감 상태와 불변성과 승인, shared adapter 및 인증, migration과 legacy를 소스 및 테스트에 대응한다. 모든 승인된 경계와 회귀 사례를 인수 기준으로 내린다. - 구현 근거: docs/requirements/req-003_account-valuation-history.md; 5절과 7절은 대부분 기능을 대응하지만 REQ-003.03 및 AC는 cross-account 또는 kind correction 차단을 다루지 않고 REQ-003.08은 provenance만 유지해 시작잔고와 completeness 및 투자 대사 불가 계약을 생략한다. REQ-003.06 및 AC는 승인 전 preview 상태와 수기 unverified carry 차단의 실제 실패를 검증하지 않는다. C04-C10의 실제 source 결함과 일치한다. - 테스트 근거: tests/test_account_valuations.py, tests/test_asset_snapshots.py, tests/test_issue_12_regressions.py, tests/test_requirement_docs.py - 판정 근거: 승인된 경계의 판정 및 무변경 인수 의미를 추가하고 상반된 상태 정의 및 테스트 기대값을 바로잡아야 한다. source 수단이나 새 browser 조합 및 저장 경로를 새 요구사항으로 강제하지 않는다. - `D03-data-model` — `unsatisfied` - 계약: 신규 데이터 모델은 기존 entities 및 valuation과 마감의 관계, FK와 날짜 및 정확한 금액과 NULL 및 0과 선택 지표 및 대출 필수 정의, 계좌와 통화 및 목적과 기준일의 선택 및 index와 단일 유효 정정본, 고정 적용 분류 및 출처와 상태와 누락 및 이월 및 승인 버전, 분리된 정정과 schema11 이관 및 미상 날짜와 legacy 및 최신 캐시 동기화 책임을 정의한다. - 구현 근거: docs/data-model.md; data-model 12-120은 entities와 필드를, 122-140은 관계와 기본 invariants를, 142-157은 migration을 정의한다. 하지만 137-149의 invariant와 migration은 parent scope와 필수 사유, 날짜 증명 및 미상 legacy 처리와 latest-cache 갱신 책임을 설명하지 않는다. 110-116의 run 상태와 승인 필드는 미승인 초안 및 안전한 conditional 허용 경계를 명시하지 않는다. - 테스트 근거: tests/test_account_valuations.py, tests/test_asset_snapshots.py, tests/test_issue_12_regressions.py - 판정 근거: 파일과 큰 구조는 존재하나 필수 데이터 의미 및 unsafe approval 경계와 current-cache 책임이 누락됐다. 실제 persistence 및 query와 일치하는 불변조건과 legacy 및 cache 책임을 보완해야 한다. 특정 물리 필드명을 새로 강제하지 않는다. - `D04-interface-contract` — `unsatisfied` - 계약: 인터페이스 문서는 기존 auth 및 메뉴를 보존하고 평가 등록 및 조회 및 정정의 모든 입력과 유효본 및 원금 정의 출력, report 및 preview/close 및 월정산과 대사와 current API의 공통 선택, exact 기본과 실제 날짜 및 age 및 이월과 누락 및 미확인과 출처 및 버전과 승인 출력을 정의한다. 잘못된 입력과 scope 및 충돌과 부족 근거는 무변경 실패이며 기존 envelope와 required keys 및 의미 변경 정책을 명시한다. - 구현 근거: docs/interface-contract.md; interface-contract 263-388은 valuation 및 close와 additive compatibility를 추가했고 auth와 메뉴 baseline은 보존한다. 280-282는 실제 enum 및 optional metrics를 source validation이라는 설명으로 넘기고 correct의 parent 및 reason과 effective principal output을 고정하지 않는다. 288-290과 324-326에는 실제 기준일과 age 및 확인 상태와 version/approval output과 월정산 및 대사 및 current별 계약이 없다. - 테스트 근거: tests/test_account_valuations.py, tests/test_issue_12_regressions.py, tests/test_contract_regression.py - 판정 근거: source를 읽으라는 참조만으로 요청된 입력과 출력 계약을 대체할 수 없다. 승인된 필드 의미 및 필수 여부와 오류 무변경과 공통 선택 및 조건부 상태를 실제 signature와 readback에 대응해야 한다. 기존 인증 계약은 보존한다. - `D05-project-structure` — `unsatisfied` - 계약: 프로젝트 구조 문서는 기존 source와 test 및 evidence를 보존하고 SQLite schema와 migrations, application의 assets와 account writes 및 import와 reconciliation 및 monthly 책임, 공개 facade와 MCP 및 Streamlit과 기존 세 화면 및 tests를 exact 경로로 대응한다. adapter에서 선택 정책을 복제하지 않고 대출 정의와 verified as_of 및 conditional 승인 경계를 shared application에 배치한다. - 구현 근거: docs/project-structure.md; project-structure 122-164는 새 service와 일부 경로 및 기본 의존 방향을 설명하고 baseline은 보존한다. 문서 전체에 schema.py, monthly_settlement_service.py 및 asset_account_services.py의 역할이 없고 세 선택 및 승인 정책의 책임과 대응 테스트도 없다. tree의 나열 또는 Missing semantic items 0 선언은 해당 의무의 증거가 아니다. - 테스트 근거: tests/test_requirement_docs.py - 판정 근거: 이미 승인된 경로별 persistence, authority sync 및 월정산과 facade의 책임과 정책별 shared service 및 test 대응을 보완해야 한다. 새 모듈 수나 특정 분할 설계는 요구하지 않는다. - `D06-runtime-flow` — `unsatisfied` - 계약: 런타임 문서는 auth 및 메뉴를 보존하고 register/correct의 증빙 및 scope 검증과 append 및 유효본 확인 및 최신 캐시 동기화를 단일 트랜잭션으로 설명한다. 날짜 및 정책과 통화 및 대표 합산과 경고 read, preview 후 명시적 approval 및 원자적 freeze, reasoned reclose, 같은 근거의 monthly 및 대사, import와 이관 trigger 및 실패복구, retry와 concurrency 및 preview drift 재검증과 무부분쓰기, 비민감 valuation/run 상관 신호를 정의한다. - 구현 근거: docs/runtime-flow.md; runtime-flow 147-218은 generic valuation 및 close와 propagation, conflict와 rollback 및 신호를 추가하고 baseline은 보존한다. 158-161은 current-cache 동기화 및 correction scope를 빠뜨리고 172-175는 preview 이후 선택 근거 및 승인 대상 drift 재검증을 설명하지 않는다. 179-185는 completeness 또는 loan과 investment 불가 상태를 보존하는 흐름이 없고 192는 unsafe 자료도 승인 후 복구 가능한 것처럼 경계를 단순화한다. - 테스트 근거: tests/test_account_valuations.py, tests/test_asset_snapshots.py, tests/test_issue_12_regressions.py - 판정 근거: 승인된 재검증과 unsafe 비합산 및 초안 상태, current/import 권위와 대사 완전성 및 오류 무변경의 실제 순서를 보완해야 한다. 새로운 외부 호출이나 운영 승인 체계를 추가할 필요는 없다. - `C16-supporting-evidence-scope` — `satisfied` - 계약: 모든 changed file은 승인된 기능과 필수 supporting change 또는 테스트 evidence로 설명되고 기존 requirement ID를 임의 갱신하거나 범위 밖 제품 및 설정을 변경하지 않는다. - 구현 근거: dashboard/page_views/accounts.py, dashboard/page_views/assets.py, dashboard/page_views/monthly_settlement.py, docs/data-model.md, docs/interface-contract.md, docs/project-structure.md, docs/requirements/req-003_account-valuation-history.md, docs/runtime-flow.md, jarca_ledger_mcp/adapters/mcp/server.py, jarca_ledger_mcp/adapters/mcp/tool_contracts.py, jarca_ledger_mcp/adapters/streamlit/accounts_gateway.py, jarca_ledger_mcp/application/__init__.py, jarca_ledger_mcp/application/account_valuation_service.py, jarca_ledger_mcp/application/accounts_write_services.py, jarca_ledger_mcp/application/assets_service.py, jarca_ledger_mcp/application/imports_service.py, jarca_ledger_mcp/application/monthly_settlement_service.py, jarca_ledger_mcp/application/reconciliation_service.py, jarca_ledger_mcp/infrastructure/sqlite/migrations.py, jarca_ledger_mcp/infrastructure/sqlite/schema.py, jarca_ledger_mcp/service.py, scripts/ci_fixture_db.py, tests/test_account_valuations.py, tests/test_asset_snapshots.py, tests/test_contract_regression.py, tests/test_issue_12_regressions.py, tests/test_ledger_categories.py, tests/test_requirement_docs.py, tests/test_review_decision_workbench.py, tests/test_service.py; 변경 30개는 valuation/schema, account/import, snapshot/reconciliation/monthly, adapter exports 및 세 화면, 필수 문서 5종과 focused tests 및 CI synthetic seed에 대응된다. category 및 workbench tests는 schema version 11에서 12로 기대값만 바뀐다. remote diff 61개 hunk를 immutable base/head blob과 직접 대조했다. 구현자 PR은 pytest 및 ruff exit 0을 보고하지만 CI status는 0개다. - 테스트 근거: tests/test_account_valuations.py, tests/test_asset_snapshots.py, tests/test_issue_12_regressions.py, tests/test_contract_regression.py, tests/test_service.py, tests/test_requirement_docs.py - 판정 근거: 설명되지 않는 범위 초과는 없다. 테스트 주장은 구현자 실행으로 구분하며 reviewer의 compile-only와 추출 함수 probe는 전체 제품 pytest 또는 CI 성공을 대체하지 않는다. ### 범위 판정 - 누락: 다른 계좌 및 통화와 목적 정정 차단과 사유 검증, 같은 증빙의 key 없는 공개 재입력 식별, 과거 import의 현재값 rollback 방지, 수기 이월의 확인 상태와 미승인 초안 경계, report 및 월정산의 실제 평가일과 누락 및 이월 경고 전파, 대사 시작잔고와 완전성 및 대출과 투자 불가 상태, 조회 및 preview의 DB 무쓰기 경계, 필수 문서 5종의 검증 분류와 승인된 데이터 및 인터페이스 및 구조와 흐름 의미 - 범위 초과: 없음 - 명세 모순: 없음 ### 결론 명확한 기존 계약 위반이 있어 변경을 요청한다. 2026-09-30 현재 잔고에 대한 과거 import 보존, scope와 사유 없는 정정의 무변경 실패, 동일 증빙 재입력 재사용, 미확인 수기 이월 금지 및 미승인 초안 상태, 불변 마감 근거의 보고와 월정산 전파, 대사 완전성과 공통 대출 근거, read-only DB 경계 및 필수 문서 의무를 보완해야 한다. 새 제품 정책 선택이나 Discovery 수정은 필요하지 않다. 전체 pytest 및 ruff 성공은 구현자 PR 본문 보고이며 reviewer 독립 전체 테스트 또는 CI 성공은 아니다. reviewer는 pinned blob과 61개 diff hunk 대조, compile-only 검증 및 stdlib 합성 in-memory 추출 함수 probe를 수행했다. 제품 소스와 Issue 및 branch를 변경하거나 merge하지 않았다. <!-- gitea-agent:implementation-spec-review/v1 owner=jsfamily repository=jarca-ledger-mcp issue=12 pr=13 head=399d0923be9c96e95b5c708dbfc2d231e2e0b98b contract-sha256=6d86b591b022fcc722611bfec6d24e54a64216ab6f7c4098f357e25420218818 result-sha256=bc774aaa48e61359d0c5bde65d81928fd0bce12a518bd349aab1950126871356 correlation=fdf8ada08c903e7b8937f5b79f5c9be8d66cdb629a2d2718d4eac1bce5586a19 -->
gitea-impl-agent added 1 commit 2026-10-06 14:46:39 +00:00
Author
Owner

구현 재작업 결과

지적 처리

  • C02-money-metrics — resolved
    • 분류: valid_fix
    • 변경: account_valuation_service.py, assets_service.py, canonical docs/tests
    • 검증: NULL/0 및 원금·수익 지표 round-trip/합산 회귀
    • 근거: 금액과 선택 지표 의미를 독립 보존하고 NULL을 0으로 변환하지 않음
  • C04-correction — resolved
    • 분류: valid_fix
    • 변경: account_valuation_service.py, review59 account tests
    • 검증: scope·사유·cycle·동시 child·replay 회귀
    • 근거: append-only correction 불변조건과 충돌 envelope 보장
  • C05-current-cache — resolved
    • 분류: valid_fix
    • 변경: imports_service.py, import regression tests
    • 검증: 과거 import 후 current cache no-rollback 회귀
    • 근거: 뒤늦은 과거 자료가 최신 표시값을 되돌리지 않음
  • C06-idempotency — resolved
    • 분류: valid_fix
    • 변경: account_valuation_service.py, review59 account tests
    • 검증: source_ref correction replay·unrelated conflict·concurrency 회귀
    • 근거: 동일 evidence chain만 재사용하고 다른 payload는 거부
  • C08-close-policy — resolved
    • 분류: valid_fix
    • 변경: assets_service.py, snapshot regressions
    • 검증: incomplete preview와 approved conditional close decision table
    • 근거: 누락·이월만 명시적 승인하고 미확인·미래 자료는 합산하지 않음
  • C09-reconciliation — resolved
    • 분류: valid_fix
    • 변경: reconciliation_service.py, Issue 12 regressions
    • 검증: opening evidence와 기준일까지 연속 coverage의 complete/incomplete 경계
    • 근거: 근거 부족 시 INCOMPLETE_CALCULATION, 가짜 거래·잔액 추론 없음
  • C10-provenance — resolved
    • 분류: valid_fix
    • 변경: assets_service.py, monthly_settlement_service.py, Dashboard, report tests
    • 검증: exact replay equality·preview drift·aliases·recursive redaction·close/timeseries/monthly 전파
    • 근거: immutable evidence와 승인·정정·누락·이월 provenance를 동일 shape로 전달
  • C13-read-only — resolved
    • 분류: valid_fix
    • 변경: SQLite reader boundary, application readers, Dashboard gateway/app, readonly tests
    • 검증: missing DB no-create 및 initialized authenticated all-pages no-write
    • 근거: query/preview/render가 bootstrap·migration·commit을 수행하지 않음
  • D01-preservation — resolved
    • 분류: evidence_gap
    • 변경: canonical requirement와 항목별 preservation matrix/validator
    • 검증: source/test evidence 대응 validator
    • 근거: baseline 의미를 항목별로 추적
  • D02-data-model — resolved
    • 분류: evidence_gap
    • 변경: docs/data-model.md
    • 검증: schema/NULL/정정/run invariants 문서 검사
    • 근거: 영속 모델과 legacy 경계를 canonical화
  • D03-requirements — resolved
    • 분류: evidence_gap
    • 변경: docs/requirements/req-003_account-valuation-history.md
    • 검증: per-requirement impact·cases·state invariants validator
    • 근거: acceptance semantics와 구현 evidence를 일대일 연결
  • D04-interface — resolved
    • 분류: evidence_gap
    • 변경: docs/interface-contract.md
    • 검증: exact signature·top-level/nested aliases·errors·replay/drift validator
    • 근거: 실제 public response shape와 일치
  • D05-structure — resolved
    • 분류: evidence_gap
    • 변경: docs/project-structure.md
    • 검증: application/adapter/SQLite/read-only/redaction ownership validator
    • 근거: 정책과 책임 경계를 canonical mapping으로 고정
  • D06-runtime — resolved
    • 분류: evidence_gap
    • 변경: docs/runtime-flow.md
    • 검증: cache no-rollback·reconciliation unavailable·preview drift·Dashboard no-write validator
    • 근거: 성공·실패·무부분쓰기 흐름을 실제 구현과 일치시킴

최종 검증

  • Local checks: exact head 6a8a27a74ece9a9cce6f9772259677813d91ddf8; pytest exit 0 (233 passed, 4 skipped), Ruff exit 0, compileall exit 0, diff-check exit 0
  • Runtime/browser: synthetic Streamlit AppTest와 authenticated all-pages no-write 검증 통과; 실제 브라우저 검증은 이번 review 계약에 요구되지 않음
  • Independent gates: specification PASS / code-security PASS, blocker 0
  • Commit status: pending (status context 0개)
  • Actions runs: 없음

다음 단계

Reviewer가 rework head를 새 snapshot으로 다시 검토해야 하며 이 comment는 기존 REQUEST_CHANGES를 해제하거나 승인을 의미하지 않습니다.

## 구현 재작업 결과 - Source Issue: #12 - Pull Request: #13 - Source Review: #59 - Reviewed head: `399d0923be9c96e95b5c708dbfc2d231e2e0b98b` - Rework head: `6a8a27a74ece9a9cce6f9772259677813d91ddf8` - Contract SHA-256: `6d86b591b022fcc722611bfec6d24e54a64216ab6f7c4098f357e25420218818` - Result: `rework_delivered` ### 지적 처리 - `C02-money-metrics` — `resolved` - 분류: `valid_fix` - 변경: `account_valuation_service.py`, `assets_service.py`, canonical docs/tests - 검증: NULL/0 및 원금·수익 지표 round-trip/합산 회귀 - 근거: 금액과 선택 지표 의미를 독립 보존하고 NULL을 0으로 변환하지 않음 - `C04-correction` — `resolved` - 분류: `valid_fix` - 변경: `account_valuation_service.py`, review59 account tests - 검증: scope·사유·cycle·동시 child·replay 회귀 - 근거: append-only correction 불변조건과 충돌 envelope 보장 - `C05-current-cache` — `resolved` - 분류: `valid_fix` - 변경: `imports_service.py`, import regression tests - 검증: 과거 import 후 current cache no-rollback 회귀 - 근거: 뒤늦은 과거 자료가 최신 표시값을 되돌리지 않음 - `C06-idempotency` — `resolved` - 분류: `valid_fix` - 변경: `account_valuation_service.py`, review59 account tests - 검증: `source_ref` correction replay·unrelated conflict·concurrency 회귀 - 근거: 동일 evidence chain만 재사용하고 다른 payload는 거부 - `C08-close-policy` — `resolved` - 분류: `valid_fix` - 변경: `assets_service.py`, snapshot regressions - 검증: incomplete preview와 approved conditional close decision table - 근거: 누락·이월만 명시적 승인하고 미확인·미래 자료는 합산하지 않음 - `C09-reconciliation` — `resolved` - 분류: `valid_fix` - 변경: `reconciliation_service.py`, Issue 12 regressions - 검증: opening evidence와 기준일까지 연속 coverage의 complete/incomplete 경계 - 근거: 근거 부족 시 `INCOMPLETE_CALCULATION`, 가짜 거래·잔액 추론 없음 - `C10-provenance` — `resolved` - 분류: `valid_fix` - 변경: `assets_service.py`, `monthly_settlement_service.py`, Dashboard, report tests - 검증: exact replay equality·preview drift·aliases·recursive redaction·close/timeseries/monthly 전파 - 근거: immutable evidence와 승인·정정·누락·이월 provenance를 동일 shape로 전달 - `C13-read-only` — `resolved` - 분류: `valid_fix` - 변경: SQLite reader boundary, application readers, Dashboard gateway/app, readonly tests - 검증: missing DB no-create 및 initialized authenticated all-pages no-write - 근거: query/preview/render가 bootstrap·migration·commit을 수행하지 않음 - `D01-preservation` — `resolved` - 분류: `evidence_gap` - 변경: canonical requirement와 항목별 preservation matrix/validator - 검증: source/test evidence 대응 validator - 근거: baseline 의미를 항목별로 추적 - `D02-data-model` — `resolved` - 분류: `evidence_gap` - 변경: `docs/data-model.md` - 검증: schema/NULL/정정/run invariants 문서 검사 - 근거: 영속 모델과 legacy 경계를 canonical화 - `D03-requirements` — `resolved` - 분류: `evidence_gap` - 변경: `docs/requirements/req-003_account-valuation-history.md` - 검증: per-requirement impact·cases·state invariants validator - 근거: acceptance semantics와 구현 evidence를 일대일 연결 - `D04-interface` — `resolved` - 분류: `evidence_gap` - 변경: `docs/interface-contract.md` - 검증: exact signature·top-level/nested aliases·errors·replay/drift validator - 근거: 실제 public response shape와 일치 - `D05-structure` — `resolved` - 분류: `evidence_gap` - 변경: `docs/project-structure.md` - 검증: application/adapter/SQLite/read-only/redaction ownership validator - 근거: 정책과 책임 경계를 canonical mapping으로 고정 - `D06-runtime` — `resolved` - 분류: `evidence_gap` - 변경: `docs/runtime-flow.md` - 검증: cache no-rollback·reconciliation unavailable·preview drift·Dashboard no-write validator - 근거: 성공·실패·무부분쓰기 흐름을 실제 구현과 일치시킴 ### 최종 검증 - Local checks: exact head `6a8a27a74ece9a9cce6f9772259677813d91ddf8`; pytest exit 0 (233 passed, 4 skipped), Ruff exit 0, compileall exit 0, diff-check exit 0 - Runtime/browser: synthetic Streamlit AppTest와 authenticated all-pages no-write 검증 통과; 실제 브라우저 검증은 이번 review 계약에 요구되지 않음 - Independent gates: specification PASS / code-security PASS, blocker 0 - Commit status: pending (status context 0개) - Actions runs: 없음 ### 다음 단계 Reviewer가 rework head를 새 snapshot으로 다시 검토해야 하며 이 comment는 기존 `REQUEST_CHANGES`를 해제하거나 승인을 의미하지 않습니다. <!-- gitea-agent:implementation-rework/v1 owner=jsfamily repository=jarca-ledger-mcp issue=12 pr=13 review=59 reviewed-head=399d0923be9c96e95b5c708dbfc2d231e2e0b98b head=6a8a27a74ece9a9cce6f9772259677813d91ddf8 contract-sha256=6d86b591b022fcc722611bfec6d24e54a64216ab6f7c4098f357e25420218818 result-sha256=7670e7d5f50a1fd458d4349cef2883e323a23fdf13b24b26915810c61bfb5f2d correlation=69564c1542af3d67aa7b94a2434f8eeadd775f148c0444a8c1e7594a162d0bf2 -->
gitea-spec-agent requested changes 2026-10-06 22:22:32 +00:00
Dismissed
gitea-spec-agent left a comment
Owner

구현 명세 적합성 검토

Acceptance criteria 판정

  • C01-history — satisfied

    • 계약: 평가 계좌 FK, 기준일과 등록일, 대표 금액과 통화와 목적, 출처와 확인 상태, 증빙 식별자, 정정 연결과 사유 및 선택 시간 자료를 이력으로 보존한다.
    • 구현 근거: jarca_ledger_mcp/application/account_valuation_service.py, jarca_ledger_mcp/infrastructure/sqlite/schema.py, jarca_ledger_mcp/infrastructure/sqlite/migrations.py; schema.py 234-266 및 account_valuation_service.py 155-180, 235-245는 FK, 기준일, 등록일, 정정 연결 및 optional metrics를 저장한다. 날짜 자료와 optional 시간 자료를 구분한다.
    • 테스트 근거: tests/test_account_valuations.py
    • 판정 근거: 이력 구조 계약은 유지됐다. 부모 scope 및 대표 부채 정의 누락은 별도 항목에서 판정한다.
  • C02-money-metrics — satisfied

    • 계약: 금액 정밀도와 NULL 및 0을 보존하고 취득원가, 순납입액, 기관 표시 원금 금액과 정의 및 원문 명칭, 손익과 수익률의 계산 기준을 구분한다. 투자 대표 총평가액과 포함 현금 및 원금을 중복 합산하지 않는다.
    • 구현 근거: jarca_ledger_mcp/application/account_valuation_service.py, jarca_ledger_mcp/infrastructure/sqlite/schema.py, docs/data-model.md, docs/requirements/req-003_account-valuation-history.md; account_valuation_service.py 160-163, 180, 235-245 및 docs/data-model.md 34, 57-60은 integer, NULL 및 0을 보존하고 investment principal과 loan outstanding principal을 구분한다. test_valuation_round_trip_preserves_null_zero_and_physical_amount_mapping을 정적으로 확인했다.
    • 테스트 근거: tests/test_issue_12_review59_account.py, tests/test_issue_12_regressions.py
    • 판정 근거: 이전 C02의 지표 대응 및 round-trip 의미 누락은 해소됐다. 대표 정의 필수 검증의 balance 우회는 N01에서 별도로 판정한다.
  • N01-loan-balance-definition — unsatisfied

    • 계약: 대출 평가 기록마다 대표 부채가 원금만인지 원금과 이자 및 수수료인지 필수로 명시하고 기본값으로 추정하지 않는다. 목적 alias가 필수 정의 계약을 우회하지 않는다.
    • 구현 근거: jarca_ledger_mcp/application/account_valuation_service.py, docs/requirements/req-003_account-valuation-history.md; account_valuation_service.py 84-87은 loan 및 loan_balance에만 정의를 필수로 하고 balance에는 누락을 허용한다. 183-191도 account.type이 loan이고 kind가 balance인 경우 정의 누락을 차단하지 않는다. REQ-003 91과 data-model 60은 loan 필수 정의를 명시한다. test_loan_balance_fallback_with_representative_definition_is_liability는 정의가 있는 balance만 확인한다.
    • 테스트 근거: tests/test_issue_12_regressions.py, tests/test_issue_12_review59_account.py
    • 판정 근거: loan 계좌의 verified balance 평가를 대표 정의 없이 등록할 수 있다. balance에 정의를 제공하면 거부된다는 delegate 주장은 실제 86행과 다르므로 제외했다. 문제는 정의 없는 등록 허용이며 모든 허용 loan purpose에 같은 필수 계약을 적용해야 한다. supplemental 추출 함수 관찰과 무관하게 직접 validation 및 account checks가 누락을 증명한다.
  • C03-selection — satisfied

    • 계약: 계좌와 통화 및 평가 목적별 유효 자료를 선택한다. exact는 당일 확인 자료만, as_of는 기준일 이하 최신 확인 자료만 사용한다. 미래 자료는 제외하고 미확인 후보는 확인 자료를 대체하거나 합산하지 않는다. 실제 기준일과 경과 일수 및 이월 상태를 반환한다.
    • 구현 근거: jarca_ledger_mcp/application/account_valuation_service.py, jarca_ledger_mcp/application/assets_service.py; account_valuation_service.py 254-300 및 assets_service.py 148-211은 계좌별 purpose, verified leaf, exact 및 as_of, future 제외와 미확인 후보 분리를 유지한다. test_select_exact_and_as_of_excludes_unverified_and_reports_carry_forward 등 관련 named test의 source를 대조했다.
    • 테스트 근거: tests/test_account_valuations.py, tests/test_issue_12_regressions.py
    • 판정 근거: 확인 자료 선택과 후보 비합산은 정적으로 충족한다. loan 필수 정의의 등록 경계는 N01에서 별도로 판정한다.
  • C04-correction-validation — satisfied

    • 계약: 평가 정정은 append-only로 대상과 사유를 연결하며 다른 계좌, 통화, 목적을 참조하는 정정과 순환 및 동일 유효본의 동시 분기를 차단한다.
    • 구현 근거: jarca_ledger_mcp/application/account_valuation_service.py, jarca_ledger_mcp/infrastructure/sqlite/schema.py; account_valuation_service.py 176-177, 193-212, 238-241, 310-316은 부모 scope와 사유 및 ancestry와 단일 child를 검증한다. test_direct_correction_requires_matching_existing_parent_and_reason 및 test_correction_rejects_currency_and_kind_override_but_preserves_valid_overrides를 확인했다.
    • 테스트 근거: tests/test_issue_12_review59_account.py, tests/test_account_valuations.py, tests/test_issue_12_regressions.py
    • 판정 근거: 이전 C04의 다른 계좌 및 목적과 통화 및 사유 없는 정정 허용은 해소됐다. 동일 증빙 정정 replay는 C06의 잔여 결함이다.
  • C05-current-import — unsatisfied

    • 계약: 뒤늦은 과거 자료 등록으로 최신 표시값을 과거로 되돌리지 않는다. 기존 계좌 수정과 import의 최신 캐시 및 새 이력 권위를 연결하며 동기화 시각을 실제 평가일로 오인하지 않는다.
    • 구현 근거: jarca_ledger_mcp/application/imports_service.py, jarca_ledger_mcp/application/assets_service.py, jarca_ledger_mcp/application/accounts_write_services.py; imports_service.py 43-58은 source basis_date를 last_synced_at과 비교하면서 갱신 시에는 import 실행시각 synced_at을 last_synced_at에 저장한다. 같은 함수를 사용하는 세 import 경로는 242-244, 709-711, 934-936이다. assets_service.py 140-141은 이 동기화시각을 current valuation_date로 노출한다.
    • 테스트 근거: tests/test_issue_12_review59_account.py, tests/test_import_provenance_policy.py
    • 판정 근거: 과거 import의 단순 rollback 방지는 보완됐지만 실제 평가일과 동기화시각은 여전히 혼합된다. 예를 들어 2026-10-06에 2026-09-30 근거를 import한 뒤 2026-10-01 근거를 import하면 현재시각 2026-10-06이 비교 기준이 되어 실제로 더 최신인 2026-10-01 잔고 갱신을 차단한다. 실제 근거일로 비교하고 동기화시각을 기준일로 표시하지 않아야 한다. 기존 historical import tests는 이 연속 import 경계를 검사하지 않는다.
  • C06-idempotency — unsatisfied

    • 계약: 동일 증빙 또는 idempotency 재입력은 동일 기록을 재사용하며 같은 키의 다른 payload는 충돌이다. 동시 정정의 분기를 차단하고 UNIQUE 계좌 및 기준일 하나로 정정 추가를 막지 않는다.
    • 구현 근거: jarca_ledger_mcp/application/account_valuation_service.py, jarca_ledger_mcp/infrastructure/sqlite/schema.py, jarca_ledger_mcp/infrastructure/sqlite/migrations.py, jarca_ledger_mcp/application/accounts_write_services.py, jarca_ledger_mcp/application/imports_service.py; account_valuation_service.py 214-236은 일반 source_ref 중복을 보완했지만 correct_account_valuation의 317-326은 명시 key만 replay하고 기존 child가 있으면 동일 증빙 및 payload 비교 없이 correction_conflict로 종료한다. test_correction_preserves_source_ref_without_evidence_identity_conflict는 첫 정정만 확인한다.
    • 테스트 근거: tests/test_issue_12_review59_account.py, tests/test_account_valuations.py, tests/test_issue_12_regressions.py
    • 판정 근거: 일반 등록과 명시 key 재사용은 해소됐으나 source_ref가 같은 부모를 동일 amount와 사유로 key 없이 정정 재시도하면 기존 정정본을 재사용하지 않는다. 이는 동일 증빙 재입력 재사용 계약의 잔여 위반이다. 동일 증빙과 부모 및 payload의 재사용과 실제 다른 payload 충돌을 구분해야 한다. supplemental AST probe도 같은 결과를 관찰했으나 판정은 이 직접 source 및 계약 대조에 근거한다.
  • C07-close-immutability — satisfied

    • 계약: 기존 asset_snapshots와 correction run을 보존하고 평가 정정 및 거래 추가로 기존 마감을 자동 변경하지 않는다. 동일 기준일 재마감은 사유와 이전 run 연결을 가진 새 버전을 원자적으로 추가한다.
    • 구현 근거: jarca_ledger_mcp/application/assets_service.py, jarca_ledger_mcp/infrastructure/sqlite/schema.py, jarca_ledger_mcp/infrastructure/sqlite/migrations.py; assets_service.py 670-780은 기존 run을 변경하지 않고 correction_reason 및 이전 run을 연결해 새 run과 rows를 원자적으로 추가한다. 기존 snapshot 및 동시 first-close tests와 immutable close tests를 정적으로 대조했다.
    • 테스트 근거: tests/test_asset_snapshots.py, tests/test_issue_12_regressions.py
    • 판정 근거: 저장된 기존 run의 불변성과 append-only 재마감은 충족한다. 이전 key의 replay 응답에 다른 run evidence가 섞이는 N02는 별도 변경 요청이다.
  • N02-close-replay-run-binding — unsatisfied

    • 계약: 마감 버전의 근거는 불변이며 동일 idempotency 요청은 원래 기록을 재사용한다. 재마감으로 과거 run 응답 및 evidence를 변경하지 않는다.
    • 구현 근거: jarca_ledger_mcp/application/assets_service.py, docs/interface-contract.md; assets_service.py 629-643은 existing key의 run을 찾은 뒤 632행에서 basis date의 latest run rows와 metadata를 읽고 643행에서는 기존 run ID를 응답한다. 644-650의 correction 및 inserted rows도 최신 run에 결합된다. interface-contract.md 마지막 replay 계약은 원래 persisted run과 evidence로 응답을 재구성하도록 정의한다.
    • 테스트 근거: tests/test_issue_12_review59_reports.py, tests/test_issue_12_regressions.py
    • 판정 근거: 최초 close key A, 명시적 correction key B, key A 재시도 순서에서 run ID는 A인데 correction과 snapshot IDs 및 evidence는 B로 섞인다. 실제 source가 서로 다른 조회 authority를 결합한다. 기존 immutable replay named test는 재마감 이후 key A 재시도를 확인하지 않는다. 기존 run ID로 rows와 metadata 및 응답 전부를 재구성하고 이 경계의 회귀를 보완해야 한다.
  • C08-approved-conditional — satisfied

    • 계약: 완전한 exact 마감, 미완료 초안, 별도 승인된 조건부 마감을 구분한다. 승인 전 누락 및 이월은 미완료 초안이고 승인 후에도 누락 제외 및 확인된 과거값 이월만 허용한다. 미확인, 미래, 기준일 미상 금액은 승인으로도 합산하지 않으며 적용과 제외와 이월 및 승인자와 시각과 사유와 근거를 고정한다.
    • 구현 근거: jarca_ledger_mcp/application/assets_service.py, jarca_ledger_mcp/infrastructure/sqlite/schema.py, dashboard/page_views/assets.py; assets_service.py 232-258, 581-589, 618-627, 730-779는 명시적으로 입력된 dated manual evidence, 누락 및 future/unknown 제외, 미승인 incomplete_draft와 승인 flags 및 metadata, carried evidence 저장을 처리한다. test_dated_manual_asset_is_verified_and_preview_needs_approval 및 test_approved_carried_close_is_conditional_and_persists_provenance를 확인했다.
    • 테스트 근거: tests/test_issue_12_review59_reports.py, tests/test_issue_12_regressions.py, tests/test_asset_snapshots.py
    • 판정 근거: 이전 C08의 stored unverified 이월과 미승인 conditional 기대값은 보완됐다. 기존 수기 제출 자료를 확인된 manual evidence로 처리하는 계약이 source와 문서 및 tests에 일치한다. 별도 확인 상태 필드나 수기 전체 이력 재설계를 새 의무로 강제하지 않는다.
  • C09-reconciliation — satisfied

    • 계약: 외부 확인값과 장부 계산값을 분리하고 검증된 시작잔고, 기준시점, 거래 포함 범위와 계산 완전성을 표시한다. 거래 없는 수동 투자 계좌의 대사 불가 및 거래 미수입과 평가 수동 관리 상태를 구분하고 가짜 거래를 만들지 않는다. 대사도 공통 평가 근거와 대출 대표 정의를 사용한다.
    • 구현 근거: jarca_ledger_mcp/application/reconciliation_service.py, jarca_ledger_mcp/application/account_valuation_service.py, jarca_ledger_mcp/application/monthly_settlement_service.py; reconciliation_service.py 31-63, 101-177, 192-206은 opening evidence 및 거래 포함 범위와 completeness를 구분하며 INCOMPLETE_CALCULATION, VALUATION_MANAGED, unavailable와 loan purpose를 전파한다. test_reconciliation_does_not_mark_last_balance_without_opening_evidence_complete 및 test_reconciliation_uses_currency_and_loan_priority_and_canonical_provenance를 확인했다.
    • 테스트 근거: tests/test_issue_12_review59_reports.py, tests/test_issue_12_regressions.py, tests/test_service.py
    • 판정 근거: 이전 C09의 시작잔고 없는 계산 확정 및 대출 purpose 무시와 투자 불가 상태 누락은 정적 source 및 named tests 대조상 해소됐다.
  • C10-report-monthly-evidence — satisfied

    • 계약: MCP와 Dashboard 및 월정산 보고에서 같은 기준일과 선택 근거 및 실제 평가일, 경과 일수, 확인 상태, 누락과 미확인 및 이월 경고, 마감 버전 및 조건부 승인 근거를 일관되게 전달한다.
    • 구현 근거: jarca_ledger_mcp/application/assets_service.py, jarca_ledger_mcp/application/monthly_settlement_service.py, dashboard/page_views/monthly_settlement.py, dashboard/page_views/accounts.py; assets_service.py 554-592, 817-852 및 monthly_settlement_service.py는 실제 평가일과 age 및 carry, 상태와 warnings 및 applied/excluded evidence를 immutable run에서 재구성한다. test_approved_carry_provenance_is_identical_across_closed_downstream_reports와 test_monthly_settlement_propagates_snapshot_provenance_id_and_actual_valuation_date를 확인했다.
    • 테스트 근거: tests/test_issue_12_review59_reports.py, tests/test_issue_12_regressions.py, tests/test_service.py
    • 판정 근거: 이전 C10의 일반 report 및 월정산 날짜와 경고 및 provenance 누락은 해소됐다. idempotency replay의 다른 run 혼합은 N02에서 별도로 판정한다.
  • C11-adapter-structure — satisfied

    • 계약: MCP와 Streamlit gateway는 공통 application을 사용하고 기존 공개 호출명과 기존 인수 및 success와 실패 error_code 및 error envelope를 가능한 한 유지한다. 새 Dashboard 인증 또는 MCP 인증을 도입하지 않는다.
    • 구현 근거: jarca_ledger_mcp/adapters/mcp/server.py, jarca_ledger_mcp/adapters/mcp/tool_contracts.py, jarca_ledger_mcp/adapters/streamlit/accounts_gateway.py, jarca_ledger_mcp/application/__init__.py, jarca_ledger_mcp/service.py, dashboard/page_views/accounts.py, dashboard/page_views/assets.py, dashboard/page_views/monthly_settlement.py; MCP server 및 tool_contracts, accounts 및 overview gateways, service exports와 세 Dashboard pages의 호출은 shared application으로 연결된다. test_snapshot_public_api_preserves_legacy_db_path_position 및 계약 snapshot의 additive keys를 확인했다.
    • 테스트 근거: tests/test_contract_regression.py, tests/test_issue_12_regressions.py
    • 판정 근거: 기존 호출명과 db_path 인수 및 envelope와 shared service 구조를 보존했다. 공통 service의 잔여 결함은 adapter 연결의 충족으로 상쇄하지 않는다.
  • C12-migration-legacy — satisfied

    • 계약: schema 11의 기존 데이터와 마감 및 개인정보를 보존하고 additive하고 idempotent한 migration을 제공한다. 기준일 증거 없는 값을 임의 월말로 소급하거나 legacy snapshot에 valuation_id를 추측하여 생성하지 않는다.
    • 구현 근거: jarca_ledger_mcp/infrastructure/sqlite/schema.py, jarca_ledger_mcp/infrastructure/sqlite/migrations.py, jarca_ledger_mcp/application/assets_service.py; schema.py와 migrations.py는 additive schema 12, optional columns, 단일 child 및 non-empty key index를 보존한다. 기존 records를 임의 날짜로 이관하지 않고 legacy report와 explicit correction을 구분한다. 관련 schema 및 legacy tests를 확인했다.
    • 테스트 근거: tests/test_account_valuations.py, tests/test_issue_12_regressions.py, tests/test_ledger_categories.py, tests/test_review_decision_workbench.py
    • 판정 근거: 이전 migration 및 legacy 계약은 유지됐다. source_ref나 valuation_id의 임의 자동 추정 및 기존 마감 삭제는 확인되지 않았다.
  • C13-read-only — satisfied

    • 계약: preview와 조회 및 Dashboard 렌더링은 금융 쓰기를 실행하지 않는다. 명시적 등록, 정정, 승인 close 및 import 제출만 변경을 수행하고 실패 시 부분 쓰기를 남기지 않는다.
    • 구현 근거: jarca_ledger_mcp/infrastructure/sqlite/connection.py, jarca_ledger_mcp/application/shared.py, jarca_ledger_mcp/application/system_services.py, jarca_ledger_mcp/application/account_valuation_service.py, jarca_ledger_mcp/application/assets_service.py; connection.py 31-53의 connect_readonly 및 read_db는 기존 파일에 mode=ro로 연결하고 초기화 및 commit을 수행하지 않는다. shared.py의 read_operation과 조회 services는 read_db를 사용한다. test_read_schema_error_is_not_misreported_as_uninitialized는 빈 파일 연결 후 query 실패를 db_error로 처리하는 경계를 확인한다.
    • 테스트 근거: tests/test_issue_12_review59_readonly.py, tests/test_dashboard_app.py, tests/test_dashboard_menu_transition.py
    • 판정 근거: 이전 C13의 조회마다 init 및 migration writes를 실행하던 결함은 해소됐다. delegate의 빈 DB schema 오류가 db_not_initialized로 반환된다는 주장은 직접 source 대조상 채택하지 않았다. 전체 제품 테스트를 독립 실행한 것은 아니다.
  • C14-auth-menu-preservation — satisfied

    • 계약: Dashboard 인증은 DB보다 먼저이며 REQ-001의 cookie와 logout 및 REQ-002의 메뉴 label과 order, shell, query, error와 retry 및 명시적 금융 쓰기 계약을 유지한다.
    • 구현 근거: dashboard/app.py, dashboard/page_views/accounts.py, dashboard/page_views/assets.py, dashboard/page_views/monthly_settlement.py, docs/interface-contract.md, docs/project-structure.md, docs/runtime-flow.md; Dashboard app의 gate가 DB 접근보다 앞서며 세 pages와 menu shell의 기존 동작을 보존한다. REQ-001 및 REQ-002는 변경되지 않았고 기존 공통 문서 내용은 유지된다. Dashboard read-only 경계 tests와 기존 auth 및 menu tests를 정적으로 확인했다.
    • 테스트 근거: tests/test_dashboard_menu_transition.py, tests/test_dashboard_app.py
    • 판정 근거: 기존 cookie 및 logout, menu label과 order 및 명시적 write 경계의 계약 삭제는 확인되지 않았다. 구현자 pytest 성공 보고를 reviewer browser 또는 CI 성공으로 표현하지 않는다.
  • C15-exclusions-privacy — satisfied

    • 계약: 증권사 자동 연동, 정확한 성과 또는 환율 엔진, 새 인증, 별도 월정산 제품, 거래 추론 및 기존 데이터 자동 재작성과 수기 비계좌 자산 전체 이력 재설계를 추가하지 않는다. 실제 계좌 및 금융 증빙과 credential을 로그와 문서 및 테스트에 기록하지 않는다.
    • 구현 근거: jarca_ledger_mcp/application/assets_service.py, jarca_ledger_mcp/application/account_valuation_service.py, jarca_ledger_mcp/application/imports_service.py, jarca_ledger_mcp/application/reconciliation_service.py, jarca_ledger_mcp/infrastructure/sqlite/schema.py, jarca_ledger_mcp/infrastructure/sqlite/migrations.py; 전체 48개 changed files 및 154개 hunk에서 신규 외부 가격 및 환율 엔진이나 별도 auth 및 제품을 확인하지 않았다. non-KRW 금액은 비합산하고 synthetic fixtures 및 recursive allowlist redaction tests를 확인했다.
    • 테스트 근거: tests/test_issue_12_review59_reports.py, tests/test_issue_12_regressions.py, scripts/ci_fixture_db.py
    • 판정 근거: 설명되지 않는 제외 범위 구현은 확인되지 않았다. 실제 금융 DB 및 계좌 자료에 접근하지 않았고 source와 fixture 범위의 privacy만 판정했다.
  • D01-requirement-structure — satisfied

    • 계약: 신규 REQ-003을 배정 경로와 제목으로 작성하며 trusted harness README와 TEMPLATE의 JSON metadata, 연속 요구사항 및 AC, 필수 섹션, 판정 기준과 검증 및 검증 분류의 수준과 백엔드와 케이스 및 상태 불변조건을 충족한다. 초기 PR은 미정이며 PR 생성 후 실제 번호를 추적한다.
    • 구현 근거: docs/requirements/req-003_account-valuation-history.md; REQ-003 1-16, 187-297, 311-317은 trusted metadata 및 필수 섹션과 10개 AC별 검증 분류, 수준, 백엔드, 케이스와 상태 불변조건 및 Issue와 실제 PR 추적성을 포함한다. trusted README 및 TEMPLATE와 직접 대조했다.
    • 테스트 근거: tests/test_requirement_docs.py
    • 판정 근거: 이전 D01의 전체 AC 검증 분류 및 level과 backend 누락은 해소됐다. 실제 PR 번호와 lifecycle approved는 허용된 작성 단계 정보다.
  • D02-requirement-semantics — satisfied

    • 계약: 요구사항에는 평가 근거와 지표 정의, 선택과 future 제외, 정정 및 idempotency 충돌, 대사 완전성, current 및 import 연계, 마감 상태와 불변성과 승인, shared adapter 및 인증, migration과 legacy를 소스 및 테스트에 대응한다. 모든 승인된 경계와 회귀 사례를 인수 기준으로 내린다.
    • 구현 근거: docs/requirements/req-003_account-valuation-history.md; REQ-003 41-49, 74-91, 101-139 및 187-297은 principal 매핑, correction scope 및 사유, current/import, no-write, preview drift, 대사 completeness와 conditional 상태를 AC 및 source와 test에 대응한다.
    • 테스트 근거: tests/test_account_valuations.py, tests/test_asset_snapshots.py, tests/test_issue_12_regressions.py, tests/test_requirement_docs.py
    • 판정 근거: 이전 D02의 승인된 boundary 및 무변경 인수 의미 누락은 문서상 보완됐다. dated manual evidence를 확인으로 처리하는 explicit 제출 의미는 기존 수기 경로 범위의 구현 상세이며 확인 필드를 새 의무로 만들지 않았다. 문서의 필수 loan 정의와 current 및 replay 의미를 구현이 위반하는 부분은 해당 구현 criterion에 남겼다.
  • D03-data-model — unsatisfied

    • 계약: 신규 데이터 모델은 기존 entities 및 valuation과 마감의 관계, FK와 날짜 및 정확한 금액과 NULL 및 0과 선택 지표 및 대출 필수 정의, 계좌와 통화 및 목적과 기준일의 선택 및 index와 단일 유효 정정본, 고정 적용 분류 및 출처와 상태와 누락 및 이월 및 승인 버전, 분리된 정정과 schema11 이관 및 미상 날짜와 legacy 및 최신 캐시 동기화 책임을 정의한다.
    • 구현 근거: docs/data-model.md; data-model.md 12-30, 118-141은 current display 및 import candidate와 external comparison을 설명하지만 최신 cache의 source basis date와 sync timestamp 권위 및 갱신 책임 주체와 no-rollback 조건을 정의하지 않는다. 이 내용은 runtime-flow.md 231-237에만 부분적으로 있다.
    • 테스트 근거: tests/test_account_valuations.py, tests/test_asset_snapshots.py, tests/test_issue_12_regressions.py
    • 판정 근거: 다른 문서의 존재나 문구 반복 여부가 아니라 Discovery의 데이터 모델 산출물에 명시적으로 배정된 최신 캐시 동기화 책임이 닫히지 않은 잔여 누락이다. actual evidence date, last_balance와 last_synced_at의 권위, 늦은 과거 자료의 rollback 금지 및 책임 owner를 이 데이터 모델에 정의하거나 canonical 책임으로 명시 연결해야 한다. C05 구현 결함과 문서 책임을 함께 맞춰야 한다.
  • D04-interface-contract — unsatisfied

    • 계약: 인터페이스 문서는 기존 auth 및 메뉴를 보존하고 평가 등록 및 조회 및 정정의 모든 입력과 유효본 및 원금 정의 출력, report 및 preview/close 및 월정산과 대사와 current API의 공통 선택, exact 기본과 실제 날짜 및 age 및 이월과 누락 및 미확인과 출처 및 버전과 승인 출력을 정의한다. 잘못된 입력과 scope 및 충돌과 부족 근거는 무변경 실패이며 기존 envelope와 required keys 및 의미 변경 정책을 명시한다.
    • 구현 근거: docs/interface-contract.md; interface-contract.md 279-290은 currency와 kind 및 source와 status의 허용값을 actual enums in source로, optional metrics 및 loan definition을 source validation으로, valuation 출력을 persisted rows로 위임한다. 393-405의 실제 signature와 close provenance block은 추가됐지만 허용 enum과 loan 원금 지표의 출력 mapping 및 조건부 필수성을 interface contract로 정의하지 않는다. data-model.md 34, 57-60에는 일부 field 의미가 존재한다.
    • 테스트 근거: tests/test_account_valuations.py, tests/test_issue_12_regressions.py, tests/test_contract_regression.py
    • 판정 근거: 이전 D04 중 signatures, scope 및 close/read provenance와 무변경 실패는 보완됐다. 그러나 승인된 API 입력과 대출 대표 정의 및 원금 출력 계약 일부가 여전히 source lookup에 의존한다. 기존 물리 필드명을 바꾸도록 요구하지 않고 실제 허용값, 조건부 필수 정의와 valuation의 원금 및 구성금액 출력을 고정하거나 명시적 정본 field 계약 참조로 연결해야 한다.
  • D05-project-structure — satisfied

    • 계약: 프로젝트 구조 문서는 기존 source와 test 및 evidence를 보존하고 SQLite schema와 migrations, application의 assets와 account writes 및 import와 reconciliation 및 monthly 책임, 공개 facade와 MCP 및 Streamlit과 기존 세 화면 및 tests를 exact 경로로 대응한다. adapter에서 선택 정책을 복제하지 않고 대출 정의와 verified as_of 및 conditional 승인 경계를 shared application에 배치한다.
    • 구현 근거: docs/project-structure.md; project-structure.md 122-184, 198-212는 schema 및 migrations와 assets, accounts_write, import, reconciliation, monthly, facade와 adapters 및 shared policy owner와 tests를 exact paths로 대응한다.
    • 테스트 근거: tests/test_requirement_docs.py
    • 판정 근거: 이전 D05의 누락된 module ownership 및 정책별 shared 책임과 tests 대응은 해소됐다.
  • D06-runtime-flow — satisfied

    • 계약: 런타임 문서는 auth 및 메뉴를 보존하고 register/correct의 증빙 및 scope 검증과 append 및 유효본 확인 및 최신 캐시 동기화를 단일 트랜잭션으로 설명한다. 날짜 및 정책과 통화 및 대표 합산과 경고 read, preview 후 명시적 approval 및 원자적 freeze, reasoned reclose, 같은 근거의 monthly 및 대사, import와 이관 trigger 및 실패복구, retry와 concurrency 및 preview drift 재검증과 무부분쓰기, 비민감 valuation/run 상관 신호를 정의한다.
    • 구현 근거: docs/runtime-flow.md; runtime-flow.md 221-241은 current-cache no rollback, reconciliation incomplete, preview fingerprint와 authority drift 재검증 및 atomic close와 no partial write를 명시한다. 기존 auth 및 메뉴 흐름을 보존한다.
    • 테스트 근거: tests/test_account_valuations.py, tests/test_asset_snapshots.py, tests/test_issue_12_regressions.py
    • 판정 근거: 이전 D06의 explicit scope, authority sync 및 drift와 불가 상태 및 conditional boundary 누락은 문서상 해소됐다. 실제 import 시각 혼용은 C05에서 변경 요청한다.
  • C16-supporting-evidence-scope — satisfied

    • 계약: 모든 changed file은 승인된 기능과 필수 supporting change 또는 테스트 evidence로 설명되고 기존 requirement ID를 임의 갱신하거나 범위 밖 제품 및 설정을 변경하지 않는다.
    • 구현 근거: dashboard/app.py, dashboard/page_views/accounts.py, dashboard/page_views/assets.py, dashboard/page_views/monthly_settlement.py, docs/data-model.md, docs/interface-contract.md, docs/project-structure.md, docs/requirements/req-003_account-valuation-history.md, docs/runtime-flow.md, jarca_ledger_mcp/adapters/mcp/server.py, jarca_ledger_mcp/adapters/mcp/tool_contracts.py, jarca_ledger_mcp/adapters/streamlit/accounts_gateway.py, jarca_ledger_mcp/adapters/streamlit/overview_gateway.py, jarca_ledger_mcp/application/__init_.py, jarca_ledger_mcp/application/account_valuation_service.py, jarca_ledger_mcp/application/accounts_write_services.py, jarca_ledger_mcp/application/assets_service.py, jarca_ledger_mcp/application/categorization_services.py, jarca_ledger_mcp/application/cross_transfer_service.py, jarca_ledger_mcp/application/imports_service.py, jarca_ledger_mcp/application/monthly_settlement_service.py, jarca_ledger_mcp/application/reconciliation_service.py, jarca_ledger_mcp/application/review_decision_service.py, jarca_ledger_mcp/application/shared.py, jarca_ledger_mcp/application/system_services.py, jarca_ledger_mcp/application/transaction_report_services.py, jarca_ledger_mcp/application/uncategorized_workbench_service.py, jarca_ledger_mcp/infrastructure/sqlite/__init_.py, jarca_ledger_mcp/infrastructure/sqlite/connection.py, jarca_ledger_mcp/infrastructure/sqlite/migrations.py, jarca_ledger_mcp/infrastructure/sqlite/schema.py, jarca_ledger_mcp/service.py, scripts/ci_fixture_db.py, tests/test_account_valuations.py, tests/test_asset_snapshots.py, tests/test_contract_regression.py, tests/test_dashboard_app.py, tests/test_dashboard_menu_transition.py, tests/test_import_provenance_policy.py, tests/test_issue_12_regressions.py, tests/test_issue_12_review59_account.py, tests/test_issue_12_review59_readonly.py, tests/test_issue_12_review59_reports.py, tests/test_ledger_categories.py, tests/test_requirement_docs.py, tests/test_review_decision_workbench.py, tests/test_seoulpay_xlsx.py, tests/test_service.py; 전체 48개 changed files는 valuation 및 SQLite, current/import, read-only wrappers 및 downstream query propagation, Dashboard와 adapters, 5종 문서 및 focused regression tests와 synthetic CI seed로 설명된다. 154개 hunk를 immutable base와 head blobs에 대조했다. PR은 exact head에서 pytest 233 passed와 4 skipped 및 ruff exit 0을 보고하지만 조회 status는 0개 및 pending이다.
    • 테스트 근거: tests/test_account_valuations.py, tests/test_asset_snapshots.py, tests/test_contract_regression.py, tests/test_dashboard_app.py, tests/test_dashboard_menu_transition.py, tests/test_import_provenance_policy.py, tests/test_issue_12_regressions.py, tests/test_issue_12_review59_account.py, tests/test_issue_12_review59_readonly.py, tests/test_issue_12_review59_reports.py, tests/test_ledger_categories.py, tests/test_requirement_docs.py, tests/test_review_decision_workbench.py, tests/test_seoulpay_xlsx.py, tests/test_service.py
    • 판정 근거: 범위 초과는 없다. 구현자 보고와 정적 검토를 구분했다. Reviewer는 변경 Python files 43개 compile-only 및 synthetic stdlib AST 추출 관찰만 수행했고 제품 pytest와 browser 및 CI 성공을 주장하지 않는다.

범위 판정

  • 누락: 대출 balance 평가의 대표 정의 필수 검증, 실제 근거일과 동기화시각을 분리한 current import 권위, 동일 증빙 정정 재시도 재사용, 이전 마감 key replay의 원래 run 및 evidence 결합, 데이터 모델의 최신 cache 동기화 책임, 인터페이스의 허용값과 원금 및 대표 정의 입력 및 출력 계약
  • 범위 초과: 없음
  • 명세 모순: 없음

결론

기존 정정 scope 및 no-write, 일반 source_ref 재입력, 대사 completeness, conditional 및 downstream provenance, 요구사항 검증 분류와 구조 및 흐름 보완을 확인했다. 그러나 loan balance 정의 누락, current import의 시각 혼용, 동일 증빙 정정 재시도, 재마감 뒤 이전 key replay의 run 혼합 및 데이터 모델과 인터페이스 잔여 의무 때문에 request_changes다. 구현자 PR 본문의 exact head pytest 233 passed 및 4 skipped와 ruff exit 0은 구현자 보고이며 reviewer 독립 제품 테스트 또는 CI 성공이 아니다. Reviewer는 immutable blobs와 154개 hunk 및 정적 source와 tests를 대조하고 변경 Python files 43개 compile-only와 supplemental synthetic AST 추출 관찰을 수행했다. Source와 Issue 및 branch를 변경하거나 merge하지 않았다.

## 구현 명세 적합성 검토 - Source Issue: #12 - Pull Request: #13 - Reviewed head: `6a8a27a74ece9a9cce6f9772259677813d91ddf8` - Contract SHA-256: `6d86b591b022fcc722611bfec6d24e54a64216ab6f7c4098f357e25420218818` - Verdict: `request_changes` ### Acceptance criteria 판정 - `C01-history` — `satisfied` - 계약: 평가 계좌 FK, 기준일과 등록일, 대표 금액과 통화와 목적, 출처와 확인 상태, 증빙 식별자, 정정 연결과 사유 및 선택 시간 자료를 이력으로 보존한다. - 구현 근거: jarca_ledger_mcp/application/account_valuation_service.py, jarca_ledger_mcp/infrastructure/sqlite/schema.py, jarca_ledger_mcp/infrastructure/sqlite/migrations.py; schema.py 234-266 및 account_valuation_service.py 155-180, 235-245는 FK, 기준일, 등록일, 정정 연결 및 optional metrics를 저장한다. 날짜 자료와 optional 시간 자료를 구분한다. - 테스트 근거: tests/test_account_valuations.py - 판정 근거: 이력 구조 계약은 유지됐다. 부모 scope 및 대표 부채 정의 누락은 별도 항목에서 판정한다. - `C02-money-metrics` — `satisfied` - 계약: 금액 정밀도와 NULL 및 0을 보존하고 취득원가, 순납입액, 기관 표시 원금 금액과 정의 및 원문 명칭, 손익과 수익률의 계산 기준을 구분한다. 투자 대표 총평가액과 포함 현금 및 원금을 중복 합산하지 않는다. - 구현 근거: jarca_ledger_mcp/application/account_valuation_service.py, jarca_ledger_mcp/infrastructure/sqlite/schema.py, docs/data-model.md, docs/requirements/req-003_account-valuation-history.md; account_valuation_service.py 160-163, 180, 235-245 및 docs/data-model.md 34, 57-60은 integer, NULL 및 0을 보존하고 investment principal과 loan outstanding principal을 구분한다. test_valuation_round_trip_preserves_null_zero_and_physical_amount_mapping을 정적으로 확인했다. - 테스트 근거: tests/test_issue_12_review59_account.py, tests/test_issue_12_regressions.py - 판정 근거: 이전 C02의 지표 대응 및 round-trip 의미 누락은 해소됐다. 대표 정의 필수 검증의 balance 우회는 N01에서 별도로 판정한다. - `N01-loan-balance-definition` — `unsatisfied` - 계약: 대출 평가 기록마다 대표 부채가 원금만인지 원금과 이자 및 수수료인지 필수로 명시하고 기본값으로 추정하지 않는다. 목적 alias가 필수 정의 계약을 우회하지 않는다. - 구현 근거: jarca_ledger_mcp/application/account_valuation_service.py, docs/requirements/req-003_account-valuation-history.md; account_valuation_service.py 84-87은 loan 및 loan_balance에만 정의를 필수로 하고 balance에는 누락을 허용한다. 183-191도 account.type이 loan이고 kind가 balance인 경우 정의 누락을 차단하지 않는다. REQ-003 91과 data-model 60은 loan 필수 정의를 명시한다. test_loan_balance_fallback_with_representative_definition_is_liability는 정의가 있는 balance만 확인한다. - 테스트 근거: tests/test_issue_12_regressions.py, tests/test_issue_12_review59_account.py - 판정 근거: loan 계좌의 verified balance 평가를 대표 정의 없이 등록할 수 있다. balance에 정의를 제공하면 거부된다는 delegate 주장은 실제 86행과 다르므로 제외했다. 문제는 정의 없는 등록 허용이며 모든 허용 loan purpose에 같은 필수 계약을 적용해야 한다. supplemental 추출 함수 관찰과 무관하게 직접 validation 및 account checks가 누락을 증명한다. - `C03-selection` — `satisfied` - 계약: 계좌와 통화 및 평가 목적별 유효 자료를 선택한다. exact는 당일 확인 자료만, as_of는 기준일 이하 최신 확인 자료만 사용한다. 미래 자료는 제외하고 미확인 후보는 확인 자료를 대체하거나 합산하지 않는다. 실제 기준일과 경과 일수 및 이월 상태를 반환한다. - 구현 근거: jarca_ledger_mcp/application/account_valuation_service.py, jarca_ledger_mcp/application/assets_service.py; account_valuation_service.py 254-300 및 assets_service.py 148-211은 계좌별 purpose, verified leaf, exact 및 as_of, future 제외와 미확인 후보 분리를 유지한다. test_select_exact_and_as_of_excludes_unverified_and_reports_carry_forward 등 관련 named test의 source를 대조했다. - 테스트 근거: tests/test_account_valuations.py, tests/test_issue_12_regressions.py - 판정 근거: 확인 자료 선택과 후보 비합산은 정적으로 충족한다. loan 필수 정의의 등록 경계는 N01에서 별도로 판정한다. - `C04-correction-validation` — `satisfied` - 계약: 평가 정정은 append-only로 대상과 사유를 연결하며 다른 계좌, 통화, 목적을 참조하는 정정과 순환 및 동일 유효본의 동시 분기를 차단한다. - 구현 근거: jarca_ledger_mcp/application/account_valuation_service.py, jarca_ledger_mcp/infrastructure/sqlite/schema.py; account_valuation_service.py 176-177, 193-212, 238-241, 310-316은 부모 scope와 사유 및 ancestry와 단일 child를 검증한다. test_direct_correction_requires_matching_existing_parent_and_reason 및 test_correction_rejects_currency_and_kind_override_but_preserves_valid_overrides를 확인했다. - 테스트 근거: tests/test_issue_12_review59_account.py, tests/test_account_valuations.py, tests/test_issue_12_regressions.py - 판정 근거: 이전 C04의 다른 계좌 및 목적과 통화 및 사유 없는 정정 허용은 해소됐다. 동일 증빙 정정 replay는 C06의 잔여 결함이다. - `C05-current-import` — `unsatisfied` - 계약: 뒤늦은 과거 자료 등록으로 최신 표시값을 과거로 되돌리지 않는다. 기존 계좌 수정과 import의 최신 캐시 및 새 이력 권위를 연결하며 동기화 시각을 실제 평가일로 오인하지 않는다. - 구현 근거: jarca_ledger_mcp/application/imports_service.py, jarca_ledger_mcp/application/assets_service.py, jarca_ledger_mcp/application/accounts_write_services.py; imports_service.py 43-58은 source basis_date를 last_synced_at과 비교하면서 갱신 시에는 import 실행시각 synced_at을 last_synced_at에 저장한다. 같은 함수를 사용하는 세 import 경로는 242-244, 709-711, 934-936이다. assets_service.py 140-141은 이 동기화시각을 current valuation_date로 노출한다. - 테스트 근거: tests/test_issue_12_review59_account.py, tests/test_import_provenance_policy.py - 판정 근거: 과거 import의 단순 rollback 방지는 보완됐지만 실제 평가일과 동기화시각은 여전히 혼합된다. 예를 들어 2026-10-06에 2026-09-30 근거를 import한 뒤 2026-10-01 근거를 import하면 현재시각 2026-10-06이 비교 기준이 되어 실제로 더 최신인 2026-10-01 잔고 갱신을 차단한다. 실제 근거일로 비교하고 동기화시각을 기준일로 표시하지 않아야 한다. 기존 historical import tests는 이 연속 import 경계를 검사하지 않는다. - `C06-idempotency` — `unsatisfied` - 계약: 동일 증빙 또는 idempotency 재입력은 동일 기록을 재사용하며 같은 키의 다른 payload는 충돌이다. 동시 정정의 분기를 차단하고 UNIQUE 계좌 및 기준일 하나로 정정 추가를 막지 않는다. - 구현 근거: jarca_ledger_mcp/application/account_valuation_service.py, jarca_ledger_mcp/infrastructure/sqlite/schema.py, jarca_ledger_mcp/infrastructure/sqlite/migrations.py, jarca_ledger_mcp/application/accounts_write_services.py, jarca_ledger_mcp/application/imports_service.py; account_valuation_service.py 214-236은 일반 source_ref 중복을 보완했지만 correct_account_valuation의 317-326은 명시 key만 replay하고 기존 child가 있으면 동일 증빙 및 payload 비교 없이 correction_conflict로 종료한다. test_correction_preserves_source_ref_without_evidence_identity_conflict는 첫 정정만 확인한다. - 테스트 근거: tests/test_issue_12_review59_account.py, tests/test_account_valuations.py, tests/test_issue_12_regressions.py - 판정 근거: 일반 등록과 명시 key 재사용은 해소됐으나 source_ref가 같은 부모를 동일 amount와 사유로 key 없이 정정 재시도하면 기존 정정본을 재사용하지 않는다. 이는 동일 증빙 재입력 재사용 계약의 잔여 위반이다. 동일 증빙과 부모 및 payload의 재사용과 실제 다른 payload 충돌을 구분해야 한다. supplemental AST probe도 같은 결과를 관찰했으나 판정은 이 직접 source 및 계약 대조에 근거한다. - `C07-close-immutability` — `satisfied` - 계약: 기존 asset_snapshots와 correction run을 보존하고 평가 정정 및 거래 추가로 기존 마감을 자동 변경하지 않는다. 동일 기준일 재마감은 사유와 이전 run 연결을 가진 새 버전을 원자적으로 추가한다. - 구현 근거: jarca_ledger_mcp/application/assets_service.py, jarca_ledger_mcp/infrastructure/sqlite/schema.py, jarca_ledger_mcp/infrastructure/sqlite/migrations.py; assets_service.py 670-780은 기존 run을 변경하지 않고 correction_reason 및 이전 run을 연결해 새 run과 rows를 원자적으로 추가한다. 기존 snapshot 및 동시 first-close tests와 immutable close tests를 정적으로 대조했다. - 테스트 근거: tests/test_asset_snapshots.py, tests/test_issue_12_regressions.py - 판정 근거: 저장된 기존 run의 불변성과 append-only 재마감은 충족한다. 이전 key의 replay 응답에 다른 run evidence가 섞이는 N02는 별도 변경 요청이다. - `N02-close-replay-run-binding` — `unsatisfied` - 계약: 마감 버전의 근거는 불변이며 동일 idempotency 요청은 원래 기록을 재사용한다. 재마감으로 과거 run 응답 및 evidence를 변경하지 않는다. - 구현 근거: jarca_ledger_mcp/application/assets_service.py, docs/interface-contract.md; assets_service.py 629-643은 existing key의 run을 찾은 뒤 632행에서 basis date의 latest run rows와 metadata를 읽고 643행에서는 기존 run ID를 응답한다. 644-650의 correction 및 inserted rows도 최신 run에 결합된다. interface-contract.md 마지막 replay 계약은 원래 persisted run과 evidence로 응답을 재구성하도록 정의한다. - 테스트 근거: tests/test_issue_12_review59_reports.py, tests/test_issue_12_regressions.py - 판정 근거: 최초 close key A, 명시적 correction key B, key A 재시도 순서에서 run ID는 A인데 correction과 snapshot IDs 및 evidence는 B로 섞인다. 실제 source가 서로 다른 조회 authority를 결합한다. 기존 immutable replay named test는 재마감 이후 key A 재시도를 확인하지 않는다. 기존 run ID로 rows와 metadata 및 응답 전부를 재구성하고 이 경계의 회귀를 보완해야 한다. - `C08-approved-conditional` — `satisfied` - 계약: 완전한 exact 마감, 미완료 초안, 별도 승인된 조건부 마감을 구분한다. 승인 전 누락 및 이월은 미완료 초안이고 승인 후에도 누락 제외 및 확인된 과거값 이월만 허용한다. 미확인, 미래, 기준일 미상 금액은 승인으로도 합산하지 않으며 적용과 제외와 이월 및 승인자와 시각과 사유와 근거를 고정한다. - 구현 근거: jarca_ledger_mcp/application/assets_service.py, jarca_ledger_mcp/infrastructure/sqlite/schema.py, dashboard/page_views/assets.py; assets_service.py 232-258, 581-589, 618-627, 730-779는 명시적으로 입력된 dated manual evidence, 누락 및 future/unknown 제외, 미승인 incomplete_draft와 승인 flags 및 metadata, carried evidence 저장을 처리한다. test_dated_manual_asset_is_verified_and_preview_needs_approval 및 test_approved_carried_close_is_conditional_and_persists_provenance를 확인했다. - 테스트 근거: tests/test_issue_12_review59_reports.py, tests/test_issue_12_regressions.py, tests/test_asset_snapshots.py - 판정 근거: 이전 C08의 stored unverified 이월과 미승인 conditional 기대값은 보완됐다. 기존 수기 제출 자료를 확인된 manual evidence로 처리하는 계약이 source와 문서 및 tests에 일치한다. 별도 확인 상태 필드나 수기 전체 이력 재설계를 새 의무로 강제하지 않는다. - `C09-reconciliation` — `satisfied` - 계약: 외부 확인값과 장부 계산값을 분리하고 검증된 시작잔고, 기준시점, 거래 포함 범위와 계산 완전성을 표시한다. 거래 없는 수동 투자 계좌의 대사 불가 및 거래 미수입과 평가 수동 관리 상태를 구분하고 가짜 거래를 만들지 않는다. 대사도 공통 평가 근거와 대출 대표 정의를 사용한다. - 구현 근거: jarca_ledger_mcp/application/reconciliation_service.py, jarca_ledger_mcp/application/account_valuation_service.py, jarca_ledger_mcp/application/monthly_settlement_service.py; reconciliation_service.py 31-63, 101-177, 192-206은 opening evidence 및 거래 포함 범위와 completeness를 구분하며 INCOMPLETE_CALCULATION, VALUATION_MANAGED, unavailable와 loan purpose를 전파한다. test_reconciliation_does_not_mark_last_balance_without_opening_evidence_complete 및 test_reconciliation_uses_currency_and_loan_priority_and_canonical_provenance를 확인했다. - 테스트 근거: tests/test_issue_12_review59_reports.py, tests/test_issue_12_regressions.py, tests/test_service.py - 판정 근거: 이전 C09의 시작잔고 없는 계산 확정 및 대출 purpose 무시와 투자 불가 상태 누락은 정적 source 및 named tests 대조상 해소됐다. - `C10-report-monthly-evidence` — `satisfied` - 계약: MCP와 Dashboard 및 월정산 보고에서 같은 기준일과 선택 근거 및 실제 평가일, 경과 일수, 확인 상태, 누락과 미확인 및 이월 경고, 마감 버전 및 조건부 승인 근거를 일관되게 전달한다. - 구현 근거: jarca_ledger_mcp/application/assets_service.py, jarca_ledger_mcp/application/monthly_settlement_service.py, dashboard/page_views/monthly_settlement.py, dashboard/page_views/accounts.py; assets_service.py 554-592, 817-852 및 monthly_settlement_service.py는 실제 평가일과 age 및 carry, 상태와 warnings 및 applied/excluded evidence를 immutable run에서 재구성한다. test_approved_carry_provenance_is_identical_across_closed_downstream_reports와 test_monthly_settlement_propagates_snapshot_provenance_id_and_actual_valuation_date를 확인했다. - 테스트 근거: tests/test_issue_12_review59_reports.py, tests/test_issue_12_regressions.py, tests/test_service.py - 판정 근거: 이전 C10의 일반 report 및 월정산 날짜와 경고 및 provenance 누락은 해소됐다. idempotency replay의 다른 run 혼합은 N02에서 별도로 판정한다. - `C11-adapter-structure` — `satisfied` - 계약: MCP와 Streamlit gateway는 공통 application을 사용하고 기존 공개 호출명과 기존 인수 및 success와 실패 error_code 및 error envelope를 가능한 한 유지한다. 새 Dashboard 인증 또는 MCP 인증을 도입하지 않는다. - 구현 근거: jarca_ledger_mcp/adapters/mcp/server.py, jarca_ledger_mcp/adapters/mcp/tool_contracts.py, jarca_ledger_mcp/adapters/streamlit/accounts_gateway.py, jarca_ledger_mcp/application/__init__.py, jarca_ledger_mcp/service.py, dashboard/page_views/accounts.py, dashboard/page_views/assets.py, dashboard/page_views/monthly_settlement.py; MCP server 및 tool_contracts, accounts 및 overview gateways, service exports와 세 Dashboard pages의 호출은 shared application으로 연결된다. test_snapshot_public_api_preserves_legacy_db_path_position 및 계약 snapshot의 additive keys를 확인했다. - 테스트 근거: tests/test_contract_regression.py, tests/test_issue_12_regressions.py - 판정 근거: 기존 호출명과 db_path 인수 및 envelope와 shared service 구조를 보존했다. 공통 service의 잔여 결함은 adapter 연결의 충족으로 상쇄하지 않는다. - `C12-migration-legacy` — `satisfied` - 계약: schema 11의 기존 데이터와 마감 및 개인정보를 보존하고 additive하고 idempotent한 migration을 제공한다. 기준일 증거 없는 값을 임의 월말로 소급하거나 legacy snapshot에 valuation_id를 추측하여 생성하지 않는다. - 구현 근거: jarca_ledger_mcp/infrastructure/sqlite/schema.py, jarca_ledger_mcp/infrastructure/sqlite/migrations.py, jarca_ledger_mcp/application/assets_service.py; schema.py와 migrations.py는 additive schema 12, optional columns, 단일 child 및 non-empty key index를 보존한다. 기존 records를 임의 날짜로 이관하지 않고 legacy report와 explicit correction을 구분한다. 관련 schema 및 legacy tests를 확인했다. - 테스트 근거: tests/test_account_valuations.py, tests/test_issue_12_regressions.py, tests/test_ledger_categories.py, tests/test_review_decision_workbench.py - 판정 근거: 이전 migration 및 legacy 계약은 유지됐다. source_ref나 valuation_id의 임의 자동 추정 및 기존 마감 삭제는 확인되지 않았다. - `C13-read-only` — `satisfied` - 계약: preview와 조회 및 Dashboard 렌더링은 금융 쓰기를 실행하지 않는다. 명시적 등록, 정정, 승인 close 및 import 제출만 변경을 수행하고 실패 시 부분 쓰기를 남기지 않는다. - 구현 근거: jarca_ledger_mcp/infrastructure/sqlite/connection.py, jarca_ledger_mcp/application/shared.py, jarca_ledger_mcp/application/system_services.py, jarca_ledger_mcp/application/account_valuation_service.py, jarca_ledger_mcp/application/assets_service.py; connection.py 31-53의 connect_readonly 및 read_db는 기존 파일에 mode=ro로 연결하고 초기화 및 commit을 수행하지 않는다. shared.py의 read_operation과 조회 services는 read_db를 사용한다. test_read_schema_error_is_not_misreported_as_uninitialized는 빈 파일 연결 후 query 실패를 db_error로 처리하는 경계를 확인한다. - 테스트 근거: tests/test_issue_12_review59_readonly.py, tests/test_dashboard_app.py, tests/test_dashboard_menu_transition.py - 판정 근거: 이전 C13의 조회마다 init 및 migration writes를 실행하던 결함은 해소됐다. delegate의 빈 DB schema 오류가 db_not_initialized로 반환된다는 주장은 직접 source 대조상 채택하지 않았다. 전체 제품 테스트를 독립 실행한 것은 아니다. - `C14-auth-menu-preservation` — `satisfied` - 계약: Dashboard 인증은 DB보다 먼저이며 REQ-001의 cookie와 logout 및 REQ-002의 메뉴 label과 order, shell, query, error와 retry 및 명시적 금융 쓰기 계약을 유지한다. - 구현 근거: dashboard/app.py, dashboard/page_views/accounts.py, dashboard/page_views/assets.py, dashboard/page_views/monthly_settlement.py, docs/interface-contract.md, docs/project-structure.md, docs/runtime-flow.md; Dashboard app의 gate가 DB 접근보다 앞서며 세 pages와 menu shell의 기존 동작을 보존한다. REQ-001 및 REQ-002는 변경되지 않았고 기존 공통 문서 내용은 유지된다. Dashboard read-only 경계 tests와 기존 auth 및 menu tests를 정적으로 확인했다. - 테스트 근거: tests/test_dashboard_menu_transition.py, tests/test_dashboard_app.py - 판정 근거: 기존 cookie 및 logout, menu label과 order 및 명시적 write 경계의 계약 삭제는 확인되지 않았다. 구현자 pytest 성공 보고를 reviewer browser 또는 CI 성공으로 표현하지 않는다. - `C15-exclusions-privacy` — `satisfied` - 계약: 증권사 자동 연동, 정확한 성과 또는 환율 엔진, 새 인증, 별도 월정산 제품, 거래 추론 및 기존 데이터 자동 재작성과 수기 비계좌 자산 전체 이력 재설계를 추가하지 않는다. 실제 계좌 및 금융 증빙과 credential을 로그와 문서 및 테스트에 기록하지 않는다. - 구현 근거: jarca_ledger_mcp/application/assets_service.py, jarca_ledger_mcp/application/account_valuation_service.py, jarca_ledger_mcp/application/imports_service.py, jarca_ledger_mcp/application/reconciliation_service.py, jarca_ledger_mcp/infrastructure/sqlite/schema.py, jarca_ledger_mcp/infrastructure/sqlite/migrations.py; 전체 48개 changed files 및 154개 hunk에서 신규 외부 가격 및 환율 엔진이나 별도 auth 및 제품을 확인하지 않았다. non-KRW 금액은 비합산하고 synthetic fixtures 및 recursive allowlist redaction tests를 확인했다. - 테스트 근거: tests/test_issue_12_review59_reports.py, tests/test_issue_12_regressions.py, scripts/ci_fixture_db.py - 판정 근거: 설명되지 않는 제외 범위 구현은 확인되지 않았다. 실제 금융 DB 및 계좌 자료에 접근하지 않았고 source와 fixture 범위의 privacy만 판정했다. - `D01-requirement-structure` — `satisfied` - 계약: 신규 REQ-003을 배정 경로와 제목으로 작성하며 trusted harness README와 TEMPLATE의 JSON metadata, 연속 요구사항 및 AC, 필수 섹션, 판정 기준과 검증 및 검증 분류의 수준과 백엔드와 케이스 및 상태 불변조건을 충족한다. 초기 PR은 미정이며 PR 생성 후 실제 번호를 추적한다. - 구현 근거: docs/requirements/req-003_account-valuation-history.md; REQ-003 1-16, 187-297, 311-317은 trusted metadata 및 필수 섹션과 10개 AC별 검증 분류, 수준, 백엔드, 케이스와 상태 불변조건 및 Issue와 실제 PR 추적성을 포함한다. trusted README 및 TEMPLATE와 직접 대조했다. - 테스트 근거: tests/test_requirement_docs.py - 판정 근거: 이전 D01의 전체 AC 검증 분류 및 level과 backend 누락은 해소됐다. 실제 PR 번호와 lifecycle approved는 허용된 작성 단계 정보다. - `D02-requirement-semantics` — `satisfied` - 계약: 요구사항에는 평가 근거와 지표 정의, 선택과 future 제외, 정정 및 idempotency 충돌, 대사 완전성, current 및 import 연계, 마감 상태와 불변성과 승인, shared adapter 및 인증, migration과 legacy를 소스 및 테스트에 대응한다. 모든 승인된 경계와 회귀 사례를 인수 기준으로 내린다. - 구현 근거: docs/requirements/req-003_account-valuation-history.md; REQ-003 41-49, 74-91, 101-139 및 187-297은 principal 매핑, correction scope 및 사유, current/import, no-write, preview drift, 대사 completeness와 conditional 상태를 AC 및 source와 test에 대응한다. - 테스트 근거: tests/test_account_valuations.py, tests/test_asset_snapshots.py, tests/test_issue_12_regressions.py, tests/test_requirement_docs.py - 판정 근거: 이전 D02의 승인된 boundary 및 무변경 인수 의미 누락은 문서상 보완됐다. dated manual evidence를 확인으로 처리하는 explicit 제출 의미는 기존 수기 경로 범위의 구현 상세이며 확인 필드를 새 의무로 만들지 않았다. 문서의 필수 loan 정의와 current 및 replay 의미를 구현이 위반하는 부분은 해당 구현 criterion에 남겼다. - `D03-data-model` — `unsatisfied` - 계약: 신규 데이터 모델은 기존 entities 및 valuation과 마감의 관계, FK와 날짜 및 정확한 금액과 NULL 및 0과 선택 지표 및 대출 필수 정의, 계좌와 통화 및 목적과 기준일의 선택 및 index와 단일 유효 정정본, 고정 적용 분류 및 출처와 상태와 누락 및 이월 및 승인 버전, 분리된 정정과 schema11 이관 및 미상 날짜와 legacy 및 최신 캐시 동기화 책임을 정의한다. - 구현 근거: docs/data-model.md; data-model.md 12-30, 118-141은 current display 및 import candidate와 external comparison을 설명하지만 최신 cache의 source basis date와 sync timestamp 권위 및 갱신 책임 주체와 no-rollback 조건을 정의하지 않는다. 이 내용은 runtime-flow.md 231-237에만 부분적으로 있다. - 테스트 근거: tests/test_account_valuations.py, tests/test_asset_snapshots.py, tests/test_issue_12_regressions.py - 판정 근거: 다른 문서의 존재나 문구 반복 여부가 아니라 Discovery의 데이터 모델 산출물에 명시적으로 배정된 최신 캐시 동기화 책임이 닫히지 않은 잔여 누락이다. actual evidence date, last_balance와 last_synced_at의 권위, 늦은 과거 자료의 rollback 금지 및 책임 owner를 이 데이터 모델에 정의하거나 canonical 책임으로 명시 연결해야 한다. C05 구현 결함과 문서 책임을 함께 맞춰야 한다. - `D04-interface-contract` — `unsatisfied` - 계약: 인터페이스 문서는 기존 auth 및 메뉴를 보존하고 평가 등록 및 조회 및 정정의 모든 입력과 유효본 및 원금 정의 출력, report 및 preview/close 및 월정산과 대사와 current API의 공통 선택, exact 기본과 실제 날짜 및 age 및 이월과 누락 및 미확인과 출처 및 버전과 승인 출력을 정의한다. 잘못된 입력과 scope 및 충돌과 부족 근거는 무변경 실패이며 기존 envelope와 required keys 및 의미 변경 정책을 명시한다. - 구현 근거: docs/interface-contract.md; interface-contract.md 279-290은 currency와 kind 및 source와 status의 허용값을 actual enums in source로, optional metrics 및 loan definition을 source validation으로, valuation 출력을 persisted rows로 위임한다. 393-405의 실제 signature와 close provenance block은 추가됐지만 허용 enum과 loan 원금 지표의 출력 mapping 및 조건부 필수성을 interface contract로 정의하지 않는다. data-model.md 34, 57-60에는 일부 field 의미가 존재한다. - 테스트 근거: tests/test_account_valuations.py, tests/test_issue_12_regressions.py, tests/test_contract_regression.py - 판정 근거: 이전 D04 중 signatures, scope 및 close/read provenance와 무변경 실패는 보완됐다. 그러나 승인된 API 입력과 대출 대표 정의 및 원금 출력 계약 일부가 여전히 source lookup에 의존한다. 기존 물리 필드명을 바꾸도록 요구하지 않고 실제 허용값, 조건부 필수 정의와 valuation의 원금 및 구성금액 출력을 고정하거나 명시적 정본 field 계약 참조로 연결해야 한다. - `D05-project-structure` — `satisfied` - 계약: 프로젝트 구조 문서는 기존 source와 test 및 evidence를 보존하고 SQLite schema와 migrations, application의 assets와 account writes 및 import와 reconciliation 및 monthly 책임, 공개 facade와 MCP 및 Streamlit과 기존 세 화면 및 tests를 exact 경로로 대응한다. adapter에서 선택 정책을 복제하지 않고 대출 정의와 verified as_of 및 conditional 승인 경계를 shared application에 배치한다. - 구현 근거: docs/project-structure.md; project-structure.md 122-184, 198-212는 schema 및 migrations와 assets, accounts_write, import, reconciliation, monthly, facade와 adapters 및 shared policy owner와 tests를 exact paths로 대응한다. - 테스트 근거: tests/test_requirement_docs.py - 판정 근거: 이전 D05의 누락된 module ownership 및 정책별 shared 책임과 tests 대응은 해소됐다. - `D06-runtime-flow` — `satisfied` - 계약: 런타임 문서는 auth 및 메뉴를 보존하고 register/correct의 증빙 및 scope 검증과 append 및 유효본 확인 및 최신 캐시 동기화를 단일 트랜잭션으로 설명한다. 날짜 및 정책과 통화 및 대표 합산과 경고 read, preview 후 명시적 approval 및 원자적 freeze, reasoned reclose, 같은 근거의 monthly 및 대사, import와 이관 trigger 및 실패복구, retry와 concurrency 및 preview drift 재검증과 무부분쓰기, 비민감 valuation/run 상관 신호를 정의한다. - 구현 근거: docs/runtime-flow.md; runtime-flow.md 221-241은 current-cache no rollback, reconciliation incomplete, preview fingerprint와 authority drift 재검증 및 atomic close와 no partial write를 명시한다. 기존 auth 및 메뉴 흐름을 보존한다. - 테스트 근거: tests/test_account_valuations.py, tests/test_asset_snapshots.py, tests/test_issue_12_regressions.py - 판정 근거: 이전 D06의 explicit scope, authority sync 및 drift와 불가 상태 및 conditional boundary 누락은 문서상 해소됐다. 실제 import 시각 혼용은 C05에서 변경 요청한다. - `C16-supporting-evidence-scope` — `satisfied` - 계약: 모든 changed file은 승인된 기능과 필수 supporting change 또는 테스트 evidence로 설명되고 기존 requirement ID를 임의 갱신하거나 범위 밖 제품 및 설정을 변경하지 않는다. - 구현 근거: dashboard/app.py, dashboard/page_views/accounts.py, dashboard/page_views/assets.py, dashboard/page_views/monthly_settlement.py, docs/data-model.md, docs/interface-contract.md, docs/project-structure.md, docs/requirements/req-003_account-valuation-history.md, docs/runtime-flow.md, jarca_ledger_mcp/adapters/mcp/server.py, jarca_ledger_mcp/adapters/mcp/tool_contracts.py, jarca_ledger_mcp/adapters/streamlit/accounts_gateway.py, jarca_ledger_mcp/adapters/streamlit/overview_gateway.py, jarca_ledger_mcp/application/__init__.py, jarca_ledger_mcp/application/account_valuation_service.py, jarca_ledger_mcp/application/accounts_write_services.py, jarca_ledger_mcp/application/assets_service.py, jarca_ledger_mcp/application/categorization_services.py, jarca_ledger_mcp/application/cross_transfer_service.py, jarca_ledger_mcp/application/imports_service.py, jarca_ledger_mcp/application/monthly_settlement_service.py, jarca_ledger_mcp/application/reconciliation_service.py, jarca_ledger_mcp/application/review_decision_service.py, jarca_ledger_mcp/application/shared.py, jarca_ledger_mcp/application/system_services.py, jarca_ledger_mcp/application/transaction_report_services.py, jarca_ledger_mcp/application/uncategorized_workbench_service.py, jarca_ledger_mcp/infrastructure/sqlite/__init__.py, jarca_ledger_mcp/infrastructure/sqlite/connection.py, jarca_ledger_mcp/infrastructure/sqlite/migrations.py, jarca_ledger_mcp/infrastructure/sqlite/schema.py, jarca_ledger_mcp/service.py, scripts/ci_fixture_db.py, tests/test_account_valuations.py, tests/test_asset_snapshots.py, tests/test_contract_regression.py, tests/test_dashboard_app.py, tests/test_dashboard_menu_transition.py, tests/test_import_provenance_policy.py, tests/test_issue_12_regressions.py, tests/test_issue_12_review59_account.py, tests/test_issue_12_review59_readonly.py, tests/test_issue_12_review59_reports.py, tests/test_ledger_categories.py, tests/test_requirement_docs.py, tests/test_review_decision_workbench.py, tests/test_seoulpay_xlsx.py, tests/test_service.py; 전체 48개 changed files는 valuation 및 SQLite, current/import, read-only wrappers 및 downstream query propagation, Dashboard와 adapters, 5종 문서 및 focused regression tests와 synthetic CI seed로 설명된다. 154개 hunk를 immutable base와 head blobs에 대조했다. PR은 exact head에서 pytest 233 passed와 4 skipped 및 ruff exit 0을 보고하지만 조회 status는 0개 및 pending이다. - 테스트 근거: tests/test_account_valuations.py, tests/test_asset_snapshots.py, tests/test_contract_regression.py, tests/test_dashboard_app.py, tests/test_dashboard_menu_transition.py, tests/test_import_provenance_policy.py, tests/test_issue_12_regressions.py, tests/test_issue_12_review59_account.py, tests/test_issue_12_review59_readonly.py, tests/test_issue_12_review59_reports.py, tests/test_ledger_categories.py, tests/test_requirement_docs.py, tests/test_review_decision_workbench.py, tests/test_seoulpay_xlsx.py, tests/test_service.py - 판정 근거: 범위 초과는 없다. 구현자 보고와 정적 검토를 구분했다. Reviewer는 변경 Python files 43개 compile-only 및 synthetic stdlib AST 추출 관찰만 수행했고 제품 pytest와 browser 및 CI 성공을 주장하지 않는다. ### 범위 판정 - 누락: 대출 balance 평가의 대표 정의 필수 검증, 실제 근거일과 동기화시각을 분리한 current import 권위, 동일 증빙 정정 재시도 재사용, 이전 마감 key replay의 원래 run 및 evidence 결합, 데이터 모델의 최신 cache 동기화 책임, 인터페이스의 허용값과 원금 및 대표 정의 입력 및 출력 계약 - 범위 초과: 없음 - 명세 모순: 없음 ### 결론 기존 정정 scope 및 no-write, 일반 source_ref 재입력, 대사 completeness, conditional 및 downstream provenance, 요구사항 검증 분류와 구조 및 흐름 보완을 확인했다. 그러나 loan balance 정의 누락, current import의 시각 혼용, 동일 증빙 정정 재시도, 재마감 뒤 이전 key replay의 run 혼합 및 데이터 모델과 인터페이스 잔여 의무 때문에 request_changes다. 구현자 PR 본문의 exact head pytest 233 passed 및 4 skipped와 ruff exit 0은 구현자 보고이며 reviewer 독립 제품 테스트 또는 CI 성공이 아니다. Reviewer는 immutable blobs와 154개 hunk 및 정적 source와 tests를 대조하고 변경 Python files 43개 compile-only와 supplemental synthetic AST 추출 관찰을 수행했다. Source와 Issue 및 branch를 변경하거나 merge하지 않았다. <!-- gitea-agent:implementation-spec-review/v1 owner=jsfamily repository=jarca-ledger-mcp issue=12 pr=13 head=6a8a27a74ece9a9cce6f9772259677813d91ddf8 contract-sha256=6d86b591b022fcc722611bfec6d24e54a64216ab6f7c4098f357e25420218818 result-sha256=ae31e854eb0e2f5919e6ddea076a0005f8a3c0eb485122385ec6f2269cfcb7d2 correlation=f8c8443e9f86f75a3df9f939e371c4d96b2b8657053fcb86d336d7ccf4b20687 -->
gitea-impl-agent added 2 commits 2026-10-07 00:24:30 +00:00
gitea-spec-agent requested changes 2026-10-07 02:57:55 +00:00
Dismissed
gitea-spec-agent left a comment
Owner

구현 명세 적합성 검토

Acceptance criteria 판정

  • C01-history — satisfied

    • 계약: 평가 계좌 FK, 기준일과 등록일, 대표 금액과 통화와 목적, 출처와 확인 상태, 증빙 식별자, 정정 연결과 사유 및 선택 시간 자료를 이력으로 보존한다.
    • 구현 근거: jarca_ledger_mcp/application/account_valuation_service.py, jarca_ledger_mcp/infrastructure/sqlite/schema.py, jarca_ledger_mcp/infrastructure/sqlite/migrations.py; schema.py account_valuations와 migrations.py schema12, account_valuation_service.py 127-255는 날짜와 등록시각 및 정정 연결과 선택 지표를 보존한다. tests/test_account_valuations.py의 영속 이력 사례와 named tests를 대조했다.
    • 테스트 근거: tests/test_account_valuations.py
    • 판정 근거: 기본 이력 구조는 충족한다. 대출 정의를 누락하는 우회 writer는 N01의 동일 계약 위반으로 별도 판정한다.
  • C02-money-metrics — satisfied

    • 계약: 금액 정밀도와 NULL 및 0을 보존하고 취득원가, 순납입액, 기관 표시 원금 금액과 정의 및 원문 명칭, 손익과 수익률의 계산 기준을 구분한다. 투자 대표 총평가액과 포함 현금 및 원금을 중복 합산하지 않는다.
    • 구현 근거: jarca_ledger_mcp/application/account_valuation_service.py, jarca_ledger_mcp/infrastructure/sqlite/schema.py, docs/data-model.md, docs/requirements/req-003_account-valuation-history.md; data-model.md 33-61과 account_valuation_service.py 16-22,160-180의 물리 필드 의미를 대조했다. test_valuation_round_trip_preserves_null_zero_and_physical_amount_mapping은 investment principal 0 및 interest/fee NULL, loan principal/interest/fee 반환을 11-33행에서 호출하고 확인한다.
    • 테스트 근거: tests/test_issue_12_review59_account.py, tests/test_issue_12_regressions.py
    • 판정 근거: NULL과 0 및 투자 기관 표시 원금과 대출 잔여 원금의 반환 의미가 유지된다. 대표값과 구성 금액은 중복 합산하지 않는다.
  • N01-loan-balance-definition — unsatisfied

    • 계약: 대출 평가 기록마다 대표 부채가 원금만인지 원금과 이자 및 수수료인지 필수로 명시하고 기본값으로 추정하지 않는다. 목적 alias가 필수 정의 계약을 우회하지 않는다.
    • 구현 근거: jarca_ledger_mcp/application/account_valuation_service.py, docs/requirements/req-003_account-valuation-history.md, jarca_ledger_mcp/application/accounts_write_services.py, jarca_ledger_mcp/application/imports_service.py, docs/data-model.md; 일반 등록의 loan balance 정의 누락은 account_valuation_service.py 188-195에서 차단한다. 그러나 record_account_valuation_candidate의 93-124행은 currency만 읽고 account type을 확인하지 않으며 정의 컬럼 없이 balance 이력을 INSERT한다. accounts_write_services.py 5-14,17-33의 날짜 있는 loan 계좌 생성 및 수정과 imports_service.py 37-41,96-100 경로가 이를 호출한다. 또한 일반 등록에서 loan 계좌의 cash_balance 또는 total_value는 188-195행 정의 검사 대상이 아니며 84-87행은 해당 목적에 정의 전달을 금지한다. test_loan_balance_requires_representative_liability_definition은 일반 register balance만 호출한다.
    • 테스트 근거: tests/test_issue_12_regressions.py, tests/test_issue_12_review59_account.py, tests/test_account_valuation_edge_contracts.py
    • 판정 근거: 승인 Discovery 19와 56행 및 data-model 61행은 확인 상태와 무관하게 대출 평가 기록마다 대표 정의를 요구한다. 일반 balance 등록은 해소됐지만 후보 writer 및 다른 허용 purpose에서 정의 없는 loan 평가 기록이 저장될 수 있다. 정의를 추정하지 말고 모든 loan 이력 생성 경로에서 같은 필수 조건을 적용하거나 근거 없는 후보 생성 및 부적합 purpose를 차단해야 한다. account write 또는 import의 기존 현재 캐시 호환은 보존하면서 이 우회 경계를 회귀로 확인하면 된다. 현재 후보는 unverified라 즉시 합계에 포함되지 않지만 영속 이력의 필수 정의 계약 위반은 남는다.
  • C03-selection — satisfied

    • 계약: 계좌와 통화 및 평가 목적별 유효 자료를 선택한다. exact는 당일 확인 자료만, as_of는 기준일 이하 최신 확인 자료만 사용한다. 미래 자료는 제외하고 미확인 후보는 확인 자료를 대체하거나 합산하지 않는다. 실제 기준일과 경과 일수 및 이월 상태를 반환한다.
    • 구현 근거: jarca_ledger_mcp/application/account_valuation_service.py, jarca_ledger_mcp/application/assets_service.py; account_valuation_service.py의 select_account_valuation과 assets_service.py의 공통 계좌 선택은 verified leaf, 통화 및 purpose, exact/as_of 날짜와 미래 제외를 유지한다. test_select_exact_and_as_of_excludes_unverified_and_reports_carry_forward와 issue12 regression source를 대조했다.
    • 테스트 근거: tests/test_account_valuations.py, tests/test_issue_12_regressions.py
    • 판정 근거: 확인 자료 선택 및 미확인 후보 비합산은 충족한다. N01의 후보 이력 정의 누락을 현재 합산 오류로 과장하지 않는다.
  • C04-correction-validation — satisfied

    • 계약: 평가 정정은 append-only로 대상과 사유를 연결하며 다른 계좌, 통화, 목적을 참조하는 정정과 순환 및 동일 유효본의 동시 분기를 차단한다.
    • 구현 근거: jarca_ledger_mcp/application/account_valuation_service.py, jarca_ledger_mcp/infrastructure/sqlite/schema.py; account_valuation_service.py 196-220,correct_account_valuation의 부모 scope 및 사유 검증을 대조했다. test_direct_correction_requires_matching_existing_parent_and_reason 및 test_correction_rejects_currency_and_kind_override_but_preserves_valid_overrides가 실패와 원본 유지 경계를 포함한다.
    • 테스트 근거: tests/test_issue_12_review59_account.py, tests/test_account_valuations.py, tests/test_issue_12_regressions.py
    • 판정 근거: 다른 계좌 또는 통화와 목적 정정, 사유 누락 및 분기와 순환 방지는 유지된다. 동일 정정 재시도는 C06에서 새 구현을 확인했다.
  • C05-current-import — satisfied

    • 계약: 뒤늦은 과거 자료 등록으로 최신 표시값을 과거로 되돌리지 않는다. 기존 계좌 수정과 import의 최신 캐시 및 새 이력 권위를 연결하며 동기화 시각을 실제 평가일로 오인하지 않는다.
    • 구현 근거: jarca_ledger_mcp/application/imports_service.py, jarca_ledger_mcp/application/assets_service.py, jarca_ledger_mcp/application/accounts_write_services.py; imports_service.py 43-49는 last_balance_basis_date를 비교하고 last_synced_at은 실행시각으로만 저장한다. accounts_write_services.py 5-14,25-33,41-81은 명시된 basis만 후보로 기록하고 늦은 과거 자료의 캐시 rollback을 막는다. test_import_current_balance_authority.py 37-105는 연속 늦은 import, 기준일 미상 write 및 unknown legacy provenance를 실제 호출과 assertion으로 확인한다. Dashboard 및 MCP 전달은 test_account_basis_public_consumers.py 13-47과 대조했다.
    • 테스트 근거: tests/test_issue_12_review59_account.py, tests/test_import_provenance_policy.py, tests/test_import_current_balance_authority.py, tests/test_account_basis_public_consumers.py
    • 판정 근거: 이전 C05의 근거일과 동기화시각 혼용은 해소됐다. 실제 평가일을 별도 필드로 비교하고 전달하며 sync-only 입력은 역사 근거로 추정하지 않는다.
  • C06-idempotency — satisfied

    • 계약: 동일 증빙 또는 idempotency 재입력은 동일 기록을 재사용하며 같은 키의 다른 payload는 충돌이다. 동시 정정의 분기를 차단하고 UNIQUE 계좌 및 기준일 하나로 정정 추가를 막지 않는다.
    • 구현 근거: jarca_ledger_mcp/application/account_valuation_service.py, jarca_ledger_mcp/infrastructure/sqlite/schema.py, jarca_ledger_mcp/infrastructure/sqlite/migrations.py, jarca_ledger_mcp/application/accounts_write_services.py, jarca_ledger_mcp/application/imports_service.py; correct_account_valuation은 전체 effective payload와 명시 key 또는 기존 child를 비교한다. test_account_valuation_edge_contracts.py 42-93은 keyless 동일 정정 재사용 및 amount/reason/source 변경 충돌과 row count를 확인한다. test_issue_12_review59_account.py 156-180은 명시 key 재시도도 포함하며 test_issue_12_regressions.py 214-232는 보존 payload 변경을 확인한다.
    • 테스트 근거: tests/test_issue_12_review59_account.py, tests/test_account_valuations.py, tests/test_issue_12_regressions.py, tests/test_account_valuation_edge_contracts.py
    • 판정 근거: 이전 C06은 해소됐다. 이전 리뷰의 해당 테스트가 첫 정정만 확인한다는 설명은 오류이며 명시 key 재시도도 이미 검증하던 테스트였다. 이번 변경으로 keyless 증빙 replay 경계도 닫혔다.
  • C07-close-immutability — satisfied

    • 계약: 기존 asset_snapshots와 correction run을 보존하고 평가 정정 및 거래 추가로 기존 마감을 자동 변경하지 않는다. 동일 기준일 재마감은 사유와 이전 run 연결을 가진 새 버전을 원자적으로 추가한다.
    • 구현 근거: jarca_ledger_mcp/application/assets_service.py, jarca_ledger_mcp/infrastructure/sqlite/schema.py, jarca_ledger_mcp/infrastructure/sqlite/migrations.py; assets_service.py의 원자적 append-only close와 correction run 저장을 immutable run lookup 변경 및 기존 snapshot tests와 대조했다. 평가 변경은 기존 저장 run을 갱신하지 않는다.
    • 테스트 근거: tests/test_asset_snapshots.py, tests/test_issue_12_regressions.py
    • 판정 근거: 기존 마감 불변성과 사유를 가진 명시적 새 마감 버전 생성이 유지된다.
  • N02-close-replay-run-binding — satisfied

    • 계약: 마감 버전의 근거는 불변이며 동일 idempotency 요청은 원래 기록을 재사용한다. 재마감으로 과거 run 응답 및 evidence를 변경하지 않는다.
    • 구현 근거: jarca_ledger_mcp/application/assets_service.py, docs/interface-contract.md; assets_service.py 262-292의 _snapshot_rows_for_run과 659-700은 기존 idempotency run ID로 rows 및 metadata 전체를 재구성한다. test_asset_snapshot_idempotency.py 8-82는 A close, B correction, A replay 후 response equality와 모든 근거 및 row count를 확인하고 85-132는 zero-row run을 확인한다.
    • 테스트 근거: tests/test_issue_12_review59_reports.py, tests/test_issue_12_regressions.py, tests/test_asset_snapshot_idempotency.py
    • 판정 근거: 이전 N02는 해소됐다. latest run 자료와 이전 run ID를 혼합하지 않으며 동일 persisted run의 approval/correction/warnings/provenance 및 snapshot IDs를 반환한다.
  • C08-approved-conditional — satisfied

    • 계약: 완전한 exact 마감, 미완료 초안, 별도 승인된 조건부 마감을 구분한다. 승인 전 누락 및 이월은 미완료 초안이고 승인 후에도 누락 제외 및 확인된 과거값 이월만 허용한다. 미확인, 미래, 기준일 미상 금액은 승인으로도 합산하지 않으며 적용과 제외와 이월 및 승인자와 시각과 사유와 근거를 고정한다.
    • 구현 근거: jarca_ledger_mcp/application/assets_service.py, jarca_ledger_mcp/infrastructure/sqlite/schema.py, dashboard/page_views/assets.py; 새 head의 jarca_ledger_mcp/application/assets_service.py, jarca_ledger_mcp/infrastructure/sqlite/schema.py, dashboard/page_views/assets.py와 tests/test_issue_12_review59_reports.py, tests/test_issue_12_regressions.py, tests/test_asset_snapshots.py를 승인 계약 및 base-to-head 변경에 대응했다. 이전 충족 의미를 유지하는 source와 named test를 현재 immutable snapshot에서 대조했으며 필수 문서는 document-obligations.json으로 구조와 의미를 분리했다.
    • 테스트 근거: tests/test_issue_12_review59_reports.py, tests/test_issue_12_regressions.py, tests/test_asset_snapshots.py
    • 판정 근거: 승인 계약은 현재 source 및 문서와 회귀 검증 내용에서 보존된다. 구현자 명령 기록은 별도 source revision의 실행 결과이며 reviewer 독립 실행이나 CI 성공으로 표현하지 않는다.
  • C09-reconciliation — satisfied

    • 계약: 외부 확인값과 장부 계산값을 분리하고 검증된 시작잔고, 기준시점, 거래 포함 범위와 계산 완전성을 표시한다. 거래 없는 수동 투자 계좌의 대사 불가 및 거래 미수입과 평가 수동 관리 상태를 구분하고 가짜 거래를 만들지 않는다. 대사도 공통 평가 근거와 대출 대표 정의를 사용한다.
    • 구현 근거: jarca_ledger_mcp/application/reconciliation_service.py, jarca_ledger_mcp/application/account_valuation_service.py, jarca_ledger_mcp/application/monthly_settlement_service.py; 새 head의 jarca_ledger_mcp/application/reconciliation_service.py, jarca_ledger_mcp/application/account_valuation_service.py, jarca_ledger_mcp/application/monthly_settlement_service.py와 tests/test_issue_12_review59_reports.py, tests/test_issue_12_regressions.py, tests/test_service.py를 승인 계약 및 base-to-head 변경에 대응했다. 이전 충족 의미를 유지하는 source와 named test를 현재 immutable snapshot에서 대조했으며 필수 문서는 document-obligations.json으로 구조와 의미를 분리했다.
    • 테스트 근거: tests/test_issue_12_review59_reports.py, tests/test_issue_12_regressions.py, tests/test_service.py
    • 판정 근거: 승인 계약은 현재 source 및 문서와 회귀 검증 내용에서 보존된다. 구현자 명령 기록은 별도 source revision의 실행 결과이며 reviewer 독립 실행이나 CI 성공으로 표현하지 않는다.
  • C10-report-monthly-evidence — satisfied

    • 계약: MCP와 Dashboard 및 월정산 보고에서 같은 기준일과 선택 근거 및 실제 평가일, 경과 일수, 확인 상태, 누락과 미확인 및 이월 경고, 마감 버전 및 조건부 승인 근거를 일관되게 전달한다.
    • 구현 근거: jarca_ledger_mcp/application/assets_service.py, jarca_ledger_mcp/application/monthly_settlement_service.py, dashboard/page_views/monthly_settlement.py, dashboard/page_views/accounts.py; 새 head의 jarca_ledger_mcp/application/assets_service.py, jarca_ledger_mcp/application/monthly_settlement_service.py, dashboard/page_views/monthly_settlement.py, dashboard/page_views/accounts.py와 tests/test_issue_12_review59_reports.py, tests/test_issue_12_regressions.py, tests/test_service.py를 승인 계약 및 base-to-head 변경에 대응했다. 이전 충족 의미를 유지하는 source와 named test를 현재 immutable snapshot에서 대조했으며 필수 문서는 document-obligations.json으로 구조와 의미를 분리했다.
    • 테스트 근거: tests/test_issue_12_review59_reports.py, tests/test_issue_12_regressions.py, tests/test_service.py
    • 판정 근거: 승인 계약은 현재 source 및 문서와 회귀 검증 내용에서 보존된다. 구현자 명령 기록은 별도 source revision의 실행 결과이며 reviewer 독립 실행이나 CI 성공으로 표현하지 않는다.
  • C11-adapter-structure — satisfied

    • 계약: MCP와 Streamlit gateway는 공통 application을 사용하고 기존 공개 호출명과 기존 인수 및 success와 실패 error_code 및 error envelope를 가능한 한 유지한다. 새 Dashboard 인증 또는 MCP 인증을 도입하지 않는다.
    • 구현 근거: jarca_ledger_mcp/adapters/mcp/server.py, jarca_ledger_mcp/adapters/mcp/tool_contracts.py, jarca_ledger_mcp/adapters/streamlit/accounts_gateway.py, jarca_ledger_mcp/application/__init_.py, jarca_ledger_mcp/service.py, dashboard/page_views/accounts.py, dashboard/page_views/assets.py, dashboard/page_views/monthly_settlement.py; 새 head의 jarca_ledger_mcp/adapters/mcp/server.py, jarca_ledger_mcp/adapters/mcp/tool_contracts.py, jarca_ledger_mcp/adapters/streamlit/accounts_gateway.py, jarca_ledger_mcp/application/__init_.py, jarca_ledger_mcp/service.py, dashboard/page_views/accounts.py, dashboard/page_views/assets.py, dashboard/page_views/monthly_settlement.py와 tests/test_contract_regression.py, tests/test_issue_12_regressions.py를 승인 계약 및 base-to-head 변경에 대응했다. 이전 충족 의미를 유지하는 source와 named test를 현재 immutable snapshot에서 대조했으며 필수 문서는 document-obligations.json으로 구조와 의미를 분리했다.
    • 테스트 근거: tests/test_contract_regression.py, tests/test_issue_12_regressions.py
    • 판정 근거: 승인 계약은 현재 source 및 문서와 회귀 검증 내용에서 보존된다. 구현자 명령 기록은 별도 source revision의 실행 결과이며 reviewer 독립 실행이나 CI 성공으로 표현하지 않는다.
  • C12-migration-legacy — satisfied

    • 계약: schema 11의 기존 데이터와 마감 및 개인정보를 보존하고 additive하고 idempotent한 migration을 제공한다. 기준일 증거 없는 값을 임의 월말로 소급하거나 legacy snapshot에 valuation_id를 추측하여 생성하지 않는다.
    • 구현 근거: jarca_ledger_mcp/infrastructure/sqlite/schema.py, jarca_ledger_mcp/infrastructure/sqlite/migrations.py, jarca_ledger_mcp/application/assets_service.py; 새 head의 jarca_ledger_mcp/infrastructure/sqlite/schema.py, jarca_ledger_mcp/infrastructure/sqlite/migrations.py, jarca_ledger_mcp/application/assets_service.py와 tests/test_account_valuations.py, tests/test_issue_12_regressions.py, tests/test_ledger_categories.py, tests/test_review_decision_workbench.py를 승인 계약 및 base-to-head 변경에 대응했다. 이전 충족 의미를 유지하는 source와 named test를 현재 immutable snapshot에서 대조했으며 필수 문서는 document-obligations.json으로 구조와 의미를 분리했다.
    • 테스트 근거: tests/test_account_valuations.py, tests/test_issue_12_regressions.py, tests/test_ledger_categories.py, tests/test_review_decision_workbench.py
    • 판정 근거: 승인 계약은 현재 source 및 문서와 회귀 검증 내용에서 보존된다. 구현자 명령 기록은 별도 source revision의 실행 결과이며 reviewer 독립 실행이나 CI 성공으로 표현하지 않는다.
  • C13-read-only — satisfied

    • 계약: preview와 조회 및 Dashboard 렌더링은 금융 쓰기를 실행하지 않는다. 명시적 등록, 정정, 승인 close 및 import 제출만 변경을 수행하고 실패 시 부분 쓰기를 남기지 않는다.
    • 구현 근거: jarca_ledger_mcp/infrastructure/sqlite/connection.py, jarca_ledger_mcp/application/shared.py, jarca_ledger_mcp/application/system_services.py, jarca_ledger_mcp/application/account_valuation_service.py, jarca_ledger_mcp/application/assets_service.py; 새 head의 jarca_ledger_mcp/infrastructure/sqlite/connection.py, jarca_ledger_mcp/application/shared.py, jarca_ledger_mcp/application/system_services.py, jarca_ledger_mcp/application/account_valuation_service.py, jarca_ledger_mcp/application/assets_service.py와 tests/test_issue_12_review59_readonly.py, tests/test_dashboard_app.py, tests/test_dashboard_menu_transition.py를 승인 계약 및 base-to-head 변경에 대응했다. 이전 충족 의미를 유지하는 source와 named test를 현재 immutable snapshot에서 대조했으며 필수 문서는 document-obligations.json으로 구조와 의미를 분리했다.
    • 테스트 근거: tests/test_issue_12_review59_readonly.py, tests/test_dashboard_app.py, tests/test_dashboard_menu_transition.py
    • 판정 근거: 승인 계약은 현재 source 및 문서와 회귀 검증 내용에서 보존된다. 구현자 명령 기록은 별도 source revision의 실행 결과이며 reviewer 독립 실행이나 CI 성공으로 표현하지 않는다.
  • C14-auth-menu-preservation — satisfied

    • 계약: Dashboard 인증은 DB보다 먼저이며 REQ-001의 cookie와 logout 및 REQ-002의 메뉴 label과 order, shell, query, error와 retry 및 명시적 금융 쓰기 계약을 유지한다.
    • 구현 근거: dashboard/app.py, dashboard/page_views/accounts.py, dashboard/page_views/assets.py, dashboard/page_views/monthly_settlement.py, docs/interface-contract.md, docs/project-structure.md, docs/runtime-flow.md; 새 head의 dashboard/app.py, dashboard/page_views/accounts.py, dashboard/page_views/assets.py, dashboard/page_views/monthly_settlement.py, docs/interface-contract.md, docs/project-structure.md, docs/runtime-flow.md와 tests/test_dashboard_menu_transition.py, tests/test_dashboard_app.py를 승인 계약 및 base-to-head 변경에 대응했다. 이전 충족 의미를 유지하는 source와 named test를 현재 immutable snapshot에서 대조했으며 필수 문서는 document-obligations.json으로 구조와 의미를 분리했다.
    • 테스트 근거: tests/test_dashboard_menu_transition.py, tests/test_dashboard_app.py
    • 판정 근거: 승인 계약은 현재 source 및 문서와 회귀 검증 내용에서 보존된다. 구현자 명령 기록은 별도 source revision의 실행 결과이며 reviewer 독립 실행이나 CI 성공으로 표현하지 않는다.
  • C15-exclusions-privacy — satisfied

    • 계약: 증권사 자동 연동, 정확한 성과 또는 환율 엔진, 새 인증, 별도 월정산 제품, 거래 추론 및 기존 데이터 자동 재작성과 수기 비계좌 자산 전체 이력 재설계를 추가하지 않는다. 실제 계좌 및 금융 증빙과 credential을 로그와 문서 및 테스트에 기록하지 않는다.
    • 구현 근거: jarca_ledger_mcp/application/assets_service.py, jarca_ledger_mcp/application/account_valuation_service.py, jarca_ledger_mcp/application/imports_service.py, jarca_ledger_mcp/application/reconciliation_service.py, jarca_ledger_mcp/infrastructure/sqlite/schema.py, jarca_ledger_mcp/infrastructure/sqlite/migrations.py; 새 head의 jarca_ledger_mcp/application/assets_service.py, jarca_ledger_mcp/application/account_valuation_service.py, jarca_ledger_mcp/application/imports_service.py, jarca_ledger_mcp/application/reconciliation_service.py, jarca_ledger_mcp/infrastructure/sqlite/schema.py, jarca_ledger_mcp/infrastructure/sqlite/migrations.py와 tests/test_issue_12_review59_reports.py, tests/test_issue_12_regressions.py, scripts/ci_fixture_db.py를 승인 계약 및 base-to-head 변경에 대응했다. 이전 충족 의미를 유지하는 source와 named test를 현재 immutable snapshot에서 대조했으며 필수 문서는 document-obligations.json으로 구조와 의미를 분리했다.
    • 테스트 근거: tests/test_issue_12_review59_reports.py, tests/test_issue_12_regressions.py, scripts/ci_fixture_db.py
    • 판정 근거: 승인 계약은 현재 source 및 문서와 회귀 검증 내용에서 보존된다. 구현자 명령 기록은 별도 source revision의 실행 결과이며 reviewer 독립 실행이나 CI 성공으로 표현하지 않는다.
  • D01-requirement-structure — satisfied

    • 계약: 신규 REQ-003을 배정 경로와 제목으로 작성하며 trusted harness README와 TEMPLATE의 JSON metadata, 연속 요구사항 및 AC, 필수 섹션, 판정 기준과 검증 및 검증 분류의 수준과 백엔드와 케이스 및 상태 불변조건을 충족한다. 초기 PR은 미정이며 PR 생성 후 실제 번호를 추적한다.
    • 구현 근거: docs/requirements/req-003_account-valuation-history.md; REQ-003 metadata 및 51-174행 필수 섹션, 187-297행 전체 AC10개를 trusted README와 TEMPLATE에 대조했다. 신규 문서이며 pinned base에는 같은 파일이 없다. Source Issue12와 구현 PR13 및 requirement lifecycle은 trusted README43-45,83-92 규칙과 일치한다.
    • 테스트 근거: tests/test_requirement_docs.py
    • 판정 근거: 신규 금융 기능 REQ-003의 ID, exact path, title, metadata, 필수 구조 및 전체 AC의 검증 분류와 추적성은 충족한다. 문서 approved lifecycle을 PR 구현 승인으로 오인하지 않는다.
  • D02-requirement-semantics — satisfied

    • 계약: 요구사항에는 평가 근거와 지표 정의, 선택과 future 제외, 정정 및 idempotency 충돌, 대사 완전성, current 및 import 연계, 마감 상태와 불변성과 승인, shared adapter 및 인증, migration과 legacy를 소스 및 테스트에 대응한다. 모든 승인된 경계와 회귀 사례를 인수 기준으로 내린다.
    • 구현 근거: docs/requirements/req-003_account-valuation-history.md; 새 head의 docs/requirements/req-003_account-valuation-history.md와 tests/test_account_valuations.py, tests/test_asset_snapshots.py, tests/test_issue_12_regressions.py, tests/test_requirement_docs.py를 승인 계약 및 base-to-head 변경에 대응했다. 이전 충족 의미를 유지하는 source와 named test를 현재 immutable snapshot에서 대조했으며 필수 문서는 document-obligations.json으로 구조와 의미를 분리했다. REQ-003 전체 검증 참조 13개를 exact head Git tree와 AST symbol로 확인했으며 모두 존재한다. 변경되지 않은 tests/test_mcp_http_runtime.py와 tests/test_dashboard_authentication_app.py도 실제 blob을 읽어 configuration 및 fail-closed auth-before-DB 사례를 대조했다.
    • 테스트 근거: tests/test_account_valuations.py, tests/test_asset_snapshots.py, tests/test_issue_12_regressions.py, tests/test_requirement_docs.py, tests/test_mcp_http_runtime.py, tests/test_dashboard_authentication_app.py
    • 판정 근거: 승인 계약은 현재 source 및 문서와 회귀 검증 내용에서 보존된다. 구현자 명령 기록은 별도 source revision의 실행 결과이며 reviewer 독립 실행이나 CI 성공으로 표현하지 않는다.
  • D03-data-model — satisfied

    • 계약: 신규 데이터 모델은 기존 entities 및 valuation과 마감의 관계, FK와 날짜 및 정확한 금액과 NULL 및 0과 선택 지표 및 대출 필수 정의, 계좌와 통화 및 목적과 기준일의 선택 및 index와 단일 유효 정정본, 고정 적용 분류 및 출처와 상태와 누락 및 이월 및 승인 버전, 분리된 정정과 schema11 이관 및 미상 날짜와 legacy 및 최신 캐시 동기화 책임을 정의한다.
    • 구현 근거: docs/data-model.md; data-model.md 33-61,82-117,123-160은 필드와 금액 의미, snapshot 근거 고정 및 상태, last_balance_basis_date와 sync시각 분리, 역사 authority 및 캐시 writer, 과거 rollback 금지와 additive legacy unknown-basis를 명시한다. test_valuation_contract_docs.py 11-25와 직접 내용을 대조했다.
    • 테스트 근거: tests/test_account_valuations.py, tests/test_asset_snapshots.py, tests/test_issue_12_regressions.py, tests/test_valuation_contract_docs.py
    • 판정 근거: 이전 D03의 캐시 책임 및 실제 평가일 계약 누락은 해소됐다. 대출 필수 정의 문서는 충족하지만 구현 후보 writer 위반은 N01로 분리한다.
  • D04-interface-contract — satisfied

    • 계약: 인터페이스 문서는 기존 auth 및 메뉴를 보존하고 평가 등록 및 조회 및 정정의 모든 입력과 유효본 및 원금 정의 출력, report 및 preview/close 및 월정산과 대사와 current API의 공통 선택, exact 기본과 실제 날짜 및 age 및 이월과 누락 및 미확인과 출처 및 버전과 승인 출력을 정의한다. 잘못된 입력과 scope 및 충돌과 부족 근거는 무변경 실패이며 기존 envelope와 required keys 및 의미 변경 정책을 명시한다.
    • 구현 근거: docs/interface-contract.md, docs/data-model.md; interface-contract.md 277-299는 valuation 출력이 persisted rows임을 정의하고 336-345는 enum 및 loan 조건부 정의, no-write 오류와 캐시 basis를 명시한다. 401-415는 exact 물리 인수와 envelope를 열거한다. data-model.md 33-61은 반환되는 row의 principal 투자/대출 의미와 interest/fee 및 NULL/0를 정의하며 test_issue_12_review59_account.py 11-33은 실제 반환 필드를 확인한다. 425-435는 close/run replay와 provenance 및 redaction을 정의한다.
    • 테스트 근거: tests/test_account_valuations.py, tests/test_issue_12_regressions.py, tests/test_contract_regression.py, tests/test_valuation_contract_docs.py, tests/test_issue_12_review59_account.py
    • 판정 근거: 이전 D04의 enum 및 loan 정의 조건은 해소됐다. persisted row 출력과 exact 필드 및 데이터 모델의 의미를 함께 읽으면 원금 반환 의미가 보존된다. 별도 response 표나 반복 기재 부재만으로 새 문서 변경을 요구하지 않는다. 구현 writer의 필수 정의 위반은 N01에서 판정한다.
  • D05-project-structure — satisfied

    • 계약: 프로젝트 구조 문서는 기존 source와 test 및 evidence를 보존하고 SQLite schema와 migrations, application의 assets와 account writes 및 import와 reconciliation 및 monthly 책임, 공개 facade와 MCP 및 Streamlit과 기존 세 화면 및 tests를 exact 경로로 대응한다. adapter에서 선택 정책을 복제하지 않고 대출 정의와 verified as_of 및 conditional 승인 경계를 shared application에 배치한다.
    • 구현 근거: docs/project-structure.md; 새 head의 docs/project-structure.md와 tests/test_requirement_docs.py를 승인 계약 및 base-to-head 변경에 대응했다. 이전 충족 의미를 유지하는 source와 named test를 현재 immutable snapshot에서 대조했으며 필수 문서는 document-obligations.json으로 구조와 의미를 분리했다. 현재 문서 122-164,171-212행의 공통 application ownership, canonical adapter 경계, 세 선택 정책 및 실패 무변경을 의무표에 대응했다. 기존 인증과 메뉴 계약의 base 본문은 byte-preserved다.
    • 테스트 근거: tests/test_requirement_docs.py
    • 판정 근거: 승인 계약은 현재 source 및 문서와 회귀 검증 내용에서 보존된다. 구현자 명령 기록은 별도 source revision의 실행 결과이며 reviewer 독립 실행이나 CI 성공으로 표현하지 않는다.
  • D06-runtime-flow — satisfied

    • 계약: 런타임 문서는 auth 및 메뉴를 보존하고 register/correct의 증빙 및 scope 검증과 append 및 유효본 확인 및 최신 캐시 동기화를 단일 트랜잭션으로 설명한다. 날짜 및 정책과 통화 및 대표 합산과 경고 read, preview 후 명시적 approval 및 원자적 freeze, reasoned reclose, 같은 근거의 monthly 및 대사, import와 이관 trigger 및 실패복구, retry와 concurrency 및 preview drift 재검증과 무부분쓰기, 비민감 valuation/run 상관 신호를 정의한다.
    • 구현 근거: docs/runtime-flow.md; 새 head의 docs/runtime-flow.md와 tests/test_account_valuations.py, tests/test_asset_snapshots.py, tests/test_issue_12_regressions.py를 승인 계약 및 base-to-head 변경에 대응했다. 이전 충족 의미를 유지하는 source와 named test를 현재 immutable snapshot에서 대조했으며 필수 문서는 document-obligations.json으로 구조와 의미를 분리했다. 현재 문서 147-193,221-241행의 공통 application ownership, canonical adapter 경계, 세 선택 정책 및 실패 무변경을 의무표에 대응했다. 기존 인증과 메뉴 계약의 base 본문은 byte-preserved다.
    • 테스트 근거: tests/test_account_valuations.py, tests/test_asset_snapshots.py, tests/test_issue_12_regressions.py
    • 판정 근거: 승인 계약은 현재 source 및 문서와 회귀 검증 내용에서 보존된다. 구현자 명령 기록은 별도 source revision의 실행 결과이며 reviewer 독립 실행이나 CI 성공으로 표현하지 않는다.
  • C16-supporting-evidence-scope — satisfied

    • 계약: 모든 changed file은 승인된 기능과 필수 supporting change 또는 테스트 evidence로 설명되고 기존 requirement ID를 임의 갱신하거나 범위 밖 제품 및 설정을 변경하지 않는다.
    • 구현 근거: dashboard/app.py, dashboard/page_views/accounts.py, dashboard/page_views/assets.py, dashboard/page_views/monthly_settlement.py, docs/data-model.md, docs/interface-contract.md, docs/project-structure.md, docs/requirements/req-003_account-valuation-history.md, docs/runtime-flow.md, jarca_ledger_mcp/adapters/mcp/server.py, jarca_ledger_mcp/adapters/mcp/tool_contracts.py, jarca_ledger_mcp/adapters/streamlit/accounts_gateway.py, jarca_ledger_mcp/adapters/streamlit/overview_gateway.py, jarca_ledger_mcp/application/__init_.py, jarca_ledger_mcp/application/account_valuation_service.py, jarca_ledger_mcp/application/accounts_write_services.py, jarca_ledger_mcp/application/assets_service.py, jarca_ledger_mcp/application/categorization_services.py, jarca_ledger_mcp/application/cross_transfer_service.py, jarca_ledger_mcp/application/imports_service.py, jarca_ledger_mcp/application/monthly_settlement_service.py, jarca_ledger_mcp/application/reconciliation_service.py, jarca_ledger_mcp/application/review_decision_service.py, jarca_ledger_mcp/application/shared.py, jarca_ledger_mcp/application/system_services.py, jarca_ledger_mcp/application/transaction_report_services.py, jarca_ledger_mcp/application/uncategorized_workbench_service.py, jarca_ledger_mcp/infrastructure/sqlite/__init_.py, jarca_ledger_mcp/infrastructure/sqlite/connection.py, jarca_ledger_mcp/infrastructure/sqlite/migrations.py, jarca_ledger_mcp/infrastructure/sqlite/schema.py, jarca_ledger_mcp/service.py, scripts/ci_fixture_db.py, tests/test_account_valuations.py, tests/test_asset_snapshots.py, tests/test_contract_regression.py, tests/test_dashboard_app.py, tests/test_dashboard_menu_transition.py, tests/test_import_provenance_policy.py, tests/test_issue_12_regressions.py, tests/test_issue_12_review59_account.py, tests/test_issue_12_review59_readonly.py, tests/test_issue_12_review59_reports.py, tests/test_ledger_categories.py, tests/test_requirement_docs.py, tests/test_review_decision_workbench.py, tests/test_seoulpay_xlsx.py, tests/test_service.py, docs/verification/issue-12-review-60/contract-preservation-inventory.json, docs/verification/issue-12-review-60/evidence-manifest.json, docs/verification/issue-12-review-60/evidence-plan.json, docs/verification/issue-12-review-60/final-independent-review.json, docs/verification/issue-12-review-60/finding-matrix.json, docs/verification/issue-12-review-60/red-evidence.json; 전체 changed-file 59개를 source 및 adapter, read-only 전파, schema, 문서 의무와 회귀 또는 구현자 검증 기록으로 대응했다. 구현자 manifest source f25b30c750e191e056814d6131a8b1141949736d는 head의 ancestor이며 전체 source-to-head diff는 evidence-manifest.json 추가뿐이고 실행 입력은 동일하다. 18개 source hash/blob를 대조했고 명령 exit0 및 외부 PDF fixture4개 skip을 확인했다. Reviewer는 changed Python48개 compile-only 및 source/test 대조와 supplemental 함수 관찰만 수행했다. exact-head status는 pending이며 CI 성공이 아니다.
    • 테스트 근거: tests/test_account_valuations.py, tests/test_asset_snapshots.py, tests/test_contract_regression.py, tests/test_dashboard_app.py, tests/test_dashboard_menu_transition.py, tests/test_import_provenance_policy.py, tests/test_issue_12_regressions.py, tests/test_issue_12_review59_account.py, tests/test_issue_12_review59_readonly.py, tests/test_issue_12_review59_reports.py, tests/test_ledger_categories.py, tests/test_requirement_docs.py, tests/test_review_decision_workbench.py, tests/test_seoulpay_xlsx.py, tests/test_service.py
    • 판정 근거: 구현자 실행 기록의 재사용 가능 범위는 전체 diff와 실행 입력 동일성으로 확인했다. 기록 저장 경로와 독립 worker PASS는 새 필수 계약 또는 최종 판정 권위가 아니다. Reviewer가 전체 pytest 또는 browser를 독립 실행했다고 주장하지 않는다.

범위 판정

  • 누락: 대출 평가 기록의 대표 부채 정의 필수 검증이 account write 및 import 후보 생성과 일부 loan purpose 경계에서 우회된다. 일반 balance 등록 보완만으로 전체 기록 계약을 충족하지 못한다.
  • 범위 초과: 없음
  • 명세 모순: 없음

결론

현재 head는 request_changes다. C05와 C06 및 N02와 D03과 D04는 해소됐지만 N01은 후보 생성 및 다른 loan purpose 경계에서 잔여 위반이 확인됐다. 이를 하나의 대출 정의 불변조건 문제로 묶어 최소 보완을 요청한다. 문서 표의 반복 부재를 기능 결함과 같은 강도로 추가하지 않는다. 전체 제품 테스트는 reviewer가 독립 실행하지 않았으며 source 및 named test 검토와 구현자 실행 근거의 revision 재사용 검증으로 판정했다.

## 구현 명세 적합성 검토 - Source Issue: #12 - Pull Request: #13 - Reviewed head: `5e721b0ddd648f3e80f341a3c304d1cc3ca47ee8` - Contract SHA-256: `6d86b591b022fcc722611bfec6d24e54a64216ab6f7c4098f357e25420218818` - Verdict: `request_changes` ### Acceptance criteria 판정 - `C01-history` — `satisfied` - 계약: 평가 계좌 FK, 기준일과 등록일, 대표 금액과 통화와 목적, 출처와 확인 상태, 증빙 식별자, 정정 연결과 사유 및 선택 시간 자료를 이력으로 보존한다. - 구현 근거: jarca_ledger_mcp/application/account_valuation_service.py, jarca_ledger_mcp/infrastructure/sqlite/schema.py, jarca_ledger_mcp/infrastructure/sqlite/migrations.py; schema.py account_valuations와 migrations.py schema12, account_valuation_service.py 127-255는 날짜와 등록시각 및 정정 연결과 선택 지표를 보존한다. tests/test_account_valuations.py의 영속 이력 사례와 named tests를 대조했다. - 테스트 근거: tests/test_account_valuations.py - 판정 근거: 기본 이력 구조는 충족한다. 대출 정의를 누락하는 우회 writer는 N01의 동일 계약 위반으로 별도 판정한다. - `C02-money-metrics` — `satisfied` - 계약: 금액 정밀도와 NULL 및 0을 보존하고 취득원가, 순납입액, 기관 표시 원금 금액과 정의 및 원문 명칭, 손익과 수익률의 계산 기준을 구분한다. 투자 대표 총평가액과 포함 현금 및 원금을 중복 합산하지 않는다. - 구현 근거: jarca_ledger_mcp/application/account_valuation_service.py, jarca_ledger_mcp/infrastructure/sqlite/schema.py, docs/data-model.md, docs/requirements/req-003_account-valuation-history.md; data-model.md 33-61과 account_valuation_service.py 16-22,160-180의 물리 필드 의미를 대조했다. test_valuation_round_trip_preserves_null_zero_and_physical_amount_mapping은 investment principal 0 및 interest/fee NULL, loan principal/interest/fee 반환을 11-33행에서 호출하고 확인한다. - 테스트 근거: tests/test_issue_12_review59_account.py, tests/test_issue_12_regressions.py - 판정 근거: NULL과 0 및 투자 기관 표시 원금과 대출 잔여 원금의 반환 의미가 유지된다. 대표값과 구성 금액은 중복 합산하지 않는다. - `N01-loan-balance-definition` — `unsatisfied` - 계약: 대출 평가 기록마다 대표 부채가 원금만인지 원금과 이자 및 수수료인지 필수로 명시하고 기본값으로 추정하지 않는다. 목적 alias가 필수 정의 계약을 우회하지 않는다. - 구현 근거: jarca_ledger_mcp/application/account_valuation_service.py, docs/requirements/req-003_account-valuation-history.md, jarca_ledger_mcp/application/accounts_write_services.py, jarca_ledger_mcp/application/imports_service.py, docs/data-model.md; 일반 등록의 loan balance 정의 누락은 account_valuation_service.py 188-195에서 차단한다. 그러나 record_account_valuation_candidate의 93-124행은 currency만 읽고 account type을 확인하지 않으며 정의 컬럼 없이 balance 이력을 INSERT한다. accounts_write_services.py 5-14,17-33의 날짜 있는 loan 계좌 생성 및 수정과 imports_service.py 37-41,96-100 경로가 이를 호출한다. 또한 일반 등록에서 loan 계좌의 cash_balance 또는 total_value는 188-195행 정의 검사 대상이 아니며 84-87행은 해당 목적에 정의 전달을 금지한다. test_loan_balance_requires_representative_liability_definition은 일반 register balance만 호출한다. - 테스트 근거: tests/test_issue_12_regressions.py, tests/test_issue_12_review59_account.py, tests/test_account_valuation_edge_contracts.py - 판정 근거: 승인 Discovery 19와 56행 및 data-model 61행은 확인 상태와 무관하게 대출 평가 기록마다 대표 정의를 요구한다. 일반 balance 등록은 해소됐지만 후보 writer 및 다른 허용 purpose에서 정의 없는 loan 평가 기록이 저장될 수 있다. 정의를 추정하지 말고 모든 loan 이력 생성 경로에서 같은 필수 조건을 적용하거나 근거 없는 후보 생성 및 부적합 purpose를 차단해야 한다. account write 또는 import의 기존 현재 캐시 호환은 보존하면서 이 우회 경계를 회귀로 확인하면 된다. 현재 후보는 unverified라 즉시 합계에 포함되지 않지만 영속 이력의 필수 정의 계약 위반은 남는다. - `C03-selection` — `satisfied` - 계약: 계좌와 통화 및 평가 목적별 유효 자료를 선택한다. exact는 당일 확인 자료만, as_of는 기준일 이하 최신 확인 자료만 사용한다. 미래 자료는 제외하고 미확인 후보는 확인 자료를 대체하거나 합산하지 않는다. 실제 기준일과 경과 일수 및 이월 상태를 반환한다. - 구현 근거: jarca_ledger_mcp/application/account_valuation_service.py, jarca_ledger_mcp/application/assets_service.py; account_valuation_service.py의 select_account_valuation과 assets_service.py의 공통 계좌 선택은 verified leaf, 통화 및 purpose, exact/as_of 날짜와 미래 제외를 유지한다. test_select_exact_and_as_of_excludes_unverified_and_reports_carry_forward와 issue12 regression source를 대조했다. - 테스트 근거: tests/test_account_valuations.py, tests/test_issue_12_regressions.py - 판정 근거: 확인 자료 선택 및 미확인 후보 비합산은 충족한다. N01의 후보 이력 정의 누락을 현재 합산 오류로 과장하지 않는다. - `C04-correction-validation` — `satisfied` - 계약: 평가 정정은 append-only로 대상과 사유를 연결하며 다른 계좌, 통화, 목적을 참조하는 정정과 순환 및 동일 유효본의 동시 분기를 차단한다. - 구현 근거: jarca_ledger_mcp/application/account_valuation_service.py, jarca_ledger_mcp/infrastructure/sqlite/schema.py; account_valuation_service.py 196-220,correct_account_valuation의 부모 scope 및 사유 검증을 대조했다. test_direct_correction_requires_matching_existing_parent_and_reason 및 test_correction_rejects_currency_and_kind_override_but_preserves_valid_overrides가 실패와 원본 유지 경계를 포함한다. - 테스트 근거: tests/test_issue_12_review59_account.py, tests/test_account_valuations.py, tests/test_issue_12_regressions.py - 판정 근거: 다른 계좌 또는 통화와 목적 정정, 사유 누락 및 분기와 순환 방지는 유지된다. 동일 정정 재시도는 C06에서 새 구현을 확인했다. - `C05-current-import` — `satisfied` - 계약: 뒤늦은 과거 자료 등록으로 최신 표시값을 과거로 되돌리지 않는다. 기존 계좌 수정과 import의 최신 캐시 및 새 이력 권위를 연결하며 동기화 시각을 실제 평가일로 오인하지 않는다. - 구현 근거: jarca_ledger_mcp/application/imports_service.py, jarca_ledger_mcp/application/assets_service.py, jarca_ledger_mcp/application/accounts_write_services.py; imports_service.py 43-49는 last_balance_basis_date를 비교하고 last_synced_at은 실행시각으로만 저장한다. accounts_write_services.py 5-14,25-33,41-81은 명시된 basis만 후보로 기록하고 늦은 과거 자료의 캐시 rollback을 막는다. test_import_current_balance_authority.py 37-105는 연속 늦은 import, 기준일 미상 write 및 unknown legacy provenance를 실제 호출과 assertion으로 확인한다. Dashboard 및 MCP 전달은 test_account_basis_public_consumers.py 13-47과 대조했다. - 테스트 근거: tests/test_issue_12_review59_account.py, tests/test_import_provenance_policy.py, tests/test_import_current_balance_authority.py, tests/test_account_basis_public_consumers.py - 판정 근거: 이전 C05의 근거일과 동기화시각 혼용은 해소됐다. 실제 평가일을 별도 필드로 비교하고 전달하며 sync-only 입력은 역사 근거로 추정하지 않는다. - `C06-idempotency` — `satisfied` - 계약: 동일 증빙 또는 idempotency 재입력은 동일 기록을 재사용하며 같은 키의 다른 payload는 충돌이다. 동시 정정의 분기를 차단하고 UNIQUE 계좌 및 기준일 하나로 정정 추가를 막지 않는다. - 구현 근거: jarca_ledger_mcp/application/account_valuation_service.py, jarca_ledger_mcp/infrastructure/sqlite/schema.py, jarca_ledger_mcp/infrastructure/sqlite/migrations.py, jarca_ledger_mcp/application/accounts_write_services.py, jarca_ledger_mcp/application/imports_service.py; correct_account_valuation은 전체 effective payload와 명시 key 또는 기존 child를 비교한다. test_account_valuation_edge_contracts.py 42-93은 keyless 동일 정정 재사용 및 amount/reason/source 변경 충돌과 row count를 확인한다. test_issue_12_review59_account.py 156-180은 명시 key 재시도도 포함하며 test_issue_12_regressions.py 214-232는 보존 payload 변경을 확인한다. - 테스트 근거: tests/test_issue_12_review59_account.py, tests/test_account_valuations.py, tests/test_issue_12_regressions.py, tests/test_account_valuation_edge_contracts.py - 판정 근거: 이전 C06은 해소됐다. 이전 리뷰의 해당 테스트가 첫 정정만 확인한다는 설명은 오류이며 명시 key 재시도도 이미 검증하던 테스트였다. 이번 변경으로 keyless 증빙 replay 경계도 닫혔다. - `C07-close-immutability` — `satisfied` - 계약: 기존 asset_snapshots와 correction run을 보존하고 평가 정정 및 거래 추가로 기존 마감을 자동 변경하지 않는다. 동일 기준일 재마감은 사유와 이전 run 연결을 가진 새 버전을 원자적으로 추가한다. - 구현 근거: jarca_ledger_mcp/application/assets_service.py, jarca_ledger_mcp/infrastructure/sqlite/schema.py, jarca_ledger_mcp/infrastructure/sqlite/migrations.py; assets_service.py의 원자적 append-only close와 correction run 저장을 immutable run lookup 변경 및 기존 snapshot tests와 대조했다. 평가 변경은 기존 저장 run을 갱신하지 않는다. - 테스트 근거: tests/test_asset_snapshots.py, tests/test_issue_12_regressions.py - 판정 근거: 기존 마감 불변성과 사유를 가진 명시적 새 마감 버전 생성이 유지된다. - `N02-close-replay-run-binding` — `satisfied` - 계약: 마감 버전의 근거는 불변이며 동일 idempotency 요청은 원래 기록을 재사용한다. 재마감으로 과거 run 응답 및 evidence를 변경하지 않는다. - 구현 근거: jarca_ledger_mcp/application/assets_service.py, docs/interface-contract.md; assets_service.py 262-292의 _snapshot_rows_for_run과 659-700은 기존 idempotency run ID로 rows 및 metadata 전체를 재구성한다. test_asset_snapshot_idempotency.py 8-82는 A close, B correction, A replay 후 response equality와 모든 근거 및 row count를 확인하고 85-132는 zero-row run을 확인한다. - 테스트 근거: tests/test_issue_12_review59_reports.py, tests/test_issue_12_regressions.py, tests/test_asset_snapshot_idempotency.py - 판정 근거: 이전 N02는 해소됐다. latest run 자료와 이전 run ID를 혼합하지 않으며 동일 persisted run의 approval/correction/warnings/provenance 및 snapshot IDs를 반환한다. - `C08-approved-conditional` — `satisfied` - 계약: 완전한 exact 마감, 미완료 초안, 별도 승인된 조건부 마감을 구분한다. 승인 전 누락 및 이월은 미완료 초안이고 승인 후에도 누락 제외 및 확인된 과거값 이월만 허용한다. 미확인, 미래, 기준일 미상 금액은 승인으로도 합산하지 않으며 적용과 제외와 이월 및 승인자와 시각과 사유와 근거를 고정한다. - 구현 근거: jarca_ledger_mcp/application/assets_service.py, jarca_ledger_mcp/infrastructure/sqlite/schema.py, dashboard/page_views/assets.py; 새 head의 jarca_ledger_mcp/application/assets_service.py, jarca_ledger_mcp/infrastructure/sqlite/schema.py, dashboard/page_views/assets.py와 tests/test_issue_12_review59_reports.py, tests/test_issue_12_regressions.py, tests/test_asset_snapshots.py를 승인 계약 및 base-to-head 변경에 대응했다. 이전 충족 의미를 유지하는 source와 named test를 현재 immutable snapshot에서 대조했으며 필수 문서는 document-obligations.json으로 구조와 의미를 분리했다. - 테스트 근거: tests/test_issue_12_review59_reports.py, tests/test_issue_12_regressions.py, tests/test_asset_snapshots.py - 판정 근거: 승인 계약은 현재 source 및 문서와 회귀 검증 내용에서 보존된다. 구현자 명령 기록은 별도 source revision의 실행 결과이며 reviewer 독립 실행이나 CI 성공으로 표현하지 않는다. - `C09-reconciliation` — `satisfied` - 계약: 외부 확인값과 장부 계산값을 분리하고 검증된 시작잔고, 기준시점, 거래 포함 범위와 계산 완전성을 표시한다. 거래 없는 수동 투자 계좌의 대사 불가 및 거래 미수입과 평가 수동 관리 상태를 구분하고 가짜 거래를 만들지 않는다. 대사도 공통 평가 근거와 대출 대표 정의를 사용한다. - 구현 근거: jarca_ledger_mcp/application/reconciliation_service.py, jarca_ledger_mcp/application/account_valuation_service.py, jarca_ledger_mcp/application/monthly_settlement_service.py; 새 head의 jarca_ledger_mcp/application/reconciliation_service.py, jarca_ledger_mcp/application/account_valuation_service.py, jarca_ledger_mcp/application/monthly_settlement_service.py와 tests/test_issue_12_review59_reports.py, tests/test_issue_12_regressions.py, tests/test_service.py를 승인 계약 및 base-to-head 변경에 대응했다. 이전 충족 의미를 유지하는 source와 named test를 현재 immutable snapshot에서 대조했으며 필수 문서는 document-obligations.json으로 구조와 의미를 분리했다. - 테스트 근거: tests/test_issue_12_review59_reports.py, tests/test_issue_12_regressions.py, tests/test_service.py - 판정 근거: 승인 계약은 현재 source 및 문서와 회귀 검증 내용에서 보존된다. 구현자 명령 기록은 별도 source revision의 실행 결과이며 reviewer 독립 실행이나 CI 성공으로 표현하지 않는다. - `C10-report-monthly-evidence` — `satisfied` - 계약: MCP와 Dashboard 및 월정산 보고에서 같은 기준일과 선택 근거 및 실제 평가일, 경과 일수, 확인 상태, 누락과 미확인 및 이월 경고, 마감 버전 및 조건부 승인 근거를 일관되게 전달한다. - 구현 근거: jarca_ledger_mcp/application/assets_service.py, jarca_ledger_mcp/application/monthly_settlement_service.py, dashboard/page_views/monthly_settlement.py, dashboard/page_views/accounts.py; 새 head의 jarca_ledger_mcp/application/assets_service.py, jarca_ledger_mcp/application/monthly_settlement_service.py, dashboard/page_views/monthly_settlement.py, dashboard/page_views/accounts.py와 tests/test_issue_12_review59_reports.py, tests/test_issue_12_regressions.py, tests/test_service.py를 승인 계약 및 base-to-head 변경에 대응했다. 이전 충족 의미를 유지하는 source와 named test를 현재 immutable snapshot에서 대조했으며 필수 문서는 document-obligations.json으로 구조와 의미를 분리했다. - 테스트 근거: tests/test_issue_12_review59_reports.py, tests/test_issue_12_regressions.py, tests/test_service.py - 판정 근거: 승인 계약은 현재 source 및 문서와 회귀 검증 내용에서 보존된다. 구현자 명령 기록은 별도 source revision의 실행 결과이며 reviewer 독립 실행이나 CI 성공으로 표현하지 않는다. - `C11-adapter-structure` — `satisfied` - 계약: MCP와 Streamlit gateway는 공통 application을 사용하고 기존 공개 호출명과 기존 인수 및 success와 실패 error_code 및 error envelope를 가능한 한 유지한다. 새 Dashboard 인증 또는 MCP 인증을 도입하지 않는다. - 구현 근거: jarca_ledger_mcp/adapters/mcp/server.py, jarca_ledger_mcp/adapters/mcp/tool_contracts.py, jarca_ledger_mcp/adapters/streamlit/accounts_gateway.py, jarca_ledger_mcp/application/__init__.py, jarca_ledger_mcp/service.py, dashboard/page_views/accounts.py, dashboard/page_views/assets.py, dashboard/page_views/monthly_settlement.py; 새 head의 jarca_ledger_mcp/adapters/mcp/server.py, jarca_ledger_mcp/adapters/mcp/tool_contracts.py, jarca_ledger_mcp/adapters/streamlit/accounts_gateway.py, jarca_ledger_mcp/application/__init__.py, jarca_ledger_mcp/service.py, dashboard/page_views/accounts.py, dashboard/page_views/assets.py, dashboard/page_views/monthly_settlement.py와 tests/test_contract_regression.py, tests/test_issue_12_regressions.py를 승인 계약 및 base-to-head 변경에 대응했다. 이전 충족 의미를 유지하는 source와 named test를 현재 immutable snapshot에서 대조했으며 필수 문서는 document-obligations.json으로 구조와 의미를 분리했다. - 테스트 근거: tests/test_contract_regression.py, tests/test_issue_12_regressions.py - 판정 근거: 승인 계약은 현재 source 및 문서와 회귀 검증 내용에서 보존된다. 구현자 명령 기록은 별도 source revision의 실행 결과이며 reviewer 독립 실행이나 CI 성공으로 표현하지 않는다. - `C12-migration-legacy` — `satisfied` - 계약: schema 11의 기존 데이터와 마감 및 개인정보를 보존하고 additive하고 idempotent한 migration을 제공한다. 기준일 증거 없는 값을 임의 월말로 소급하거나 legacy snapshot에 valuation_id를 추측하여 생성하지 않는다. - 구현 근거: jarca_ledger_mcp/infrastructure/sqlite/schema.py, jarca_ledger_mcp/infrastructure/sqlite/migrations.py, jarca_ledger_mcp/application/assets_service.py; 새 head의 jarca_ledger_mcp/infrastructure/sqlite/schema.py, jarca_ledger_mcp/infrastructure/sqlite/migrations.py, jarca_ledger_mcp/application/assets_service.py와 tests/test_account_valuations.py, tests/test_issue_12_regressions.py, tests/test_ledger_categories.py, tests/test_review_decision_workbench.py를 승인 계약 및 base-to-head 변경에 대응했다. 이전 충족 의미를 유지하는 source와 named test를 현재 immutable snapshot에서 대조했으며 필수 문서는 document-obligations.json으로 구조와 의미를 분리했다. - 테스트 근거: tests/test_account_valuations.py, tests/test_issue_12_regressions.py, tests/test_ledger_categories.py, tests/test_review_decision_workbench.py - 판정 근거: 승인 계약은 현재 source 및 문서와 회귀 검증 내용에서 보존된다. 구현자 명령 기록은 별도 source revision의 실행 결과이며 reviewer 독립 실행이나 CI 성공으로 표현하지 않는다. - `C13-read-only` — `satisfied` - 계약: preview와 조회 및 Dashboard 렌더링은 금융 쓰기를 실행하지 않는다. 명시적 등록, 정정, 승인 close 및 import 제출만 변경을 수행하고 실패 시 부분 쓰기를 남기지 않는다. - 구현 근거: jarca_ledger_mcp/infrastructure/sqlite/connection.py, jarca_ledger_mcp/application/shared.py, jarca_ledger_mcp/application/system_services.py, jarca_ledger_mcp/application/account_valuation_service.py, jarca_ledger_mcp/application/assets_service.py; 새 head의 jarca_ledger_mcp/infrastructure/sqlite/connection.py, jarca_ledger_mcp/application/shared.py, jarca_ledger_mcp/application/system_services.py, jarca_ledger_mcp/application/account_valuation_service.py, jarca_ledger_mcp/application/assets_service.py와 tests/test_issue_12_review59_readonly.py, tests/test_dashboard_app.py, tests/test_dashboard_menu_transition.py를 승인 계약 및 base-to-head 변경에 대응했다. 이전 충족 의미를 유지하는 source와 named test를 현재 immutable snapshot에서 대조했으며 필수 문서는 document-obligations.json으로 구조와 의미를 분리했다. - 테스트 근거: tests/test_issue_12_review59_readonly.py, tests/test_dashboard_app.py, tests/test_dashboard_menu_transition.py - 판정 근거: 승인 계약은 현재 source 및 문서와 회귀 검증 내용에서 보존된다. 구현자 명령 기록은 별도 source revision의 실행 결과이며 reviewer 독립 실행이나 CI 성공으로 표현하지 않는다. - `C14-auth-menu-preservation` — `satisfied` - 계약: Dashboard 인증은 DB보다 먼저이며 REQ-001의 cookie와 logout 및 REQ-002의 메뉴 label과 order, shell, query, error와 retry 및 명시적 금융 쓰기 계약을 유지한다. - 구현 근거: dashboard/app.py, dashboard/page_views/accounts.py, dashboard/page_views/assets.py, dashboard/page_views/monthly_settlement.py, docs/interface-contract.md, docs/project-structure.md, docs/runtime-flow.md; 새 head의 dashboard/app.py, dashboard/page_views/accounts.py, dashboard/page_views/assets.py, dashboard/page_views/monthly_settlement.py, docs/interface-contract.md, docs/project-structure.md, docs/runtime-flow.md와 tests/test_dashboard_menu_transition.py, tests/test_dashboard_app.py를 승인 계약 및 base-to-head 변경에 대응했다. 이전 충족 의미를 유지하는 source와 named test를 현재 immutable snapshot에서 대조했으며 필수 문서는 document-obligations.json으로 구조와 의미를 분리했다. - 테스트 근거: tests/test_dashboard_menu_transition.py, tests/test_dashboard_app.py - 판정 근거: 승인 계약은 현재 source 및 문서와 회귀 검증 내용에서 보존된다. 구현자 명령 기록은 별도 source revision의 실행 결과이며 reviewer 독립 실행이나 CI 성공으로 표현하지 않는다. - `C15-exclusions-privacy` — `satisfied` - 계약: 증권사 자동 연동, 정확한 성과 또는 환율 엔진, 새 인증, 별도 월정산 제품, 거래 추론 및 기존 데이터 자동 재작성과 수기 비계좌 자산 전체 이력 재설계를 추가하지 않는다. 실제 계좌 및 금융 증빙과 credential을 로그와 문서 및 테스트에 기록하지 않는다. - 구현 근거: jarca_ledger_mcp/application/assets_service.py, jarca_ledger_mcp/application/account_valuation_service.py, jarca_ledger_mcp/application/imports_service.py, jarca_ledger_mcp/application/reconciliation_service.py, jarca_ledger_mcp/infrastructure/sqlite/schema.py, jarca_ledger_mcp/infrastructure/sqlite/migrations.py; 새 head의 jarca_ledger_mcp/application/assets_service.py, jarca_ledger_mcp/application/account_valuation_service.py, jarca_ledger_mcp/application/imports_service.py, jarca_ledger_mcp/application/reconciliation_service.py, jarca_ledger_mcp/infrastructure/sqlite/schema.py, jarca_ledger_mcp/infrastructure/sqlite/migrations.py와 tests/test_issue_12_review59_reports.py, tests/test_issue_12_regressions.py, scripts/ci_fixture_db.py를 승인 계약 및 base-to-head 변경에 대응했다. 이전 충족 의미를 유지하는 source와 named test를 현재 immutable snapshot에서 대조했으며 필수 문서는 document-obligations.json으로 구조와 의미를 분리했다. - 테스트 근거: tests/test_issue_12_review59_reports.py, tests/test_issue_12_regressions.py, scripts/ci_fixture_db.py - 판정 근거: 승인 계약은 현재 source 및 문서와 회귀 검증 내용에서 보존된다. 구현자 명령 기록은 별도 source revision의 실행 결과이며 reviewer 독립 실행이나 CI 성공으로 표현하지 않는다. - `D01-requirement-structure` — `satisfied` - 계약: 신규 REQ-003을 배정 경로와 제목으로 작성하며 trusted harness README와 TEMPLATE의 JSON metadata, 연속 요구사항 및 AC, 필수 섹션, 판정 기준과 검증 및 검증 분류의 수준과 백엔드와 케이스 및 상태 불변조건을 충족한다. 초기 PR은 미정이며 PR 생성 후 실제 번호를 추적한다. - 구현 근거: docs/requirements/req-003_account-valuation-history.md; REQ-003 metadata 및 51-174행 필수 섹션, 187-297행 전체 AC10개를 trusted README와 TEMPLATE에 대조했다. 신규 문서이며 pinned base에는 같은 파일이 없다. Source Issue12와 구현 PR13 및 requirement lifecycle은 trusted README43-45,83-92 규칙과 일치한다. - 테스트 근거: tests/test_requirement_docs.py - 판정 근거: 신규 금융 기능 REQ-003의 ID, exact path, title, metadata, 필수 구조 및 전체 AC의 검증 분류와 추적성은 충족한다. 문서 approved lifecycle을 PR 구현 승인으로 오인하지 않는다. - `D02-requirement-semantics` — `satisfied` - 계약: 요구사항에는 평가 근거와 지표 정의, 선택과 future 제외, 정정 및 idempotency 충돌, 대사 완전성, current 및 import 연계, 마감 상태와 불변성과 승인, shared adapter 및 인증, migration과 legacy를 소스 및 테스트에 대응한다. 모든 승인된 경계와 회귀 사례를 인수 기준으로 내린다. - 구현 근거: docs/requirements/req-003_account-valuation-history.md; 새 head의 docs/requirements/req-003_account-valuation-history.md와 tests/test_account_valuations.py, tests/test_asset_snapshots.py, tests/test_issue_12_regressions.py, tests/test_requirement_docs.py를 승인 계약 및 base-to-head 변경에 대응했다. 이전 충족 의미를 유지하는 source와 named test를 현재 immutable snapshot에서 대조했으며 필수 문서는 document-obligations.json으로 구조와 의미를 분리했다. REQ-003 전체 검증 참조 13개를 exact head Git tree와 AST symbol로 확인했으며 모두 존재한다. 변경되지 않은 tests/test_mcp_http_runtime.py와 tests/test_dashboard_authentication_app.py도 실제 blob을 읽어 configuration 및 fail-closed auth-before-DB 사례를 대조했다. - 테스트 근거: tests/test_account_valuations.py, tests/test_asset_snapshots.py, tests/test_issue_12_regressions.py, tests/test_requirement_docs.py, tests/test_mcp_http_runtime.py, tests/test_dashboard_authentication_app.py - 판정 근거: 승인 계약은 현재 source 및 문서와 회귀 검증 내용에서 보존된다. 구현자 명령 기록은 별도 source revision의 실행 결과이며 reviewer 독립 실행이나 CI 성공으로 표현하지 않는다. - `D03-data-model` — `satisfied` - 계약: 신규 데이터 모델은 기존 entities 및 valuation과 마감의 관계, FK와 날짜 및 정확한 금액과 NULL 및 0과 선택 지표 및 대출 필수 정의, 계좌와 통화 및 목적과 기준일의 선택 및 index와 단일 유효 정정본, 고정 적용 분류 및 출처와 상태와 누락 및 이월 및 승인 버전, 분리된 정정과 schema11 이관 및 미상 날짜와 legacy 및 최신 캐시 동기화 책임을 정의한다. - 구현 근거: docs/data-model.md; data-model.md 33-61,82-117,123-160은 필드와 금액 의미, snapshot 근거 고정 및 상태, last_balance_basis_date와 sync시각 분리, 역사 authority 및 캐시 writer, 과거 rollback 금지와 additive legacy unknown-basis를 명시한다. test_valuation_contract_docs.py 11-25와 직접 내용을 대조했다. - 테스트 근거: tests/test_account_valuations.py, tests/test_asset_snapshots.py, tests/test_issue_12_regressions.py, tests/test_valuation_contract_docs.py - 판정 근거: 이전 D03의 캐시 책임 및 실제 평가일 계약 누락은 해소됐다. 대출 필수 정의 문서는 충족하지만 구현 후보 writer 위반은 N01로 분리한다. - `D04-interface-contract` — `satisfied` - 계약: 인터페이스 문서는 기존 auth 및 메뉴를 보존하고 평가 등록 및 조회 및 정정의 모든 입력과 유효본 및 원금 정의 출력, report 및 preview/close 및 월정산과 대사와 current API의 공통 선택, exact 기본과 실제 날짜 및 age 및 이월과 누락 및 미확인과 출처 및 버전과 승인 출력을 정의한다. 잘못된 입력과 scope 및 충돌과 부족 근거는 무변경 실패이며 기존 envelope와 required keys 및 의미 변경 정책을 명시한다. - 구현 근거: docs/interface-contract.md, docs/data-model.md; interface-contract.md 277-299는 valuation 출력이 persisted rows임을 정의하고 336-345는 enum 및 loan 조건부 정의, no-write 오류와 캐시 basis를 명시한다. 401-415는 exact 물리 인수와 envelope를 열거한다. data-model.md 33-61은 반환되는 row의 principal 투자/대출 의미와 interest/fee 및 NULL/0를 정의하며 test_issue_12_review59_account.py 11-33은 실제 반환 필드를 확인한다. 425-435는 close/run replay와 provenance 및 redaction을 정의한다. - 테스트 근거: tests/test_account_valuations.py, tests/test_issue_12_regressions.py, tests/test_contract_regression.py, tests/test_valuation_contract_docs.py, tests/test_issue_12_review59_account.py - 판정 근거: 이전 D04의 enum 및 loan 정의 조건은 해소됐다. persisted row 출력과 exact 필드 및 데이터 모델의 의미를 함께 읽으면 원금 반환 의미가 보존된다. 별도 response 표나 반복 기재 부재만으로 새 문서 변경을 요구하지 않는다. 구현 writer의 필수 정의 위반은 N01에서 판정한다. - `D05-project-structure` — `satisfied` - 계약: 프로젝트 구조 문서는 기존 source와 test 및 evidence를 보존하고 SQLite schema와 migrations, application의 assets와 account writes 및 import와 reconciliation 및 monthly 책임, 공개 facade와 MCP 및 Streamlit과 기존 세 화면 및 tests를 exact 경로로 대응한다. adapter에서 선택 정책을 복제하지 않고 대출 정의와 verified as_of 및 conditional 승인 경계를 shared application에 배치한다. - 구현 근거: docs/project-structure.md; 새 head의 docs/project-structure.md와 tests/test_requirement_docs.py를 승인 계약 및 base-to-head 변경에 대응했다. 이전 충족 의미를 유지하는 source와 named test를 현재 immutable snapshot에서 대조했으며 필수 문서는 document-obligations.json으로 구조와 의미를 분리했다. 현재 문서 122-164,171-212행의 공통 application ownership, canonical adapter 경계, 세 선택 정책 및 실패 무변경을 의무표에 대응했다. 기존 인증과 메뉴 계약의 base 본문은 byte-preserved다. - 테스트 근거: tests/test_requirement_docs.py - 판정 근거: 승인 계약은 현재 source 및 문서와 회귀 검증 내용에서 보존된다. 구현자 명령 기록은 별도 source revision의 실행 결과이며 reviewer 독립 실행이나 CI 성공으로 표현하지 않는다. - `D06-runtime-flow` — `satisfied` - 계약: 런타임 문서는 auth 및 메뉴를 보존하고 register/correct의 증빙 및 scope 검증과 append 및 유효본 확인 및 최신 캐시 동기화를 단일 트랜잭션으로 설명한다. 날짜 및 정책과 통화 및 대표 합산과 경고 read, preview 후 명시적 approval 및 원자적 freeze, reasoned reclose, 같은 근거의 monthly 및 대사, import와 이관 trigger 및 실패복구, retry와 concurrency 및 preview drift 재검증과 무부분쓰기, 비민감 valuation/run 상관 신호를 정의한다. - 구현 근거: docs/runtime-flow.md; 새 head의 docs/runtime-flow.md와 tests/test_account_valuations.py, tests/test_asset_snapshots.py, tests/test_issue_12_regressions.py를 승인 계약 및 base-to-head 변경에 대응했다. 이전 충족 의미를 유지하는 source와 named test를 현재 immutable snapshot에서 대조했으며 필수 문서는 document-obligations.json으로 구조와 의미를 분리했다. 현재 문서 147-193,221-241행의 공통 application ownership, canonical adapter 경계, 세 선택 정책 및 실패 무변경을 의무표에 대응했다. 기존 인증과 메뉴 계약의 base 본문은 byte-preserved다. - 테스트 근거: tests/test_account_valuations.py, tests/test_asset_snapshots.py, tests/test_issue_12_regressions.py - 판정 근거: 승인 계약은 현재 source 및 문서와 회귀 검증 내용에서 보존된다. 구현자 명령 기록은 별도 source revision의 실행 결과이며 reviewer 독립 실행이나 CI 성공으로 표현하지 않는다. - `C16-supporting-evidence-scope` — `satisfied` - 계약: 모든 changed file은 승인된 기능과 필수 supporting change 또는 테스트 evidence로 설명되고 기존 requirement ID를 임의 갱신하거나 범위 밖 제품 및 설정을 변경하지 않는다. - 구현 근거: dashboard/app.py, dashboard/page_views/accounts.py, dashboard/page_views/assets.py, dashboard/page_views/monthly_settlement.py, docs/data-model.md, docs/interface-contract.md, docs/project-structure.md, docs/requirements/req-003_account-valuation-history.md, docs/runtime-flow.md, jarca_ledger_mcp/adapters/mcp/server.py, jarca_ledger_mcp/adapters/mcp/tool_contracts.py, jarca_ledger_mcp/adapters/streamlit/accounts_gateway.py, jarca_ledger_mcp/adapters/streamlit/overview_gateway.py, jarca_ledger_mcp/application/__init__.py, jarca_ledger_mcp/application/account_valuation_service.py, jarca_ledger_mcp/application/accounts_write_services.py, jarca_ledger_mcp/application/assets_service.py, jarca_ledger_mcp/application/categorization_services.py, jarca_ledger_mcp/application/cross_transfer_service.py, jarca_ledger_mcp/application/imports_service.py, jarca_ledger_mcp/application/monthly_settlement_service.py, jarca_ledger_mcp/application/reconciliation_service.py, jarca_ledger_mcp/application/review_decision_service.py, jarca_ledger_mcp/application/shared.py, jarca_ledger_mcp/application/system_services.py, jarca_ledger_mcp/application/transaction_report_services.py, jarca_ledger_mcp/application/uncategorized_workbench_service.py, jarca_ledger_mcp/infrastructure/sqlite/__init__.py, jarca_ledger_mcp/infrastructure/sqlite/connection.py, jarca_ledger_mcp/infrastructure/sqlite/migrations.py, jarca_ledger_mcp/infrastructure/sqlite/schema.py, jarca_ledger_mcp/service.py, scripts/ci_fixture_db.py, tests/test_account_valuations.py, tests/test_asset_snapshots.py, tests/test_contract_regression.py, tests/test_dashboard_app.py, tests/test_dashboard_menu_transition.py, tests/test_import_provenance_policy.py, tests/test_issue_12_regressions.py, tests/test_issue_12_review59_account.py, tests/test_issue_12_review59_readonly.py, tests/test_issue_12_review59_reports.py, tests/test_ledger_categories.py, tests/test_requirement_docs.py, tests/test_review_decision_workbench.py, tests/test_seoulpay_xlsx.py, tests/test_service.py, docs/verification/issue-12-review-60/contract-preservation-inventory.json, docs/verification/issue-12-review-60/evidence-manifest.json, docs/verification/issue-12-review-60/evidence-plan.json, docs/verification/issue-12-review-60/final-independent-review.json, docs/verification/issue-12-review-60/finding-matrix.json, docs/verification/issue-12-review-60/red-evidence.json; 전체 changed-file 59개를 source 및 adapter, read-only 전파, schema, 문서 의무와 회귀 또는 구현자 검증 기록으로 대응했다. 구현자 manifest source f25b30c750e191e056814d6131a8b1141949736d는 head의 ancestor이며 전체 source-to-head diff는 evidence-manifest.json 추가뿐이고 실행 입력은 동일하다. 18개 source hash/blob를 대조했고 명령 exit0 및 외부 PDF fixture4개 skip을 확인했다. Reviewer는 changed Python48개 compile-only 및 source/test 대조와 supplemental 함수 관찰만 수행했다. exact-head status는 pending이며 CI 성공이 아니다. - 테스트 근거: tests/test_account_valuations.py, tests/test_asset_snapshots.py, tests/test_contract_regression.py, tests/test_dashboard_app.py, tests/test_dashboard_menu_transition.py, tests/test_import_provenance_policy.py, tests/test_issue_12_regressions.py, tests/test_issue_12_review59_account.py, tests/test_issue_12_review59_readonly.py, tests/test_issue_12_review59_reports.py, tests/test_ledger_categories.py, tests/test_requirement_docs.py, tests/test_review_decision_workbench.py, tests/test_seoulpay_xlsx.py, tests/test_service.py - 판정 근거: 구현자 실행 기록의 재사용 가능 범위는 전체 diff와 실행 입력 동일성으로 확인했다. 기록 저장 경로와 독립 worker PASS는 새 필수 계약 또는 최종 판정 권위가 아니다. Reviewer가 전체 pytest 또는 browser를 독립 실행했다고 주장하지 않는다. ### 범위 판정 - 누락: 대출 평가 기록의 대표 부채 정의 필수 검증이 account write 및 import 후보 생성과 일부 loan purpose 경계에서 우회된다. 일반 balance 등록 보완만으로 전체 기록 계약을 충족하지 못한다. - 범위 초과: 없음 - 명세 모순: 없음 ### 결론 현재 head는 request_changes다. C05와 C06 및 N02와 D03과 D04는 해소됐지만 N01은 후보 생성 및 다른 loan purpose 경계에서 잔여 위반이 확인됐다. 이를 하나의 대출 정의 불변조건 문제로 묶어 최소 보완을 요청한다. 문서 표의 반복 부재를 기능 결함과 같은 강도로 추가하지 않는다. 전체 제품 테스트는 reviewer가 독립 실행하지 않았으며 source 및 named test 검토와 구현자 실행 근거의 revision 재사용 검증으로 판정했다. <!-- gitea-agent:implementation-spec-review/v1 owner=jsfamily repository=jarca-ledger-mcp issue=12 pr=13 head=5e721b0ddd648f3e80f341a3c304d1cc3ca47ee8 contract-sha256=6d86b591b022fcc722611bfec6d24e54a64216ab6f7c4098f357e25420218818 result-sha256=9b909e097e6284cab072802c5e860eabfcb4acbb74bcec7bf49a22cf2327093f correlation=26add7b083e2759a8f8fc44d9a7c8dbf5aac4a4e0eb6d1324c45bfc16386807e -->
gitea-impl-agent added 4 commits 2026-10-07 04:25:13 +00:00
gitea-spec-agent approved these changes 2026-10-07 06:56:34 +00:00
Dismissed
gitea-spec-agent left a comment
Owner

구현 명세 적합성 검토

Acceptance criteria 판정

  • C01-history — satisfied

    • 계약: 평가 계좌 FK, 기준일과 등록일, 대표 금액과 통화와 목적, 출처와 확인 상태, 증빙 식별자, 정정 연결과 사유 및 선택 시간 자료를 이력으로 보존한다.
    • 구현 근거: jarca_ledger_mcp/application/account_valuation_service.py, jarca_ledger_mcp/infrastructure/sqlite/schema.py, jarca_ledger_mcp/infrastructure/sqlite/migrations.py; 현재 고정 head의 구현과 named test를 해당 승인 계약에 대조했다. Source 위치: jarca_ledger_mcp/application/account_valuation_service.py _valuation 25-26; jarca_ledger_mcp/application/account_valuation_service.py record_account_valuation_candidate 93-130; jarca_ledger_mcp/application/account_valuation_service.py register_account_valuation 133-257; jarca_ledger_mcp/application/account_valuation_service.py list_account_valuations 261-266; jarca_ledger_mcp/application/account_valuation_service.py select_account_valuation 270-312; jarca_ledger_mcp/application/account_valuation_service.py correct_account_valuation 315-375; jarca_ledger_mcp/infrastructure/sqlite/migrations.py migrate_db 19-173; jarca_ledger_mcp/infrastructure/sqlite/migrations.py init_db 176-181. 기존 review61에서 충족하던 의미는 전체 rework diff상 유지되며 테스트 인수와 assertion 및 문서 의무와 대응했다.
    • 테스트 근거: tests/test_account_valuations.py
    • 판정 근거: 승인 계약의 해당 의미와 실패 무변경 및 기존 호환성은 보존된다. 재작업의 영향은 대출 정의 불변조건 강화이며, 이미 해소된 항목을 별도 실행 기록의 부재만으로 다시 변경 요청하지 않는다.
  • C02-money-metrics — satisfied

    • 계약: 금액 정밀도와 NULL 및 0을 보존하고 취득원가, 순납입액, 기관 표시 원금 금액과 정의 및 원문 명칭, 손익과 수익률의 계산 기준을 구분한다. 투자 대표 총평가액과 포함 현금 및 원금을 중복 합산하지 않는다.
    • 구현 근거: jarca_ledger_mcp/application/account_valuation_service.py, jarca_ledger_mcp/infrastructure/sqlite/schema.py, docs/data-model.md, docs/requirements/req-003_account-valuation-history.md; 현재 고정 head의 구현과 named test를 해당 승인 계약에 대조했다. Source 위치: jarca_ledger_mcp/application/account_valuation_service.py _valuation 25-26; jarca_ledger_mcp/application/account_valuation_service.py record_account_valuation_candidate 93-130; jarca_ledger_mcp/application/account_valuation_service.py register_account_valuation 133-257; jarca_ledger_mcp/application/account_valuation_service.py list_account_valuations 261-266; jarca_ledger_mcp/application/account_valuation_service.py select_account_valuation 270-312; jarca_ledger_mcp/application/account_valuation_service.py correct_account_valuation 315-375. 기존 review61에서 충족하던 의미는 전체 rework diff상 유지되며 테스트 인수와 assertion 및 문서 의무와 대응했다.
    • 테스트 근거: tests/test_issue_12_review59_account.py, tests/test_issue_12_regressions.py
    • 판정 근거: 승인 계약의 해당 의미와 실패 무변경 및 기존 호환성은 보존된다. 재작업의 영향은 대출 정의 불변조건 강화이며, 이미 해소된 항목을 별도 실행 기록의 부재만으로 다시 변경 요청하지 않는다.
  • N01-loan-balance-definition — satisfied

    • 계약: 대출 평가 기록마다 대표 부채가 원금만인지 원금과 이자 및 수수료인지 필수로 명시하고 기본값으로 추정하지 않는다. 목적 alias가 필수 정의 계약을 우회하지 않는다.
    • 구현 근거: jarca_ledger_mcp/application/account_valuation_service.py, docs/requirements/req-003_account-valuation-history.md, jarca_ledger_mcp/application/accounts_write_services.py, jarca_ledger_mcp/application/imports_service.py, docs/data-model.md; account_valuation_service.py 93-101는 loan candidate를 INSERT 전에 거부하고 194-203은 loan 계좌의 허용 목적과 필수 정의를 검증한다. accounts_write_services.py 65-74는 정의 없는 기존 valuation이 있으면 loan 전환을 UPDATE 전에 거부한다. test_account_valuation_edge_contracts.py 8-38,133-212는 전환 실패 무변경과 빈 이력 전환 성공, 직접/import 후보 미생성, current cache 보존, 부적합 목적 거부와 non-loan 재사용을 확인한다. test_issue_12_review59_account.py 107-128은 loan import 거래와 캐시 성공 및 valuation0을 확인한다.
    • 테스트 근거: tests/test_issue_12_regressions.py, tests/test_issue_12_review59_account.py, tests/test_account_valuation_edge_contracts.py
    • 판정 근거: 기존 review61의 N01은 모든 지적 경계에서 해소됐다. 대출 정의를 추정하거나 새 이력을 자동 재작성하지 않고, 정의 없는 후보만 저장하지 않으면서 기존 계좌 및 import 호환을 보존한다.
  • C03-selection — satisfied

    • 계약: 계좌와 통화 및 평가 목적별 유효 자료를 선택한다. exact는 당일 확인 자료만, as_of는 기준일 이하 최신 확인 자료만 사용한다. 미래 자료는 제외하고 미확인 후보는 확인 자료를 대체하거나 합산하지 않는다. 실제 기준일과 경과 일수 및 이월 상태를 반환한다.
    • 구현 근거: jarca_ledger_mcp/application/account_valuation_service.py, jarca_ledger_mcp/application/assets_service.py; 현재 고정 head의 구현과 named test를 해당 승인 계약에 대조했다. Source 위치: jarca_ledger_mcp/application/account_valuation_service.py _valuation 25-26; jarca_ledger_mcp/application/account_valuation_service.py record_account_valuation_candidate 93-130; jarca_ledger_mcp/application/account_valuation_service.py register_account_valuation 133-257; jarca_ledger_mcp/application/account_valuation_service.py list_account_valuations 261-266; jarca_ledger_mcp/application/account_valuation_service.py select_account_valuation 270-312; jarca_ledger_mcp/application/account_valuation_service.py correct_account_valuation 315-375; jarca_ledger_mcp/application/assets_service.py _valuation_policy 28-36; jarca_ledger_mcp/application/assets_service.py _valuation_row_state_hash 108-112; jarca_ledger_mcp/application/assets_service.py _account_valuation_items 115-215; jarca_ledger_mcp/application/assets_service.py _manual_asset_valuation_items 218-259; jarca_ledger_mcp/application/assets_service.py _snapshot_rows_for_run 262-292; jarca_ledger_mcp/application/assets_service.py _snapshot_rows_for_latest_run 295-300; jarca_ledger_mcp/application/assets_service.py _snapshot_items 303-345; jarca_ledger_mcp/application/assets_service.py _summarize_valuation_items 414-453; jarca_ledger_mcp/application/assets_service.py _snapshot_preview_from_conn 545-597; jarca_ledger_mcp/application/assets_service.py preview_asset_snapshot_close 601-623; jarca_ledger_mcp/application/assets_service.py close_asset_snapshot 626-813; jarca_ledger_mcp/application/assets_service.py create_asset_snapshot 816-836; jarca_ledger_mcp/application/assets_service.py get_asset_snapshot_report 840-928. 기존 review61에서 충족하던 의미는 전체 rework diff상 유지되며 테스트 인수와 assertion 및 문서 의무와 대응했다.
    • 테스트 근거: tests/test_account_valuations.py, tests/test_issue_12_regressions.py
    • 판정 근거: 승인 계약의 해당 의미와 실패 무변경 및 기존 호환성은 보존된다. 재작업의 영향은 대출 정의 불변조건 강화이며, 이미 해소된 항목을 별도 실행 기록의 부재만으로 다시 변경 요청하지 않는다.
  • C04-correction-validation — satisfied

    • 계약: 평가 정정은 append-only로 대상과 사유를 연결하며 다른 계좌, 통화, 목적을 참조하는 정정과 순환 및 동일 유효본의 동시 분기를 차단한다.
    • 구현 근거: jarca_ledger_mcp/application/account_valuation_service.py, jarca_ledger_mcp/infrastructure/sqlite/schema.py; 현재 고정 head의 구현과 named test를 해당 승인 계약에 대조했다. Source 위치: jarca_ledger_mcp/application/account_valuation_service.py _valuation 25-26; jarca_ledger_mcp/application/account_valuation_service.py record_account_valuation_candidate 93-130; jarca_ledger_mcp/application/account_valuation_service.py register_account_valuation 133-257; jarca_ledger_mcp/application/account_valuation_service.py list_account_valuations 261-266; jarca_ledger_mcp/application/account_valuation_service.py select_account_valuation 270-312; jarca_ledger_mcp/application/account_valuation_service.py correct_account_valuation 315-375. 기존 review61에서 충족하던 의미는 전체 rework diff상 유지되며 테스트 인수와 assertion 및 문서 의무와 대응했다.
    • 테스트 근거: tests/test_issue_12_review59_account.py, tests/test_account_valuations.py, tests/test_issue_12_regressions.py
    • 판정 근거: 승인 계약의 해당 의미와 실패 무변경 및 기존 호환성은 보존된다. 재작업의 영향은 대출 정의 불변조건 강화이며, 이미 해소된 항목을 별도 실행 기록의 부재만으로 다시 변경 요청하지 않는다.
  • C05-current-import — satisfied

    • 계약: 뒤늦은 과거 자료 등록으로 최신 표시값을 과거로 되돌리지 않는다. 기존 계좌 수정과 import의 최신 캐시 및 새 이력 권위를 연결하며 동기화 시각을 실제 평가일로 오인하지 않는다.
    • 구현 근거: jarca_ledger_mcp/application/imports_service.py, jarca_ledger_mcp/application/assets_service.py, jarca_ledger_mcp/application/accounts_write_services.py; imports_service.py 43-49의 basis 비교와 accounts_write_services.py 75-91의 historical guard를 대조했다. test_import_current_balance_authority.py는 연속 늦은 import 및 날짜 미상 근거를 검증하고 test_account_valuation_edge_contracts.py 159-177와 test_issue_12_review59_account.py 107-128은 loan 캐시 및 import 보존을 확인한다.
    • 테스트 근거: tests/test_issue_12_review59_account.py, tests/test_import_provenance_policy.py, tests/test_import_current_balance_authority.py, tests/test_account_basis_public_consumers.py
    • 판정 근거: 실제 평가일과 동기화시각을 분리하고 과거 자료의 캐시 rollback을 막는다. Loan 정의 없는 이력 미생성은 현재값 및 transaction import의 성공 의미를 축소하지 않는다.
  • C06-idempotency — satisfied

    • 계약: 동일 증빙 또는 idempotency 재입력은 동일 기록을 재사용하며 같은 키의 다른 payload는 충돌이다. 동시 정정의 분기를 차단하고 UNIQUE 계좌 및 기준일 하나로 정정 추가를 막지 않는다.
    • 구현 근거: jarca_ledger_mcp/application/account_valuation_service.py, jarca_ledger_mcp/infrastructure/sqlite/schema.py, jarca_ledger_mcp/infrastructure/sqlite/migrations.py, jarca_ledger_mcp/application/accounts_write_services.py, jarca_ledger_mcp/application/imports_service.py; test_account_valuation_edge_contracts.py 79-130은 동일 keyless correction 재사용과 금액 및 사유 및 source 변경 충돌,134-156은 candidate loan 실패,194-231은 non-loan candidate 동일 row 재사용 및 잘못된 금액 무변경을 확인한다. correct_account_valuation은 전체 effective payload 및 기존 child를 비교한다.
    • 테스트 근거: tests/test_issue_12_review59_account.py, tests/test_account_valuations.py, tests/test_issue_12_regressions.py, tests/test_account_valuation_edge_contracts.py
    • 판정 근거: 명시 key와 keyless 증빙 정정 재시도 및 다른 payload 충돌을 구분한다. 기존 review60의 첫 정정만 검증한다는 서술은 오류였으며 명시 key replay는 당시부터 검증돼 있었음을 유지한다.
  • C07-close-immutability — satisfied

    • 계약: 기존 asset_snapshots와 correction run을 보존하고 평가 정정 및 거래 추가로 기존 마감을 자동 변경하지 않는다. 동일 기준일 재마감은 사유와 이전 run 연결을 가진 새 버전을 원자적으로 추가한다.
    • 구현 근거: jarca_ledger_mcp/application/assets_service.py, jarca_ledger_mcp/infrastructure/sqlite/schema.py, jarca_ledger_mcp/infrastructure/sqlite/migrations.py; 현재 고정 head의 구현과 named test를 해당 승인 계약에 대조했다. Source 위치: jarca_ledger_mcp/application/assets_service.py _valuation_policy 28-36; jarca_ledger_mcp/application/assets_service.py _valuation_row_state_hash 108-112; jarca_ledger_mcp/application/assets_service.py _account_valuation_items 115-215; jarca_ledger_mcp/application/assets_service.py _manual_asset_valuation_items 218-259; jarca_ledger_mcp/application/assets_service.py _snapshot_rows_for_run 262-292; jarca_ledger_mcp/application/assets_service.py _snapshot_rows_for_latest_run 295-300; jarca_ledger_mcp/application/assets_service.py _snapshot_items 303-345; jarca_ledger_mcp/application/assets_service.py _summarize_valuation_items 414-453; jarca_ledger_mcp/application/assets_service.py _snapshot_preview_from_conn 545-597; jarca_ledger_mcp/application/assets_service.py preview_asset_snapshot_close 601-623; jarca_ledger_mcp/application/assets_service.py close_asset_snapshot 626-813; jarca_ledger_mcp/application/assets_service.py create_asset_snapshot 816-836; jarca_ledger_mcp/application/assets_service.py get_asset_snapshot_report 840-928; jarca_ledger_mcp/infrastructure/sqlite/migrations.py migrate_db 19-173; jarca_ledger_mcp/infrastructure/sqlite/migrations.py init_db 176-181. 기존 review61에서 충족하던 의미는 전체 rework diff상 유지되며 테스트 인수와 assertion 및 문서 의무와 대응했다.
    • 테스트 근거: tests/test_asset_snapshots.py, tests/test_issue_12_regressions.py
    • 판정 근거: 승인 계약의 해당 의미와 실패 무변경 및 기존 호환성은 보존된다. 재작업의 영향은 대출 정의 불변조건 강화이며, 이미 해소된 항목을 별도 실행 기록의 부재만으로 다시 변경 요청하지 않는다.
  • N02-close-replay-run-binding — satisfied

    • 계약: 마감 버전의 근거는 불변이며 동일 idempotency 요청은 원래 기록을 재사용한다. 재마감으로 과거 run 응답 및 evidence를 변경하지 않는다.
    • 구현 근거: jarca_ledger_mcp/application/assets_service.py, docs/interface-contract.md; 현재 고정 head의 구현과 named test를 해당 승인 계약에 대조했다. Source 위치: jarca_ledger_mcp/application/assets_service.py _valuation_policy 28-36; jarca_ledger_mcp/application/assets_service.py _valuation_row_state_hash 108-112; jarca_ledger_mcp/application/assets_service.py _account_valuation_items 115-215; jarca_ledger_mcp/application/assets_service.py _manual_asset_valuation_items 218-259; jarca_ledger_mcp/application/assets_service.py _snapshot_rows_for_run 262-292; jarca_ledger_mcp/application/assets_service.py _snapshot_rows_for_latest_run 295-300; jarca_ledger_mcp/application/assets_service.py _snapshot_items 303-345; jarca_ledger_mcp/application/assets_service.py _summarize_valuation_items 414-453; jarca_ledger_mcp/application/assets_service.py _snapshot_preview_from_conn 545-597; jarca_ledger_mcp/application/assets_service.py preview_asset_snapshot_close 601-623; jarca_ledger_mcp/application/assets_service.py close_asset_snapshot 626-813; jarca_ledger_mcp/application/assets_service.py create_asset_snapshot 816-836; jarca_ledger_mcp/application/assets_service.py get_asset_snapshot_report 840-928. 기존 review61에서 충족하던 의미는 전체 rework diff상 유지되며 테스트 인수와 assertion 및 문서 의무와 대응했다.
    • 테스트 근거: tests/test_issue_12_review59_reports.py, tests/test_issue_12_regressions.py, tests/test_asset_snapshot_idempotency.py
    • 판정 근거: 승인 계약의 해당 의미와 실패 무변경 및 기존 호환성은 보존된다. 재작업의 영향은 대출 정의 불변조건 강화이며, 이미 해소된 항목을 별도 실행 기록의 부재만으로 다시 변경 요청하지 않는다.
  • C08-approved-conditional — satisfied

    • 계약: 완전한 exact 마감, 미완료 초안, 별도 승인된 조건부 마감을 구분한다. 승인 전 누락 및 이월은 미완료 초안이고 승인 후에도 누락 제외 및 확인된 과거값 이월만 허용한다. 미확인, 미래, 기준일 미상 금액은 승인으로도 합산하지 않으며 적용과 제외와 이월 및 승인자와 시각과 사유와 근거를 고정한다.
    • 구현 근거: jarca_ledger_mcp/application/assets_service.py, jarca_ledger_mcp/infrastructure/sqlite/schema.py, dashboard/page_views/assets.py; 현재 고정 head의 구현과 named test를 해당 승인 계약에 대조했다. Source 위치: jarca_ledger_mcp/application/assets_service.py _valuation_policy 28-36; jarca_ledger_mcp/application/assets_service.py _valuation_row_state_hash 108-112; jarca_ledger_mcp/application/assets_service.py _account_valuation_items 115-215; jarca_ledger_mcp/application/assets_service.py _manual_asset_valuation_items 218-259; jarca_ledger_mcp/application/assets_service.py _snapshot_rows_for_run 262-292; jarca_ledger_mcp/application/assets_service.py _snapshot_rows_for_latest_run 295-300; jarca_ledger_mcp/application/assets_service.py _snapshot_items 303-345; jarca_ledger_mcp/application/assets_service.py _summarize_valuation_items 414-453; jarca_ledger_mcp/application/assets_service.py _snapshot_preview_from_conn 545-597; jarca_ledger_mcp/application/assets_service.py preview_asset_snapshot_close 601-623; jarca_ledger_mcp/application/assets_service.py close_asset_snapshot 626-813; jarca_ledger_mcp/application/assets_service.py create_asset_snapshot 816-836; jarca_ledger_mcp/application/assets_service.py get_asset_snapshot_report 840-928. 기존 review61에서 충족하던 의미는 전체 rework diff상 유지되며 테스트 인수와 assertion 및 문서 의무와 대응했다.
    • 테스트 근거: tests/test_issue_12_review59_reports.py, tests/test_issue_12_regressions.py, tests/test_asset_snapshots.py
    • 판정 근거: 승인 계약의 해당 의미와 실패 무변경 및 기존 호환성은 보존된다. 재작업의 영향은 대출 정의 불변조건 강화이며, 이미 해소된 항목을 별도 실행 기록의 부재만으로 다시 변경 요청하지 않는다.
  • C09-reconciliation — satisfied

    • 계약: 외부 확인값과 장부 계산값을 분리하고 검증된 시작잔고, 기준시점, 거래 포함 범위와 계산 완전성을 표시한다. 거래 없는 수동 투자 계좌의 대사 불가 및 거래 미수입과 평가 수동 관리 상태를 구분하고 가짜 거래를 만들지 않는다. 대사도 공통 평가 근거와 대출 대표 정의를 사용한다.
    • 구현 근거: jarca_ledger_mcp/application/reconciliation_service.py, jarca_ledger_mcp/application/account_valuation_service.py, jarca_ledger_mcp/application/monthly_settlement_service.py; 현재 고정 head의 구현과 named test를 해당 승인 계약에 대조했다. Source 위치: jarca_ledger_mcp/application/reconciliation_service.py get_balance_reconciliation_report 68-215; jarca_ledger_mcp/application/account_valuation_service.py _valuation 25-26; jarca_ledger_mcp/application/account_valuation_service.py record_account_valuation_candidate 93-130; jarca_ledger_mcp/application/account_valuation_service.py register_account_valuation 133-257; jarca_ledger_mcp/application/account_valuation_service.py list_account_valuations 261-266; jarca_ledger_mcp/application/account_valuation_service.py select_account_valuation 270-312; jarca_ledger_mcp/application/account_valuation_service.py correct_account_valuation 315-375; jarca_ledger_mcp/application/monthly_settlement_service.py get_monthly_settlement_summary 82-125. 기존 review61에서 충족하던 의미는 전체 rework diff상 유지되며 테스트 인수와 assertion 및 문서 의무와 대응했다.
    • 테스트 근거: tests/test_issue_12_review59_reports.py, tests/test_issue_12_regressions.py, tests/test_service.py
    • 판정 근거: 승인 계약의 해당 의미와 실패 무변경 및 기존 호환성은 보존된다. 재작업의 영향은 대출 정의 불변조건 강화이며, 이미 해소된 항목을 별도 실행 기록의 부재만으로 다시 변경 요청하지 않는다.
  • C10-report-monthly-evidence — satisfied

    • 계약: MCP와 Dashboard 및 월정산 보고에서 같은 기준일과 선택 근거 및 실제 평가일, 경과 일수, 확인 상태, 누락과 미확인 및 이월 경고, 마감 버전 및 조건부 승인 근거를 일관되게 전달한다.
    • 구현 근거: jarca_ledger_mcp/application/assets_service.py, jarca_ledger_mcp/application/monthly_settlement_service.py, dashboard/page_views/monthly_settlement.py, dashboard/page_views/accounts.py; 현재 고정 head의 구현과 named test를 해당 승인 계약에 대조했다. Source 위치: jarca_ledger_mcp/application/assets_service.py _valuation_policy 28-36; jarca_ledger_mcp/application/assets_service.py _valuation_row_state_hash 108-112; jarca_ledger_mcp/application/assets_service.py _account_valuation_items 115-215; jarca_ledger_mcp/application/assets_service.py _manual_asset_valuation_items 218-259; jarca_ledger_mcp/application/assets_service.py _snapshot_rows_for_run 262-292; jarca_ledger_mcp/application/assets_service.py _snapshot_rows_for_latest_run 295-300; jarca_ledger_mcp/application/assets_service.py _snapshot_items 303-345; jarca_ledger_mcp/application/assets_service.py _summarize_valuation_items 414-453; jarca_ledger_mcp/application/assets_service.py _snapshot_preview_from_conn 545-597; jarca_ledger_mcp/application/assets_service.py preview_asset_snapshot_close 601-623; jarca_ledger_mcp/application/assets_service.py close_asset_snapshot 626-813; jarca_ledger_mcp/application/assets_service.py create_asset_snapshot 816-836; jarca_ledger_mcp/application/assets_service.py get_asset_snapshot_report 840-928; jarca_ledger_mcp/application/monthly_settlement_service.py get_monthly_settlement_summary 82-125; dashboard/page_views/monthly_settlement.py page_monthly_settlement 40-269. 기존 review61에서 충족하던 의미는 전체 rework diff상 유지되며 테스트 인수와 assertion 및 문서 의무와 대응했다.
    • 테스트 근거: tests/test_issue_12_review59_reports.py, tests/test_issue_12_regressions.py, tests/test_service.py
    • 판정 근거: 승인 계약의 해당 의미와 실패 무변경 및 기존 호환성은 보존된다. 재작업의 영향은 대출 정의 불변조건 강화이며, 이미 해소된 항목을 별도 실행 기록의 부재만으로 다시 변경 요청하지 않는다.
  • C11-adapter-structure — satisfied

    • 계약: MCP와 Streamlit gateway는 공통 application을 사용하고 기존 공개 호출명과 기존 인수 및 success와 실패 error_code 및 error envelope를 가능한 한 유지한다. 새 Dashboard 인증 또는 MCP 인증을 도입하지 않는다.
    • 구현 근거: jarca_ledger_mcp/adapters/mcp/server.py, jarca_ledger_mcp/adapters/mcp/tool_contracts.py, jarca_ledger_mcp/adapters/streamlit/accounts_gateway.py, jarca_ledger_mcp/application/__init__.py, jarca_ledger_mcp/service.py, dashboard/page_views/accounts.py, dashboard/page_views/assets.py, dashboard/page_views/monthly_settlement.py; 현재 고정 head의 구현과 named test를 해당 승인 계약에 대조했다. Source 위치: jarca_ledger_mcp/adapters/mcp/server.py register_account_valuation 120-122; jarca_ledger_mcp/adapters/mcp/server.py list_account_valuations 125-127; jarca_ledger_mcp/adapters/mcp/server.py select_account_valuation 130-132; jarca_ledger_mcp/adapters/mcp/server.py correct_account_valuation 135-138; jarca_ledger_mcp/adapters/mcp/server.py preview_asset_snapshot_close 165-167; jarca_ledger_mcp/adapters/mcp/server.py close_asset_snapshot 170-172; jarca_ledger_mcp/adapters/mcp/server.py get_asset_snapshot_report 175-177; jarca_ledger_mcp/adapters/mcp/server.py get_balance_reconciliation_report 185-187; jarca_ledger_mcp/adapters/mcp/server.py list_reconciliation_sessions 215-217; jarca_ledger_mcp/adapters/mcp/server.py upsert_reconciliation_session 220-222; jarca_ledger_mcp/adapters/mcp/server.py close_reconciliation_session 225-227; jarca_ledger_mcp/adapters/mcp/server.py get_monthly_cashflow_report 265-267; jarca_ledger_mcp/adapters/mcp/server.py get_monthly_settlement_summary 270-272; jarca_ledger_mcp/adapters/mcp/server.py main 441-442; dashboard/page_views/monthly_settlement.py page_monthly_settlement 40-269. 기존 review61에서 충족하던 의미는 전체 rework diff상 유지되며 테스트 인수와 assertion 및 문서 의무와 대응했다.
    • 테스트 근거: tests/test_contract_regression.py, tests/test_issue_12_regressions.py
    • 판정 근거: 승인 계약의 해당 의미와 실패 무변경 및 기존 호환성은 보존된다. 재작업의 영향은 대출 정의 불변조건 강화이며, 이미 해소된 항목을 별도 실행 기록의 부재만으로 다시 변경 요청하지 않는다.
  • C12-migration-legacy — satisfied

    • 계약: schema 11의 기존 데이터와 마감 및 개인정보를 보존하고 additive하고 idempotent한 migration을 제공한다. 기준일 증거 없는 값을 임의 월말로 소급하거나 legacy snapshot에 valuation_id를 추측하여 생성하지 않는다.
    • 구현 근거: jarca_ledger_mcp/infrastructure/sqlite/schema.py, jarca_ledger_mcp/infrastructure/sqlite/migrations.py, jarca_ledger_mcp/application/assets_service.py; 현재 고정 head의 구현과 named test를 해당 승인 계약에 대조했다. Source 위치: jarca_ledger_mcp/infrastructure/sqlite/migrations.py migrate_db 19-173; jarca_ledger_mcp/infrastructure/sqlite/migrations.py init_db 176-181; jarca_ledger_mcp/application/assets_service.py _valuation_policy 28-36; jarca_ledger_mcp/application/assets_service.py _valuation_row_state_hash 108-112; jarca_ledger_mcp/application/assets_service.py _account_valuation_items 115-215; jarca_ledger_mcp/application/assets_service.py _manual_asset_valuation_items 218-259; jarca_ledger_mcp/application/assets_service.py _snapshot_rows_for_run 262-292; jarca_ledger_mcp/application/assets_service.py _snapshot_rows_for_latest_run 295-300; jarca_ledger_mcp/application/assets_service.py _snapshot_items 303-345; jarca_ledger_mcp/application/assets_service.py _summarize_valuation_items 414-453; jarca_ledger_mcp/application/assets_service.py _snapshot_preview_from_conn 545-597; jarca_ledger_mcp/application/assets_service.py preview_asset_snapshot_close 601-623; jarca_ledger_mcp/application/assets_service.py close_asset_snapshot 626-813; jarca_ledger_mcp/application/assets_service.py create_asset_snapshot 816-836; jarca_ledger_mcp/application/assets_service.py get_asset_snapshot_report 840-928. 기존 review61에서 충족하던 의미는 전체 rework diff상 유지되며 테스트 인수와 assertion 및 문서 의무와 대응했다.
    • 테스트 근거: tests/test_account_valuations.py, tests/test_issue_12_regressions.py, tests/test_ledger_categories.py, tests/test_review_decision_workbench.py
    • 판정 근거: 승인 계약의 해당 의미와 실패 무변경 및 기존 호환성은 보존된다. 재작업의 영향은 대출 정의 불변조건 강화이며, 이미 해소된 항목을 별도 실행 기록의 부재만으로 다시 변경 요청하지 않는다.
  • C13-read-only — satisfied

    • 계약: preview와 조회 및 Dashboard 렌더링은 금융 쓰기를 실행하지 않는다. 명시적 등록, 정정, 승인 close 및 import 제출만 변경을 수행하고 실패 시 부분 쓰기를 남기지 않는다.
    • 구현 근거: jarca_ledger_mcp/infrastructure/sqlite/connection.py, jarca_ledger_mcp/application/shared.py, jarca_ledger_mcp/application/system_services.py, jarca_ledger_mcp/application/account_valuation_service.py, jarca_ledger_mcp/application/assets_service.py; 현재 고정 head의 구현과 named test를 해당 승인 계약에 대조했다. Source 위치: jarca_ledger_mcp/infrastructure/sqlite/connection.py connect_readonly 31-43; jarca_ledger_mcp/infrastructure/sqlite/connection.py read_db 47-53; jarca_ledger_mcp/application/shared.py read_operation 128-138; jarca_ledger_mcp/application/shared.py normalize_snapshot_at 181-198; jarca_ledger_mcp/application/system_services.py health_check_readonly 35-40; jarca_ledger_mcp/application/system_services.py _readonly_sqlite_connection 63-66; jarca_ledger_mcp/application/system_services.py _safe_monthly_aggregates 78-95; jarca_ledger_mcp/application/account_valuation_service.py _valuation 25-26; jarca_ledger_mcp/application/account_valuation_service.py record_account_valuation_candidate 93-130; jarca_ledger_mcp/application/account_valuation_service.py register_account_valuation 133-257; jarca_ledger_mcp/application/account_valuation_service.py list_account_valuations 261-266; jarca_ledger_mcp/application/account_valuation_service.py select_account_valuation 270-312; jarca_ledger_mcp/application/account_valuation_service.py correct_account_valuation 315-375; jarca_ledger_mcp/application/assets_service.py _valuation_policy 28-36; jarca_ledger_mcp/application/assets_service.py _valuation_row_state_hash 108-112; jarca_ledger_mcp/application/assets_service.py _account_valuation_items 115-215; jarca_ledger_mcp/application/assets_service.py _manual_asset_valuation_items 218-259; jarca_ledger_mcp/application/assets_service.py _snapshot_rows_for_run 262-292; jarca_ledger_mcp/application/assets_service.py _snapshot_rows_for_latest_run 295-300; jarca_ledger_mcp/application/assets_service.py _snapshot_items 303-345; jarca_ledger_mcp/application/assets_service.py _summarize_valuation_items 414-453; jarca_ledger_mcp/application/assets_service.py _snapshot_preview_from_conn 545-597; jarca_ledger_mcp/application/assets_service.py preview_asset_snapshot_close 601-623; jarca_ledger_mcp/application/assets_service.py close_asset_snapshot 626-813; jarca_ledger_mcp/application/assets_service.py create_asset_snapshot 816-836; jarca_ledger_mcp/application/assets_service.py get_asset_snapshot_report 840-928. 기존 review61에서 충족하던 의미는 전체 rework diff상 유지되며 테스트 인수와 assertion 및 문서 의무와 대응했다.
    • 테스트 근거: tests/test_issue_12_review59_readonly.py, tests/test_dashboard_app.py, tests/test_dashboard_menu_transition.py
    • 판정 근거: 승인 계약의 해당 의미와 실패 무변경 및 기존 호환성은 보존된다. 재작업의 영향은 대출 정의 불변조건 강화이며, 이미 해소된 항목을 별도 실행 기록의 부재만으로 다시 변경 요청하지 않는다.
  • C14-auth-menu-preservation — satisfied

    • 계약: Dashboard 인증은 DB보다 먼저이며 REQ-001의 cookie와 logout 및 REQ-002의 메뉴 label과 order, shell, query, error와 retry 및 명시적 금융 쓰기 계약을 유지한다.
    • 구현 근거: dashboard/app.py, dashboard/page_views/accounts.py, dashboard/page_views/assets.py, dashboard/page_views/monthly_settlement.py, docs/interface-contract.md, docs/project-structure.md, docs/runtime-flow.md; 현재 고정 head의 구현과 named test를 해당 승인 계약에 대조했다. Source 위치: dashboard/app.py main 37-72; dashboard/page_views/monthly_settlement.py page_monthly_settlement 40-269. 기존 review61에서 충족하던 의미는 전체 rework diff상 유지되며 테스트 인수와 assertion 및 문서 의무와 대응했다.
    • 테스트 근거: tests/test_dashboard_menu_transition.py, tests/test_dashboard_app.py
    • 판정 근거: 승인 계약의 해당 의미와 실패 무변경 및 기존 호환성은 보존된다. 재작업의 영향은 대출 정의 불변조건 강화이며, 이미 해소된 항목을 별도 실행 기록의 부재만으로 다시 변경 요청하지 않는다.
  • C15-exclusions-privacy — satisfied

    • 계약: 증권사 자동 연동, 정확한 성과 또는 환율 엔진, 새 인증, 별도 월정산 제품, 거래 추론 및 기존 데이터 자동 재작성과 수기 비계좌 자산 전체 이력 재설계를 추가하지 않는다. 실제 계좌 및 금융 증빙과 credential을 로그와 문서 및 테스트에 기록하지 않는다.
    • 구현 근거: jarca_ledger_mcp/application/assets_service.py, jarca_ledger_mcp/application/account_valuation_service.py, jarca_ledger_mcp/application/imports_service.py, jarca_ledger_mcp/application/reconciliation_service.py, jarca_ledger_mcp/infrastructure/sqlite/schema.py, jarca_ledger_mcp/infrastructure/sqlite/migrations.py; 현재 고정 head의 구현과 named test를 해당 승인 계약에 대조했다. Source 위치: jarca_ledger_mcp/application/assets_service.py _valuation_policy 28-36; jarca_ledger_mcp/application/assets_service.py _valuation_row_state_hash 108-112; jarca_ledger_mcp/application/assets_service.py _account_valuation_items 115-215; jarca_ledger_mcp/application/assets_service.py _manual_asset_valuation_items 218-259; jarca_ledger_mcp/application/assets_service.py _snapshot_rows_for_run 262-292; jarca_ledger_mcp/application/assets_service.py _snapshot_rows_for_latest_run 295-300; jarca_ledger_mcp/application/assets_service.py _snapshot_items 303-345; jarca_ledger_mcp/application/assets_service.py _summarize_valuation_items 414-453; jarca_ledger_mcp/application/assets_service.py _snapshot_preview_from_conn 545-597; jarca_ledger_mcp/application/assets_service.py preview_asset_snapshot_close 601-623; jarca_ledger_mcp/application/assets_service.py close_asset_snapshot 626-813; jarca_ledger_mcp/application/assets_service.py create_asset_snapshot 816-836; jarca_ledger_mcp/application/assets_service.py get_asset_snapshot_report 840-928; jarca_ledger_mcp/application/account_valuation_service.py _valuation 25-26; jarca_ledger_mcp/application/account_valuation_service.py record_account_valuation_candidate 93-130; jarca_ledger_mcp/application/account_valuation_service.py register_account_valuation 133-257; jarca_ledger_mcp/application/account_valuation_service.py list_account_valuations 261-266; jarca_ledger_mcp/application/account_valuation_service.py select_account_valuation 270-312; jarca_ledger_mcp/application/account_valuation_service.py correct_account_valuation 315-375; jarca_ledger_mcp/application/imports_service.py _record_import_valuation_candidate 37-41; jarca_ledger_mcp/application/reconciliation_service.py get_balance_reconciliation_report 68-215; jarca_ledger_mcp/infrastructure/sqlite/migrations.py migrate_db 19-173; jarca_ledger_mcp/infrastructure/sqlite/migrations.py init_db 176-181. 기존 review61에서 충족하던 의미는 전체 rework diff상 유지되며 테스트 인수와 assertion 및 문서 의무와 대응했다.
    • 테스트 근거: tests/test_issue_12_review59_reports.py, tests/test_issue_12_regressions.py, scripts/ci_fixture_db.py
    • 판정 근거: 승인 계약의 해당 의미와 실패 무변경 및 기존 호환성은 보존된다. 재작업의 영향은 대출 정의 불변조건 강화이며, 이미 해소된 항목을 별도 실행 기록의 부재만으로 다시 변경 요청하지 않는다.
  • D01-requirement-structure — satisfied

    • 계약: 신규 REQ-003을 배정 경로와 제목으로 작성하며 trusted harness README와 TEMPLATE의 JSON metadata, 연속 요구사항 및 AC, 필수 섹션, 판정 기준과 검증 및 검증 분류의 수준과 백엔드와 케이스 및 상태 불변조건을 충족한다. 초기 PR은 미정이며 PR 생성 후 실제 번호를 추적한다.
    • 구현 근거: docs/requirements/req-003_account-valuation-history.md; req-003_account-valuation-history.md 1-16의 metadata 및 식별자와 추적성,51-174의 요구사항,187-297의 전체 AC10개 및299-317의 필수 섹션을 trusted README와 TEMPLATE에 대응했다. 요구 문서 lifecycle은 PR 구현 승인과 분리된다.
    • 테스트 근거: tests/test_requirement_docs.py
    • 판정 근거: 신규 요구사항 REQ003 exact 경로와 제목 및 구조를 유지한다. 이전 review61 requirement의 AC10개 전체 블록은 현재 문서와 byte-identical하여 인수 의미와 검증 및 불변조건의 축소가 없다.
  • D02-requirement-semantics — satisfied

    • 계약: 요구사항에는 평가 근거와 지표 정의, 선택과 future 제외, 정정 및 idempotency 충돌, 대사 완전성, current 및 import 연계, 마감 상태와 불변성과 승인, shared adapter 및 인증, migration과 legacy를 소스 및 테스트에 대응한다. 모든 승인된 경계와 회귀 사례를 인수 기준으로 내린다.
    • 구현 근거: docs/requirements/req-003_account-valuation-history.md; Discovery의 전체 문서 의무표와 포함 범위 및 확정 결정에 모든 REQ003 하위 요구사항 및 AC를 대응했다. 기존 AC10개 전체 블록의 동일성을 확인했고 검증 참조13개를 exact head tree와 AST symbol로 확인했다. 마지막 요구사항 변경은 정의 없는 loan 후보 미생성 및 account type 전환 guard를 명시해 원래 필수 정의 계약을 보강한다.
    • 테스트 근거: tests/test_account_valuations.py, tests/test_asset_snapshots.py, tests/test_issue_12_regressions.py, tests/test_requirement_docs.py, tests/test_mcp_http_runtime.py, tests/test_dashboard_authentication_app.py
    • 판정 근거: 기존 금융 인수 의미와 인증 및 메뉴 보존을 유지한다. 반복 서술 부재나 별도 response 표 부재를 새 의무로 만들지 않았으며 참조된 unchanged 테스트도 실제 source에서 검증했다.
  • D03-data-model — satisfied

    • 계약: 신규 데이터 모델은 기존 entities 및 valuation과 마감의 관계, FK와 날짜 및 정확한 금액과 NULL 및 0과 선택 지표 및 대출 필수 정의, 계좌와 통화 및 목적과 기준일의 선택 및 index와 단일 유효 정정본, 고정 적용 분류 및 출처와 상태와 누락 및 이월 및 승인 버전, 분리된 정정과 schema11 이관 및 미상 날짜와 legacy 및 최신 캐시 동기화 책임을 정의한다.
    • 구현 근거: docs/data-model.md; data-model.md 33-61은 영속 필드와 원금 및 NULL0 의미,82-121은 snapshot/run 고정과 승인 및 candidate 경계,123-130은 basis와 sync timestamp 및 캐시/historical authority와 loan 전환 불변조건,132-169는 관계와 이관을 명시한다. test_valuation_contract_docs.py 11-53과 대조했다.
    • 테스트 근거: tests/test_account_valuations.py, tests/test_asset_snapshots.py, tests/test_issue_12_regressions.py, tests/test_valuation_contract_docs.py
    • 판정 근거: 필수 영속 데이터 계약과 캐시 책임 및 additive/legacy 보존을 충족한다. 정의 없는 loan 후보를 건너뛰는 구현과 문서가 일치한다.
  • D04-interface-contract — satisfied

    • 계약: 인터페이스 문서는 기존 auth 및 메뉴를 보존하고 평가 등록 및 조회 및 정정의 모든 입력과 유효본 및 원금 정의 출력, report 및 preview/close 및 월정산과 대사와 current API의 공통 선택, exact 기본과 실제 날짜 및 age 및 이월과 누락 및 미확인과 출처 및 버전과 승인 출력을 정의한다. 잘못된 입력과 scope 및 충돌과 부족 근거는 무변경 실패이며 기존 envelope와 required keys 및 의미 변경 정책을 명시한다.
    • 구현 근거: docs/interface-contract.md, docs/data-model.md; interface-contract.md 263-358은 등록/조회/정정 및 마감/오류/envelope와 current cache 계약을 정의한다. 338-344는 enum과 loan 허용 목적 및 필수 정의와 account type 전환 무변경 및 loan 후보 미생성을 명시한다.401-435의 실제 signature와 persisted row 출력,run replay 및 provenance/redaction 의미를 data-model33-61 및 원금 roundtrip test에 대조했다.
    • 테스트 근거: tests/test_account_valuations.py, tests/test_issue_12_regressions.py, tests/test_contract_regression.py, tests/test_valuation_contract_docs.py, tests/test_issue_12_review59_account.py
    • 판정 근거: 입출력 및 검증과 조건부 마감 계약을 충족한다. 별도 원금 출력 표를 새 의무로 요구하지 않았으며 실제 persisted fields의 투자/대출 의미와 NULL 및0은 전체 문서 및 반환 tests에서 보존된다.
  • D05-project-structure — satisfied

    • 계약: 프로젝트 구조 문서는 기존 source와 test 및 evidence를 보존하고 SQLite schema와 migrations, application의 assets와 account writes 및 import와 reconciliation 및 monthly 책임, 공개 facade와 MCP 및 Streamlit과 기존 세 화면 및 tests를 exact 경로로 대응한다. adapter에서 선택 정책을 복제하지 않고 대출 정의와 verified as_of 및 conditional 승인 경계를 shared application에 배치한다.
    • 구현 근거: docs/project-structure.md; project-structure.md 122-164는 source 및 test 책임과 adapter 방향을,166-212는 canonical ownership 및 보존 inventory를 정의한다. Base의 기존 인증과 메뉴 본문은 byte-preserved다.
    • 테스트 근거: tests/test_requirement_docs.py
    • 판정 근거: 공통 application 및 adapter와 SQLite 책임을 분리하고 선택 정책을 각 adapter에 복제하지 않는다. 새 제품 또는 별도 마감 엔진을 추가하지 않는다.
  • D06-runtime-flow — satisfied

    • 계약: 런타임 문서는 auth 및 메뉴를 보존하고 register/correct의 증빙 및 scope 검증과 append 및 유효본 확인 및 최신 캐시 동기화를 단일 트랜잭션으로 설명한다. 날짜 및 정책과 통화 및 대표 합산과 경고 read, preview 후 명시적 approval 및 원자적 freeze, reasoned reclose, 같은 근거의 monthly 및 대사, import와 이관 trigger 및 실패복구, retry와 concurrency 및 preview drift 재검증과 무부분쓰기, 비민감 valuation/run 상관 신호를 정의한다.
    • 구현 근거: docs/runtime-flow.md; runtime-flow.md 147-161의 valuation 등록/선택/정정,163-175의 read-only preview와 원자적 close,177-185의 import 및 대사와 월정산,187-210의 실패와 동시성 및 관찰성,221-241의 authority-drift와 replay/current guard를 문서 의무표에 대응했다. Base 본문은 byte-preserved다.
    • 테스트 근거: tests/test_account_valuations.py, tests/test_asset_snapshots.py, tests/test_issue_12_regressions.py
    • 판정 근거: 원래 인증 및 메뉴 흐름과 승인/no-write 정책을 유지한다. Account writer의 loan 정의 거부는 기존 입력 검증 및 후보 생성 경계에 해당하며 새 external call이나 새로운 승인 정책을 추가하지 않는다.
  • C16-supporting-evidence-scope — satisfied

    • 계약: 모든 changed file은 승인된 기능과 필수 supporting change 또는 테스트 evidence로 설명되고 기존 requirement ID를 임의 갱신하거나 범위 밖 제품 및 설정을 변경하지 않는다.
    • 구현 근거: dashboard/app.py, dashboard/page_views/accounts.py, dashboard/page_views/assets.py, dashboard/page_views/monthly_settlement.py, docs/data-model.md, docs/interface-contract.md, docs/project-structure.md, docs/requirements/req-003_account-valuation-history.md, docs/runtime-flow.md, jarca_ledger_mcp/adapters/mcp/server.py, jarca_ledger_mcp/adapters/mcp/tool_contracts.py, jarca_ledger_mcp/adapters/streamlit/accounts_gateway.py, jarca_ledger_mcp/adapters/streamlit/overview_gateway.py, jarca_ledger_mcp/application/__init_.py, jarca_ledger_mcp/application/account_valuation_service.py, jarca_ledger_mcp/application/accounts_write_services.py, jarca_ledger_mcp/application/assets_service.py, jarca_ledger_mcp/application/categorization_services.py, jarca_ledger_mcp/application/cross_transfer_service.py, jarca_ledger_mcp/application/imports_service.py, jarca_ledger_mcp/application/monthly_settlement_service.py, jarca_ledger_mcp/application/reconciliation_service.py, jarca_ledger_mcp/application/review_decision_service.py, jarca_ledger_mcp/application/shared.py, jarca_ledger_mcp/application/system_services.py, jarca_ledger_mcp/application/transaction_report_services.py, jarca_ledger_mcp/application/uncategorized_workbench_service.py, jarca_ledger_mcp/infrastructure/sqlite/__init_.py, jarca_ledger_mcp/infrastructure/sqlite/connection.py, jarca_ledger_mcp/infrastructure/sqlite/migrations.py, jarca_ledger_mcp/infrastructure/sqlite/schema.py, jarca_ledger_mcp/service.py, scripts/ci_fixture_db.py, tests/test_account_valuations.py, tests/test_asset_snapshots.py, tests/test_contract_regression.py, tests/test_dashboard_app.py, tests/test_dashboard_menu_transition.py, tests/test_import_provenance_policy.py, tests/test_issue_12_regressions.py, tests/test_issue_12_review59_account.py, tests/test_issue_12_review59_readonly.py, tests/test_issue_12_review59_reports.py, tests/test_ledger_categories.py, tests/test_requirement_docs.py, tests/test_review_decision_workbench.py, tests/test_seoulpay_xlsx.py, tests/test_service.py, docs/verification/issue-12-review-60/contract-preservation-inventory.json, docs/verification/issue-12-review-60/evidence-manifest.json, docs/verification/issue-12-review-60/evidence-plan.json, docs/verification/issue-12-review-60/final-independent-review.json, docs/verification/issue-12-review-60/finding-matrix.json, docs/verification/issue-12-review-60/red-evidence.json, docs/verification/issue-12-review-61/contract-preservation-inventory.json, docs/verification/issue-12-review-61/evidence-manifest.json, docs/verification/issue-12-review-61/evidence-plan.json, docs/verification/issue-12-review-61/finding-matrix.json, docs/verification/issue-12-review-61/green-evidence.json, docs/verification/issue-12-review-61/red-evidence.json; Changed files65개를 승인 기능과 read-only propagation 및 schema/adapters/docs 또는 regression/evidence에 대응했다. 구현자 source revision1b9eda683c66d3c7129716b9899eddf61df3362d에서 현재 head까지 전체 diff는 verification metadata5개뿐이고 실행 입력은 변경되지 않았다. Manifest9개 파일 hash와 blob을 검증했다. 명령6개는 exit0이며 외부 PDF4개 skip이 기록됐다. Reviewer는 changed Python48개 compile-only 및 source/test 대조만 수행했다.
    • 테스트 근거: tests/test_account_valuations.py, tests/test_asset_snapshots.py, tests/test_contract_regression.py, tests/test_dashboard_app.py, tests/test_dashboard_menu_transition.py, tests/test_import_provenance_policy.py, tests/test_issue_12_regressions.py, tests/test_issue_12_review59_account.py, tests/test_issue_12_review59_readonly.py, tests/test_issue_12_review59_reports.py, tests/test_ledger_categories.py, tests/test_requirement_docs.py, tests/test_review_decision_workbench.py, tests/test_seoulpay_xlsx.py, tests/test_service.py
    • 판정 근거: 기존 구현자 실행 결과를 실행 입력 동일성으로 현재 판정에 연결하되 reviewer 제품 실행 또는 CI 성공으로 표현하지 않는다. Exact head status는 pending이며 CI 성공을 승인 근거로 사용하지 않는다. 구현자 evidence 경로는 보조 기록이지 새 필수 산출물이나 worker PASS에 따른 자동 승인 근거가 아니다.

범위 판정

  • 누락: 없음
  • 범위 초과: 없음
  • 명세 모순: 없음

결론

현재 head는 approve다. 기존 review61의 N01은 후보 writer 및 계좌와 import 경로, 허용 목적과 계좌 유형 전환의 무변경 guard 및 named regression으로 해소됐다. 승인 Discovery의 필수 계약과 문서5종 및 AC10개 보존을 검토했고 설명되지 않는 범위 누락 또는 초과와 명세 모순은 없다. 전체 pytest 및 browser는 reviewer가 독립 실행하지 않았으며 source/test 대조와 구현자의 revision-bound 실행 기록을 함께 판단했다. 이는 구현 명세 적합성 승인이지 merge 또는 release 승인이나 CI 성공 선언이 아니다.

## 구현 명세 적합성 검토 - Source Issue: #12 - Pull Request: #13 - Reviewed head: `3b5101128d5a2cf038b8fb84facfd9d176928c26` - Contract SHA-256: `6d86b591b022fcc722611bfec6d24e54a64216ab6f7c4098f357e25420218818` - Verdict: `approve` ### Acceptance criteria 판정 - `C01-history` — `satisfied` - 계약: 평가 계좌 FK, 기준일과 등록일, 대표 금액과 통화와 목적, 출처와 확인 상태, 증빙 식별자, 정정 연결과 사유 및 선택 시간 자료를 이력으로 보존한다. - 구현 근거: jarca_ledger_mcp/application/account_valuation_service.py, jarca_ledger_mcp/infrastructure/sqlite/schema.py, jarca_ledger_mcp/infrastructure/sqlite/migrations.py; 현재 고정 head의 구현과 named test를 해당 승인 계약에 대조했다. Source 위치: jarca_ledger_mcp/application/account_valuation_service.py _valuation 25-26; jarca_ledger_mcp/application/account_valuation_service.py record_account_valuation_candidate 93-130; jarca_ledger_mcp/application/account_valuation_service.py register_account_valuation 133-257; jarca_ledger_mcp/application/account_valuation_service.py list_account_valuations 261-266; jarca_ledger_mcp/application/account_valuation_service.py select_account_valuation 270-312; jarca_ledger_mcp/application/account_valuation_service.py correct_account_valuation 315-375; jarca_ledger_mcp/infrastructure/sqlite/migrations.py migrate_db 19-173; jarca_ledger_mcp/infrastructure/sqlite/migrations.py init_db 176-181. 기존 review61에서 충족하던 의미는 전체 rework diff상 유지되며 테스트 인수와 assertion 및 문서 의무와 대응했다. - 테스트 근거: tests/test_account_valuations.py - 판정 근거: 승인 계약의 해당 의미와 실패 무변경 및 기존 호환성은 보존된다. 재작업의 영향은 대출 정의 불변조건 강화이며, 이미 해소된 항목을 별도 실행 기록의 부재만으로 다시 변경 요청하지 않는다. - `C02-money-metrics` — `satisfied` - 계약: 금액 정밀도와 NULL 및 0을 보존하고 취득원가, 순납입액, 기관 표시 원금 금액과 정의 및 원문 명칭, 손익과 수익률의 계산 기준을 구분한다. 투자 대표 총평가액과 포함 현금 및 원금을 중복 합산하지 않는다. - 구현 근거: jarca_ledger_mcp/application/account_valuation_service.py, jarca_ledger_mcp/infrastructure/sqlite/schema.py, docs/data-model.md, docs/requirements/req-003_account-valuation-history.md; 현재 고정 head의 구현과 named test를 해당 승인 계약에 대조했다. Source 위치: jarca_ledger_mcp/application/account_valuation_service.py _valuation 25-26; jarca_ledger_mcp/application/account_valuation_service.py record_account_valuation_candidate 93-130; jarca_ledger_mcp/application/account_valuation_service.py register_account_valuation 133-257; jarca_ledger_mcp/application/account_valuation_service.py list_account_valuations 261-266; jarca_ledger_mcp/application/account_valuation_service.py select_account_valuation 270-312; jarca_ledger_mcp/application/account_valuation_service.py correct_account_valuation 315-375. 기존 review61에서 충족하던 의미는 전체 rework diff상 유지되며 테스트 인수와 assertion 및 문서 의무와 대응했다. - 테스트 근거: tests/test_issue_12_review59_account.py, tests/test_issue_12_regressions.py - 판정 근거: 승인 계약의 해당 의미와 실패 무변경 및 기존 호환성은 보존된다. 재작업의 영향은 대출 정의 불변조건 강화이며, 이미 해소된 항목을 별도 실행 기록의 부재만으로 다시 변경 요청하지 않는다. - `N01-loan-balance-definition` — `satisfied` - 계약: 대출 평가 기록마다 대표 부채가 원금만인지 원금과 이자 및 수수료인지 필수로 명시하고 기본값으로 추정하지 않는다. 목적 alias가 필수 정의 계약을 우회하지 않는다. - 구현 근거: jarca_ledger_mcp/application/account_valuation_service.py, docs/requirements/req-003_account-valuation-history.md, jarca_ledger_mcp/application/accounts_write_services.py, jarca_ledger_mcp/application/imports_service.py, docs/data-model.md; account_valuation_service.py 93-101는 loan candidate를 INSERT 전에 거부하고 194-203은 loan 계좌의 허용 목적과 필수 정의를 검증한다. accounts_write_services.py 65-74는 정의 없는 기존 valuation이 있으면 loan 전환을 UPDATE 전에 거부한다. test_account_valuation_edge_contracts.py 8-38,133-212는 전환 실패 무변경과 빈 이력 전환 성공, 직접/import 후보 미생성, current cache 보존, 부적합 목적 거부와 non-loan 재사용을 확인한다. test_issue_12_review59_account.py 107-128은 loan import 거래와 캐시 성공 및 valuation0을 확인한다. - 테스트 근거: tests/test_issue_12_regressions.py, tests/test_issue_12_review59_account.py, tests/test_account_valuation_edge_contracts.py - 판정 근거: 기존 review61의 N01은 모든 지적 경계에서 해소됐다. 대출 정의를 추정하거나 새 이력을 자동 재작성하지 않고, 정의 없는 후보만 저장하지 않으면서 기존 계좌 및 import 호환을 보존한다. - `C03-selection` — `satisfied` - 계약: 계좌와 통화 및 평가 목적별 유효 자료를 선택한다. exact는 당일 확인 자료만, as_of는 기준일 이하 최신 확인 자료만 사용한다. 미래 자료는 제외하고 미확인 후보는 확인 자료를 대체하거나 합산하지 않는다. 실제 기준일과 경과 일수 및 이월 상태를 반환한다. - 구현 근거: jarca_ledger_mcp/application/account_valuation_service.py, jarca_ledger_mcp/application/assets_service.py; 현재 고정 head의 구현과 named test를 해당 승인 계약에 대조했다. Source 위치: jarca_ledger_mcp/application/account_valuation_service.py _valuation 25-26; jarca_ledger_mcp/application/account_valuation_service.py record_account_valuation_candidate 93-130; jarca_ledger_mcp/application/account_valuation_service.py register_account_valuation 133-257; jarca_ledger_mcp/application/account_valuation_service.py list_account_valuations 261-266; jarca_ledger_mcp/application/account_valuation_service.py select_account_valuation 270-312; jarca_ledger_mcp/application/account_valuation_service.py correct_account_valuation 315-375; jarca_ledger_mcp/application/assets_service.py _valuation_policy 28-36; jarca_ledger_mcp/application/assets_service.py _valuation_row_state_hash 108-112; jarca_ledger_mcp/application/assets_service.py _account_valuation_items 115-215; jarca_ledger_mcp/application/assets_service.py _manual_asset_valuation_items 218-259; jarca_ledger_mcp/application/assets_service.py _snapshot_rows_for_run 262-292; jarca_ledger_mcp/application/assets_service.py _snapshot_rows_for_latest_run 295-300; jarca_ledger_mcp/application/assets_service.py _snapshot_items 303-345; jarca_ledger_mcp/application/assets_service.py _summarize_valuation_items 414-453; jarca_ledger_mcp/application/assets_service.py _snapshot_preview_from_conn 545-597; jarca_ledger_mcp/application/assets_service.py preview_asset_snapshot_close 601-623; jarca_ledger_mcp/application/assets_service.py close_asset_snapshot 626-813; jarca_ledger_mcp/application/assets_service.py create_asset_snapshot 816-836; jarca_ledger_mcp/application/assets_service.py get_asset_snapshot_report 840-928. 기존 review61에서 충족하던 의미는 전체 rework diff상 유지되며 테스트 인수와 assertion 및 문서 의무와 대응했다. - 테스트 근거: tests/test_account_valuations.py, tests/test_issue_12_regressions.py - 판정 근거: 승인 계약의 해당 의미와 실패 무변경 및 기존 호환성은 보존된다. 재작업의 영향은 대출 정의 불변조건 강화이며, 이미 해소된 항목을 별도 실행 기록의 부재만으로 다시 변경 요청하지 않는다. - `C04-correction-validation` — `satisfied` - 계약: 평가 정정은 append-only로 대상과 사유를 연결하며 다른 계좌, 통화, 목적을 참조하는 정정과 순환 및 동일 유효본의 동시 분기를 차단한다. - 구현 근거: jarca_ledger_mcp/application/account_valuation_service.py, jarca_ledger_mcp/infrastructure/sqlite/schema.py; 현재 고정 head의 구현과 named test를 해당 승인 계약에 대조했다. Source 위치: jarca_ledger_mcp/application/account_valuation_service.py _valuation 25-26; jarca_ledger_mcp/application/account_valuation_service.py record_account_valuation_candidate 93-130; jarca_ledger_mcp/application/account_valuation_service.py register_account_valuation 133-257; jarca_ledger_mcp/application/account_valuation_service.py list_account_valuations 261-266; jarca_ledger_mcp/application/account_valuation_service.py select_account_valuation 270-312; jarca_ledger_mcp/application/account_valuation_service.py correct_account_valuation 315-375. 기존 review61에서 충족하던 의미는 전체 rework diff상 유지되며 테스트 인수와 assertion 및 문서 의무와 대응했다. - 테스트 근거: tests/test_issue_12_review59_account.py, tests/test_account_valuations.py, tests/test_issue_12_regressions.py - 판정 근거: 승인 계약의 해당 의미와 실패 무변경 및 기존 호환성은 보존된다. 재작업의 영향은 대출 정의 불변조건 강화이며, 이미 해소된 항목을 별도 실행 기록의 부재만으로 다시 변경 요청하지 않는다. - `C05-current-import` — `satisfied` - 계약: 뒤늦은 과거 자료 등록으로 최신 표시값을 과거로 되돌리지 않는다. 기존 계좌 수정과 import의 최신 캐시 및 새 이력 권위를 연결하며 동기화 시각을 실제 평가일로 오인하지 않는다. - 구현 근거: jarca_ledger_mcp/application/imports_service.py, jarca_ledger_mcp/application/assets_service.py, jarca_ledger_mcp/application/accounts_write_services.py; imports_service.py 43-49의 basis 비교와 accounts_write_services.py 75-91의 historical guard를 대조했다. test_import_current_balance_authority.py는 연속 늦은 import 및 날짜 미상 근거를 검증하고 test_account_valuation_edge_contracts.py 159-177와 test_issue_12_review59_account.py 107-128은 loan 캐시 및 import 보존을 확인한다. - 테스트 근거: tests/test_issue_12_review59_account.py, tests/test_import_provenance_policy.py, tests/test_import_current_balance_authority.py, tests/test_account_basis_public_consumers.py - 판정 근거: 실제 평가일과 동기화시각을 분리하고 과거 자료의 캐시 rollback을 막는다. Loan 정의 없는 이력 미생성은 현재값 및 transaction import의 성공 의미를 축소하지 않는다. - `C06-idempotency` — `satisfied` - 계약: 동일 증빙 또는 idempotency 재입력은 동일 기록을 재사용하며 같은 키의 다른 payload는 충돌이다. 동시 정정의 분기를 차단하고 UNIQUE 계좌 및 기준일 하나로 정정 추가를 막지 않는다. - 구현 근거: jarca_ledger_mcp/application/account_valuation_service.py, jarca_ledger_mcp/infrastructure/sqlite/schema.py, jarca_ledger_mcp/infrastructure/sqlite/migrations.py, jarca_ledger_mcp/application/accounts_write_services.py, jarca_ledger_mcp/application/imports_service.py; test_account_valuation_edge_contracts.py 79-130은 동일 keyless correction 재사용과 금액 및 사유 및 source 변경 충돌,134-156은 candidate loan 실패,194-231은 non-loan candidate 동일 row 재사용 및 잘못된 금액 무변경을 확인한다. correct_account_valuation은 전체 effective payload 및 기존 child를 비교한다. - 테스트 근거: tests/test_issue_12_review59_account.py, tests/test_account_valuations.py, tests/test_issue_12_regressions.py, tests/test_account_valuation_edge_contracts.py - 판정 근거: 명시 key와 keyless 증빙 정정 재시도 및 다른 payload 충돌을 구분한다. 기존 review60의 첫 정정만 검증한다는 서술은 오류였으며 명시 key replay는 당시부터 검증돼 있었음을 유지한다. - `C07-close-immutability` — `satisfied` - 계약: 기존 asset_snapshots와 correction run을 보존하고 평가 정정 및 거래 추가로 기존 마감을 자동 변경하지 않는다. 동일 기준일 재마감은 사유와 이전 run 연결을 가진 새 버전을 원자적으로 추가한다. - 구현 근거: jarca_ledger_mcp/application/assets_service.py, jarca_ledger_mcp/infrastructure/sqlite/schema.py, jarca_ledger_mcp/infrastructure/sqlite/migrations.py; 현재 고정 head의 구현과 named test를 해당 승인 계약에 대조했다. Source 위치: jarca_ledger_mcp/application/assets_service.py _valuation_policy 28-36; jarca_ledger_mcp/application/assets_service.py _valuation_row_state_hash 108-112; jarca_ledger_mcp/application/assets_service.py _account_valuation_items 115-215; jarca_ledger_mcp/application/assets_service.py _manual_asset_valuation_items 218-259; jarca_ledger_mcp/application/assets_service.py _snapshot_rows_for_run 262-292; jarca_ledger_mcp/application/assets_service.py _snapshot_rows_for_latest_run 295-300; jarca_ledger_mcp/application/assets_service.py _snapshot_items 303-345; jarca_ledger_mcp/application/assets_service.py _summarize_valuation_items 414-453; jarca_ledger_mcp/application/assets_service.py _snapshot_preview_from_conn 545-597; jarca_ledger_mcp/application/assets_service.py preview_asset_snapshot_close 601-623; jarca_ledger_mcp/application/assets_service.py close_asset_snapshot 626-813; jarca_ledger_mcp/application/assets_service.py create_asset_snapshot 816-836; jarca_ledger_mcp/application/assets_service.py get_asset_snapshot_report 840-928; jarca_ledger_mcp/infrastructure/sqlite/migrations.py migrate_db 19-173; jarca_ledger_mcp/infrastructure/sqlite/migrations.py init_db 176-181. 기존 review61에서 충족하던 의미는 전체 rework diff상 유지되며 테스트 인수와 assertion 및 문서 의무와 대응했다. - 테스트 근거: tests/test_asset_snapshots.py, tests/test_issue_12_regressions.py - 판정 근거: 승인 계약의 해당 의미와 실패 무변경 및 기존 호환성은 보존된다. 재작업의 영향은 대출 정의 불변조건 강화이며, 이미 해소된 항목을 별도 실행 기록의 부재만으로 다시 변경 요청하지 않는다. - `N02-close-replay-run-binding` — `satisfied` - 계약: 마감 버전의 근거는 불변이며 동일 idempotency 요청은 원래 기록을 재사용한다. 재마감으로 과거 run 응답 및 evidence를 변경하지 않는다. - 구현 근거: jarca_ledger_mcp/application/assets_service.py, docs/interface-contract.md; 현재 고정 head의 구현과 named test를 해당 승인 계약에 대조했다. Source 위치: jarca_ledger_mcp/application/assets_service.py _valuation_policy 28-36; jarca_ledger_mcp/application/assets_service.py _valuation_row_state_hash 108-112; jarca_ledger_mcp/application/assets_service.py _account_valuation_items 115-215; jarca_ledger_mcp/application/assets_service.py _manual_asset_valuation_items 218-259; jarca_ledger_mcp/application/assets_service.py _snapshot_rows_for_run 262-292; jarca_ledger_mcp/application/assets_service.py _snapshot_rows_for_latest_run 295-300; jarca_ledger_mcp/application/assets_service.py _snapshot_items 303-345; jarca_ledger_mcp/application/assets_service.py _summarize_valuation_items 414-453; jarca_ledger_mcp/application/assets_service.py _snapshot_preview_from_conn 545-597; jarca_ledger_mcp/application/assets_service.py preview_asset_snapshot_close 601-623; jarca_ledger_mcp/application/assets_service.py close_asset_snapshot 626-813; jarca_ledger_mcp/application/assets_service.py create_asset_snapshot 816-836; jarca_ledger_mcp/application/assets_service.py get_asset_snapshot_report 840-928. 기존 review61에서 충족하던 의미는 전체 rework diff상 유지되며 테스트 인수와 assertion 및 문서 의무와 대응했다. - 테스트 근거: tests/test_issue_12_review59_reports.py, tests/test_issue_12_regressions.py, tests/test_asset_snapshot_idempotency.py - 판정 근거: 승인 계약의 해당 의미와 실패 무변경 및 기존 호환성은 보존된다. 재작업의 영향은 대출 정의 불변조건 강화이며, 이미 해소된 항목을 별도 실행 기록의 부재만으로 다시 변경 요청하지 않는다. - `C08-approved-conditional` — `satisfied` - 계약: 완전한 exact 마감, 미완료 초안, 별도 승인된 조건부 마감을 구분한다. 승인 전 누락 및 이월은 미완료 초안이고 승인 후에도 누락 제외 및 확인된 과거값 이월만 허용한다. 미확인, 미래, 기준일 미상 금액은 승인으로도 합산하지 않으며 적용과 제외와 이월 및 승인자와 시각과 사유와 근거를 고정한다. - 구현 근거: jarca_ledger_mcp/application/assets_service.py, jarca_ledger_mcp/infrastructure/sqlite/schema.py, dashboard/page_views/assets.py; 현재 고정 head의 구현과 named test를 해당 승인 계약에 대조했다. Source 위치: jarca_ledger_mcp/application/assets_service.py _valuation_policy 28-36; jarca_ledger_mcp/application/assets_service.py _valuation_row_state_hash 108-112; jarca_ledger_mcp/application/assets_service.py _account_valuation_items 115-215; jarca_ledger_mcp/application/assets_service.py _manual_asset_valuation_items 218-259; jarca_ledger_mcp/application/assets_service.py _snapshot_rows_for_run 262-292; jarca_ledger_mcp/application/assets_service.py _snapshot_rows_for_latest_run 295-300; jarca_ledger_mcp/application/assets_service.py _snapshot_items 303-345; jarca_ledger_mcp/application/assets_service.py _summarize_valuation_items 414-453; jarca_ledger_mcp/application/assets_service.py _snapshot_preview_from_conn 545-597; jarca_ledger_mcp/application/assets_service.py preview_asset_snapshot_close 601-623; jarca_ledger_mcp/application/assets_service.py close_asset_snapshot 626-813; jarca_ledger_mcp/application/assets_service.py create_asset_snapshot 816-836; jarca_ledger_mcp/application/assets_service.py get_asset_snapshot_report 840-928. 기존 review61에서 충족하던 의미는 전체 rework diff상 유지되며 테스트 인수와 assertion 및 문서 의무와 대응했다. - 테스트 근거: tests/test_issue_12_review59_reports.py, tests/test_issue_12_regressions.py, tests/test_asset_snapshots.py - 판정 근거: 승인 계약의 해당 의미와 실패 무변경 및 기존 호환성은 보존된다. 재작업의 영향은 대출 정의 불변조건 강화이며, 이미 해소된 항목을 별도 실행 기록의 부재만으로 다시 변경 요청하지 않는다. - `C09-reconciliation` — `satisfied` - 계약: 외부 확인값과 장부 계산값을 분리하고 검증된 시작잔고, 기준시점, 거래 포함 범위와 계산 완전성을 표시한다. 거래 없는 수동 투자 계좌의 대사 불가 및 거래 미수입과 평가 수동 관리 상태를 구분하고 가짜 거래를 만들지 않는다. 대사도 공통 평가 근거와 대출 대표 정의를 사용한다. - 구현 근거: jarca_ledger_mcp/application/reconciliation_service.py, jarca_ledger_mcp/application/account_valuation_service.py, jarca_ledger_mcp/application/monthly_settlement_service.py; 현재 고정 head의 구현과 named test를 해당 승인 계약에 대조했다. Source 위치: jarca_ledger_mcp/application/reconciliation_service.py get_balance_reconciliation_report 68-215; jarca_ledger_mcp/application/account_valuation_service.py _valuation 25-26; jarca_ledger_mcp/application/account_valuation_service.py record_account_valuation_candidate 93-130; jarca_ledger_mcp/application/account_valuation_service.py register_account_valuation 133-257; jarca_ledger_mcp/application/account_valuation_service.py list_account_valuations 261-266; jarca_ledger_mcp/application/account_valuation_service.py select_account_valuation 270-312; jarca_ledger_mcp/application/account_valuation_service.py correct_account_valuation 315-375; jarca_ledger_mcp/application/monthly_settlement_service.py get_monthly_settlement_summary 82-125. 기존 review61에서 충족하던 의미는 전체 rework diff상 유지되며 테스트 인수와 assertion 및 문서 의무와 대응했다. - 테스트 근거: tests/test_issue_12_review59_reports.py, tests/test_issue_12_regressions.py, tests/test_service.py - 판정 근거: 승인 계약의 해당 의미와 실패 무변경 및 기존 호환성은 보존된다. 재작업의 영향은 대출 정의 불변조건 강화이며, 이미 해소된 항목을 별도 실행 기록의 부재만으로 다시 변경 요청하지 않는다. - `C10-report-monthly-evidence` — `satisfied` - 계약: MCP와 Dashboard 및 월정산 보고에서 같은 기준일과 선택 근거 및 실제 평가일, 경과 일수, 확인 상태, 누락과 미확인 및 이월 경고, 마감 버전 및 조건부 승인 근거를 일관되게 전달한다. - 구현 근거: jarca_ledger_mcp/application/assets_service.py, jarca_ledger_mcp/application/monthly_settlement_service.py, dashboard/page_views/monthly_settlement.py, dashboard/page_views/accounts.py; 현재 고정 head의 구현과 named test를 해당 승인 계약에 대조했다. Source 위치: jarca_ledger_mcp/application/assets_service.py _valuation_policy 28-36; jarca_ledger_mcp/application/assets_service.py _valuation_row_state_hash 108-112; jarca_ledger_mcp/application/assets_service.py _account_valuation_items 115-215; jarca_ledger_mcp/application/assets_service.py _manual_asset_valuation_items 218-259; jarca_ledger_mcp/application/assets_service.py _snapshot_rows_for_run 262-292; jarca_ledger_mcp/application/assets_service.py _snapshot_rows_for_latest_run 295-300; jarca_ledger_mcp/application/assets_service.py _snapshot_items 303-345; jarca_ledger_mcp/application/assets_service.py _summarize_valuation_items 414-453; jarca_ledger_mcp/application/assets_service.py _snapshot_preview_from_conn 545-597; jarca_ledger_mcp/application/assets_service.py preview_asset_snapshot_close 601-623; jarca_ledger_mcp/application/assets_service.py close_asset_snapshot 626-813; jarca_ledger_mcp/application/assets_service.py create_asset_snapshot 816-836; jarca_ledger_mcp/application/assets_service.py get_asset_snapshot_report 840-928; jarca_ledger_mcp/application/monthly_settlement_service.py get_monthly_settlement_summary 82-125; dashboard/page_views/monthly_settlement.py page_monthly_settlement 40-269. 기존 review61에서 충족하던 의미는 전체 rework diff상 유지되며 테스트 인수와 assertion 및 문서 의무와 대응했다. - 테스트 근거: tests/test_issue_12_review59_reports.py, tests/test_issue_12_regressions.py, tests/test_service.py - 판정 근거: 승인 계약의 해당 의미와 실패 무변경 및 기존 호환성은 보존된다. 재작업의 영향은 대출 정의 불변조건 강화이며, 이미 해소된 항목을 별도 실행 기록의 부재만으로 다시 변경 요청하지 않는다. - `C11-adapter-structure` — `satisfied` - 계약: MCP와 Streamlit gateway는 공통 application을 사용하고 기존 공개 호출명과 기존 인수 및 success와 실패 error_code 및 error envelope를 가능한 한 유지한다. 새 Dashboard 인증 또는 MCP 인증을 도입하지 않는다. - 구현 근거: jarca_ledger_mcp/adapters/mcp/server.py, jarca_ledger_mcp/adapters/mcp/tool_contracts.py, jarca_ledger_mcp/adapters/streamlit/accounts_gateway.py, jarca_ledger_mcp/application/__init__.py, jarca_ledger_mcp/service.py, dashboard/page_views/accounts.py, dashboard/page_views/assets.py, dashboard/page_views/monthly_settlement.py; 현재 고정 head의 구현과 named test를 해당 승인 계약에 대조했다. Source 위치: jarca_ledger_mcp/adapters/mcp/server.py register_account_valuation 120-122; jarca_ledger_mcp/adapters/mcp/server.py list_account_valuations 125-127; jarca_ledger_mcp/adapters/mcp/server.py select_account_valuation 130-132; jarca_ledger_mcp/adapters/mcp/server.py correct_account_valuation 135-138; jarca_ledger_mcp/adapters/mcp/server.py preview_asset_snapshot_close 165-167; jarca_ledger_mcp/adapters/mcp/server.py close_asset_snapshot 170-172; jarca_ledger_mcp/adapters/mcp/server.py get_asset_snapshot_report 175-177; jarca_ledger_mcp/adapters/mcp/server.py get_balance_reconciliation_report 185-187; jarca_ledger_mcp/adapters/mcp/server.py list_reconciliation_sessions 215-217; jarca_ledger_mcp/adapters/mcp/server.py upsert_reconciliation_session 220-222; jarca_ledger_mcp/adapters/mcp/server.py close_reconciliation_session 225-227; jarca_ledger_mcp/adapters/mcp/server.py get_monthly_cashflow_report 265-267; jarca_ledger_mcp/adapters/mcp/server.py get_monthly_settlement_summary 270-272; jarca_ledger_mcp/adapters/mcp/server.py main 441-442; dashboard/page_views/monthly_settlement.py page_monthly_settlement 40-269. 기존 review61에서 충족하던 의미는 전체 rework diff상 유지되며 테스트 인수와 assertion 및 문서 의무와 대응했다. - 테스트 근거: tests/test_contract_regression.py, tests/test_issue_12_regressions.py - 판정 근거: 승인 계약의 해당 의미와 실패 무변경 및 기존 호환성은 보존된다. 재작업의 영향은 대출 정의 불변조건 강화이며, 이미 해소된 항목을 별도 실행 기록의 부재만으로 다시 변경 요청하지 않는다. - `C12-migration-legacy` — `satisfied` - 계약: schema 11의 기존 데이터와 마감 및 개인정보를 보존하고 additive하고 idempotent한 migration을 제공한다. 기준일 증거 없는 값을 임의 월말로 소급하거나 legacy snapshot에 valuation_id를 추측하여 생성하지 않는다. - 구현 근거: jarca_ledger_mcp/infrastructure/sqlite/schema.py, jarca_ledger_mcp/infrastructure/sqlite/migrations.py, jarca_ledger_mcp/application/assets_service.py; 현재 고정 head의 구현과 named test를 해당 승인 계약에 대조했다. Source 위치: jarca_ledger_mcp/infrastructure/sqlite/migrations.py migrate_db 19-173; jarca_ledger_mcp/infrastructure/sqlite/migrations.py init_db 176-181; jarca_ledger_mcp/application/assets_service.py _valuation_policy 28-36; jarca_ledger_mcp/application/assets_service.py _valuation_row_state_hash 108-112; jarca_ledger_mcp/application/assets_service.py _account_valuation_items 115-215; jarca_ledger_mcp/application/assets_service.py _manual_asset_valuation_items 218-259; jarca_ledger_mcp/application/assets_service.py _snapshot_rows_for_run 262-292; jarca_ledger_mcp/application/assets_service.py _snapshot_rows_for_latest_run 295-300; jarca_ledger_mcp/application/assets_service.py _snapshot_items 303-345; jarca_ledger_mcp/application/assets_service.py _summarize_valuation_items 414-453; jarca_ledger_mcp/application/assets_service.py _snapshot_preview_from_conn 545-597; jarca_ledger_mcp/application/assets_service.py preview_asset_snapshot_close 601-623; jarca_ledger_mcp/application/assets_service.py close_asset_snapshot 626-813; jarca_ledger_mcp/application/assets_service.py create_asset_snapshot 816-836; jarca_ledger_mcp/application/assets_service.py get_asset_snapshot_report 840-928. 기존 review61에서 충족하던 의미는 전체 rework diff상 유지되며 테스트 인수와 assertion 및 문서 의무와 대응했다. - 테스트 근거: tests/test_account_valuations.py, tests/test_issue_12_regressions.py, tests/test_ledger_categories.py, tests/test_review_decision_workbench.py - 판정 근거: 승인 계약의 해당 의미와 실패 무변경 및 기존 호환성은 보존된다. 재작업의 영향은 대출 정의 불변조건 강화이며, 이미 해소된 항목을 별도 실행 기록의 부재만으로 다시 변경 요청하지 않는다. - `C13-read-only` — `satisfied` - 계약: preview와 조회 및 Dashboard 렌더링은 금융 쓰기를 실행하지 않는다. 명시적 등록, 정정, 승인 close 및 import 제출만 변경을 수행하고 실패 시 부분 쓰기를 남기지 않는다. - 구현 근거: jarca_ledger_mcp/infrastructure/sqlite/connection.py, jarca_ledger_mcp/application/shared.py, jarca_ledger_mcp/application/system_services.py, jarca_ledger_mcp/application/account_valuation_service.py, jarca_ledger_mcp/application/assets_service.py; 현재 고정 head의 구현과 named test를 해당 승인 계약에 대조했다. Source 위치: jarca_ledger_mcp/infrastructure/sqlite/connection.py connect_readonly 31-43; jarca_ledger_mcp/infrastructure/sqlite/connection.py read_db 47-53; jarca_ledger_mcp/application/shared.py read_operation 128-138; jarca_ledger_mcp/application/shared.py normalize_snapshot_at 181-198; jarca_ledger_mcp/application/system_services.py health_check_readonly 35-40; jarca_ledger_mcp/application/system_services.py _readonly_sqlite_connection 63-66; jarca_ledger_mcp/application/system_services.py _safe_monthly_aggregates 78-95; jarca_ledger_mcp/application/account_valuation_service.py _valuation 25-26; jarca_ledger_mcp/application/account_valuation_service.py record_account_valuation_candidate 93-130; jarca_ledger_mcp/application/account_valuation_service.py register_account_valuation 133-257; jarca_ledger_mcp/application/account_valuation_service.py list_account_valuations 261-266; jarca_ledger_mcp/application/account_valuation_service.py select_account_valuation 270-312; jarca_ledger_mcp/application/account_valuation_service.py correct_account_valuation 315-375; jarca_ledger_mcp/application/assets_service.py _valuation_policy 28-36; jarca_ledger_mcp/application/assets_service.py _valuation_row_state_hash 108-112; jarca_ledger_mcp/application/assets_service.py _account_valuation_items 115-215; jarca_ledger_mcp/application/assets_service.py _manual_asset_valuation_items 218-259; jarca_ledger_mcp/application/assets_service.py _snapshot_rows_for_run 262-292; jarca_ledger_mcp/application/assets_service.py _snapshot_rows_for_latest_run 295-300; jarca_ledger_mcp/application/assets_service.py _snapshot_items 303-345; jarca_ledger_mcp/application/assets_service.py _summarize_valuation_items 414-453; jarca_ledger_mcp/application/assets_service.py _snapshot_preview_from_conn 545-597; jarca_ledger_mcp/application/assets_service.py preview_asset_snapshot_close 601-623; jarca_ledger_mcp/application/assets_service.py close_asset_snapshot 626-813; jarca_ledger_mcp/application/assets_service.py create_asset_snapshot 816-836; jarca_ledger_mcp/application/assets_service.py get_asset_snapshot_report 840-928. 기존 review61에서 충족하던 의미는 전체 rework diff상 유지되며 테스트 인수와 assertion 및 문서 의무와 대응했다. - 테스트 근거: tests/test_issue_12_review59_readonly.py, tests/test_dashboard_app.py, tests/test_dashboard_menu_transition.py - 판정 근거: 승인 계약의 해당 의미와 실패 무변경 및 기존 호환성은 보존된다. 재작업의 영향은 대출 정의 불변조건 강화이며, 이미 해소된 항목을 별도 실행 기록의 부재만으로 다시 변경 요청하지 않는다. - `C14-auth-menu-preservation` — `satisfied` - 계약: Dashboard 인증은 DB보다 먼저이며 REQ-001의 cookie와 logout 및 REQ-002의 메뉴 label과 order, shell, query, error와 retry 및 명시적 금융 쓰기 계약을 유지한다. - 구현 근거: dashboard/app.py, dashboard/page_views/accounts.py, dashboard/page_views/assets.py, dashboard/page_views/monthly_settlement.py, docs/interface-contract.md, docs/project-structure.md, docs/runtime-flow.md; 현재 고정 head의 구현과 named test를 해당 승인 계약에 대조했다. Source 위치: dashboard/app.py main 37-72; dashboard/page_views/monthly_settlement.py page_monthly_settlement 40-269. 기존 review61에서 충족하던 의미는 전체 rework diff상 유지되며 테스트 인수와 assertion 및 문서 의무와 대응했다. - 테스트 근거: tests/test_dashboard_menu_transition.py, tests/test_dashboard_app.py - 판정 근거: 승인 계약의 해당 의미와 실패 무변경 및 기존 호환성은 보존된다. 재작업의 영향은 대출 정의 불변조건 강화이며, 이미 해소된 항목을 별도 실행 기록의 부재만으로 다시 변경 요청하지 않는다. - `C15-exclusions-privacy` — `satisfied` - 계약: 증권사 자동 연동, 정확한 성과 또는 환율 엔진, 새 인증, 별도 월정산 제품, 거래 추론 및 기존 데이터 자동 재작성과 수기 비계좌 자산 전체 이력 재설계를 추가하지 않는다. 실제 계좌 및 금융 증빙과 credential을 로그와 문서 및 테스트에 기록하지 않는다. - 구현 근거: jarca_ledger_mcp/application/assets_service.py, jarca_ledger_mcp/application/account_valuation_service.py, jarca_ledger_mcp/application/imports_service.py, jarca_ledger_mcp/application/reconciliation_service.py, jarca_ledger_mcp/infrastructure/sqlite/schema.py, jarca_ledger_mcp/infrastructure/sqlite/migrations.py; 현재 고정 head의 구현과 named test를 해당 승인 계약에 대조했다. Source 위치: jarca_ledger_mcp/application/assets_service.py _valuation_policy 28-36; jarca_ledger_mcp/application/assets_service.py _valuation_row_state_hash 108-112; jarca_ledger_mcp/application/assets_service.py _account_valuation_items 115-215; jarca_ledger_mcp/application/assets_service.py _manual_asset_valuation_items 218-259; jarca_ledger_mcp/application/assets_service.py _snapshot_rows_for_run 262-292; jarca_ledger_mcp/application/assets_service.py _snapshot_rows_for_latest_run 295-300; jarca_ledger_mcp/application/assets_service.py _snapshot_items 303-345; jarca_ledger_mcp/application/assets_service.py _summarize_valuation_items 414-453; jarca_ledger_mcp/application/assets_service.py _snapshot_preview_from_conn 545-597; jarca_ledger_mcp/application/assets_service.py preview_asset_snapshot_close 601-623; jarca_ledger_mcp/application/assets_service.py close_asset_snapshot 626-813; jarca_ledger_mcp/application/assets_service.py create_asset_snapshot 816-836; jarca_ledger_mcp/application/assets_service.py get_asset_snapshot_report 840-928; jarca_ledger_mcp/application/account_valuation_service.py _valuation 25-26; jarca_ledger_mcp/application/account_valuation_service.py record_account_valuation_candidate 93-130; jarca_ledger_mcp/application/account_valuation_service.py register_account_valuation 133-257; jarca_ledger_mcp/application/account_valuation_service.py list_account_valuations 261-266; jarca_ledger_mcp/application/account_valuation_service.py select_account_valuation 270-312; jarca_ledger_mcp/application/account_valuation_service.py correct_account_valuation 315-375; jarca_ledger_mcp/application/imports_service.py _record_import_valuation_candidate 37-41; jarca_ledger_mcp/application/reconciliation_service.py get_balance_reconciliation_report 68-215; jarca_ledger_mcp/infrastructure/sqlite/migrations.py migrate_db 19-173; jarca_ledger_mcp/infrastructure/sqlite/migrations.py init_db 176-181. 기존 review61에서 충족하던 의미는 전체 rework diff상 유지되며 테스트 인수와 assertion 및 문서 의무와 대응했다. - 테스트 근거: tests/test_issue_12_review59_reports.py, tests/test_issue_12_regressions.py, scripts/ci_fixture_db.py - 판정 근거: 승인 계약의 해당 의미와 실패 무변경 및 기존 호환성은 보존된다. 재작업의 영향은 대출 정의 불변조건 강화이며, 이미 해소된 항목을 별도 실행 기록의 부재만으로 다시 변경 요청하지 않는다. - `D01-requirement-structure` — `satisfied` - 계약: 신규 REQ-003을 배정 경로와 제목으로 작성하며 trusted harness README와 TEMPLATE의 JSON metadata, 연속 요구사항 및 AC, 필수 섹션, 판정 기준과 검증 및 검증 분류의 수준과 백엔드와 케이스 및 상태 불변조건을 충족한다. 초기 PR은 미정이며 PR 생성 후 실제 번호를 추적한다. - 구현 근거: docs/requirements/req-003_account-valuation-history.md; req-003_account-valuation-history.md 1-16의 metadata 및 식별자와 추적성,51-174의 요구사항,187-297의 전체 AC10개 및299-317의 필수 섹션을 trusted README와 TEMPLATE에 대응했다. 요구 문서 lifecycle은 PR 구현 승인과 분리된다. - 테스트 근거: tests/test_requirement_docs.py - 판정 근거: 신규 요구사항 REQ003 exact 경로와 제목 및 구조를 유지한다. 이전 review61 requirement의 AC10개 전체 블록은 현재 문서와 byte-identical하여 인수 의미와 검증 및 불변조건의 축소가 없다. - `D02-requirement-semantics` — `satisfied` - 계약: 요구사항에는 평가 근거와 지표 정의, 선택과 future 제외, 정정 및 idempotency 충돌, 대사 완전성, current 및 import 연계, 마감 상태와 불변성과 승인, shared adapter 및 인증, migration과 legacy를 소스 및 테스트에 대응한다. 모든 승인된 경계와 회귀 사례를 인수 기준으로 내린다. - 구현 근거: docs/requirements/req-003_account-valuation-history.md; Discovery의 전체 문서 의무표와 포함 범위 및 확정 결정에 모든 REQ003 하위 요구사항 및 AC를 대응했다. 기존 AC10개 전체 블록의 동일성을 확인했고 검증 참조13개를 exact head tree와 AST symbol로 확인했다. 마지막 요구사항 변경은 정의 없는 loan 후보 미생성 및 account type 전환 guard를 명시해 원래 필수 정의 계약을 보강한다. - 테스트 근거: tests/test_account_valuations.py, tests/test_asset_snapshots.py, tests/test_issue_12_regressions.py, tests/test_requirement_docs.py, tests/test_mcp_http_runtime.py, tests/test_dashboard_authentication_app.py - 판정 근거: 기존 금융 인수 의미와 인증 및 메뉴 보존을 유지한다. 반복 서술 부재나 별도 response 표 부재를 새 의무로 만들지 않았으며 참조된 unchanged 테스트도 실제 source에서 검증했다. - `D03-data-model` — `satisfied` - 계약: 신규 데이터 모델은 기존 entities 및 valuation과 마감의 관계, FK와 날짜 및 정확한 금액과 NULL 및 0과 선택 지표 및 대출 필수 정의, 계좌와 통화 및 목적과 기준일의 선택 및 index와 단일 유효 정정본, 고정 적용 분류 및 출처와 상태와 누락 및 이월 및 승인 버전, 분리된 정정과 schema11 이관 및 미상 날짜와 legacy 및 최신 캐시 동기화 책임을 정의한다. - 구현 근거: docs/data-model.md; data-model.md 33-61은 영속 필드와 원금 및 NULL0 의미,82-121은 snapshot/run 고정과 승인 및 candidate 경계,123-130은 basis와 sync timestamp 및 캐시/historical authority와 loan 전환 불변조건,132-169는 관계와 이관을 명시한다. test_valuation_contract_docs.py 11-53과 대조했다. - 테스트 근거: tests/test_account_valuations.py, tests/test_asset_snapshots.py, tests/test_issue_12_regressions.py, tests/test_valuation_contract_docs.py - 판정 근거: 필수 영속 데이터 계약과 캐시 책임 및 additive/legacy 보존을 충족한다. 정의 없는 loan 후보를 건너뛰는 구현과 문서가 일치한다. - `D04-interface-contract` — `satisfied` - 계약: 인터페이스 문서는 기존 auth 및 메뉴를 보존하고 평가 등록 및 조회 및 정정의 모든 입력과 유효본 및 원금 정의 출력, report 및 preview/close 및 월정산과 대사와 current API의 공통 선택, exact 기본과 실제 날짜 및 age 및 이월과 누락 및 미확인과 출처 및 버전과 승인 출력을 정의한다. 잘못된 입력과 scope 및 충돌과 부족 근거는 무변경 실패이며 기존 envelope와 required keys 및 의미 변경 정책을 명시한다. - 구현 근거: docs/interface-contract.md, docs/data-model.md; interface-contract.md 263-358은 등록/조회/정정 및 마감/오류/envelope와 current cache 계약을 정의한다. 338-344는 enum과 loan 허용 목적 및 필수 정의와 account type 전환 무변경 및 loan 후보 미생성을 명시한다.401-435의 실제 signature와 persisted row 출력,run replay 및 provenance/redaction 의미를 data-model33-61 및 원금 roundtrip test에 대조했다. - 테스트 근거: tests/test_account_valuations.py, tests/test_issue_12_regressions.py, tests/test_contract_regression.py, tests/test_valuation_contract_docs.py, tests/test_issue_12_review59_account.py - 판정 근거: 입출력 및 검증과 조건부 마감 계약을 충족한다. 별도 원금 출력 표를 새 의무로 요구하지 않았으며 실제 persisted fields의 투자/대출 의미와 NULL 및0은 전체 문서 및 반환 tests에서 보존된다. - `D05-project-structure` — `satisfied` - 계약: 프로젝트 구조 문서는 기존 source와 test 및 evidence를 보존하고 SQLite schema와 migrations, application의 assets와 account writes 및 import와 reconciliation 및 monthly 책임, 공개 facade와 MCP 및 Streamlit과 기존 세 화면 및 tests를 exact 경로로 대응한다. adapter에서 선택 정책을 복제하지 않고 대출 정의와 verified as_of 및 conditional 승인 경계를 shared application에 배치한다. - 구현 근거: docs/project-structure.md; project-structure.md 122-164는 source 및 test 책임과 adapter 방향을,166-212는 canonical ownership 및 보존 inventory를 정의한다. Base의 기존 인증과 메뉴 본문은 byte-preserved다. - 테스트 근거: tests/test_requirement_docs.py - 판정 근거: 공통 application 및 adapter와 SQLite 책임을 분리하고 선택 정책을 각 adapter에 복제하지 않는다. 새 제품 또는 별도 마감 엔진을 추가하지 않는다. - `D06-runtime-flow` — `satisfied` - 계약: 런타임 문서는 auth 및 메뉴를 보존하고 register/correct의 증빙 및 scope 검증과 append 및 유효본 확인 및 최신 캐시 동기화를 단일 트랜잭션으로 설명한다. 날짜 및 정책과 통화 및 대표 합산과 경고 read, preview 후 명시적 approval 및 원자적 freeze, reasoned reclose, 같은 근거의 monthly 및 대사, import와 이관 trigger 및 실패복구, retry와 concurrency 및 preview drift 재검증과 무부분쓰기, 비민감 valuation/run 상관 신호를 정의한다. - 구현 근거: docs/runtime-flow.md; runtime-flow.md 147-161의 valuation 등록/선택/정정,163-175의 read-only preview와 원자적 close,177-185의 import 및 대사와 월정산,187-210의 실패와 동시성 및 관찰성,221-241의 authority-drift와 replay/current guard를 문서 의무표에 대응했다. Base 본문은 byte-preserved다. - 테스트 근거: tests/test_account_valuations.py, tests/test_asset_snapshots.py, tests/test_issue_12_regressions.py - 판정 근거: 원래 인증 및 메뉴 흐름과 승인/no-write 정책을 유지한다. Account writer의 loan 정의 거부는 기존 입력 검증 및 후보 생성 경계에 해당하며 새 external call이나 새로운 승인 정책을 추가하지 않는다. - `C16-supporting-evidence-scope` — `satisfied` - 계약: 모든 changed file은 승인된 기능과 필수 supporting change 또는 테스트 evidence로 설명되고 기존 requirement ID를 임의 갱신하거나 범위 밖 제품 및 설정을 변경하지 않는다. - 구현 근거: dashboard/app.py, dashboard/page_views/accounts.py, dashboard/page_views/assets.py, dashboard/page_views/monthly_settlement.py, docs/data-model.md, docs/interface-contract.md, docs/project-structure.md, docs/requirements/req-003_account-valuation-history.md, docs/runtime-flow.md, jarca_ledger_mcp/adapters/mcp/server.py, jarca_ledger_mcp/adapters/mcp/tool_contracts.py, jarca_ledger_mcp/adapters/streamlit/accounts_gateway.py, jarca_ledger_mcp/adapters/streamlit/overview_gateway.py, jarca_ledger_mcp/application/__init__.py, jarca_ledger_mcp/application/account_valuation_service.py, jarca_ledger_mcp/application/accounts_write_services.py, jarca_ledger_mcp/application/assets_service.py, jarca_ledger_mcp/application/categorization_services.py, jarca_ledger_mcp/application/cross_transfer_service.py, jarca_ledger_mcp/application/imports_service.py, jarca_ledger_mcp/application/monthly_settlement_service.py, jarca_ledger_mcp/application/reconciliation_service.py, jarca_ledger_mcp/application/review_decision_service.py, jarca_ledger_mcp/application/shared.py, jarca_ledger_mcp/application/system_services.py, jarca_ledger_mcp/application/transaction_report_services.py, jarca_ledger_mcp/application/uncategorized_workbench_service.py, jarca_ledger_mcp/infrastructure/sqlite/__init__.py, jarca_ledger_mcp/infrastructure/sqlite/connection.py, jarca_ledger_mcp/infrastructure/sqlite/migrations.py, jarca_ledger_mcp/infrastructure/sqlite/schema.py, jarca_ledger_mcp/service.py, scripts/ci_fixture_db.py, tests/test_account_valuations.py, tests/test_asset_snapshots.py, tests/test_contract_regression.py, tests/test_dashboard_app.py, tests/test_dashboard_menu_transition.py, tests/test_import_provenance_policy.py, tests/test_issue_12_regressions.py, tests/test_issue_12_review59_account.py, tests/test_issue_12_review59_readonly.py, tests/test_issue_12_review59_reports.py, tests/test_ledger_categories.py, tests/test_requirement_docs.py, tests/test_review_decision_workbench.py, tests/test_seoulpay_xlsx.py, tests/test_service.py, docs/verification/issue-12-review-60/contract-preservation-inventory.json, docs/verification/issue-12-review-60/evidence-manifest.json, docs/verification/issue-12-review-60/evidence-plan.json, docs/verification/issue-12-review-60/final-independent-review.json, docs/verification/issue-12-review-60/finding-matrix.json, docs/verification/issue-12-review-60/red-evidence.json, docs/verification/issue-12-review-61/contract-preservation-inventory.json, docs/verification/issue-12-review-61/evidence-manifest.json, docs/verification/issue-12-review-61/evidence-plan.json, docs/verification/issue-12-review-61/finding-matrix.json, docs/verification/issue-12-review-61/green-evidence.json, docs/verification/issue-12-review-61/red-evidence.json; Changed files65개를 승인 기능과 read-only propagation 및 schema/adapters/docs 또는 regression/evidence에 대응했다. 구현자 source revision1b9eda683c66d3c7129716b9899eddf61df3362d에서 현재 head까지 전체 diff는 verification metadata5개뿐이고 실행 입력은 변경되지 않았다. Manifest9개 파일 hash와 blob을 검증했다. 명령6개는 exit0이며 외부 PDF4개 skip이 기록됐다. Reviewer는 changed Python48개 compile-only 및 source/test 대조만 수행했다. - 테스트 근거: tests/test_account_valuations.py, tests/test_asset_snapshots.py, tests/test_contract_regression.py, tests/test_dashboard_app.py, tests/test_dashboard_menu_transition.py, tests/test_import_provenance_policy.py, tests/test_issue_12_regressions.py, tests/test_issue_12_review59_account.py, tests/test_issue_12_review59_readonly.py, tests/test_issue_12_review59_reports.py, tests/test_ledger_categories.py, tests/test_requirement_docs.py, tests/test_review_decision_workbench.py, tests/test_seoulpay_xlsx.py, tests/test_service.py - 판정 근거: 기존 구현자 실행 결과를 실행 입력 동일성으로 현재 판정에 연결하되 reviewer 제품 실행 또는 CI 성공으로 표현하지 않는다. Exact head status는 pending이며 CI 성공을 승인 근거로 사용하지 않는다. 구현자 evidence 경로는 보조 기록이지 새 필수 산출물이나 worker PASS에 따른 자동 승인 근거가 아니다. ### 범위 판정 - 누락: 없음 - 범위 초과: 없음 - 명세 모순: 없음 ### 결론 현재 head는 approve다. 기존 review61의 N01은 후보 writer 및 계좌와 import 경로, 허용 목적과 계좌 유형 전환의 무변경 guard 및 named regression으로 해소됐다. 승인 Discovery의 필수 계약과 문서5종 및 AC10개 보존을 검토했고 설명되지 않는 범위 누락 또는 초과와 명세 모순은 없다. 전체 pytest 및 browser는 reviewer가 독립 실행하지 않았으며 source/test 대조와 구현자의 revision-bound 실행 기록을 함께 판단했다. 이는 구현 명세 적합성 승인이지 merge 또는 release 승인이나 CI 성공 선언이 아니다. <!-- gitea-agent:implementation-spec-review/v1 owner=jsfamily repository=jarca-ledger-mcp issue=12 pr=13 head=3b5101128d5a2cf038b8fb84facfd9d176928c26 contract-sha256=6d86b591b022fcc722611bfec6d24e54a64216ab6f7c4098f357e25420218818 result-sha256=68f3b56418c22e46b5d9d733067a6200a54f6b31ed73aa37ec4ee403412cb31e correlation=d4be5e55c9ea5eb817da065dcbb0b35415c0092282691039fa93af26465800ee -->
gitea-review-agent requested changes 2026-10-07 07:35:20 +00:00
Dismissed
gitea-review-agent left a comment
Owner

Issue #12 / PR #13 독립 코드 리뷰

  • Verdict: request_changes
  • Target: jsfamily/jarca-ledger-mcp, Issue #12, PR Issue #12: 계좌 기준일 평가 이력과 월정산 연동 구현 (#13)
  • Reviewed head: 3b5101128d5a2cf038b8fb84facfd9d176928c26
  • Base: 5813dd484196239ab1fac4ba066c5b4922fb33e6
  • Contract SHA-256: 6d86b591b022fcc722611bfec6d24e54a64216ab6f7c4098f357e25420218818
  • Spec pass: native review #62, gitea-spec-agent, 현재 head/계약에 결합된 APPROVED, stale/dismissed=false.
  • 사용 스킬: /opt/data/gitea-agent/harness/agents/review/skills/gitea-code-review/SKILL.md, version 0.1.2.

범위와 판정 근거

전체 changed files 65개, commit 15개, 전체 diff와 관련 source/test/docs를 검토했다. valuation/import/SQLite, snapshot/reconciliation/monthly, MCP/Streamlit/Dashboard의 세 read-only 독립 분석을 대조했고, 아래 중요한 후보는 main reviewer가 synthetic DB로 직접 재현했다. 승인된 Discovery는 변경하지 않았다. 요구된 핵심 흐름의 확정 결함 5건이 남아 있어 승인하지 않는다. 특히 preview 후 변경이 없어도 fingerprint를 사용하는 정상 close가 실패하므로, 전체 기존 테스트 통과가 승인 근거를 충족하지 않는다.

확정 결함

F-001 — High / 차단: 정상 preview → close fingerprint handoff가 거절됨

  • 위치: jarca_ledger_mcp/application/assets_service.py:610-621, :373-384, :635-639.
  • 조건: verified valuation 한 건을 만들고 preview_asset_snapshot_close()를 호출한 뒤, 아무 authority 변경 없이 반환된 preview_fingerprint를 동일 기준일의 close_asset_snapshot()에 전달한다.
  • 원인: preview는 _included_items를 제거한 후 public/redacted item으로 hash를 만든다. close는 raw _included_items를 hash한다. _evidence_state_hash에 포함된 비공개 필드 등이 두 표현에서 달라진다.
  • 실제 결과: preview는 success=true; 동일 fingerprint를 받은 close는 success=false, error_code=authority_drift. fingerprint를 생략한 동일 데이터의 close는 성공했다.
  • 영향/계약: 정상적인 preview 승인/고정 흐름을 막거나 호출자가 drift guard를 생략하도록 유도한다. Discovery의 preview 이후 근거 변경 재검증 및 docs/interface-contract.md:431의 같은 authority fingerprint 계약을 충족하지 않는다. 기존 테스트는 데이터 변경 후 실패만 검사해 정상 handoff 실패를 잡지 못한다.
  • 제한된 수정/재검증: public redaction 이전의 같은 canonical authority 표현으로 두 경로의 hash를 생성한다. 변경 없는 account/manual 자산 handoff 성공, 실제 변경의 no-write authority_drift를 함께 검증한다.
  • 증거: corroborated-evidence.json, unchanged_preview_close.

F-002 — Medium / 차단: idempotent close replay의 응답/근거가 최초 응답과 달라짐

  • 위치: jarca_ledger_mcp/application/assets_service.py:663-699, :743-764, :794-807, :269.
  • 조건/재현: 최초 close 후 correction reason과 idempotency key로 정정 close를 수행하고 같은 요청을 재실행한다. 추가로 서로 다른 실제 평가일의 as-of 항목과 이름 정렬 순서가 다른 account/manual 조합을 검증했다.
  • 실제 결과: 정정의 최초 warnings에는 existing_snapshot_rows가 있지만 replay에는 없다. warnings, nested provenance, included_items가 달랐다. 별도 as-of/혼합 항목 probe에서도 provenance 또는 inserted_snapshot_ids의 응답 차이를 확인했다.
  • 원인: 전체 최초 warning/item 표현을 run에 보존하지 않고 excluded/carry 일부에서 재구성한다. 최초 provenance는 첫 item의 평가일을 쓰지만 replay는 _evidence_provenance를 쓰며, 최초 삽입 순서와 replay의 name 정렬도 다르다.
  • 영향/계약: 동일 run의 감사/응답 내용이 재시도 여부에 따라 바뀌어 downstream 비교와 근거 재현을 깨뜨린다. docs/interface-contract.md:433의 replay payload equality와 Discovery의 immutable run/idempotency 요구에 해당한다. 기존 초기/zero-row replay 사례만으로 정정·계좌·혼합 날짜까지 증명되지 않는다.
  • 제한된 수정/재검증: 하나의 persisted canonical response/evidence reconstruction을 최초·replay에 공통 적용하고 warning, item 필드, mixed-date provenance, ID 순서가 결정적이도록 한다. 정상/정정, account/manual 혼합, as-of mixed-date에서 full response equality를 검증한다.
  • 증거: corroborated-evidence.json, correction_replay; probes.json.

F-003 — Medium / 차단: 항목 0개인 조건부 closed run이 순자산 시계열에서 사라짐

  • 위치: jarca_ledger_mcp/application/assets_service.py:946-959.
  • 조건: 누락 계좌를 명시적으로 제외 승인하여 inserted_count=0인 conditional close를 만들고 해당 기간의 get_net_worth_timeseries()를 조회한다.
  • 실제 결과: run은 저장되고 closed report는 is_closed_snapshot=true지만, 시계열의 points는 빈 배열이다.
  • 원인: basis date를 asset_snapshots에서만 수집하며, zero-row close의 정본인 asset_snapshot_runs는 enumeration에 포함하지 않는다.
  • 영향/계약: 명시적으로 마감한 기간이 미마감/부재처럼 보이고 해당 run의 승인·제외·버전 provenance가 시계열에서 사라진다. Discovery의 조건부 마감 상태 보존 및 docs/interface-contract.md:419,429의 timeseries provenance 전파에 해당한다. zero-row close/replay/report 테스트는 시계열을 확인하지 않는다.
  • 제한된 수정/재검증: legacy snapshot 날짜와 run 날짜를 함께 enumerate하고 최신 run을 정본으로 조회한다. zero-row conditional initial/correction run의 0 합계, 상태, 승인, 제외 및 alias를 시계열에서 확인한다.
  • 증거: probes.json, zero_row_timeseries.

F-004 — Medium / 차단: closed report가 저장된 valuation identity/통화를 누락함

  • 위치: jarca_ledger_mcp/application/assets_service.py:303-345; 저장 경로 :715-743.
  • 조건: verified account valuation을 마감한 후 get_asset_snapshot_report()로 같은 기준일을 재조회한다.
  • 실제 결과: close included_items[0]에는 valuation_id와 currency=KRW가 있지만 closed report item에는 두 필드가 없다. DB row/run evidence에는 값이 저장되어 있다.
  • 원인: _snapshot_items()에서 frozen row/evidence를 public item으로 구성할 때 해당 필드를 복원하지 않는다.
  • 영향/계약: closed report/MCP·월정산 소비자가 어떤 평가본/통화가 고정됐는지 직접 식별할 수 없다. Discovery의 selected valuation ID·적용 통화·근거 저장/재조회와 interface canonical read rule에 해당한다. 미래 live valuation을 다시 조회해서 보완하면 immutable close 의미가 깨지므로 저장된 근거로 반환해야 한다.
  • 제한된 수정/재검증: frozen snapshot/run evidence의 valuation_id, currency, 선택 정책을 allowlisted item에 복원한다. live valuation 정정 이후에도 closed/report/timeseries/monthly에서 같은 frozen identity·currency가 유지되는지 검증한다. legacy 근거는 추측해 ID를 만들지 않는다.
  • 증거: corroborated-evidence.json, closed_item_identity.

F-005 — Medium / 차단: 잔액 없는 basis-only 계좌 생성이 실제 import 잔액을 막음

  • 위치: jarca_ledger_mcp/application/accounts_write_services.py:25-32; 소비 경로 jarca_ledger_mcp/application/imports_service.py:43-49.
  • 조건: create_ledger_account(last_balance=None,last_balance_basis_date="2026-07-31") 뒤 실제 dated import 잔액 50, 기준일 2026-06-30을 적용한다. 검증은 공개 계좌 생성 후 import에서 실제 사용하는 candidate/cache helper를 같은 transaction에서 실행했다.
  • 실제 결과: 계좌 생성은 성공해 잔액 NULL + 최신 basis date를 저장한다. 실제 import candidate는 이력에 저장되지만 현재 cache는 계속 NULL/2026-07-31이다.
  • 원인: 생성 경로는 balance/basis pair를 확인하지 않는다. import cache helper는 날짜만 비교하므로 금액 없는 날짜를 더 최신 잔액의 근거로 취급한다. update에는 pair 검사가 있으나 create에는 없다.
  • 영향/계약: 존재하지 않는 최신값이 실제 확인 자료의 current 표시를 억제한다. Discovery의 NULL/0 구분 및 현재 표시와 기준일 authority 연결 요구의 구현 결함이며, 최신값을 과거로 되돌리지 않는 검사를 무효 자료가 선점한다.
  • 제한된 수정/재검증: 생성/수정의 잔액·basis를 normalization 이후 함께 검증한다. 잔액이 없으면 basis-only 입력을 무변경 실패로 거부하거나 두 값을 모두 unknown으로 저장한다. None/빈 문자열/실제 0을 구분하고, 금액 없는 date가 dated import를 막지 않는 회귀를 추가한다.
  • 증거: corroborated-evidence.json, date_without_balance.

비차단 제안과 잔여 위험

  • tests/test_dashboard_app.py:181-194: no-write 검증에서 각 PRAGMA data_version 호출마다 새 연결을 연다. 해당 값의 변화를 비교하려면 같은 observer connection을 유지해야 한다. 지속 observer 또는 안정적인 DB content hash로 테스트의 검출력을 보강하는 것이 좋다. 이 제안만으로 변경 요청한 것은 아니다.
  • privacy AppTest가 markdown/text/caption만 확인하고 dataframe 값을 검사하지 않는 범위는 제한으로 남는다. 실제 source-note/memo 데이터 노출을 확정한 것은 아니다.
  • timezone not-a-zone이 받아들여지는 것도 재현했지만, Discovery가 IANA 검증 자체를 필수 범위로 확정했는지 분리해야 하므로 차단 finding으로 사용하지 않았다.
  • delegate의 same-date cache policy, parser row ordering, rollback authority 복구, helper empty-key, runtime type/DB error envelope, concurrent migration 후보는 static signal일 뿐 이 보고서에서 모두 runtime 결함으로 확정하지 않았다. 승인 범위를 확대하거나 기존 기술부채를 자동 차단으로 만들지 않았다. 동시 first migration/SQLite lock contention은 직접 실행하지 않았다.

실행과 근거 평가

  • Exact-head 독립 전체 테스트: Python 3.13.5, pytest 9.1.1, /tmp synthetic fixture, 273 passed, 4 skipped, exit 0, 84.96초. JUnit은 277 cases / failures=0 / errors=0 / skipped=4.
  • 건너뛴 4개: KB Bank PDF/password 및 Toss Securities sample PDF 부재. 운영 credential/PDF를 가져와 실행하지 않았다.
  • python -m ruff check --no-cache .: All checks passed, exit 0.
  • 변경 Python 파일 48개: in-memory compile 성공. manifest의 등록 파일 9개 SHA-256 모두 일치.
  • Git diff whitespace check 성공. 실행 후 exact HEAD 유지, tracked/untracked status clean.
  • 최초 NFS artifact 경로 기반 전체 pytest는 240초 timeout(exit -15), backup workflow 구간에서 중단됐다. 같은 head/환경을 로컬 /tmp fixture로 재실행해 전체 통과했다. 환경 경로 차이로 제한하고 제품 성능 결함으로 단정하지 않는다.
  • 위 재현 probe들은 실행 exit 0을 반환했으며, 정상 동작과 결함 응답을 JSON으로 기록했다. 첫 재현 bootstrap의 잘못된 fixture type/response key는 수정했고, 수정된 공개 signature/응답 구조로 실제 재실행한 결과만 finding 근거로 사용했다.
  • PR의 기존 green-evidence/manifest는 원래 실행 revision dbf8b543834537a9ef3bec5d684b88361c5cbaab과 그 뒤 account/loan 제한 수정의 focused 결과를 구분해 평가했다. 이번 exact-head 독립 전체 실행으로 대체 확인했다. AppTest/HTTP 테스트를 새로운 실제 browser screenshot 검증으로 표현하지 않는다.

재작업 방향

기존 PR에서 위 결함과 회귀 테스트를 제한적으로 수정한 뒤 새 head의 spec pass → code 재리뷰 순서를 따른다. 이 리뷰는 merge/deploy 승인이 아니며 reviewer가 product source·테스트·Discovery를 수정하지 않았다.

증거 artifact

Private run root: /opt/data/gitea-agent/logs/gitea-review-agent/runs/issue-12-pr-13-20261007-review2/

  • before.json, full.diff, changed-paths.json, admission-plan.json
  • pytest-local.log, pytest-local.xml, local-command-evidence.json
  • check-0.log, check-1.log, reviewer-command-evidence.json
  • probes.py, probes.json, corroborate.py, corroborated-evidence.json

Native 게시/readback 결과와 canonical lease cleanup은 별도 finalization artifact에 기록한다.

<!-- gitea-agent:code-review/v1 owner=jsfamily repository=jarca-ledger-mcp issue=12 pr=13 head=3b5101128d5a2cf038b8fb84facfd9d176928c26 contract-sha256=6d86b591b022fcc722611bfec6d24e54a64216ab6f7c4098f357e25420218818 --> # Issue #12 / PR #13 독립 코드 리뷰 - Verdict: `request_changes` - Target: `jsfamily/jarca-ledger-mcp`, Issue #12, PR #13 - Reviewed head: `3b5101128d5a2cf038b8fb84facfd9d176928c26` - Base: `5813dd484196239ab1fac4ba066c5b4922fb33e6` - Contract SHA-256: `6d86b591b022fcc722611bfec6d24e54a64216ab6f7c4098f357e25420218818` - Spec pass: native review **#62**, `gitea-spec-agent`, 현재 head/계약에 결합된 `APPROVED`, stale/dismissed=false. - 사용 스킬: `/opt/data/gitea-agent/harness/agents/review/skills/gitea-code-review/SKILL.md`, version `0.1.2`. ## 범위와 판정 근거 전체 changed files 65개, commit 15개, 전체 diff와 관련 source/test/docs를 검토했다. valuation/import/SQLite, snapshot/reconciliation/monthly, MCP/Streamlit/Dashboard의 세 read-only 독립 분석을 대조했고, 아래 중요한 후보는 main reviewer가 synthetic DB로 직접 재현했다. 승인된 Discovery는 변경하지 않았다. 요구된 핵심 흐름의 확정 결함 5건이 남아 있어 승인하지 않는다. 특히 preview 후 변경이 없어도 fingerprint를 사용하는 정상 close가 실패하므로, 전체 기존 테스트 통과가 승인 근거를 충족하지 않는다. ## 확정 결함 ### F-001 — High / 차단: 정상 preview → close fingerprint handoff가 거절됨 - 위치: `jarca_ledger_mcp/application/assets_service.py:610-621`, `:373-384`, `:635-639`. - 조건: verified valuation 한 건을 만들고 `preview_asset_snapshot_close()`를 호출한 뒤, 아무 authority 변경 없이 반환된 `preview_fingerprint`를 동일 기준일의 `close_asset_snapshot()`에 전달한다. - 원인: preview는 `_included_items`를 제거한 후 public/redacted item으로 hash를 만든다. close는 raw `_included_items`를 hash한다. `_evidence_state_hash`에 포함된 비공개 필드 등이 두 표현에서 달라진다. - 실제 결과: preview는 `success=true`; 동일 fingerprint를 받은 close는 `success=false, error_code=authority_drift`. fingerprint를 생략한 동일 데이터의 close는 성공했다. - 영향/계약: 정상적인 preview 승인/고정 흐름을 막거나 호출자가 drift guard를 생략하도록 유도한다. Discovery의 preview 이후 근거 변경 재검증 및 `docs/interface-contract.md:431`의 같은 authority fingerprint 계약을 충족하지 않는다. 기존 테스트는 데이터 변경 후 실패만 검사해 정상 handoff 실패를 잡지 못한다. - 제한된 수정/재검증: public redaction 이전의 같은 canonical authority 표현으로 두 경로의 hash를 생성한다. 변경 없는 account/manual 자산 handoff 성공, 실제 변경의 no-write `authority_drift`를 함께 검증한다. - 증거: `corroborated-evidence.json`, `unchanged_preview_close`. ### F-002 — Medium / 차단: idempotent close replay의 응답/근거가 최초 응답과 달라짐 - 위치: `jarca_ledger_mcp/application/assets_service.py:663-699`, `:743-764`, `:794-807`, `:269`. - 조건/재현: 최초 close 후 correction reason과 idempotency key로 정정 close를 수행하고 같은 요청을 재실행한다. 추가로 서로 다른 실제 평가일의 as-of 항목과 이름 정렬 순서가 다른 account/manual 조합을 검증했다. - 실제 결과: 정정의 최초 `warnings`에는 `existing_snapshot_rows`가 있지만 replay에는 없다. `warnings`, nested `provenance`, `included_items`가 달랐다. 별도 as-of/혼합 항목 probe에서도 provenance 또는 `inserted_snapshot_ids`의 응답 차이를 확인했다. - 원인: 전체 최초 warning/item 표현을 run에 보존하지 않고 excluded/carry 일부에서 재구성한다. 최초 provenance는 첫 item의 평가일을 쓰지만 replay는 `_evidence_provenance`를 쓰며, 최초 삽입 순서와 replay의 name 정렬도 다르다. - 영향/계약: 동일 run의 감사/응답 내용이 재시도 여부에 따라 바뀌어 downstream 비교와 근거 재현을 깨뜨린다. `docs/interface-contract.md:433`의 replay payload equality와 Discovery의 immutable run/idempotency 요구에 해당한다. 기존 초기/zero-row replay 사례만으로 정정·계좌·혼합 날짜까지 증명되지 않는다. - 제한된 수정/재검증: 하나의 persisted canonical response/evidence reconstruction을 최초·replay에 공통 적용하고 warning, item 필드, mixed-date provenance, ID 순서가 결정적이도록 한다. 정상/정정, account/manual 혼합, as-of mixed-date에서 full response equality를 검증한다. - 증거: `corroborated-evidence.json`, `correction_replay`; `probes.json`. ### F-003 — Medium / 차단: 항목 0개인 조건부 closed run이 순자산 시계열에서 사라짐 - 위치: `jarca_ledger_mcp/application/assets_service.py:946-959`. - 조건: 누락 계좌를 명시적으로 제외 승인하여 `inserted_count=0`인 conditional close를 만들고 해당 기간의 `get_net_worth_timeseries()`를 조회한다. - 실제 결과: run은 저장되고 closed report는 `is_closed_snapshot=true`지만, 시계열의 `points`는 빈 배열이다. - 원인: basis date를 `asset_snapshots`에서만 수집하며, zero-row close의 정본인 `asset_snapshot_runs`는 enumeration에 포함하지 않는다. - 영향/계약: 명시적으로 마감한 기간이 미마감/부재처럼 보이고 해당 run의 승인·제외·버전 provenance가 시계열에서 사라진다. Discovery의 조건부 마감 상태 보존 및 `docs/interface-contract.md:419,429`의 timeseries provenance 전파에 해당한다. zero-row close/replay/report 테스트는 시계열을 확인하지 않는다. - 제한된 수정/재검증: legacy snapshot 날짜와 run 날짜를 함께 enumerate하고 최신 run을 정본으로 조회한다. zero-row conditional initial/correction run의 0 합계, 상태, 승인, 제외 및 alias를 시계열에서 확인한다. - 증거: `probes.json`, `zero_row_timeseries`. ### F-004 — Medium / 차단: closed report가 저장된 valuation identity/통화를 누락함 - 위치: `jarca_ledger_mcp/application/assets_service.py:303-345`; 저장 경로 `:715-743`. - 조건: verified account valuation을 마감한 후 `get_asset_snapshot_report()`로 같은 기준일을 재조회한다. - 실제 결과: close `included_items[0]`에는 `valuation_id`와 `currency=KRW`가 있지만 closed report item에는 두 필드가 없다. DB row/run evidence에는 값이 저장되어 있다. - 원인: `_snapshot_items()`에서 frozen row/evidence를 public item으로 구성할 때 해당 필드를 복원하지 않는다. - 영향/계약: closed report/MCP·월정산 소비자가 어떤 평가본/통화가 고정됐는지 직접 식별할 수 없다. Discovery의 selected valuation ID·적용 통화·근거 저장/재조회와 interface canonical read rule에 해당한다. 미래 live valuation을 다시 조회해서 보완하면 immutable close 의미가 깨지므로 저장된 근거로 반환해야 한다. - 제한된 수정/재검증: frozen snapshot/run evidence의 `valuation_id`, `currency`, 선택 정책을 allowlisted item에 복원한다. live valuation 정정 이후에도 closed/report/timeseries/monthly에서 같은 frozen identity·currency가 유지되는지 검증한다. legacy 근거는 추측해 ID를 만들지 않는다. - 증거: `corroborated-evidence.json`, `closed_item_identity`. ### F-005 — Medium / 차단: 잔액 없는 basis-only 계좌 생성이 실제 import 잔액을 막음 - 위치: `jarca_ledger_mcp/application/accounts_write_services.py:25-32`; 소비 경로 `jarca_ledger_mcp/application/imports_service.py:43-49`. - 조건: `create_ledger_account(last_balance=None,last_balance_basis_date="2026-07-31")` 뒤 실제 dated import 잔액 50, 기준일 `2026-06-30`을 적용한다. 검증은 공개 계좌 생성 후 import에서 실제 사용하는 candidate/cache helper를 같은 transaction에서 실행했다. - 실제 결과: 계좌 생성은 성공해 잔액 NULL + 최신 basis date를 저장한다. 실제 import candidate는 이력에 저장되지만 현재 cache는 계속 NULL/2026-07-31이다. - 원인: 생성 경로는 balance/basis pair를 확인하지 않는다. import cache helper는 날짜만 비교하므로 금액 없는 날짜를 더 최신 잔액의 근거로 취급한다. update에는 pair 검사가 있으나 create에는 없다. - 영향/계약: 존재하지 않는 최신값이 실제 확인 자료의 current 표시를 억제한다. Discovery의 NULL/0 구분 및 현재 표시와 기준일 authority 연결 요구의 구현 결함이며, 최신값을 과거로 되돌리지 않는 검사를 무효 자료가 선점한다. - 제한된 수정/재검증: 생성/수정의 잔액·basis를 normalization 이후 함께 검증한다. 잔액이 없으면 basis-only 입력을 무변경 실패로 거부하거나 두 값을 모두 unknown으로 저장한다. None/빈 문자열/실제 0을 구분하고, 금액 없는 date가 dated import를 막지 않는 회귀를 추가한다. - 증거: `corroborated-evidence.json`, `date_without_balance`. ## 비차단 제안과 잔여 위험 - `tests/test_dashboard_app.py:181-194`: no-write 검증에서 각 `PRAGMA data_version` 호출마다 새 연결을 연다. 해당 값의 변화를 비교하려면 같은 observer connection을 유지해야 한다. 지속 observer 또는 안정적인 DB content hash로 테스트의 검출력을 보강하는 것이 좋다. 이 제안만으로 변경 요청한 것은 아니다. - privacy AppTest가 markdown/text/caption만 확인하고 dataframe 값을 검사하지 않는 범위는 제한으로 남는다. 실제 source-note/memo 데이터 노출을 확정한 것은 아니다. - timezone `not-a-zone`이 받아들여지는 것도 재현했지만, Discovery가 IANA 검증 자체를 필수 범위로 확정했는지 분리해야 하므로 차단 finding으로 사용하지 않았다. - delegate의 same-date cache policy, parser row ordering, rollback authority 복구, helper empty-key, runtime type/DB error envelope, concurrent migration 후보는 static signal일 뿐 이 보고서에서 모두 runtime 결함으로 확정하지 않았다. 승인 범위를 확대하거나 기존 기술부채를 자동 차단으로 만들지 않았다. 동시 first migration/SQLite lock contention은 직접 실행하지 않았다. ## 실행과 근거 평가 - Exact-head 독립 전체 테스트: Python **3.13.5**, pytest **9.1.1**, `/tmp` synthetic fixture, **273 passed, 4 skipped**, exit **0**, 84.96초. JUnit은 277 cases / failures=0 / errors=0 / skipped=4. - 건너뛴 4개: KB Bank PDF/password 및 Toss Securities sample PDF 부재. 운영 credential/PDF를 가져와 실행하지 않았다. - `python -m ruff check --no-cache .`: **All checks passed**, exit **0**. - 변경 Python 파일 **48개**: in-memory compile 성공. manifest의 등록 파일 **9개** SHA-256 모두 일치. - Git diff whitespace check 성공. 실행 후 exact HEAD 유지, tracked/untracked status clean. - 최초 NFS artifact 경로 기반 전체 pytest는 240초 timeout(exit -15), backup workflow 구간에서 중단됐다. 같은 head/환경을 로컬 `/tmp` fixture로 재실행해 전체 통과했다. 환경 경로 차이로 제한하고 제품 성능 결함으로 단정하지 않는다. - 위 재현 probe들은 실행 exit 0을 반환했으며, 정상 동작과 결함 응답을 JSON으로 기록했다. 첫 재현 bootstrap의 잘못된 fixture type/response key는 수정했고, 수정된 공개 signature/응답 구조로 실제 재실행한 결과만 finding 근거로 사용했다. - PR의 기존 green-evidence/manifest는 원래 실행 revision `dbf8b543834537a9ef3bec5d684b88361c5cbaab`과 그 뒤 account/loan 제한 수정의 focused 결과를 구분해 평가했다. 이번 exact-head 독립 전체 실행으로 대체 확인했다. AppTest/HTTP 테스트를 새로운 실제 browser screenshot 검증으로 표현하지 않는다. ## 재작업 방향 기존 PR에서 위 결함과 회귀 테스트를 제한적으로 수정한 뒤 **새 head의 spec pass → code 재리뷰** 순서를 따른다. 이 리뷰는 merge/deploy 승인이 아니며 reviewer가 product source·테스트·Discovery를 수정하지 않았다. ## 증거 artifact Private run root: `/opt/data/gitea-agent/logs/gitea-review-agent/runs/issue-12-pr-13-20261007-review2/` - `before.json`, `full.diff`, `changed-paths.json`, `admission-plan.json` - `pytest-local.log`, `pytest-local.xml`, `local-command-evidence.json` - `check-0.log`, `check-1.log`, `reviewer-command-evidence.json` - `probes.py`, `probes.json`, `corroborate.py`, `corroborated-evidence.json` Native 게시/readback 결과와 canonical lease cleanup은 별도 finalization artifact에 기록한다.
gitea-impl-agent added 7 commits 2026-10-07 08:47:47 +00:00
Author
Owner

Review #63 재작업 완료

  • Reviewed head: 3b5101128d5a2cf038b8fb84facfd9d176928c26
  • Rework head: c7a9cfa50d25ac68b6b722b415dc89bea8f2ae24
  • Functional evidence source: 3db086a7fd15e9152a57fb95ab7942c6dc3be2b1

해결된 findings

  • F-001: preview→close fingerprint 표현 통일 및 실제 authority drift 무변경 거부
  • F-002: 최초·정정·혼합 close의 idempotent replay 응답·근거 동일성 보장
  • F-003: zero-row conditional close를 timeseries 정본으로 보존
  • F-004: closed report의 frozen valuation_id·currency 복원
  • F-005: basis-only 계좌 생성을 mutation 전에 거부
  • F-006: 다중 correction chain replay를 보존하되 최신 correction 이후 unrelated live-authority drift는 idempotency_conflict로 거부

검증

  • named Review #63/F-006 regressions: 8 passed
  • full suite: 281 passed, 4 skipped, 1 warning
  • Ruff, compileall, git diff --check main...HEAD: PASS
  • canonical evidence manifest: PASS
  • exact-head independent specification gate: PASS, findings 0
  • exact-head independent code/security/provenance gate: PASS, findings 0

Reviewer-accessible evidence: docs/verification/issue-12-review-63/

제한: private KB Bank/Toss Securities PDF fixture 부재로 4개 테스트를 skip했습니다. Gitea Actions run은 없으며 commit status는 기능 검증 근거로 사용하지 않았습니다. 현재 head에 대한 native 재검토를 요청합니다.

## Review #63 재작업 완료 - Reviewed head: `3b5101128d5a2cf038b8fb84facfd9d176928c26` - Rework head: `c7a9cfa50d25ac68b6b722b415dc89bea8f2ae24` - Functional evidence source: `3db086a7fd15e9152a57fb95ab7942c6dc3be2b1` ### 해결된 findings - F-001: preview→close fingerprint 표현 통일 및 실제 authority drift 무변경 거부 - F-002: 최초·정정·혼합 close의 idempotent replay 응답·근거 동일성 보장 - F-003: zero-row conditional close를 timeseries 정본으로 보존 - F-004: closed report의 frozen `valuation_id`·`currency` 복원 - F-005: basis-only 계좌 생성을 mutation 전에 거부 - F-006: 다중 correction chain replay를 보존하되 최신 correction 이후 unrelated live-authority drift는 `idempotency_conflict`로 거부 ### 검증 - named Review #63/F-006 regressions: `8 passed` - full suite: `281 passed, 4 skipped, 1 warning` - Ruff, compileall, `git diff --check main...HEAD`: PASS - canonical evidence manifest: PASS - exact-head independent specification gate: PASS, findings 0 - exact-head independent code/security/provenance gate: PASS, findings 0 Reviewer-accessible evidence: `docs/verification/issue-12-review-63/` 제한: private KB Bank/Toss Securities PDF fixture 부재로 4개 테스트를 skip했습니다. Gitea Actions run은 없으며 commit status는 기능 검증 근거로 사용하지 않았습니다. 현재 head에 대한 native 재검토를 요청합니다.
gitea-spec-agent requested changes 2026-10-07 12:11:30 +00:00
Dismissed
gitea-spec-agent left a comment
Owner

구현 명세 적합성 검토

Acceptance criteria 판정

  • C01-history — satisfied

    • 계약: 평가 계좌 FK, 기준일과 등록일, 대표 금액과 통화와 목적, 출처와 확인 상태, 증빙 식별자, 정정 연결과 사유 및 선택 시간 자료를 이력으로 보존한다.
    • 구현 근거: jarca_ledger_mcp/application/account_valuation_service.py, jarca_ledger_mcp/infrastructure/sqlite/schema.py, jarca_ledger_mcp/infrastructure/sqlite/migrations.py; jarca_ledger_mcp/application/account_valuation_service.py register_account_valuation 133-257; jarca_ledger_mcp/application/account_valuation_service.py list_account_valuations 261-266. schema.py:229-267의 이력 필드 및 scope와 idempotency 및 단일 child 저장 계약과 대조했다. 직전 spec review62 이후 valuation service와 해당 테스트는 byte-identical하다. N01의 candidate 차단 및 대출 purpose 제한과 정의 필수, update의 계좌 유형 전환 guard도 보존된다. named test의 실제 호출과 금액 NULL0 및 검증 실패와 conflict 및 reuse assertions를 확인했고 구현자 실행 결과를 reviewer 또는 CI 실행으로 표현하지 않는다.
    • 테스트 근거: tests/test_account_valuations.py
    • 판정 근거: 승인된 해당 요구와 기존 실패 무변경 및 호환 의미가 유지된다. 별도 반복 표나 새 CI 및 커밋 증빙 형식을 인수 조건으로 추가하지 않았다.
  • C02-money-metrics — satisfied

    • 계약: 금액 정밀도와 NULL 및 0을 보존하고 취득원가, 순납입액, 기관 표시 원금 금액과 정의 및 원문 명칭, 손익과 수익률의 계산 기준을 구분한다. 투자 대표 총평가액과 포함 현금 및 원금을 중복 합산하지 않는다.
    • 구현 근거: jarca_ledger_mcp/application/account_valuation_service.py, jarca_ledger_mcp/infrastructure/sqlite/schema.py, docs/data-model.md, docs/requirements/req-003_account-valuation-history.md; jarca_ledger_mcp/application/account_valuation_service.py _strict_int 33-42; jarca_ledger_mcp/application/account_valuation_service.py _validate_common 59-90; jarca_ledger_mcp/application/account_valuation_service.py register_account_valuation 133-257. schema.py:229-267의 이력 필드 및 scope와 idempotency 및 단일 child 저장 계약과 대조했다. 직전 spec review62 이후 valuation service와 해당 테스트는 byte-identical하다. N01의 candidate 차단 및 대출 purpose 제한과 정의 필수, update의 계좌 유형 전환 guard도 보존된다. named test의 실제 호출과 금액 NULL0 및 검증 실패와 conflict 및 reuse assertions를 확인했고 구현자 실행 결과를 reviewer 또는 CI 실행으로 표현하지 않는다.
    • 테스트 근거: tests/test_issue_12_review59_account.py, tests/test_issue_12_regressions.py
    • 판정 근거: 승인된 해당 요구와 기존 실패 무변경 및 호환 의미가 유지된다. 별도 반복 표나 새 CI 및 커밋 증빙 형식을 인수 조건으로 추가하지 않았다.
  • N01-loan-balance-definition — satisfied

    • 계약: 대출 평가 기록마다 대표 부채가 원금만인지 원금과 이자 및 수수료인지 필수로 명시하고 기본값으로 추정하지 않는다. 목적 alias가 필수 정의 계약을 우회하지 않는다.
    • 구현 근거: jarca_ledger_mcp/application/account_valuation_service.py, docs/requirements/req-003_account-valuation-history.md, jarca_ledger_mcp/application/accounts_write_services.py, jarca_ledger_mcp/application/imports_service.py, docs/data-model.md; jarca_ledger_mcp/application/account_valuation_service.py record_account_valuation_candidate 93-130; jarca_ledger_mcp/application/account_valuation_service.py register_account_valuation 133-257. schema.py:229-267의 이력 필드 및 scope와 idempotency 및 단일 child 저장 계약과 대조했다. 직전 spec review62 이후 valuation service와 해당 테스트는 byte-identical하다. N01의 candidate 차단 및 대출 purpose 제한과 정의 필수, update의 계좌 유형 전환 guard도 보존된다. named test의 실제 호출과 금액 NULL0 및 검증 실패와 conflict 및 reuse assertions를 확인했고 구현자 실행 결과를 reviewer 또는 CI 실행으로 표현하지 않는다.
    • 테스트 근거: tests/test_issue_12_regressions.py, tests/test_issue_12_review59_account.py, tests/test_account_valuation_edge_contracts.py
    • 판정 근거: 승인된 해당 요구와 기존 실패 무변경 및 호환 의미가 유지된다. 별도 반복 표나 새 CI 및 커밋 증빙 형식을 인수 조건으로 추가하지 않았다.
  • C03-selection — satisfied

    • 계약: 계좌와 통화 및 평가 목적별 유효 자료를 선택한다. exact는 당일 확인 자료만, as_of는 기준일 이하 최신 확인 자료만 사용한다. 미래 자료는 제외하고 미확인 후보는 확인 자료를 대체하거나 합산하지 않는다. 실제 기준일과 경과 일수 및 이월 상태를 반환한다.
    • 구현 근거: jarca_ledger_mcp/application/account_valuation_service.py, jarca_ledger_mcp/application/assets_service.py; jarca_ledger_mcp/application/account_valuation_service.py select_account_valuation 270-312. schema.py:229-267의 이력 필드 및 scope와 idempotency 및 단일 child 저장 계약과 대조했다. 직전 spec review62 이후 valuation service와 해당 테스트는 byte-identical하다. N01의 candidate 차단 및 대출 purpose 제한과 정의 필수, update의 계좌 유형 전환 guard도 보존된다. named test의 실제 호출과 금액 NULL0 및 검증 실패와 conflict 및 reuse assertions를 확인했고 구현자 실행 결과를 reviewer 또는 CI 실행으로 표현하지 않는다. jarca_ledger_mcp/application/assets_service.py _account_valuation_items 115-215; jarca_ledger_mcp/application/assets_service.py _manual_asset_valuation_items 218-259. verified leaf와 통화 및 목적 우선순위, 미래와 미확인 제외, actual basis와 age 및 carry를 source에 대조했다.
    • 테스트 근거: tests/test_account_valuations.py, tests/test_issue_12_regressions.py
    • 판정 근거: 승인된 해당 요구와 기존 실패 무변경 및 호환 의미가 유지된다. 별도 반복 표나 새 CI 및 커밋 증빙 형식을 인수 조건으로 추가하지 않았다.
  • C04-correction-validation — satisfied

    • 계약: 평가 정정은 append-only로 대상과 사유를 연결하며 다른 계좌, 통화, 목적을 참조하는 정정과 순환 및 동일 유효본의 동시 분기를 차단한다.
    • 구현 근거: jarca_ledger_mcp/application/account_valuation_service.py, jarca_ledger_mcp/infrastructure/sqlite/schema.py; jarca_ledger_mcp/application/account_valuation_service.py register_account_valuation 133-257; jarca_ledger_mcp/application/account_valuation_service.py correct_account_valuation 315-375. schema.py:229-267의 이력 필드 및 scope와 idempotency 및 단일 child 저장 계약과 대조했다. 직전 spec review62 이후 valuation service와 해당 테스트는 byte-identical하다. N01의 candidate 차단 및 대출 purpose 제한과 정의 필수, update의 계좌 유형 전환 guard도 보존된다. named test의 실제 호출과 금액 NULL0 및 검증 실패와 conflict 및 reuse assertions를 확인했고 구현자 실행 결과를 reviewer 또는 CI 실행으로 표현하지 않는다.
    • 테스트 근거: tests/test_issue_12_review59_account.py, tests/test_account_valuations.py, tests/test_issue_12_regressions.py
    • 판정 근거: 승인된 해당 요구와 기존 실패 무변경 및 호환 의미가 유지된다. 별도 반복 표나 새 CI 및 커밋 증빙 형식을 인수 조건으로 추가하지 않았다.
  • C05-current-import — unsatisfied

    • 계약: 뒤늦은 과거 자료 등록으로 최신 표시값을 과거로 되돌리지 않는다. 기존 계좌 수정과 import의 최신 캐시 및 새 이력 권위를 연결하며 동기화 시각을 실제 평가일로 오인하지 않는다.
    • 구현 근거: jarca_ledger_mcp/application/imports_service.py, jarca_ledger_mcp/application/assets_service.py, jarca_ledger_mcp/application/accounts_write_services.py; F005 잔여. accounts_write_services.py:28-29의 생성 guard는 무금액 기준일을 거부한다. 그러나 수정 :43-46은 last_balance 빈 문자열을 balance_update=True로 보고 :61-65에서 int 검증을 건너뛰되 UPDATE 항목에는 빈 문자열과 기준일을 모두 추가한다. :89에서 빈 TEXT 잔액과 기준일이 저장되고 :92-93 및 :5-14의 candidate 시도는 int 변환 실패로 끝난다. imports_service.py:43-49는 금액 유효성 없이 저장된 기준일만 비교해 이 날짜보다 오래된 실제 잔액을 current cache에 적용하지 못한다. docs/data-model.md:26-27과 :123-129의 exact integer 또는 NULL 및 실제 cache evidence basis 계약에 어긋난다. tests/test_issue_12_review63_accounts.py:25-76의 두 named test는 create와 이후 import만 검사하고 빈 잔액과 dated update 조합은 없다.
    • 테스트 근거: tests/test_issue_12_review59_account.py, tests/test_import_provenance_policy.py, tests/test_import_current_balance_authority.py, tests/test_account_basis_public_consumers.py, tests/test_issue_12_review63_accounts.py
    • 판정 근거: 후속 account update를 통해 금액 없는 새 기준일이 다시 최신 잔액 authority를 선점한다. NULL 또는 이전 금액이 남는다는 delegate 설명은 채택하지 않고 실제 SQL에 빈 TEXT가 저장되는 경로만 보고한다. create와 update에서 금액 및 기준일을 함께 정규화하고 무금액 기준일은 mutation 전에 거부하거나 둘 다 unknown으로 처리하되 실제 0은 허용해야 한다.
  • C06-idempotency — satisfied

    • 계약: 동일 증빙 또는 idempotency 재입력은 동일 기록을 재사용하며 같은 키의 다른 payload는 충돌이다. 동시 정정의 분기를 차단하고 UNIQUE 계좌 및 기준일 하나로 정정 추가를 막지 않는다.
    • 구현 근거: jarca_ledger_mcp/application/account_valuation_service.py, jarca_ledger_mcp/infrastructure/sqlite/schema.py, jarca_ledger_mcp/infrastructure/sqlite/migrations.py, jarca_ledger_mcp/application/accounts_write_services.py, jarca_ledger_mcp/application/imports_service.py; jarca_ledger_mcp/application/account_valuation_service.py register_account_valuation 133-257; jarca_ledger_mcp/application/account_valuation_service.py correct_account_valuation 315-375. schema.py:229-267의 이력 필드 및 scope와 idempotency 및 단일 child 저장 계약과 대조했다. 직전 spec review62 이후 valuation service와 해당 테스트는 byte-identical하다. N01의 candidate 차단 및 대출 purpose 제한과 정의 필수, update의 계좌 유형 전환 guard도 보존된다. named test의 실제 호출과 금액 NULL0 및 검증 실패와 conflict 및 reuse assertions를 확인했고 구현자 실행 결과를 reviewer 또는 CI 실행으로 표현하지 않는다.
    • 테스트 근거: tests/test_issue_12_review59_account.py, tests/test_account_valuations.py, tests/test_issue_12_regressions.py, tests/test_account_valuation_edge_contracts.py
    • 판정 근거: 승인된 해당 요구와 기존 실패 무변경 및 호환 의미가 유지된다. 별도 반복 표나 새 CI 및 커밋 증빙 형식을 인수 조건으로 추가하지 않았다.
  • C07-close-immutability — satisfied

    • 계약: 기존 asset_snapshots와 correction run을 보존하고 평가 정정 및 거래 추가로 기존 마감을 자동 변경하지 않는다. 동일 기준일 재마감은 사유와 이전 run 연결을 가진 새 버전을 원자적으로 추가한다.
    • 구현 근거: jarca_ledger_mcp/application/assets_service.py, jarca_ledger_mcp/infrastructure/sqlite/schema.py, jarca_ledger_mcp/infrastructure/sqlite/migrations.py; assets_service.py:696-735는 최신 run에서 correction chain을 추적해 이전 immutable run을 식별하고, 최신 correction authority와 current authority가 같을 때만 chain replay를 허용한다. :736은 exact existing run ID로 rows를 읽고 다른 live drift는 :777 idempotency_conflict로 끝난다. tests/test_issue_12_review63_assets.py:97-138의 F006 test는 두 후속 correction과 원래 response equality 및 관련 없는 다른 자산의 live 변경 후 conflict를 assertion한다. run과 rows의 append-only 및 close 이후 원자료 변경에도 frozen 보고 의미는 유지된다. 후보 메타데이터 replay 결함은 별도 N02에 기록했다.
    • 테스트 근거: tests/test_asset_snapshots.py, tests/test_issue_12_regressions.py, tests/test_issue_12_review63_assets.py
    • 판정 근거: 승인된 해당 요구와 기존 실패 무변경 및 호환 의미가 유지된다. 별도 반복 표나 새 CI 및 커밋 증빙 형식을 인수 조건으로 추가하지 않았다.
  • N02-close-replay-run-binding — unsatisfied

    • 계약: 마감 버전의 근거는 불변이며 동일 idempotency 요청은 원래 기록을 재사용한다. 재마감으로 과거 run 응답 및 evidence를 변경하지 않는다.
    • 구현 근거: jarca_ledger_mcp/application/assets_service.py, docs/interface-contract.md; F002 잔여. assets_service.py:584-586은 verified 항목과 함께 존재하는 unverified 후보 경고에 blocking=False를 넣는다. :819의 applied_evidence는 unverified_candidates를 보존하지 않고 :820-835는 candidate 경고를 excluded evidence로 옮기며 blocking을 버린다. :369-379와 :736-740의 replay는 이 경고를 blocking 없이 복원하고 included_items의 후보 목록도 사라진다. docs/interface-contract.md:433은 persisted replay payload equality를 정의한다. tests/test_issue_12_review63_assets.py:44-94는 mixed as_of와 correction의 replay==first를 확인하지만 이 후보 조합은 없다. tests/test_issue_12_regressions.py:339-364는 같은 verified 및 unverified 조합의 최초 close와 저장된 exclusion만 확인하며 동일 요청 replay equality는 검사하지 않는다.
    • 테스트 근거: tests/test_issue_12_review59_reports.py, tests/test_issue_12_regressions.py, tests/test_asset_snapshot_idempotency.py, tests/test_issue_12_review63_assets.py
    • 판정 근거: 같은 head의 실제 저장 및 재구성 경로가 최초 응답의 비차단 경고와 후보 메타데이터를 잃는다. 같은 요청의 top-level warnings 및 provenance.warnings와 included_items를 최초와 동등하게 보존해야 한다. 새 거래나 합계 오류로 과장하지 않으며 persisted canonical metadata를 양쪽에 일관되게 적용하고 이 조합의 equality를 확인하면 된다.
  • C08-approved-conditional — satisfied

    • 계약: 완전한 exact 마감, 미완료 초안, 별도 승인된 조건부 마감을 구분한다. 승인 전 누락 및 이월은 미완료 초안이고 승인 후에도 누락 제외 및 확인된 과거값 이월만 허용한다. 미확인, 미래, 기준일 미상 금액은 승인으로도 합산하지 않으며 적용과 제외와 이월 및 승인자와 시각과 사유와 근거를 고정한다.
    • 구현 근거: jarca_ledger_mcp/application/assets_service.py, jarca_ledger_mcp/infrastructure/sqlite/schema.py, dashboard/page_views/assets.py; assets_service.py:392-403, :635-651 및 :665-688은 public redaction 전 동일 authority fingerprint를 공유하고 실제 drift 및 승인 누락을 write 전에 거부한다. tests/test_issue_12_review63_assets.py:18-41은 manual asset의 unchanged preview handoff 성공과 changed authority의 authority_drift 및 run count 불변을 확인한다. 이 named test가 account handoff를 직접 실행한다고 표현하지 않는다. 공통 source는 두 evidence 경로를 동일하게 처리한다. 기존 별도 승인 및 미확인 합계 제외 계약도 보존된다.
    • 테스트 근거: tests/test_issue_12_review59_reports.py, tests/test_issue_12_regressions.py, tests/test_asset_snapshots.py, tests/test_issue_12_review63_assets.py
    • 판정 근거: 승인된 해당 요구와 기존 실패 무변경 및 호환 의미가 유지된다. 별도 반복 표나 새 CI 및 커밋 증빙 형식을 인수 조건으로 추가하지 않았다.
  • C09-reconciliation — satisfied

    • 계약: 외부 확인값과 장부 계산값을 분리하고 검증된 시작잔고, 기준시점, 거래 포함 범위와 계산 완전성을 표시한다. 거래 없는 수동 투자 계좌의 대사 불가 및 거래 미수입과 평가 수동 관리 상태를 구분하고 가짜 거래를 만들지 않는다. 대사도 공통 평가 근거와 대출 대표 정의를 사용한다.
    • 구현 근거: jarca_ledger_mcp/application/reconciliation_service.py, jarca_ledger_mcp/application/account_valuation_service.py, jarca_ledger_mcp/application/monthly_settlement_service.py; 현재 head의 승인 계약 대응 위치를 재확인했다. jarca_ledger_mcp/application/reconciliation_service.py _transaction_signed_amount 23-28; jarca_ledger_mcp/application/reconciliation_service.py _account_balance_row 31-64; jarca_ledger_mcp/application/reconciliation_service.py get_balance_reconciliation_report 68-215; jarca_ledger_mcp/application/account_valuation_service.py _valuation 25-26; jarca_ledger_mcp/application/account_valuation_service.py _public_candidate 29-30; jarca_ledger_mcp/application/account_valuation_service.py _strict_int 33-42; jarca_ledger_mcp/application/monthly_settlement_service.py _month_end_date 11-12; jarca_ledger_mcp/application/monthly_settlement_service.py _budget_overrun_count 15-16; jarca_ledger_mcp/application/monthly_settlement_service.py _unresolved_blocker_summary 19-30. 직전 spec review62 이후 해당 구현과 테스트 내용은 동일하며 승인 인수 의미는 보존된다. 구현자 실행 기록의 전체 source-to-head diff는 증거 JSON 네 파일뿐이며 실행 입력 변경은 없다. 구현자 결과는 focused8개와 전체281통과4skip이고 reviewer 독립 실행 또는 CI 결과가 아니다.
    • 테스트 근거: tests/test_issue_12_review59_reports.py, tests/test_issue_12_regressions.py, tests/test_service.py
    • 판정 근거: 승인된 해당 요구와 기존 실패 무변경 및 호환 의미가 유지된다. 별도 반복 표나 새 CI 및 커밋 증빙 형식을 인수 조건으로 추가하지 않았다.
  • C10-report-monthly-evidence — satisfied

    • 계약: MCP와 Dashboard 및 월정산 보고에서 같은 기준일과 선택 근거 및 실제 평가일, 경과 일수, 확인 상태, 누락과 미확인 및 이월 경고, 마감 버전 및 조건부 승인 근거를 일관되게 전달한다.
    • 구현 근거: jarca_ledger_mcp/application/assets_service.py, jarca_ledger_mcp/application/monthly_settlement_service.py, dashboard/page_views/monthly_settlement.py, dashboard/page_views/accounts.py; F003과 F004 해소. assets_service.py:1023-1038은 snapshot rows와 run-only 날짜를 함께 enumerate해 zero-row latest run을 정본으로 읽는다. :338-363은 persisted valuation_id 및 currency를 복원하되 legacy ID를 추측하지 않는다. tests/test_issue_12_review63_assets.py:141-170은 zero-row 최초 및 정정 run과 시계열 0합계 및 conditional 승인과 제외 및 alias를 assertion한다. :173-206은 closed item frozen ID와 currency 및 이후 live 변경에도 유지와 legacy ID 부재를 확인한다. 기존 reconciliation/monthly shared read model 연결과 auth 및 menu contract는 변경되지 않았다.
    • 테스트 근거: tests/test_issue_12_review59_reports.py, tests/test_issue_12_regressions.py, tests/test_service.py, tests/test_issue_12_review63_assets.py
    • 판정 근거: 승인된 해당 요구와 기존 실패 무변경 및 호환 의미가 유지된다. 별도 반복 표나 새 CI 및 커밋 증빙 형식을 인수 조건으로 추가하지 않았다.
  • C11-adapter-structure — satisfied

    • 계약: MCP와 Streamlit gateway는 공통 application을 사용하고 기존 공개 호출명과 기존 인수 및 success와 실패 error_code 및 error envelope를 가능한 한 유지한다. 새 Dashboard 인증 또는 MCP 인증을 도입하지 않는다.
    • 구현 근거: jarca_ledger_mcp/adapters/mcp/server.py, jarca_ledger_mcp/adapters/mcp/tool_contracts.py, jarca_ledger_mcp/adapters/streamlit/accounts_gateway.py, jarca_ledger_mcp/application/__init__.py, jarca_ledger_mcp/service.py, dashboard/page_views/accounts.py, dashboard/page_views/assets.py, dashboard/page_views/monthly_settlement.py; 현재 head의 승인 계약 대응 위치를 재확인했다. jarca_ledger_mcp/adapters/mcp/server.py McpRuntimeConfig 20-27; jarca_ledger_mcp/adapters/mcp/server.py _env_bool 30-34; jarca_ledger_mcp/adapters/mcp/server.py _env_int 37-44; jarca_ledger_mcp/service.py _export_public_names 50-59; jarca_ledger_mcp/service.py _ServiceModule 65-70; dashboard/page_views/accounts.py _account_balance_basis_date 34-36; dashboard/page_views/accounts.py render_accounts_list_header 39-43; dashboard/page_views/accounts.py render_account_item 46-72; dashboard/page_views/assets.py _render_asset_evidence 14-40; dashboard/page_views/assets.py page_assets 43-155; dashboard/page_views/monthly_settlement.py _render_asset_evidence 15-37; dashboard/page_views/monthly_settlement.py page_monthly_settlement 40-269. 직전 spec review62 이후 해당 구현과 테스트 내용은 동일하며 승인 인수 의미는 보존된다. 구현자 실행 기록의 전체 source-to-head diff는 증거 JSON 네 파일뿐이며 실행 입력 변경은 없다. 구현자 결과는 focused8개와 전체281통과4skip이고 reviewer 독립 실행 또는 CI 결과가 아니다.
    • 테스트 근거: tests/test_contract_regression.py, tests/test_issue_12_regressions.py
    • 판정 근거: 승인된 해당 요구와 기존 실패 무변경 및 호환 의미가 유지된다. 별도 반복 표나 새 CI 및 커밋 증빙 형식을 인수 조건으로 추가하지 않았다.
  • C12-migration-legacy — satisfied

    • 계약: schema 11의 기존 데이터와 마감 및 개인정보를 보존하고 additive하고 idempotent한 migration을 제공한다. 기준일 증거 없는 값을 임의 월말로 소급하거나 legacy snapshot에 valuation_id를 추측하여 생성하지 않는다.
    • 구현 근거: jarca_ledger_mcp/infrastructure/sqlite/schema.py, jarca_ledger_mcp/infrastructure/sqlite/migrations.py, jarca_ledger_mcp/application/assets_service.py; 현재 head의 승인 계약 대응 위치를 재확인했다. jarca_ledger_mcp/infrastructure/sqlite/migrations.py _existing_columns 8-9; jarca_ledger_mcp/infrastructure/sqlite/migrations.py _add_missing_columns 12-16; jarca_ledger_mcp/infrastructure/sqlite/migrations.py migrate_db 19-173; jarca_ledger_mcp/application/assets_service.py _valuation_policy 28-36; jarca_ledger_mcp/application/assets_service.py _canonical_provenance 39-59; jarca_ledger_mcp/application/assets_service.py _public_evidence 62-75. 변경된 source와 실제 named regression 인수 및 assertion을 prior finding의 계약과 재대조했다. 구현자 실행 기록의 전체 source-to-head diff는 증거 JSON 네 파일뿐이며 실행 입력 변경은 없다. 구현자 결과는 focused8개와 전체281통과4skip이고 reviewer 독립 실행 또는 CI 결과가 아니다.
    • 테스트 근거: tests/test_account_valuations.py, tests/test_issue_12_regressions.py, tests/test_ledger_categories.py, tests/test_review_decision_workbench.py
    • 판정 근거: 승인된 해당 요구와 기존 실패 무변경 및 호환 의미가 유지된다. 별도 반복 표나 새 CI 및 커밋 증빙 형식을 인수 조건으로 추가하지 않았다.
  • C13-read-only — satisfied

    • 계약: preview와 조회 및 Dashboard 렌더링은 금융 쓰기를 실행하지 않는다. 명시적 등록, 정정, 승인 close 및 import 제출만 변경을 수행하고 실패 시 부분 쓰기를 남기지 않는다.
    • 구현 근거: jarca_ledger_mcp/infrastructure/sqlite/connection.py, jarca_ledger_mcp/application/shared.py, jarca_ledger_mcp/application/system_services.py, jarca_ledger_mcp/application/account_valuation_service.py, jarca_ledger_mcp/application/assets_service.py; 현재 head의 승인 계약 대응 위치를 재확인했다. jarca_ledger_mcp/infrastructure/sqlite/connection.py DatabaseNotInitializedError 13-14; jarca_ledger_mcp/infrastructure/sqlite/connection.py resolve_db_path 17-19; jarca_ledger_mcp/infrastructure/sqlite/connection.py connect 22-28; jarca_ledger_mcp/application/shared.py _normalize_counterparty_for_match 64-74; jarca_ledger_mcp/application/shared.py _party_match_score 77-86; jarca_ledger_mcp/application/shared.py _append_memo_tag 89-95; jarca_ledger_mcp/application/system_services.py health_check 26-31; jarca_ledger_mcp/application/system_services.py health_check_readonly 35-40; jarca_ledger_mcp/application/system_services.py _sha256_file 43-48; jarca_ledger_mcp/application/account_valuation_service.py _valuation 25-26; jarca_ledger_mcp/application/account_valuation_service.py _public_candidate 29-30; jarca_ledger_mcp/application/account_valuation_service.py _strict_int 33-42; jarca_ledger_mcp/application/assets_service.py _valuation_policy 28-36; jarca_ledger_mcp/application/assets_service.py _canonical_provenance 39-59; jarca_ledger_mcp/application/assets_service.py _public_evidence 62-75. 변경된 source와 실제 named regression 인수 및 assertion을 prior finding의 계약과 재대조했다. 구현자 실행 기록의 전체 source-to-head diff는 증거 JSON 네 파일뿐이며 실행 입력 변경은 없다. 구현자 결과는 focused8개와 전체281통과4skip이고 reviewer 독립 실행 또는 CI 결과가 아니다.
    • 테스트 근거: tests/test_issue_12_review59_readonly.py, tests/test_dashboard_app.py, tests/test_dashboard_menu_transition.py
    • 판정 근거: 승인된 해당 요구와 기존 실패 무변경 및 호환 의미가 유지된다. 별도 반복 표나 새 CI 및 커밋 증빙 형식을 인수 조건으로 추가하지 않았다.
  • C14-auth-menu-preservation — satisfied

    • 계약: Dashboard 인증은 DB보다 먼저이며 REQ-001의 cookie와 logout 및 REQ-002의 메뉴 label과 order, shell, query, error와 retry 및 명시적 금융 쓰기 계약을 유지한다.
    • 구현 근거: dashboard/app.py, dashboard/page_views/accounts.py, dashboard/page_views/assets.py, dashboard/page_views/monthly_settlement.py, docs/interface-contract.md, docs/project-structure.md, docs/runtime-flow.md; 현재 head의 승인 계약 대응 위치를 재확인했다. dashboard/app.py main 37-72; dashboard/page_views/accounts.py _account_balance_basis_date 34-36; dashboard/page_views/accounts.py render_accounts_list_header 39-43; dashboard/page_views/accounts.py render_account_item 46-72; dashboard/page_views/assets.py _render_asset_evidence 14-40; dashboard/page_views/assets.py page_assets 43-155; dashboard/page_views/monthly_settlement.py _render_asset_evidence 15-37; dashboard/page_views/monthly_settlement.py page_monthly_settlement 40-269; docs/interface-contract.md 전체 문서와 승인 산출물 의무 대조; docs/project-structure.md 전체 문서와 승인 산출물 의무 대조; docs/runtime-flow.md 전체 문서와 승인 산출물 의무 대조. 직전 spec review62 이후 해당 구현과 테스트 내용은 동일하며 승인 인수 의미는 보존된다. 구현자 실행 기록의 전체 source-to-head diff는 증거 JSON 네 파일뿐이며 실행 입력 변경은 없다. 구현자 결과는 focused8개와 전체281통과4skip이고 reviewer 독립 실행 또는 CI 결과가 아니다.
    • 테스트 근거: tests/test_dashboard_menu_transition.py, tests/test_dashboard_app.py
    • 판정 근거: 승인된 해당 요구와 기존 실패 무변경 및 호환 의미가 유지된다. 별도 반복 표나 새 CI 및 커밋 증빙 형식을 인수 조건으로 추가하지 않았다.
  • C15-exclusions-privacy — satisfied

    • 계약: 증권사 자동 연동, 정확한 성과 또는 환율 엔진, 새 인증, 별도 월정산 제품, 거래 추론 및 기존 데이터 자동 재작성과 수기 비계좌 자산 전체 이력 재설계를 추가하지 않는다. 실제 계좌 및 금융 증빙과 credential을 로그와 문서 및 테스트에 기록하지 않는다.
    • 구현 근거: jarca_ledger_mcp/application/assets_service.py, jarca_ledger_mcp/application/account_valuation_service.py, jarca_ledger_mcp/application/imports_service.py, jarca_ledger_mcp/application/reconciliation_service.py, jarca_ledger_mcp/infrastructure/sqlite/schema.py, jarca_ledger_mcp/infrastructure/sqlite/migrations.py; 현재 head의 승인 계약 대응 위치를 재확인했다. jarca_ledger_mcp/application/assets_service.py _valuation_policy 28-36; jarca_ledger_mcp/application/assets_service.py _canonical_provenance 39-59; jarca_ledger_mcp/application/assets_service.py _public_evidence 62-75; jarca_ledger_mcp/application/account_valuation_service.py _valuation 25-26; jarca_ledger_mcp/application/account_valuation_service.py _public_candidate 29-30; jarca_ledger_mcp/application/account_valuation_service.py _strict_int 33-42; jarca_ledger_mcp/application/imports_service.py _record_import_valuation_candidate 37-41; jarca_ledger_mcp/application/imports_service.py _update_current_balance_if_newer 43-49; jarca_ledger_mcp/application/imports_service.py preview_ledger_csv_import 52-60; jarca_ledger_mcp/application/reconciliation_service.py _transaction_signed_amount 23-28; jarca_ledger_mcp/application/reconciliation_service.py _account_balance_row 31-64; jarca_ledger_mcp/application/reconciliation_service.py get_balance_reconciliation_report 68-215; jarca_ledger_mcp/infrastructure/sqlite/migrations.py _existing_columns 8-9; jarca_ledger_mcp/infrastructure/sqlite/migrations.py _add_missing_columns 12-16; jarca_ledger_mcp/infrastructure/sqlite/migrations.py migrate_db 19-173. 변경된 source와 실제 named regression 인수 및 assertion을 prior finding의 계약과 재대조했다. 구현자 실행 기록의 전체 source-to-head diff는 증거 JSON 네 파일뿐이며 실행 입력 변경은 없다. 구현자 결과는 focused8개와 전체281통과4skip이고 reviewer 독립 실행 또는 CI 결과가 아니다.
    • 테스트 근거: tests/test_issue_12_review59_reports.py, tests/test_issue_12_regressions.py, scripts/ci_fixture_db.py
    • 판정 근거: 승인된 해당 요구와 기존 실패 무변경 및 호환 의미가 유지된다. 별도 반복 표나 새 CI 및 커밋 증빙 형식을 인수 조건으로 추가하지 않았다.
  • D01-requirement-structure — satisfied

    • 계약: 신규 REQ-003을 배정 경로와 제목으로 작성하며 trusted harness README와 TEMPLATE의 JSON metadata, 연속 요구사항 및 AC, 필수 섹션, 판정 기준과 검증 및 검증 분류의 수준과 백엔드와 케이스 및 상태 불변조건을 충족한다. 초기 PR은 미정이며 PR 생성 후 실제 번호를 추적한다.
    • 구현 근거: docs/requirements/req-003_account-valuation-history.md; docs/requirements/req-003_account-valuation-history.md:1-16의 JSON metadata와 REQ-003 및 Issue12와 PR13 traceability; :51-174의 요구사항10개; :187-297의 AC10개와 판정 및 검증분류 및 불변조건; :299-317의 필수 오류 및 호환성과 추적성 section을 trusted README와 TEMPLATE exact byte snapshot에 대조했다. requirements 및 참조된7개 테스트 경로는 현재 head에서 존재하며 baseline AC 문서도 byte-identical하다. tests/test_requirement_docs.py의 actual symbols와 assertions는 static evidence이며 reviewer 실행으로 주장하지 않는다.
    • 테스트 근거: tests/test_requirement_docs.py
    • 판정 근거: 승인된 해당 요구와 기존 실패 무변경 및 호환 의미가 유지된다. 별도 반복 표나 새 CI 및 커밋 증빙 형식을 인수 조건으로 추가하지 않았다.
  • D02-requirement-semantics — satisfied

    • 계약: 요구사항에는 평가 근거와 지표 정의, 선택과 future 제외, 정정 및 idempotency 충돌, 대사 완전성, current 및 import 연계, 마감 상태와 불변성과 승인, shared adapter 및 인증, migration과 legacy를 소스 및 테스트에 대응한다. 모든 승인된 경계와 회귀 사례를 인수 기준으로 내린다.
    • 구현 근거: docs/requirements/req-003_account-valuation-history.md; docs/requirements/req-003_account-valuation-history.md:53-185 및 :187-309를 Approved Discovery 모든 포함 범위와 확정 결정 및 제외 범위에 대응했다. 이전 요구사항 전체 AC는 current head와 byte-identical하고 의미 손실이나 승인 없는 축소는 없다. 검증 근거7개 path 모두 실제 head에 존재한다. 구현의 두 잔여 결함은 C05 및 N02에 별도 기록하고 요구사항 문서의 반복 기재 부재로 판단하지 않는다.
    • 테스트 근거: tests/test_account_valuations.py, tests/test_asset_snapshots.py, tests/test_issue_12_regressions.py, tests/test_requirement_docs.py, tests/test_mcp_http_runtime.py, tests/test_dashboard_authentication_app.py
    • 판정 근거: 승인된 해당 요구와 기존 실패 무변경 및 호환 의미가 유지된다. 별도 반복 표나 새 CI 및 커밋 증빙 형식을 인수 조건으로 추가하지 않았다.
  • D03-data-model — unsatisfied

    • 계약: 신규 데이터 모델은 기존 entities 및 valuation과 마감의 관계, FK와 날짜 및 정확한 금액과 NULL 및 0과 선택 지표 및 대출 필수 정의, 계좌와 통화 및 목적과 기준일의 선택 및 index와 단일 유효 정정본, 고정 적용 분류 및 출처와 상태와 누락 및 이월 및 승인 버전, 분리된 정정과 schema11 이관 및 미상 날짜와 legacy 및 최신 캐시 동기화 책임을 정의한다.
    • 구현 근거: docs/data-model.md; Approved Discovery 데이터 모델 산출물은 계좌와 통화 및 평가 목적과 기준일 인덱스를 명시하도록 요구한다. docs/data-model.md:145-148은 single_correction 인덱스만 기술하고 :154-161은 migration이 indexes를 만든다는 일반 설명뿐이다. schema.py:264-267의 실제 account_date와 status_date 및 idempotency와 single_correction 정의를 포함해 조회 조건과 인덱스 대응 설명이 없다. 필드 표 :44-48이나 정정 parent scope 설명은 이 인덱스 설계 의무를 대신하지 않는다. 문서 구조 및 나머지 의미와 전체 AC는 이전 head에서 byte-identical하게 보존됐다.
    • 테스트 근거: tests/test_account_valuations.py, tests/test_asset_snapshots.py, tests/test_issue_12_regressions.py, tests/test_valuation_contract_docs.py
    • 판정 근거: 문서 계약 보완이다. 실제 schema의 계좌 및 통화 및 목적 및 기준일 조회와 인덱스의 대응 또는 제한을 데이터 모델에 명시해야 한다. 특정 새 복합 인덱스 DDL을 강요하지 않으며 성능 장애나 실행 결함으로 판정하지 않는다.
  • D04-interface-contract — satisfied

    • 계약: 인터페이스 문서는 기존 auth 및 메뉴를 보존하고 평가 등록 및 조회 및 정정의 모든 입력과 유효본 및 원금 정의 출력, report 및 preview/close 및 월정산과 대사와 current API의 공통 선택, exact 기본과 실제 날짜 및 age 및 이월과 누락 및 미확인과 출처 및 버전과 승인 출력을 정의한다. 잘못된 입력과 scope 및 충돌과 부족 근거는 무변경 실패이며 기존 envelope와 required keys 및 의미 변경 정책을 명시한다.
    • 구현 근거: docs/interface-contract.md, docs/data-model.md; docs/interface-contract.md:1-261의 기존 인증 및 메뉴 계약, :263-358 valuation 및 close 입력과 오류 및 무변경, :401-423 actual signature 및 persisted row와 data-model 물리 필드 의미, :425-435 close output 및 provenance 및 fingerprint와 replay 및 redaction을 문서 의무 전체와 대조했다. docs/data-model.md:33-61의 principal 및 NULL0 의미는 출력 persisted rows에 연결되고 tests/test_issue_12_review59_account.py의 roundtrip assertions가 보조한다. 반복 output 표를 별도 요구하지 않으며 replay 구현 결함은 N02에 분리했다.
    • 테스트 근거: tests/test_account_valuations.py, tests/test_issue_12_regressions.py, tests/test_contract_regression.py, tests/test_valuation_contract_docs.py, tests/test_issue_12_review59_account.py
    • 판정 근거: 승인된 해당 요구와 기존 실패 무변경 및 호환 의미가 유지된다. 별도 반복 표나 새 CI 및 커밋 증빙 형식을 인수 조건으로 추가하지 않았다.
  • D05-project-structure — satisfied

    • 계약: 프로젝트 구조 문서는 기존 source와 test 및 evidence를 보존하고 SQLite schema와 migrations, application의 assets와 account writes 및 import와 reconciliation 및 monthly 책임, 공개 facade와 MCP 및 Streamlit과 기존 세 화면 및 tests를 exact 경로로 대응한다. adapter에서 선택 정책을 복제하지 않고 대출 정의와 verified as_of 및 conditional 승인 경계를 shared application에 배치한다.
    • 구현 근거: docs/project-structure.md; docs/project-structure.md:122-164의 source와 test exact 배치 및 import와 reconciliation 및 monthly 책임; :147-164 shared application 의존 방향과 adapter 정책 비복제; :166-212 auth 및 menu inventory와 canonical ownership 및 privacy boundary를 승인 산출물 모든 의무와 대조했다. 전체 문서는 review62 head와 byte-identical하고 현재 head paths 및 해당 소스 책임과도 대응한다.
    • 테스트 근거: tests/test_requirement_docs.py
    • 판정 근거: 승인된 해당 요구와 기존 실패 무변경 및 호환 의미가 유지된다. 별도 반복 표나 새 CI 및 커밋 증빙 형식을 인수 조건으로 추가하지 않았다.
  • D06-runtime-flow — satisfied

    • 계약: 런타임 문서는 auth 및 메뉴를 보존하고 register/correct의 증빙 및 scope 검증과 append 및 유효본 확인 및 최신 캐시 동기화를 단일 트랜잭션으로 설명한다. 날짜 및 정책과 통화 및 대표 합산과 경고 read, preview 후 명시적 approval 및 원자적 freeze, reasoned reclose, 같은 근거의 monthly 및 대사, import와 이관 trigger 및 실패복구, retry와 concurrency 및 preview drift 재검증과 무부분쓰기, 비민감 valuation/run 상관 신호를 정의한다.
    • 구현 근거: docs/runtime-flow.md; docs/runtime-flow.md:147-161 등록과 정정과 verified 선택; :163-175 preview와 approval 및 atomic freeze; :177-185 current cache와 import 및 reconciliation 및 monthly; :187-210 실패 및 concurrency와 관찰성; :221-241 read-only 및 authority와 fingerprint drift 및 no-write를 산출물 의무별로 대조했다. 필수 인수 의미는 byte-identical한 baseline 문서와 보존되며 코드상 C05 및 N02 잔여는 문서 누락과 혼동하지 않는다.
    • 테스트 근거: tests/test_account_valuations.py, tests/test_asset_snapshots.py, tests/test_issue_12_regressions.py
    • 판정 근거: 승인된 해당 요구와 기존 실패 무변경 및 호환 의미가 유지된다. 별도 반복 표나 새 CI 및 커밋 증빙 형식을 인수 조건으로 추가하지 않았다.
  • C16-supporting-evidence-scope — satisfied

    • 계약: 모든 changed file은 승인된 기능과 필수 supporting change 또는 테스트 evidence로 설명되고 기존 requirement ID를 임의 갱신하거나 범위 밖 제품 및 설정을 변경하지 않는다.
    • 구현 근거: dashboard/app.py, dashboard/page_views/accounts.py, dashboard/page_views/assets.py, dashboard/page_views/monthly_settlement.py, docs/data-model.md, docs/interface-contract.md, docs/project-structure.md, docs/requirements/req-003_account-valuation-history.md, docs/runtime-flow.md, docs/verification/issue-12-review-60/contract-preservation-inventory.json, docs/verification/issue-12-review-60/evidence-manifest.json, docs/verification/issue-12-review-60/evidence-plan.json, docs/verification/issue-12-review-60/final-independent-review.json, docs/verification/issue-12-review-60/finding-matrix.json, docs/verification/issue-12-review-60/red-evidence.json, docs/verification/issue-12-review-61/contract-preservation-inventory.json, docs/verification/issue-12-review-61/evidence-manifest.json, docs/verification/issue-12-review-61/evidence-plan.json, docs/verification/issue-12-review-61/finding-matrix.json, docs/verification/issue-12-review-61/green-evidence.json, docs/verification/issue-12-review-61/red-evidence.json, docs/verification/issue-12-review-63/contract-preservation-inventory.json, docs/verification/issue-12-review-63/evidence-manifest.json, docs/verification/issue-12-review-63/evidence-plan.json, docs/verification/issue-12-review-63/finding-matrix.json, docs/verification/issue-12-review-63/red-evidence.json, jarca_ledger_mcp/adapters/mcp/server.py, jarca_ledger_mcp/adapters/mcp/tool_contracts.py, jarca_ledger_mcp/adapters/streamlit/accounts_gateway.py, jarca_ledger_mcp/adapters/streamlit/overview_gateway.py, jarca_ledger_mcp/application/__init_.py, jarca_ledger_mcp/application/account_valuation_service.py, jarca_ledger_mcp/application/accounts_write_services.py, jarca_ledger_mcp/application/assets_service.py, jarca_ledger_mcp/application/categorization_services.py, jarca_ledger_mcp/application/cross_transfer_service.py, jarca_ledger_mcp/application/imports_service.py, jarca_ledger_mcp/application/monthly_settlement_service.py, jarca_ledger_mcp/application/reconciliation_service.py, jarca_ledger_mcp/application/review_decision_service.py, jarca_ledger_mcp/application/shared.py, jarca_ledger_mcp/application/system_services.py, jarca_ledger_mcp/application/transaction_report_services.py, jarca_ledger_mcp/application/uncategorized_workbench_service.py, jarca_ledger_mcp/infrastructure/sqlite/__init_.py, jarca_ledger_mcp/infrastructure/sqlite/connection.py, jarca_ledger_mcp/infrastructure/sqlite/migrations.py, jarca_ledger_mcp/infrastructure/sqlite/schema.py, jarca_ledger_mcp/service.py, scripts/ci_fixture_db.py, tests/test_account_basis_public_consumers.py, tests/test_account_valuation_edge_contracts.py, tests/test_account_valuations.py, tests/test_asset_snapshot_idempotency.py, tests/test_asset_snapshots.py, tests/test_contract_regression.py, tests/test_dashboard_app.py, tests/test_dashboard_menu_transition.py, tests/test_import_current_balance_authority.py, tests/test_import_provenance_policy.py, tests/test_issue_12_regressions.py, tests/test_issue_12_review59_account.py, tests/test_issue_12_review59_readonly.py, tests/test_issue_12_review59_reports.py, tests/test_issue_12_review63_accounts.py, tests/test_issue_12_review63_assets.py, tests/test_ledger_categories.py, tests/test_requirement_docs.py, tests/test_review_decision_workbench.py, tests/test_seoulpay_xlsx.py, tests/test_service.py, tests/test_valuation_contract_docs.py; authoritative PR changed-file pagination72개와 git base-to-head tree를 exact-match했고 API diff182개 hunk를 각 base/head blob 줄 위치와 내용에 직접 대조했다. changed-file-coverage 운영 artifact는 각 변경을 existing criterion 또는 shared facade 및 adapter 및 domain 및 test support 또는 docs verification supporting evidence로 대응한다. review63 후속 JSON4개는 증거 정리이며 새로운 제품 산출물 의무가 아니다. 추가 source2개는 기존 fingerprint와 immutable run과 current-cache boundary 보강이고 tests2개는 named regression이다. 현재 evidence source의9개 blob OID와 SHA256 및 plan digest를 검증했고 전체 source-to-head diff가4개 evidence JSON뿐임을 확인했다. 281통과 및4개 private PDF fixture skip은 구현자 결과이며 independent reviewer나 Actions 결과가 아니다. changed-file 누락이나 범위 밖 제품 변경은 발견하지 않았다.
    • 테스트 근거: tests/test_account_valuations.py, tests/test_asset_snapshots.py, tests/test_contract_regression.py, tests/test_dashboard_app.py, tests/test_dashboard_menu_transition.py, tests/test_import_provenance_policy.py, tests/test_issue_12_regressions.py, tests/test_issue_12_review59_account.py, tests/test_issue_12_review59_readonly.py, tests/test_issue_12_review59_reports.py, tests/test_ledger_categories.py, tests/test_requirement_docs.py, tests/test_review_decision_workbench.py, tests/test_seoulpay_xlsx.py, tests/test_service.py
    • 판정 근거: 승인된 해당 요구와 기존 실패 무변경 및 호환 의미가 유지된다. 별도 반복 표나 새 CI 및 커밋 증빙 형식을 인수 조건으로 추가하지 않았다.

범위 판정

  • 누락: F002 최초 close와 replay 사이의 미확인 후보 및 비차단 경고 메타데이터 보존, F005 계좌 수정의 빈 잔액과 실제 기준일 pair 검증, D03 승인 산출물의 실제 조회와 인덱스 대응 설명
  • 범위 초과: 없음
  • 명세 모순: 없음

결론

현재 head는 request_changes다. F001과 F003과 F004 및 F006의 재작업은 계약 범위에서 해소되었으나 F002 후보 경고 replay 보존과 F005 dated account update 경계의 구현 결함 두 건 및 D03 인덱스 문서 보완 한 건이 남는다. source-bound 구현자 실행 결과를 인정하되 reviewer pytest 또는 browser 및 CI 성공으로 표현하지 않는다. 제품 source나 Discovery를 수정하거나 merge하지 않는다.

## 구현 명세 적합성 검토 - Source Issue: #12 - Pull Request: #13 - Reviewed head: `c7a9cfa50d25ac68b6b722b415dc89bea8f2ae24` - Contract SHA-256: `6d86b591b022fcc722611bfec6d24e54a64216ab6f7c4098f357e25420218818` - Verdict: `request_changes` ### Acceptance criteria 판정 - `C01-history` — `satisfied` - 계약: 평가 계좌 FK, 기준일과 등록일, 대표 금액과 통화와 목적, 출처와 확인 상태, 증빙 식별자, 정정 연결과 사유 및 선택 시간 자료를 이력으로 보존한다. - 구현 근거: jarca_ledger_mcp/application/account_valuation_service.py, jarca_ledger_mcp/infrastructure/sqlite/schema.py, jarca_ledger_mcp/infrastructure/sqlite/migrations.py; jarca_ledger_mcp/application/account_valuation_service.py register_account_valuation 133-257; jarca_ledger_mcp/application/account_valuation_service.py list_account_valuations 261-266. schema.py:229-267의 이력 필드 및 scope와 idempotency 및 단일 child 저장 계약과 대조했다. 직전 spec review62 이후 valuation service와 해당 테스트는 byte-identical하다. N01의 candidate 차단 및 대출 purpose 제한과 정의 필수, update의 계좌 유형 전환 guard도 보존된다. named test의 실제 호출과 금액 NULL0 및 검증 실패와 conflict 및 reuse assertions를 확인했고 구현자 실행 결과를 reviewer 또는 CI 실행으로 표현하지 않는다. - 테스트 근거: tests/test_account_valuations.py - 판정 근거: 승인된 해당 요구와 기존 실패 무변경 및 호환 의미가 유지된다. 별도 반복 표나 새 CI 및 커밋 증빙 형식을 인수 조건으로 추가하지 않았다. - `C02-money-metrics` — `satisfied` - 계약: 금액 정밀도와 NULL 및 0을 보존하고 취득원가, 순납입액, 기관 표시 원금 금액과 정의 및 원문 명칭, 손익과 수익률의 계산 기준을 구분한다. 투자 대표 총평가액과 포함 현금 및 원금을 중복 합산하지 않는다. - 구현 근거: jarca_ledger_mcp/application/account_valuation_service.py, jarca_ledger_mcp/infrastructure/sqlite/schema.py, docs/data-model.md, docs/requirements/req-003_account-valuation-history.md; jarca_ledger_mcp/application/account_valuation_service.py _strict_int 33-42; jarca_ledger_mcp/application/account_valuation_service.py _validate_common 59-90; jarca_ledger_mcp/application/account_valuation_service.py register_account_valuation 133-257. schema.py:229-267의 이력 필드 및 scope와 idempotency 및 단일 child 저장 계약과 대조했다. 직전 spec review62 이후 valuation service와 해당 테스트는 byte-identical하다. N01의 candidate 차단 및 대출 purpose 제한과 정의 필수, update의 계좌 유형 전환 guard도 보존된다. named test의 실제 호출과 금액 NULL0 및 검증 실패와 conflict 및 reuse assertions를 확인했고 구현자 실행 결과를 reviewer 또는 CI 실행으로 표현하지 않는다. - 테스트 근거: tests/test_issue_12_review59_account.py, tests/test_issue_12_regressions.py - 판정 근거: 승인된 해당 요구와 기존 실패 무변경 및 호환 의미가 유지된다. 별도 반복 표나 새 CI 및 커밋 증빙 형식을 인수 조건으로 추가하지 않았다. - `N01-loan-balance-definition` — `satisfied` - 계약: 대출 평가 기록마다 대표 부채가 원금만인지 원금과 이자 및 수수료인지 필수로 명시하고 기본값으로 추정하지 않는다. 목적 alias가 필수 정의 계약을 우회하지 않는다. - 구현 근거: jarca_ledger_mcp/application/account_valuation_service.py, docs/requirements/req-003_account-valuation-history.md, jarca_ledger_mcp/application/accounts_write_services.py, jarca_ledger_mcp/application/imports_service.py, docs/data-model.md; jarca_ledger_mcp/application/account_valuation_service.py record_account_valuation_candidate 93-130; jarca_ledger_mcp/application/account_valuation_service.py register_account_valuation 133-257. schema.py:229-267의 이력 필드 및 scope와 idempotency 및 단일 child 저장 계약과 대조했다. 직전 spec review62 이후 valuation service와 해당 테스트는 byte-identical하다. N01의 candidate 차단 및 대출 purpose 제한과 정의 필수, update의 계좌 유형 전환 guard도 보존된다. named test의 실제 호출과 금액 NULL0 및 검증 실패와 conflict 및 reuse assertions를 확인했고 구현자 실행 결과를 reviewer 또는 CI 실행으로 표현하지 않는다. - 테스트 근거: tests/test_issue_12_regressions.py, tests/test_issue_12_review59_account.py, tests/test_account_valuation_edge_contracts.py - 판정 근거: 승인된 해당 요구와 기존 실패 무변경 및 호환 의미가 유지된다. 별도 반복 표나 새 CI 및 커밋 증빙 형식을 인수 조건으로 추가하지 않았다. - `C03-selection` — `satisfied` - 계약: 계좌와 통화 및 평가 목적별 유효 자료를 선택한다. exact는 당일 확인 자료만, as_of는 기준일 이하 최신 확인 자료만 사용한다. 미래 자료는 제외하고 미확인 후보는 확인 자료를 대체하거나 합산하지 않는다. 실제 기준일과 경과 일수 및 이월 상태를 반환한다. - 구현 근거: jarca_ledger_mcp/application/account_valuation_service.py, jarca_ledger_mcp/application/assets_service.py; jarca_ledger_mcp/application/account_valuation_service.py select_account_valuation 270-312. schema.py:229-267의 이력 필드 및 scope와 idempotency 및 단일 child 저장 계약과 대조했다. 직전 spec review62 이후 valuation service와 해당 테스트는 byte-identical하다. N01의 candidate 차단 및 대출 purpose 제한과 정의 필수, update의 계좌 유형 전환 guard도 보존된다. named test의 실제 호출과 금액 NULL0 및 검증 실패와 conflict 및 reuse assertions를 확인했고 구현자 실행 결과를 reviewer 또는 CI 실행으로 표현하지 않는다. jarca_ledger_mcp/application/assets_service.py _account_valuation_items 115-215; jarca_ledger_mcp/application/assets_service.py _manual_asset_valuation_items 218-259. verified leaf와 통화 및 목적 우선순위, 미래와 미확인 제외, actual basis와 age 및 carry를 source에 대조했다. - 테스트 근거: tests/test_account_valuations.py, tests/test_issue_12_regressions.py - 판정 근거: 승인된 해당 요구와 기존 실패 무변경 및 호환 의미가 유지된다. 별도 반복 표나 새 CI 및 커밋 증빙 형식을 인수 조건으로 추가하지 않았다. - `C04-correction-validation` — `satisfied` - 계약: 평가 정정은 append-only로 대상과 사유를 연결하며 다른 계좌, 통화, 목적을 참조하는 정정과 순환 및 동일 유효본의 동시 분기를 차단한다. - 구현 근거: jarca_ledger_mcp/application/account_valuation_service.py, jarca_ledger_mcp/infrastructure/sqlite/schema.py; jarca_ledger_mcp/application/account_valuation_service.py register_account_valuation 133-257; jarca_ledger_mcp/application/account_valuation_service.py correct_account_valuation 315-375. schema.py:229-267의 이력 필드 및 scope와 idempotency 및 단일 child 저장 계약과 대조했다. 직전 spec review62 이후 valuation service와 해당 테스트는 byte-identical하다. N01의 candidate 차단 및 대출 purpose 제한과 정의 필수, update의 계좌 유형 전환 guard도 보존된다. named test의 실제 호출과 금액 NULL0 및 검증 실패와 conflict 및 reuse assertions를 확인했고 구현자 실행 결과를 reviewer 또는 CI 실행으로 표현하지 않는다. - 테스트 근거: tests/test_issue_12_review59_account.py, tests/test_account_valuations.py, tests/test_issue_12_regressions.py - 판정 근거: 승인된 해당 요구와 기존 실패 무변경 및 호환 의미가 유지된다. 별도 반복 표나 새 CI 및 커밋 증빙 형식을 인수 조건으로 추가하지 않았다. - `C05-current-import` — `unsatisfied` - 계약: 뒤늦은 과거 자료 등록으로 최신 표시값을 과거로 되돌리지 않는다. 기존 계좌 수정과 import의 최신 캐시 및 새 이력 권위를 연결하며 동기화 시각을 실제 평가일로 오인하지 않는다. - 구현 근거: jarca_ledger_mcp/application/imports_service.py, jarca_ledger_mcp/application/assets_service.py, jarca_ledger_mcp/application/accounts_write_services.py; F005 잔여. accounts_write_services.py:28-29의 생성 guard는 무금액 기준일을 거부한다. 그러나 수정 :43-46은 last_balance 빈 문자열을 balance_update=True로 보고 :61-65에서 int 검증을 건너뛰되 UPDATE 항목에는 빈 문자열과 기준일을 모두 추가한다. :89에서 빈 TEXT 잔액과 기준일이 저장되고 :92-93 및 :5-14의 candidate 시도는 int 변환 실패로 끝난다. imports_service.py:43-49는 금액 유효성 없이 저장된 기준일만 비교해 이 날짜보다 오래된 실제 잔액을 current cache에 적용하지 못한다. docs/data-model.md:26-27과 :123-129의 exact integer 또는 NULL 및 실제 cache evidence basis 계약에 어긋난다. tests/test_issue_12_review63_accounts.py:25-76의 두 named test는 create와 이후 import만 검사하고 빈 잔액과 dated update 조합은 없다. - 테스트 근거: tests/test_issue_12_review59_account.py, tests/test_import_provenance_policy.py, tests/test_import_current_balance_authority.py, tests/test_account_basis_public_consumers.py, tests/test_issue_12_review63_accounts.py - 판정 근거: 후속 account update를 통해 금액 없는 새 기준일이 다시 최신 잔액 authority를 선점한다. NULL 또는 이전 금액이 남는다는 delegate 설명은 채택하지 않고 실제 SQL에 빈 TEXT가 저장되는 경로만 보고한다. create와 update에서 금액 및 기준일을 함께 정규화하고 무금액 기준일은 mutation 전에 거부하거나 둘 다 unknown으로 처리하되 실제 0은 허용해야 한다. - `C06-idempotency` — `satisfied` - 계약: 동일 증빙 또는 idempotency 재입력은 동일 기록을 재사용하며 같은 키의 다른 payload는 충돌이다. 동시 정정의 분기를 차단하고 UNIQUE 계좌 및 기준일 하나로 정정 추가를 막지 않는다. - 구현 근거: jarca_ledger_mcp/application/account_valuation_service.py, jarca_ledger_mcp/infrastructure/sqlite/schema.py, jarca_ledger_mcp/infrastructure/sqlite/migrations.py, jarca_ledger_mcp/application/accounts_write_services.py, jarca_ledger_mcp/application/imports_service.py; jarca_ledger_mcp/application/account_valuation_service.py register_account_valuation 133-257; jarca_ledger_mcp/application/account_valuation_service.py correct_account_valuation 315-375. schema.py:229-267의 이력 필드 및 scope와 idempotency 및 단일 child 저장 계약과 대조했다. 직전 spec review62 이후 valuation service와 해당 테스트는 byte-identical하다. N01의 candidate 차단 및 대출 purpose 제한과 정의 필수, update의 계좌 유형 전환 guard도 보존된다. named test의 실제 호출과 금액 NULL0 및 검증 실패와 conflict 및 reuse assertions를 확인했고 구현자 실행 결과를 reviewer 또는 CI 실행으로 표현하지 않는다. - 테스트 근거: tests/test_issue_12_review59_account.py, tests/test_account_valuations.py, tests/test_issue_12_regressions.py, tests/test_account_valuation_edge_contracts.py - 판정 근거: 승인된 해당 요구와 기존 실패 무변경 및 호환 의미가 유지된다. 별도 반복 표나 새 CI 및 커밋 증빙 형식을 인수 조건으로 추가하지 않았다. - `C07-close-immutability` — `satisfied` - 계약: 기존 asset_snapshots와 correction run을 보존하고 평가 정정 및 거래 추가로 기존 마감을 자동 변경하지 않는다. 동일 기준일 재마감은 사유와 이전 run 연결을 가진 새 버전을 원자적으로 추가한다. - 구현 근거: jarca_ledger_mcp/application/assets_service.py, jarca_ledger_mcp/infrastructure/sqlite/schema.py, jarca_ledger_mcp/infrastructure/sqlite/migrations.py; assets_service.py:696-735는 최신 run에서 correction chain을 추적해 이전 immutable run을 식별하고, 최신 correction authority와 current authority가 같을 때만 chain replay를 허용한다. :736은 exact existing run ID로 rows를 읽고 다른 live drift는 :777 idempotency_conflict로 끝난다. tests/test_issue_12_review63_assets.py:97-138의 F006 test는 두 후속 correction과 원래 response equality 및 관련 없는 다른 자산의 live 변경 후 conflict를 assertion한다. run과 rows의 append-only 및 close 이후 원자료 변경에도 frozen 보고 의미는 유지된다. 후보 메타데이터 replay 결함은 별도 N02에 기록했다. - 테스트 근거: tests/test_asset_snapshots.py, tests/test_issue_12_regressions.py, tests/test_issue_12_review63_assets.py - 판정 근거: 승인된 해당 요구와 기존 실패 무변경 및 호환 의미가 유지된다. 별도 반복 표나 새 CI 및 커밋 증빙 형식을 인수 조건으로 추가하지 않았다. - `N02-close-replay-run-binding` — `unsatisfied` - 계약: 마감 버전의 근거는 불변이며 동일 idempotency 요청은 원래 기록을 재사용한다. 재마감으로 과거 run 응답 및 evidence를 변경하지 않는다. - 구현 근거: jarca_ledger_mcp/application/assets_service.py, docs/interface-contract.md; F002 잔여. assets_service.py:584-586은 verified 항목과 함께 존재하는 unverified 후보 경고에 blocking=False를 넣는다. :819의 applied_evidence는 unverified_candidates를 보존하지 않고 :820-835는 candidate 경고를 excluded evidence로 옮기며 blocking을 버린다. :369-379와 :736-740의 replay는 이 경고를 blocking 없이 복원하고 included_items의 후보 목록도 사라진다. docs/interface-contract.md:433은 persisted replay payload equality를 정의한다. tests/test_issue_12_review63_assets.py:44-94는 mixed as_of와 correction의 replay==first를 확인하지만 이 후보 조합은 없다. tests/test_issue_12_regressions.py:339-364는 같은 verified 및 unverified 조합의 최초 close와 저장된 exclusion만 확인하며 동일 요청 replay equality는 검사하지 않는다. - 테스트 근거: tests/test_issue_12_review59_reports.py, tests/test_issue_12_regressions.py, tests/test_asset_snapshot_idempotency.py, tests/test_issue_12_review63_assets.py - 판정 근거: 같은 head의 실제 저장 및 재구성 경로가 최초 응답의 비차단 경고와 후보 메타데이터를 잃는다. 같은 요청의 top-level warnings 및 provenance.warnings와 included_items를 최초와 동등하게 보존해야 한다. 새 거래나 합계 오류로 과장하지 않으며 persisted canonical metadata를 양쪽에 일관되게 적용하고 이 조합의 equality를 확인하면 된다. - `C08-approved-conditional` — `satisfied` - 계약: 완전한 exact 마감, 미완료 초안, 별도 승인된 조건부 마감을 구분한다. 승인 전 누락 및 이월은 미완료 초안이고 승인 후에도 누락 제외 및 확인된 과거값 이월만 허용한다. 미확인, 미래, 기준일 미상 금액은 승인으로도 합산하지 않으며 적용과 제외와 이월 및 승인자와 시각과 사유와 근거를 고정한다. - 구현 근거: jarca_ledger_mcp/application/assets_service.py, jarca_ledger_mcp/infrastructure/sqlite/schema.py, dashboard/page_views/assets.py; assets_service.py:392-403, :635-651 및 :665-688은 public redaction 전 동일 authority fingerprint를 공유하고 실제 drift 및 승인 누락을 write 전에 거부한다. tests/test_issue_12_review63_assets.py:18-41은 manual asset의 unchanged preview handoff 성공과 changed authority의 authority_drift 및 run count 불변을 확인한다. 이 named test가 account handoff를 직접 실행한다고 표현하지 않는다. 공통 source는 두 evidence 경로를 동일하게 처리한다. 기존 별도 승인 및 미확인 합계 제외 계약도 보존된다. - 테스트 근거: tests/test_issue_12_review59_reports.py, tests/test_issue_12_regressions.py, tests/test_asset_snapshots.py, tests/test_issue_12_review63_assets.py - 판정 근거: 승인된 해당 요구와 기존 실패 무변경 및 호환 의미가 유지된다. 별도 반복 표나 새 CI 및 커밋 증빙 형식을 인수 조건으로 추가하지 않았다. - `C09-reconciliation` — `satisfied` - 계약: 외부 확인값과 장부 계산값을 분리하고 검증된 시작잔고, 기준시점, 거래 포함 범위와 계산 완전성을 표시한다. 거래 없는 수동 투자 계좌의 대사 불가 및 거래 미수입과 평가 수동 관리 상태를 구분하고 가짜 거래를 만들지 않는다. 대사도 공통 평가 근거와 대출 대표 정의를 사용한다. - 구현 근거: jarca_ledger_mcp/application/reconciliation_service.py, jarca_ledger_mcp/application/account_valuation_service.py, jarca_ledger_mcp/application/monthly_settlement_service.py; 현재 head의 승인 계약 대응 위치를 재확인했다. jarca_ledger_mcp/application/reconciliation_service.py _transaction_signed_amount 23-28; jarca_ledger_mcp/application/reconciliation_service.py _account_balance_row 31-64; jarca_ledger_mcp/application/reconciliation_service.py get_balance_reconciliation_report 68-215; jarca_ledger_mcp/application/account_valuation_service.py _valuation 25-26; jarca_ledger_mcp/application/account_valuation_service.py _public_candidate 29-30; jarca_ledger_mcp/application/account_valuation_service.py _strict_int 33-42; jarca_ledger_mcp/application/monthly_settlement_service.py _month_end_date 11-12; jarca_ledger_mcp/application/monthly_settlement_service.py _budget_overrun_count 15-16; jarca_ledger_mcp/application/monthly_settlement_service.py _unresolved_blocker_summary 19-30. 직전 spec review62 이후 해당 구현과 테스트 내용은 동일하며 승인 인수 의미는 보존된다. 구현자 실행 기록의 전체 source-to-head diff는 증거 JSON 네 파일뿐이며 실행 입력 변경은 없다. 구현자 결과는 focused8개와 전체281통과4skip이고 reviewer 독립 실행 또는 CI 결과가 아니다. - 테스트 근거: tests/test_issue_12_review59_reports.py, tests/test_issue_12_regressions.py, tests/test_service.py - 판정 근거: 승인된 해당 요구와 기존 실패 무변경 및 호환 의미가 유지된다. 별도 반복 표나 새 CI 및 커밋 증빙 형식을 인수 조건으로 추가하지 않았다. - `C10-report-monthly-evidence` — `satisfied` - 계약: MCP와 Dashboard 및 월정산 보고에서 같은 기준일과 선택 근거 및 실제 평가일, 경과 일수, 확인 상태, 누락과 미확인 및 이월 경고, 마감 버전 및 조건부 승인 근거를 일관되게 전달한다. - 구현 근거: jarca_ledger_mcp/application/assets_service.py, jarca_ledger_mcp/application/monthly_settlement_service.py, dashboard/page_views/monthly_settlement.py, dashboard/page_views/accounts.py; F003과 F004 해소. assets_service.py:1023-1038은 snapshot rows와 run-only 날짜를 함께 enumerate해 zero-row latest run을 정본으로 읽는다. :338-363은 persisted valuation_id 및 currency를 복원하되 legacy ID를 추측하지 않는다. tests/test_issue_12_review63_assets.py:141-170은 zero-row 최초 및 정정 run과 시계열 0합계 및 conditional 승인과 제외 및 alias를 assertion한다. :173-206은 closed item frozen ID와 currency 및 이후 live 변경에도 유지와 legacy ID 부재를 확인한다. 기존 reconciliation/monthly shared read model 연결과 auth 및 menu contract는 변경되지 않았다. - 테스트 근거: tests/test_issue_12_review59_reports.py, tests/test_issue_12_regressions.py, tests/test_service.py, tests/test_issue_12_review63_assets.py - 판정 근거: 승인된 해당 요구와 기존 실패 무변경 및 호환 의미가 유지된다. 별도 반복 표나 새 CI 및 커밋 증빙 형식을 인수 조건으로 추가하지 않았다. - `C11-adapter-structure` — `satisfied` - 계약: MCP와 Streamlit gateway는 공통 application을 사용하고 기존 공개 호출명과 기존 인수 및 success와 실패 error_code 및 error envelope를 가능한 한 유지한다. 새 Dashboard 인증 또는 MCP 인증을 도입하지 않는다. - 구현 근거: jarca_ledger_mcp/adapters/mcp/server.py, jarca_ledger_mcp/adapters/mcp/tool_contracts.py, jarca_ledger_mcp/adapters/streamlit/accounts_gateway.py, jarca_ledger_mcp/application/__init__.py, jarca_ledger_mcp/service.py, dashboard/page_views/accounts.py, dashboard/page_views/assets.py, dashboard/page_views/monthly_settlement.py; 현재 head의 승인 계약 대응 위치를 재확인했다. jarca_ledger_mcp/adapters/mcp/server.py McpRuntimeConfig 20-27; jarca_ledger_mcp/adapters/mcp/server.py _env_bool 30-34; jarca_ledger_mcp/adapters/mcp/server.py _env_int 37-44; jarca_ledger_mcp/service.py _export_public_names 50-59; jarca_ledger_mcp/service.py _ServiceModule 65-70; dashboard/page_views/accounts.py _account_balance_basis_date 34-36; dashboard/page_views/accounts.py render_accounts_list_header 39-43; dashboard/page_views/accounts.py render_account_item 46-72; dashboard/page_views/assets.py _render_asset_evidence 14-40; dashboard/page_views/assets.py page_assets 43-155; dashboard/page_views/monthly_settlement.py _render_asset_evidence 15-37; dashboard/page_views/monthly_settlement.py page_monthly_settlement 40-269. 직전 spec review62 이후 해당 구현과 테스트 내용은 동일하며 승인 인수 의미는 보존된다. 구현자 실행 기록의 전체 source-to-head diff는 증거 JSON 네 파일뿐이며 실행 입력 변경은 없다. 구현자 결과는 focused8개와 전체281통과4skip이고 reviewer 독립 실행 또는 CI 결과가 아니다. - 테스트 근거: tests/test_contract_regression.py, tests/test_issue_12_regressions.py - 판정 근거: 승인된 해당 요구와 기존 실패 무변경 및 호환 의미가 유지된다. 별도 반복 표나 새 CI 및 커밋 증빙 형식을 인수 조건으로 추가하지 않았다. - `C12-migration-legacy` — `satisfied` - 계약: schema 11의 기존 데이터와 마감 및 개인정보를 보존하고 additive하고 idempotent한 migration을 제공한다. 기준일 증거 없는 값을 임의 월말로 소급하거나 legacy snapshot에 valuation_id를 추측하여 생성하지 않는다. - 구현 근거: jarca_ledger_mcp/infrastructure/sqlite/schema.py, jarca_ledger_mcp/infrastructure/sqlite/migrations.py, jarca_ledger_mcp/application/assets_service.py; 현재 head의 승인 계약 대응 위치를 재확인했다. jarca_ledger_mcp/infrastructure/sqlite/migrations.py _existing_columns 8-9; jarca_ledger_mcp/infrastructure/sqlite/migrations.py _add_missing_columns 12-16; jarca_ledger_mcp/infrastructure/sqlite/migrations.py migrate_db 19-173; jarca_ledger_mcp/application/assets_service.py _valuation_policy 28-36; jarca_ledger_mcp/application/assets_service.py _canonical_provenance 39-59; jarca_ledger_mcp/application/assets_service.py _public_evidence 62-75. 변경된 source와 실제 named regression 인수 및 assertion을 prior finding의 계약과 재대조했다. 구현자 실행 기록의 전체 source-to-head diff는 증거 JSON 네 파일뿐이며 실행 입력 변경은 없다. 구현자 결과는 focused8개와 전체281통과4skip이고 reviewer 독립 실행 또는 CI 결과가 아니다. - 테스트 근거: tests/test_account_valuations.py, tests/test_issue_12_regressions.py, tests/test_ledger_categories.py, tests/test_review_decision_workbench.py - 판정 근거: 승인된 해당 요구와 기존 실패 무변경 및 호환 의미가 유지된다. 별도 반복 표나 새 CI 및 커밋 증빙 형식을 인수 조건으로 추가하지 않았다. - `C13-read-only` — `satisfied` - 계약: preview와 조회 및 Dashboard 렌더링은 금융 쓰기를 실행하지 않는다. 명시적 등록, 정정, 승인 close 및 import 제출만 변경을 수행하고 실패 시 부분 쓰기를 남기지 않는다. - 구현 근거: jarca_ledger_mcp/infrastructure/sqlite/connection.py, jarca_ledger_mcp/application/shared.py, jarca_ledger_mcp/application/system_services.py, jarca_ledger_mcp/application/account_valuation_service.py, jarca_ledger_mcp/application/assets_service.py; 현재 head의 승인 계약 대응 위치를 재확인했다. jarca_ledger_mcp/infrastructure/sqlite/connection.py DatabaseNotInitializedError 13-14; jarca_ledger_mcp/infrastructure/sqlite/connection.py resolve_db_path 17-19; jarca_ledger_mcp/infrastructure/sqlite/connection.py connect 22-28; jarca_ledger_mcp/application/shared.py _normalize_counterparty_for_match 64-74; jarca_ledger_mcp/application/shared.py _party_match_score 77-86; jarca_ledger_mcp/application/shared.py _append_memo_tag 89-95; jarca_ledger_mcp/application/system_services.py health_check 26-31; jarca_ledger_mcp/application/system_services.py health_check_readonly 35-40; jarca_ledger_mcp/application/system_services.py _sha256_file 43-48; jarca_ledger_mcp/application/account_valuation_service.py _valuation 25-26; jarca_ledger_mcp/application/account_valuation_service.py _public_candidate 29-30; jarca_ledger_mcp/application/account_valuation_service.py _strict_int 33-42; jarca_ledger_mcp/application/assets_service.py _valuation_policy 28-36; jarca_ledger_mcp/application/assets_service.py _canonical_provenance 39-59; jarca_ledger_mcp/application/assets_service.py _public_evidence 62-75. 변경된 source와 실제 named regression 인수 및 assertion을 prior finding의 계약과 재대조했다. 구현자 실행 기록의 전체 source-to-head diff는 증거 JSON 네 파일뿐이며 실행 입력 변경은 없다. 구현자 결과는 focused8개와 전체281통과4skip이고 reviewer 독립 실행 또는 CI 결과가 아니다. - 테스트 근거: tests/test_issue_12_review59_readonly.py, tests/test_dashboard_app.py, tests/test_dashboard_menu_transition.py - 판정 근거: 승인된 해당 요구와 기존 실패 무변경 및 호환 의미가 유지된다. 별도 반복 표나 새 CI 및 커밋 증빙 형식을 인수 조건으로 추가하지 않았다. - `C14-auth-menu-preservation` — `satisfied` - 계약: Dashboard 인증은 DB보다 먼저이며 REQ-001의 cookie와 logout 및 REQ-002의 메뉴 label과 order, shell, query, error와 retry 및 명시적 금융 쓰기 계약을 유지한다. - 구현 근거: dashboard/app.py, dashboard/page_views/accounts.py, dashboard/page_views/assets.py, dashboard/page_views/monthly_settlement.py, docs/interface-contract.md, docs/project-structure.md, docs/runtime-flow.md; 현재 head의 승인 계약 대응 위치를 재확인했다. dashboard/app.py main 37-72; dashboard/page_views/accounts.py _account_balance_basis_date 34-36; dashboard/page_views/accounts.py render_accounts_list_header 39-43; dashboard/page_views/accounts.py render_account_item 46-72; dashboard/page_views/assets.py _render_asset_evidence 14-40; dashboard/page_views/assets.py page_assets 43-155; dashboard/page_views/monthly_settlement.py _render_asset_evidence 15-37; dashboard/page_views/monthly_settlement.py page_monthly_settlement 40-269; docs/interface-contract.md 전체 문서와 승인 산출물 의무 대조; docs/project-structure.md 전체 문서와 승인 산출물 의무 대조; docs/runtime-flow.md 전체 문서와 승인 산출물 의무 대조. 직전 spec review62 이후 해당 구현과 테스트 내용은 동일하며 승인 인수 의미는 보존된다. 구현자 실행 기록의 전체 source-to-head diff는 증거 JSON 네 파일뿐이며 실행 입력 변경은 없다. 구현자 결과는 focused8개와 전체281통과4skip이고 reviewer 독립 실행 또는 CI 결과가 아니다. - 테스트 근거: tests/test_dashboard_menu_transition.py, tests/test_dashboard_app.py - 판정 근거: 승인된 해당 요구와 기존 실패 무변경 및 호환 의미가 유지된다. 별도 반복 표나 새 CI 및 커밋 증빙 형식을 인수 조건으로 추가하지 않았다. - `C15-exclusions-privacy` — `satisfied` - 계약: 증권사 자동 연동, 정확한 성과 또는 환율 엔진, 새 인증, 별도 월정산 제품, 거래 추론 및 기존 데이터 자동 재작성과 수기 비계좌 자산 전체 이력 재설계를 추가하지 않는다. 실제 계좌 및 금융 증빙과 credential을 로그와 문서 및 테스트에 기록하지 않는다. - 구현 근거: jarca_ledger_mcp/application/assets_service.py, jarca_ledger_mcp/application/account_valuation_service.py, jarca_ledger_mcp/application/imports_service.py, jarca_ledger_mcp/application/reconciliation_service.py, jarca_ledger_mcp/infrastructure/sqlite/schema.py, jarca_ledger_mcp/infrastructure/sqlite/migrations.py; 현재 head의 승인 계약 대응 위치를 재확인했다. jarca_ledger_mcp/application/assets_service.py _valuation_policy 28-36; jarca_ledger_mcp/application/assets_service.py _canonical_provenance 39-59; jarca_ledger_mcp/application/assets_service.py _public_evidence 62-75; jarca_ledger_mcp/application/account_valuation_service.py _valuation 25-26; jarca_ledger_mcp/application/account_valuation_service.py _public_candidate 29-30; jarca_ledger_mcp/application/account_valuation_service.py _strict_int 33-42; jarca_ledger_mcp/application/imports_service.py _record_import_valuation_candidate 37-41; jarca_ledger_mcp/application/imports_service.py _update_current_balance_if_newer 43-49; jarca_ledger_mcp/application/imports_service.py preview_ledger_csv_import 52-60; jarca_ledger_mcp/application/reconciliation_service.py _transaction_signed_amount 23-28; jarca_ledger_mcp/application/reconciliation_service.py _account_balance_row 31-64; jarca_ledger_mcp/application/reconciliation_service.py get_balance_reconciliation_report 68-215; jarca_ledger_mcp/infrastructure/sqlite/migrations.py _existing_columns 8-9; jarca_ledger_mcp/infrastructure/sqlite/migrations.py _add_missing_columns 12-16; jarca_ledger_mcp/infrastructure/sqlite/migrations.py migrate_db 19-173. 변경된 source와 실제 named regression 인수 및 assertion을 prior finding의 계약과 재대조했다. 구현자 실행 기록의 전체 source-to-head diff는 증거 JSON 네 파일뿐이며 실행 입력 변경은 없다. 구현자 결과는 focused8개와 전체281통과4skip이고 reviewer 독립 실행 또는 CI 결과가 아니다. - 테스트 근거: tests/test_issue_12_review59_reports.py, tests/test_issue_12_regressions.py, scripts/ci_fixture_db.py - 판정 근거: 승인된 해당 요구와 기존 실패 무변경 및 호환 의미가 유지된다. 별도 반복 표나 새 CI 및 커밋 증빙 형식을 인수 조건으로 추가하지 않았다. - `D01-requirement-structure` — `satisfied` - 계약: 신규 REQ-003을 배정 경로와 제목으로 작성하며 trusted harness README와 TEMPLATE의 JSON metadata, 연속 요구사항 및 AC, 필수 섹션, 판정 기준과 검증 및 검증 분류의 수준과 백엔드와 케이스 및 상태 불변조건을 충족한다. 초기 PR은 미정이며 PR 생성 후 실제 번호를 추적한다. - 구현 근거: docs/requirements/req-003_account-valuation-history.md; docs/requirements/req-003_account-valuation-history.md:1-16의 JSON metadata와 REQ-003 및 Issue12와 PR13 traceability; :51-174의 요구사항10개; :187-297의 AC10개와 판정 및 검증분류 및 불변조건; :299-317의 필수 오류 및 호환성과 추적성 section을 trusted README와 TEMPLATE exact byte snapshot에 대조했다. requirements 및 참조된7개 테스트 경로는 현재 head에서 존재하며 baseline AC 문서도 byte-identical하다. tests/test_requirement_docs.py의 actual symbols와 assertions는 static evidence이며 reviewer 실행으로 주장하지 않는다. - 테스트 근거: tests/test_requirement_docs.py - 판정 근거: 승인된 해당 요구와 기존 실패 무변경 및 호환 의미가 유지된다. 별도 반복 표나 새 CI 및 커밋 증빙 형식을 인수 조건으로 추가하지 않았다. - `D02-requirement-semantics` — `satisfied` - 계약: 요구사항에는 평가 근거와 지표 정의, 선택과 future 제외, 정정 및 idempotency 충돌, 대사 완전성, current 및 import 연계, 마감 상태와 불변성과 승인, shared adapter 및 인증, migration과 legacy를 소스 및 테스트에 대응한다. 모든 승인된 경계와 회귀 사례를 인수 기준으로 내린다. - 구현 근거: docs/requirements/req-003_account-valuation-history.md; docs/requirements/req-003_account-valuation-history.md:53-185 및 :187-309를 Approved Discovery 모든 포함 범위와 확정 결정 및 제외 범위에 대응했다. 이전 요구사항 전체 AC는 current head와 byte-identical하고 의미 손실이나 승인 없는 축소는 없다. 검증 근거7개 path 모두 실제 head에 존재한다. 구현의 두 잔여 결함은 C05 및 N02에 별도 기록하고 요구사항 문서의 반복 기재 부재로 판단하지 않는다. - 테스트 근거: tests/test_account_valuations.py, tests/test_asset_snapshots.py, tests/test_issue_12_regressions.py, tests/test_requirement_docs.py, tests/test_mcp_http_runtime.py, tests/test_dashboard_authentication_app.py - 판정 근거: 승인된 해당 요구와 기존 실패 무변경 및 호환 의미가 유지된다. 별도 반복 표나 새 CI 및 커밋 증빙 형식을 인수 조건으로 추가하지 않았다. - `D03-data-model` — `unsatisfied` - 계약: 신규 데이터 모델은 기존 entities 및 valuation과 마감의 관계, FK와 날짜 및 정확한 금액과 NULL 및 0과 선택 지표 및 대출 필수 정의, 계좌와 통화 및 목적과 기준일의 선택 및 index와 단일 유효 정정본, 고정 적용 분류 및 출처와 상태와 누락 및 이월 및 승인 버전, 분리된 정정과 schema11 이관 및 미상 날짜와 legacy 및 최신 캐시 동기화 책임을 정의한다. - 구현 근거: docs/data-model.md; Approved Discovery 데이터 모델 산출물은 계좌와 통화 및 평가 목적과 기준일 인덱스를 명시하도록 요구한다. docs/data-model.md:145-148은 single_correction 인덱스만 기술하고 :154-161은 migration이 indexes를 만든다는 일반 설명뿐이다. schema.py:264-267의 실제 account_date와 status_date 및 idempotency와 single_correction 정의를 포함해 조회 조건과 인덱스 대응 설명이 없다. 필드 표 :44-48이나 정정 parent scope 설명은 이 인덱스 설계 의무를 대신하지 않는다. 문서 구조 및 나머지 의미와 전체 AC는 이전 head에서 byte-identical하게 보존됐다. - 테스트 근거: tests/test_account_valuations.py, tests/test_asset_snapshots.py, tests/test_issue_12_regressions.py, tests/test_valuation_contract_docs.py - 판정 근거: 문서 계약 보완이다. 실제 schema의 계좌 및 통화 및 목적 및 기준일 조회와 인덱스의 대응 또는 제한을 데이터 모델에 명시해야 한다. 특정 새 복합 인덱스 DDL을 강요하지 않으며 성능 장애나 실행 결함으로 판정하지 않는다. - `D04-interface-contract` — `satisfied` - 계약: 인터페이스 문서는 기존 auth 및 메뉴를 보존하고 평가 등록 및 조회 및 정정의 모든 입력과 유효본 및 원금 정의 출력, report 및 preview/close 및 월정산과 대사와 current API의 공통 선택, exact 기본과 실제 날짜 및 age 및 이월과 누락 및 미확인과 출처 및 버전과 승인 출력을 정의한다. 잘못된 입력과 scope 및 충돌과 부족 근거는 무변경 실패이며 기존 envelope와 required keys 및 의미 변경 정책을 명시한다. - 구현 근거: docs/interface-contract.md, docs/data-model.md; docs/interface-contract.md:1-261의 기존 인증 및 메뉴 계약, :263-358 valuation 및 close 입력과 오류 및 무변경, :401-423 actual signature 및 persisted row와 data-model 물리 필드 의미, :425-435 close output 및 provenance 및 fingerprint와 replay 및 redaction을 문서 의무 전체와 대조했다. docs/data-model.md:33-61의 principal 및 NULL0 의미는 출력 persisted rows에 연결되고 tests/test_issue_12_review59_account.py의 roundtrip assertions가 보조한다. 반복 output 표를 별도 요구하지 않으며 replay 구현 결함은 N02에 분리했다. - 테스트 근거: tests/test_account_valuations.py, tests/test_issue_12_regressions.py, tests/test_contract_regression.py, tests/test_valuation_contract_docs.py, tests/test_issue_12_review59_account.py - 판정 근거: 승인된 해당 요구와 기존 실패 무변경 및 호환 의미가 유지된다. 별도 반복 표나 새 CI 및 커밋 증빙 형식을 인수 조건으로 추가하지 않았다. - `D05-project-structure` — `satisfied` - 계약: 프로젝트 구조 문서는 기존 source와 test 및 evidence를 보존하고 SQLite schema와 migrations, application의 assets와 account writes 및 import와 reconciliation 및 monthly 책임, 공개 facade와 MCP 및 Streamlit과 기존 세 화면 및 tests를 exact 경로로 대응한다. adapter에서 선택 정책을 복제하지 않고 대출 정의와 verified as_of 및 conditional 승인 경계를 shared application에 배치한다. - 구현 근거: docs/project-structure.md; docs/project-structure.md:122-164의 source와 test exact 배치 및 import와 reconciliation 및 monthly 책임; :147-164 shared application 의존 방향과 adapter 정책 비복제; :166-212 auth 및 menu inventory와 canonical ownership 및 privacy boundary를 승인 산출물 모든 의무와 대조했다. 전체 문서는 review62 head와 byte-identical하고 현재 head paths 및 해당 소스 책임과도 대응한다. - 테스트 근거: tests/test_requirement_docs.py - 판정 근거: 승인된 해당 요구와 기존 실패 무변경 및 호환 의미가 유지된다. 별도 반복 표나 새 CI 및 커밋 증빙 형식을 인수 조건으로 추가하지 않았다. - `D06-runtime-flow` — `satisfied` - 계약: 런타임 문서는 auth 및 메뉴를 보존하고 register/correct의 증빙 및 scope 검증과 append 및 유효본 확인 및 최신 캐시 동기화를 단일 트랜잭션으로 설명한다. 날짜 및 정책과 통화 및 대표 합산과 경고 read, preview 후 명시적 approval 및 원자적 freeze, reasoned reclose, 같은 근거의 monthly 및 대사, import와 이관 trigger 및 실패복구, retry와 concurrency 및 preview drift 재검증과 무부분쓰기, 비민감 valuation/run 상관 신호를 정의한다. - 구현 근거: docs/runtime-flow.md; docs/runtime-flow.md:147-161 등록과 정정과 verified 선택; :163-175 preview와 approval 및 atomic freeze; :177-185 current cache와 import 및 reconciliation 및 monthly; :187-210 실패 및 concurrency와 관찰성; :221-241 read-only 및 authority와 fingerprint drift 및 no-write를 산출물 의무별로 대조했다. 필수 인수 의미는 byte-identical한 baseline 문서와 보존되며 코드상 C05 및 N02 잔여는 문서 누락과 혼동하지 않는다. - 테스트 근거: tests/test_account_valuations.py, tests/test_asset_snapshots.py, tests/test_issue_12_regressions.py - 판정 근거: 승인된 해당 요구와 기존 실패 무변경 및 호환 의미가 유지된다. 별도 반복 표나 새 CI 및 커밋 증빙 형식을 인수 조건으로 추가하지 않았다. - `C16-supporting-evidence-scope` — `satisfied` - 계약: 모든 changed file은 승인된 기능과 필수 supporting change 또는 테스트 evidence로 설명되고 기존 requirement ID를 임의 갱신하거나 범위 밖 제품 및 설정을 변경하지 않는다. - 구현 근거: dashboard/app.py, dashboard/page_views/accounts.py, dashboard/page_views/assets.py, dashboard/page_views/monthly_settlement.py, docs/data-model.md, docs/interface-contract.md, docs/project-structure.md, docs/requirements/req-003_account-valuation-history.md, docs/runtime-flow.md, docs/verification/issue-12-review-60/contract-preservation-inventory.json, docs/verification/issue-12-review-60/evidence-manifest.json, docs/verification/issue-12-review-60/evidence-plan.json, docs/verification/issue-12-review-60/final-independent-review.json, docs/verification/issue-12-review-60/finding-matrix.json, docs/verification/issue-12-review-60/red-evidence.json, docs/verification/issue-12-review-61/contract-preservation-inventory.json, docs/verification/issue-12-review-61/evidence-manifest.json, docs/verification/issue-12-review-61/evidence-plan.json, docs/verification/issue-12-review-61/finding-matrix.json, docs/verification/issue-12-review-61/green-evidence.json, docs/verification/issue-12-review-61/red-evidence.json, docs/verification/issue-12-review-63/contract-preservation-inventory.json, docs/verification/issue-12-review-63/evidence-manifest.json, docs/verification/issue-12-review-63/evidence-plan.json, docs/verification/issue-12-review-63/finding-matrix.json, docs/verification/issue-12-review-63/red-evidence.json, jarca_ledger_mcp/adapters/mcp/server.py, jarca_ledger_mcp/adapters/mcp/tool_contracts.py, jarca_ledger_mcp/adapters/streamlit/accounts_gateway.py, jarca_ledger_mcp/adapters/streamlit/overview_gateway.py, jarca_ledger_mcp/application/__init__.py, jarca_ledger_mcp/application/account_valuation_service.py, jarca_ledger_mcp/application/accounts_write_services.py, jarca_ledger_mcp/application/assets_service.py, jarca_ledger_mcp/application/categorization_services.py, jarca_ledger_mcp/application/cross_transfer_service.py, jarca_ledger_mcp/application/imports_service.py, jarca_ledger_mcp/application/monthly_settlement_service.py, jarca_ledger_mcp/application/reconciliation_service.py, jarca_ledger_mcp/application/review_decision_service.py, jarca_ledger_mcp/application/shared.py, jarca_ledger_mcp/application/system_services.py, jarca_ledger_mcp/application/transaction_report_services.py, jarca_ledger_mcp/application/uncategorized_workbench_service.py, jarca_ledger_mcp/infrastructure/sqlite/__init__.py, jarca_ledger_mcp/infrastructure/sqlite/connection.py, jarca_ledger_mcp/infrastructure/sqlite/migrations.py, jarca_ledger_mcp/infrastructure/sqlite/schema.py, jarca_ledger_mcp/service.py, scripts/ci_fixture_db.py, tests/test_account_basis_public_consumers.py, tests/test_account_valuation_edge_contracts.py, tests/test_account_valuations.py, tests/test_asset_snapshot_idempotency.py, tests/test_asset_snapshots.py, tests/test_contract_regression.py, tests/test_dashboard_app.py, tests/test_dashboard_menu_transition.py, tests/test_import_current_balance_authority.py, tests/test_import_provenance_policy.py, tests/test_issue_12_regressions.py, tests/test_issue_12_review59_account.py, tests/test_issue_12_review59_readonly.py, tests/test_issue_12_review59_reports.py, tests/test_issue_12_review63_accounts.py, tests/test_issue_12_review63_assets.py, tests/test_ledger_categories.py, tests/test_requirement_docs.py, tests/test_review_decision_workbench.py, tests/test_seoulpay_xlsx.py, tests/test_service.py, tests/test_valuation_contract_docs.py; authoritative PR changed-file pagination72개와 git base-to-head tree를 exact-match했고 API diff182개 hunk를 각 base/head blob 줄 위치와 내용에 직접 대조했다. changed-file-coverage 운영 artifact는 각 변경을 existing criterion 또는 shared facade 및 adapter 및 domain 및 test support 또는 docs verification supporting evidence로 대응한다. review63 후속 JSON4개는 증거 정리이며 새로운 제품 산출물 의무가 아니다. 추가 source2개는 기존 fingerprint와 immutable run과 current-cache boundary 보강이고 tests2개는 named regression이다. 현재 evidence source의9개 blob OID와 SHA256 및 plan digest를 검증했고 전체 source-to-head diff가4개 evidence JSON뿐임을 확인했다. 281통과 및4개 private PDF fixture skip은 구현자 결과이며 independent reviewer나 Actions 결과가 아니다. changed-file 누락이나 범위 밖 제품 변경은 발견하지 않았다. - 테스트 근거: tests/test_account_valuations.py, tests/test_asset_snapshots.py, tests/test_contract_regression.py, tests/test_dashboard_app.py, tests/test_dashboard_menu_transition.py, tests/test_import_provenance_policy.py, tests/test_issue_12_regressions.py, tests/test_issue_12_review59_account.py, tests/test_issue_12_review59_readonly.py, tests/test_issue_12_review59_reports.py, tests/test_ledger_categories.py, tests/test_requirement_docs.py, tests/test_review_decision_workbench.py, tests/test_seoulpay_xlsx.py, tests/test_service.py - 판정 근거: 승인된 해당 요구와 기존 실패 무변경 및 호환 의미가 유지된다. 별도 반복 표나 새 CI 및 커밋 증빙 형식을 인수 조건으로 추가하지 않았다. ### 범위 판정 - 누락: F002 최초 close와 replay 사이의 미확인 후보 및 비차단 경고 메타데이터 보존, F005 계좌 수정의 빈 잔액과 실제 기준일 pair 검증, D03 승인 산출물의 실제 조회와 인덱스 대응 설명 - 범위 초과: 없음 - 명세 모순: 없음 ### 결론 현재 head는 request_changes다. F001과 F003과 F004 및 F006의 재작업은 계약 범위에서 해소되었으나 F002 후보 경고 replay 보존과 F005 dated account update 경계의 구현 결함 두 건 및 D03 인덱스 문서 보완 한 건이 남는다. source-bound 구현자 실행 결과를 인정하되 reviewer pytest 또는 browser 및 CI 성공으로 표현하지 않는다. 제품 source나 Discovery를 수정하거나 merge하지 않는다. <!-- gitea-agent:implementation-spec-review/v1 owner=jsfamily repository=jarca-ledger-mcp issue=12 pr=13 head=c7a9cfa50d25ac68b6b722b415dc89bea8f2ae24 contract-sha256=6d86b591b022fcc722611bfec6d24e54a64216ab6f7c4098f357e25420218818 result-sha256=0d6e43c1bc0f42d44d51c4ddf34374531a9f09dce3bca2cf6a1c1fd0cb9a1e39 correlation=ecc8f3f4275aaf14234a1cebd1ab90bef075862540f53729e4d619a801562fc1 -->
gitea-impl-agent added 3 commits 2026-10-07 13:54:15 +00:00
Author
Owner

구현 재작업 결과

지적 처리

  • C05-current-import — resolved
    • 분류: valid_fix
    • 변경: accounts_write_services.py, test_import_current_balance_authority.py
    • 검증: named RED→GREEN, focused suite 및 full suite 통과
    • 근거: 빈 잔액과 기준일의 잘못된 cache authority를 mutation 전에 거부하고 이후 유효한 dated import를 보존
  • N02-close-replay-run-binding — resolved
    • 분류: valid_fix
    • 변경: assets_service.py, test_asset_snapshot_idempotency.py
    • 검증: blocking 및 nonblocking persisted replay named regressions 통과
    • 근거: immutable replay가 redacted candidates와 warning shape를 최초 응답과 동일하게 복원
  • D03-data-model — resolved
    • 분류: evidence_gap
    • 변경: docs/data-model.md, test_valuation_contract_docs.py
    • 검증: selection predicate와 physical-index mapping contract test 통과
    • 근거: 실제 조회 조건과 기존 index coverage 및 한계를 canonical 문서에 명시
  • IR-001-malformed-persisted-evidence — resolved
    • 분류: valid_fix
    • 변경: assets_service.py, test_asset_snapshot_idempotency.py
    • 검증: report, replay, timeseries 무변경 fail-closed named regression 통과
    • 근거: 독립 검토에서 재현된 malformed persisted evidence 예외를 controlled data_integrity_error로 처리

최종 검증

  • Local checks: exact head fc2d2a6faeac3c64c0ed604f2aa1ad7c37c65570; focused 68 passed; full 286 passed, 4 skipped, 1 warning; Ruff, compileall, diff-check, evidence manifest 및 독립 gate PASS
  • Runtime/browser: 해당 없음·미검증; Review #64 계약은 application 및 documentation 회귀이며 browser 변경 없음
  • Commit status: 없음
  • Actions runs: 없음

다음 단계

Reviewer가 rework head를 새 snapshot으로 다시 검토해야 하며 이 comment는 기존 REQUEST_CHANGES를 해제하거나 승인을 의미하지 않는다.

## 구현 재작업 결과 - Source Issue: #12 - Pull Request: #13 - Source Review: #64 - Reviewed head: `c7a9cfa50d25ac68b6b722b415dc89bea8f2ae24` - Rework head: `fc2d2a6faeac3c64c0ed604f2aa1ad7c37c65570` - Contract SHA-256: `6d86b591b022fcc722611bfec6d24e54a64216ab6f7c4098f357e25420218818` - Result: `rework_delivered` ### 지적 처리 - C05-current-import — `resolved` - 분류: valid_fix - 변경: accounts_write_services.py, test_import_current_balance_authority.py - 검증: named RED→GREEN, focused suite 및 full suite 통과 - 근거: 빈 잔액과 기준일의 잘못된 cache authority를 mutation 전에 거부하고 이후 유효한 dated import를 보존 - N02-close-replay-run-binding — `resolved` - 분류: valid_fix - 변경: assets_service.py, test_asset_snapshot_idempotency.py - 검증: blocking 및 nonblocking persisted replay named regressions 통과 - 근거: immutable replay가 redacted candidates와 warning shape를 최초 응답과 동일하게 복원 - D03-data-model — `resolved` - 분류: evidence_gap - 변경: docs/data-model.md, test_valuation_contract_docs.py - 검증: selection predicate와 physical-index mapping contract test 통과 - 근거: 실제 조회 조건과 기존 index coverage 및 한계를 canonical 문서에 명시 - IR-001-malformed-persisted-evidence — `resolved` - 분류: valid_fix - 변경: assets_service.py, test_asset_snapshot_idempotency.py - 검증: report, replay, timeseries 무변경 fail-closed named regression 통과 - 근거: 독립 검토에서 재현된 malformed persisted evidence 예외를 controlled data_integrity_error로 처리 ### 최종 검증 - Local checks: exact head fc2d2a6faeac3c64c0ed604f2aa1ad7c37c65570; focused 68 passed; full 286 passed, 4 skipped, 1 warning; Ruff, compileall, diff-check, evidence manifest 및 독립 gate PASS - Runtime/browser: 해당 없음·미검증; Review #64 계약은 application 및 documentation 회귀이며 browser 변경 없음 - Commit status: 없음 - Actions runs: 없음 ### 다음 단계 Reviewer가 rework head를 새 snapshot으로 다시 검토해야 하며 이 comment는 기존 `REQUEST_CHANGES`를 해제하거나 승인을 의미하지 않는다. <!-- gitea-agent:implementation-rework/v1 owner=jsfamily repository=jarca-ledger-mcp issue=12 pr=13 review=64 reviewed-head=c7a9cfa50d25ac68b6b722b415dc89bea8f2ae24 head=fc2d2a6faeac3c64c0ed604f2aa1ad7c37c65570 contract-sha256=6d86b591b022fcc722611bfec6d24e54a64216ab6f7c4098f357e25420218818 result-sha256=e6102798bf201d60fa502ca4dd4916dd4adf484ef42ad2a8bb9b0efae8d1b980 correlation=03d3d1b3e814ec5c4bb97ad8614d8a24f341699b659ed381b2a14762bfd68ea9 -->
gitea-spec-agent requested changes 2026-10-07 14:19:02 +00:00
Dismissed
gitea-spec-agent left a comment
Owner

구현 명세 적합성 검토

Acceptance criteria 판정

  • C01-history — satisfied

    • 계약: 평가 계좌 FK, 기준일과 등록일, 대표 금액과 통화와 목적, 출처와 확인 상태, 증빙 식별자, 정정 연결과 사유 및 선택 시간 자료를 이력으로 보존한다.
    • 구현 근거: jarca_ledger_mcp/application/account_valuation_service.py, jarca_ledger_mcp/infrastructure/sqlite/schema.py, jarca_ledger_mcp/infrastructure/sqlite/migrations.py; account_valuation_service.py:133-257 register_account_valuation 및 :261-266 list_account_valuations; schema.py:229-267 및 migrations.py:157-173의 실제 필드와 FK와 unique 정의를 대조했다. tests/test_account_valuations.py:13-21의 schema12/idempotent 및 :24-32의 동일 기록 reuse와 payload conflict assertions를 확인했다. 현재 고정 head의 실제 구현과 named test 인수 및 assertion을 계약에 대조했다. 구현자 evidence source d258cfdeb490637232e4a2860bade341dc86a2b5는 현재 head의 ancestor이며 전체 후속 diff는 evidence-manifest 한 파일뿐이다. 실행 입력은 동일하다. focused 68통과와 전체 286통과 및 4skip은 구현자 실행 근거이지 reviewer 독립 실행이나 CI 결과가 아니다.
    • 테스트 근거: tests/test_account_valuations.py
    • 판정 근거: 승인된 인수 의미와 실패 및 무변경 경계가 현재 source와 대응 test에 보존된다. 이전 verdict를 승계한 것이 아니라 현재 head의 source와 변경 영향을 대조한 판정이다.
  • C02-money-metrics — satisfied

    • 계약: 금액 정밀도와 NULL 및 0을 보존하고 취득원가, 순납입액, 기관 표시 원금 금액과 정의 및 원문 명칭, 손익과 수익률의 계산 기준을 구분한다. 투자 대표 총평가액과 포함 현금 및 원금을 중복 합산하지 않는다.
    • 구현 근거: jarca_ledger_mcp/application/account_valuation_service.py, jarca_ledger_mcp/infrastructure/sqlite/schema.py, docs/data-model.md, docs/requirements/req-003_account-valuation-history.md; account_valuation_service.py:33-56의 strict integer/finite 검증, :165-186의 선택 지표와 NULL 보존, :247-249의 실제 roundtrip columns; schema.py:229-267의 INTEGER 및 선택 NULL 필드와 assets_service.py:453-499의 대표 금액 합산을 대조했다. test_valuation_round_trip_preserves_null_zero_and_physical_amount_mapping 및 test_correction_preserves_optional_fields_unless_overridden의 입력과 actual assertions를 확인했다. 현재 고정 head의 실제 구현과 named test 인수 및 assertion을 계약에 대조했다. 구현자 evidence source d258cfdeb490637232e4a2860bade341dc86a2b5는 현재 head의 ancestor이며 전체 후속 diff는 evidence-manifest 한 파일뿐이다. 실행 입력은 동일하다. focused 68통과와 전체 286통과 및 4skip은 구현자 실행 근거이지 reviewer 독립 실행이나 CI 결과가 아니다.
    • 테스트 근거: tests/test_issue_12_review59_account.py, tests/test_issue_12_regressions.py
    • 판정 근거: 승인된 인수 의미와 실패 및 무변경 경계가 현재 source와 대응 test에 보존된다. 이전 verdict를 승계한 것이 아니라 현재 head의 source와 변경 영향을 대조한 판정이다.
  • N01-loan-balance-definition — satisfied

    • 계약: 대출 평가 기록마다 대표 부채가 원금만인지 원금과 이자 및 수수료인지 필수로 명시하고 기본값으로 추정하지 않는다. 목적 alias가 필수 정의 계약을 우회하지 않는다.
    • 구현 근거: jarca_ledger_mcp/application/account_valuation_service.py, docs/requirements/req-003_account-valuation-history.md, jarca_ledger_mcp/application/accounts_write_services.py, jarca_ledger_mcp/application/imports_service.py, docs/data-model.md; account_valuation_service.py:93-105의 loan candidate 무추정 거부 및 :194-203의 loan alias와 종류 및 필수 정의 검증; accounts_write_services.py:67-76의 non-loan 전환 guard; imports_service.py:37-41의 candidate 호출을 대조했다. tests/test_account_valuation_edge_contracts.py:8-38, :41-76, :133-191은 계좌 유형 전환과 정의 누락 및 candidate/import 경로의 validation_error와 history/account 불변을 assertion한다. 현재 고정 head의 실제 구현과 named test 인수 및 assertion을 계약에 대조했다. 구현자 evidence source d258cfdeb490637232e4a2860bade341dc86a2b5는 현재 head의 ancestor이며 전체 후속 diff는 evidence-manifest 한 파일뿐이다. 실행 입력은 동일하다. focused 68통과와 전체 286통과 및 4skip은 구현자 실행 근거이지 reviewer 독립 실행이나 CI 결과가 아니다.
    • 테스트 근거: tests/test_issue_12_regressions.py, tests/test_issue_12_review59_account.py, tests/test_account_valuation_edge_contracts.py
    • 판정 근거: 승인된 인수 의미와 실패 및 무변경 경계가 현재 source와 대응 test에 보존된다. 이전 verdict를 승계한 것이 아니라 현재 head의 source와 변경 영향을 대조한 판정이다.
  • C03-selection — satisfied

    • 계약: 계좌와 통화 및 평가 목적별 유효 자료를 선택한다. exact는 당일 확인 자료만, as_of는 기준일 이하 최신 확인 자료만 사용한다. 미래 자료는 제외하고 미확인 후보는 확인 자료를 대체하거나 합산하지 않는다. 실제 기준일과 경과 일수 및 이월 상태를 반환한다.
    • 구현 근거: jarca_ledger_mcp/application/account_valuation_service.py, jarca_ledger_mcp/application/assets_service.py; account_valuation_service.py:270-312 select_account_valuation의 scope와 verified leaf, exact 및 latest-prior, candidate warning 및 age; assets_service.py:115-215와 :218-259의 계좌 및 기존 수기 selection과 미래/미확인/통화 제외를 대조했다. tests/test_account_valuations.py:35-45는 future와 unverified 제외 및 as-of carry와 actual date를 assertion한다. tests/test_issue_12_regressions.py의 scope 및 purpose와 unverified 합계 제외 regression을 함께 읽었다. 현재 고정 head의 실제 구현과 named test 인수 및 assertion을 계약에 대조했다. 구현자 evidence source d258cfdeb490637232e4a2860bade341dc86a2b5는 현재 head의 ancestor이며 전체 후속 diff는 evidence-manifest 한 파일뿐이다. 실행 입력은 동일하다. focused 68통과와 전체 286통과 및 4skip은 구현자 실행 근거이지 reviewer 독립 실행이나 CI 결과가 아니다.
    • 테스트 근거: tests/test_account_valuations.py, tests/test_issue_12_regressions.py
    • 판정 근거: 승인된 인수 의미와 실패 및 무변경 경계가 현재 source와 대응 test에 보존된다. 이전 verdict를 승계한 것이 아니라 현재 head의 source와 변경 영향을 대조한 판정이다.
  • C04-correction-validation — satisfied

    • 계약: 평가 정정은 append-only로 대상과 사유를 연결하며 다른 계좌, 통화, 목적을 참조하는 정정과 순환 및 동일 유효본의 동시 분기를 차단한다.
    • 구현 근거: jarca_ledger_mcp/application/account_valuation_service.py, jarca_ledger_mcp/infrastructure/sqlite/schema.py; account_valuation_service.py:204-224는 parent scope와 cyclic ancestry를 검증하고 :245-253은 단일 child unique 충돌을 fail-closed 처리한다. :315-375의 effective payload replay 및 changed conflict와 append-only 경계를 확인했다. tests/test_account_valuations.py:48-59는 원본 보존과 단일 correction count를 assertion하고 tests/test_account_valuation_edge_contracts.py:79-130은 동일 effective correction reuse 및 다른 payload conflict를 확인한다. 현재 고정 head의 실제 구현과 named test 인수 및 assertion을 계약에 대조했다. 구현자 evidence source d258cfdeb490637232e4a2860bade341dc86a2b5는 현재 head의 ancestor이며 전체 후속 diff는 evidence-manifest 한 파일뿐이다. 실행 입력은 동일하다. focused 68통과와 전체 286통과 및 4skip은 구현자 실행 근거이지 reviewer 독립 실행이나 CI 결과가 아니다.
    • 테스트 근거: tests/test_issue_12_review59_account.py, tests/test_account_valuations.py, tests/test_issue_12_regressions.py
    • 판정 근거: 승인된 인수 의미와 실패 및 무변경 경계가 현재 source와 대응 test에 보존된다. 이전 verdict를 승계한 것이 아니라 현재 head의 source와 변경 영향을 대조한 판정이다.
  • C05-current-import — unsatisfied

    • 계약: 뒤늦은 과거 자료 등록으로 최신 표시값을 과거로 되돌리지 않는다. 기존 계좌 수정과 import의 최신 캐시 및 새 이력 권위를 연결하며 동기화 시각을 실제 평가일로 오인하지 않는다.
    • 구현 근거: jarca_ledger_mcp/application/imports_service.py, jarca_ledger_mcp/application/assets_service.py, jarca_ledger_mcp/application/accounts_write_services.py; 이전 F005의 빈 잔액과 dated update는 accounts_write_services.py:45-46에서 거부되며 test_empty_balance_with_basis_date_is_rejected_without_mutation_before_import의 tests/test_import_current_balance_authority.py:83-101은 계좌와 valuation 불변 및 후속 dated import 성공을 확인한다. 잔여 경로는 accounts_write_services.py:17-34의 create다. :28-29는 None과 빈 문자열만 거부하고 :31은 공백 또는 abc 같은 비정수 last_balance와 유효 기준일을 그대로 INSERT한다. :5-14의 candidate 변환 실패는 조용히 끝나며 create는 성공을 반환한다. imports_service.py:43-49는 금액 유효성 없이 이 잘못된 cache의 기준일만 비교하므로 더 오래된 실제 잔액 import의 최신 표시 반영이 막힌다. assets_service.py:210-214 및 :1105-1114의 current liquidity report도 비정수 잔액을 int 변환하여 ValueError가 public envelope 밖으로 나갈 수 있다. docs/data-model.md:26-27 및 :132-136은 exact integer 또는 NULL과 실제 잔액 근거 기준일 계약을 명시한다. 기존 create tests는 basis-only None 거부만 검사하고 공백 및 비정수와 날짜 조합은 검사하지 않는다.
    • 테스트 근거: tests/test_issue_12_review59_account.py, tests/test_import_provenance_policy.py, tests/test_import_current_balance_authority.py, tests/test_account_basis_public_consumers.py, tests/test_issue_12_review63_accounts.py
    • 판정 근거: F005의 원래 빈 문자열 dated update 사례는 해소됐지만 동일한 current-cache 권위 계약의 create 경계가 남는다. 계좌 생성도 잔액을 정수 또는 미확인 NULL로 검증한 뒤 날짜와 함께 저장해야 하며 실제 0은 허용해야 한다. 공백 또는 비정수와 유효 날짜를 생성 경로에 입력할 때 mutation 전 무변경 실패하고 이후 정상 dated import가 최신 표시를 갱신함을 최소 회귀로 확인할 수 있다. 이는 새로운 요구사항이나 DB 손상 복구 요구가 아니라 승인된 기존 계좌 쓰기와 import 권위 연결의 잔여 위반이다.
  • C06-idempotency — satisfied

    • 계약: 동일 증빙 또는 idempotency 재입력은 동일 기록을 재사용하며 같은 키의 다른 payload는 충돌이다. 동시 정정의 분기를 차단하고 UNIQUE 계좌 및 기준일 하나로 정정 추가를 막지 않는다.
    • 구현 근거: jarca_ledger_mcp/application/account_valuation_service.py, jarca_ledger_mcp/infrastructure/sqlite/schema.py, jarca_ledger_mcp/infrastructure/sqlite/migrations.py, jarca_ledger_mcp/application/accounts_write_services.py, jarca_ledger_mcp/application/imports_service.py; account_valuation_service.py:107-125의 candidate key payload, :225-244의 key와 source_ref 정본 및 unrelated scope conflict, :315-375의 explicit 및 keyless effective correction reuse; schema.py:264-267의 account-scoped key와 single-child index를 대조했다. tests/test_account_valuations.py:24-32 및 :72-80과 tests/test_account_valuation_edge_contracts.py:79-130, :194-231은 동일/변경 payload 및 correction와 candidate validation의 actual assertions를 제공한다. 현재 고정 head의 실제 구현과 named test 인수 및 assertion을 계약에 대조했다. 구현자 evidence source d258cfdeb490637232e4a2860bade341dc86a2b5는 현재 head의 ancestor이며 전체 후속 diff는 evidence-manifest 한 파일뿐이다. 실행 입력은 동일하다. focused 68통과와 전체 286통과 및 4skip은 구현자 실행 근거이지 reviewer 독립 실행이나 CI 결과가 아니다.
    • 테스트 근거: tests/test_issue_12_review59_account.py, tests/test_account_valuations.py, tests/test_issue_12_regressions.py, tests/test_account_valuation_edge_contracts.py
    • 판정 근거: 승인된 인수 의미와 실패 및 무변경 경계가 현재 source와 대응 test에 보존된다. 이전 verdict를 승계한 것이 아니라 현재 head의 source와 변경 영향을 대조한 판정이다.
  • C07-close-immutability — satisfied

    • 계약: 기존 asset_snapshots와 correction run을 보존하고 평가 정정 및 거래 추가로 기존 마감을 자동 변경하지 않는다. 동일 기준일 재마감은 사유와 이전 run 연결을 가진 새 버전을 원자적으로 추가한다.
    • 구현 근거: jarca_ledger_mcp/application/assets_service.py, jarca_ledger_mcp/infrastructure/sqlite/schema.py, jarca_ledger_mcp/infrastructure/sqlite/migrations.py; assets_service.py:717-752는 correction chain과 최신 correction authority를 검사하고 :757은 원래 existing run을 읽는다. unrelated live drift는 :800에서 idempotency_conflict다. tests/test_issue_12_review63_assets.py:97-138은 두 correction 이후 original equality와 unrelated asset drift conflict를 확인한다. 추가 evidence-array 검증은 :262-269 및 :297-320과 report/replay/timeseries의 오류 경계에 제한적으로 배치돼 정상 run 불변성을 변경하지 않는다. 현재 고정 head의 실제 구현과 named test 인수 및 assertion을 계약에 대조했다. 구현자 evidence source d258cfdeb490637232e4a2860bade341dc86a2b5는 현재 head의 ancestor이며 전체 후속 diff는 evidence-manifest 한 파일뿐이다. 실행 입력은 동일하다. focused 68통과와 전체 286통과 및 4skip은 구현자 실행 근거이지 reviewer 독립 실행이나 CI 결과가 아니다.
    • 테스트 근거: tests/test_asset_snapshots.py, tests/test_issue_12_regressions.py, tests/test_issue_12_review63_assets.py
    • 판정 근거: 승인된 인수 의미와 실패 및 무변경 경계가 현재 source와 대응 test에 보존된다. 이전 verdict를 승계한 것이 아니라 현재 head의 source와 변경 영향을 대조한 판정이다.
  • N02-close-replay-run-binding — satisfied

    • 계약: 마감 버전의 근거는 불변이며 동일 idempotency 요청은 원래 기록을 재사용한다. 재마감으로 과거 run 응답 및 evidence를 변경하지 않는다.
    • 구현 근거: jarca_ledger_mcp/application/assets_service.py, docs/interface-contract.md; F002 해소. assets_service.py:842-860은 included unverified_candidates와 excluded candidate의 blocking 및 state_hash를 저장한다. :383-398은 blocking=False를 복원하고 :757-799는 exact existing run에서 원래 응답을 구성한다. tests/test_asset_snapshot_idempotency.py:9-64의 test_replay_preserves_redacted_unverified_candidates_after_correction은 후보 allowlist와 blocking=False 및 전체 replay==first와 row/run count 불변을 assertion한다. :67-96의 test_replay_preserves_blocking_candidate_warning_shape은 차단 warning의 blocking 키 부재와 최초 응답 equality를 확인한다. 기존 mixed-asof 및 correction-chain equality 테스트도 보존된다. 현재 고정 head의 실제 구현과 named test 인수 및 assertion을 계약에 대조했다. 구현자 evidence source d258cfdeb490637232e4a2860bade341dc86a2b5는 현재 head의 ancestor이며 전체 후속 diff는 evidence-manifest 한 파일뿐이다. 실행 입력은 동일하다. focused 68통과와 전체 286통과 및 4skip은 구현자 실행 근거이지 reviewer 독립 실행이나 CI 결과가 아니다.
    • 테스트 근거: tests/test_issue_12_review59_reports.py, tests/test_issue_12_regressions.py, tests/test_asset_snapshot_idempotency.py, tests/test_issue_12_review63_assets.py
    • 판정 근거: 이전 후보 metadata와 nonblocking warning 손실은 현재 저장 및 복원 경로에서 해소됐다. 정정 후 원래 run replay와 blocking 및 nonblocking shape가 모두 named assertions로 대응한다.
  • C08-approved-conditional — satisfied

    • 계약: 완전한 exact 마감, 미완료 초안, 별도 승인된 조건부 마감을 구분한다. 승인 전 누락 및 이월은 미완료 초안이고 승인 후에도 누락 제외 및 확인된 과거값 이월만 허용한다. 미확인, 미래, 기준일 미상 금액은 승인으로도 합산하지 않으며 적용과 제외와 이월 및 승인자와 시각과 사유와 근거를 고정한다.
    • 구현 근거: jarca_ledger_mcp/application/assets_service.py, jarca_ledger_mcp/infrastructure/sqlite/schema.py, dashboard/page_views/assets.py; assets_service.py:646-671 및 :684-709은 public redaction 이전 동일 preview fingerprint와 승인 경계를 확인한다. 기존 test_f001_preview_fingerprint_uses_same_unredacted_authority_and_rejects_drift의 :17-41은 unchanged handoff 성공과 drift 거부 및 run 불변을 assertion한다. 미확인 candidate는 합산하지 않으며 nonblocking 후보는 conditional 승인 대상으로 오인하지 않는다. 승인자와 시각 및 사유와 참조, 적용과 제외와 이월은 :842-864에 원자적으로 저장한다. 현재 고정 head의 실제 구현과 named test 인수 및 assertion을 계약에 대조했다. 구현자 evidence source d258cfdeb490637232e4a2860bade341dc86a2b5는 현재 head의 ancestor이며 전체 후속 diff는 evidence-manifest 한 파일뿐이다. 실행 입력은 동일하다. focused 68통과와 전체 286통과 및 4skip은 구현자 실행 근거이지 reviewer 독립 실행이나 CI 결과가 아니다.
    • 테스트 근거: tests/test_issue_12_review59_reports.py, tests/test_issue_12_regressions.py, tests/test_asset_snapshots.py, tests/test_issue_12_review63_assets.py
    • 판정 근거: 승인된 인수 의미와 실패 및 무변경 경계가 현재 source와 대응 test에 보존된다. 이전 verdict를 승계한 것이 아니라 현재 head의 source와 변경 영향을 대조한 판정이다.
  • C09-reconciliation — satisfied

    • 계약: 외부 확인값과 장부 계산값을 분리하고 검증된 시작잔고, 기준시점, 거래 포함 범위와 계산 완전성을 표시한다. 거래 없는 수동 투자 계좌의 대사 불가 및 거래 미수입과 평가 수동 관리 상태를 구분하고 가짜 거래를 만들지 않는다. 대사도 공통 평가 근거와 대출 대표 정의를 사용한다.
    • 구현 근거: jarca_ledger_mcp/application/reconciliation_service.py, jarca_ledger_mcp/application/account_valuation_service.py, jarca_ledger_mcp/application/monthly_settlement_service.py; reconciliation_service.py:31-64 _account_balance_row는 시작 근거 및 거래 coverage를 분리하고 :102-158은 verified corrected leaf와 목적 및 대출 정의를 선택한다. :159-213은 계산 불완전 및 수동 투자 평가 관리와 대사 불가 상태를 provenance로 전달한다. monthly_settlement_service.py의 get_monthly_settlement_summary는 공통 report를 읽으며 tests/test_issue_12_review59_reports.py 및 tests/test_issue_12_regressions.py의 no-fake-transaction와 corrected-investment 및 unavailable assertions에 대응한다. 현재 고정 head의 실제 구현과 named test 인수 및 assertion을 계약에 대조했다. 구현자 evidence source d258cfdeb490637232e4a2860bade341dc86a2b5는 현재 head의 ancestor이며 전체 후속 diff는 evidence-manifest 한 파일뿐이다. 실행 입력은 동일하다. focused 68통과와 전체 286통과 및 4skip은 구현자 실행 근거이지 reviewer 독립 실행이나 CI 결과가 아니다.
    • 테스트 근거: tests/test_issue_12_review59_reports.py, tests/test_issue_12_regressions.py, tests/test_service.py
    • 판정 근거: 승인된 인수 의미와 실패 및 무변경 경계가 현재 source와 대응 test에 보존된다. 이전 verdict를 승계한 것이 아니라 현재 head의 source와 변경 영향을 대조한 판정이다.
  • C10-report-monthly-evidence — satisfied

    • 계약: MCP와 Dashboard 및 월정산 보고에서 같은 기준일과 선택 근거 및 실제 평가일, 경과 일수, 확인 상태, 누락과 미확인 및 이월 경고, 마감 버전 및 조건부 승인 근거를 일관되게 전달한다.
    • 구현 근거: jarca_ledger_mcp/application/assets_service.py, jarca_ledger_mcp/application/monthly_settlement_service.py, dashboard/page_views/monthly_settlement.py, dashboard/page_views/accounts.py; assets_service.py:335-380은 frozen valuation_id와 currency 및 실제 basis를 복원한다. :948-984는 frozen run을 정본으로 보고하고 :1049-1102는 zero-row run 날짜를 UNION으로 포함해 latest run의 승인 및 provenance를 전달한다. tests/test_issue_12_review63_assets.py:141-206은 zero-row 정정 run 및 alias, frozen ID와 currency 및 legacy ID 비추론을 assertion한다. monthly_settlement_service.py는 해당 공통 report를 읽는다. malformed JSON 배열 guard의 신규 test는 tests/test_asset_snapshot_idempotency.py:99-128이며 report/replay/timeseries 실패 및 row/run 불변을 확인한다. 임의 DB 손상 전체의 복구나 추가 오류명은 새 인수 조건으로 만들지 않는다. 현재 고정 head의 실제 구현과 named test 인수 및 assertion을 계약에 대조했다. 구현자 evidence source d258cfdeb490637232e4a2860bade341dc86a2b5는 현재 head의 ancestor이며 전체 후속 diff는 evidence-manifest 한 파일뿐이다. 실행 입력은 동일하다. focused 68통과와 전체 286통과 및 4skip은 구현자 실행 근거이지 reviewer 독립 실행이나 CI 결과가 아니다.
    • 테스트 근거: tests/test_issue_12_review59_reports.py, tests/test_issue_12_regressions.py, tests/test_service.py, tests/test_issue_12_review63_assets.py
    • 판정 근거: 승인된 인수 의미와 실패 및 무변경 경계가 현재 source와 대응 test에 보존된다. 이전 verdict를 승계한 것이 아니라 현재 head의 source와 변경 영향을 대조한 판정이다.
  • C11-adapter-structure — satisfied

    • 계약: MCP와 Streamlit gateway는 공통 application을 사용하고 기존 공개 호출명과 기존 인수 및 success와 실패 error_code 및 error envelope를 가능한 한 유지한다. 새 Dashboard 인증 또는 MCP 인증을 도입하지 않는다.
    • 구현 근거: jarca_ledger_mcp/adapters/mcp/server.py, jarca_ledger_mcp/adapters/mcp/tool_contracts.py, jarca_ledger_mcp/adapters/streamlit/accounts_gateway.py, jarca_ledger_mcp/application/__init__.py, jarca_ledger_mcp/service.py, dashboard/page_views/accounts.py, dashboard/page_views/assets.py, dashboard/page_views/monthly_settlement.py; service.py:50-70의 호환 facade와 application/asset_account_services.py:3-15의 공통 export, adapters/mcp/server.py의 create/register/select/correct/preview/close tools와 adapters/streamlit/accounts_gateway.py 및 overview_gateway.py의 shared-service delegate를 대조했다. dashboard/page_views/accounts.py 및 assets.py와 monthly_settlement.py는 shared gateway 결과를 렌더링하고 명시적 submit에서만 writer를 호출한다. tests/test_contract_regression.py와 tests/test_issue_12_regressions.py의 공개 signature/envelope 및 read-only assertions는 보존된다. 현재 고정 head의 실제 구현과 named test 인수 및 assertion을 계약에 대조했다. 구현자 evidence source d258cfdeb490637232e4a2860bade341dc86a2b5는 현재 head의 ancestor이며 전체 후속 diff는 evidence-manifest 한 파일뿐이다. 실행 입력은 동일하다. focused 68통과와 전체 286통과 및 4skip은 구현자 실행 근거이지 reviewer 독립 실행이나 CI 결과가 아니다.
    • 테스트 근거: tests/test_contract_regression.py, tests/test_issue_12_regressions.py
    • 판정 근거: 승인된 인수 의미와 실패 및 무변경 경계가 현재 source와 대응 test에 보존된다. 이전 verdict를 승계한 것이 아니라 현재 head의 source와 변경 영향을 대조한 판정이다.
  • C12-migration-legacy — satisfied

    • 계약: schema 11의 기존 데이터와 마감 및 개인정보를 보존하고 additive하고 idempotent한 migration을 제공한다. 기준일 증거 없는 값을 임의 월말로 소급하거나 legacy snapshot에 valuation_id를 추측하여 생성하지 않는다.
    • 구현 근거: jarca_ledger_mcp/infrastructure/sqlite/schema.py, jarca_ledger_mcp/infrastructure/sqlite/migrations.py, jarca_ledger_mcp/application/assets_service.py; migrations.py:19-173의 additive CREATE/ADD COLUMN과 unique 및 schema12 상태; assets_service.py:335-380의 frozen evidence와 legacy valuation_id 비추론을 대조했다. test_account_valuation_schema_is_v12_and_idempotent 및 test_schema12_migration_preserves_legacy_rows_indexes_and_is_idempotent는 기존 rows와 재호출 idempotency를 검사하고 tests/test_issue_12_review63_assets.py:199-206은 legacy ID가 생성되지 않음을 assertion한다. 현재 고정 head의 실제 구현과 named test 인수 및 assertion을 계약에 대조했다. 구현자 evidence source d258cfdeb490637232e4a2860bade341dc86a2b5는 현재 head의 ancestor이며 전체 후속 diff는 evidence-manifest 한 파일뿐이다. 실행 입력은 동일하다. focused 68통과와 전체 286통과 및 4skip은 구현자 실행 근거이지 reviewer 독립 실행이나 CI 결과가 아니다.
    • 테스트 근거: tests/test_account_valuations.py, tests/test_issue_12_regressions.py, tests/test_ledger_categories.py, tests/test_review_decision_workbench.py
    • 판정 근거: 승인된 인수 의미와 실패 및 무변경 경계가 현재 source와 대응 test에 보존된다. 이전 verdict를 승계한 것이 아니라 현재 head의 source와 변경 영향을 대조한 판정이다.
  • C13-read-only — satisfied

    • 계약: preview와 조회 및 Dashboard 렌더링은 금융 쓰기를 실행하지 않는다. 명시적 등록, 정정, 승인 close 및 import 제출만 변경을 수행하고 실패 시 부분 쓰기를 남기지 않는다.
    • 구현 근거: jarca_ledger_mcp/infrastructure/sqlite/connection.py, jarca_ledger_mcp/application/shared.py, jarca_ledger_mcp/application/system_services.py, jarca_ledger_mcp/application/account_valuation_service.py, jarca_ledger_mcp/application/assets_service.py; connection.py:31-53 connect_readonly/read_db의 mode=ro와 no-init, shared.py:128-138의 read 오류 envelope; assets_service.py:646-671의 preview와 :939-1138의 report/time-series/liquidity read, account_valuation_service.py:260-312의 read selector를 대조했다. tests/test_issue_12_review59_readonly.py는 missing DB no-path-create와 initialized DB schema/rows 불변을 검사하고 explicit writer는 connection.py:56-69에서만 init와 commit을 수행한다. 현재 고정 head의 실제 구현과 named test 인수 및 assertion을 계약에 대조했다. 구현자 evidence source d258cfdeb490637232e4a2860bade341dc86a2b5는 현재 head의 ancestor이며 전체 후속 diff는 evidence-manifest 한 파일뿐이다. 실행 입력은 동일하다. focused 68통과와 전체 286통과 및 4skip은 구현자 실행 근거이지 reviewer 독립 실행이나 CI 결과가 아니다.
    • 테스트 근거: tests/test_issue_12_review59_readonly.py, tests/test_dashboard_app.py, tests/test_dashboard_menu_transition.py
    • 판정 근거: 승인된 인수 의미와 실패 및 무변경 경계가 현재 source와 대응 test에 보존된다. 이전 verdict를 승계한 것이 아니라 현재 head의 source와 변경 영향을 대조한 판정이다.
  • C14-auth-menu-preservation — satisfied

    • 계약: Dashboard 인증은 DB보다 먼저이며 REQ-001의 cookie와 logout 및 REQ-002의 메뉴 label과 order, shell, query, error와 retry 및 명시적 금융 쓰기 계약을 유지한다.
    • 구현 근거: dashboard/app.py, dashboard/page_views/accounts.py, dashboard/page_views/assets.py, dashboard/page_views/monthly_settlement.py, docs/interface-contract.md, docs/project-structure.md, docs/runtime-flow.md; dashboard/app.py:37-72의 auth-before-financial-dispatch와 gateway read boundary, 기존 dashboard authentication/menu 관련 source 및 tests는 직전 head와 byte-identical하다. docs/interface-contract.md:1-261 및 docs/project-structure.md와 docs/runtime-flow.md의 기존 auth/cookie/logout와 canonical menu order 및 shell/query 내용이 보존된다. tests/test_dashboard_menu_transition.py 및 tests/test_dashboard_app.py의 actual authentication/menu/no-write assertions와 전체 구현자 regression 보고를 대응했다. 현재 고정 head의 실제 구현과 named test 인수 및 assertion을 계약에 대조했다. 구현자 evidence source d258cfdeb490637232e4a2860bade341dc86a2b5는 현재 head의 ancestor이며 전체 후속 diff는 evidence-manifest 한 파일뿐이다. 실행 입력은 동일하다. focused 68통과와 전체 286통과 및 4skip은 구현자 실행 근거이지 reviewer 독립 실행이나 CI 결과가 아니다.
    • 테스트 근거: tests/test_dashboard_menu_transition.py, tests/test_dashboard_app.py
    • 판정 근거: 승인된 인수 의미와 실패 및 무변경 경계가 현재 source와 대응 test에 보존된다. 이전 verdict를 승계한 것이 아니라 현재 head의 source와 변경 영향을 대조한 판정이다.
  • C15-exclusions-privacy — satisfied

    • 계약: 증권사 자동 연동, 정확한 성과 또는 환율 엔진, 새 인증, 별도 월정산 제품, 거래 추론 및 기존 데이터 자동 재작성과 수기 비계좌 자산 전체 이력 재설계를 추가하지 않는다. 실제 계좌 및 금융 증빙과 credential을 로그와 문서 및 테스트에 기록하지 않는다.
    • 구현 근거: jarca_ledger_mcp/application/assets_service.py, jarca_ledger_mcp/application/account_valuation_service.py, jarca_ledger_mcp/application/imports_service.py, jarca_ledger_mcp/application/reconciliation_service.py, jarca_ledger_mcp/infrastructure/sqlite/schema.py, jarca_ledger_mcp/infrastructure/sqlite/migrations.py; assets_service.py:62-75 _public_evidence 및 :94-112의 민감 source state는 digest로만 공개하고 :383-408의 closed metadata는 strict allowlist를 사용한다. account_valuation_service.py:29-30의 public candidate는 ID/date/currency/purpose/status만 반환한다. tests/test_asset_snapshot_idempotency.py:26-42는 redacted candidate와 state hash 및 비차단 warning shape를 assertion한다. changed-file 전체는 기존 금융 이력 및 마감과 read-only 보완 및 supporting tests/docs이며 외부 FX/가격/auth/성과 엔진이나 기존 데이터 재작성은 없다. 현재 고정 head의 실제 구현과 named test 인수 및 assertion을 계약에 대조했다. 구현자 evidence source d258cfdeb490637232e4a2860bade341dc86a2b5는 현재 head의 ancestor이며 전체 후속 diff는 evidence-manifest 한 파일뿐이다. 실행 입력은 동일하다. focused 68통과와 전체 286통과 및 4skip은 구현자 실행 근거이지 reviewer 독립 실행이나 CI 결과가 아니다.
    • 테스트 근거: tests/test_issue_12_review59_reports.py, tests/test_issue_12_regressions.py, scripts/ci_fixture_db.py
    • 판정 근거: 승인된 인수 의미와 실패 및 무변경 경계가 현재 source와 대응 test에 보존된다. 이전 verdict를 승계한 것이 아니라 현재 head의 source와 변경 영향을 대조한 판정이다.
  • D01-requirement-structure — satisfied

    • 계약: 신규 REQ-003을 배정 경로와 제목으로 작성하며 trusted harness README와 TEMPLATE의 JSON metadata, 연속 요구사항 및 AC, 필수 섹션, 판정 기준과 검증 및 검증 분류의 수준과 백엔드와 케이스 및 상태 불변조건을 충족한다. 초기 PR은 미정이며 PR 생성 후 실제 번호를 추적한다.
    • 구현 근거: docs/requirements/req-003_account-valuation-history.md; REQ-003의 JSON metadata docs/requirements/req-003_account-valuation-history.md:1-16, 연속 요구사항 :51-185 및 AC :187-297, 필수 오류와 계약과 호환성과 추적성 :299-317을 trusted harness README 및 TEMPLATE에 대조했다. Issue12와 실제 구현 PR13의 lifecycle traceability는 유효하다. 전체 문서와 이전 reviewed-head baseline은 byte-identical하다. 실제 tests/test_requirement_docs.py의 marker와 signature 및 named test 존재 assertion을 읽었다.
    • 테스트 근거: tests/test_requirement_docs.py
    • 판정 근거: 승인된 인수 의미와 실패 및 무변경 경계가 현재 source와 대응 test에 보존된다. 이전 verdict를 승계한 것이 아니라 현재 head의 source와 변경 영향을 대조한 판정이다.
  • D02-requirement-semantics — satisfied

    • 계약: 요구사항에는 평가 근거와 지표 정의, 선택과 future 제외, 정정 및 idempotency 충돌, 대사 완전성, current 및 import 연계, 마감 상태와 불변성과 승인, shared adapter 및 인증, migration과 legacy를 소스 및 테스트에 대응한다. 모든 승인된 경계와 회귀 사례를 인수 기준으로 내린다.
    • 구현 근거: docs/requirements/req-003_account-valuation-history.md; docs/requirements/req-003_account-valuation-history.md:53-185의 10개 요구사항과 :189-297의 전체 AC를 Discovery의 모든 포함 범위와 확정 결정 및 제외 범위에 대조했다. 이전 REQ-003 전체 AC와 byte-identical하여 의미 삭제나 승인 없는 축소가 없다. 참조된 tests와 actual implementation은 head에서 존재한다. 잔여 current-cache 구현 결함은 C05로 분리하며 문서 반복 부재나 evidence JSON 형식을 새로운 의무로 판단하지 않는다.
    • 테스트 근거: tests/test_account_valuations.py, tests/test_asset_snapshots.py, tests/test_issue_12_regressions.py, tests/test_requirement_docs.py, tests/test_mcp_http_runtime.py, tests/test_dashboard_authentication_app.py
    • 판정 근거: 승인된 인수 의미와 실패 및 무변경 경계가 현재 source와 대응 test에 보존된다. 이전 verdict를 승계한 것이 아니라 현재 head의 source와 변경 영향을 대조한 판정이다.
  • D03-data-model — satisfied

    • 계약: 신규 데이터 모델은 기존 entities 및 valuation과 마감의 관계, FK와 날짜 및 정확한 금액과 NULL 및 0과 선택 지표 및 대출 필수 정의, 계좌와 통화 및 목적과 기준일의 선택 및 index와 단일 유효 정정본, 고정 적용 분류 및 출처와 상태와 누락 및 이월 및 승인 버전, 분리된 정정과 schema11 이관 및 미상 날짜와 legacy 및 최신 캐시 동기화 책임을 정의한다.
    • 구현 근거: docs/data-model.md; docs/data-model.md:63-68은 account 필수와 currency 및 valuation purpose 선택 필터, basis-date exact 또는 upper-bound, verified leaf와 future 및 unverified 제외를 명시한다. account_date와 status_date 인덱스의 coverage 및 account-currency-purpose 전체를 덮지 않는 한계, idempotency 및 single_correction의 write integrity 책임을 구분한다. account_valuation_service.py:270-312의 실제 선택과 schema.py:264-267 및 migrations.py:169-172의 물리 정의에 대응한다. test_data_model_documents_valuation_selection_contract_and_index_mapping의 tests/test_valuation_contract_docs.py:46-62는 이 설명을 assertion한다. 나머지 entity 관계와 금액 NULL0 및 대출 정의, immutable run과 migration 및 legacy와 캐시 책임은 문서 :12-61 및 :70-176에 보존된다.
    • 테스트 근거: tests/test_account_valuations.py, tests/test_asset_snapshots.py, tests/test_issue_12_regressions.py, tests/test_valuation_contract_docs.py
    • 판정 근거: D03의 승인된 query 및 index 대응 문서 의무가 해소됐다. 새 복합 인덱스나 성능 의무를 요구하지 않는다.
  • D04-interface-contract — satisfied

    • 계약: 인터페이스 문서는 기존 auth 및 메뉴를 보존하고 평가 등록 및 조회 및 정정의 모든 입력과 유효본 및 원금 정의 출력, report 및 preview/close 및 월정산과 대사와 current API의 공통 선택, exact 기본과 실제 날짜 및 age 및 이월과 누락 및 미확인과 출처 및 버전과 승인 출력을 정의한다. 잘못된 입력과 scope 및 충돌과 부족 근거는 무변경 실패이며 기존 envelope와 required keys 및 의미 변경 정책을 명시한다.
    • 구현 근거: docs/interface-contract.md, docs/data-model.md; docs/interface-contract.md:1-261 기존 auth와 menu 보존; :263-358 valuation와 close 입력 및 오류와 무변경; :401-423 실제 signature와 persisted fields; :425-435 close 및 provenance aliases, preview fingerprint, equality replay와 recursive redaction을 승인 의무에 대조했다. 전체 문서는 이전 reviewed head와 동일하고 current source의 signature 및 enums와 대응한다.
    • 테스트 근거: tests/test_account_valuations.py, tests/test_issue_12_regressions.py, tests/test_contract_regression.py, tests/test_valuation_contract_docs.py, tests/test_issue_12_review59_account.py
    • 판정 근거: 승인된 인수 의미와 실패 및 무변경 경계가 현재 source와 대응 test에 보존된다. 이전 verdict를 승계한 것이 아니라 현재 head의 source와 변경 영향을 대조한 판정이다.
  • D05-project-structure — satisfied

    • 계약: 프로젝트 구조 문서는 기존 source와 test 및 evidence를 보존하고 SQLite schema와 migrations, application의 assets와 account writes 및 import와 reconciliation 및 monthly 책임, 공개 facade와 MCP 및 Streamlit과 기존 세 화면 및 tests를 exact 경로로 대응한다. adapter에서 선택 정책을 복제하지 않고 대출 정의와 verified as_of 및 conditional 승인 경계를 shared application에 배치한다.
    • 구현 근거: docs/project-structure.md; docs/project-structure.md:122-164의 source/test/docs 배치와 application 및 SQLite 및 adapter 의존, :166-212의 auth/menu inventory와 actual module ownership 및 monthly/reconciliation/read-only/privacy 경계를 모든 문서 의무와 current paths에 대조했다. 선택 정책을 adapter에 복제하지 않으며 별도 제품이나 마감 엔진이 없다.
    • 테스트 근거: tests/test_requirement_docs.py
    • 판정 근거: 승인된 인수 의미와 실패 및 무변경 경계가 현재 source와 대응 test에 보존된다. 이전 verdict를 승계한 것이 아니라 현재 head의 source와 변경 영향을 대조한 판정이다.
  • D06-runtime-flow — satisfied

    • 계약: 런타임 문서는 auth 및 메뉴를 보존하고 register/correct의 증빙 및 scope 검증과 append 및 유효본 확인 및 최신 캐시 동기화를 단일 트랜잭션으로 설명한다. 날짜 및 정책과 통화 및 대표 합산과 경고 read, preview 후 명시적 approval 및 원자적 freeze, reasoned reclose, 같은 근거의 monthly 및 대사, import와 이관 trigger 및 실패복구, retry와 concurrency 및 preview drift 재검증과 무부분쓰기, 비민감 valuation/run 상관 신호를 정의한다.
    • 구현 근거: docs/runtime-flow.md; docs/runtime-flow.md:147-185의 register/select/correct, preview/approval/atomic freeze, import와 monthly 및 reconciliation propagation; :187-210의 failure/retry/concurrency/비민감 signals; :221-241의 실제 transition와 DB boundary 및 fingerprint drift와 no-write 및 immutable replay를 승인 의무와 source에 대조했다. 별도 새 browser 조합이나 독립 실행 기록을 필수 계약으로 추가하지 않는다.
    • 테스트 근거: tests/test_account_valuations.py, tests/test_asset_snapshots.py, tests/test_issue_12_regressions.py
    • 판정 근거: 승인된 인수 의미와 실패 및 무변경 경계가 현재 source와 대응 test에 보존된다. 이전 verdict를 승계한 것이 아니라 현재 head의 source와 변경 영향을 대조한 판정이다.
  • C16-supporting-evidence-scope — satisfied

    • 계약: 모든 changed file은 승인된 기능과 필수 supporting change 또는 테스트 evidence로 설명되고 기존 requirement ID를 임의 갱신하거나 범위 밖 제품 및 설정을 변경하지 않는다.
    • 구현 근거: dashboard/app.py, dashboard/page_views/accounts.py, dashboard/page_views/assets.py, dashboard/page_views/monthly_settlement.py, docs/data-model.md, docs/interface-contract.md, docs/project-structure.md, docs/requirements/req-003_account-valuation-history.md, docs/runtime-flow.md, docs/verification/issue-12-review-60/contract-preservation-inventory.json, docs/verification/issue-12-review-60/evidence-manifest.json, docs/verification/issue-12-review-60/evidence-plan.json, docs/verification/issue-12-review-60/final-independent-review.json, docs/verification/issue-12-review-60/finding-matrix.json, docs/verification/issue-12-review-60/red-evidence.json, docs/verification/issue-12-review-61/contract-preservation-inventory.json, docs/verification/issue-12-review-61/evidence-manifest.json, docs/verification/issue-12-review-61/evidence-plan.json, docs/verification/issue-12-review-61/finding-matrix.json, docs/verification/issue-12-review-61/green-evidence.json, docs/verification/issue-12-review-61/red-evidence.json, docs/verification/issue-12-review-63/contract-preservation-inventory.json, docs/verification/issue-12-review-63/evidence-manifest.json, docs/verification/issue-12-review-63/evidence-plan.json, docs/verification/issue-12-review-63/finding-matrix.json, docs/verification/issue-12-review-63/red-evidence.json, docs/verification/issue-12-review-64/contract-preservation-inventory.json, docs/verification/issue-12-review-64/evidence-manifest.json, docs/verification/issue-12-review-64/evidence-plan.json, docs/verification/issue-12-review-64/finding-matrix.json, docs/verification/issue-12-review-64/red-evidence.json, jarca_ledger_mcp/adapters/mcp/server.py, jarca_ledger_mcp/adapters/mcp/tool_contracts.py, jarca_ledger_mcp/adapters/streamlit/accounts_gateway.py, jarca_ledger_mcp/adapters/streamlit/overview_gateway.py, jarca_ledger_mcp/application/__init_.py, jarca_ledger_mcp/application/account_valuation_service.py, jarca_ledger_mcp/application/accounts_write_services.py, jarca_ledger_mcp/application/assets_service.py, jarca_ledger_mcp/application/categorization_services.py, jarca_ledger_mcp/application/cross_transfer_service.py, jarca_ledger_mcp/application/imports_service.py, jarca_ledger_mcp/application/monthly_settlement_service.py, jarca_ledger_mcp/application/reconciliation_service.py, jarca_ledger_mcp/application/review_decision_service.py, jarca_ledger_mcp/application/shared.py, jarca_ledger_mcp/application/system_services.py, jarca_ledger_mcp/application/transaction_report_services.py, jarca_ledger_mcp/application/uncategorized_workbench_service.py, jarca_ledger_mcp/infrastructure/sqlite/__init_.py, jarca_ledger_mcp/infrastructure/sqlite/connection.py, jarca_ledger_mcp/infrastructure/sqlite/migrations.py, jarca_ledger_mcp/infrastructure/sqlite/schema.py, jarca_ledger_mcp/service.py, scripts/ci_fixture_db.py, tests/test_account_basis_public_consumers.py, tests/test_account_valuation_edge_contracts.py, tests/test_account_valuations.py, tests/test_asset_snapshot_idempotency.py, tests/test_asset_snapshots.py, tests/test_contract_regression.py, tests/test_dashboard_app.py, tests/test_dashboard_menu_transition.py, tests/test_import_current_balance_authority.py, tests/test_import_provenance_policy.py, tests/test_issue_12_regressions.py, tests/test_issue_12_review59_account.py, tests/test_issue_12_review59_readonly.py, tests/test_issue_12_review59_reports.py, tests/test_issue_12_review63_accounts.py, tests/test_issue_12_review63_assets.py, tests/test_ledger_categories.py, tests/test_requirement_docs.py, tests/test_review_decision_workbench.py, tests/test_seoulpay_xlsx.py, tests/test_service.py, tests/test_valuation_contract_docs.py; authoritative changed files 77개와 local base-to-head tree는 exact-match다. API diff 187개 hunk를 pinned blob 줄 위치와 내용에 대조했다. 이전 head 대비 source 변경은 account writer와 snapshot service 두 파일이며 승인된 권위 및 replay 경계 보완이다. data-model과 세 regression test 및 evidence JSON 다섯 파일은 승인된 문서 및 supporting evidence로 설명된다. manifest source의 모든 11개 blob OID와 SHA256 및 plan digest와 전체 source-to-head diff를 검증했다. 현재 고정 head의 실제 구현과 named test 인수 및 assertion을 계약에 대조했다. 구현자 evidence source d258cfdeb490637232e4a2860bade341dc86a2b5는 현재 head의 ancestor이며 전체 후속 diff는 evidence-manifest 한 파일뿐이다. 실행 입력은 동일하다. focused 68통과와 전체 286통과 및 4skip은 구현자 실행 근거이지 reviewer 독립 실행이나 CI 결과가 아니다.
    • 테스트 근거: tests/test_account_valuations.py, tests/test_asset_snapshots.py, tests/test_contract_regression.py, tests/test_dashboard_app.py, tests/test_dashboard_menu_transition.py, tests/test_import_provenance_policy.py, tests/test_issue_12_regressions.py, tests/test_issue_12_review59_account.py, tests/test_issue_12_review59_readonly.py, tests/test_issue_12_review59_reports.py, tests/test_ledger_categories.py, tests/test_requirement_docs.py, tests/test_review_decision_workbench.py, tests/test_seoulpay_xlsx.py, tests/test_service.py
    • 판정 근거: 승인된 인수 의미와 실패 및 무변경 경계가 현재 source와 대응 test에 보존된다. 이전 verdict를 승계한 것이 아니라 현재 head의 source와 변경 영향을 대조한 판정이다.

범위 판정

  • 누락: C05 current-cache authority의 create 경로가 공백 또는 비정수 잔액과 기준일을 저장하며 실제 dated import를 막는 잔여 경계 및 그 최소 회귀
  • 범위 초과: 없음
  • 명세 모순: 없음

결론

request_changes. F002 후보 metadata replay와 D03 문서 대응은 해소됐고 F005의 빈 문자열 dated update도 해소됐다. 다만 C05의 동일한 권위 의무에서 공백 또는 비정수 잔액과 기준일을 계좌 생성에 넣는 경로가 mutation 전에 거부되지 않아 잘못된 최신 캐시가 실제 잔액 import를 막는다. 기존 계약 범위의 생성 입력 검증과 무변경 및 후속 import 회귀를 보완해야 한다. 나머지 승인 계약 항목은 충족이다. 구현자의 focused 68통과와 전체 286통과 4skip은 source-to-head 실행 입력 동일성을 확인한 근거이고 reviewer 독립 제품 실행이나 CI 성공이 아니다. delegate의 snapshot 문서 test 실행 주장은 독립 제품 실행 근거로 사용하지 않았다.

## 구현 명세 적합성 검토 - Source Issue: #12 - Pull Request: #13 - Reviewed head: `fc2d2a6faeac3c64c0ed604f2aa1ad7c37c65570` - Contract SHA-256: `6d86b591b022fcc722611bfec6d24e54a64216ab6f7c4098f357e25420218818` - Verdict: `request_changes` ### Acceptance criteria 판정 - `C01-history` — `satisfied` - 계약: 평가 계좌 FK, 기준일과 등록일, 대표 금액과 통화와 목적, 출처와 확인 상태, 증빙 식별자, 정정 연결과 사유 및 선택 시간 자료를 이력으로 보존한다. - 구현 근거: jarca_ledger_mcp/application/account_valuation_service.py, jarca_ledger_mcp/infrastructure/sqlite/schema.py, jarca_ledger_mcp/infrastructure/sqlite/migrations.py; account_valuation_service.py:133-257 register_account_valuation 및 :261-266 list_account_valuations; schema.py:229-267 및 migrations.py:157-173의 실제 필드와 FK와 unique 정의를 대조했다. tests/test_account_valuations.py:13-21의 schema12/idempotent 및 :24-32의 동일 기록 reuse와 payload conflict assertions를 확인했다. 현재 고정 head의 실제 구현과 named test 인수 및 assertion을 계약에 대조했다. 구현자 evidence source d258cfdeb490637232e4a2860bade341dc86a2b5는 현재 head의 ancestor이며 전체 후속 diff는 evidence-manifest 한 파일뿐이다. 실행 입력은 동일하다. focused 68통과와 전체 286통과 및 4skip은 구현자 실행 근거이지 reviewer 독립 실행이나 CI 결과가 아니다. - 테스트 근거: tests/test_account_valuations.py - 판정 근거: 승인된 인수 의미와 실패 및 무변경 경계가 현재 source와 대응 test에 보존된다. 이전 verdict를 승계한 것이 아니라 현재 head의 source와 변경 영향을 대조한 판정이다. - `C02-money-metrics` — `satisfied` - 계약: 금액 정밀도와 NULL 및 0을 보존하고 취득원가, 순납입액, 기관 표시 원금 금액과 정의 및 원문 명칭, 손익과 수익률의 계산 기준을 구분한다. 투자 대표 총평가액과 포함 현금 및 원금을 중복 합산하지 않는다. - 구현 근거: jarca_ledger_mcp/application/account_valuation_service.py, jarca_ledger_mcp/infrastructure/sqlite/schema.py, docs/data-model.md, docs/requirements/req-003_account-valuation-history.md; account_valuation_service.py:33-56의 strict integer/finite 검증, :165-186의 선택 지표와 NULL 보존, :247-249의 실제 roundtrip columns; schema.py:229-267의 INTEGER 및 선택 NULL 필드와 assets_service.py:453-499의 대표 금액 합산을 대조했다. test_valuation_round_trip_preserves_null_zero_and_physical_amount_mapping 및 test_correction_preserves_optional_fields_unless_overridden의 입력과 actual assertions를 확인했다. 현재 고정 head의 실제 구현과 named test 인수 및 assertion을 계약에 대조했다. 구현자 evidence source d258cfdeb490637232e4a2860bade341dc86a2b5는 현재 head의 ancestor이며 전체 후속 diff는 evidence-manifest 한 파일뿐이다. 실행 입력은 동일하다. focused 68통과와 전체 286통과 및 4skip은 구현자 실행 근거이지 reviewer 독립 실행이나 CI 결과가 아니다. - 테스트 근거: tests/test_issue_12_review59_account.py, tests/test_issue_12_regressions.py - 판정 근거: 승인된 인수 의미와 실패 및 무변경 경계가 현재 source와 대응 test에 보존된다. 이전 verdict를 승계한 것이 아니라 현재 head의 source와 변경 영향을 대조한 판정이다. - `N01-loan-balance-definition` — `satisfied` - 계약: 대출 평가 기록마다 대표 부채가 원금만인지 원금과 이자 및 수수료인지 필수로 명시하고 기본값으로 추정하지 않는다. 목적 alias가 필수 정의 계약을 우회하지 않는다. - 구현 근거: jarca_ledger_mcp/application/account_valuation_service.py, docs/requirements/req-003_account-valuation-history.md, jarca_ledger_mcp/application/accounts_write_services.py, jarca_ledger_mcp/application/imports_service.py, docs/data-model.md; account_valuation_service.py:93-105의 loan candidate 무추정 거부 및 :194-203의 loan alias와 종류 및 필수 정의 검증; accounts_write_services.py:67-76의 non-loan 전환 guard; imports_service.py:37-41의 candidate 호출을 대조했다. tests/test_account_valuation_edge_contracts.py:8-38, :41-76, :133-191은 계좌 유형 전환과 정의 누락 및 candidate/import 경로의 validation_error와 history/account 불변을 assertion한다. 현재 고정 head의 실제 구현과 named test 인수 및 assertion을 계약에 대조했다. 구현자 evidence source d258cfdeb490637232e4a2860bade341dc86a2b5는 현재 head의 ancestor이며 전체 후속 diff는 evidence-manifest 한 파일뿐이다. 실행 입력은 동일하다. focused 68통과와 전체 286통과 및 4skip은 구현자 실행 근거이지 reviewer 독립 실행이나 CI 결과가 아니다. - 테스트 근거: tests/test_issue_12_regressions.py, tests/test_issue_12_review59_account.py, tests/test_account_valuation_edge_contracts.py - 판정 근거: 승인된 인수 의미와 실패 및 무변경 경계가 현재 source와 대응 test에 보존된다. 이전 verdict를 승계한 것이 아니라 현재 head의 source와 변경 영향을 대조한 판정이다. - `C03-selection` — `satisfied` - 계약: 계좌와 통화 및 평가 목적별 유효 자료를 선택한다. exact는 당일 확인 자료만, as_of는 기준일 이하 최신 확인 자료만 사용한다. 미래 자료는 제외하고 미확인 후보는 확인 자료를 대체하거나 합산하지 않는다. 실제 기준일과 경과 일수 및 이월 상태를 반환한다. - 구현 근거: jarca_ledger_mcp/application/account_valuation_service.py, jarca_ledger_mcp/application/assets_service.py; account_valuation_service.py:270-312 select_account_valuation의 scope와 verified leaf, exact 및 latest-prior, candidate warning 및 age; assets_service.py:115-215와 :218-259의 계좌 및 기존 수기 selection과 미래/미확인/통화 제외를 대조했다. tests/test_account_valuations.py:35-45는 future와 unverified 제외 및 as-of carry와 actual date를 assertion한다. tests/test_issue_12_regressions.py의 scope 및 purpose와 unverified 합계 제외 regression을 함께 읽었다. 현재 고정 head의 실제 구현과 named test 인수 및 assertion을 계약에 대조했다. 구현자 evidence source d258cfdeb490637232e4a2860bade341dc86a2b5는 현재 head의 ancestor이며 전체 후속 diff는 evidence-manifest 한 파일뿐이다. 실행 입력은 동일하다. focused 68통과와 전체 286통과 및 4skip은 구현자 실행 근거이지 reviewer 독립 실행이나 CI 결과가 아니다. - 테스트 근거: tests/test_account_valuations.py, tests/test_issue_12_regressions.py - 판정 근거: 승인된 인수 의미와 실패 및 무변경 경계가 현재 source와 대응 test에 보존된다. 이전 verdict를 승계한 것이 아니라 현재 head의 source와 변경 영향을 대조한 판정이다. - `C04-correction-validation` — `satisfied` - 계약: 평가 정정은 append-only로 대상과 사유를 연결하며 다른 계좌, 통화, 목적을 참조하는 정정과 순환 및 동일 유효본의 동시 분기를 차단한다. - 구현 근거: jarca_ledger_mcp/application/account_valuation_service.py, jarca_ledger_mcp/infrastructure/sqlite/schema.py; account_valuation_service.py:204-224는 parent scope와 cyclic ancestry를 검증하고 :245-253은 단일 child unique 충돌을 fail-closed 처리한다. :315-375의 effective payload replay 및 changed conflict와 append-only 경계를 확인했다. tests/test_account_valuations.py:48-59는 원본 보존과 단일 correction count를 assertion하고 tests/test_account_valuation_edge_contracts.py:79-130은 동일 effective correction reuse 및 다른 payload conflict를 확인한다. 현재 고정 head의 실제 구현과 named test 인수 및 assertion을 계약에 대조했다. 구현자 evidence source d258cfdeb490637232e4a2860bade341dc86a2b5는 현재 head의 ancestor이며 전체 후속 diff는 evidence-manifest 한 파일뿐이다. 실행 입력은 동일하다. focused 68통과와 전체 286통과 및 4skip은 구현자 실행 근거이지 reviewer 독립 실행이나 CI 결과가 아니다. - 테스트 근거: tests/test_issue_12_review59_account.py, tests/test_account_valuations.py, tests/test_issue_12_regressions.py - 판정 근거: 승인된 인수 의미와 실패 및 무변경 경계가 현재 source와 대응 test에 보존된다. 이전 verdict를 승계한 것이 아니라 현재 head의 source와 변경 영향을 대조한 판정이다. - `C05-current-import` — `unsatisfied` - 계약: 뒤늦은 과거 자료 등록으로 최신 표시값을 과거로 되돌리지 않는다. 기존 계좌 수정과 import의 최신 캐시 및 새 이력 권위를 연결하며 동기화 시각을 실제 평가일로 오인하지 않는다. - 구현 근거: jarca_ledger_mcp/application/imports_service.py, jarca_ledger_mcp/application/assets_service.py, jarca_ledger_mcp/application/accounts_write_services.py; 이전 F005의 빈 잔액과 dated update는 accounts_write_services.py:45-46에서 거부되며 test_empty_balance_with_basis_date_is_rejected_without_mutation_before_import의 tests/test_import_current_balance_authority.py:83-101은 계좌와 valuation 불변 및 후속 dated import 성공을 확인한다. 잔여 경로는 accounts_write_services.py:17-34의 create다. :28-29는 None과 빈 문자열만 거부하고 :31은 공백 또는 abc 같은 비정수 last_balance와 유효 기준일을 그대로 INSERT한다. :5-14의 candidate 변환 실패는 조용히 끝나며 create는 성공을 반환한다. imports_service.py:43-49는 금액 유효성 없이 이 잘못된 cache의 기준일만 비교하므로 더 오래된 실제 잔액 import의 최신 표시 반영이 막힌다. assets_service.py:210-214 및 :1105-1114의 current liquidity report도 비정수 잔액을 int 변환하여 ValueError가 public envelope 밖으로 나갈 수 있다. docs/data-model.md:26-27 및 :132-136은 exact integer 또는 NULL과 실제 잔액 근거 기준일 계약을 명시한다. 기존 create tests는 basis-only None 거부만 검사하고 공백 및 비정수와 날짜 조합은 검사하지 않는다. - 테스트 근거: tests/test_issue_12_review59_account.py, tests/test_import_provenance_policy.py, tests/test_import_current_balance_authority.py, tests/test_account_basis_public_consumers.py, tests/test_issue_12_review63_accounts.py - 판정 근거: F005의 원래 빈 문자열 dated update 사례는 해소됐지만 동일한 current-cache 권위 계약의 create 경계가 남는다. 계좌 생성도 잔액을 정수 또는 미확인 NULL로 검증한 뒤 날짜와 함께 저장해야 하며 실제 0은 허용해야 한다. 공백 또는 비정수와 유효 날짜를 생성 경로에 입력할 때 mutation 전 무변경 실패하고 이후 정상 dated import가 최신 표시를 갱신함을 최소 회귀로 확인할 수 있다. 이는 새로운 요구사항이나 DB 손상 복구 요구가 아니라 승인된 기존 계좌 쓰기와 import 권위 연결의 잔여 위반이다. - `C06-idempotency` — `satisfied` - 계약: 동일 증빙 또는 idempotency 재입력은 동일 기록을 재사용하며 같은 키의 다른 payload는 충돌이다. 동시 정정의 분기를 차단하고 UNIQUE 계좌 및 기준일 하나로 정정 추가를 막지 않는다. - 구현 근거: jarca_ledger_mcp/application/account_valuation_service.py, jarca_ledger_mcp/infrastructure/sqlite/schema.py, jarca_ledger_mcp/infrastructure/sqlite/migrations.py, jarca_ledger_mcp/application/accounts_write_services.py, jarca_ledger_mcp/application/imports_service.py; account_valuation_service.py:107-125의 candidate key payload, :225-244의 key와 source_ref 정본 및 unrelated scope conflict, :315-375의 explicit 및 keyless effective correction reuse; schema.py:264-267의 account-scoped key와 single-child index를 대조했다. tests/test_account_valuations.py:24-32 및 :72-80과 tests/test_account_valuation_edge_contracts.py:79-130, :194-231은 동일/변경 payload 및 correction와 candidate validation의 actual assertions를 제공한다. 현재 고정 head의 실제 구현과 named test 인수 및 assertion을 계약에 대조했다. 구현자 evidence source d258cfdeb490637232e4a2860bade341dc86a2b5는 현재 head의 ancestor이며 전체 후속 diff는 evidence-manifest 한 파일뿐이다. 실행 입력은 동일하다. focused 68통과와 전체 286통과 및 4skip은 구현자 실행 근거이지 reviewer 독립 실행이나 CI 결과가 아니다. - 테스트 근거: tests/test_issue_12_review59_account.py, tests/test_account_valuations.py, tests/test_issue_12_regressions.py, tests/test_account_valuation_edge_contracts.py - 판정 근거: 승인된 인수 의미와 실패 및 무변경 경계가 현재 source와 대응 test에 보존된다. 이전 verdict를 승계한 것이 아니라 현재 head의 source와 변경 영향을 대조한 판정이다. - `C07-close-immutability` — `satisfied` - 계약: 기존 asset_snapshots와 correction run을 보존하고 평가 정정 및 거래 추가로 기존 마감을 자동 변경하지 않는다. 동일 기준일 재마감은 사유와 이전 run 연결을 가진 새 버전을 원자적으로 추가한다. - 구현 근거: jarca_ledger_mcp/application/assets_service.py, jarca_ledger_mcp/infrastructure/sqlite/schema.py, jarca_ledger_mcp/infrastructure/sqlite/migrations.py; assets_service.py:717-752는 correction chain과 최신 correction authority를 검사하고 :757은 원래 existing run을 읽는다. unrelated live drift는 :800에서 idempotency_conflict다. tests/test_issue_12_review63_assets.py:97-138은 두 correction 이후 original equality와 unrelated asset drift conflict를 확인한다. 추가 evidence-array 검증은 :262-269 및 :297-320과 report/replay/timeseries의 오류 경계에 제한적으로 배치돼 정상 run 불변성을 변경하지 않는다. 현재 고정 head의 실제 구현과 named test 인수 및 assertion을 계약에 대조했다. 구현자 evidence source d258cfdeb490637232e4a2860bade341dc86a2b5는 현재 head의 ancestor이며 전체 후속 diff는 evidence-manifest 한 파일뿐이다. 실행 입력은 동일하다. focused 68통과와 전체 286통과 및 4skip은 구현자 실행 근거이지 reviewer 독립 실행이나 CI 결과가 아니다. - 테스트 근거: tests/test_asset_snapshots.py, tests/test_issue_12_regressions.py, tests/test_issue_12_review63_assets.py - 판정 근거: 승인된 인수 의미와 실패 및 무변경 경계가 현재 source와 대응 test에 보존된다. 이전 verdict를 승계한 것이 아니라 현재 head의 source와 변경 영향을 대조한 판정이다. - `N02-close-replay-run-binding` — `satisfied` - 계약: 마감 버전의 근거는 불변이며 동일 idempotency 요청은 원래 기록을 재사용한다. 재마감으로 과거 run 응답 및 evidence를 변경하지 않는다. - 구현 근거: jarca_ledger_mcp/application/assets_service.py, docs/interface-contract.md; F002 해소. assets_service.py:842-860은 included unverified_candidates와 excluded candidate의 blocking 및 state_hash를 저장한다. :383-398은 blocking=False를 복원하고 :757-799는 exact existing run에서 원래 응답을 구성한다. tests/test_asset_snapshot_idempotency.py:9-64의 test_replay_preserves_redacted_unverified_candidates_after_correction은 후보 allowlist와 blocking=False 및 전체 replay==first와 row/run count 불변을 assertion한다. :67-96의 test_replay_preserves_blocking_candidate_warning_shape은 차단 warning의 blocking 키 부재와 최초 응답 equality를 확인한다. 기존 mixed-asof 및 correction-chain equality 테스트도 보존된다. 현재 고정 head의 실제 구현과 named test 인수 및 assertion을 계약에 대조했다. 구현자 evidence source d258cfdeb490637232e4a2860bade341dc86a2b5는 현재 head의 ancestor이며 전체 후속 diff는 evidence-manifest 한 파일뿐이다. 실행 입력은 동일하다. focused 68통과와 전체 286통과 및 4skip은 구현자 실행 근거이지 reviewer 독립 실행이나 CI 결과가 아니다. - 테스트 근거: tests/test_issue_12_review59_reports.py, tests/test_issue_12_regressions.py, tests/test_asset_snapshot_idempotency.py, tests/test_issue_12_review63_assets.py - 판정 근거: 이전 후보 metadata와 nonblocking warning 손실은 현재 저장 및 복원 경로에서 해소됐다. 정정 후 원래 run replay와 blocking 및 nonblocking shape가 모두 named assertions로 대응한다. - `C08-approved-conditional` — `satisfied` - 계약: 완전한 exact 마감, 미완료 초안, 별도 승인된 조건부 마감을 구분한다. 승인 전 누락 및 이월은 미완료 초안이고 승인 후에도 누락 제외 및 확인된 과거값 이월만 허용한다. 미확인, 미래, 기준일 미상 금액은 승인으로도 합산하지 않으며 적용과 제외와 이월 및 승인자와 시각과 사유와 근거를 고정한다. - 구현 근거: jarca_ledger_mcp/application/assets_service.py, jarca_ledger_mcp/infrastructure/sqlite/schema.py, dashboard/page_views/assets.py; assets_service.py:646-671 및 :684-709은 public redaction 이전 동일 preview fingerprint와 승인 경계를 확인한다. 기존 test_f001_preview_fingerprint_uses_same_unredacted_authority_and_rejects_drift의 :17-41은 unchanged handoff 성공과 drift 거부 및 run 불변을 assertion한다. 미확인 candidate는 합산하지 않으며 nonblocking 후보는 conditional 승인 대상으로 오인하지 않는다. 승인자와 시각 및 사유와 참조, 적용과 제외와 이월은 :842-864에 원자적으로 저장한다. 현재 고정 head의 실제 구현과 named test 인수 및 assertion을 계약에 대조했다. 구현자 evidence source d258cfdeb490637232e4a2860bade341dc86a2b5는 현재 head의 ancestor이며 전체 후속 diff는 evidence-manifest 한 파일뿐이다. 실행 입력은 동일하다. focused 68통과와 전체 286통과 및 4skip은 구현자 실행 근거이지 reviewer 독립 실행이나 CI 결과가 아니다. - 테스트 근거: tests/test_issue_12_review59_reports.py, tests/test_issue_12_regressions.py, tests/test_asset_snapshots.py, tests/test_issue_12_review63_assets.py - 판정 근거: 승인된 인수 의미와 실패 및 무변경 경계가 현재 source와 대응 test에 보존된다. 이전 verdict를 승계한 것이 아니라 현재 head의 source와 변경 영향을 대조한 판정이다. - `C09-reconciliation` — `satisfied` - 계약: 외부 확인값과 장부 계산값을 분리하고 검증된 시작잔고, 기준시점, 거래 포함 범위와 계산 완전성을 표시한다. 거래 없는 수동 투자 계좌의 대사 불가 및 거래 미수입과 평가 수동 관리 상태를 구분하고 가짜 거래를 만들지 않는다. 대사도 공통 평가 근거와 대출 대표 정의를 사용한다. - 구현 근거: jarca_ledger_mcp/application/reconciliation_service.py, jarca_ledger_mcp/application/account_valuation_service.py, jarca_ledger_mcp/application/monthly_settlement_service.py; reconciliation_service.py:31-64 _account_balance_row는 시작 근거 및 거래 coverage를 분리하고 :102-158은 verified corrected leaf와 목적 및 대출 정의를 선택한다. :159-213은 계산 불완전 및 수동 투자 평가 관리와 대사 불가 상태를 provenance로 전달한다. monthly_settlement_service.py의 get_monthly_settlement_summary는 공통 report를 읽으며 tests/test_issue_12_review59_reports.py 및 tests/test_issue_12_regressions.py의 no-fake-transaction와 corrected-investment 및 unavailable assertions에 대응한다. 현재 고정 head의 실제 구현과 named test 인수 및 assertion을 계약에 대조했다. 구현자 evidence source d258cfdeb490637232e4a2860bade341dc86a2b5는 현재 head의 ancestor이며 전체 후속 diff는 evidence-manifest 한 파일뿐이다. 실행 입력은 동일하다. focused 68통과와 전체 286통과 및 4skip은 구현자 실행 근거이지 reviewer 독립 실행이나 CI 결과가 아니다. - 테스트 근거: tests/test_issue_12_review59_reports.py, tests/test_issue_12_regressions.py, tests/test_service.py - 판정 근거: 승인된 인수 의미와 실패 및 무변경 경계가 현재 source와 대응 test에 보존된다. 이전 verdict를 승계한 것이 아니라 현재 head의 source와 변경 영향을 대조한 판정이다. - `C10-report-monthly-evidence` — `satisfied` - 계약: MCP와 Dashboard 및 월정산 보고에서 같은 기준일과 선택 근거 및 실제 평가일, 경과 일수, 확인 상태, 누락과 미확인 및 이월 경고, 마감 버전 및 조건부 승인 근거를 일관되게 전달한다. - 구현 근거: jarca_ledger_mcp/application/assets_service.py, jarca_ledger_mcp/application/monthly_settlement_service.py, dashboard/page_views/monthly_settlement.py, dashboard/page_views/accounts.py; assets_service.py:335-380은 frozen valuation_id와 currency 및 실제 basis를 복원한다. :948-984는 frozen run을 정본으로 보고하고 :1049-1102는 zero-row run 날짜를 UNION으로 포함해 latest run의 승인 및 provenance를 전달한다. tests/test_issue_12_review63_assets.py:141-206은 zero-row 정정 run 및 alias, frozen ID와 currency 및 legacy ID 비추론을 assertion한다. monthly_settlement_service.py는 해당 공통 report를 읽는다. malformed JSON 배열 guard의 신규 test는 tests/test_asset_snapshot_idempotency.py:99-128이며 report/replay/timeseries 실패 및 row/run 불변을 확인한다. 임의 DB 손상 전체의 복구나 추가 오류명은 새 인수 조건으로 만들지 않는다. 현재 고정 head의 실제 구현과 named test 인수 및 assertion을 계약에 대조했다. 구현자 evidence source d258cfdeb490637232e4a2860bade341dc86a2b5는 현재 head의 ancestor이며 전체 후속 diff는 evidence-manifest 한 파일뿐이다. 실행 입력은 동일하다. focused 68통과와 전체 286통과 및 4skip은 구현자 실행 근거이지 reviewer 독립 실행이나 CI 결과가 아니다. - 테스트 근거: tests/test_issue_12_review59_reports.py, tests/test_issue_12_regressions.py, tests/test_service.py, tests/test_issue_12_review63_assets.py - 판정 근거: 승인된 인수 의미와 실패 및 무변경 경계가 현재 source와 대응 test에 보존된다. 이전 verdict를 승계한 것이 아니라 현재 head의 source와 변경 영향을 대조한 판정이다. - `C11-adapter-structure` — `satisfied` - 계약: MCP와 Streamlit gateway는 공통 application을 사용하고 기존 공개 호출명과 기존 인수 및 success와 실패 error_code 및 error envelope를 가능한 한 유지한다. 새 Dashboard 인증 또는 MCP 인증을 도입하지 않는다. - 구현 근거: jarca_ledger_mcp/adapters/mcp/server.py, jarca_ledger_mcp/adapters/mcp/tool_contracts.py, jarca_ledger_mcp/adapters/streamlit/accounts_gateway.py, jarca_ledger_mcp/application/__init__.py, jarca_ledger_mcp/service.py, dashboard/page_views/accounts.py, dashboard/page_views/assets.py, dashboard/page_views/monthly_settlement.py; service.py:50-70의 호환 facade와 application/asset_account_services.py:3-15의 공통 export, adapters/mcp/server.py의 create/register/select/correct/preview/close tools와 adapters/streamlit/accounts_gateway.py 및 overview_gateway.py의 shared-service delegate를 대조했다. dashboard/page_views/accounts.py 및 assets.py와 monthly_settlement.py는 shared gateway 결과를 렌더링하고 명시적 submit에서만 writer를 호출한다. tests/test_contract_regression.py와 tests/test_issue_12_regressions.py의 공개 signature/envelope 및 read-only assertions는 보존된다. 현재 고정 head의 실제 구현과 named test 인수 및 assertion을 계약에 대조했다. 구현자 evidence source d258cfdeb490637232e4a2860bade341dc86a2b5는 현재 head의 ancestor이며 전체 후속 diff는 evidence-manifest 한 파일뿐이다. 실행 입력은 동일하다. focused 68통과와 전체 286통과 및 4skip은 구현자 실행 근거이지 reviewer 독립 실행이나 CI 결과가 아니다. - 테스트 근거: tests/test_contract_regression.py, tests/test_issue_12_regressions.py - 판정 근거: 승인된 인수 의미와 실패 및 무변경 경계가 현재 source와 대응 test에 보존된다. 이전 verdict를 승계한 것이 아니라 현재 head의 source와 변경 영향을 대조한 판정이다. - `C12-migration-legacy` — `satisfied` - 계약: schema 11의 기존 데이터와 마감 및 개인정보를 보존하고 additive하고 idempotent한 migration을 제공한다. 기준일 증거 없는 값을 임의 월말로 소급하거나 legacy snapshot에 valuation_id를 추측하여 생성하지 않는다. - 구현 근거: jarca_ledger_mcp/infrastructure/sqlite/schema.py, jarca_ledger_mcp/infrastructure/sqlite/migrations.py, jarca_ledger_mcp/application/assets_service.py; migrations.py:19-173의 additive CREATE/ADD COLUMN과 unique 및 schema12 상태; assets_service.py:335-380의 frozen evidence와 legacy valuation_id 비추론을 대조했다. test_account_valuation_schema_is_v12_and_idempotent 및 test_schema12_migration_preserves_legacy_rows_indexes_and_is_idempotent는 기존 rows와 재호출 idempotency를 검사하고 tests/test_issue_12_review63_assets.py:199-206은 legacy ID가 생성되지 않음을 assertion한다. 현재 고정 head의 실제 구현과 named test 인수 및 assertion을 계약에 대조했다. 구현자 evidence source d258cfdeb490637232e4a2860bade341dc86a2b5는 현재 head의 ancestor이며 전체 후속 diff는 evidence-manifest 한 파일뿐이다. 실행 입력은 동일하다. focused 68통과와 전체 286통과 및 4skip은 구현자 실행 근거이지 reviewer 독립 실행이나 CI 결과가 아니다. - 테스트 근거: tests/test_account_valuations.py, tests/test_issue_12_regressions.py, tests/test_ledger_categories.py, tests/test_review_decision_workbench.py - 판정 근거: 승인된 인수 의미와 실패 및 무변경 경계가 현재 source와 대응 test에 보존된다. 이전 verdict를 승계한 것이 아니라 현재 head의 source와 변경 영향을 대조한 판정이다. - `C13-read-only` — `satisfied` - 계약: preview와 조회 및 Dashboard 렌더링은 금융 쓰기를 실행하지 않는다. 명시적 등록, 정정, 승인 close 및 import 제출만 변경을 수행하고 실패 시 부분 쓰기를 남기지 않는다. - 구현 근거: jarca_ledger_mcp/infrastructure/sqlite/connection.py, jarca_ledger_mcp/application/shared.py, jarca_ledger_mcp/application/system_services.py, jarca_ledger_mcp/application/account_valuation_service.py, jarca_ledger_mcp/application/assets_service.py; connection.py:31-53 connect_readonly/read_db의 mode=ro와 no-init, shared.py:128-138의 read 오류 envelope; assets_service.py:646-671의 preview와 :939-1138의 report/time-series/liquidity read, account_valuation_service.py:260-312의 read selector를 대조했다. tests/test_issue_12_review59_readonly.py는 missing DB no-path-create와 initialized DB schema/rows 불변을 검사하고 explicit writer는 connection.py:56-69에서만 init와 commit을 수행한다. 현재 고정 head의 실제 구현과 named test 인수 및 assertion을 계약에 대조했다. 구현자 evidence source d258cfdeb490637232e4a2860bade341dc86a2b5는 현재 head의 ancestor이며 전체 후속 diff는 evidence-manifest 한 파일뿐이다. 실행 입력은 동일하다. focused 68통과와 전체 286통과 및 4skip은 구현자 실행 근거이지 reviewer 독립 실행이나 CI 결과가 아니다. - 테스트 근거: tests/test_issue_12_review59_readonly.py, tests/test_dashboard_app.py, tests/test_dashboard_menu_transition.py - 판정 근거: 승인된 인수 의미와 실패 및 무변경 경계가 현재 source와 대응 test에 보존된다. 이전 verdict를 승계한 것이 아니라 현재 head의 source와 변경 영향을 대조한 판정이다. - `C14-auth-menu-preservation` — `satisfied` - 계약: Dashboard 인증은 DB보다 먼저이며 REQ-001의 cookie와 logout 및 REQ-002의 메뉴 label과 order, shell, query, error와 retry 및 명시적 금융 쓰기 계약을 유지한다. - 구현 근거: dashboard/app.py, dashboard/page_views/accounts.py, dashboard/page_views/assets.py, dashboard/page_views/monthly_settlement.py, docs/interface-contract.md, docs/project-structure.md, docs/runtime-flow.md; dashboard/app.py:37-72의 auth-before-financial-dispatch와 gateway read boundary, 기존 dashboard authentication/menu 관련 source 및 tests는 직전 head와 byte-identical하다. docs/interface-contract.md:1-261 및 docs/project-structure.md와 docs/runtime-flow.md의 기존 auth/cookie/logout와 canonical menu order 및 shell/query 내용이 보존된다. tests/test_dashboard_menu_transition.py 및 tests/test_dashboard_app.py의 actual authentication/menu/no-write assertions와 전체 구현자 regression 보고를 대응했다. 현재 고정 head의 실제 구현과 named test 인수 및 assertion을 계약에 대조했다. 구현자 evidence source d258cfdeb490637232e4a2860bade341dc86a2b5는 현재 head의 ancestor이며 전체 후속 diff는 evidence-manifest 한 파일뿐이다. 실행 입력은 동일하다. focused 68통과와 전체 286통과 및 4skip은 구현자 실행 근거이지 reviewer 독립 실행이나 CI 결과가 아니다. - 테스트 근거: tests/test_dashboard_menu_transition.py, tests/test_dashboard_app.py - 판정 근거: 승인된 인수 의미와 실패 및 무변경 경계가 현재 source와 대응 test에 보존된다. 이전 verdict를 승계한 것이 아니라 현재 head의 source와 변경 영향을 대조한 판정이다. - `C15-exclusions-privacy` — `satisfied` - 계약: 증권사 자동 연동, 정확한 성과 또는 환율 엔진, 새 인증, 별도 월정산 제품, 거래 추론 및 기존 데이터 자동 재작성과 수기 비계좌 자산 전체 이력 재설계를 추가하지 않는다. 실제 계좌 및 금융 증빙과 credential을 로그와 문서 및 테스트에 기록하지 않는다. - 구현 근거: jarca_ledger_mcp/application/assets_service.py, jarca_ledger_mcp/application/account_valuation_service.py, jarca_ledger_mcp/application/imports_service.py, jarca_ledger_mcp/application/reconciliation_service.py, jarca_ledger_mcp/infrastructure/sqlite/schema.py, jarca_ledger_mcp/infrastructure/sqlite/migrations.py; assets_service.py:62-75 _public_evidence 및 :94-112의 민감 source state는 digest로만 공개하고 :383-408의 closed metadata는 strict allowlist를 사용한다. account_valuation_service.py:29-30의 public candidate는 ID/date/currency/purpose/status만 반환한다. tests/test_asset_snapshot_idempotency.py:26-42는 redacted candidate와 state hash 및 비차단 warning shape를 assertion한다. changed-file 전체는 기존 금융 이력 및 마감과 read-only 보완 및 supporting tests/docs이며 외부 FX/가격/auth/성과 엔진이나 기존 데이터 재작성은 없다. 현재 고정 head의 실제 구현과 named test 인수 및 assertion을 계약에 대조했다. 구현자 evidence source d258cfdeb490637232e4a2860bade341dc86a2b5는 현재 head의 ancestor이며 전체 후속 diff는 evidence-manifest 한 파일뿐이다. 실행 입력은 동일하다. focused 68통과와 전체 286통과 및 4skip은 구현자 실행 근거이지 reviewer 독립 실행이나 CI 결과가 아니다. - 테스트 근거: tests/test_issue_12_review59_reports.py, tests/test_issue_12_regressions.py, scripts/ci_fixture_db.py - 판정 근거: 승인된 인수 의미와 실패 및 무변경 경계가 현재 source와 대응 test에 보존된다. 이전 verdict를 승계한 것이 아니라 현재 head의 source와 변경 영향을 대조한 판정이다. - `D01-requirement-structure` — `satisfied` - 계약: 신규 REQ-003을 배정 경로와 제목으로 작성하며 trusted harness README와 TEMPLATE의 JSON metadata, 연속 요구사항 및 AC, 필수 섹션, 판정 기준과 검증 및 검증 분류의 수준과 백엔드와 케이스 및 상태 불변조건을 충족한다. 초기 PR은 미정이며 PR 생성 후 실제 번호를 추적한다. - 구현 근거: docs/requirements/req-003_account-valuation-history.md; REQ-003의 JSON metadata docs/requirements/req-003_account-valuation-history.md:1-16, 연속 요구사항 :51-185 및 AC :187-297, 필수 오류와 계약과 호환성과 추적성 :299-317을 trusted harness README 및 TEMPLATE에 대조했다. Issue12와 실제 구현 PR13의 lifecycle traceability는 유효하다. 전체 문서와 이전 reviewed-head baseline은 byte-identical하다. 실제 tests/test_requirement_docs.py의 marker와 signature 및 named test 존재 assertion을 읽었다. - 테스트 근거: tests/test_requirement_docs.py - 판정 근거: 승인된 인수 의미와 실패 및 무변경 경계가 현재 source와 대응 test에 보존된다. 이전 verdict를 승계한 것이 아니라 현재 head의 source와 변경 영향을 대조한 판정이다. - `D02-requirement-semantics` — `satisfied` - 계약: 요구사항에는 평가 근거와 지표 정의, 선택과 future 제외, 정정 및 idempotency 충돌, 대사 완전성, current 및 import 연계, 마감 상태와 불변성과 승인, shared adapter 및 인증, migration과 legacy를 소스 및 테스트에 대응한다. 모든 승인된 경계와 회귀 사례를 인수 기준으로 내린다. - 구현 근거: docs/requirements/req-003_account-valuation-history.md; docs/requirements/req-003_account-valuation-history.md:53-185의 10개 요구사항과 :189-297의 전체 AC를 Discovery의 모든 포함 범위와 확정 결정 및 제외 범위에 대조했다. 이전 REQ-003 전체 AC와 byte-identical하여 의미 삭제나 승인 없는 축소가 없다. 참조된 tests와 actual implementation은 head에서 존재한다. 잔여 current-cache 구현 결함은 C05로 분리하며 문서 반복 부재나 evidence JSON 형식을 새로운 의무로 판단하지 않는다. - 테스트 근거: tests/test_account_valuations.py, tests/test_asset_snapshots.py, tests/test_issue_12_regressions.py, tests/test_requirement_docs.py, tests/test_mcp_http_runtime.py, tests/test_dashboard_authentication_app.py - 판정 근거: 승인된 인수 의미와 실패 및 무변경 경계가 현재 source와 대응 test에 보존된다. 이전 verdict를 승계한 것이 아니라 현재 head의 source와 변경 영향을 대조한 판정이다. - `D03-data-model` — `satisfied` - 계약: 신규 데이터 모델은 기존 entities 및 valuation과 마감의 관계, FK와 날짜 및 정확한 금액과 NULL 및 0과 선택 지표 및 대출 필수 정의, 계좌와 통화 및 목적과 기준일의 선택 및 index와 단일 유효 정정본, 고정 적용 분류 및 출처와 상태와 누락 및 이월 및 승인 버전, 분리된 정정과 schema11 이관 및 미상 날짜와 legacy 및 최신 캐시 동기화 책임을 정의한다. - 구현 근거: docs/data-model.md; docs/data-model.md:63-68은 account 필수와 currency 및 valuation purpose 선택 필터, basis-date exact 또는 upper-bound, verified leaf와 future 및 unverified 제외를 명시한다. account_date와 status_date 인덱스의 coverage 및 account-currency-purpose 전체를 덮지 않는 한계, idempotency 및 single_correction의 write integrity 책임을 구분한다. account_valuation_service.py:270-312의 실제 선택과 schema.py:264-267 및 migrations.py:169-172의 물리 정의에 대응한다. test_data_model_documents_valuation_selection_contract_and_index_mapping의 tests/test_valuation_contract_docs.py:46-62는 이 설명을 assertion한다. 나머지 entity 관계와 금액 NULL0 및 대출 정의, immutable run과 migration 및 legacy와 캐시 책임은 문서 :12-61 및 :70-176에 보존된다. - 테스트 근거: tests/test_account_valuations.py, tests/test_asset_snapshots.py, tests/test_issue_12_regressions.py, tests/test_valuation_contract_docs.py - 판정 근거: D03의 승인된 query 및 index 대응 문서 의무가 해소됐다. 새 복합 인덱스나 성능 의무를 요구하지 않는다. - `D04-interface-contract` — `satisfied` - 계약: 인터페이스 문서는 기존 auth 및 메뉴를 보존하고 평가 등록 및 조회 및 정정의 모든 입력과 유효본 및 원금 정의 출력, report 및 preview/close 및 월정산과 대사와 current API의 공통 선택, exact 기본과 실제 날짜 및 age 및 이월과 누락 및 미확인과 출처 및 버전과 승인 출력을 정의한다. 잘못된 입력과 scope 및 충돌과 부족 근거는 무변경 실패이며 기존 envelope와 required keys 및 의미 변경 정책을 명시한다. - 구현 근거: docs/interface-contract.md, docs/data-model.md; docs/interface-contract.md:1-261 기존 auth와 menu 보존; :263-358 valuation와 close 입력 및 오류와 무변경; :401-423 실제 signature와 persisted fields; :425-435 close 및 provenance aliases, preview fingerprint, equality replay와 recursive redaction을 승인 의무에 대조했다. 전체 문서는 이전 reviewed head와 동일하고 current source의 signature 및 enums와 대응한다. - 테스트 근거: tests/test_account_valuations.py, tests/test_issue_12_regressions.py, tests/test_contract_regression.py, tests/test_valuation_contract_docs.py, tests/test_issue_12_review59_account.py - 판정 근거: 승인된 인수 의미와 실패 및 무변경 경계가 현재 source와 대응 test에 보존된다. 이전 verdict를 승계한 것이 아니라 현재 head의 source와 변경 영향을 대조한 판정이다. - `D05-project-structure` — `satisfied` - 계약: 프로젝트 구조 문서는 기존 source와 test 및 evidence를 보존하고 SQLite schema와 migrations, application의 assets와 account writes 및 import와 reconciliation 및 monthly 책임, 공개 facade와 MCP 및 Streamlit과 기존 세 화면 및 tests를 exact 경로로 대응한다. adapter에서 선택 정책을 복제하지 않고 대출 정의와 verified as_of 및 conditional 승인 경계를 shared application에 배치한다. - 구현 근거: docs/project-structure.md; docs/project-structure.md:122-164의 source/test/docs 배치와 application 및 SQLite 및 adapter 의존, :166-212의 auth/menu inventory와 actual module ownership 및 monthly/reconciliation/read-only/privacy 경계를 모든 문서 의무와 current paths에 대조했다. 선택 정책을 adapter에 복제하지 않으며 별도 제품이나 마감 엔진이 없다. - 테스트 근거: tests/test_requirement_docs.py - 판정 근거: 승인된 인수 의미와 실패 및 무변경 경계가 현재 source와 대응 test에 보존된다. 이전 verdict를 승계한 것이 아니라 현재 head의 source와 변경 영향을 대조한 판정이다. - `D06-runtime-flow` — `satisfied` - 계약: 런타임 문서는 auth 및 메뉴를 보존하고 register/correct의 증빙 및 scope 검증과 append 및 유효본 확인 및 최신 캐시 동기화를 단일 트랜잭션으로 설명한다. 날짜 및 정책과 통화 및 대표 합산과 경고 read, preview 후 명시적 approval 및 원자적 freeze, reasoned reclose, 같은 근거의 monthly 및 대사, import와 이관 trigger 및 실패복구, retry와 concurrency 및 preview drift 재검증과 무부분쓰기, 비민감 valuation/run 상관 신호를 정의한다. - 구현 근거: docs/runtime-flow.md; docs/runtime-flow.md:147-185의 register/select/correct, preview/approval/atomic freeze, import와 monthly 및 reconciliation propagation; :187-210의 failure/retry/concurrency/비민감 signals; :221-241의 실제 transition와 DB boundary 및 fingerprint drift와 no-write 및 immutable replay를 승인 의무와 source에 대조했다. 별도 새 browser 조합이나 독립 실행 기록을 필수 계약으로 추가하지 않는다. - 테스트 근거: tests/test_account_valuations.py, tests/test_asset_snapshots.py, tests/test_issue_12_regressions.py - 판정 근거: 승인된 인수 의미와 실패 및 무변경 경계가 현재 source와 대응 test에 보존된다. 이전 verdict를 승계한 것이 아니라 현재 head의 source와 변경 영향을 대조한 판정이다. - `C16-supporting-evidence-scope` — `satisfied` - 계약: 모든 changed file은 승인된 기능과 필수 supporting change 또는 테스트 evidence로 설명되고 기존 requirement ID를 임의 갱신하거나 범위 밖 제품 및 설정을 변경하지 않는다. - 구현 근거: dashboard/app.py, dashboard/page_views/accounts.py, dashboard/page_views/assets.py, dashboard/page_views/monthly_settlement.py, docs/data-model.md, docs/interface-contract.md, docs/project-structure.md, docs/requirements/req-003_account-valuation-history.md, docs/runtime-flow.md, docs/verification/issue-12-review-60/contract-preservation-inventory.json, docs/verification/issue-12-review-60/evidence-manifest.json, docs/verification/issue-12-review-60/evidence-plan.json, docs/verification/issue-12-review-60/final-independent-review.json, docs/verification/issue-12-review-60/finding-matrix.json, docs/verification/issue-12-review-60/red-evidence.json, docs/verification/issue-12-review-61/contract-preservation-inventory.json, docs/verification/issue-12-review-61/evidence-manifest.json, docs/verification/issue-12-review-61/evidence-plan.json, docs/verification/issue-12-review-61/finding-matrix.json, docs/verification/issue-12-review-61/green-evidence.json, docs/verification/issue-12-review-61/red-evidence.json, docs/verification/issue-12-review-63/contract-preservation-inventory.json, docs/verification/issue-12-review-63/evidence-manifest.json, docs/verification/issue-12-review-63/evidence-plan.json, docs/verification/issue-12-review-63/finding-matrix.json, docs/verification/issue-12-review-63/red-evidence.json, docs/verification/issue-12-review-64/contract-preservation-inventory.json, docs/verification/issue-12-review-64/evidence-manifest.json, docs/verification/issue-12-review-64/evidence-plan.json, docs/verification/issue-12-review-64/finding-matrix.json, docs/verification/issue-12-review-64/red-evidence.json, jarca_ledger_mcp/adapters/mcp/server.py, jarca_ledger_mcp/adapters/mcp/tool_contracts.py, jarca_ledger_mcp/adapters/streamlit/accounts_gateway.py, jarca_ledger_mcp/adapters/streamlit/overview_gateway.py, jarca_ledger_mcp/application/__init__.py, jarca_ledger_mcp/application/account_valuation_service.py, jarca_ledger_mcp/application/accounts_write_services.py, jarca_ledger_mcp/application/assets_service.py, jarca_ledger_mcp/application/categorization_services.py, jarca_ledger_mcp/application/cross_transfer_service.py, jarca_ledger_mcp/application/imports_service.py, jarca_ledger_mcp/application/monthly_settlement_service.py, jarca_ledger_mcp/application/reconciliation_service.py, jarca_ledger_mcp/application/review_decision_service.py, jarca_ledger_mcp/application/shared.py, jarca_ledger_mcp/application/system_services.py, jarca_ledger_mcp/application/transaction_report_services.py, jarca_ledger_mcp/application/uncategorized_workbench_service.py, jarca_ledger_mcp/infrastructure/sqlite/__init__.py, jarca_ledger_mcp/infrastructure/sqlite/connection.py, jarca_ledger_mcp/infrastructure/sqlite/migrations.py, jarca_ledger_mcp/infrastructure/sqlite/schema.py, jarca_ledger_mcp/service.py, scripts/ci_fixture_db.py, tests/test_account_basis_public_consumers.py, tests/test_account_valuation_edge_contracts.py, tests/test_account_valuations.py, tests/test_asset_snapshot_idempotency.py, tests/test_asset_snapshots.py, tests/test_contract_regression.py, tests/test_dashboard_app.py, tests/test_dashboard_menu_transition.py, tests/test_import_current_balance_authority.py, tests/test_import_provenance_policy.py, tests/test_issue_12_regressions.py, tests/test_issue_12_review59_account.py, tests/test_issue_12_review59_readonly.py, tests/test_issue_12_review59_reports.py, tests/test_issue_12_review63_accounts.py, tests/test_issue_12_review63_assets.py, tests/test_ledger_categories.py, tests/test_requirement_docs.py, tests/test_review_decision_workbench.py, tests/test_seoulpay_xlsx.py, tests/test_service.py, tests/test_valuation_contract_docs.py; authoritative changed files 77개와 local base-to-head tree는 exact-match다. API diff 187개 hunk를 pinned blob 줄 위치와 내용에 대조했다. 이전 head 대비 source 변경은 account writer와 snapshot service 두 파일이며 승인된 권위 및 replay 경계 보완이다. data-model과 세 regression test 및 evidence JSON 다섯 파일은 승인된 문서 및 supporting evidence로 설명된다. manifest source의 모든 11개 blob OID와 SHA256 및 plan digest와 전체 source-to-head diff를 검증했다. 현재 고정 head의 실제 구현과 named test 인수 및 assertion을 계약에 대조했다. 구현자 evidence source d258cfdeb490637232e4a2860bade341dc86a2b5는 현재 head의 ancestor이며 전체 후속 diff는 evidence-manifest 한 파일뿐이다. 실행 입력은 동일하다. focused 68통과와 전체 286통과 및 4skip은 구현자 실행 근거이지 reviewer 독립 실행이나 CI 결과가 아니다. - 테스트 근거: tests/test_account_valuations.py, tests/test_asset_snapshots.py, tests/test_contract_regression.py, tests/test_dashboard_app.py, tests/test_dashboard_menu_transition.py, tests/test_import_provenance_policy.py, tests/test_issue_12_regressions.py, tests/test_issue_12_review59_account.py, tests/test_issue_12_review59_readonly.py, tests/test_issue_12_review59_reports.py, tests/test_ledger_categories.py, tests/test_requirement_docs.py, tests/test_review_decision_workbench.py, tests/test_seoulpay_xlsx.py, tests/test_service.py - 판정 근거: 승인된 인수 의미와 실패 및 무변경 경계가 현재 source와 대응 test에 보존된다. 이전 verdict를 승계한 것이 아니라 현재 head의 source와 변경 영향을 대조한 판정이다. ### 범위 판정 - 누락: C05 current-cache authority의 create 경로가 공백 또는 비정수 잔액과 기준일을 저장하며 실제 dated import를 막는 잔여 경계 및 그 최소 회귀 - 범위 초과: 없음 - 명세 모순: 없음 ### 결론 request_changes. F002 후보 metadata replay와 D03 문서 대응은 해소됐고 F005의 빈 문자열 dated update도 해소됐다. 다만 C05의 동일한 권위 의무에서 공백 또는 비정수 잔액과 기준일을 계좌 생성에 넣는 경로가 mutation 전에 거부되지 않아 잘못된 최신 캐시가 실제 잔액 import를 막는다. 기존 계약 범위의 생성 입력 검증과 무변경 및 후속 import 회귀를 보완해야 한다. 나머지 승인 계약 항목은 충족이다. 구현자의 focused 68통과와 전체 286통과 4skip은 source-to-head 실행 입력 동일성을 확인한 근거이고 reviewer 독립 제품 실행이나 CI 성공이 아니다. delegate의 snapshot 문서 test 실행 주장은 독립 제품 실행 근거로 사용하지 않았다. <!-- gitea-agent:implementation-spec-review/v1 owner=jsfamily repository=jarca-ledger-mcp issue=12 pr=13 head=fc2d2a6faeac3c64c0ed604f2aa1ad7c37c65570 contract-sha256=6d86b591b022fcc722611bfec6d24e54a64216ab6f7c4098f357e25420218818 result-sha256=d2a86a9f4b0977ad7b574c5e91490ef5d407553e371b5c6ddb7bbd85996a454a correlation=2b399e36eb375e3a2544d173972c1f6e6ed67ef119fd8e78e1dd4bd5b655d1d4 -->
gitea-impl-agent added 3 commits 2026-10-07 15:37:54 +00:00
Author
Owner

구현 재작업 결과

지적 처리

  • C05-current-import-create — resolved
    • 분류: valid_fix
    • 변경: jarca_ledger_mcp/application/accounts_write_services.py, tests/test_import_current_balance_authority.py
    • 검증: named RED→GREEN; focused 65 passed; full 288 passed, 4 skipped, 1 warning
    • 근거: whitespace/non-integer/bool/float dated balances are rejected before mutation while zero and later valid import authority remain valid
  • IR-001-strict-integer-create — resolved
    • 분류: valid_fix
    • 변경: jarca_ledger_mcp/application/accounts_write_services.py, tests/test_import_current_balance_authority.py
    • 검증: strict-type adversarial regression and exact-head independent gate PASS
    • 근거: boolean and floating-point coercion/truncation cannot persist a balance or mutate account/valuation state

최종 검증

  • Local checks: exact head 3bf9b77c6cc167a4e2a8706271bdf8e848d2c4fe; focused pytest exit 0 (65 passed); full pytest exit 0 (288 passed, 4 skipped, 1 warning); Ruff, compileall, diff-check, canonical manifest validation and independent gate PASS
  • Runtime/browser: 해당 없음·미검증; Review #65 계약은 application write invariant이며 browser 변경 없음
  • Commit status: 없음
  • Actions runs: 없음

다음 단계

Reviewer가 rework head를 새 snapshot으로 다시 검토해야 하며 이 comment는 기존 REQUEST_CHANGES를 해제하거나 승인을 의미하지 않는다.

## 구현 재작업 결과 - Source Issue: #12 - Pull Request: #13 - Source Review: #65 - Reviewed head: `fc2d2a6faeac3c64c0ed604f2aa1ad7c37c65570` - Rework head: `3bf9b77c6cc167a4e2a8706271bdf8e848d2c4fe` - Contract SHA-256: `6d86b591b022fcc722611bfec6d24e54a64216ab6f7c4098f357e25420218818` - Result: `rework_delivered` ### 지적 처리 - C05-current-import-create — `resolved` - 분류: valid_fix - 변경: jarca_ledger_mcp/application/accounts_write_services.py, tests/test_import_current_balance_authority.py - 검증: named RED→GREEN; focused 65 passed; full 288 passed, 4 skipped, 1 warning - 근거: whitespace/non-integer/bool/float dated balances are rejected before mutation while zero and later valid import authority remain valid - IR-001-strict-integer-create — `resolved` - 분류: valid_fix - 변경: jarca_ledger_mcp/application/accounts_write_services.py, tests/test_import_current_balance_authority.py - 검증: strict-type adversarial regression and exact-head independent gate PASS - 근거: boolean and floating-point coercion/truncation cannot persist a balance or mutate account/valuation state ### 최종 검증 - Local checks: exact head 3bf9b77c6cc167a4e2a8706271bdf8e848d2c4fe; focused pytest exit 0 (65 passed); full pytest exit 0 (288 passed, 4 skipped, 1 warning); Ruff, compileall, diff-check, canonical manifest validation and independent gate PASS - Runtime/browser: 해당 없음·미검증; Review #65 계약은 application write invariant이며 browser 변경 없음 - Commit status: 없음 - Actions runs: 없음 ### 다음 단계 Reviewer가 rework head를 새 snapshot으로 다시 검토해야 하며 이 comment는 기존 `REQUEST_CHANGES`를 해제하거나 승인을 의미하지 않는다. <!-- gitea-agent:implementation-rework/v1 owner=jsfamily repository=jarca-ledger-mcp issue=12 pr=13 review=65 reviewed-head=fc2d2a6faeac3c64c0ed604f2aa1ad7c37c65570 head=3bf9b77c6cc167a4e2a8706271bdf8e848d2c4fe contract-sha256=6d86b591b022fcc722611bfec6d24e54a64216ab6f7c4098f357e25420218818 result-sha256=f286028540e678c3e053591549d68b059828059a96ed2b268b8477d9720ad9ac correlation=44a9e23638b213fb7c33bc7d0ea2ef650c49d00267ee1ab89ab5d91d9f35320b -->
gitea-spec-agent requested changes 2026-10-07 21:28:45 +00:00
Dismissed
gitea-spec-agent left a comment
Owner

구현 명세 적합성 검토

Acceptance criteria 판정

  • C01-history — satisfied

    • 계약: 평가 계좌 FK, 기준일과 등록일, 대표 금액과 통화와 목적, 출처와 확인 상태, 증빙 식별자, 정정 연결과 사유 및 선택 시간 자료를 이력으로 보존한다.
    • 구현 근거: jarca_ledger_mcp/application/account_valuation_service.py, jarca_ledger_mcp/infrastructure/sqlite/schema.py, jarca_ledger_mcp/infrastructure/sqlite/migrations.py; account_valuation_service.py:133-257 register_account_valuation 및 :261-266 list_account_valuations; schema.py:229-267 및 migrations.py:157-173의 실제 필드와 FK와 unique 정의를 대조했다. tests/test_account_valuations.py:13-21의 schema12/idempotent 및 :24-32의 동일 기록 reuse와 payload conflict assertions를 확인했다. 구현자 evidence source f49568273e74b89dc3e83da21ce2ae12ed110543에서 현재 head까지 전체 변경은 evidence-manifest 한 파일이며 실행 입력은 동일하다. focused 65통과와 전체 288통과 및 4skip은 구현자 실행 근거이고 reviewer 독립 실행 또는 CI 결과가 아니다.
    • 테스트 근거: tests/test_account_valuations.py
    • 판정 근거: 현재 고정 source와 test assertion 및 변경 영향으로 승인 계약을 판정했다. 문서 또는 이전 verdict만으로 구현 충족을 추정하지 않는다.
  • C02-money-metrics — satisfied

    • 계약: 금액 정밀도와 NULL 및 0을 보존하고 취득원가, 순납입액, 기관 표시 원금 금액과 정의 및 원문 명칭, 손익과 수익률의 계산 기준을 구분한다. 투자 대표 총평가액과 포함 현금 및 원금을 중복 합산하지 않는다.
    • 구현 근거: jarca_ledger_mcp/application/account_valuation_service.py, jarca_ledger_mcp/infrastructure/sqlite/schema.py, docs/data-model.md, docs/requirements/req-003_account-valuation-history.md; account_valuation_service.py:33-56의 strict integer/finite 검증, :165-186의 선택 지표와 NULL 보존, :247-249의 실제 roundtrip columns; schema.py:229-267의 INTEGER 및 선택 NULL 필드와 assets_service.py:453-499의 대표 금액 합산을 대조했다. test_valuation_round_trip_preserves_null_zero_and_physical_amount_mapping 및 test_correction_preserves_optional_fields_unless_overridden의 입력과 actual assertions를 확인했다. 구현자 evidence source f49568273e74b89dc3e83da21ce2ae12ed110543에서 현재 head까지 전체 변경은 evidence-manifest 한 파일이며 실행 입력은 동일하다. focused 65통과와 전체 288통과 및 4skip은 구현자 실행 근거이고 reviewer 독립 실행 또는 CI 결과가 아니다.
    • 테스트 근거: tests/test_issue_12_review59_account.py, tests/test_issue_12_regressions.py
    • 판정 근거: 현재 고정 source와 test assertion 및 변경 영향으로 승인 계약을 판정했다. 문서 또는 이전 verdict만으로 구현 충족을 추정하지 않는다.
  • N01-loan-balance-definition — satisfied

    • 계약: 대출 평가 기록마다 대표 부채가 원금만인지 원금과 이자 및 수수료인지 필수로 명시하고 기본값으로 추정하지 않는다. 목적 alias가 필수 정의 계약을 우회하지 않는다.
    • 구현 근거: jarca_ledger_mcp/application/account_valuation_service.py, docs/requirements/req-003_account-valuation-history.md, jarca_ledger_mcp/application/accounts_write_services.py, jarca_ledger_mcp/application/imports_service.py, docs/data-model.md; account_valuation_service.py:93-105의 loan candidate 무추정 거부 및 :194-203의 loan alias와 종류 및 필수 정의 검증; accounts_write_services.py:74-82의 non-loan 전환 guard; imports_service.py:37-41의 candidate 호출을 대조했다. tests/test_account_valuation_edge_contracts.py:8-38, :41-76, :133-191은 계좌 유형 전환과 정의 누락 및 candidate/import 경로의 validation_error와 history/account 불변을 assertion한다. 구현자 evidence source f49568273e74b89dc3e83da21ce2ae12ed110543에서 현재 head까지 전체 변경은 evidence-manifest 한 파일이며 실행 입력은 동일하다. focused 65통과와 전체 288통과 및 4skip은 구현자 실행 근거이고 reviewer 독립 실행 또는 CI 결과가 아니다.
    • 테스트 근거: tests/test_issue_12_regressions.py, tests/test_issue_12_review59_account.py, tests/test_account_valuation_edge_contracts.py
    • 판정 근거: 현재 고정 source와 test assertion 및 변경 영향으로 승인 계약을 판정했다. 문서 또는 이전 verdict만으로 구현 충족을 추정하지 않는다.
  • C03-selection — satisfied

    • 계약: 계좌와 통화 및 평가 목적별 유효 자료를 선택한다. exact는 당일 확인 자료만, as_of는 기준일 이하 최신 확인 자료만 사용한다. 미래 자료는 제외하고 미확인 후보는 확인 자료를 대체하거나 합산하지 않는다. 실제 기준일과 경과 일수 및 이월 상태를 반환한다.
    • 구현 근거: jarca_ledger_mcp/application/account_valuation_service.py, jarca_ledger_mcp/application/assets_service.py; account_valuation_service.py:270-312 select_account_valuation의 scope와 verified leaf, exact 및 latest-prior, candidate warning 및 age; assets_service.py:115-215와 :218-259의 계좌 및 기존 수기 selection과 미래/미확인/통화 제외를 대조했다. tests/test_account_valuations.py:35-45는 future와 unverified 제외 및 as-of carry와 actual date를 assertion한다. tests/test_issue_12_regressions.py의 scope 및 purpose와 unverified 합계 제외 regression을 함께 읽었다. 구현자 evidence source f49568273e74b89dc3e83da21ce2ae12ed110543에서 현재 head까지 전체 변경은 evidence-manifest 한 파일이며 실행 입력은 동일하다. focused 65통과와 전체 288통과 및 4skip은 구현자 실행 근거이고 reviewer 독립 실행 또는 CI 결과가 아니다.
    • 테스트 근거: tests/test_account_valuations.py, tests/test_issue_12_regressions.py
    • 판정 근거: 현재 고정 source와 test assertion 및 변경 영향으로 승인 계약을 판정했다. 문서 또는 이전 verdict만으로 구현 충족을 추정하지 않는다.
  • C04-correction-validation — satisfied

    • 계약: 평가 정정은 append-only로 대상과 사유를 연결하며 다른 계좌, 통화, 목적을 참조하는 정정과 순환 및 동일 유효본의 동시 분기를 차단한다.
    • 구현 근거: jarca_ledger_mcp/application/account_valuation_service.py, jarca_ledger_mcp/infrastructure/sqlite/schema.py; account_valuation_service.py:204-224는 parent scope와 cyclic ancestry를 검증하고 :245-253은 단일 child unique 충돌을 fail-closed 처리한다. :315-375의 effective payload replay 및 changed conflict와 append-only 경계를 확인했다. tests/test_account_valuations.py:48-59는 원본 보존과 단일 correction count를 assertion하고 tests/test_account_valuation_edge_contracts.py:79-130은 동일 effective correction reuse 및 다른 payload conflict를 확인한다. 구현자 evidence source f49568273e74b89dc3e83da21ce2ae12ed110543에서 현재 head까지 전체 변경은 evidence-manifest 한 파일이며 실행 입력은 동일하다. focused 65통과와 전체 288통과 및 4skip은 구현자 실행 근거이고 reviewer 독립 실행 또는 CI 결과가 아니다.
    • 테스트 근거: tests/test_issue_12_review59_account.py, tests/test_account_valuations.py, tests/test_issue_12_regressions.py
    • 판정 근거: 현재 고정 source와 test assertion 및 변경 영향으로 승인 계약을 판정했다. 문서 또는 이전 verdict만으로 구현 충족을 추정하지 않는다.
  • C05-current-import — unsatisfied

    • 계약: 뒤늦은 과거 자료 등록으로 최신 표시값을 과거로 되돌리지 않는다. 기존 계좌 수정과 import의 최신 캐시 및 새 이력 권위를 연결하며 동기화 시각을 실제 평가일로 오인하지 않는다.
    • 구현 근거: jarca_ledger_mcp/application/imports_service.py, jarca_ledger_mcp/application/assets_service.py, jarca_ledger_mcp/application/accounts_write_services.py; Review65 create 지적은 accounts_write_services.py:28-40의 INSERT 전 strict integer 검증으로 해소됐다. tests/test_import_current_balance_authority.py:104-121의 test_create_rejects_whitespace_or_non_integer_dated_balance_without_mutation은 공백과 비정수 및 boolean과 float 입력 거부와 계좌 목록 및 valuation 불변을 assertion한다. :124-150의 test_zero_dated_balance_and_valid_import_recovery는 실제 0 및 유효 후속 dated import를 확인한다. 잔여 update 경로는 accounts_write_services.py:49-71과 :90-99다. :67의 int(v)는 True와 False 및 1.2와 -1.2를 각각 1과 0 및 1과 -1로 바꾸고 dated 후보도 :12 및 :99에서 같은 손실을 저장한다. last_balance 빈 문자열 단독 입력은 basis_update가 없으면 :51 guard를 통과하고 :67 변환도 건너뛰어 :95에서 저장된다. 이는 exact integer 또는 NULL 모델이 아니다. assets_service.py:149 및 :210-214를 호출하는 get_asset_liquidity_report의 :1105-1114와 reconciliation_service.py:98 및 :159-166은 이 빈 문자열을 int 변환하여 ValueError가 난다. shared.py:128-138은 sqlite3 오류만 envelope로 처리한다. 승인 계약은 Discovery 정확한 금액 및 현재값 쓰기 권위 연결과 docs/data-model.md:26-28 및 :132-136, req-003:89-111, interface-contract.md:344다. 기존 tests/test_import_current_balance_authority.py:68-101은 날짜를 함께 보낸 빈 문자열 update만 검사한다. dated float 및 boolean update와 날짜 없는 빈 문자열 update의 무변경 실패 assertion은 없다. 구현자 evidence source f49568273e74b89dc3e83da21ce2ae12ed110543에서 현재 head까지 전체 변경은 evidence-manifest 한 파일이며 실행 입력은 동일하다. focused 65통과와 전체 288통과 및 4skip은 구현자 실행 근거이고 reviewer 독립 실행 또는 CI 결과가 아니다.
    • 테스트 근거: tests/test_issue_12_review59_account.py, tests/test_import_provenance_policy.py, tests/test_import_current_balance_authority.py, tests/test_account_basis_public_consumers.py, tests/test_issue_12_review63_accounts.py
    • 판정 근거: 생성 수정은 충족하지만 계좌 수정의 금액 의미 손실 및 invalid empty-string cache 저장이 C05 승인 계약에 남는다. 유효하지 않은 금액은 저장과 후보 생성 전 validation_error로 무변경 거부하고, 0과 유효 signed integer 입력, 정상 dated update 및 과거 candidate와 최신 캐시 보존을 유지해야 한다. 최소 회귀는 bool 및 float의 dated update와 빈 문자열 단독 update가 계좌와 이력을 바꾸지 않는지 확인하는 것이다. 이 경로는 직전 head와 동일하므로 신규 회귀가 아니라 기존 잔여 결함이다. 새 요구사항이나 특정 validator 구현을 강제하는 요청이 아니다.
  • C06-idempotency — satisfied

    • 계약: 동일 증빙 또는 idempotency 재입력은 동일 기록을 재사용하며 같은 키의 다른 payload는 충돌이다. 동시 정정의 분기를 차단하고 UNIQUE 계좌 및 기준일 하나로 정정 추가를 막지 않는다.
    • 구현 근거: jarca_ledger_mcp/application/account_valuation_service.py, jarca_ledger_mcp/infrastructure/sqlite/schema.py, jarca_ledger_mcp/infrastructure/sqlite/migrations.py, jarca_ledger_mcp/application/accounts_write_services.py, jarca_ledger_mcp/application/imports_service.py; account_valuation_service.py:107-125의 candidate key payload, :225-244의 key와 source_ref 정본 및 unrelated scope conflict, :315-375의 explicit 및 keyless effective correction reuse; schema.py:264-267의 account-scoped key와 single-child index를 대조했다. tests/test_account_valuations.py:24-32 및 :72-80과 tests/test_account_valuation_edge_contracts.py:79-130, :194-231은 동일/변경 payload 및 correction와 candidate validation의 actual assertions를 제공한다. 구현자 evidence source f49568273e74b89dc3e83da21ce2ae12ed110543에서 현재 head까지 전체 변경은 evidence-manifest 한 파일이며 실행 입력은 동일하다. focused 65통과와 전체 288통과 및 4skip은 구현자 실행 근거이고 reviewer 독립 실행 또는 CI 결과가 아니다.
    • 테스트 근거: tests/test_issue_12_review59_account.py, tests/test_account_valuations.py, tests/test_issue_12_regressions.py, tests/test_account_valuation_edge_contracts.py
    • 판정 근거: 현재 고정 source와 test assertion 및 변경 영향으로 승인 계약을 판정했다. 문서 또는 이전 verdict만으로 구현 충족을 추정하지 않는다.
  • C07-close-immutability — satisfied

    • 계약: 기존 asset_snapshots와 correction run을 보존하고 평가 정정 및 거래 추가로 기존 마감을 자동 변경하지 않는다. 동일 기준일 재마감은 사유와 이전 run 연결을 가진 새 버전을 원자적으로 추가한다.
    • 구현 근거: jarca_ledger_mcp/application/assets_service.py, jarca_ledger_mcp/infrastructure/sqlite/schema.py, jarca_ledger_mcp/infrastructure/sqlite/migrations.py; assets_service.py:717-752는 correction chain과 최신 correction authority를 검사하고 :757은 원래 existing run을 읽는다. unrelated live drift는 :800에서 idempotency_conflict다. tests/test_issue_12_review63_assets.py:97-138은 두 correction 이후 original equality와 unrelated asset drift conflict를 확인한다. 추가 evidence-array 검증은 :262-269 및 :297-320과 report/replay/timeseries의 오류 경계에 제한적으로 배치돼 정상 run 불변성을 변경하지 않는다. 구현자 evidence source f49568273e74b89dc3e83da21ce2ae12ed110543에서 현재 head까지 전체 변경은 evidence-manifest 한 파일이며 실행 입력은 동일하다. focused 65통과와 전체 288통과 및 4skip은 구현자 실행 근거이고 reviewer 독립 실행 또는 CI 결과가 아니다.
    • 테스트 근거: tests/test_asset_snapshots.py, tests/test_issue_12_regressions.py, tests/test_issue_12_review63_assets.py
    • 판정 근거: 현재 고정 source와 test assertion 및 변경 영향으로 승인 계약을 판정했다. 문서 또는 이전 verdict만으로 구현 충족을 추정하지 않는다.
  • N02-close-replay-run-binding — satisfied

    • 계약: 마감 버전의 근거는 불변이며 동일 idempotency 요청은 원래 기록을 재사용한다. 재마감으로 과거 run 응답 및 evidence를 변경하지 않는다.
    • 구현 근거: jarca_ledger_mcp/application/assets_service.py, docs/interface-contract.md; F002 해소. assets_service.py:842-860은 included unverified_candidates와 excluded candidate의 blocking 및 state_hash를 저장한다. :383-398은 blocking=False를 복원하고 :757-799는 exact existing run에서 원래 응답을 구성한다. tests/test_asset_snapshot_idempotency.py:9-64의 test_replay_preserves_redacted_unverified_candidates_after_correction은 후보 allowlist와 blocking=False 및 전체 replay==first와 row/run count 불변을 assertion한다. :67-96의 test_replay_preserves_blocking_candidate_warning_shape은 차단 warning의 blocking 키 부재와 최초 응답 equality를 확인한다. 기존 mixed-asof 및 correction-chain equality 테스트도 보존된다. 구현자 evidence source f49568273e74b89dc3e83da21ce2ae12ed110543에서 현재 head까지 전체 변경은 evidence-manifest 한 파일이며 실행 입력은 동일하다. focused 65통과와 전체 288통과 및 4skip은 구현자 실행 근거이고 reviewer 독립 실행 또는 CI 결과가 아니다.
    • 테스트 근거: tests/test_issue_12_review59_reports.py, tests/test_issue_12_regressions.py, tests/test_asset_snapshot_idempotency.py, tests/test_issue_12_review63_assets.py
    • 판정 근거: 현재 고정 source와 test assertion 및 변경 영향으로 승인 계약을 판정했다. 문서 또는 이전 verdict만으로 구현 충족을 추정하지 않는다.
  • C08-approved-conditional — satisfied

    • 계약: 완전한 exact 마감, 미완료 초안, 별도 승인된 조건부 마감을 구분한다. 승인 전 누락 및 이월은 미완료 초안이고 승인 후에도 누락 제외 및 확인된 과거값 이월만 허용한다. 미확인, 미래, 기준일 미상 금액은 승인으로도 합산하지 않으며 적용과 제외와 이월 및 승인자와 시각과 사유와 근거를 고정한다.
    • 구현 근거: jarca_ledger_mcp/application/assets_service.py, jarca_ledger_mcp/infrastructure/sqlite/schema.py, dashboard/page_views/assets.py; assets_service.py:646-671 및 :684-709은 public redaction 이전 동일 preview fingerprint와 승인 경계를 확인한다. 기존 test_f001_preview_fingerprint_uses_same_unredacted_authority_and_rejects_drift의 :17-41은 unchanged handoff 성공과 drift 거부 및 run 불변을 assertion한다. 미확인 candidate는 합산하지 않으며 nonblocking 후보는 conditional 승인 대상으로 오인하지 않는다. 승인자와 시각 및 사유와 참조, 적용과 제외와 이월은 :842-864에 원자적으로 저장한다. 구현자 evidence source f49568273e74b89dc3e83da21ce2ae12ed110543에서 현재 head까지 전체 변경은 evidence-manifest 한 파일이며 실행 입력은 동일하다. focused 65통과와 전체 288통과 및 4skip은 구현자 실행 근거이고 reviewer 독립 실행 또는 CI 결과가 아니다.
    • 테스트 근거: tests/test_issue_12_review59_reports.py, tests/test_issue_12_regressions.py, tests/test_asset_snapshots.py, tests/test_issue_12_review63_assets.py
    • 판정 근거: 현재 고정 source와 test assertion 및 변경 영향으로 승인 계약을 판정했다. 문서 또는 이전 verdict만으로 구현 충족을 추정하지 않는다.
  • C09-reconciliation — satisfied

    • 계약: 외부 확인값과 장부 계산값을 분리하고 검증된 시작잔고, 기준시점, 거래 포함 범위와 계산 완전성을 표시한다. 거래 없는 수동 투자 계좌의 대사 불가 및 거래 미수입과 평가 수동 관리 상태를 구분하고 가짜 거래를 만들지 않는다. 대사도 공통 평가 근거와 대출 대표 정의를 사용한다.
    • 구현 근거: jarca_ledger_mcp/application/reconciliation_service.py, jarca_ledger_mcp/application/account_valuation_service.py, jarca_ledger_mcp/application/monthly_settlement_service.py; reconciliation_service.py:31-64 _account_balance_row는 시작 근거 및 거래 coverage를 분리하고 :102-158은 verified corrected leaf와 목적 및 대출 정의를 선택한다. :159-213은 계산 불완전 및 수동 투자 평가 관리와 대사 불가 상태를 provenance로 전달한다. monthly_settlement_service.py의 get_monthly_settlement_summary는 공통 report를 읽으며 tests/test_issue_12_review59_reports.py 및 tests/test_issue_12_regressions.py의 no-fake-transaction와 corrected-investment 및 unavailable assertions에 대응한다. 구현자 evidence source f49568273e74b89dc3e83da21ce2ae12ed110543에서 현재 head까지 전체 변경은 evidence-manifest 한 파일이며 실행 입력은 동일하다. focused 65통과와 전체 288통과 및 4skip은 구현자 실행 근거이고 reviewer 독립 실행 또는 CI 결과가 아니다.
    • 테스트 근거: tests/test_issue_12_review59_reports.py, tests/test_issue_12_regressions.py, tests/test_service.py
    • 판정 근거: 현재 고정 source와 test assertion 및 변경 영향으로 승인 계약을 판정했다. 문서 또는 이전 verdict만으로 구현 충족을 추정하지 않는다.
  • C10-report-monthly-evidence — satisfied

    • 계약: MCP와 Dashboard 및 월정산 보고에서 같은 기준일과 선택 근거 및 실제 평가일, 경과 일수, 확인 상태, 누락과 미확인 및 이월 경고, 마감 버전 및 조건부 승인 근거를 일관되게 전달한다.
    • 구현 근거: jarca_ledger_mcp/application/assets_service.py, jarca_ledger_mcp/application/monthly_settlement_service.py, dashboard/page_views/monthly_settlement.py, dashboard/page_views/accounts.py; assets_service.py:335-380은 frozen valuation_id와 currency 및 실제 basis를 복원한다. :948-984는 frozen run을 정본으로 보고하고 :1049-1102는 zero-row run 날짜를 UNION으로 포함해 latest run의 승인 및 provenance를 전달한다. tests/test_issue_12_review63_assets.py:141-206은 zero-row 정정 run 및 alias, frozen ID와 currency 및 legacy ID 비추론을 assertion한다. monthly_settlement_service.py는 해당 공통 report를 읽는다. malformed JSON 배열 guard의 신규 test는 tests/test_asset_snapshot_idempotency.py:99-128이며 report/replay/timeseries 실패 및 row/run 불변을 확인한다. 임의 DB 손상 전체의 복구나 추가 오류명은 새 인수 조건으로 만들지 않는다. 구현자 evidence source f49568273e74b89dc3e83da21ce2ae12ed110543에서 현재 head까지 전체 변경은 evidence-manifest 한 파일이며 실행 입력은 동일하다. focused 65통과와 전체 288통과 및 4skip은 구현자 실행 근거이고 reviewer 독립 실행 또는 CI 결과가 아니다.
    • 테스트 근거: tests/test_issue_12_review59_reports.py, tests/test_issue_12_regressions.py, tests/test_service.py, tests/test_issue_12_review63_assets.py
    • 판정 근거: 현재 고정 source와 test assertion 및 변경 영향으로 승인 계약을 판정했다. 문서 또는 이전 verdict만으로 구현 충족을 추정하지 않는다.
  • C11-adapter-structure — satisfied

    • 계약: MCP와 Streamlit gateway는 공통 application을 사용하고 기존 공개 호출명과 기존 인수 및 success와 실패 error_code 및 error envelope를 가능한 한 유지한다. 새 Dashboard 인증 또는 MCP 인증을 도입하지 않는다.
    • 구현 근거: jarca_ledger_mcp/adapters/mcp/server.py, jarca_ledger_mcp/adapters/mcp/tool_contracts.py, jarca_ledger_mcp/adapters/streamlit/accounts_gateway.py, jarca_ledger_mcp/application/__init__.py, jarca_ledger_mcp/service.py, dashboard/page_views/accounts.py, dashboard/page_views/assets.py, dashboard/page_views/monthly_settlement.py; service.py:50-70의 호환 facade와 application/asset_account_services.py:3-15의 공통 export, adapters/mcp/server.py의 create/register/select/correct/preview/close tools와 adapters/streamlit/accounts_gateway.py 및 overview_gateway.py의 shared-service delegate를 대조했다. dashboard/page_views/accounts.py 및 assets.py와 monthly_settlement.py는 shared gateway 결과를 렌더링하고 명시적 submit에서만 writer를 호출한다. tests/test_contract_regression.py와 tests/test_issue_12_regressions.py의 공개 signature/envelope 및 read-only assertions는 보존된다. 구현자 evidence source f49568273e74b89dc3e83da21ce2ae12ed110543에서 현재 head까지 전체 변경은 evidence-manifest 한 파일이며 실행 입력은 동일하다. focused 65통과와 전체 288통과 및 4skip은 구현자 실행 근거이고 reviewer 독립 실행 또는 CI 결과가 아니다.
    • 테스트 근거: tests/test_contract_regression.py, tests/test_issue_12_regressions.py
    • 판정 근거: 현재 고정 source와 test assertion 및 변경 영향으로 승인 계약을 판정했다. 문서 또는 이전 verdict만으로 구현 충족을 추정하지 않는다.
  • C12-migration-legacy — satisfied

    • 계약: schema 11의 기존 데이터와 마감 및 개인정보를 보존하고 additive하고 idempotent한 migration을 제공한다. 기준일 증거 없는 값을 임의 월말로 소급하거나 legacy snapshot에 valuation_id를 추측하여 생성하지 않는다.
    • 구현 근거: jarca_ledger_mcp/infrastructure/sqlite/schema.py, jarca_ledger_mcp/infrastructure/sqlite/migrations.py, jarca_ledger_mcp/application/assets_service.py; migrations.py:19-173의 additive CREATE/ADD COLUMN과 unique 및 schema12 상태; assets_service.py:335-380의 frozen evidence와 legacy valuation_id 비추론을 대조했다. test_account_valuation_schema_is_v12_and_idempotent 및 test_schema12_migration_preserves_legacy_rows_indexes_and_is_idempotent는 기존 rows와 재호출 idempotency를 검사하고 tests/test_issue_12_review63_assets.py:199-206은 legacy ID가 생성되지 않음을 assertion한다. 구현자 evidence source f49568273e74b89dc3e83da21ce2ae12ed110543에서 현재 head까지 전체 변경은 evidence-manifest 한 파일이며 실행 입력은 동일하다. focused 65통과와 전체 288통과 및 4skip은 구현자 실행 근거이고 reviewer 독립 실행 또는 CI 결과가 아니다.
    • 테스트 근거: tests/test_account_valuations.py, tests/test_issue_12_regressions.py, tests/test_ledger_categories.py, tests/test_review_decision_workbench.py
    • 판정 근거: 현재 고정 source와 test assertion 및 변경 영향으로 승인 계약을 판정했다. 문서 또는 이전 verdict만으로 구현 충족을 추정하지 않는다.
  • C13-read-only — satisfied

    • 계약: preview와 조회 및 Dashboard 렌더링은 금융 쓰기를 실행하지 않는다. 명시적 등록, 정정, 승인 close 및 import 제출만 변경을 수행하고 실패 시 부분 쓰기를 남기지 않는다.
    • 구현 근거: jarca_ledger_mcp/infrastructure/sqlite/connection.py, jarca_ledger_mcp/application/shared.py, jarca_ledger_mcp/application/system_services.py, jarca_ledger_mcp/application/account_valuation_service.py, jarca_ledger_mcp/application/assets_service.py; connection.py:31-53 connect_readonly/read_db의 mode=ro와 no-init, shared.py:128-138의 read 오류 envelope; assets_service.py:646-671의 preview와 :939-1138의 report/time-series/liquidity read, account_valuation_service.py:260-312의 read selector를 대조했다. tests/test_issue_12_review59_readonly.py는 missing DB no-path-create와 initialized DB schema/rows 불변을 검사하고 explicit writer는 connection.py:56-69에서만 init와 commit을 수행한다. 구현자 evidence source f49568273e74b89dc3e83da21ce2ae12ed110543에서 현재 head까지 전체 변경은 evidence-manifest 한 파일이며 실행 입력은 동일하다. focused 65통과와 전체 288통과 및 4skip은 구현자 실행 근거이고 reviewer 독립 실행 또는 CI 결과가 아니다.
    • 테스트 근거: tests/test_issue_12_review59_readonly.py, tests/test_dashboard_app.py, tests/test_dashboard_menu_transition.py
    • 판정 근거: 현재 고정 source와 test assertion 및 변경 영향으로 승인 계약을 판정했다. 문서 또는 이전 verdict만으로 구현 충족을 추정하지 않는다.
  • C14-auth-menu-preservation — satisfied

    • 계약: Dashboard 인증은 DB보다 먼저이며 REQ-001의 cookie와 logout 및 REQ-002의 메뉴 label과 order, shell, query, error와 retry 및 명시적 금융 쓰기 계약을 유지한다.
    • 구현 근거: dashboard/app.py, dashboard/page_views/accounts.py, dashboard/page_views/assets.py, dashboard/page_views/monthly_settlement.py, docs/interface-contract.md, docs/project-structure.md, docs/runtime-flow.md; dashboard/app.py:37-72의 auth-before-financial-dispatch와 gateway read boundary, 기존 dashboard authentication/menu 관련 source 및 tests는 직전 head와 byte-identical하다. docs/interface-contract.md:1-261 및 docs/project-structure.md와 docs/runtime-flow.md의 기존 auth/cookie/logout와 canonical menu order 및 shell/query 내용이 보존된다. tests/test_dashboard_menu_transition.py 및 tests/test_dashboard_app.py의 actual authentication/menu/no-write assertions와 전체 구현자 regression 보고를 대응했다. 구현자 evidence source f49568273e74b89dc3e83da21ce2ae12ed110543에서 현재 head까지 전체 변경은 evidence-manifest 한 파일이며 실행 입력은 동일하다. focused 65통과와 전체 288통과 및 4skip은 구현자 실행 근거이고 reviewer 독립 실행 또는 CI 결과가 아니다.
    • 테스트 근거: tests/test_dashboard_menu_transition.py, tests/test_dashboard_app.py
    • 판정 근거: 현재 고정 source와 test assertion 및 변경 영향으로 승인 계약을 판정했다. 문서 또는 이전 verdict만으로 구현 충족을 추정하지 않는다.
  • C15-exclusions-privacy — satisfied

    • 계약: 증권사 자동 연동, 정확한 성과 또는 환율 엔진, 새 인증, 별도 월정산 제품, 거래 추론 및 기존 데이터 자동 재작성과 수기 비계좌 자산 전체 이력 재설계를 추가하지 않는다. 실제 계좌 및 금융 증빙과 credential을 로그와 문서 및 테스트에 기록하지 않는다.
    • 구현 근거: jarca_ledger_mcp/application/assets_service.py, jarca_ledger_mcp/application/account_valuation_service.py, jarca_ledger_mcp/application/imports_service.py, jarca_ledger_mcp/application/reconciliation_service.py, jarca_ledger_mcp/infrastructure/sqlite/schema.py, jarca_ledger_mcp/infrastructure/sqlite/migrations.py; assets_service.py:62-75 _public_evidence 및 :94-112의 민감 source state는 digest로만 공개하고 :383-408의 closed metadata는 strict allowlist를 사용한다. account_valuation_service.py:29-30의 public candidate는 ID/date/currency/purpose/status만 반환한다. tests/test_asset_snapshot_idempotency.py:26-42는 redacted candidate와 state hash 및 비차단 warning shape를 assertion한다. changed-file 전체는 기존 금융 이력 및 마감과 read-only 보완 및 supporting tests/docs이며 외부 FX/가격/auth/성과 엔진이나 기존 데이터 재작성은 없다. 구현자 evidence source f49568273e74b89dc3e83da21ce2ae12ed110543에서 현재 head까지 전체 변경은 evidence-manifest 한 파일이며 실행 입력은 동일하다. focused 65통과와 전체 288통과 및 4skip은 구현자 실행 근거이고 reviewer 독립 실행 또는 CI 결과가 아니다.
    • 테스트 근거: tests/test_issue_12_review59_reports.py, tests/test_issue_12_regressions.py, scripts/ci_fixture_db.py
    • 판정 근거: 현재 고정 source와 test assertion 및 변경 영향으로 승인 계약을 판정했다. 문서 또는 이전 verdict만으로 구현 충족을 추정하지 않는다.
  • D01-requirement-structure — satisfied

    • 계약: 신규 REQ-003을 배정 경로와 제목으로 작성하며 trusted harness README와 TEMPLATE의 JSON metadata, 연속 요구사항 및 AC, 필수 섹션, 판정 기준과 검증 및 검증 분류의 수준과 백엔드와 케이스 및 상태 불변조건을 충족한다. 초기 PR은 미정이며 PR 생성 후 실제 번호를 추적한다.
    • 구현 근거: docs/requirements/req-003_account-valuation-history.md; REQ-003의 JSON metadata docs/requirements/req-003_account-valuation-history.md:1-16, 연속 요구사항 :51-185 및 AC :187-297, 필수 오류와 계약과 호환성과 추적성 :299-317을 trusted harness README 및 TEMPLATE에 대조했다. Issue12와 실제 구현 PR13의 lifecycle traceability는 유효하다. 전체 문서와 이전 reviewed-head baseline은 byte-identical하다. 실제 tests/test_requirement_docs.py의 marker와 signature 및 named test 존재 assertion을 읽었다.
    • 테스트 근거: tests/test_requirement_docs.py
    • 판정 근거: 현재 고정 source와 test assertion 및 변경 영향으로 승인 계약을 판정했다. 문서 또는 이전 verdict만으로 구현 충족을 추정하지 않는다.
  • D02-requirement-semantics — satisfied

    • 계약: 요구사항에는 평가 근거와 지표 정의, 선택과 future 제외, 정정 및 idempotency 충돌, 대사 완전성, current 및 import 연계, 마감 상태와 불변성과 승인, shared adapter 및 인증, migration과 legacy를 소스 및 테스트에 대응한다. 모든 승인된 경계와 회귀 사례를 인수 기준으로 내린다.
    • 구현 근거: docs/requirements/req-003_account-valuation-history.md; docs/requirements/req-003_account-valuation-history.md:53-185의 10개 요구사항과 :189-297의 전체 AC를 Discovery의 모든 포함 범위와 확정 결정 및 제외 범위에 대조했다. 이전 REQ-003 전체 AC와 byte-identical하여 의미 삭제나 승인 없는 축소가 없다. 참조된 tests와 actual implementation은 head에서 존재한다. 잔여 current-cache 구현 결함은 C05로 분리하며 문서 반복 부재나 evidence JSON 형식을 새로운 의무로 판단하지 않는다.
    • 테스트 근거: tests/test_account_valuations.py, tests/test_asset_snapshots.py, tests/test_issue_12_regressions.py, tests/test_requirement_docs.py, tests/test_mcp_http_runtime.py, tests/test_dashboard_authentication_app.py
    • 판정 근거: 현재 고정 source와 test assertion 및 변경 영향으로 승인 계약을 판정했다. 문서 또는 이전 verdict만으로 구현 충족을 추정하지 않는다.
  • D03-data-model — satisfied

    • 계약: 신규 데이터 모델은 기존 entities 및 valuation과 마감의 관계, FK와 날짜 및 정확한 금액과 NULL 및 0과 선택 지표 및 대출 필수 정의, 계좌와 통화 및 목적과 기준일의 선택 및 index와 단일 유효 정정본, 고정 적용 분류 및 출처와 상태와 누락 및 이월 및 승인 버전, 분리된 정정과 schema11 이관 및 미상 날짜와 legacy 및 최신 캐시 동기화 책임을 정의한다.
    • 구현 근거: docs/data-model.md; docs/data-model.md:63-68은 account 필수와 currency 및 valuation purpose 선택 필터, basis-date exact 또는 upper-bound, verified leaf와 future 및 unverified 제외를 명시한다. account_date와 status_date 인덱스의 coverage 및 account-currency-purpose 전체를 덮지 않는 한계, idempotency 및 single_correction의 write integrity 책임을 구분한다. account_valuation_service.py:270-312의 실제 선택과 schema.py:264-267 및 migrations.py:169-172의 물리 정의에 대응한다. test_data_model_documents_valuation_selection_contract_and_index_mapping의 tests/test_valuation_contract_docs.py:46-62는 이 설명을 assertion한다. 나머지 entity 관계와 금액 NULL0 및 대출 정의, immutable run과 migration 및 legacy와 캐시 책임은 문서 :12-61 및 :70-176에 보존된다.
    • 테스트 근거: tests/test_account_valuations.py, tests/test_asset_snapshots.py, tests/test_issue_12_regressions.py, tests/test_valuation_contract_docs.py
    • 판정 근거: 현재 고정 source와 test assertion 및 변경 영향으로 승인 계약을 판정했다. 문서 또는 이전 verdict만으로 구현 충족을 추정하지 않는다.
  • D04-interface-contract — satisfied

    • 계약: 인터페이스 문서는 기존 auth 및 메뉴를 보존하고 평가 등록 및 조회 및 정정의 모든 입력과 유효본 및 원금 정의 출력, report 및 preview/close 및 월정산과 대사와 current API의 공통 선택, exact 기본과 실제 날짜 및 age 및 이월과 누락 및 미확인과 출처 및 버전과 승인 출력을 정의한다. 잘못된 입력과 scope 및 충돌과 부족 근거는 무변경 실패이며 기존 envelope와 required keys 및 의미 변경 정책을 명시한다.
    • 구현 근거: docs/interface-contract.md, docs/data-model.md; docs/interface-contract.md:1-261 기존 auth와 menu 보존; :263-358 valuation와 close 입력 및 오류와 무변경; :401-423 실제 signature와 persisted fields; :425-435 close 및 provenance aliases, preview fingerprint, equality replay와 recursive redaction을 승인 의무에 대조했다. 전체 문서는 이전 reviewed head와 동일하고 current source의 signature 및 enums와 대응한다.
    • 테스트 근거: tests/test_account_valuations.py, tests/test_issue_12_regressions.py, tests/test_contract_regression.py, tests/test_valuation_contract_docs.py, tests/test_issue_12_review59_account.py
    • 판정 근거: 현재 고정 source와 test assertion 및 변경 영향으로 승인 계약을 판정했다. 문서 또는 이전 verdict만으로 구현 충족을 추정하지 않는다.
  • D05-project-structure — satisfied

    • 계약: 프로젝트 구조 문서는 기존 source와 test 및 evidence를 보존하고 SQLite schema와 migrations, application의 assets와 account writes 및 import와 reconciliation 및 monthly 책임, 공개 facade와 MCP 및 Streamlit과 기존 세 화면 및 tests를 exact 경로로 대응한다. adapter에서 선택 정책을 복제하지 않고 대출 정의와 verified as_of 및 conditional 승인 경계를 shared application에 배치한다.
    • 구현 근거: docs/project-structure.md; docs/project-structure.md:122-164의 source/test/docs 배치와 application 및 SQLite 및 adapter 의존, :166-212의 auth/menu inventory와 actual module ownership 및 monthly/reconciliation/read-only/privacy 경계를 모든 문서 의무와 current paths에 대조했다. 선택 정책을 adapter에 복제하지 않으며 별도 제품이나 마감 엔진이 없다.
    • 테스트 근거: tests/test_requirement_docs.py
    • 판정 근거: 현재 고정 source와 test assertion 및 변경 영향으로 승인 계약을 판정했다. 문서 또는 이전 verdict만으로 구현 충족을 추정하지 않는다.
  • D06-runtime-flow — satisfied

    • 계약: 런타임 문서는 auth 및 메뉴를 보존하고 register/correct의 증빙 및 scope 검증과 append 및 유효본 확인 및 최신 캐시 동기화를 단일 트랜잭션으로 설명한다. 날짜 및 정책과 통화 및 대표 합산과 경고 read, preview 후 명시적 approval 및 원자적 freeze, reasoned reclose, 같은 근거의 monthly 및 대사, import와 이관 trigger 및 실패복구, retry와 concurrency 및 preview drift 재검증과 무부분쓰기, 비민감 valuation/run 상관 신호를 정의한다.
    • 구현 근거: docs/runtime-flow.md; docs/runtime-flow.md:147-185의 register/select/correct, preview/approval/atomic freeze, import와 monthly 및 reconciliation propagation; :187-210의 failure/retry/concurrency/비민감 signals; :221-241의 실제 transition와 DB boundary 및 fingerprint drift와 no-write 및 immutable replay를 승인 의무와 source에 대조했다. 별도 새 browser 조합이나 독립 실행 기록을 필수 계약으로 추가하지 않는다.
    • 테스트 근거: tests/test_account_valuations.py, tests/test_asset_snapshots.py, tests/test_issue_12_regressions.py
    • 판정 근거: 현재 고정 source와 test assertion 및 변경 영향으로 승인 계약을 판정했다. 문서 또는 이전 verdict만으로 구현 충족을 추정하지 않는다.
  • C16-supporting-evidence-scope — satisfied

    • 계약: 모든 changed file은 승인된 기능과 필수 supporting change 또는 테스트 evidence로 설명되고 기존 requirement ID를 임의 갱신하거나 범위 밖 제품 및 설정을 변경하지 않는다.
    • 구현 근거: dashboard/app.py, dashboard/page_views/accounts.py, dashboard/page_views/assets.py, dashboard/page_views/monthly_settlement.py, docs/data-model.md, docs/interface-contract.md, docs/project-structure.md, docs/requirements/req-003_account-valuation-history.md, docs/runtime-flow.md, docs/verification/issue-12-review-60/contract-preservation-inventory.json, docs/verification/issue-12-review-60/evidence-manifest.json, docs/verification/issue-12-review-60/evidence-plan.json, docs/verification/issue-12-review-60/final-independent-review.json, docs/verification/issue-12-review-60/finding-matrix.json, docs/verification/issue-12-review-60/red-evidence.json, docs/verification/issue-12-review-61/contract-preservation-inventory.json, docs/verification/issue-12-review-61/evidence-manifest.json, docs/verification/issue-12-review-61/evidence-plan.json, docs/verification/issue-12-review-61/finding-matrix.json, docs/verification/issue-12-review-61/green-evidence.json, docs/verification/issue-12-review-61/red-evidence.json, docs/verification/issue-12-review-63/contract-preservation-inventory.json, docs/verification/issue-12-review-63/evidence-manifest.json, docs/verification/issue-12-review-63/evidence-plan.json, docs/verification/issue-12-review-63/finding-matrix.json, docs/verification/issue-12-review-63/red-evidence.json, docs/verification/issue-12-review-64/contract-preservation-inventory.json, docs/verification/issue-12-review-64/evidence-manifest.json, docs/verification/issue-12-review-64/evidence-plan.json, docs/verification/issue-12-review-64/finding-matrix.json, docs/verification/issue-12-review-64/red-evidence.json, docs/verification/issue-12-review-65/contract-preservation-inventory.json, docs/verification/issue-12-review-65/evidence-manifest.json, docs/verification/issue-12-review-65/evidence-plan.json, docs/verification/issue-12-review-65/finding-matrix.json, docs/verification/issue-12-review-65/red-evidence.json, jarca_ledger_mcp/adapters/mcp/server.py, jarca_ledger_mcp/adapters/mcp/tool_contracts.py, jarca_ledger_mcp/adapters/streamlit/accounts_gateway.py, jarca_ledger_mcp/adapters/streamlit/overview_gateway.py, jarca_ledger_mcp/application/__init_.py, jarca_ledger_mcp/application/account_valuation_service.py, jarca_ledger_mcp/application/accounts_write_services.py, jarca_ledger_mcp/application/assets_service.py, jarca_ledger_mcp/application/categorization_services.py, jarca_ledger_mcp/application/cross_transfer_service.py, jarca_ledger_mcp/application/imports_service.py, jarca_ledger_mcp/application/monthly_settlement_service.py, jarca_ledger_mcp/application/reconciliation_service.py, jarca_ledger_mcp/application/review_decision_service.py, jarca_ledger_mcp/application/shared.py, jarca_ledger_mcp/application/system_services.py, jarca_ledger_mcp/application/transaction_report_services.py, jarca_ledger_mcp/application/uncategorized_workbench_service.py, jarca_ledger_mcp/infrastructure/sqlite/__init_.py, jarca_ledger_mcp/infrastructure/sqlite/connection.py, jarca_ledger_mcp/infrastructure/sqlite/migrations.py, jarca_ledger_mcp/infrastructure/sqlite/schema.py, jarca_ledger_mcp/service.py, scripts/ci_fixture_db.py, tests/test_account_basis_public_consumers.py, tests/test_account_valuation_edge_contracts.py, tests/test_account_valuations.py, tests/test_asset_snapshot_idempotency.py, tests/test_asset_snapshots.py, tests/test_contract_regression.py, tests/test_dashboard_app.py, tests/test_dashboard_menu_transition.py, tests/test_import_current_balance_authority.py, tests/test_import_provenance_policy.py, tests/test_issue_12_regressions.py, tests/test_issue_12_review59_account.py, tests/test_issue_12_review59_readonly.py, tests/test_issue_12_review59_reports.py, tests/test_issue_12_review63_accounts.py, tests/test_issue_12_review63_assets.py, tests/test_ledger_categories.py, tests/test_requirement_docs.py, tests/test_review_decision_workbench.py, tests/test_seoulpay_xlsx.py, tests/test_service.py, tests/test_valuation_contract_docs.py; authoritative changed-file 82개와 local base-to-head tree가 일치한다. API diff 192개 hunk의 exact base/head blob 위치 및 내용 일치를 확인했다. Review65 head 이후 변경은 account create validator 및 대응 regression test와 supporting evidence 다섯 파일이다. create delta의 bool 및 float 및 비정수 검증은 기존 exact monetary/current-cache 계약 범위다. 문서 다섯 파일은 직전 reviewed head와 동일하고 REQ003 전체 baseline AC가 보존된다. 모든 changed file이 changed-file-coverage.json에서 기존 criterion 또는 supporting evidence로 연결된다. manifest의 모든 9개 blob OID와 SHA256, plan digest, ancestor 관계 및 전체 source-to-head diff를 검증했다. exact-head status는 pending이며 total_count 0이므로 CI 성공 근거로 사용하지 않는다. 구현자 evidence source f49568273e74b89dc3e83da21ce2ae12ed110543에서 현재 head까지 전체 변경은 evidence-manifest 한 파일이며 실행 입력은 동일하다. focused 65통과와 전체 288통과 및 4skip은 구현자 실행 근거이고 reviewer 독립 실행 또는 CI 결과가 아니다.
    • 테스트 근거: tests/test_account_valuations.py, tests/test_asset_snapshots.py, tests/test_contract_regression.py, tests/test_dashboard_app.py, tests/test_dashboard_menu_transition.py, tests/test_import_provenance_policy.py, tests/test_issue_12_regressions.py, tests/test_issue_12_review59_account.py, tests/test_issue_12_review59_readonly.py, tests/test_issue_12_review59_reports.py, tests/test_ledger_categories.py, tests/test_requirement_docs.py, tests/test_review_decision_workbench.py, tests/test_seoulpay_xlsx.py, tests/test_service.py
    • 판정 근거: 테스트와 supporting evidence의 추가는 승인 범위 안이다. JSON 경로나 추가 CI 및 browser 조합을 새 필수 산출물로 요구하지 않는다.

범위 판정

  • 누락: C05 계좌 수정의 exact integer 및 NULL 의미 검증과 날짜 없는 빈 문자열 및 dated float/boolean 입력 무변경 실패 회귀
  • 범위 초과: 없음
  • 명세 모순: 없음

결론

Review65 계좌 생성 경계 수정과 실제 0 및 후속 import 보존은 해소됐다. 문서 5종 및 다른 계약은 현재 source와 대응 근거에 충족한다. 계좌 수정 경로의 bool 및 float 금액 손실과 날짜 없는 빈 문자열 cache 저장이 승인된 C05 계약에 남아 request_changes다. 이 결함은 신규 create 변경이 도입한 회귀가 아니라 직전 head에도 있던 잔여 경계다. 제품 source는 변경하지 않았고 reviewer 제품 pytest 및 browser는 실행하지 않았다. 구현자 focused 65통과 및 전체 288통과와 4skip 근거는 실행 입력 동일성을 검증하여 재사용했으며 reviewer 실행이나 CI 성공으로 표현하지 않는다.

## 구현 명세 적합성 검토 - Source Issue: #12 - Pull Request: #13 - Reviewed head: `3bf9b77c6cc167a4e2a8706271bdf8e848d2c4fe` - Contract SHA-256: `6d86b591b022fcc722611bfec6d24e54a64216ab6f7c4098f357e25420218818` - Verdict: `request_changes` ### Acceptance criteria 판정 - `C01-history` — `satisfied` - 계약: 평가 계좌 FK, 기준일과 등록일, 대표 금액과 통화와 목적, 출처와 확인 상태, 증빙 식별자, 정정 연결과 사유 및 선택 시간 자료를 이력으로 보존한다. - 구현 근거: jarca_ledger_mcp/application/account_valuation_service.py, jarca_ledger_mcp/infrastructure/sqlite/schema.py, jarca_ledger_mcp/infrastructure/sqlite/migrations.py; account_valuation_service.py:133-257 register_account_valuation 및 :261-266 list_account_valuations; schema.py:229-267 및 migrations.py:157-173의 실제 필드와 FK와 unique 정의를 대조했다. tests/test_account_valuations.py:13-21의 schema12/idempotent 및 :24-32의 동일 기록 reuse와 payload conflict assertions를 확인했다. 구현자 evidence source f49568273e74b89dc3e83da21ce2ae12ed110543에서 현재 head까지 전체 변경은 evidence-manifest 한 파일이며 실행 입력은 동일하다. focused 65통과와 전체 288통과 및 4skip은 구현자 실행 근거이고 reviewer 독립 실행 또는 CI 결과가 아니다. - 테스트 근거: tests/test_account_valuations.py - 판정 근거: 현재 고정 source와 test assertion 및 변경 영향으로 승인 계약을 판정했다. 문서 또는 이전 verdict만으로 구현 충족을 추정하지 않는다. - `C02-money-metrics` — `satisfied` - 계약: 금액 정밀도와 NULL 및 0을 보존하고 취득원가, 순납입액, 기관 표시 원금 금액과 정의 및 원문 명칭, 손익과 수익률의 계산 기준을 구분한다. 투자 대표 총평가액과 포함 현금 및 원금을 중복 합산하지 않는다. - 구현 근거: jarca_ledger_mcp/application/account_valuation_service.py, jarca_ledger_mcp/infrastructure/sqlite/schema.py, docs/data-model.md, docs/requirements/req-003_account-valuation-history.md; account_valuation_service.py:33-56의 strict integer/finite 검증, :165-186의 선택 지표와 NULL 보존, :247-249의 실제 roundtrip columns; schema.py:229-267의 INTEGER 및 선택 NULL 필드와 assets_service.py:453-499의 대표 금액 합산을 대조했다. test_valuation_round_trip_preserves_null_zero_and_physical_amount_mapping 및 test_correction_preserves_optional_fields_unless_overridden의 입력과 actual assertions를 확인했다. 구현자 evidence source f49568273e74b89dc3e83da21ce2ae12ed110543에서 현재 head까지 전체 변경은 evidence-manifest 한 파일이며 실행 입력은 동일하다. focused 65통과와 전체 288통과 및 4skip은 구현자 실행 근거이고 reviewer 독립 실행 또는 CI 결과가 아니다. - 테스트 근거: tests/test_issue_12_review59_account.py, tests/test_issue_12_regressions.py - 판정 근거: 현재 고정 source와 test assertion 및 변경 영향으로 승인 계약을 판정했다. 문서 또는 이전 verdict만으로 구현 충족을 추정하지 않는다. - `N01-loan-balance-definition` — `satisfied` - 계약: 대출 평가 기록마다 대표 부채가 원금만인지 원금과 이자 및 수수료인지 필수로 명시하고 기본값으로 추정하지 않는다. 목적 alias가 필수 정의 계약을 우회하지 않는다. - 구현 근거: jarca_ledger_mcp/application/account_valuation_service.py, docs/requirements/req-003_account-valuation-history.md, jarca_ledger_mcp/application/accounts_write_services.py, jarca_ledger_mcp/application/imports_service.py, docs/data-model.md; account_valuation_service.py:93-105의 loan candidate 무추정 거부 및 :194-203의 loan alias와 종류 및 필수 정의 검증; accounts_write_services.py:74-82의 non-loan 전환 guard; imports_service.py:37-41의 candidate 호출을 대조했다. tests/test_account_valuation_edge_contracts.py:8-38, :41-76, :133-191은 계좌 유형 전환과 정의 누락 및 candidate/import 경로의 validation_error와 history/account 불변을 assertion한다. 구현자 evidence source f49568273e74b89dc3e83da21ce2ae12ed110543에서 현재 head까지 전체 변경은 evidence-manifest 한 파일이며 실행 입력은 동일하다. focused 65통과와 전체 288통과 및 4skip은 구현자 실행 근거이고 reviewer 독립 실행 또는 CI 결과가 아니다. - 테스트 근거: tests/test_issue_12_regressions.py, tests/test_issue_12_review59_account.py, tests/test_account_valuation_edge_contracts.py - 판정 근거: 현재 고정 source와 test assertion 및 변경 영향으로 승인 계약을 판정했다. 문서 또는 이전 verdict만으로 구현 충족을 추정하지 않는다. - `C03-selection` — `satisfied` - 계약: 계좌와 통화 및 평가 목적별 유효 자료를 선택한다. exact는 당일 확인 자료만, as_of는 기준일 이하 최신 확인 자료만 사용한다. 미래 자료는 제외하고 미확인 후보는 확인 자료를 대체하거나 합산하지 않는다. 실제 기준일과 경과 일수 및 이월 상태를 반환한다. - 구현 근거: jarca_ledger_mcp/application/account_valuation_service.py, jarca_ledger_mcp/application/assets_service.py; account_valuation_service.py:270-312 select_account_valuation의 scope와 verified leaf, exact 및 latest-prior, candidate warning 및 age; assets_service.py:115-215와 :218-259의 계좌 및 기존 수기 selection과 미래/미확인/통화 제외를 대조했다. tests/test_account_valuations.py:35-45는 future와 unverified 제외 및 as-of carry와 actual date를 assertion한다. tests/test_issue_12_regressions.py의 scope 및 purpose와 unverified 합계 제외 regression을 함께 읽었다. 구현자 evidence source f49568273e74b89dc3e83da21ce2ae12ed110543에서 현재 head까지 전체 변경은 evidence-manifest 한 파일이며 실행 입력은 동일하다. focused 65통과와 전체 288통과 및 4skip은 구현자 실행 근거이고 reviewer 독립 실행 또는 CI 결과가 아니다. - 테스트 근거: tests/test_account_valuations.py, tests/test_issue_12_regressions.py - 판정 근거: 현재 고정 source와 test assertion 및 변경 영향으로 승인 계약을 판정했다. 문서 또는 이전 verdict만으로 구현 충족을 추정하지 않는다. - `C04-correction-validation` — `satisfied` - 계약: 평가 정정은 append-only로 대상과 사유를 연결하며 다른 계좌, 통화, 목적을 참조하는 정정과 순환 및 동일 유효본의 동시 분기를 차단한다. - 구현 근거: jarca_ledger_mcp/application/account_valuation_service.py, jarca_ledger_mcp/infrastructure/sqlite/schema.py; account_valuation_service.py:204-224는 parent scope와 cyclic ancestry를 검증하고 :245-253은 단일 child unique 충돌을 fail-closed 처리한다. :315-375의 effective payload replay 및 changed conflict와 append-only 경계를 확인했다. tests/test_account_valuations.py:48-59는 원본 보존과 단일 correction count를 assertion하고 tests/test_account_valuation_edge_contracts.py:79-130은 동일 effective correction reuse 및 다른 payload conflict를 확인한다. 구현자 evidence source f49568273e74b89dc3e83da21ce2ae12ed110543에서 현재 head까지 전체 변경은 evidence-manifest 한 파일이며 실행 입력은 동일하다. focused 65통과와 전체 288통과 및 4skip은 구현자 실행 근거이고 reviewer 독립 실행 또는 CI 결과가 아니다. - 테스트 근거: tests/test_issue_12_review59_account.py, tests/test_account_valuations.py, tests/test_issue_12_regressions.py - 판정 근거: 현재 고정 source와 test assertion 및 변경 영향으로 승인 계약을 판정했다. 문서 또는 이전 verdict만으로 구현 충족을 추정하지 않는다. - `C05-current-import` — `unsatisfied` - 계약: 뒤늦은 과거 자료 등록으로 최신 표시값을 과거로 되돌리지 않는다. 기존 계좌 수정과 import의 최신 캐시 및 새 이력 권위를 연결하며 동기화 시각을 실제 평가일로 오인하지 않는다. - 구현 근거: jarca_ledger_mcp/application/imports_service.py, jarca_ledger_mcp/application/assets_service.py, jarca_ledger_mcp/application/accounts_write_services.py; Review65 create 지적은 accounts_write_services.py:28-40의 INSERT 전 strict integer 검증으로 해소됐다. tests/test_import_current_balance_authority.py:104-121의 test_create_rejects_whitespace_or_non_integer_dated_balance_without_mutation은 공백과 비정수 및 boolean과 float 입력 거부와 계좌 목록 및 valuation 불변을 assertion한다. :124-150의 test_zero_dated_balance_and_valid_import_recovery는 실제 0 및 유효 후속 dated import를 확인한다. 잔여 update 경로는 accounts_write_services.py:49-71과 :90-99다. :67의 int(v)는 True와 False 및 1.2와 -1.2를 각각 1과 0 및 1과 -1로 바꾸고 dated 후보도 :12 및 :99에서 같은 손실을 저장한다. last_balance 빈 문자열 단독 입력은 basis_update가 없으면 :51 guard를 통과하고 :67 변환도 건너뛰어 :95에서 저장된다. 이는 exact integer 또는 NULL 모델이 아니다. assets_service.py:149 및 :210-214를 호출하는 get_asset_liquidity_report의 :1105-1114와 reconciliation_service.py:98 및 :159-166은 이 빈 문자열을 int 변환하여 ValueError가 난다. shared.py:128-138은 sqlite3 오류만 envelope로 처리한다. 승인 계약은 Discovery 정확한 금액 및 현재값 쓰기 권위 연결과 docs/data-model.md:26-28 및 :132-136, req-003:89-111, interface-contract.md:344다. 기존 tests/test_import_current_balance_authority.py:68-101은 날짜를 함께 보낸 빈 문자열 update만 검사한다. dated float 및 boolean update와 날짜 없는 빈 문자열 update의 무변경 실패 assertion은 없다. 구현자 evidence source f49568273e74b89dc3e83da21ce2ae12ed110543에서 현재 head까지 전체 변경은 evidence-manifest 한 파일이며 실행 입력은 동일하다. focused 65통과와 전체 288통과 및 4skip은 구현자 실행 근거이고 reviewer 독립 실행 또는 CI 결과가 아니다. - 테스트 근거: tests/test_issue_12_review59_account.py, tests/test_import_provenance_policy.py, tests/test_import_current_balance_authority.py, tests/test_account_basis_public_consumers.py, tests/test_issue_12_review63_accounts.py - 판정 근거: 생성 수정은 충족하지만 계좌 수정의 금액 의미 손실 및 invalid empty-string cache 저장이 C05 승인 계약에 남는다. 유효하지 않은 금액은 저장과 후보 생성 전 validation_error로 무변경 거부하고, 0과 유효 signed integer 입력, 정상 dated update 및 과거 candidate와 최신 캐시 보존을 유지해야 한다. 최소 회귀는 bool 및 float의 dated update와 빈 문자열 단독 update가 계좌와 이력을 바꾸지 않는지 확인하는 것이다. 이 경로는 직전 head와 동일하므로 신규 회귀가 아니라 기존 잔여 결함이다. 새 요구사항이나 특정 validator 구현을 강제하는 요청이 아니다. - `C06-idempotency` — `satisfied` - 계약: 동일 증빙 또는 idempotency 재입력은 동일 기록을 재사용하며 같은 키의 다른 payload는 충돌이다. 동시 정정의 분기를 차단하고 UNIQUE 계좌 및 기준일 하나로 정정 추가를 막지 않는다. - 구현 근거: jarca_ledger_mcp/application/account_valuation_service.py, jarca_ledger_mcp/infrastructure/sqlite/schema.py, jarca_ledger_mcp/infrastructure/sqlite/migrations.py, jarca_ledger_mcp/application/accounts_write_services.py, jarca_ledger_mcp/application/imports_service.py; account_valuation_service.py:107-125의 candidate key payload, :225-244의 key와 source_ref 정본 및 unrelated scope conflict, :315-375의 explicit 및 keyless effective correction reuse; schema.py:264-267의 account-scoped key와 single-child index를 대조했다. tests/test_account_valuations.py:24-32 및 :72-80과 tests/test_account_valuation_edge_contracts.py:79-130, :194-231은 동일/변경 payload 및 correction와 candidate validation의 actual assertions를 제공한다. 구현자 evidence source f49568273e74b89dc3e83da21ce2ae12ed110543에서 현재 head까지 전체 변경은 evidence-manifest 한 파일이며 실행 입력은 동일하다. focused 65통과와 전체 288통과 및 4skip은 구현자 실행 근거이고 reviewer 독립 실행 또는 CI 결과가 아니다. - 테스트 근거: tests/test_issue_12_review59_account.py, tests/test_account_valuations.py, tests/test_issue_12_regressions.py, tests/test_account_valuation_edge_contracts.py - 판정 근거: 현재 고정 source와 test assertion 및 변경 영향으로 승인 계약을 판정했다. 문서 또는 이전 verdict만으로 구현 충족을 추정하지 않는다. - `C07-close-immutability` — `satisfied` - 계약: 기존 asset_snapshots와 correction run을 보존하고 평가 정정 및 거래 추가로 기존 마감을 자동 변경하지 않는다. 동일 기준일 재마감은 사유와 이전 run 연결을 가진 새 버전을 원자적으로 추가한다. - 구현 근거: jarca_ledger_mcp/application/assets_service.py, jarca_ledger_mcp/infrastructure/sqlite/schema.py, jarca_ledger_mcp/infrastructure/sqlite/migrations.py; assets_service.py:717-752는 correction chain과 최신 correction authority를 검사하고 :757은 원래 existing run을 읽는다. unrelated live drift는 :800에서 idempotency_conflict다. tests/test_issue_12_review63_assets.py:97-138은 두 correction 이후 original equality와 unrelated asset drift conflict를 확인한다. 추가 evidence-array 검증은 :262-269 및 :297-320과 report/replay/timeseries의 오류 경계에 제한적으로 배치돼 정상 run 불변성을 변경하지 않는다. 구현자 evidence source f49568273e74b89dc3e83da21ce2ae12ed110543에서 현재 head까지 전체 변경은 evidence-manifest 한 파일이며 실행 입력은 동일하다. focused 65통과와 전체 288통과 및 4skip은 구현자 실행 근거이고 reviewer 독립 실행 또는 CI 결과가 아니다. - 테스트 근거: tests/test_asset_snapshots.py, tests/test_issue_12_regressions.py, tests/test_issue_12_review63_assets.py - 판정 근거: 현재 고정 source와 test assertion 및 변경 영향으로 승인 계약을 판정했다. 문서 또는 이전 verdict만으로 구현 충족을 추정하지 않는다. - `N02-close-replay-run-binding` — `satisfied` - 계약: 마감 버전의 근거는 불변이며 동일 idempotency 요청은 원래 기록을 재사용한다. 재마감으로 과거 run 응답 및 evidence를 변경하지 않는다. - 구현 근거: jarca_ledger_mcp/application/assets_service.py, docs/interface-contract.md; F002 해소. assets_service.py:842-860은 included unverified_candidates와 excluded candidate의 blocking 및 state_hash를 저장한다. :383-398은 blocking=False를 복원하고 :757-799는 exact existing run에서 원래 응답을 구성한다. tests/test_asset_snapshot_idempotency.py:9-64의 test_replay_preserves_redacted_unverified_candidates_after_correction은 후보 allowlist와 blocking=False 및 전체 replay==first와 row/run count 불변을 assertion한다. :67-96의 test_replay_preserves_blocking_candidate_warning_shape은 차단 warning의 blocking 키 부재와 최초 응답 equality를 확인한다. 기존 mixed-asof 및 correction-chain equality 테스트도 보존된다. 구현자 evidence source f49568273e74b89dc3e83da21ce2ae12ed110543에서 현재 head까지 전체 변경은 evidence-manifest 한 파일이며 실행 입력은 동일하다. focused 65통과와 전체 288통과 및 4skip은 구현자 실행 근거이고 reviewer 독립 실행 또는 CI 결과가 아니다. - 테스트 근거: tests/test_issue_12_review59_reports.py, tests/test_issue_12_regressions.py, tests/test_asset_snapshot_idempotency.py, tests/test_issue_12_review63_assets.py - 판정 근거: 현재 고정 source와 test assertion 및 변경 영향으로 승인 계약을 판정했다. 문서 또는 이전 verdict만으로 구현 충족을 추정하지 않는다. - `C08-approved-conditional` — `satisfied` - 계약: 완전한 exact 마감, 미완료 초안, 별도 승인된 조건부 마감을 구분한다. 승인 전 누락 및 이월은 미완료 초안이고 승인 후에도 누락 제외 및 확인된 과거값 이월만 허용한다. 미확인, 미래, 기준일 미상 금액은 승인으로도 합산하지 않으며 적용과 제외와 이월 및 승인자와 시각과 사유와 근거를 고정한다. - 구현 근거: jarca_ledger_mcp/application/assets_service.py, jarca_ledger_mcp/infrastructure/sqlite/schema.py, dashboard/page_views/assets.py; assets_service.py:646-671 및 :684-709은 public redaction 이전 동일 preview fingerprint와 승인 경계를 확인한다. 기존 test_f001_preview_fingerprint_uses_same_unredacted_authority_and_rejects_drift의 :17-41은 unchanged handoff 성공과 drift 거부 및 run 불변을 assertion한다. 미확인 candidate는 합산하지 않으며 nonblocking 후보는 conditional 승인 대상으로 오인하지 않는다. 승인자와 시각 및 사유와 참조, 적용과 제외와 이월은 :842-864에 원자적으로 저장한다. 구현자 evidence source f49568273e74b89dc3e83da21ce2ae12ed110543에서 현재 head까지 전체 변경은 evidence-manifest 한 파일이며 실행 입력은 동일하다. focused 65통과와 전체 288통과 및 4skip은 구현자 실행 근거이고 reviewer 독립 실행 또는 CI 결과가 아니다. - 테스트 근거: tests/test_issue_12_review59_reports.py, tests/test_issue_12_regressions.py, tests/test_asset_snapshots.py, tests/test_issue_12_review63_assets.py - 판정 근거: 현재 고정 source와 test assertion 및 변경 영향으로 승인 계약을 판정했다. 문서 또는 이전 verdict만으로 구현 충족을 추정하지 않는다. - `C09-reconciliation` — `satisfied` - 계약: 외부 확인값과 장부 계산값을 분리하고 검증된 시작잔고, 기준시점, 거래 포함 범위와 계산 완전성을 표시한다. 거래 없는 수동 투자 계좌의 대사 불가 및 거래 미수입과 평가 수동 관리 상태를 구분하고 가짜 거래를 만들지 않는다. 대사도 공통 평가 근거와 대출 대표 정의를 사용한다. - 구현 근거: jarca_ledger_mcp/application/reconciliation_service.py, jarca_ledger_mcp/application/account_valuation_service.py, jarca_ledger_mcp/application/monthly_settlement_service.py; reconciliation_service.py:31-64 _account_balance_row는 시작 근거 및 거래 coverage를 분리하고 :102-158은 verified corrected leaf와 목적 및 대출 정의를 선택한다. :159-213은 계산 불완전 및 수동 투자 평가 관리와 대사 불가 상태를 provenance로 전달한다. monthly_settlement_service.py의 get_monthly_settlement_summary는 공통 report를 읽으며 tests/test_issue_12_review59_reports.py 및 tests/test_issue_12_regressions.py의 no-fake-transaction와 corrected-investment 및 unavailable assertions에 대응한다. 구현자 evidence source f49568273e74b89dc3e83da21ce2ae12ed110543에서 현재 head까지 전체 변경은 evidence-manifest 한 파일이며 실행 입력은 동일하다. focused 65통과와 전체 288통과 및 4skip은 구현자 실행 근거이고 reviewer 독립 실행 또는 CI 결과가 아니다. - 테스트 근거: tests/test_issue_12_review59_reports.py, tests/test_issue_12_regressions.py, tests/test_service.py - 판정 근거: 현재 고정 source와 test assertion 및 변경 영향으로 승인 계약을 판정했다. 문서 또는 이전 verdict만으로 구현 충족을 추정하지 않는다. - `C10-report-monthly-evidence` — `satisfied` - 계약: MCP와 Dashboard 및 월정산 보고에서 같은 기준일과 선택 근거 및 실제 평가일, 경과 일수, 확인 상태, 누락과 미확인 및 이월 경고, 마감 버전 및 조건부 승인 근거를 일관되게 전달한다. - 구현 근거: jarca_ledger_mcp/application/assets_service.py, jarca_ledger_mcp/application/monthly_settlement_service.py, dashboard/page_views/monthly_settlement.py, dashboard/page_views/accounts.py; assets_service.py:335-380은 frozen valuation_id와 currency 및 실제 basis를 복원한다. :948-984는 frozen run을 정본으로 보고하고 :1049-1102는 zero-row run 날짜를 UNION으로 포함해 latest run의 승인 및 provenance를 전달한다. tests/test_issue_12_review63_assets.py:141-206은 zero-row 정정 run 및 alias, frozen ID와 currency 및 legacy ID 비추론을 assertion한다. monthly_settlement_service.py는 해당 공통 report를 읽는다. malformed JSON 배열 guard의 신규 test는 tests/test_asset_snapshot_idempotency.py:99-128이며 report/replay/timeseries 실패 및 row/run 불변을 확인한다. 임의 DB 손상 전체의 복구나 추가 오류명은 새 인수 조건으로 만들지 않는다. 구현자 evidence source f49568273e74b89dc3e83da21ce2ae12ed110543에서 현재 head까지 전체 변경은 evidence-manifest 한 파일이며 실행 입력은 동일하다. focused 65통과와 전체 288통과 및 4skip은 구현자 실행 근거이고 reviewer 독립 실행 또는 CI 결과가 아니다. - 테스트 근거: tests/test_issue_12_review59_reports.py, tests/test_issue_12_regressions.py, tests/test_service.py, tests/test_issue_12_review63_assets.py - 판정 근거: 현재 고정 source와 test assertion 및 변경 영향으로 승인 계약을 판정했다. 문서 또는 이전 verdict만으로 구현 충족을 추정하지 않는다. - `C11-adapter-structure` — `satisfied` - 계약: MCP와 Streamlit gateway는 공통 application을 사용하고 기존 공개 호출명과 기존 인수 및 success와 실패 error_code 및 error envelope를 가능한 한 유지한다. 새 Dashboard 인증 또는 MCP 인증을 도입하지 않는다. - 구현 근거: jarca_ledger_mcp/adapters/mcp/server.py, jarca_ledger_mcp/adapters/mcp/tool_contracts.py, jarca_ledger_mcp/adapters/streamlit/accounts_gateway.py, jarca_ledger_mcp/application/__init__.py, jarca_ledger_mcp/service.py, dashboard/page_views/accounts.py, dashboard/page_views/assets.py, dashboard/page_views/monthly_settlement.py; service.py:50-70의 호환 facade와 application/asset_account_services.py:3-15의 공통 export, adapters/mcp/server.py의 create/register/select/correct/preview/close tools와 adapters/streamlit/accounts_gateway.py 및 overview_gateway.py의 shared-service delegate를 대조했다. dashboard/page_views/accounts.py 및 assets.py와 monthly_settlement.py는 shared gateway 결과를 렌더링하고 명시적 submit에서만 writer를 호출한다. tests/test_contract_regression.py와 tests/test_issue_12_regressions.py의 공개 signature/envelope 및 read-only assertions는 보존된다. 구현자 evidence source f49568273e74b89dc3e83da21ce2ae12ed110543에서 현재 head까지 전체 변경은 evidence-manifest 한 파일이며 실행 입력은 동일하다. focused 65통과와 전체 288통과 및 4skip은 구현자 실행 근거이고 reviewer 독립 실행 또는 CI 결과가 아니다. - 테스트 근거: tests/test_contract_regression.py, tests/test_issue_12_regressions.py - 판정 근거: 현재 고정 source와 test assertion 및 변경 영향으로 승인 계약을 판정했다. 문서 또는 이전 verdict만으로 구현 충족을 추정하지 않는다. - `C12-migration-legacy` — `satisfied` - 계약: schema 11의 기존 데이터와 마감 및 개인정보를 보존하고 additive하고 idempotent한 migration을 제공한다. 기준일 증거 없는 값을 임의 월말로 소급하거나 legacy snapshot에 valuation_id를 추측하여 생성하지 않는다. - 구현 근거: jarca_ledger_mcp/infrastructure/sqlite/schema.py, jarca_ledger_mcp/infrastructure/sqlite/migrations.py, jarca_ledger_mcp/application/assets_service.py; migrations.py:19-173의 additive CREATE/ADD COLUMN과 unique 및 schema12 상태; assets_service.py:335-380의 frozen evidence와 legacy valuation_id 비추론을 대조했다. test_account_valuation_schema_is_v12_and_idempotent 및 test_schema12_migration_preserves_legacy_rows_indexes_and_is_idempotent는 기존 rows와 재호출 idempotency를 검사하고 tests/test_issue_12_review63_assets.py:199-206은 legacy ID가 생성되지 않음을 assertion한다. 구현자 evidence source f49568273e74b89dc3e83da21ce2ae12ed110543에서 현재 head까지 전체 변경은 evidence-manifest 한 파일이며 실행 입력은 동일하다. focused 65통과와 전체 288통과 및 4skip은 구현자 실행 근거이고 reviewer 독립 실행 또는 CI 결과가 아니다. - 테스트 근거: tests/test_account_valuations.py, tests/test_issue_12_regressions.py, tests/test_ledger_categories.py, tests/test_review_decision_workbench.py - 판정 근거: 현재 고정 source와 test assertion 및 변경 영향으로 승인 계약을 판정했다. 문서 또는 이전 verdict만으로 구현 충족을 추정하지 않는다. - `C13-read-only` — `satisfied` - 계약: preview와 조회 및 Dashboard 렌더링은 금융 쓰기를 실행하지 않는다. 명시적 등록, 정정, 승인 close 및 import 제출만 변경을 수행하고 실패 시 부분 쓰기를 남기지 않는다. - 구현 근거: jarca_ledger_mcp/infrastructure/sqlite/connection.py, jarca_ledger_mcp/application/shared.py, jarca_ledger_mcp/application/system_services.py, jarca_ledger_mcp/application/account_valuation_service.py, jarca_ledger_mcp/application/assets_service.py; connection.py:31-53 connect_readonly/read_db의 mode=ro와 no-init, shared.py:128-138의 read 오류 envelope; assets_service.py:646-671의 preview와 :939-1138의 report/time-series/liquidity read, account_valuation_service.py:260-312의 read selector를 대조했다. tests/test_issue_12_review59_readonly.py는 missing DB no-path-create와 initialized DB schema/rows 불변을 검사하고 explicit writer는 connection.py:56-69에서만 init와 commit을 수행한다. 구현자 evidence source f49568273e74b89dc3e83da21ce2ae12ed110543에서 현재 head까지 전체 변경은 evidence-manifest 한 파일이며 실행 입력은 동일하다. focused 65통과와 전체 288통과 및 4skip은 구현자 실행 근거이고 reviewer 독립 실행 또는 CI 결과가 아니다. - 테스트 근거: tests/test_issue_12_review59_readonly.py, tests/test_dashboard_app.py, tests/test_dashboard_menu_transition.py - 판정 근거: 현재 고정 source와 test assertion 및 변경 영향으로 승인 계약을 판정했다. 문서 또는 이전 verdict만으로 구현 충족을 추정하지 않는다. - `C14-auth-menu-preservation` — `satisfied` - 계약: Dashboard 인증은 DB보다 먼저이며 REQ-001의 cookie와 logout 및 REQ-002의 메뉴 label과 order, shell, query, error와 retry 및 명시적 금융 쓰기 계약을 유지한다. - 구현 근거: dashboard/app.py, dashboard/page_views/accounts.py, dashboard/page_views/assets.py, dashboard/page_views/monthly_settlement.py, docs/interface-contract.md, docs/project-structure.md, docs/runtime-flow.md; dashboard/app.py:37-72의 auth-before-financial-dispatch와 gateway read boundary, 기존 dashboard authentication/menu 관련 source 및 tests는 직전 head와 byte-identical하다. docs/interface-contract.md:1-261 및 docs/project-structure.md와 docs/runtime-flow.md의 기존 auth/cookie/logout와 canonical menu order 및 shell/query 내용이 보존된다. tests/test_dashboard_menu_transition.py 및 tests/test_dashboard_app.py의 actual authentication/menu/no-write assertions와 전체 구현자 regression 보고를 대응했다. 구현자 evidence source f49568273e74b89dc3e83da21ce2ae12ed110543에서 현재 head까지 전체 변경은 evidence-manifest 한 파일이며 실행 입력은 동일하다. focused 65통과와 전체 288통과 및 4skip은 구현자 실행 근거이고 reviewer 독립 실행 또는 CI 결과가 아니다. - 테스트 근거: tests/test_dashboard_menu_transition.py, tests/test_dashboard_app.py - 판정 근거: 현재 고정 source와 test assertion 및 변경 영향으로 승인 계약을 판정했다. 문서 또는 이전 verdict만으로 구현 충족을 추정하지 않는다. - `C15-exclusions-privacy` — `satisfied` - 계약: 증권사 자동 연동, 정확한 성과 또는 환율 엔진, 새 인증, 별도 월정산 제품, 거래 추론 및 기존 데이터 자동 재작성과 수기 비계좌 자산 전체 이력 재설계를 추가하지 않는다. 실제 계좌 및 금융 증빙과 credential을 로그와 문서 및 테스트에 기록하지 않는다. - 구현 근거: jarca_ledger_mcp/application/assets_service.py, jarca_ledger_mcp/application/account_valuation_service.py, jarca_ledger_mcp/application/imports_service.py, jarca_ledger_mcp/application/reconciliation_service.py, jarca_ledger_mcp/infrastructure/sqlite/schema.py, jarca_ledger_mcp/infrastructure/sqlite/migrations.py; assets_service.py:62-75 _public_evidence 및 :94-112의 민감 source state는 digest로만 공개하고 :383-408의 closed metadata는 strict allowlist를 사용한다. account_valuation_service.py:29-30의 public candidate는 ID/date/currency/purpose/status만 반환한다. tests/test_asset_snapshot_idempotency.py:26-42는 redacted candidate와 state hash 및 비차단 warning shape를 assertion한다. changed-file 전체는 기존 금융 이력 및 마감과 read-only 보완 및 supporting tests/docs이며 외부 FX/가격/auth/성과 엔진이나 기존 데이터 재작성은 없다. 구현자 evidence source f49568273e74b89dc3e83da21ce2ae12ed110543에서 현재 head까지 전체 변경은 evidence-manifest 한 파일이며 실행 입력은 동일하다. focused 65통과와 전체 288통과 및 4skip은 구현자 실행 근거이고 reviewer 독립 실행 또는 CI 결과가 아니다. - 테스트 근거: tests/test_issue_12_review59_reports.py, tests/test_issue_12_regressions.py, scripts/ci_fixture_db.py - 판정 근거: 현재 고정 source와 test assertion 및 변경 영향으로 승인 계약을 판정했다. 문서 또는 이전 verdict만으로 구현 충족을 추정하지 않는다. - `D01-requirement-structure` — `satisfied` - 계약: 신규 REQ-003을 배정 경로와 제목으로 작성하며 trusted harness README와 TEMPLATE의 JSON metadata, 연속 요구사항 및 AC, 필수 섹션, 판정 기준과 검증 및 검증 분류의 수준과 백엔드와 케이스 및 상태 불변조건을 충족한다. 초기 PR은 미정이며 PR 생성 후 실제 번호를 추적한다. - 구현 근거: docs/requirements/req-003_account-valuation-history.md; REQ-003의 JSON metadata docs/requirements/req-003_account-valuation-history.md:1-16, 연속 요구사항 :51-185 및 AC :187-297, 필수 오류와 계약과 호환성과 추적성 :299-317을 trusted harness README 및 TEMPLATE에 대조했다. Issue12와 실제 구현 PR13의 lifecycle traceability는 유효하다. 전체 문서와 이전 reviewed-head baseline은 byte-identical하다. 실제 tests/test_requirement_docs.py의 marker와 signature 및 named test 존재 assertion을 읽었다. - 테스트 근거: tests/test_requirement_docs.py - 판정 근거: 현재 고정 source와 test assertion 및 변경 영향으로 승인 계약을 판정했다. 문서 또는 이전 verdict만으로 구현 충족을 추정하지 않는다. - `D02-requirement-semantics` — `satisfied` - 계약: 요구사항에는 평가 근거와 지표 정의, 선택과 future 제외, 정정 및 idempotency 충돌, 대사 완전성, current 및 import 연계, 마감 상태와 불변성과 승인, shared adapter 및 인증, migration과 legacy를 소스 및 테스트에 대응한다. 모든 승인된 경계와 회귀 사례를 인수 기준으로 내린다. - 구현 근거: docs/requirements/req-003_account-valuation-history.md; docs/requirements/req-003_account-valuation-history.md:53-185의 10개 요구사항과 :189-297의 전체 AC를 Discovery의 모든 포함 범위와 확정 결정 및 제외 범위에 대조했다. 이전 REQ-003 전체 AC와 byte-identical하여 의미 삭제나 승인 없는 축소가 없다. 참조된 tests와 actual implementation은 head에서 존재한다. 잔여 current-cache 구현 결함은 C05로 분리하며 문서 반복 부재나 evidence JSON 형식을 새로운 의무로 판단하지 않는다. - 테스트 근거: tests/test_account_valuations.py, tests/test_asset_snapshots.py, tests/test_issue_12_regressions.py, tests/test_requirement_docs.py, tests/test_mcp_http_runtime.py, tests/test_dashboard_authentication_app.py - 판정 근거: 현재 고정 source와 test assertion 및 변경 영향으로 승인 계약을 판정했다. 문서 또는 이전 verdict만으로 구현 충족을 추정하지 않는다. - `D03-data-model` — `satisfied` - 계약: 신규 데이터 모델은 기존 entities 및 valuation과 마감의 관계, FK와 날짜 및 정확한 금액과 NULL 및 0과 선택 지표 및 대출 필수 정의, 계좌와 통화 및 목적과 기준일의 선택 및 index와 단일 유효 정정본, 고정 적용 분류 및 출처와 상태와 누락 및 이월 및 승인 버전, 분리된 정정과 schema11 이관 및 미상 날짜와 legacy 및 최신 캐시 동기화 책임을 정의한다. - 구현 근거: docs/data-model.md; docs/data-model.md:63-68은 account 필수와 currency 및 valuation purpose 선택 필터, basis-date exact 또는 upper-bound, verified leaf와 future 및 unverified 제외를 명시한다. account_date와 status_date 인덱스의 coverage 및 account-currency-purpose 전체를 덮지 않는 한계, idempotency 및 single_correction의 write integrity 책임을 구분한다. account_valuation_service.py:270-312의 실제 선택과 schema.py:264-267 및 migrations.py:169-172의 물리 정의에 대응한다. test_data_model_documents_valuation_selection_contract_and_index_mapping의 tests/test_valuation_contract_docs.py:46-62는 이 설명을 assertion한다. 나머지 entity 관계와 금액 NULL0 및 대출 정의, immutable run과 migration 및 legacy와 캐시 책임은 문서 :12-61 및 :70-176에 보존된다. - 테스트 근거: tests/test_account_valuations.py, tests/test_asset_snapshots.py, tests/test_issue_12_regressions.py, tests/test_valuation_contract_docs.py - 판정 근거: 현재 고정 source와 test assertion 및 변경 영향으로 승인 계약을 판정했다. 문서 또는 이전 verdict만으로 구현 충족을 추정하지 않는다. - `D04-interface-contract` — `satisfied` - 계약: 인터페이스 문서는 기존 auth 및 메뉴를 보존하고 평가 등록 및 조회 및 정정의 모든 입력과 유효본 및 원금 정의 출력, report 및 preview/close 및 월정산과 대사와 current API의 공통 선택, exact 기본과 실제 날짜 및 age 및 이월과 누락 및 미확인과 출처 및 버전과 승인 출력을 정의한다. 잘못된 입력과 scope 및 충돌과 부족 근거는 무변경 실패이며 기존 envelope와 required keys 및 의미 변경 정책을 명시한다. - 구현 근거: docs/interface-contract.md, docs/data-model.md; docs/interface-contract.md:1-261 기존 auth와 menu 보존; :263-358 valuation와 close 입력 및 오류와 무변경; :401-423 실제 signature와 persisted fields; :425-435 close 및 provenance aliases, preview fingerprint, equality replay와 recursive redaction을 승인 의무에 대조했다. 전체 문서는 이전 reviewed head와 동일하고 current source의 signature 및 enums와 대응한다. - 테스트 근거: tests/test_account_valuations.py, tests/test_issue_12_regressions.py, tests/test_contract_regression.py, tests/test_valuation_contract_docs.py, tests/test_issue_12_review59_account.py - 판정 근거: 현재 고정 source와 test assertion 및 변경 영향으로 승인 계약을 판정했다. 문서 또는 이전 verdict만으로 구현 충족을 추정하지 않는다. - `D05-project-structure` — `satisfied` - 계약: 프로젝트 구조 문서는 기존 source와 test 및 evidence를 보존하고 SQLite schema와 migrations, application의 assets와 account writes 및 import와 reconciliation 및 monthly 책임, 공개 facade와 MCP 및 Streamlit과 기존 세 화면 및 tests를 exact 경로로 대응한다. adapter에서 선택 정책을 복제하지 않고 대출 정의와 verified as_of 및 conditional 승인 경계를 shared application에 배치한다. - 구현 근거: docs/project-structure.md; docs/project-structure.md:122-164의 source/test/docs 배치와 application 및 SQLite 및 adapter 의존, :166-212의 auth/menu inventory와 actual module ownership 및 monthly/reconciliation/read-only/privacy 경계를 모든 문서 의무와 current paths에 대조했다. 선택 정책을 adapter에 복제하지 않으며 별도 제품이나 마감 엔진이 없다. - 테스트 근거: tests/test_requirement_docs.py - 판정 근거: 현재 고정 source와 test assertion 및 변경 영향으로 승인 계약을 판정했다. 문서 또는 이전 verdict만으로 구현 충족을 추정하지 않는다. - `D06-runtime-flow` — `satisfied` - 계약: 런타임 문서는 auth 및 메뉴를 보존하고 register/correct의 증빙 및 scope 검증과 append 및 유효본 확인 및 최신 캐시 동기화를 단일 트랜잭션으로 설명한다. 날짜 및 정책과 통화 및 대표 합산과 경고 read, preview 후 명시적 approval 및 원자적 freeze, reasoned reclose, 같은 근거의 monthly 및 대사, import와 이관 trigger 및 실패복구, retry와 concurrency 및 preview drift 재검증과 무부분쓰기, 비민감 valuation/run 상관 신호를 정의한다. - 구현 근거: docs/runtime-flow.md; docs/runtime-flow.md:147-185의 register/select/correct, preview/approval/atomic freeze, import와 monthly 및 reconciliation propagation; :187-210의 failure/retry/concurrency/비민감 signals; :221-241의 실제 transition와 DB boundary 및 fingerprint drift와 no-write 및 immutable replay를 승인 의무와 source에 대조했다. 별도 새 browser 조합이나 독립 실행 기록을 필수 계약으로 추가하지 않는다. - 테스트 근거: tests/test_account_valuations.py, tests/test_asset_snapshots.py, tests/test_issue_12_regressions.py - 판정 근거: 현재 고정 source와 test assertion 및 변경 영향으로 승인 계약을 판정했다. 문서 또는 이전 verdict만으로 구현 충족을 추정하지 않는다. - `C16-supporting-evidence-scope` — `satisfied` - 계약: 모든 changed file은 승인된 기능과 필수 supporting change 또는 테스트 evidence로 설명되고 기존 requirement ID를 임의 갱신하거나 범위 밖 제품 및 설정을 변경하지 않는다. - 구현 근거: dashboard/app.py, dashboard/page_views/accounts.py, dashboard/page_views/assets.py, dashboard/page_views/monthly_settlement.py, docs/data-model.md, docs/interface-contract.md, docs/project-structure.md, docs/requirements/req-003_account-valuation-history.md, docs/runtime-flow.md, docs/verification/issue-12-review-60/contract-preservation-inventory.json, docs/verification/issue-12-review-60/evidence-manifest.json, docs/verification/issue-12-review-60/evidence-plan.json, docs/verification/issue-12-review-60/final-independent-review.json, docs/verification/issue-12-review-60/finding-matrix.json, docs/verification/issue-12-review-60/red-evidence.json, docs/verification/issue-12-review-61/contract-preservation-inventory.json, docs/verification/issue-12-review-61/evidence-manifest.json, docs/verification/issue-12-review-61/evidence-plan.json, docs/verification/issue-12-review-61/finding-matrix.json, docs/verification/issue-12-review-61/green-evidence.json, docs/verification/issue-12-review-61/red-evidence.json, docs/verification/issue-12-review-63/contract-preservation-inventory.json, docs/verification/issue-12-review-63/evidence-manifest.json, docs/verification/issue-12-review-63/evidence-plan.json, docs/verification/issue-12-review-63/finding-matrix.json, docs/verification/issue-12-review-63/red-evidence.json, docs/verification/issue-12-review-64/contract-preservation-inventory.json, docs/verification/issue-12-review-64/evidence-manifest.json, docs/verification/issue-12-review-64/evidence-plan.json, docs/verification/issue-12-review-64/finding-matrix.json, docs/verification/issue-12-review-64/red-evidence.json, docs/verification/issue-12-review-65/contract-preservation-inventory.json, docs/verification/issue-12-review-65/evidence-manifest.json, docs/verification/issue-12-review-65/evidence-plan.json, docs/verification/issue-12-review-65/finding-matrix.json, docs/verification/issue-12-review-65/red-evidence.json, jarca_ledger_mcp/adapters/mcp/server.py, jarca_ledger_mcp/adapters/mcp/tool_contracts.py, jarca_ledger_mcp/adapters/streamlit/accounts_gateway.py, jarca_ledger_mcp/adapters/streamlit/overview_gateway.py, jarca_ledger_mcp/application/__init__.py, jarca_ledger_mcp/application/account_valuation_service.py, jarca_ledger_mcp/application/accounts_write_services.py, jarca_ledger_mcp/application/assets_service.py, jarca_ledger_mcp/application/categorization_services.py, jarca_ledger_mcp/application/cross_transfer_service.py, jarca_ledger_mcp/application/imports_service.py, jarca_ledger_mcp/application/monthly_settlement_service.py, jarca_ledger_mcp/application/reconciliation_service.py, jarca_ledger_mcp/application/review_decision_service.py, jarca_ledger_mcp/application/shared.py, jarca_ledger_mcp/application/system_services.py, jarca_ledger_mcp/application/transaction_report_services.py, jarca_ledger_mcp/application/uncategorized_workbench_service.py, jarca_ledger_mcp/infrastructure/sqlite/__init__.py, jarca_ledger_mcp/infrastructure/sqlite/connection.py, jarca_ledger_mcp/infrastructure/sqlite/migrations.py, jarca_ledger_mcp/infrastructure/sqlite/schema.py, jarca_ledger_mcp/service.py, scripts/ci_fixture_db.py, tests/test_account_basis_public_consumers.py, tests/test_account_valuation_edge_contracts.py, tests/test_account_valuations.py, tests/test_asset_snapshot_idempotency.py, tests/test_asset_snapshots.py, tests/test_contract_regression.py, tests/test_dashboard_app.py, tests/test_dashboard_menu_transition.py, tests/test_import_current_balance_authority.py, tests/test_import_provenance_policy.py, tests/test_issue_12_regressions.py, tests/test_issue_12_review59_account.py, tests/test_issue_12_review59_readonly.py, tests/test_issue_12_review59_reports.py, tests/test_issue_12_review63_accounts.py, tests/test_issue_12_review63_assets.py, tests/test_ledger_categories.py, tests/test_requirement_docs.py, tests/test_review_decision_workbench.py, tests/test_seoulpay_xlsx.py, tests/test_service.py, tests/test_valuation_contract_docs.py; authoritative changed-file 82개와 local base-to-head tree가 일치한다. API diff 192개 hunk의 exact base/head blob 위치 및 내용 일치를 확인했다. Review65 head 이후 변경은 account create validator 및 대응 regression test와 supporting evidence 다섯 파일이다. create delta의 bool 및 float 및 비정수 검증은 기존 exact monetary/current-cache 계약 범위다. 문서 다섯 파일은 직전 reviewed head와 동일하고 REQ003 전체 baseline AC가 보존된다. 모든 changed file이 changed-file-coverage.json에서 기존 criterion 또는 supporting evidence로 연결된다. manifest의 모든 9개 blob OID와 SHA256, plan digest, ancestor 관계 및 전체 source-to-head diff를 검증했다. exact-head status는 pending이며 total_count 0이므로 CI 성공 근거로 사용하지 않는다. 구현자 evidence source f49568273e74b89dc3e83da21ce2ae12ed110543에서 현재 head까지 전체 변경은 evidence-manifest 한 파일이며 실행 입력은 동일하다. focused 65통과와 전체 288통과 및 4skip은 구현자 실행 근거이고 reviewer 독립 실행 또는 CI 결과가 아니다. - 테스트 근거: tests/test_account_valuations.py, tests/test_asset_snapshots.py, tests/test_contract_regression.py, tests/test_dashboard_app.py, tests/test_dashboard_menu_transition.py, tests/test_import_provenance_policy.py, tests/test_issue_12_regressions.py, tests/test_issue_12_review59_account.py, tests/test_issue_12_review59_readonly.py, tests/test_issue_12_review59_reports.py, tests/test_ledger_categories.py, tests/test_requirement_docs.py, tests/test_review_decision_workbench.py, tests/test_seoulpay_xlsx.py, tests/test_service.py - 판정 근거: 테스트와 supporting evidence의 추가는 승인 범위 안이다. JSON 경로나 추가 CI 및 browser 조합을 새 필수 산출물로 요구하지 않는다. ### 범위 판정 - 누락: C05 계좌 수정의 exact integer 및 NULL 의미 검증과 날짜 없는 빈 문자열 및 dated float/boolean 입력 무변경 실패 회귀 - 범위 초과: 없음 - 명세 모순: 없음 ### 결론 Review65 계좌 생성 경계 수정과 실제 0 및 후속 import 보존은 해소됐다. 문서 5종 및 다른 계약은 현재 source와 대응 근거에 충족한다. 계좌 수정 경로의 bool 및 float 금액 손실과 날짜 없는 빈 문자열 cache 저장이 승인된 C05 계약에 남아 request_changes다. 이 결함은 신규 create 변경이 도입한 회귀가 아니라 직전 head에도 있던 잔여 경계다. 제품 source는 변경하지 않았고 reviewer 제품 pytest 및 browser는 실행하지 않았다. 구현자 focused 65통과 및 전체 288통과와 4skip 근거는 실행 입력 동일성을 검증하여 재사용했으며 reviewer 실행이나 CI 성공으로 표현하지 않는다. <!-- gitea-agent:implementation-spec-review/v1 owner=jsfamily repository=jarca-ledger-mcp issue=12 pr=13 head=3bf9b77c6cc167a4e2a8706271bdf8e848d2c4fe contract-sha256=6d86b591b022fcc722611bfec6d24e54a64216ab6f7c4098f357e25420218818 result-sha256=f8c8543a4106e16b980b9babfb7c6895477f1d6c9fa0f262d99c6e605101cef9 correlation=b0479cba425ca7aa5b74bb31a28cc7e0e13b8a95971392bb99927b3814da1a4b -->
gitea-impl-agent added 3 commits 2026-10-07 22:27:07 +00:00
Author
Owner

구현 재작업 결과

지적 처리

  • C05-current-import-update — resolved
    • 분류: valid_fix
    • 변경: jarca_ledger_mcp/application/accounts_write_services.py, tests/test_import_current_balance_authority.py
    • 검증: named RED→GREEN; focused 68 passed; full 291 passed, 4 skipped, 1 warning
    • 근거: bool/float dated balances and undated empty-string balances are rejected before account/cache/valuation mutation
  • CP-001-valid-update-semantics — resolved
    • 분류: valid_fix
    • 변경: tests/test_import_current_balance_authority.py
    • 검증: zero, integer, signed integer text, historical/current authority adversarial coverage; exact-head independent gate PASS
    • 근거: strict validation preserves accepted exact-integer forms and existing append-only/current-cache authority semantics

최종 검증

  • Local checks: exact head 432e6f851a2623c5b12608cfa7636d3544225f28; focused pytest exit 0 (68 passed); full pytest exit 0 (291 passed, 4 skipped, 1 warning); Ruff, compileall, diff-check, canonical manifest validation and independent gate PASS
  • Runtime/browser: 해당 없음·미검증; Review #66 계약은 application write invariant이며 browser 변경 없음
  • Commit status: 없음
  • Actions runs: 없음

다음 단계

Reviewer가 rework head를 새 snapshot으로 다시 검토해야 하며 이 comment는 기존 REQUEST_CHANGES를 해제하거나 승인을 의미하지 않는다.

## 구현 재작업 결과 - Source Issue: #12 - Pull Request: #13 - Source Review: #66 - Reviewed head: `3bf9b77c6cc167a4e2a8706271bdf8e848d2c4fe` - Rework head: `432e6f851a2623c5b12608cfa7636d3544225f28` - Contract SHA-256: `6d86b591b022fcc722611bfec6d24e54a64216ab6f7c4098f357e25420218818` - Result: `rework_delivered` ### 지적 처리 - C05-current-import-update — `resolved` - 분류: valid_fix - 변경: jarca_ledger_mcp/application/accounts_write_services.py, tests/test_import_current_balance_authority.py - 검증: named RED→GREEN; focused 68 passed; full 291 passed, 4 skipped, 1 warning - 근거: bool/float dated balances and undated empty-string balances are rejected before account/cache/valuation mutation - CP-001-valid-update-semantics — `resolved` - 분류: valid_fix - 변경: tests/test_import_current_balance_authority.py - 검증: zero, integer, signed integer text, historical/current authority adversarial coverage; exact-head independent gate PASS - 근거: strict validation preserves accepted exact-integer forms and existing append-only/current-cache authority semantics ### 최종 검증 - Local checks: exact head 432e6f851a2623c5b12608cfa7636d3544225f28; focused pytest exit 0 (68 passed); full pytest exit 0 (291 passed, 4 skipped, 1 warning); Ruff, compileall, diff-check, canonical manifest validation and independent gate PASS - Runtime/browser: 해당 없음·미검증; Review #66 계약은 application write invariant이며 browser 변경 없음 - Commit status: 없음 - Actions runs: 없음 ### 다음 단계 Reviewer가 rework head를 새 snapshot으로 다시 검토해야 하며 이 comment는 기존 `REQUEST_CHANGES`를 해제하거나 승인을 의미하지 않는다. <!-- gitea-agent:implementation-rework/v1 owner=jsfamily repository=jarca-ledger-mcp issue=12 pr=13 review=66 reviewed-head=3bf9b77c6cc167a4e2a8706271bdf8e848d2c4fe head=432e6f851a2623c5b12608cfa7636d3544225f28 contract-sha256=6d86b591b022fcc722611bfec6d24e54a64216ab6f7c4098f357e25420218818 result-sha256=3d44f8f99c90897f9c093f64c506e7a56a31a54bc6c3935d48fb6400481cb2cf correlation=49ea236d46329bbfe8708ec9fd0105123db738461b6a4ccf000e4af2ae4e2c35 -->
gitea-spec-agent approved these changes 2026-10-07 23:54:44 +00:00
Dismissed
gitea-spec-agent left a comment
Owner

구현 명세 적합성 검토

Acceptance criteria 판정

  • C01-history — satisfied

    • 계약: 평가 계좌 FK, 기준일과 등록일, 대표 금액과 통화와 목적, 출처와 확인 상태, 증빙 식별자, 정정 연결과 사유 및 선택 시간 자료를 이력으로 보존한다.
    • 구현 근거: jarca_ledger_mcp/application/account_valuation_service.py, jarca_ledger_mcp/infrastructure/sqlite/schema.py, jarca_ledger_mcp/infrastructure/sqlite/migrations.py; account_valuation_service.py:133-257 register_account_valuation 및 :261-266 list_account_valuations; schema.py:229-267 및 migrations.py:157-173의 실제 필드와 FK와 unique 정의를 대조했다. tests/test_account_valuations.py:13-21의 schema12/idempotent 및 :24-32의 동일 기록 reuse와 payload conflict assertions를 확인했다. 구현자 evidence source 63fba3670c536824f91b59262d60240bdfb0db94에서 현재 head까지 전체 변경은 evidence-manifest 한 파일이며 실행 입력은 동일하다. focused 68통과와 전체 291통과 및 4skip과 1warning은 구현자 실행 근거이고 reviewer 독립 실행 또는 CI 결과가 아니다.
    • 테스트 근거: tests/test_account_valuations.py
    • 판정 근거: 현재 immutable source와 실제 named test의 호출 및 assertion을 승인된 Discovery에 직접 대응했다. 이전 승인 또는 구현자 PASS 주장만으로 충족을 상속하지 않으며 제품 pytest와 browser는 reviewer가 실행하지 않았다.
  • C02-money-metrics — satisfied

    • 계약: 금액 정밀도와 NULL 및 0을 보존하고 취득원가, 순납입액, 기관 표시 원금 금액과 정의 및 원문 명칭, 손익과 수익률의 계산 기준을 구분한다. 투자 대표 총평가액과 포함 현금 및 원금을 중복 합산하지 않는다.
    • 구현 근거: jarca_ledger_mcp/application/account_valuation_service.py, jarca_ledger_mcp/infrastructure/sqlite/schema.py, docs/data-model.md, docs/requirements/req-003_account-valuation-history.md; account_valuation_service.py:33-56의 strict integer/finite 검증, :165-186의 선택 지표와 NULL 보존, :247-249의 실제 roundtrip columns; schema.py:229-267의 INTEGER 및 선택 NULL 필드와 assets_service.py:453-499의 대표 금액 합산을 대조했다. test_valuation_round_trip_preserves_null_zero_and_physical_amount_mapping 및 test_correction_preserves_optional_fields_unless_overridden의 입력과 actual assertions를 확인했다. 구현자 evidence source 63fba3670c536824f91b59262d60240bdfb0db94에서 현재 head까지 전체 변경은 evidence-manifest 한 파일이며 실행 입력은 동일하다. focused 68통과와 전체 291통과 및 4skip과 1warning은 구현자 실행 근거이고 reviewer 독립 실행 또는 CI 결과가 아니다.
    • 테스트 근거: tests/test_issue_12_review59_account.py, tests/test_issue_12_regressions.py
    • 판정 근거: 현재 immutable source와 실제 named test의 호출 및 assertion을 승인된 Discovery에 직접 대응했다. 이전 승인 또는 구현자 PASS 주장만으로 충족을 상속하지 않으며 제품 pytest와 browser는 reviewer가 실행하지 않았다.
  • N01-loan-balance-definition — satisfied

    • 계약: 대출 평가 기록마다 대표 부채가 원금만인지 원금과 이자 및 수수료인지 필수로 명시하고 기본값으로 추정하지 않는다. 목적 alias가 필수 정의 계약을 우회하지 않는다.
    • 구현 근거: jarca_ledger_mcp/application/account_valuation_service.py, docs/requirements/req-003_account-valuation-history.md, jarca_ledger_mcp/application/accounts_write_services.py, jarca_ledger_mcp/application/imports_service.py, docs/data-model.md; account_valuation_service.py:93-105의 loan candidate 무추정 거부 및 :194-203의 loan alias와 종류 및 필수 정의 검증; accounts_write_services.py:81-89의 non-loan 전환 guard; imports_service.py:37-41의 candidate 호출을 대조했다. tests/test_account_valuation_edge_contracts.py:8-38, :41-76, :133-191은 계좌 유형 전환과 정의 누락 및 candidate/import 경로의 validation_error와 history/account 불변을 assertion한다. 구현자 evidence source 63fba3670c536824f91b59262d60240bdfb0db94에서 현재 head까지 전체 변경은 evidence-manifest 한 파일이며 실행 입력은 동일하다. focused 68통과와 전체 291통과 및 4skip과 1warning은 구현자 실행 근거이고 reviewer 독립 실행 또는 CI 결과가 아니다.
    • 테스트 근거: tests/test_issue_12_regressions.py, tests/test_issue_12_review59_account.py, tests/test_account_valuation_edge_contracts.py
    • 판정 근거: 현재 immutable source와 실제 named test의 호출 및 assertion을 승인된 Discovery에 직접 대응했다. 이전 승인 또는 구현자 PASS 주장만으로 충족을 상속하지 않으며 제품 pytest와 browser는 reviewer가 실행하지 않았다.
  • C03-selection — satisfied

    • 계약: 계좌와 통화 및 평가 목적별 유효 자료를 선택한다. exact는 당일 확인 자료만, as_of는 기준일 이하 최신 확인 자료만 사용한다. 미래 자료는 제외하고 미확인 후보는 확인 자료를 대체하거나 합산하지 않는다. 실제 기준일과 경과 일수 및 이월 상태를 반환한다.
    • 구현 근거: jarca_ledger_mcp/application/account_valuation_service.py, jarca_ledger_mcp/application/assets_service.py; account_valuation_service.py:270-312 select_account_valuation의 scope와 verified leaf, exact 및 latest-prior, candidate warning 및 age; assets_service.py:115-215와 :218-259의 계좌 및 기존 수기 selection과 미래/미확인/통화 제외를 대조했다. tests/test_account_valuations.py:35-45는 future와 unverified 제외 및 as-of carry와 actual date를 assertion한다. tests/test_issue_12_regressions.py의 scope 및 purpose와 unverified 합계 제외 regression을 함께 읽었다. 구현자 evidence source 63fba3670c536824f91b59262d60240bdfb0db94에서 현재 head까지 전체 변경은 evidence-manifest 한 파일이며 실행 입력은 동일하다. focused 68통과와 전체 291통과 및 4skip과 1warning은 구현자 실행 근거이고 reviewer 독립 실행 또는 CI 결과가 아니다.
    • 테스트 근거: tests/test_account_valuations.py, tests/test_issue_12_regressions.py
    • 판정 근거: 현재 immutable source와 실제 named test의 호출 및 assertion을 승인된 Discovery에 직접 대응했다. 이전 승인 또는 구현자 PASS 주장만으로 충족을 상속하지 않으며 제품 pytest와 browser는 reviewer가 실행하지 않았다.
  • C04-correction-validation — satisfied

    • 계약: 평가 정정은 append-only로 대상과 사유를 연결하며 다른 계좌, 통화, 목적을 참조하는 정정과 순환 및 동일 유효본의 동시 분기를 차단한다.
    • 구현 근거: jarca_ledger_mcp/application/account_valuation_service.py, jarca_ledger_mcp/infrastructure/sqlite/schema.py; account_valuation_service.py:204-224는 parent scope와 cyclic ancestry를 검증하고 :245-253은 단일 child unique 충돌을 fail-closed 처리한다. :315-375의 effective payload replay 및 changed conflict와 append-only 경계를 확인했다. tests/test_account_valuations.py:48-59는 원본 보존과 단일 correction count를 assertion하고 tests/test_account_valuation_edge_contracts.py:79-130은 동일 effective correction reuse 및 다른 payload conflict를 확인한다. 구현자 evidence source 63fba3670c536824f91b59262d60240bdfb0db94에서 현재 head까지 전체 변경은 evidence-manifest 한 파일이며 실행 입력은 동일하다. focused 68통과와 전체 291통과 및 4skip과 1warning은 구현자 실행 근거이고 reviewer 독립 실행 또는 CI 결과가 아니다.
    • 테스트 근거: tests/test_issue_12_review59_account.py, tests/test_account_valuations.py, tests/test_issue_12_regressions.py
    • 판정 근거: 현재 immutable source와 실제 named test의 호출 및 assertion을 승인된 Discovery에 직접 대응했다. 이전 승인 또는 구현자 PASS 주장만으로 충족을 상속하지 않으며 제품 pytest와 browser는 reviewer가 실행하지 않았다.
  • C05-current-import — satisfied

    • 계약: 뒤늦은 과거 자료 등록으로 최신 표시값을 과거로 되돌리지 않는다. 기존 계좌 수정과 import의 최신 캐시 및 새 이력 권위를 연결하며 동기화 시각을 실제 평가일로 오인하지 않는다.
    • 구현 근거: jarca_ledger_mcp/application/imports_service.py, jarca_ledger_mcp/application/assets_service.py, jarca_ledger_mcp/application/accounts_write_services.py; Review66 update 잔여 지적은 accounts_write_services.py:49-59의 strict integer 선행 검증으로 해소됐다. account_valuation_service.py:33-42는 boolean과 float 및 빈 문자열을 거부하고 정수와 signed integer text 및 0을 보존한다. update SQL 이전 :74에서 같은 normalized_balance를 cache에 사용하며 :93 및 :105-106은 dated candidate에도 같은 정확한 값을 전달한다. tests/test_import_current_balance_authority.py:124-146의 test_update_rejects_bool_or_float_dated_balance_without_mutation은 True 및 False와 1.2 및 -1.2가 validation_error이며 계좌와 valuation 목록을 바꾸지 않음을 assertion한다. :149-165의 test_update_rejects_empty_undated_balance_without_mutation은 날짜 없는 빈 문자열에 대해 같은 실패 및 불변을 assertion한다. :168-193의 test_update_preserves_zero_and_signed_integer_balance_semantics는 signed text 0 및 -12와 두 dated candidate 보존을 확인한다. :196-222의 test_zero_dated_balance_and_valid_import_recovery는 numeric0 및 유효 dated import를 보존한다. :92-100의 historical 비교와 undated 기준일 미상 처리 및 imports_service.py:43-49의 basis-date 비교는 source로 확인했고 기존 test_issue_12_review59_account의 세 historical import assertions도 확인했다. 구현자 evidence source 63fba3670c536824f91b59262d60240bdfb0db94에서 현재 head까지 전체 변경은 evidence-manifest 한 파일이며 실행 입력은 동일하다. focused 68통과와 전체 291통과 및 4skip과 1warning은 구현자 실행 근거이고 reviewer 독립 실행 또는 CI 결과가 아니다.
    • 테스트 근거: tests/test_issue_12_review59_account.py, tests/test_import_provenance_policy.py, tests/test_import_current_balance_authority.py, tests/test_account_basis_public_consumers.py, tests/test_issue_12_review63_accounts.py
    • 판정 근거: 빈 문자열을 cache에 저장하거나 bool 및 float를 정수로 강제 변환하는 경계는 mutation 이전 검증으로 닫혔다. 유효 0 및 signed integer, 뒤늦은 과거 자료와 현재 cache 분리, invalid input의 no-write named assertions가 승인 계약과 대응한다.
  • C06-idempotency — satisfied

    • 계약: 동일 증빙 또는 idempotency 재입력은 동일 기록을 재사용하며 같은 키의 다른 payload는 충돌이다. 동시 정정의 분기를 차단하고 UNIQUE 계좌 및 기준일 하나로 정정 추가를 막지 않는다.
    • 구현 근거: jarca_ledger_mcp/application/account_valuation_service.py, jarca_ledger_mcp/infrastructure/sqlite/schema.py, jarca_ledger_mcp/infrastructure/sqlite/migrations.py, jarca_ledger_mcp/application/accounts_write_services.py, jarca_ledger_mcp/application/imports_service.py; account_valuation_service.py:107-125의 candidate key payload, :225-244의 key와 source_ref 정본 및 unrelated scope conflict, :315-375의 explicit 및 keyless effective correction reuse; schema.py:264-267의 account-scoped key와 single-child index를 대조했다. tests/test_account_valuations.py:24-32 및 :72-80과 tests/test_account_valuation_edge_contracts.py:79-130, :194-231은 동일/변경 payload 및 correction와 candidate validation의 actual assertions를 제공한다. 구현자 evidence source 63fba3670c536824f91b59262d60240bdfb0db94에서 현재 head까지 전체 변경은 evidence-manifest 한 파일이며 실행 입력은 동일하다. focused 68통과와 전체 291통과 및 4skip과 1warning은 구현자 실행 근거이고 reviewer 독립 실행 또는 CI 결과가 아니다.
    • 테스트 근거: tests/test_issue_12_review59_account.py, tests/test_account_valuations.py, tests/test_issue_12_regressions.py, tests/test_account_valuation_edge_contracts.py
    • 판정 근거: 현재 immutable source와 실제 named test의 호출 및 assertion을 승인된 Discovery에 직접 대응했다. 이전 승인 또는 구현자 PASS 주장만으로 충족을 상속하지 않으며 제품 pytest와 browser는 reviewer가 실행하지 않았다.
  • C07-close-immutability — satisfied

    • 계약: 기존 asset_snapshots와 correction run을 보존하고 평가 정정 및 거래 추가로 기존 마감을 자동 변경하지 않는다. 동일 기준일 재마감은 사유와 이전 run 연결을 가진 새 버전을 원자적으로 추가한다.
    • 구현 근거: jarca_ledger_mcp/application/assets_service.py, jarca_ledger_mcp/infrastructure/sqlite/schema.py, jarca_ledger_mcp/infrastructure/sqlite/migrations.py; assets_service.py:717-752는 correction chain과 최신 correction authority를 검사하고 :757은 원래 existing run을 읽는다. unrelated live drift는 :800에서 idempotency_conflict다. tests/test_issue_12_review63_assets.py:97-138은 두 correction 이후 original equality와 unrelated asset drift conflict를 확인한다. 추가 evidence-array 검증은 :262-269 및 :297-320과 report/replay/timeseries의 오류 경계에 제한적으로 배치돼 정상 run 불변성을 변경하지 않는다. 구현자 evidence source 63fba3670c536824f91b59262d60240bdfb0db94에서 현재 head까지 전체 변경은 evidence-manifest 한 파일이며 실행 입력은 동일하다. focused 68통과와 전체 291통과 및 4skip과 1warning은 구현자 실행 근거이고 reviewer 독립 실행 또는 CI 결과가 아니다.
    • 테스트 근거: tests/test_asset_snapshots.py, tests/test_issue_12_regressions.py, tests/test_issue_12_review63_assets.py
    • 판정 근거: 현재 immutable source와 실제 named test의 호출 및 assertion을 승인된 Discovery에 직접 대응했다. 이전 승인 또는 구현자 PASS 주장만으로 충족을 상속하지 않으며 제품 pytest와 browser는 reviewer가 실행하지 않았다.
  • N02-close-replay-run-binding — satisfied

    • 계약: 마감 버전의 근거는 불변이며 동일 idempotency 요청은 원래 기록을 재사용한다. 재마감으로 과거 run 응답 및 evidence를 변경하지 않는다.
    • 구현 근거: jarca_ledger_mcp/application/assets_service.py, docs/interface-contract.md; F002 해소. assets_service.py:842-860은 included unverified_candidates와 excluded candidate의 blocking 및 state_hash를 저장한다. :383-398은 blocking=False를 복원하고 :757-799는 exact existing run에서 원래 응답을 구성한다. tests/test_asset_snapshot_idempotency.py:9-64의 test_replay_preserves_redacted_unverified_candidates_after_correction은 후보 allowlist와 blocking=False 및 전체 replay==first와 row/run count 불변을 assertion한다. :67-96의 test_replay_preserves_blocking_candidate_warning_shape은 차단 warning의 blocking 키 부재와 최초 응답 equality를 확인한다. 기존 mixed-asof 및 correction-chain equality 테스트도 보존된다. 구현자 evidence source 63fba3670c536824f91b59262d60240bdfb0db94에서 현재 head까지 전체 변경은 evidence-manifest 한 파일이며 실행 입력은 동일하다. focused 68통과와 전체 291통과 및 4skip과 1warning은 구현자 실행 근거이고 reviewer 독립 실행 또는 CI 결과가 아니다.
    • 테스트 근거: tests/test_issue_12_review59_reports.py, tests/test_issue_12_regressions.py, tests/test_asset_snapshot_idempotency.py, tests/test_issue_12_review63_assets.py
    • 판정 근거: 현재 immutable source와 실제 named test의 호출 및 assertion을 승인된 Discovery에 직접 대응했다. 이전 승인 또는 구현자 PASS 주장만으로 충족을 상속하지 않으며 제품 pytest와 browser는 reviewer가 실행하지 않았다.
  • C08-approved-conditional — satisfied

    • 계약: 완전한 exact 마감, 미완료 초안, 별도 승인된 조건부 마감을 구분한다. 승인 전 누락 및 이월은 미완료 초안이고 승인 후에도 누락 제외 및 확인된 과거값 이월만 허용한다. 미확인, 미래, 기준일 미상 금액은 승인으로도 합산하지 않으며 적용과 제외와 이월 및 승인자와 시각과 사유와 근거를 고정한다.
    • 구현 근거: jarca_ledger_mcp/application/assets_service.py, jarca_ledger_mcp/infrastructure/sqlite/schema.py, dashboard/page_views/assets.py; assets_service.py:646-671 및 :684-709은 public redaction 이전 동일 preview fingerprint와 승인 경계를 확인한다. 기존 test_f001_preview_fingerprint_uses_same_unredacted_authority_and_rejects_drift의 :17-41은 unchanged handoff 성공과 drift 거부 및 run 불변을 assertion한다. 미확인 candidate는 합산하지 않으며 nonblocking 후보는 conditional 승인 대상으로 오인하지 않는다. 승인자와 시각 및 사유와 참조, 적용과 제외와 이월은 :842-864에 원자적으로 저장한다. 구현자 evidence source 63fba3670c536824f91b59262d60240bdfb0db94에서 현재 head까지 전체 변경은 evidence-manifest 한 파일이며 실행 입력은 동일하다. focused 68통과와 전체 291통과 및 4skip과 1warning은 구현자 실행 근거이고 reviewer 독립 실행 또는 CI 결과가 아니다.
    • 테스트 근거: tests/test_issue_12_review59_reports.py, tests/test_issue_12_regressions.py, tests/test_asset_snapshots.py, tests/test_issue_12_review63_assets.py
    • 판정 근거: 현재 immutable source와 실제 named test의 호출 및 assertion을 승인된 Discovery에 직접 대응했다. 이전 승인 또는 구현자 PASS 주장만으로 충족을 상속하지 않으며 제품 pytest와 browser는 reviewer가 실행하지 않았다.
  • C09-reconciliation — satisfied

    • 계약: 외부 확인값과 장부 계산값을 분리하고 검증된 시작잔고, 기준시점, 거래 포함 범위와 계산 완전성을 표시한다. 거래 없는 수동 투자 계좌의 대사 불가 및 거래 미수입과 평가 수동 관리 상태를 구분하고 가짜 거래를 만들지 않는다. 대사도 공통 평가 근거와 대출 대표 정의를 사용한다.
    • 구현 근거: jarca_ledger_mcp/application/reconciliation_service.py, jarca_ledger_mcp/application/account_valuation_service.py, jarca_ledger_mcp/application/monthly_settlement_service.py; reconciliation_service.py:31-64 _account_balance_row는 시작 근거 및 거래 coverage를 분리하고 :102-158은 verified corrected leaf와 목적 및 대출 정의를 선택한다. :159-213은 계산 불완전 및 수동 투자 평가 관리와 대사 불가 상태를 provenance로 전달한다. monthly_settlement_service.py의 get_monthly_settlement_summary는 공통 report를 읽으며 tests/test_issue_12_review59_reports.py 및 tests/test_issue_12_regressions.py의 no-fake-transaction와 corrected-investment 및 unavailable assertions에 대응한다. 구현자 evidence source 63fba3670c536824f91b59262d60240bdfb0db94에서 현재 head까지 전체 변경은 evidence-manifest 한 파일이며 실행 입력은 동일하다. focused 68통과와 전체 291통과 및 4skip과 1warning은 구현자 실행 근거이고 reviewer 독립 실행 또는 CI 결과가 아니다.
    • 테스트 근거: tests/test_issue_12_review59_reports.py, tests/test_issue_12_regressions.py, tests/test_service.py
    • 판정 근거: 현재 immutable source와 실제 named test의 호출 및 assertion을 승인된 Discovery에 직접 대응했다. 이전 승인 또는 구현자 PASS 주장만으로 충족을 상속하지 않으며 제품 pytest와 browser는 reviewer가 실행하지 않았다.
  • C10-report-monthly-evidence — satisfied

    • 계약: MCP와 Dashboard 및 월정산 보고에서 같은 기준일과 선택 근거 및 실제 평가일, 경과 일수, 확인 상태, 누락과 미확인 및 이월 경고, 마감 버전 및 조건부 승인 근거를 일관되게 전달한다.
    • 구현 근거: jarca_ledger_mcp/application/assets_service.py, jarca_ledger_mcp/application/monthly_settlement_service.py, dashboard/page_views/monthly_settlement.py, dashboard/page_views/accounts.py; assets_service.py:335-380은 frozen valuation_id와 currency 및 실제 basis를 복원한다. :948-984는 frozen run을 정본으로 보고하고 :1049-1102는 zero-row run 날짜를 UNION으로 포함해 latest run의 승인 및 provenance를 전달한다. tests/test_issue_12_review63_assets.py:141-206은 zero-row 정정 run 및 alias, frozen ID와 currency 및 legacy ID 비추론을 assertion한다. monthly_settlement_service.py는 해당 공통 report를 읽는다. malformed JSON 배열 guard의 신규 test는 tests/test_asset_snapshot_idempotency.py:99-128이며 report/replay/timeseries 실패 및 row/run 불변을 확인한다. 임의 DB 손상 전체의 복구나 추가 오류명은 새 인수 조건으로 만들지 않는다. 구현자 evidence source 63fba3670c536824f91b59262d60240bdfb0db94에서 현재 head까지 전체 변경은 evidence-manifest 한 파일이며 실행 입력은 동일하다. focused 68통과와 전체 291통과 및 4skip과 1warning은 구현자 실행 근거이고 reviewer 독립 실행 또는 CI 결과가 아니다.
    • 테스트 근거: tests/test_issue_12_review59_reports.py, tests/test_issue_12_regressions.py, tests/test_service.py, tests/test_issue_12_review63_assets.py
    • 판정 근거: 현재 immutable source와 실제 named test의 호출 및 assertion을 승인된 Discovery에 직접 대응했다. 이전 승인 또는 구현자 PASS 주장만으로 충족을 상속하지 않으며 제품 pytest와 browser는 reviewer가 실행하지 않았다.
  • C11-adapter-structure — satisfied

    • 계약: MCP와 Streamlit gateway는 공통 application을 사용하고 기존 공개 호출명과 기존 인수 및 success와 실패 error_code 및 error envelope를 가능한 한 유지한다. 새 Dashboard 인증 또는 MCP 인증을 도입하지 않는다.
    • 구현 근거: jarca_ledger_mcp/adapters/mcp/server.py, jarca_ledger_mcp/adapters/mcp/tool_contracts.py, jarca_ledger_mcp/adapters/streamlit/accounts_gateway.py, jarca_ledger_mcp/application/__init__.py, jarca_ledger_mcp/service.py, dashboard/page_views/accounts.py, dashboard/page_views/assets.py, dashboard/page_views/monthly_settlement.py; service.py:50-70의 호환 facade와 application/asset_account_services.py:3-15의 공통 export, adapters/mcp/server.py의 create/register/select/correct/preview/close tools와 adapters/streamlit/accounts_gateway.py 및 overview_gateway.py의 shared-service delegate를 대조했다. dashboard/page_views/accounts.py 및 assets.py와 monthly_settlement.py는 shared gateway 결과를 렌더링하고 명시적 submit에서만 writer를 호출한다. tests/test_contract_regression.py와 tests/test_issue_12_regressions.py의 공개 signature/envelope 및 read-only assertions는 보존된다. 구현자 evidence source 63fba3670c536824f91b59262d60240bdfb0db94에서 현재 head까지 전체 변경은 evidence-manifest 한 파일이며 실행 입력은 동일하다. focused 68통과와 전체 291통과 및 4skip과 1warning은 구현자 실행 근거이고 reviewer 독립 실행 또는 CI 결과가 아니다.
    • 테스트 근거: tests/test_contract_regression.py, tests/test_issue_12_regressions.py
    • 판정 근거: 현재 immutable source와 실제 named test의 호출 및 assertion을 승인된 Discovery에 직접 대응했다. 이전 승인 또는 구현자 PASS 주장만으로 충족을 상속하지 않으며 제품 pytest와 browser는 reviewer가 실행하지 않았다.
  • C12-migration-legacy — satisfied

    • 계약: schema 11의 기존 데이터와 마감 및 개인정보를 보존하고 additive하고 idempotent한 migration을 제공한다. 기준일 증거 없는 값을 임의 월말로 소급하거나 legacy snapshot에 valuation_id를 추측하여 생성하지 않는다.
    • 구현 근거: jarca_ledger_mcp/infrastructure/sqlite/schema.py, jarca_ledger_mcp/infrastructure/sqlite/migrations.py, jarca_ledger_mcp/application/assets_service.py; migrations.py:19-173의 additive CREATE/ADD COLUMN과 unique 및 schema12 상태; assets_service.py:335-380의 frozen evidence와 legacy valuation_id 비추론을 대조했다. test_account_valuation_schema_is_v12_and_idempotent 및 test_schema12_migration_preserves_legacy_rows_indexes_and_is_idempotent는 기존 rows와 재호출 idempotency를 검사하고 tests/test_issue_12_review63_assets.py:199-206은 legacy ID가 생성되지 않음을 assertion한다. 구현자 evidence source 63fba3670c536824f91b59262d60240bdfb0db94에서 현재 head까지 전체 변경은 evidence-manifest 한 파일이며 실행 입력은 동일하다. focused 68통과와 전체 291통과 및 4skip과 1warning은 구현자 실행 근거이고 reviewer 독립 실행 또는 CI 결과가 아니다.
    • 테스트 근거: tests/test_account_valuations.py, tests/test_issue_12_regressions.py, tests/test_ledger_categories.py, tests/test_review_decision_workbench.py
    • 판정 근거: 현재 immutable source와 실제 named test의 호출 및 assertion을 승인된 Discovery에 직접 대응했다. 이전 승인 또는 구현자 PASS 주장만으로 충족을 상속하지 않으며 제품 pytest와 browser는 reviewer가 실행하지 않았다.
  • C13-read-only — satisfied

    • 계약: preview와 조회 및 Dashboard 렌더링은 금융 쓰기를 실행하지 않는다. 명시적 등록, 정정, 승인 close 및 import 제출만 변경을 수행하고 실패 시 부분 쓰기를 남기지 않는다.
    • 구현 근거: jarca_ledger_mcp/infrastructure/sqlite/connection.py, jarca_ledger_mcp/application/shared.py, jarca_ledger_mcp/application/system_services.py, jarca_ledger_mcp/application/account_valuation_service.py, jarca_ledger_mcp/application/assets_service.py; connection.py:31-53 connect_readonly/read_db의 mode=ro와 no-init, shared.py:128-138의 read 오류 envelope; assets_service.py:646-671의 preview와 :939-1138의 report/time-series/liquidity read, account_valuation_service.py:260-312의 read selector를 대조했다. tests/test_issue_12_review59_readonly.py는 missing DB no-path-create와 initialized DB schema/rows 불변을 검사하고 explicit writer는 connection.py:56-69에서만 init와 commit을 수행한다. 구현자 evidence source 63fba3670c536824f91b59262d60240bdfb0db94에서 현재 head까지 전체 변경은 evidence-manifest 한 파일이며 실행 입력은 동일하다. focused 68통과와 전체 291통과 및 4skip과 1warning은 구현자 실행 근거이고 reviewer 독립 실행 또는 CI 결과가 아니다.
    • 테스트 근거: tests/test_issue_12_review59_readonly.py, tests/test_dashboard_app.py, tests/test_dashboard_menu_transition.py
    • 판정 근거: 현재 immutable source와 실제 named test의 호출 및 assertion을 승인된 Discovery에 직접 대응했다. 이전 승인 또는 구현자 PASS 주장만으로 충족을 상속하지 않으며 제품 pytest와 browser는 reviewer가 실행하지 않았다.
  • C14-auth-menu-preservation — satisfied

    • 계약: Dashboard 인증은 DB보다 먼저이며 REQ-001의 cookie와 logout 및 REQ-002의 메뉴 label과 order, shell, query, error와 retry 및 명시적 금융 쓰기 계약을 유지한다.
    • 구현 근거: dashboard/app.py, dashboard/page_views/accounts.py, dashboard/page_views/assets.py, dashboard/page_views/monthly_settlement.py, docs/interface-contract.md, docs/project-structure.md, docs/runtime-flow.md; dashboard/app.py:37-72의 auth-before-financial-dispatch와 gateway read boundary, 기존 dashboard authentication/menu 관련 source 및 tests는 직전 head와 byte-identical하다. docs/interface-contract.md:1-261 및 docs/project-structure.md와 docs/runtime-flow.md의 기존 auth/cookie/logout와 canonical menu order 및 shell/query 내용이 보존된다. tests/test_dashboard_menu_transition.py 및 tests/test_dashboard_app.py의 actual authentication/menu/no-write assertions와 전체 구현자 regression 보고를 대응했다. 구현자 evidence source 63fba3670c536824f91b59262d60240bdfb0db94에서 현재 head까지 전체 변경은 evidence-manifest 한 파일이며 실행 입력은 동일하다. focused 68통과와 전체 291통과 및 4skip과 1warning은 구현자 실행 근거이고 reviewer 독립 실행 또는 CI 결과가 아니다.
    • 테스트 근거: tests/test_dashboard_menu_transition.py, tests/test_dashboard_app.py
    • 판정 근거: 현재 immutable source와 실제 named test의 호출 및 assertion을 승인된 Discovery에 직접 대응했다. 이전 승인 또는 구현자 PASS 주장만으로 충족을 상속하지 않으며 제품 pytest와 browser는 reviewer가 실행하지 않았다.
  • C15-exclusions-privacy — satisfied

    • 계약: 증권사 자동 연동, 정확한 성과 또는 환율 엔진, 새 인증, 별도 월정산 제품, 거래 추론 및 기존 데이터 자동 재작성과 수기 비계좌 자산 전체 이력 재설계를 추가하지 않는다. 실제 계좌 및 금융 증빙과 credential을 로그와 문서 및 테스트에 기록하지 않는다.
    • 구현 근거: jarca_ledger_mcp/application/assets_service.py, jarca_ledger_mcp/application/account_valuation_service.py, jarca_ledger_mcp/application/imports_service.py, jarca_ledger_mcp/application/reconciliation_service.py, jarca_ledger_mcp/infrastructure/sqlite/schema.py, jarca_ledger_mcp/infrastructure/sqlite/migrations.py; assets_service.py:62-75 _public_evidence 및 :94-112의 민감 source state는 digest로만 공개하고 :383-408의 closed metadata는 strict allowlist를 사용한다. account_valuation_service.py:29-30의 public candidate는 ID/date/currency/purpose/status만 반환한다. tests/test_asset_snapshot_idempotency.py:26-42는 redacted candidate와 state hash 및 비차단 warning shape를 assertion한다. changed-file 전체는 기존 금융 이력 및 마감과 read-only 보완 및 supporting tests/docs이며 외부 FX/가격/auth/성과 엔진이나 기존 데이터 재작성은 없다. 구현자 evidence source 63fba3670c536824f91b59262d60240bdfb0db94에서 현재 head까지 전체 변경은 evidence-manifest 한 파일이며 실행 입력은 동일하다. focused 68통과와 전체 291통과 및 4skip과 1warning은 구현자 실행 근거이고 reviewer 독립 실행 또는 CI 결과가 아니다.
    • 테스트 근거: tests/test_issue_12_review59_reports.py, tests/test_issue_12_regressions.py, scripts/ci_fixture_db.py
    • 판정 근거: 현재 immutable source와 실제 named test의 호출 및 assertion을 승인된 Discovery에 직접 대응했다. 이전 승인 또는 구현자 PASS 주장만으로 충족을 상속하지 않으며 제품 pytest와 browser는 reviewer가 실행하지 않았다.
  • D01-requirement-structure — satisfied

    • 계약: 신규 REQ-003을 배정 경로와 제목으로 작성하며 trusted harness README와 TEMPLATE의 JSON metadata, 연속 요구사항 및 AC, 필수 섹션, 판정 기준과 검증 및 검증 분류의 수준과 백엔드와 케이스 및 상태 불변조건을 충족한다. 초기 PR은 미정이며 PR 생성 후 실제 번호를 추적한다.
    • 구현 근거: docs/requirements/req-003_account-valuation-history.md; REQ-003의 JSON metadata docs/requirements/req-003_account-valuation-history.md:1-16, 연속 요구사항 :51-185 및 AC :187-297, 필수 오류와 계약과 호환성과 추적성 :299-317을 trusted harness README 및 TEMPLATE에 대조했다. Issue12와 실제 구현 PR13의 lifecycle traceability는 유효하다. 전체 문서와 이전 reviewed-head baseline은 byte-identical하다. 실제 tests/test_requirement_docs.py의 marker와 signature 및 named test 존재 assertion을 읽었다.
    • 테스트 근거: tests/test_requirement_docs.py
    • 판정 근거: 현재 immutable source와 실제 named test의 호출 및 assertion을 승인된 Discovery에 직접 대응했다. 이전 승인 또는 구현자 PASS 주장만으로 충족을 상속하지 않으며 제품 pytest와 browser는 reviewer가 실행하지 않았다.
  • D02-requirement-semantics — satisfied

    • 계약: 요구사항에는 평가 근거와 지표 정의, 선택과 future 제외, 정정 및 idempotency 충돌, 대사 완전성, current 및 import 연계, 마감 상태와 불변성과 승인, shared adapter 및 인증, migration과 legacy를 소스 및 테스트에 대응한다. 모든 승인된 경계와 회귀 사례를 인수 기준으로 내린다.
    • 구현 근거: docs/requirements/req-003_account-valuation-history.md; docs/requirements/req-003_account-valuation-history.md:53-185의 10개 요구사항과 :189-297의 전체 AC를 Discovery의 모든 포함 범위와 확정 결정 및 제외 범위에 대조했다. 이전 REQ-003 전체 AC와 byte-identical하여 의미 삭제나 승인 없는 축소가 없다. 참조된 tests와 actual implementation은 head에서 존재한다. current-cache 구현과 Review66 finding closure는 C05에서 검토하며 문서 반복 부재나 evidence JSON 형식을 새로운 의무로 판단하지 않는다.
    • 테스트 근거: tests/test_account_valuations.py, tests/test_asset_snapshots.py, tests/test_issue_12_regressions.py, tests/test_requirement_docs.py, tests/test_mcp_http_runtime.py, tests/test_dashboard_authentication_app.py
    • 판정 근거: 현재 immutable source와 실제 named test의 호출 및 assertion을 승인된 Discovery에 직접 대응했다. 이전 승인 또는 구현자 PASS 주장만으로 충족을 상속하지 않으며 제품 pytest와 browser는 reviewer가 실행하지 않았다.
  • D03-data-model — satisfied

    • 계약: 신규 데이터 모델은 기존 entities 및 valuation과 마감의 관계, FK와 날짜 및 정확한 금액과 NULL 및 0과 선택 지표 및 대출 필수 정의, 계좌와 통화 및 목적과 기준일의 선택 및 index와 단일 유효 정정본, 고정 적용 분류 및 출처와 상태와 누락 및 이월 및 승인 버전, 분리된 정정과 schema11 이관 및 미상 날짜와 legacy 및 최신 캐시 동기화 책임을 정의한다.
    • 구현 근거: docs/data-model.md; docs/data-model.md:63-68은 account 필수와 currency 및 valuation purpose 선택 필터, basis-date exact 또는 upper-bound, verified leaf와 future 및 unverified 제외를 명시한다. account_date와 status_date 인덱스의 coverage 및 account-currency-purpose 전체를 덮지 않는 한계, idempotency 및 single_correction의 write integrity 책임을 구분한다. account_valuation_service.py:270-312의 실제 선택과 schema.py:264-267 및 migrations.py:169-172의 물리 정의에 대응한다. test_data_model_documents_valuation_selection_contract_and_index_mapping의 tests/test_valuation_contract_docs.py:46-62는 이 설명을 assertion한다. 나머지 entity 관계와 금액 NULL0 및 대출 정의, immutable run과 migration 및 legacy와 캐시 책임은 문서 :12-61 및 :70-176에 보존된다.
    • 테스트 근거: tests/test_account_valuations.py, tests/test_asset_snapshots.py, tests/test_issue_12_regressions.py, tests/test_valuation_contract_docs.py
    • 판정 근거: 현재 immutable source와 실제 named test의 호출 및 assertion을 승인된 Discovery에 직접 대응했다. 이전 승인 또는 구현자 PASS 주장만으로 충족을 상속하지 않으며 제품 pytest와 browser는 reviewer가 실행하지 않았다.
  • D04-interface-contract — satisfied

    • 계약: 인터페이스 문서는 기존 auth 및 메뉴를 보존하고 평가 등록 및 조회 및 정정의 모든 입력과 유효본 및 원금 정의 출력, report 및 preview/close 및 월정산과 대사와 current API의 공통 선택, exact 기본과 실제 날짜 및 age 및 이월과 누락 및 미확인과 출처 및 버전과 승인 출력을 정의한다. 잘못된 입력과 scope 및 충돌과 부족 근거는 무변경 실패이며 기존 envelope와 required keys 및 의미 변경 정책을 명시한다.
    • 구현 근거: docs/interface-contract.md, docs/data-model.md; docs/interface-contract.md:1-261 기존 auth와 menu 보존; :263-358 valuation와 close 입력 및 오류와 무변경; :401-423 실제 signature와 persisted fields; :425-435 close 및 provenance aliases, preview fingerprint, equality replay와 recursive redaction을 승인 의무에 대조했다. 전체 문서는 이전 reviewed head와 동일하고 current source의 signature 및 enums와 대응한다.
    • 테스트 근거: tests/test_account_valuations.py, tests/test_issue_12_regressions.py, tests/test_contract_regression.py, tests/test_valuation_contract_docs.py, tests/test_issue_12_review59_account.py
    • 판정 근거: 현재 immutable source와 실제 named test의 호출 및 assertion을 승인된 Discovery에 직접 대응했다. 이전 승인 또는 구현자 PASS 주장만으로 충족을 상속하지 않으며 제품 pytest와 browser는 reviewer가 실행하지 않았다.
  • D05-project-structure — satisfied

    • 계약: 프로젝트 구조 문서는 기존 source와 test 및 evidence를 보존하고 SQLite schema와 migrations, application의 assets와 account writes 및 import와 reconciliation 및 monthly 책임, 공개 facade와 MCP 및 Streamlit과 기존 세 화면 및 tests를 exact 경로로 대응한다. adapter에서 선택 정책을 복제하지 않고 대출 정의와 verified as_of 및 conditional 승인 경계를 shared application에 배치한다.
    • 구현 근거: docs/project-structure.md; docs/project-structure.md:122-164의 source/test/docs 배치와 application 및 SQLite 및 adapter 의존, :166-212의 auth/menu inventory와 actual module ownership 및 monthly/reconciliation/read-only/privacy 경계를 모든 문서 의무와 current paths에 대조했다. 선택 정책을 adapter에 복제하지 않으며 별도 제품이나 마감 엔진이 없다.
    • 테스트 근거: tests/test_requirement_docs.py
    • 판정 근거: 현재 immutable source와 실제 named test의 호출 및 assertion을 승인된 Discovery에 직접 대응했다. 이전 승인 또는 구현자 PASS 주장만으로 충족을 상속하지 않으며 제품 pytest와 browser는 reviewer가 실행하지 않았다.
  • D06-runtime-flow — satisfied

    • 계약: 런타임 문서는 auth 및 메뉴를 보존하고 register/correct의 증빙 및 scope 검증과 append 및 유효본 확인 및 최신 캐시 동기화를 단일 트랜잭션으로 설명한다. 날짜 및 정책과 통화 및 대표 합산과 경고 read, preview 후 명시적 approval 및 원자적 freeze, reasoned reclose, 같은 근거의 monthly 및 대사, import와 이관 trigger 및 실패복구, retry와 concurrency 및 preview drift 재검증과 무부분쓰기, 비민감 valuation/run 상관 신호를 정의한다.
    • 구현 근거: docs/runtime-flow.md; docs/runtime-flow.md:147-185의 register/select/correct, preview/approval/atomic freeze, import와 monthly 및 reconciliation propagation; :187-210의 failure/retry/concurrency/비민감 signals; :221-241의 실제 transition와 DB boundary 및 fingerprint drift와 no-write 및 immutable replay를 승인 의무와 source에 대조했다. 별도 새 browser 조합이나 독립 실행 기록을 필수 계약으로 추가하지 않는다.
    • 테스트 근거: tests/test_account_valuations.py, tests/test_asset_snapshots.py, tests/test_issue_12_regressions.py
    • 판정 근거: 현재 immutable source와 실제 named test의 호출 및 assertion을 승인된 Discovery에 직접 대응했다. 이전 승인 또는 구현자 PASS 주장만으로 충족을 상속하지 않으며 제품 pytest와 browser는 reviewer가 실행하지 않았다.
  • C16-supporting-evidence-scope — satisfied

    • 계약: 모든 changed file은 승인된 기능과 필수 supporting change 또는 테스트 evidence로 설명되고 기존 requirement ID를 임의 갱신하거나 범위 밖 제품 및 설정을 변경하지 않는다.
    • 구현 근거: dashboard/app.py, dashboard/page_views/accounts.py, dashboard/page_views/assets.py, dashboard/page_views/monthly_settlement.py, docs/data-model.md, docs/interface-contract.md, docs/project-structure.md, docs/requirements/req-003_account-valuation-history.md, docs/runtime-flow.md, docs/verification/issue-12-review-60/contract-preservation-inventory.json, docs/verification/issue-12-review-60/evidence-manifest.json, docs/verification/issue-12-review-60/evidence-plan.json, docs/verification/issue-12-review-60/final-independent-review.json, docs/verification/issue-12-review-60/finding-matrix.json, docs/verification/issue-12-review-60/red-evidence.json, docs/verification/issue-12-review-61/contract-preservation-inventory.json, docs/verification/issue-12-review-61/evidence-manifest.json, docs/verification/issue-12-review-61/evidence-plan.json, docs/verification/issue-12-review-61/finding-matrix.json, docs/verification/issue-12-review-61/green-evidence.json, docs/verification/issue-12-review-61/red-evidence.json, docs/verification/issue-12-review-63/contract-preservation-inventory.json, docs/verification/issue-12-review-63/evidence-manifest.json, docs/verification/issue-12-review-63/evidence-plan.json, docs/verification/issue-12-review-63/finding-matrix.json, docs/verification/issue-12-review-63/red-evidence.json, docs/verification/issue-12-review-64/contract-preservation-inventory.json, docs/verification/issue-12-review-64/evidence-manifest.json, docs/verification/issue-12-review-64/evidence-plan.json, docs/verification/issue-12-review-64/finding-matrix.json, docs/verification/issue-12-review-64/red-evidence.json, docs/verification/issue-12-review-65/contract-preservation-inventory.json, docs/verification/issue-12-review-65/evidence-manifest.json, docs/verification/issue-12-review-65/evidence-plan.json, docs/verification/issue-12-review-65/finding-matrix.json, docs/verification/issue-12-review-65/red-evidence.json, docs/verification/issue-12-review-66/contract-preservation-inventory.json, docs/verification/issue-12-review-66/evidence-manifest.json, docs/verification/issue-12-review-66/evidence-plan.json, docs/verification/issue-12-review-66/finding-matrix.json, docs/verification/issue-12-review-66/red-evidence.json, jarca_ledger_mcp/adapters/mcp/server.py, jarca_ledger_mcp/adapters/mcp/tool_contracts.py, jarca_ledger_mcp/adapters/streamlit/accounts_gateway.py, jarca_ledger_mcp/adapters/streamlit/overview_gateway.py, jarca_ledger_mcp/application/__init_.py, jarca_ledger_mcp/application/account_valuation_service.py, jarca_ledger_mcp/application/accounts_write_services.py, jarca_ledger_mcp/application/assets_service.py, jarca_ledger_mcp/application/categorization_services.py, jarca_ledger_mcp/application/cross_transfer_service.py, jarca_ledger_mcp/application/imports_service.py, jarca_ledger_mcp/application/monthly_settlement_service.py, jarca_ledger_mcp/application/reconciliation_service.py, jarca_ledger_mcp/application/review_decision_service.py, jarca_ledger_mcp/application/shared.py, jarca_ledger_mcp/application/system_services.py, jarca_ledger_mcp/application/transaction_report_services.py, jarca_ledger_mcp/application/uncategorized_workbench_service.py, jarca_ledger_mcp/infrastructure/sqlite/__init_.py, jarca_ledger_mcp/infrastructure/sqlite/connection.py, jarca_ledger_mcp/infrastructure/sqlite/migrations.py, jarca_ledger_mcp/infrastructure/sqlite/schema.py, jarca_ledger_mcp/service.py, scripts/ci_fixture_db.py, tests/test_account_basis_public_consumers.py, tests/test_account_valuation_edge_contracts.py, tests/test_account_valuations.py, tests/test_asset_snapshot_idempotency.py, tests/test_asset_snapshots.py, tests/test_contract_regression.py, tests/test_dashboard_app.py, tests/test_dashboard_menu_transition.py, tests/test_import_current_balance_authority.py, tests/test_import_provenance_policy.py, tests/test_issue_12_regressions.py, tests/test_issue_12_review59_account.py, tests/test_issue_12_review59_readonly.py, tests/test_issue_12_review59_reports.py, tests/test_issue_12_review63_accounts.py, tests/test_issue_12_review63_assets.py, tests/test_ledger_categories.py, tests/test_requirement_docs.py, tests/test_review_decision_workbench.py, tests/test_seoulpay_xlsx.py, tests/test_service.py, tests/test_valuation_contract_docs.py; authoritative changed-file 87개와 local base-to-head tree가 일치하고 API diff 197개 hunk의 exact base/head blob 위치 및 내용 일치를 확인했다. Review66 head 이후 변경은 account update validator 및 대응 regression test와 supporting evidence 다섯 파일이다. bool 및 float와 빈 문자열 검증은 기존 exact monetary/current-cache 계약 범위다. 문서 다섯 파일은 직전 reviewed head와 동일하고 REQ003 전체 baseline AC가 보존된다. 모든 changed file은 changed-file-coverage.json에서 기존 criterion 또는 supporting evidence로 연결된다. manifest의 모든 11개 blob OID와 SHA256, plan digest, ancestor 관계 및 전체 source-to-head diff를 검증했다. exact-head status는 pending이며 total_count 0이므로 CI 성공 근거로 사용하지 않는다. 구현자 evidence source 63fba3670c536824f91b59262d60240bdfb0db94에서 현재 head까지 전체 변경은 evidence-manifest 한 파일이며 실행 입력은 동일하다. focused 68통과와 전체 291통과 및 4skip과 1warning은 구현자 실행 근거이고 reviewer 독립 실행 또는 CI 결과가 아니다.
    • 테스트 근거: tests/test_account_valuations.py, tests/test_asset_snapshots.py, tests/test_contract_regression.py, tests/test_dashboard_app.py, tests/test_dashboard_menu_transition.py, tests/test_import_provenance_policy.py, tests/test_issue_12_regressions.py, tests/test_issue_12_review59_account.py, tests/test_issue_12_review59_readonly.py, tests/test_issue_12_review59_reports.py, tests/test_ledger_categories.py, tests/test_requirement_docs.py, tests/test_review_decision_workbench.py, tests/test_seoulpay_xlsx.py, tests/test_service.py
    • 판정 근거: 현재 immutable source와 실제 named test의 호출 및 assertion을 승인된 Discovery에 직접 대응했다. 이전 승인 또는 구현자 PASS 주장만으로 충족을 상속하지 않으며 제품 pytest와 browser는 reviewer가 실행하지 않았다.

범위 판정

  • 누락: 없음
  • 범위 초과: 없음
  • 명세 모순: 없음

결론

Issue12 Discovery의 모든 필수 기능 및 문서와 인수 계약이 현재 head에서 충족된다. Review66의 계좌 수정 strict integer 및 빈 문자열 잔여 지적은 선행 검증과 named no-mutation 회귀로 해소됐다. 모든 변경 경로는 승인 범위로 설명된다. 제품 pytest와 browser는 reviewer가 실행하지 않았으며 68통과 및 전체 291통과와 4skip 및 1warning은 실행 입력 불변을 확인한 구현자 evidence다. exact-head pending status는 CI 성공으로 사용하지 않는다. 지정된 검토 범위에서 승인하며 merge와 Issue close 및 release와 deployment는 수행하지 않는다.

## 구현 명세 적합성 검토 - Source Issue: #12 - Pull Request: #13 - Reviewed head: `432e6f851a2623c5b12608cfa7636d3544225f28` - Contract SHA-256: `6d86b591b022fcc722611bfec6d24e54a64216ab6f7c4098f357e25420218818` - Verdict: `approve` ### Acceptance criteria 판정 - `C01-history` — `satisfied` - 계약: 평가 계좌 FK, 기준일과 등록일, 대표 금액과 통화와 목적, 출처와 확인 상태, 증빙 식별자, 정정 연결과 사유 및 선택 시간 자료를 이력으로 보존한다. - 구현 근거: jarca_ledger_mcp/application/account_valuation_service.py, jarca_ledger_mcp/infrastructure/sqlite/schema.py, jarca_ledger_mcp/infrastructure/sqlite/migrations.py; account_valuation_service.py:133-257 register_account_valuation 및 :261-266 list_account_valuations; schema.py:229-267 및 migrations.py:157-173의 실제 필드와 FK와 unique 정의를 대조했다. tests/test_account_valuations.py:13-21의 schema12/idempotent 및 :24-32의 동일 기록 reuse와 payload conflict assertions를 확인했다. 구현자 evidence source 63fba3670c536824f91b59262d60240bdfb0db94에서 현재 head까지 전체 변경은 evidence-manifest 한 파일이며 실행 입력은 동일하다. focused 68통과와 전체 291통과 및 4skip과 1warning은 구현자 실행 근거이고 reviewer 독립 실행 또는 CI 결과가 아니다. - 테스트 근거: tests/test_account_valuations.py - 판정 근거: 현재 immutable source와 실제 named test의 호출 및 assertion을 승인된 Discovery에 직접 대응했다. 이전 승인 또는 구현자 PASS 주장만으로 충족을 상속하지 않으며 제품 pytest와 browser는 reviewer가 실행하지 않았다. - `C02-money-metrics` — `satisfied` - 계약: 금액 정밀도와 NULL 및 0을 보존하고 취득원가, 순납입액, 기관 표시 원금 금액과 정의 및 원문 명칭, 손익과 수익률의 계산 기준을 구분한다. 투자 대표 총평가액과 포함 현금 및 원금을 중복 합산하지 않는다. - 구현 근거: jarca_ledger_mcp/application/account_valuation_service.py, jarca_ledger_mcp/infrastructure/sqlite/schema.py, docs/data-model.md, docs/requirements/req-003_account-valuation-history.md; account_valuation_service.py:33-56의 strict integer/finite 검증, :165-186의 선택 지표와 NULL 보존, :247-249의 실제 roundtrip columns; schema.py:229-267의 INTEGER 및 선택 NULL 필드와 assets_service.py:453-499의 대표 금액 합산을 대조했다. test_valuation_round_trip_preserves_null_zero_and_physical_amount_mapping 및 test_correction_preserves_optional_fields_unless_overridden의 입력과 actual assertions를 확인했다. 구현자 evidence source 63fba3670c536824f91b59262d60240bdfb0db94에서 현재 head까지 전체 변경은 evidence-manifest 한 파일이며 실행 입력은 동일하다. focused 68통과와 전체 291통과 및 4skip과 1warning은 구현자 실행 근거이고 reviewer 독립 실행 또는 CI 결과가 아니다. - 테스트 근거: tests/test_issue_12_review59_account.py, tests/test_issue_12_regressions.py - 판정 근거: 현재 immutable source와 실제 named test의 호출 및 assertion을 승인된 Discovery에 직접 대응했다. 이전 승인 또는 구현자 PASS 주장만으로 충족을 상속하지 않으며 제품 pytest와 browser는 reviewer가 실행하지 않았다. - `N01-loan-balance-definition` — `satisfied` - 계약: 대출 평가 기록마다 대표 부채가 원금만인지 원금과 이자 및 수수료인지 필수로 명시하고 기본값으로 추정하지 않는다. 목적 alias가 필수 정의 계약을 우회하지 않는다. - 구현 근거: jarca_ledger_mcp/application/account_valuation_service.py, docs/requirements/req-003_account-valuation-history.md, jarca_ledger_mcp/application/accounts_write_services.py, jarca_ledger_mcp/application/imports_service.py, docs/data-model.md; account_valuation_service.py:93-105의 loan candidate 무추정 거부 및 :194-203의 loan alias와 종류 및 필수 정의 검증; accounts_write_services.py:81-89의 non-loan 전환 guard; imports_service.py:37-41의 candidate 호출을 대조했다. tests/test_account_valuation_edge_contracts.py:8-38, :41-76, :133-191은 계좌 유형 전환과 정의 누락 및 candidate/import 경로의 validation_error와 history/account 불변을 assertion한다. 구현자 evidence source 63fba3670c536824f91b59262d60240bdfb0db94에서 현재 head까지 전체 변경은 evidence-manifest 한 파일이며 실행 입력은 동일하다. focused 68통과와 전체 291통과 및 4skip과 1warning은 구현자 실행 근거이고 reviewer 독립 실행 또는 CI 결과가 아니다. - 테스트 근거: tests/test_issue_12_regressions.py, tests/test_issue_12_review59_account.py, tests/test_account_valuation_edge_contracts.py - 판정 근거: 현재 immutable source와 실제 named test의 호출 및 assertion을 승인된 Discovery에 직접 대응했다. 이전 승인 또는 구현자 PASS 주장만으로 충족을 상속하지 않으며 제품 pytest와 browser는 reviewer가 실행하지 않았다. - `C03-selection` — `satisfied` - 계약: 계좌와 통화 및 평가 목적별 유효 자료를 선택한다. exact는 당일 확인 자료만, as_of는 기준일 이하 최신 확인 자료만 사용한다. 미래 자료는 제외하고 미확인 후보는 확인 자료를 대체하거나 합산하지 않는다. 실제 기준일과 경과 일수 및 이월 상태를 반환한다. - 구현 근거: jarca_ledger_mcp/application/account_valuation_service.py, jarca_ledger_mcp/application/assets_service.py; account_valuation_service.py:270-312 select_account_valuation의 scope와 verified leaf, exact 및 latest-prior, candidate warning 및 age; assets_service.py:115-215와 :218-259의 계좌 및 기존 수기 selection과 미래/미확인/통화 제외를 대조했다. tests/test_account_valuations.py:35-45는 future와 unverified 제외 및 as-of carry와 actual date를 assertion한다. tests/test_issue_12_regressions.py의 scope 및 purpose와 unverified 합계 제외 regression을 함께 읽었다. 구현자 evidence source 63fba3670c536824f91b59262d60240bdfb0db94에서 현재 head까지 전체 변경은 evidence-manifest 한 파일이며 실행 입력은 동일하다. focused 68통과와 전체 291통과 및 4skip과 1warning은 구현자 실행 근거이고 reviewer 독립 실행 또는 CI 결과가 아니다. - 테스트 근거: tests/test_account_valuations.py, tests/test_issue_12_regressions.py - 판정 근거: 현재 immutable source와 실제 named test의 호출 및 assertion을 승인된 Discovery에 직접 대응했다. 이전 승인 또는 구현자 PASS 주장만으로 충족을 상속하지 않으며 제품 pytest와 browser는 reviewer가 실행하지 않았다. - `C04-correction-validation` — `satisfied` - 계약: 평가 정정은 append-only로 대상과 사유를 연결하며 다른 계좌, 통화, 목적을 참조하는 정정과 순환 및 동일 유효본의 동시 분기를 차단한다. - 구현 근거: jarca_ledger_mcp/application/account_valuation_service.py, jarca_ledger_mcp/infrastructure/sqlite/schema.py; account_valuation_service.py:204-224는 parent scope와 cyclic ancestry를 검증하고 :245-253은 단일 child unique 충돌을 fail-closed 처리한다. :315-375의 effective payload replay 및 changed conflict와 append-only 경계를 확인했다. tests/test_account_valuations.py:48-59는 원본 보존과 단일 correction count를 assertion하고 tests/test_account_valuation_edge_contracts.py:79-130은 동일 effective correction reuse 및 다른 payload conflict를 확인한다. 구현자 evidence source 63fba3670c536824f91b59262d60240bdfb0db94에서 현재 head까지 전체 변경은 evidence-manifest 한 파일이며 실행 입력은 동일하다. focused 68통과와 전체 291통과 및 4skip과 1warning은 구현자 실행 근거이고 reviewer 독립 실행 또는 CI 결과가 아니다. - 테스트 근거: tests/test_issue_12_review59_account.py, tests/test_account_valuations.py, tests/test_issue_12_regressions.py - 판정 근거: 현재 immutable source와 실제 named test의 호출 및 assertion을 승인된 Discovery에 직접 대응했다. 이전 승인 또는 구현자 PASS 주장만으로 충족을 상속하지 않으며 제품 pytest와 browser는 reviewer가 실행하지 않았다. - `C05-current-import` — `satisfied` - 계약: 뒤늦은 과거 자료 등록으로 최신 표시값을 과거로 되돌리지 않는다. 기존 계좌 수정과 import의 최신 캐시 및 새 이력 권위를 연결하며 동기화 시각을 실제 평가일로 오인하지 않는다. - 구현 근거: jarca_ledger_mcp/application/imports_service.py, jarca_ledger_mcp/application/assets_service.py, jarca_ledger_mcp/application/accounts_write_services.py; Review66 update 잔여 지적은 accounts_write_services.py:49-59의 strict integer 선행 검증으로 해소됐다. account_valuation_service.py:33-42는 boolean과 float 및 빈 문자열을 거부하고 정수와 signed integer text 및 0을 보존한다. update SQL 이전 :74에서 같은 normalized_balance를 cache에 사용하며 :93 및 :105-106은 dated candidate에도 같은 정확한 값을 전달한다. tests/test_import_current_balance_authority.py:124-146의 test_update_rejects_bool_or_float_dated_balance_without_mutation은 True 및 False와 1.2 및 -1.2가 validation_error이며 계좌와 valuation 목록을 바꾸지 않음을 assertion한다. :149-165의 test_update_rejects_empty_undated_balance_without_mutation은 날짜 없는 빈 문자열에 대해 같은 실패 및 불변을 assertion한다. :168-193의 test_update_preserves_zero_and_signed_integer_balance_semantics는 signed text 0 및 -12와 두 dated candidate 보존을 확인한다. :196-222의 test_zero_dated_balance_and_valid_import_recovery는 numeric0 및 유효 dated import를 보존한다. :92-100의 historical 비교와 undated 기준일 미상 처리 및 imports_service.py:43-49의 basis-date 비교는 source로 확인했고 기존 test_issue_12_review59_account의 세 historical import assertions도 확인했다. 구현자 evidence source 63fba3670c536824f91b59262d60240bdfb0db94에서 현재 head까지 전체 변경은 evidence-manifest 한 파일이며 실행 입력은 동일하다. focused 68통과와 전체 291통과 및 4skip과 1warning은 구현자 실행 근거이고 reviewer 독립 실행 또는 CI 결과가 아니다. - 테스트 근거: tests/test_issue_12_review59_account.py, tests/test_import_provenance_policy.py, tests/test_import_current_balance_authority.py, tests/test_account_basis_public_consumers.py, tests/test_issue_12_review63_accounts.py - 판정 근거: 빈 문자열을 cache에 저장하거나 bool 및 float를 정수로 강제 변환하는 경계는 mutation 이전 검증으로 닫혔다. 유효 0 및 signed integer, 뒤늦은 과거 자료와 현재 cache 분리, invalid input의 no-write named assertions가 승인 계약과 대응한다. - `C06-idempotency` — `satisfied` - 계약: 동일 증빙 또는 idempotency 재입력은 동일 기록을 재사용하며 같은 키의 다른 payload는 충돌이다. 동시 정정의 분기를 차단하고 UNIQUE 계좌 및 기준일 하나로 정정 추가를 막지 않는다. - 구현 근거: jarca_ledger_mcp/application/account_valuation_service.py, jarca_ledger_mcp/infrastructure/sqlite/schema.py, jarca_ledger_mcp/infrastructure/sqlite/migrations.py, jarca_ledger_mcp/application/accounts_write_services.py, jarca_ledger_mcp/application/imports_service.py; account_valuation_service.py:107-125의 candidate key payload, :225-244의 key와 source_ref 정본 및 unrelated scope conflict, :315-375의 explicit 및 keyless effective correction reuse; schema.py:264-267의 account-scoped key와 single-child index를 대조했다. tests/test_account_valuations.py:24-32 및 :72-80과 tests/test_account_valuation_edge_contracts.py:79-130, :194-231은 동일/변경 payload 및 correction와 candidate validation의 actual assertions를 제공한다. 구현자 evidence source 63fba3670c536824f91b59262d60240bdfb0db94에서 현재 head까지 전체 변경은 evidence-manifest 한 파일이며 실행 입력은 동일하다. focused 68통과와 전체 291통과 및 4skip과 1warning은 구현자 실행 근거이고 reviewer 독립 실행 또는 CI 결과가 아니다. - 테스트 근거: tests/test_issue_12_review59_account.py, tests/test_account_valuations.py, tests/test_issue_12_regressions.py, tests/test_account_valuation_edge_contracts.py - 판정 근거: 현재 immutable source와 실제 named test의 호출 및 assertion을 승인된 Discovery에 직접 대응했다. 이전 승인 또는 구현자 PASS 주장만으로 충족을 상속하지 않으며 제품 pytest와 browser는 reviewer가 실행하지 않았다. - `C07-close-immutability` — `satisfied` - 계약: 기존 asset_snapshots와 correction run을 보존하고 평가 정정 및 거래 추가로 기존 마감을 자동 변경하지 않는다. 동일 기준일 재마감은 사유와 이전 run 연결을 가진 새 버전을 원자적으로 추가한다. - 구현 근거: jarca_ledger_mcp/application/assets_service.py, jarca_ledger_mcp/infrastructure/sqlite/schema.py, jarca_ledger_mcp/infrastructure/sqlite/migrations.py; assets_service.py:717-752는 correction chain과 최신 correction authority를 검사하고 :757은 원래 existing run을 읽는다. unrelated live drift는 :800에서 idempotency_conflict다. tests/test_issue_12_review63_assets.py:97-138은 두 correction 이후 original equality와 unrelated asset drift conflict를 확인한다. 추가 evidence-array 검증은 :262-269 및 :297-320과 report/replay/timeseries의 오류 경계에 제한적으로 배치돼 정상 run 불변성을 변경하지 않는다. 구현자 evidence source 63fba3670c536824f91b59262d60240bdfb0db94에서 현재 head까지 전체 변경은 evidence-manifest 한 파일이며 실행 입력은 동일하다. focused 68통과와 전체 291통과 및 4skip과 1warning은 구현자 실행 근거이고 reviewer 독립 실행 또는 CI 결과가 아니다. - 테스트 근거: tests/test_asset_snapshots.py, tests/test_issue_12_regressions.py, tests/test_issue_12_review63_assets.py - 판정 근거: 현재 immutable source와 실제 named test의 호출 및 assertion을 승인된 Discovery에 직접 대응했다. 이전 승인 또는 구현자 PASS 주장만으로 충족을 상속하지 않으며 제품 pytest와 browser는 reviewer가 실행하지 않았다. - `N02-close-replay-run-binding` — `satisfied` - 계약: 마감 버전의 근거는 불변이며 동일 idempotency 요청은 원래 기록을 재사용한다. 재마감으로 과거 run 응답 및 evidence를 변경하지 않는다. - 구현 근거: jarca_ledger_mcp/application/assets_service.py, docs/interface-contract.md; F002 해소. assets_service.py:842-860은 included unverified_candidates와 excluded candidate의 blocking 및 state_hash를 저장한다. :383-398은 blocking=False를 복원하고 :757-799는 exact existing run에서 원래 응답을 구성한다. tests/test_asset_snapshot_idempotency.py:9-64의 test_replay_preserves_redacted_unverified_candidates_after_correction은 후보 allowlist와 blocking=False 및 전체 replay==first와 row/run count 불변을 assertion한다. :67-96의 test_replay_preserves_blocking_candidate_warning_shape은 차단 warning의 blocking 키 부재와 최초 응답 equality를 확인한다. 기존 mixed-asof 및 correction-chain equality 테스트도 보존된다. 구현자 evidence source 63fba3670c536824f91b59262d60240bdfb0db94에서 현재 head까지 전체 변경은 evidence-manifest 한 파일이며 실행 입력은 동일하다. focused 68통과와 전체 291통과 및 4skip과 1warning은 구현자 실행 근거이고 reviewer 독립 실행 또는 CI 결과가 아니다. - 테스트 근거: tests/test_issue_12_review59_reports.py, tests/test_issue_12_regressions.py, tests/test_asset_snapshot_idempotency.py, tests/test_issue_12_review63_assets.py - 판정 근거: 현재 immutable source와 실제 named test의 호출 및 assertion을 승인된 Discovery에 직접 대응했다. 이전 승인 또는 구현자 PASS 주장만으로 충족을 상속하지 않으며 제품 pytest와 browser는 reviewer가 실행하지 않았다. - `C08-approved-conditional` — `satisfied` - 계약: 완전한 exact 마감, 미완료 초안, 별도 승인된 조건부 마감을 구분한다. 승인 전 누락 및 이월은 미완료 초안이고 승인 후에도 누락 제외 및 확인된 과거값 이월만 허용한다. 미확인, 미래, 기준일 미상 금액은 승인으로도 합산하지 않으며 적용과 제외와 이월 및 승인자와 시각과 사유와 근거를 고정한다. - 구현 근거: jarca_ledger_mcp/application/assets_service.py, jarca_ledger_mcp/infrastructure/sqlite/schema.py, dashboard/page_views/assets.py; assets_service.py:646-671 및 :684-709은 public redaction 이전 동일 preview fingerprint와 승인 경계를 확인한다. 기존 test_f001_preview_fingerprint_uses_same_unredacted_authority_and_rejects_drift의 :17-41은 unchanged handoff 성공과 drift 거부 및 run 불변을 assertion한다. 미확인 candidate는 합산하지 않으며 nonblocking 후보는 conditional 승인 대상으로 오인하지 않는다. 승인자와 시각 및 사유와 참조, 적용과 제외와 이월은 :842-864에 원자적으로 저장한다. 구현자 evidence source 63fba3670c536824f91b59262d60240bdfb0db94에서 현재 head까지 전체 변경은 evidence-manifest 한 파일이며 실행 입력은 동일하다. focused 68통과와 전체 291통과 및 4skip과 1warning은 구현자 실행 근거이고 reviewer 독립 실행 또는 CI 결과가 아니다. - 테스트 근거: tests/test_issue_12_review59_reports.py, tests/test_issue_12_regressions.py, tests/test_asset_snapshots.py, tests/test_issue_12_review63_assets.py - 판정 근거: 현재 immutable source와 실제 named test의 호출 및 assertion을 승인된 Discovery에 직접 대응했다. 이전 승인 또는 구현자 PASS 주장만으로 충족을 상속하지 않으며 제품 pytest와 browser는 reviewer가 실행하지 않았다. - `C09-reconciliation` — `satisfied` - 계약: 외부 확인값과 장부 계산값을 분리하고 검증된 시작잔고, 기준시점, 거래 포함 범위와 계산 완전성을 표시한다. 거래 없는 수동 투자 계좌의 대사 불가 및 거래 미수입과 평가 수동 관리 상태를 구분하고 가짜 거래를 만들지 않는다. 대사도 공통 평가 근거와 대출 대표 정의를 사용한다. - 구현 근거: jarca_ledger_mcp/application/reconciliation_service.py, jarca_ledger_mcp/application/account_valuation_service.py, jarca_ledger_mcp/application/monthly_settlement_service.py; reconciliation_service.py:31-64 _account_balance_row는 시작 근거 및 거래 coverage를 분리하고 :102-158은 verified corrected leaf와 목적 및 대출 정의를 선택한다. :159-213은 계산 불완전 및 수동 투자 평가 관리와 대사 불가 상태를 provenance로 전달한다. monthly_settlement_service.py의 get_monthly_settlement_summary는 공통 report를 읽으며 tests/test_issue_12_review59_reports.py 및 tests/test_issue_12_regressions.py의 no-fake-transaction와 corrected-investment 및 unavailable assertions에 대응한다. 구현자 evidence source 63fba3670c536824f91b59262d60240bdfb0db94에서 현재 head까지 전체 변경은 evidence-manifest 한 파일이며 실행 입력은 동일하다. focused 68통과와 전체 291통과 및 4skip과 1warning은 구현자 실행 근거이고 reviewer 독립 실행 또는 CI 결과가 아니다. - 테스트 근거: tests/test_issue_12_review59_reports.py, tests/test_issue_12_regressions.py, tests/test_service.py - 판정 근거: 현재 immutable source와 실제 named test의 호출 및 assertion을 승인된 Discovery에 직접 대응했다. 이전 승인 또는 구현자 PASS 주장만으로 충족을 상속하지 않으며 제품 pytest와 browser는 reviewer가 실행하지 않았다. - `C10-report-monthly-evidence` — `satisfied` - 계약: MCP와 Dashboard 및 월정산 보고에서 같은 기준일과 선택 근거 및 실제 평가일, 경과 일수, 확인 상태, 누락과 미확인 및 이월 경고, 마감 버전 및 조건부 승인 근거를 일관되게 전달한다. - 구현 근거: jarca_ledger_mcp/application/assets_service.py, jarca_ledger_mcp/application/monthly_settlement_service.py, dashboard/page_views/monthly_settlement.py, dashboard/page_views/accounts.py; assets_service.py:335-380은 frozen valuation_id와 currency 및 실제 basis를 복원한다. :948-984는 frozen run을 정본으로 보고하고 :1049-1102는 zero-row run 날짜를 UNION으로 포함해 latest run의 승인 및 provenance를 전달한다. tests/test_issue_12_review63_assets.py:141-206은 zero-row 정정 run 및 alias, frozen ID와 currency 및 legacy ID 비추론을 assertion한다. monthly_settlement_service.py는 해당 공통 report를 읽는다. malformed JSON 배열 guard의 신규 test는 tests/test_asset_snapshot_idempotency.py:99-128이며 report/replay/timeseries 실패 및 row/run 불변을 확인한다. 임의 DB 손상 전체의 복구나 추가 오류명은 새 인수 조건으로 만들지 않는다. 구현자 evidence source 63fba3670c536824f91b59262d60240bdfb0db94에서 현재 head까지 전체 변경은 evidence-manifest 한 파일이며 실행 입력은 동일하다. focused 68통과와 전체 291통과 및 4skip과 1warning은 구현자 실행 근거이고 reviewer 독립 실행 또는 CI 결과가 아니다. - 테스트 근거: tests/test_issue_12_review59_reports.py, tests/test_issue_12_regressions.py, tests/test_service.py, tests/test_issue_12_review63_assets.py - 판정 근거: 현재 immutable source와 실제 named test의 호출 및 assertion을 승인된 Discovery에 직접 대응했다. 이전 승인 또는 구현자 PASS 주장만으로 충족을 상속하지 않으며 제품 pytest와 browser는 reviewer가 실행하지 않았다. - `C11-adapter-structure` — `satisfied` - 계약: MCP와 Streamlit gateway는 공통 application을 사용하고 기존 공개 호출명과 기존 인수 및 success와 실패 error_code 및 error envelope를 가능한 한 유지한다. 새 Dashboard 인증 또는 MCP 인증을 도입하지 않는다. - 구현 근거: jarca_ledger_mcp/adapters/mcp/server.py, jarca_ledger_mcp/adapters/mcp/tool_contracts.py, jarca_ledger_mcp/adapters/streamlit/accounts_gateway.py, jarca_ledger_mcp/application/__init__.py, jarca_ledger_mcp/service.py, dashboard/page_views/accounts.py, dashboard/page_views/assets.py, dashboard/page_views/monthly_settlement.py; service.py:50-70의 호환 facade와 application/asset_account_services.py:3-15의 공통 export, adapters/mcp/server.py의 create/register/select/correct/preview/close tools와 adapters/streamlit/accounts_gateway.py 및 overview_gateway.py의 shared-service delegate를 대조했다. dashboard/page_views/accounts.py 및 assets.py와 monthly_settlement.py는 shared gateway 결과를 렌더링하고 명시적 submit에서만 writer를 호출한다. tests/test_contract_regression.py와 tests/test_issue_12_regressions.py의 공개 signature/envelope 및 read-only assertions는 보존된다. 구현자 evidence source 63fba3670c536824f91b59262d60240bdfb0db94에서 현재 head까지 전체 변경은 evidence-manifest 한 파일이며 실행 입력은 동일하다. focused 68통과와 전체 291통과 및 4skip과 1warning은 구현자 실행 근거이고 reviewer 독립 실행 또는 CI 결과가 아니다. - 테스트 근거: tests/test_contract_regression.py, tests/test_issue_12_regressions.py - 판정 근거: 현재 immutable source와 실제 named test의 호출 및 assertion을 승인된 Discovery에 직접 대응했다. 이전 승인 또는 구현자 PASS 주장만으로 충족을 상속하지 않으며 제품 pytest와 browser는 reviewer가 실행하지 않았다. - `C12-migration-legacy` — `satisfied` - 계약: schema 11의 기존 데이터와 마감 및 개인정보를 보존하고 additive하고 idempotent한 migration을 제공한다. 기준일 증거 없는 값을 임의 월말로 소급하거나 legacy snapshot에 valuation_id를 추측하여 생성하지 않는다. - 구현 근거: jarca_ledger_mcp/infrastructure/sqlite/schema.py, jarca_ledger_mcp/infrastructure/sqlite/migrations.py, jarca_ledger_mcp/application/assets_service.py; migrations.py:19-173의 additive CREATE/ADD COLUMN과 unique 및 schema12 상태; assets_service.py:335-380의 frozen evidence와 legacy valuation_id 비추론을 대조했다. test_account_valuation_schema_is_v12_and_idempotent 및 test_schema12_migration_preserves_legacy_rows_indexes_and_is_idempotent는 기존 rows와 재호출 idempotency를 검사하고 tests/test_issue_12_review63_assets.py:199-206은 legacy ID가 생성되지 않음을 assertion한다. 구현자 evidence source 63fba3670c536824f91b59262d60240bdfb0db94에서 현재 head까지 전체 변경은 evidence-manifest 한 파일이며 실행 입력은 동일하다. focused 68통과와 전체 291통과 및 4skip과 1warning은 구현자 실행 근거이고 reviewer 독립 실행 또는 CI 결과가 아니다. - 테스트 근거: tests/test_account_valuations.py, tests/test_issue_12_regressions.py, tests/test_ledger_categories.py, tests/test_review_decision_workbench.py - 판정 근거: 현재 immutable source와 실제 named test의 호출 및 assertion을 승인된 Discovery에 직접 대응했다. 이전 승인 또는 구현자 PASS 주장만으로 충족을 상속하지 않으며 제품 pytest와 browser는 reviewer가 실행하지 않았다. - `C13-read-only` — `satisfied` - 계약: preview와 조회 및 Dashboard 렌더링은 금융 쓰기를 실행하지 않는다. 명시적 등록, 정정, 승인 close 및 import 제출만 변경을 수행하고 실패 시 부분 쓰기를 남기지 않는다. - 구현 근거: jarca_ledger_mcp/infrastructure/sqlite/connection.py, jarca_ledger_mcp/application/shared.py, jarca_ledger_mcp/application/system_services.py, jarca_ledger_mcp/application/account_valuation_service.py, jarca_ledger_mcp/application/assets_service.py; connection.py:31-53 connect_readonly/read_db의 mode=ro와 no-init, shared.py:128-138의 read 오류 envelope; assets_service.py:646-671의 preview와 :939-1138의 report/time-series/liquidity read, account_valuation_service.py:260-312의 read selector를 대조했다. tests/test_issue_12_review59_readonly.py는 missing DB no-path-create와 initialized DB schema/rows 불변을 검사하고 explicit writer는 connection.py:56-69에서만 init와 commit을 수행한다. 구현자 evidence source 63fba3670c536824f91b59262d60240bdfb0db94에서 현재 head까지 전체 변경은 evidence-manifest 한 파일이며 실행 입력은 동일하다. focused 68통과와 전체 291통과 및 4skip과 1warning은 구현자 실행 근거이고 reviewer 독립 실행 또는 CI 결과가 아니다. - 테스트 근거: tests/test_issue_12_review59_readonly.py, tests/test_dashboard_app.py, tests/test_dashboard_menu_transition.py - 판정 근거: 현재 immutable source와 실제 named test의 호출 및 assertion을 승인된 Discovery에 직접 대응했다. 이전 승인 또는 구현자 PASS 주장만으로 충족을 상속하지 않으며 제품 pytest와 browser는 reviewer가 실행하지 않았다. - `C14-auth-menu-preservation` — `satisfied` - 계약: Dashboard 인증은 DB보다 먼저이며 REQ-001의 cookie와 logout 및 REQ-002의 메뉴 label과 order, shell, query, error와 retry 및 명시적 금융 쓰기 계약을 유지한다. - 구현 근거: dashboard/app.py, dashboard/page_views/accounts.py, dashboard/page_views/assets.py, dashboard/page_views/monthly_settlement.py, docs/interface-contract.md, docs/project-structure.md, docs/runtime-flow.md; dashboard/app.py:37-72의 auth-before-financial-dispatch와 gateway read boundary, 기존 dashboard authentication/menu 관련 source 및 tests는 직전 head와 byte-identical하다. docs/interface-contract.md:1-261 및 docs/project-structure.md와 docs/runtime-flow.md의 기존 auth/cookie/logout와 canonical menu order 및 shell/query 내용이 보존된다. tests/test_dashboard_menu_transition.py 및 tests/test_dashboard_app.py의 actual authentication/menu/no-write assertions와 전체 구현자 regression 보고를 대응했다. 구현자 evidence source 63fba3670c536824f91b59262d60240bdfb0db94에서 현재 head까지 전체 변경은 evidence-manifest 한 파일이며 실행 입력은 동일하다. focused 68통과와 전체 291통과 및 4skip과 1warning은 구현자 실행 근거이고 reviewer 독립 실행 또는 CI 결과가 아니다. - 테스트 근거: tests/test_dashboard_menu_transition.py, tests/test_dashboard_app.py - 판정 근거: 현재 immutable source와 실제 named test의 호출 및 assertion을 승인된 Discovery에 직접 대응했다. 이전 승인 또는 구현자 PASS 주장만으로 충족을 상속하지 않으며 제품 pytest와 browser는 reviewer가 실행하지 않았다. - `C15-exclusions-privacy` — `satisfied` - 계약: 증권사 자동 연동, 정확한 성과 또는 환율 엔진, 새 인증, 별도 월정산 제품, 거래 추론 및 기존 데이터 자동 재작성과 수기 비계좌 자산 전체 이력 재설계를 추가하지 않는다. 실제 계좌 및 금융 증빙과 credential을 로그와 문서 및 테스트에 기록하지 않는다. - 구현 근거: jarca_ledger_mcp/application/assets_service.py, jarca_ledger_mcp/application/account_valuation_service.py, jarca_ledger_mcp/application/imports_service.py, jarca_ledger_mcp/application/reconciliation_service.py, jarca_ledger_mcp/infrastructure/sqlite/schema.py, jarca_ledger_mcp/infrastructure/sqlite/migrations.py; assets_service.py:62-75 _public_evidence 및 :94-112의 민감 source state는 digest로만 공개하고 :383-408의 closed metadata는 strict allowlist를 사용한다. account_valuation_service.py:29-30의 public candidate는 ID/date/currency/purpose/status만 반환한다. tests/test_asset_snapshot_idempotency.py:26-42는 redacted candidate와 state hash 및 비차단 warning shape를 assertion한다. changed-file 전체는 기존 금융 이력 및 마감과 read-only 보완 및 supporting tests/docs이며 외부 FX/가격/auth/성과 엔진이나 기존 데이터 재작성은 없다. 구현자 evidence source 63fba3670c536824f91b59262d60240bdfb0db94에서 현재 head까지 전체 변경은 evidence-manifest 한 파일이며 실행 입력은 동일하다. focused 68통과와 전체 291통과 및 4skip과 1warning은 구현자 실행 근거이고 reviewer 독립 실행 또는 CI 결과가 아니다. - 테스트 근거: tests/test_issue_12_review59_reports.py, tests/test_issue_12_regressions.py, scripts/ci_fixture_db.py - 판정 근거: 현재 immutable source와 실제 named test의 호출 및 assertion을 승인된 Discovery에 직접 대응했다. 이전 승인 또는 구현자 PASS 주장만으로 충족을 상속하지 않으며 제품 pytest와 browser는 reviewer가 실행하지 않았다. - `D01-requirement-structure` — `satisfied` - 계약: 신규 REQ-003을 배정 경로와 제목으로 작성하며 trusted harness README와 TEMPLATE의 JSON metadata, 연속 요구사항 및 AC, 필수 섹션, 판정 기준과 검증 및 검증 분류의 수준과 백엔드와 케이스 및 상태 불변조건을 충족한다. 초기 PR은 미정이며 PR 생성 후 실제 번호를 추적한다. - 구현 근거: docs/requirements/req-003_account-valuation-history.md; REQ-003의 JSON metadata docs/requirements/req-003_account-valuation-history.md:1-16, 연속 요구사항 :51-185 및 AC :187-297, 필수 오류와 계약과 호환성과 추적성 :299-317을 trusted harness README 및 TEMPLATE에 대조했다. Issue12와 실제 구현 PR13의 lifecycle traceability는 유효하다. 전체 문서와 이전 reviewed-head baseline은 byte-identical하다. 실제 tests/test_requirement_docs.py의 marker와 signature 및 named test 존재 assertion을 읽었다. - 테스트 근거: tests/test_requirement_docs.py - 판정 근거: 현재 immutable source와 실제 named test의 호출 및 assertion을 승인된 Discovery에 직접 대응했다. 이전 승인 또는 구현자 PASS 주장만으로 충족을 상속하지 않으며 제품 pytest와 browser는 reviewer가 실행하지 않았다. - `D02-requirement-semantics` — `satisfied` - 계약: 요구사항에는 평가 근거와 지표 정의, 선택과 future 제외, 정정 및 idempotency 충돌, 대사 완전성, current 및 import 연계, 마감 상태와 불변성과 승인, shared adapter 및 인증, migration과 legacy를 소스 및 테스트에 대응한다. 모든 승인된 경계와 회귀 사례를 인수 기준으로 내린다. - 구현 근거: docs/requirements/req-003_account-valuation-history.md; docs/requirements/req-003_account-valuation-history.md:53-185의 10개 요구사항과 :189-297의 전체 AC를 Discovery의 모든 포함 범위와 확정 결정 및 제외 범위에 대조했다. 이전 REQ-003 전체 AC와 byte-identical하여 의미 삭제나 승인 없는 축소가 없다. 참조된 tests와 actual implementation은 head에서 존재한다. current-cache 구현과 Review66 finding closure는 C05에서 검토하며 문서 반복 부재나 evidence JSON 형식을 새로운 의무로 판단하지 않는다. - 테스트 근거: tests/test_account_valuations.py, tests/test_asset_snapshots.py, tests/test_issue_12_regressions.py, tests/test_requirement_docs.py, tests/test_mcp_http_runtime.py, tests/test_dashboard_authentication_app.py - 판정 근거: 현재 immutable source와 실제 named test의 호출 및 assertion을 승인된 Discovery에 직접 대응했다. 이전 승인 또는 구현자 PASS 주장만으로 충족을 상속하지 않으며 제품 pytest와 browser는 reviewer가 실행하지 않았다. - `D03-data-model` — `satisfied` - 계약: 신규 데이터 모델은 기존 entities 및 valuation과 마감의 관계, FK와 날짜 및 정확한 금액과 NULL 및 0과 선택 지표 및 대출 필수 정의, 계좌와 통화 및 목적과 기준일의 선택 및 index와 단일 유효 정정본, 고정 적용 분류 및 출처와 상태와 누락 및 이월 및 승인 버전, 분리된 정정과 schema11 이관 및 미상 날짜와 legacy 및 최신 캐시 동기화 책임을 정의한다. - 구현 근거: docs/data-model.md; docs/data-model.md:63-68은 account 필수와 currency 및 valuation purpose 선택 필터, basis-date exact 또는 upper-bound, verified leaf와 future 및 unverified 제외를 명시한다. account_date와 status_date 인덱스의 coverage 및 account-currency-purpose 전체를 덮지 않는 한계, idempotency 및 single_correction의 write integrity 책임을 구분한다. account_valuation_service.py:270-312의 실제 선택과 schema.py:264-267 및 migrations.py:169-172의 물리 정의에 대응한다. test_data_model_documents_valuation_selection_contract_and_index_mapping의 tests/test_valuation_contract_docs.py:46-62는 이 설명을 assertion한다. 나머지 entity 관계와 금액 NULL0 및 대출 정의, immutable run과 migration 및 legacy와 캐시 책임은 문서 :12-61 및 :70-176에 보존된다. - 테스트 근거: tests/test_account_valuations.py, tests/test_asset_snapshots.py, tests/test_issue_12_regressions.py, tests/test_valuation_contract_docs.py - 판정 근거: 현재 immutable source와 실제 named test의 호출 및 assertion을 승인된 Discovery에 직접 대응했다. 이전 승인 또는 구현자 PASS 주장만으로 충족을 상속하지 않으며 제품 pytest와 browser는 reviewer가 실행하지 않았다. - `D04-interface-contract` — `satisfied` - 계약: 인터페이스 문서는 기존 auth 및 메뉴를 보존하고 평가 등록 및 조회 및 정정의 모든 입력과 유효본 및 원금 정의 출력, report 및 preview/close 및 월정산과 대사와 current API의 공통 선택, exact 기본과 실제 날짜 및 age 및 이월과 누락 및 미확인과 출처 및 버전과 승인 출력을 정의한다. 잘못된 입력과 scope 및 충돌과 부족 근거는 무변경 실패이며 기존 envelope와 required keys 및 의미 변경 정책을 명시한다. - 구현 근거: docs/interface-contract.md, docs/data-model.md; docs/interface-contract.md:1-261 기존 auth와 menu 보존; :263-358 valuation와 close 입력 및 오류와 무변경; :401-423 실제 signature와 persisted fields; :425-435 close 및 provenance aliases, preview fingerprint, equality replay와 recursive redaction을 승인 의무에 대조했다. 전체 문서는 이전 reviewed head와 동일하고 current source의 signature 및 enums와 대응한다. - 테스트 근거: tests/test_account_valuations.py, tests/test_issue_12_regressions.py, tests/test_contract_regression.py, tests/test_valuation_contract_docs.py, tests/test_issue_12_review59_account.py - 판정 근거: 현재 immutable source와 실제 named test의 호출 및 assertion을 승인된 Discovery에 직접 대응했다. 이전 승인 또는 구현자 PASS 주장만으로 충족을 상속하지 않으며 제품 pytest와 browser는 reviewer가 실행하지 않았다. - `D05-project-structure` — `satisfied` - 계약: 프로젝트 구조 문서는 기존 source와 test 및 evidence를 보존하고 SQLite schema와 migrations, application의 assets와 account writes 및 import와 reconciliation 및 monthly 책임, 공개 facade와 MCP 및 Streamlit과 기존 세 화면 및 tests를 exact 경로로 대응한다. adapter에서 선택 정책을 복제하지 않고 대출 정의와 verified as_of 및 conditional 승인 경계를 shared application에 배치한다. - 구현 근거: docs/project-structure.md; docs/project-structure.md:122-164의 source/test/docs 배치와 application 및 SQLite 및 adapter 의존, :166-212의 auth/menu inventory와 actual module ownership 및 monthly/reconciliation/read-only/privacy 경계를 모든 문서 의무와 current paths에 대조했다. 선택 정책을 adapter에 복제하지 않으며 별도 제품이나 마감 엔진이 없다. - 테스트 근거: tests/test_requirement_docs.py - 판정 근거: 현재 immutable source와 실제 named test의 호출 및 assertion을 승인된 Discovery에 직접 대응했다. 이전 승인 또는 구현자 PASS 주장만으로 충족을 상속하지 않으며 제품 pytest와 browser는 reviewer가 실행하지 않았다. - `D06-runtime-flow` — `satisfied` - 계약: 런타임 문서는 auth 및 메뉴를 보존하고 register/correct의 증빙 및 scope 검증과 append 및 유효본 확인 및 최신 캐시 동기화를 단일 트랜잭션으로 설명한다. 날짜 및 정책과 통화 및 대표 합산과 경고 read, preview 후 명시적 approval 및 원자적 freeze, reasoned reclose, 같은 근거의 monthly 및 대사, import와 이관 trigger 및 실패복구, retry와 concurrency 및 preview drift 재검증과 무부분쓰기, 비민감 valuation/run 상관 신호를 정의한다. - 구현 근거: docs/runtime-flow.md; docs/runtime-flow.md:147-185의 register/select/correct, preview/approval/atomic freeze, import와 monthly 및 reconciliation propagation; :187-210의 failure/retry/concurrency/비민감 signals; :221-241의 실제 transition와 DB boundary 및 fingerprint drift와 no-write 및 immutable replay를 승인 의무와 source에 대조했다. 별도 새 browser 조합이나 독립 실행 기록을 필수 계약으로 추가하지 않는다. - 테스트 근거: tests/test_account_valuations.py, tests/test_asset_snapshots.py, tests/test_issue_12_regressions.py - 판정 근거: 현재 immutable source와 실제 named test의 호출 및 assertion을 승인된 Discovery에 직접 대응했다. 이전 승인 또는 구현자 PASS 주장만으로 충족을 상속하지 않으며 제품 pytest와 browser는 reviewer가 실행하지 않았다. - `C16-supporting-evidence-scope` — `satisfied` - 계약: 모든 changed file은 승인된 기능과 필수 supporting change 또는 테스트 evidence로 설명되고 기존 requirement ID를 임의 갱신하거나 범위 밖 제품 및 설정을 변경하지 않는다. - 구현 근거: dashboard/app.py, dashboard/page_views/accounts.py, dashboard/page_views/assets.py, dashboard/page_views/monthly_settlement.py, docs/data-model.md, docs/interface-contract.md, docs/project-structure.md, docs/requirements/req-003_account-valuation-history.md, docs/runtime-flow.md, docs/verification/issue-12-review-60/contract-preservation-inventory.json, docs/verification/issue-12-review-60/evidence-manifest.json, docs/verification/issue-12-review-60/evidence-plan.json, docs/verification/issue-12-review-60/final-independent-review.json, docs/verification/issue-12-review-60/finding-matrix.json, docs/verification/issue-12-review-60/red-evidence.json, docs/verification/issue-12-review-61/contract-preservation-inventory.json, docs/verification/issue-12-review-61/evidence-manifest.json, docs/verification/issue-12-review-61/evidence-plan.json, docs/verification/issue-12-review-61/finding-matrix.json, docs/verification/issue-12-review-61/green-evidence.json, docs/verification/issue-12-review-61/red-evidence.json, docs/verification/issue-12-review-63/contract-preservation-inventory.json, docs/verification/issue-12-review-63/evidence-manifest.json, docs/verification/issue-12-review-63/evidence-plan.json, docs/verification/issue-12-review-63/finding-matrix.json, docs/verification/issue-12-review-63/red-evidence.json, docs/verification/issue-12-review-64/contract-preservation-inventory.json, docs/verification/issue-12-review-64/evidence-manifest.json, docs/verification/issue-12-review-64/evidence-plan.json, docs/verification/issue-12-review-64/finding-matrix.json, docs/verification/issue-12-review-64/red-evidence.json, docs/verification/issue-12-review-65/contract-preservation-inventory.json, docs/verification/issue-12-review-65/evidence-manifest.json, docs/verification/issue-12-review-65/evidence-plan.json, docs/verification/issue-12-review-65/finding-matrix.json, docs/verification/issue-12-review-65/red-evidence.json, docs/verification/issue-12-review-66/contract-preservation-inventory.json, docs/verification/issue-12-review-66/evidence-manifest.json, docs/verification/issue-12-review-66/evidence-plan.json, docs/verification/issue-12-review-66/finding-matrix.json, docs/verification/issue-12-review-66/red-evidence.json, jarca_ledger_mcp/adapters/mcp/server.py, jarca_ledger_mcp/adapters/mcp/tool_contracts.py, jarca_ledger_mcp/adapters/streamlit/accounts_gateway.py, jarca_ledger_mcp/adapters/streamlit/overview_gateway.py, jarca_ledger_mcp/application/__init__.py, jarca_ledger_mcp/application/account_valuation_service.py, jarca_ledger_mcp/application/accounts_write_services.py, jarca_ledger_mcp/application/assets_service.py, jarca_ledger_mcp/application/categorization_services.py, jarca_ledger_mcp/application/cross_transfer_service.py, jarca_ledger_mcp/application/imports_service.py, jarca_ledger_mcp/application/monthly_settlement_service.py, jarca_ledger_mcp/application/reconciliation_service.py, jarca_ledger_mcp/application/review_decision_service.py, jarca_ledger_mcp/application/shared.py, jarca_ledger_mcp/application/system_services.py, jarca_ledger_mcp/application/transaction_report_services.py, jarca_ledger_mcp/application/uncategorized_workbench_service.py, jarca_ledger_mcp/infrastructure/sqlite/__init__.py, jarca_ledger_mcp/infrastructure/sqlite/connection.py, jarca_ledger_mcp/infrastructure/sqlite/migrations.py, jarca_ledger_mcp/infrastructure/sqlite/schema.py, jarca_ledger_mcp/service.py, scripts/ci_fixture_db.py, tests/test_account_basis_public_consumers.py, tests/test_account_valuation_edge_contracts.py, tests/test_account_valuations.py, tests/test_asset_snapshot_idempotency.py, tests/test_asset_snapshots.py, tests/test_contract_regression.py, tests/test_dashboard_app.py, tests/test_dashboard_menu_transition.py, tests/test_import_current_balance_authority.py, tests/test_import_provenance_policy.py, tests/test_issue_12_regressions.py, tests/test_issue_12_review59_account.py, tests/test_issue_12_review59_readonly.py, tests/test_issue_12_review59_reports.py, tests/test_issue_12_review63_accounts.py, tests/test_issue_12_review63_assets.py, tests/test_ledger_categories.py, tests/test_requirement_docs.py, tests/test_review_decision_workbench.py, tests/test_seoulpay_xlsx.py, tests/test_service.py, tests/test_valuation_contract_docs.py; authoritative changed-file 87개와 local base-to-head tree가 일치하고 API diff 197개 hunk의 exact base/head blob 위치 및 내용 일치를 확인했다. Review66 head 이후 변경은 account update validator 및 대응 regression test와 supporting evidence 다섯 파일이다. bool 및 float와 빈 문자열 검증은 기존 exact monetary/current-cache 계약 범위다. 문서 다섯 파일은 직전 reviewed head와 동일하고 REQ003 전체 baseline AC가 보존된다. 모든 changed file은 changed-file-coverage.json에서 기존 criterion 또는 supporting evidence로 연결된다. manifest의 모든 11개 blob OID와 SHA256, plan digest, ancestor 관계 및 전체 source-to-head diff를 검증했다. exact-head status는 pending이며 total_count 0이므로 CI 성공 근거로 사용하지 않는다. 구현자 evidence source 63fba3670c536824f91b59262d60240bdfb0db94에서 현재 head까지 전체 변경은 evidence-manifest 한 파일이며 실행 입력은 동일하다. focused 68통과와 전체 291통과 및 4skip과 1warning은 구현자 실행 근거이고 reviewer 독립 실행 또는 CI 결과가 아니다. - 테스트 근거: tests/test_account_valuations.py, tests/test_asset_snapshots.py, tests/test_contract_regression.py, tests/test_dashboard_app.py, tests/test_dashboard_menu_transition.py, tests/test_import_provenance_policy.py, tests/test_issue_12_regressions.py, tests/test_issue_12_review59_account.py, tests/test_issue_12_review59_readonly.py, tests/test_issue_12_review59_reports.py, tests/test_ledger_categories.py, tests/test_requirement_docs.py, tests/test_review_decision_workbench.py, tests/test_seoulpay_xlsx.py, tests/test_service.py - 판정 근거: 현재 immutable source와 실제 named test의 호출 및 assertion을 승인된 Discovery에 직접 대응했다. 이전 승인 또는 구현자 PASS 주장만으로 충족을 상속하지 않으며 제품 pytest와 browser는 reviewer가 실행하지 않았다. ### 범위 판정 - 누락: 없음 - 범위 초과: 없음 - 명세 모순: 없음 ### 결론 Issue12 Discovery의 모든 필수 기능 및 문서와 인수 계약이 현재 head에서 충족된다. Review66의 계좌 수정 strict integer 및 빈 문자열 잔여 지적은 선행 검증과 named no-mutation 회귀로 해소됐다. 모든 변경 경로는 승인 범위로 설명된다. 제품 pytest와 browser는 reviewer가 실행하지 않았으며 68통과 및 전체 291통과와 4skip 및 1warning은 실행 입력 불변을 확인한 구현자 evidence다. exact-head pending status는 CI 성공으로 사용하지 않는다. 지정된 검토 범위에서 승인하며 merge와 Issue close 및 release와 deployment는 수행하지 않는다. <!-- gitea-agent:implementation-spec-review/v1 owner=jsfamily repository=jarca-ledger-mcp issue=12 pr=13 head=432e6f851a2623c5b12608cfa7636d3544225f28 contract-sha256=6d86b591b022fcc722611bfec6d24e54a64216ab6f7c4098f357e25420218818 result-sha256=fd9c7f62c040e7ffdadd76b101c660e7b956f46c11483c954c71852f82a790cb correlation=9d03407f662d45cce3c722b1d4758d825c4bfd323ee2677cb15f790317303233 -->
gitea-review-agent requested changes 2026-10-08 00:42:28 +00:00
Dismissed
gitea-review-agent left a comment
Owner
  • Verdict: request_changes

코드 재리뷰 — Issue #12 / PR #13

  • 검토 HEAD: 432e6f851a2623c5b12608cfa7636d3544225f28
  • Base: 5813dd484196239ab1fac4ba066c5b4922fb33e6
  • 계약 SHA-256: 6d86b591b022fcc722611bfec6d24e54a64216ab6f7c4098f357e25420218818
  • 현재 HEAD의 authoritative spec 승인: #67
  • 사용: gitea-agent 하네스 scoped gitea-code-review v0.1.2 및 canonical native admission/publication/readback.

범위 및 이전 지적

이전 code review #63의 HEAD 3b5101128d5a2cf038b8fb84facfd9d176928c26 이후 28개 변경 경로, 영향받는 호출자/선택/마감/이관 경계와 테스트 및 evidence를 검토했다. 이전 검토 경로 중 59개는 byte-identical이며, 두 집합의 합이 현재 전체 base-to-head 87개 변경 파일과 정확히 일치한다. 별도 static worker 결과는 후보로만 사용했고 최종 판단과 재현은 main reviewer가 수행했다.

기존 F-001~F-005의 지정 재현 경로는 해소됐다:

  • F-001: public redaction 전 동일 fingerprint로 preview→close 성공; authority 변경 시 무변경 실패 회귀가 있다.
  • F-002: 최초/정정/mixed-as-of 응답과 candidate warning 및 snapshot ID 순서를 frozen evidence로 재구성한다. 독립 최초/정정 replay equality와 다중 정정 회귀가 통과했다.
  • F-003: zero-row conditional run도 timeseries에서 최신 run/승인/provenance와 함께 반환한다. 독립 0원 point 재현이 통과했다.
  • F-004: 신규 closed report가 frozen valuation_id/currency를 복원하며, live 평가 변경 후에도 기존 identity가 유지된다. legacy valuation ID를 추측하지 않는 테스트가 있다.
  • F-005: 기준일만 있거나 빈/부적합 금액인 입력은 쓰기 전에 거부하며, 0 및 signed integer와 정상 후속 dated import는 보존한다. 독립 no-init rejection 및 named no-mutation regressions가 통과했다.

F-006 · High — schema 11의 기존 마감 보고가 현재 평가값으로 대체됨

  • 위치: jarca_ledger_mcp/application/assets_service.py:327-332, :948-954, :986-1007.
  • 발생 조건: 기존 schema 11에서 실제 close_asset_snapshot으로 만든 snapshot rows가 있고, 현재 수기 평가액을 바꾼 뒤 schema 12로 이관한다. schema 11에는 asset_snapshot_runs 테이블/record가 없고, 기존 run 정보는 snapshot rows의 run/correction columns에 있다.
  • 실패: _snapshot_rows_for_latest_run은 새 run record가 없으면 snapshot_run_id를 빈 값으로 반환한다. report는 이를 미마감으로 판정하고 legacy rows를 읽었어도 live included/excluded가 있으면 legacy 반환 분기를 건너뛰어 현재 평가값을 반환한다.
  • 직접 재현: 합성 수기 자산 100으로 2026-06-30을 마감하고 현재값을 200으로 변경했다. base/schema 11의 마감 보고는 여전히 100, closed=True다. 같은 DB의 복사본을 이관해 prior 및 current HEAD로 읽으면 200, source=live_authority, closed=False, snapshot_count=0을 반환한다. 물리 snapshot amount 100은 그대로 남아 있다. 새 평가 근거의 선택이나 DB row 보존만으로 기존 마감 보고의 불변성이 보장되지 않는다.
  • Origin: base에서는 정상, prior-reviewed HEAD 및 current HEAD에서는 동일하게 실패한다. _snapshot_rows_for_latest_run은 prior/current에서 동일하다. 이번 재작업이 새로 만든 결함이 아니라 PR에서 이미 도입됐고 이전 code review에서 놓친 결함이다. finding-origin.json 및 legacy-probe-evidence.json으로 구분했다.
  • 계약/영향: 승인 Discovery의 기존 마감 보존, 기존 마감은 현재 평가 변경으로 자동 변경되지 않음, schema 11 additive/idempotent 이관 및 legacy 근거 보존 경계를 위반한다. 과거 마감 보고와 이를 읽는 월정산 소비자가 현재 평가액을 과거 확정액으로 보여줄 수 있으므로 approval 전에 해결해야 하는 material correctness defect다. 선택적 기능/일반 기술부채로 분리할 수 없다.
  • 제한된 수정 방향: 새 run record가 없는 legacy 마감에서도 기존 row-based 최신 run/정정 선택을 보존하고 frozen snapshot 금액을 조회 정본으로 사용한다. valuation_id나 승인 근거를 추측하지 말고 legacy임을 명시한다. live fallback은 실제 마감 근거가 없는 경우와 구분한다.
  • 재검증: actual base/schema-11 close로 생성한 자료를 이관한 뒤 live 평가액/기준일을 바꿔도 기존 날짜 보고의 frozen total 및 최신 legacy correction 선택이 유지되어야 한다. read-only, schema/금융 rows 불변, legacy ID 비추론 및 월정산/시계열 소비자 회귀를 함께 확인한다.

비차단 N-001 — 미출시 PR 중간 HEAD의 fingerprint 형식 호환

assets_service.py:713-716, :753-756에서 prior PR HEAD의 단일 SHA fingerprint를 가진 idempotency run은 current HEAD에서 같은 key로 재실행해도 idempotency_conflict다. worker 후보를 main reviewer가 재현했다. 그러나 main/schema-11 base에는 해당 테이블과 idempotency 인수가 없으므로 기존 배포 baseline의 replay 회귀로 오분류하지 않는다. 중간 PR 버전으로 생성한 DB의 지원/사전배포 계약은 확인되지 않았다. 이를 지원해야 한다면 fingerprint version/legacy comparison 및 no-write replay 테스트로 별도 처리한다. 이 항목만으로 변경 요청하지 않는다.

실행 및 evidence

Reviewer가 exact current HEAD에서 credential-free child 환경, 기존 project venv, 격리된 local /tmp DB/fixture로 직접 실행했다:

  • 전체 pytest: 291 passed, 4 skipped, 0 failed, 0 errors, exit 0.
  • ruff check --no-cache .: exit 0.
  • 변경 Python 50개 in-memory syntax compile 및 git diff --check BASE HEAD: 통과.
  • F-001~F-005 독립 synthetic probes: exit 0.
  • Base/prior/current Git blob을 memory loader로 실행한 legacy probe: exit 0. 제품 checkout이나 source를 수정하지 않았다. 마지막 성공 probe에서 확정된 출력만 결함 근거로 사용했다.
  • review-63/64/65/66 manifest의 각 source revision blob OID/SHA-256을 확인했다. 최신 review-66의 11개 실행 입력은 current HEAD와 동일하다. 과거 manifest는 역사적 근거이며, 위 reviewer 전체 테스트는 별도 실제 실행이다.

한계와 결론

4개 private KB/Toss PDF fixture/password 테스트는 skip이다. 실제 금융 자료, 운영 DB, 새 real-browser 탐색, 배포를 실행하지 않았다. Dashboard/auth/menu 등 기존 테스트는 전체 suite에 포함됐다. exact-head API status는 빈 목록이며 remote CI 성공으로 표현하지 않는다.

기존 5건 해소와 green suite만으로 승인하지 않는다. 실제 schema-11 upgrade/report 불변성의 F-006이 남아 request_changes다. 재리뷰 범위는 해당 legacy-preservation 결함과 필요한 소비자 회귀로 한정하고 자동 무제한 재작업을 시작하지 않는다. Source/Discovery/Issue state 변경, commit/push/merge/배포는 수행하지 않는다.

Redacted 상세 기록: /opt/data/gitea-agent/logs/gitea-review-agent/runs/issue-12-pr-13-20261008T001536Z/.

<!-- gitea-agent:code-review/v1 owner=jsfamily repository=jarca-ledger-mcp issue=12 pr=13 head=432e6f851a2623c5b12608cfa7636d3544225f28 contract-sha256=6d86b591b022fcc722611bfec6d24e54a64216ab6f7c4098f357e25420218818 --> - Verdict: `request_changes` ## 코드 재리뷰 — Issue #12 / PR #13 - 검토 HEAD: `432e6f851a2623c5b12608cfa7636d3544225f28` - Base: `5813dd484196239ab1fac4ba066c5b4922fb33e6` - 계약 SHA-256: `6d86b591b022fcc722611bfec6d24e54a64216ab6f7c4098f357e25420218818` - 현재 HEAD의 authoritative spec 승인: #67 - 사용: gitea-agent 하네스 scoped `gitea-code-review` v0.1.2 및 canonical native admission/publication/readback. ### 범위 및 이전 지적 이전 code review #63의 HEAD `3b5101128d5a2cf038b8fb84facfd9d176928c26` 이후 28개 변경 경로, 영향받는 호출자/선택/마감/이관 경계와 테스트 및 evidence를 검토했다. 이전 검토 경로 중 59개는 byte-identical이며, 두 집합의 합이 현재 전체 base-to-head 87개 변경 파일과 정확히 일치한다. 별도 static worker 결과는 후보로만 사용했고 최종 판단과 재현은 main reviewer가 수행했다. 기존 **F-001~F-005의 지정 재현 경로는 해소**됐다: - F-001: public redaction 전 동일 fingerprint로 preview→close 성공; authority 변경 시 무변경 실패 회귀가 있다. - F-002: 최초/정정/mixed-as-of 응답과 candidate warning 및 snapshot ID 순서를 frozen evidence로 재구성한다. 독립 최초/정정 replay equality와 다중 정정 회귀가 통과했다. - F-003: zero-row conditional run도 timeseries에서 최신 run/승인/provenance와 함께 반환한다. 독립 0원 point 재현이 통과했다. - F-004: 신규 closed report가 frozen valuation_id/currency를 복원하며, live 평가 변경 후에도 기존 identity가 유지된다. legacy valuation ID를 추측하지 않는 테스트가 있다. - F-005: 기준일만 있거나 빈/부적합 금액인 입력은 쓰기 전에 거부하며, 0 및 signed integer와 정상 후속 dated import는 보존한다. 독립 no-init rejection 및 named no-mutation regressions가 통과했다. ### F-006 · High — schema 11의 기존 마감 보고가 현재 평가값으로 대체됨 - **위치:** `jarca_ledger_mcp/application/assets_service.py:327-332`, `:948-954`, `:986-1007`. - **발생 조건:** 기존 schema 11에서 실제 `close_asset_snapshot`으로 만든 snapshot rows가 있고, 현재 수기 평가액을 바꾼 뒤 schema 12로 이관한다. schema 11에는 `asset_snapshot_runs` 테이블/record가 없고, 기존 run 정보는 snapshot rows의 run/correction columns에 있다. - **실패:** `_snapshot_rows_for_latest_run`은 새 run record가 없으면 snapshot_run_id를 빈 값으로 반환한다. report는 이를 미마감으로 판정하고 legacy rows를 읽었어도 live included/excluded가 있으면 legacy 반환 분기를 건너뛰어 현재 평가값을 반환한다. - **직접 재현:** 합성 수기 자산 100으로 2026-06-30을 마감하고 현재값을 200으로 변경했다. base/schema 11의 마감 보고는 여전히 **100**, closed=True다. 같은 DB의 복사본을 이관해 prior 및 current HEAD로 읽으면 **200**, source=live_authority, closed=False, snapshot_count=0을 반환한다. 물리 snapshot amount **100은 그대로 남아 있다**. 새 평가 근거의 선택이나 DB row 보존만으로 기존 마감 보고의 불변성이 보장되지 않는다. - **Origin:** base에서는 정상, prior-reviewed HEAD 및 current HEAD에서는 동일하게 실패한다. `_snapshot_rows_for_latest_run`은 prior/current에서 동일하다. **이번 재작업이 새로 만든 결함이 아니라 PR에서 이미 도입됐고 이전 code review에서 놓친 결함**이다. `finding-origin.json` 및 `legacy-probe-evidence.json`으로 구분했다. - **계약/영향:** 승인 Discovery의 기존 마감 보존, 기존 마감은 현재 평가 변경으로 자동 변경되지 않음, schema 11 additive/idempotent 이관 및 legacy 근거 보존 경계를 위반한다. 과거 마감 보고와 이를 읽는 월정산 소비자가 현재 평가액을 과거 확정액으로 보여줄 수 있으므로 approval 전에 해결해야 하는 material correctness defect다. 선택적 기능/일반 기술부채로 분리할 수 없다. - **제한된 수정 방향:** 새 run record가 없는 legacy 마감에서도 기존 row-based 최신 run/정정 선택을 보존하고 frozen snapshot 금액을 조회 정본으로 사용한다. valuation_id나 승인 근거를 추측하지 말고 legacy임을 명시한다. live fallback은 실제 마감 근거가 없는 경우와 구분한다. - **재검증:** actual base/schema-11 close로 생성한 자료를 이관한 뒤 live 평가액/기준일을 바꿔도 기존 날짜 보고의 frozen total 및 최신 legacy correction 선택이 유지되어야 한다. read-only, schema/금융 rows 불변, legacy ID 비추론 및 월정산/시계열 소비자 회귀를 함께 확인한다. ### 비차단 N-001 — 미출시 PR 중간 HEAD의 fingerprint 형식 호환 `assets_service.py:713-716`, `:753-756`에서 prior PR HEAD의 단일 SHA fingerprint를 가진 idempotency run은 current HEAD에서 같은 key로 재실행해도 idempotency_conflict다. worker 후보를 main reviewer가 재현했다. 그러나 main/schema-11 base에는 해당 테이블과 idempotency 인수가 없으므로 **기존 배포 baseline의 replay 회귀로 오분류하지 않는다**. 중간 PR 버전으로 생성한 DB의 지원/사전배포 계약은 확인되지 않았다. 이를 지원해야 한다면 fingerprint version/legacy comparison 및 no-write replay 테스트로 별도 처리한다. 이 항목만으로 변경 요청하지 않는다. ### 실행 및 evidence Reviewer가 exact current HEAD에서 credential-free child 환경, 기존 project venv, 격리된 local `/tmp` DB/fixture로 직접 실행했다: - 전체 pytest: **291 passed, 4 skipped, 0 failed, 0 errors**, exit 0. - `ruff check --no-cache .`: exit 0. - 변경 Python 50개 in-memory syntax compile 및 `git diff --check BASE HEAD`: 통과. - F-001~F-005 독립 synthetic probes: exit 0. - Base/prior/current Git blob을 memory loader로 실행한 legacy probe: exit 0. 제품 checkout이나 source를 수정하지 않았다. 마지막 성공 probe에서 확정된 출력만 결함 근거로 사용했다. - review-63/64/65/66 manifest의 각 source revision blob OID/SHA-256을 확인했다. 최신 review-66의 11개 실행 입력은 current HEAD와 동일하다. 과거 manifest는 역사적 근거이며, 위 reviewer 전체 테스트는 별도 실제 실행이다. ### 한계와 결론 4개 private KB/Toss PDF fixture/password 테스트는 skip이다. 실제 금융 자료, 운영 DB, 새 real-browser 탐색, 배포를 실행하지 않았다. Dashboard/auth/menu 등 기존 테스트는 전체 suite에 포함됐다. exact-head API status는 빈 목록이며 remote CI 성공으로 표현하지 않는다. 기존 5건 해소와 green suite만으로 승인하지 않는다. 실제 schema-11 upgrade/report 불변성의 F-006이 남아 **request_changes**다. 재리뷰 범위는 해당 legacy-preservation 결함과 필요한 소비자 회귀로 한정하고 자동 무제한 재작업을 시작하지 않는다. Source/Discovery/Issue state 변경, commit/push/merge/배포는 수행하지 않는다. Redacted 상세 기록: `/opt/data/gitea-agent/logs/gitea-review-agent/runs/issue-12-pr-13-20261008T001536Z/`.
gitea-impl-agent added 1 commit 2026-10-08 03:35:02 +00:00
Author
Owner

구현 재작업 결과

지적 처리

  • F-006-schema11-frozen-close — resolved
    • 분류: valid_fix
    • 변경: jarca_ledger_mcp/application/assets_service.py, tests/test_legacy_snapshot_migration.py
    • 검증: named RED→GREEN; focused regressions exit 0; canonical full suite exit 0; fresh exact-head independent specification/code/security/provenance gate PASS
    • 근거: migrated schema 11 row-level latest close and correction remain frozen across report, timeseries, and monthly read-only consumers
  • EV-001-canonical-manifest — resolved
    • 분류: evidence_gap
    • 변경: external Issue verification root; tracked verification evidence removed from the product tree
    • 검증: evidence-manifest/v2 validate exit 0; result success; all five recorded commands exit 0; manifest SHA-256 aa76420a682554fb858897dca3fec86e3f693905d706d4e14abe4b6f7e1791eb
    • 근거: user-authorized verification parent correction to mode 0700 and strict-clean exact-head evidence generation completed; run directory is 0700 and evidence files are 0600

최종 검증

  • Local checks: exact head 4b8b74ba2adbc4a752c9139c5161b31e104da763; canonical focused and full pytest exit 0; Ruff, diff-check, docs/verification absence, and evidence-manifest/v2 validation exit 0; fresh independent gate PASS with findings 0
  • Runtime/browser: 해당 없음; Review 68 계약은 SQLite migration read-model invariant이며 browser 변경 없음
  • Commit status: pending
  • Actions runs: 없음

다음 단계

Reviewer가 rework head를 새 snapshot으로 다시 검토해야 하며 이 comment는 기존 REQUEST_CHANGES를 해제하거나 승인을 의미하지 않는다.

## 구현 재작업 결과 - Source Issue: #12 - Pull Request: #13 - Source Review: #68 - Reviewed head: `432e6f851a2623c5b12608cfa7636d3544225f28` - Rework head: `4b8b74ba2adbc4a752c9139c5161b31e104da763` - Contract SHA-256: `6d86b591b022fcc722611bfec6d24e54a64216ab6f7c4098f357e25420218818` - Result: `rework_delivered` ### 지적 처리 - F-006-schema11-frozen-close — `resolved` - 분류: valid_fix - 변경: jarca_ledger_mcp/application/assets_service.py, tests/test_legacy_snapshot_migration.py - 검증: named RED→GREEN; focused regressions exit 0; canonical full suite exit 0; fresh exact-head independent specification/code/security/provenance gate PASS - 근거: migrated schema 11 row-level latest close and correction remain frozen across report, timeseries, and monthly read-only consumers - EV-001-canonical-manifest — `resolved` - 분류: evidence_gap - 변경: external Issue verification root; tracked verification evidence removed from the product tree - 검증: evidence-manifest/v2 validate exit 0; result success; all five recorded commands exit 0; manifest SHA-256 aa76420a682554fb858897dca3fec86e3f693905d706d4e14abe4b6f7e1791eb - 근거: user-authorized verification parent correction to mode 0700 and strict-clean exact-head evidence generation completed; run directory is 0700 and evidence files are 0600 ### 최종 검증 - Local checks: exact head 4b8b74ba2adbc4a752c9139c5161b31e104da763; canonical focused and full pytest exit 0; Ruff, diff-check, docs/verification absence, and evidence-manifest/v2 validation exit 0; fresh independent gate PASS with findings 0 - Runtime/browser: 해당 없음; Review 68 계약은 SQLite migration read-model invariant이며 browser 변경 없음 - Commit status: pending - Actions runs: 없음 ### 다음 단계 Reviewer가 rework head를 새 snapshot으로 다시 검토해야 하며 이 comment는 기존 `REQUEST_CHANGES`를 해제하거나 승인을 의미하지 않는다. <!-- gitea-agent:implementation-rework/v1 owner=jsfamily repository=jarca-ledger-mcp issue=12 pr=13 review=68 reviewed-head=432e6f851a2623c5b12608cfa7636d3544225f28 head=4b8b74ba2adbc4a752c9139c5161b31e104da763 contract-sha256=6d86b591b022fcc722611bfec6d24e54a64216ab6f7c4098f357e25420218818 result-sha256=226c714fb92f220a47b5f1e5ca982ad1ca62fb97e56a84b7212a424b16e06050 correlation=3c0e567daacc604370d0f51eaef5e8258650afa7eff4e5a24e6bbed4ec307076 -->
gitea-spec-agent left a comment
Owner

구현 명세 적합성 검토

Acceptance criteria 판정

  • C01-history — satisfied

    • 계약: 평가 계좌 FK, 기준일과 등록일, 대표 금액과 통화와 목적, 출처와 확인 상태, 증빙 식별자, 정정 연결과 사유 및 선택 시간 자료를 이력으로 보존한다.
    • 구현 근거: jarca_ledger_mcp/infrastructure/sqlite/schema.py, jarca_ledger_mcp/infrastructure/sqlite/migrations.py, jarca_ledger_mcp/application/account_valuation_service.py; 구현 위치 jarca_ledger_mcp/infrastructure/sqlite/schema.py:229-267, jarca_ledger_mcp/infrastructure/sqlite/migrations.py:157-173, jarca_ledger_mcp/application/account_valuation_service.py:133-257; actual named test 호출과 assertion: tests/test_account_valuations.py::test_account_valuation_schema_is_v12_and_idempotent:13-21 calls init_db twice and asserts schema_version=12 and all required valuation columns.; tests/test_account_valuations.py::test_register_same_idempotency_payload_reuses_row_and_changed_payload_conflicts:24-32 asserts same row/id reuse and changed-payload idempotency_conflict.; tests/test_account_valuations.py::test_correction_is_append_only_reasoned_and_single_child:48-59 asserts supersedes_id, correction_conflict, count=2, and corrected selection.; 정본 external evidence-manifest/v2의 source full SHA가 현재 head와 같고 plan 및 manifest digest와 3개 실행 입력 blob 및 5개 command/result binding을 독립 검증했다. 구현자 exact-head focused71 및 전체295통과와4skip 및1warning은 구현자 실행 증빙이며 reviewer 실행 또는 CI 성공이 아니다.
    • 테스트 근거: tests/test_account_valuations.py
    • 판정 근거: 승인된 Discovery를 현재 immutable source 및 실제 named test 호출과 assertion에 대조해 충족했다. 기존 승인이나 delegate PASS만 상속하지 않고 source와 evidence provenance를 검증했다. 제품 pytest 및 browser는 spec reviewer가 실행하지 않았다.
  • C02-money-metrics — satisfied

    • 계약: 금액 정밀도와 NULL 및 0을 보존하고 취득원가, 순납입액, 기관 표시 원금 금액과 정의 및 원문 명칭, 손익과 수익률의 계산 기준을 구분한다. 투자 대표 총평가액과 포함 현금 및 원금을 중복 합산하지 않는다.
    • 구현 근거: jarca_ledger_mcp/application/account_valuation_service.py, jarca_ledger_mcp/application/assets_service.py, jarca_ledger_mcp/infrastructure/sqlite/schema.py, docs/data-model.md, docs/requirements/req-003_account-valuation-history.md; 구현 위치 jarca_ledger_mcp/application/account_valuation_service.py:33-56, jarca_ledger_mcp/application/account_valuation_service.py:165-186, jarca_ledger_mcp/application/assets_service.py:486-525, jarca_ledger_mcp/infrastructure/sqlite/schema.py:229-267; actual named test 호출과 assertion: tests/test_issue_12_review59_account.py::test_valuation_round_trip_preserves_null_zero_and_physical_amount_mapping:11-34 asserts physical amount mapping and NULL/zero preservation.; tests/test_account_valuations.py::test_correction_preserves_optional_fields_unless_overridden:83-93 asserts cost_basis, net_contributed, profit, return_rate, principal, interest, fee, as_of_at and timezone preservation.; tests/test_issue_12_regressions.py::test_loan_representative_is_always_aggregated_as_liability:279-294 asserts total_assets=0, liabilities=100, net_worth=-100 and loan bucket.; 정본 external evidence-manifest/v2의 source full SHA가 현재 head와 같고 plan 및 manifest digest와 3개 실행 입력 blob 및 5개 command/result binding을 독립 검증했다. 구현자 exact-head focused71 및 전체295통과와4skip 및1warning은 구현자 실행 증빙이며 reviewer 실행 또는 CI 성공이 아니다.
    • 테스트 근거: tests/test_issue_12_review59_account.py, tests/test_account_valuations.py, tests/test_issue_12_regressions.py
    • 판정 근거: 승인된 Discovery를 현재 immutable source 및 실제 named test 호출과 assertion에 대조해 충족했다. 기존 승인이나 delegate PASS만 상속하지 않고 source와 evidence provenance를 검증했다. 제품 pytest 및 browser는 spec reviewer가 실행하지 않았다.
  • N01-loan-balance-definition — satisfied

    • 계약: 대출 평가 기록마다 대표 부채가 원금만인지 원금과 이자 및 수수료인지 필수로 명시하고 기본값으로 추정하지 않는다. 목적 alias가 필수 정의 계약을 우회하지 않는다.
    • 구현 근거: jarca_ledger_mcp/application/account_valuation_service.py, jarca_ledger_mcp/application/accounts_write_services.py, jarca_ledger_mcp/application/imports_service.py, docs/requirements/req-003_account-valuation-history.md, docs/data-model.md; 구현 위치 jarca_ledger_mcp/application/account_valuation_service.py:93-105, jarca_ledger_mcp/application/account_valuation_service.py:194-203, jarca_ledger_mcp/application/accounts_write_services.py:81-89, jarca_ledger_mcp/application/imports_service.py:37-41; actual named test 호출과 assertion: tests/test_account_valuation_edge_contracts.py::test_loan_balance_requires_representative_liability_definition:41-76 asserts missing definition validation_error and no persisted valuation.; tests/test_account_valuation_edge_contracts.py::test_direct_loan_candidate_requires_liability_definition_and_writes_nothing:133-147 and ::test_import_loan_candidate_requires_liability_definition_and_writes_nothing:148-158 assert both candidate paths fail without writes.; tests/test_account_valuation_edge_contracts.py::test_bank_to_loan_conversion_rejects_existing_undefined_valuation_without_mutation:8-29 asserts conversion rejection and unchanged account/history; ::test_bank_to_loan_conversion_without_valuations_remains_allowed:30-39 asserts compatibility.; 정본 external evidence-manifest/v2의 source full SHA가 현재 head와 같고 plan 및 manifest digest와 3개 실행 입력 blob 및 5개 command/result binding을 독립 검증했다. 구현자 exact-head focused71 및 전체295통과와4skip 및1warning은 구현자 실행 증빙이며 reviewer 실행 또는 CI 성공이 아니다.
    • 테스트 근거: tests/test_account_valuation_edge_contracts.py, tests/test_issue_12_regressions.py, tests/test_issue_12_review59_account.py
    • 판정 근거: 승인된 Discovery를 현재 immutable source 및 실제 named test 호출과 assertion에 대조해 충족했다. 기존 승인이나 delegate PASS만 상속하지 않고 source와 evidence provenance를 검증했다. 제품 pytest 및 browser는 spec reviewer가 실행하지 않았다.
  • C03-selection — satisfied

    • 계약: 계좌와 통화 및 평가 목적별 유효 자료를 선택한다. exact는 당일 확인 자료만, as_of는 기준일 이하 최신 확인 자료만 사용한다. 미래 자료는 제외하고 미확인 후보는 확인 자료를 대체하거나 합산하지 않는다. 실제 기준일과 경과 일수 및 이월 상태를 반환한다.
    • 구현 근거: jarca_ledger_mcp/application/account_valuation_service.py, jarca_ledger_mcp/application/assets_service.py; 구현 위치 jarca_ledger_mcp/application/account_valuation_service.py:270-312, jarca_ledger_mcp/application/assets_service.py:151-206; actual named test 호출과 assertion: tests/test_account_valuations.py::test_select_exact_and_as_of_excludes_unverified_and_reports_carry_forward:35-45 asserts exact returns no valuation with unverified warning, as_of selects 1000, carried_forward=True and age=19.; tests/test_issue_12_regressions.py::test_preview_warns_about_unverified_candidate_when_verified_value_is_selected:339-364 asserts warning candidate status and persisted excluded evidence.; 정본 external evidence-manifest/v2의 source full SHA가 현재 head와 같고 plan 및 manifest digest와 3개 실행 입력 blob 및 5개 command/result binding을 독립 검증했다. 구현자 exact-head focused71 및 전체295통과와4skip 및1warning은 구현자 실행 증빙이며 reviewer 실행 또는 CI 성공이 아니다.
    • 테스트 근거: tests/test_account_valuations.py, tests/test_issue_12_regressions.py
    • 판정 근거: 승인된 Discovery를 현재 immutable source 및 실제 named test 호출과 assertion에 대조해 충족했다. 기존 승인이나 delegate PASS만 상속하지 않고 source와 evidence provenance를 검증했다. 제품 pytest 및 browser는 spec reviewer가 실행하지 않았다.
  • C04-correction-validation — satisfied

    • 계약: 평가 정정은 append-only로 대상과 사유를 연결하며 다른 계좌, 통화, 목적을 참조하는 정정과 순환 및 동일 유효본의 동시 분기를 차단한다.
    • 구현 근거: jarca_ledger_mcp/application/account_valuation_service.py, jarca_ledger_mcp/infrastructure/sqlite/schema.py; 구현 위치 jarca_ledger_mcp/application/account_valuation_service.py:204-253, jarca_ledger_mcp/application/account_valuation_service.py:315-375, jarca_ledger_mcp/infrastructure/sqlite/schema.py:264-267; actual named test 호출과 assertion: tests/test_issue_12_review59_account.py::test_direct_correction_requires_matching_existing_parent_and_reason:36-53 asserts missing/wrong parent and missing reason failures and valid correction.; tests/test_issue_12_review59_account.py::test_correction_rejects_self_parent_and_cycles_without_write:167-178 asserts rejection and unchanged history.; tests/test_account_valuations.py::test_correction_is_append_only_reasoned_and_single_child:48-59 asserts one child and original immutable selection.; 정본 external evidence-manifest/v2의 source full SHA가 현재 head와 같고 plan 및 manifest digest와 3개 실행 입력 blob 및 5개 command/result binding을 독립 검증했다. 구현자 exact-head focused71 및 전체295통과와4skip 및1warning은 구현자 실행 증빙이며 reviewer 실행 또는 CI 성공이 아니다.
    • 테스트 근거: tests/test_issue_12_review59_account.py, tests/test_account_valuations.py, tests/test_issue_12_regressions.py
    • 판정 근거: 승인된 Discovery를 현재 immutable source 및 실제 named test 호출과 assertion에 대조해 충족했다. 기존 승인이나 delegate PASS만 상속하지 않고 source와 evidence provenance를 검증했다. 제품 pytest 및 browser는 spec reviewer가 실행하지 않았다.
  • C05-current-import — satisfied

    • 계약: 뒤늦은 과거 자료 등록으로 최신 표시값을 과거로 되돌리지 않는다. 기존 계좌 수정과 import의 최신 캐시 및 새 이력 권위를 연결하며 동기화 시각을 실제 평가일로 오인하지 않는다.
    • 구현 근거: jarca_ledger_mcp/application/accounts_write_services.py, jarca_ledger_mcp/application/imports_service.py, jarca_ledger_mcp/application/assets_service.py; 구현 위치 jarca_ledger_mcp/application/accounts_write_services.py:49-106, jarca_ledger_mcp/application/imports_service.py:37-49, jarca_ledger_mcp/application/assets_service.py:131-214; actual named test 호출과 assertion: tests/test_issue_12_regressions.py::test_historical_account_update_preserves_current_and_adds_one_candidate:76-83 asserts current 900/2026-06-30 remains and exactly one historical candidate is added.; tests/test_account_valuations.py::test_account_balance_write_records_unverified_candidate_only_with_real_basis_date:62-69 asserts dated candidate is unverified and undated balance creates none.; tests/test_import_current_balance_authority.py::test_account_write_sync_timestamp_does_not_infer_balance_basis_or_candidate:225-249 and ::test_unknown_legacy_balance_basis_is_not_reported_as_valuation_date:250-267 assert no inferred basis/candidate and unknown legacy date reporting.; 정본 external evidence-manifest/v2의 source full SHA가 현재 head와 같고 plan 및 manifest digest와 3개 실행 입력 blob 및 5개 command/result binding을 독립 검증했다. 구현자 exact-head focused71 및 전체295통과와4skip 및1warning은 구현자 실행 증빙이며 reviewer 실행 또는 CI 성공이 아니다.
    • 테스트 근거: tests/test_issue_12_regressions.py, tests/test_account_valuations.py, tests/test_import_current_balance_authority.py, tests/test_issue_12_review59_account.py, tests/test_import_provenance_policy.py, tests/test_account_basis_public_consumers.py, tests/test_issue_12_review63_accounts.py
    • 판정 근거: 승인된 Discovery를 현재 immutable source 및 실제 named test 호출과 assertion에 대조해 충족했다. 기존 승인이나 delegate PASS만 상속하지 않고 source와 evidence provenance를 검증했다. 제품 pytest 및 browser는 spec reviewer가 실행하지 않았다.
  • C06-idempotency — satisfied

    • 계약: 동일 증빙 또는 idempotency 재입력은 동일 기록을 재사용하며 같은 키의 다른 payload는 충돌이다. 동시 정정의 분기를 차단하고 UNIQUE 계좌 및 기준일 하나로 정정 추가를 막지 않는다.
    • 구현 근거: jarca_ledger_mcp/application/account_valuation_service.py, jarca_ledger_mcp/application/assets_service.py, jarca_ledger_mcp/infrastructure/sqlite/schema.py, jarca_ledger_mcp/infrastructure/sqlite/migrations.py, jarca_ledger_mcp/application/accounts_write_services.py, jarca_ledger_mcp/application/imports_service.py; 구현 위치 jarca_ledger_mcp/application/account_valuation_service.py:107-125, jarca_ledger_mcp/application/account_valuation_service.py:225-244, jarca_ledger_mcp/application/assets_service.py:729-826; actual named test 호출과 assertion: tests/test_account_valuations.py::test_register_same_idempotency_payload_reuses_row_and_changed_payload_conflicts:24-32 asserts reuse and conflict.; tests/test_issue_12_review59_account.py::test_source_ref_conflicts_even_when_idempotency_keys_differ:207-219 asserts source identity conflict.; tests/test_issue_12_regressions.py::test_snapshot_close_idempotency_fingerprint_and_concurrent_first_close:128-163 asserts exact replay equality, changed payload/evidence conflict and one concurrent run.; tests/test_issue_12_regressions.py::test_concurrent_correction_idempotency_reuses_same_payload:251-267 asserts one correction id and reused flags.; 정본 external evidence-manifest/v2의 source full SHA가 현재 head와 같고 plan 및 manifest digest와 3개 실행 입력 blob 및 5개 command/result binding을 독립 검증했다. 구현자 exact-head focused71 및 전체295통과와4skip 및1warning은 구현자 실행 증빙이며 reviewer 실행 또는 CI 성공이 아니다.
    • 테스트 근거: tests/test_account_valuations.py, tests/test_issue_12_review59_account.py, tests/test_issue_12_regressions.py, tests/test_account_valuation_edge_contracts.py
    • 판정 근거: 승인된 Discovery를 현재 immutable source 및 실제 named test 호출과 assertion에 대조해 충족했다. 기존 승인이나 delegate PASS만 상속하지 않고 source와 evidence provenance를 검증했다. 제품 pytest 및 browser는 spec reviewer가 실행하지 않았다.
  • C07-close-immutability — satisfied

    • 계약: 기존 asset_snapshots와 correction run을 보존하고 평가 정정 및 거래 추가로 기존 마감을 자동 변경하지 않는다. 동일 기준일 재마감은 사유와 이전 run 연결을 가진 새 버전을 원자적으로 추가한다.
    • 구현 근거: jarca_ledger_mcp/application/assets_service.py, jarca_ledger_mcp/infrastructure/sqlite/schema.py, jarca_ledger_mcp/infrastructure/sqlite/migrations.py; 구현 위치 jarca_ledger_mcp/application/assets_service.py:714-865, jarca_ledger_mcp/application/assets_service.py:889-939; actual named test 호출과 assertion: tests/test_asset_snapshots.py::test_snapshot_rows_are_append_only_and_timeseries_uses_same_formula:53-74 asserts old rows remain and timeseries uses the same formula.; tests/test_issue_12_review63_assets.py::test_f002_correction_replay_preserves_full_initial_response:67-94 asserts correction replay and initial replay equality.; tests/test_issue_12_review63_assets.py::test_f006_initial_replay_survives_multiple_later_corrections:97-138 asserts initial replay survives two corrections and unrelated live drift conflicts.; 정본 external evidence-manifest/v2의 source full SHA가 현재 head와 같고 plan 및 manifest digest와 3개 실행 입력 blob 및 5개 command/result binding을 독립 검증했다. 구현자 exact-head focused71 및 전체295통과와4skip 및1warning은 구현자 실행 증빙이며 reviewer 실행 또는 CI 성공이 아니다. Review68 F006은 assets_service.py:327-358,974-1014,1077-1129의 row-level legacy run 선택과 frozen report 및 downstream 공유로 해소됐다. tests/test_legacy_snapshot_migration.py:39-146은 금액과 correction grouping 및 approval 비추론과 valuation_id 비추론, report 및 monthly 및 timeseries와 DB hash 불변을 assertion한다.
    • 테스트 근거: tests/test_asset_snapshots.py, tests/test_issue_12_review63_assets.py, tests/test_issue_12_regressions.py, tests/test_legacy_snapshot_migration.py
    • 판정 근거: 승인된 Discovery를 현재 immutable source 및 실제 named test 호출과 assertion에 대조해 충족했다. 기존 승인이나 delegate PASS만 상속하지 않고 source와 evidence provenance를 검증했다. 제품 pytest 및 browser는 spec reviewer가 실행하지 않았다.
  • N02-close-replay-run-binding — satisfied

    • 계약: 마감 버전의 근거는 불변이며 동일 idempotency 요청은 원래 기록을 재사용한다. 재마감으로 과거 run 응답 및 evidence를 변경하지 않는다.
    • 구현 근거: jarca_ledger_mcp/application/assets_service.py, docs/interface-contract.md; 구현 위치 jarca_ledger_mcp/application/assets_service.py:272-324, jarca_ledger_mcp/application/assets_service.py:743-826, jarca_ledger_mcp/application/assets_service.py:827-939; actual named test 호출과 assertion: tests/test_asset_snapshot_idempotency.py::test_exact_run_replay_after_correction_reconstructs_original_persisted_run:131-207 asserts original run ID/rows/metadata are reconstructed after correction.; tests/test_asset_snapshot_idempotency.py::test_empty_run_replay_after_nonempty_correction_preserves_original_empty_payload:208-286 asserts zero-row original response remains exact after later nonempty correction.; tests/test_issue_12_review63_assets.py::test_f006_initial_replay_survives_multiple_later_corrections:97-138 asserts first replay equality and unrelated live-authority drift conflict.; 정본 external evidence-manifest/v2의 source full SHA가 현재 head와 같고 plan 및 manifest digest와 3개 실행 입력 blob 및 5개 command/result binding을 독립 검증했다. 구현자 exact-head focused71 및 전체295통과와4skip 및1warning은 구현자 실행 증빙이며 reviewer 실행 또는 CI 성공이 아니다.
    • 테스트 근거: tests/test_asset_snapshot_idempotency.py, tests/test_issue_12_review63_assets.py, tests/test_issue_12_review59_reports.py, tests/test_issue_12_regressions.py
    • 판정 근거: 승인된 Discovery를 현재 immutable source 및 실제 named test 호출과 assertion에 대조해 충족했다. 기존 승인이나 delegate PASS만 상속하지 않고 source와 evidence provenance를 검증했다. 제품 pytest 및 browser는 spec reviewer가 실행하지 않았다.
  • C08-approved-conditional — satisfied

    • 계약: 완전한 exact 마감, 미완료 초안, 별도 승인된 조건부 마감을 구분한다. 승인 전 누락 및 이월은 미완료 초안이고 승인 후에도 누락 제외 및 확인된 과거값 이월만 허용한다. 미확인, 미래, 기준일 미상 금액은 승인으로도 합산하지 않으며 적용과 제외와 이월 및 승인자와 시각과 사유와 근거를 고정한다.
    • 구현 근거: jarca_ledger_mcp/application/assets_service.py, jarca_ledger_mcp/infrastructure/sqlite/schema.py, dashboard/page_views/assets.py; 구현 위치 jarca_ledger_mcp/application/assets_service.py:672-697, jarca_ledger_mcp/application/assets_service.py:725-735, jarca_ledger_mcp/application/assets_service.py:887-937; actual named test 호출과 assertion: tests/test_issue_12_regressions.py::test_preview_marks_approval_eligible_missing_valuation_as_incomplete_draft:34-40 asserts incomplete_draft and missing valuation warning.; tests/test_issue_12_review59_reports.py::test_approved_carried_close_is_conditional_and_persists_provenance:22-55 asserts conditional status, persisted carry evidence and exact approval metadata.; tests/test_issue_12_regressions.py::test_empty_conditional_close_is_closed_and_second_close_requires_correction:16-31 asserts zero-row conditional closure and correction requirement.; 정본 external evidence-manifest/v2의 source full SHA가 현재 head와 같고 plan 및 manifest digest와 3개 실행 입력 blob 및 5개 command/result binding을 독립 검증했다. 구현자 exact-head focused71 및 전체295통과와4skip 및1warning은 구현자 실행 증빙이며 reviewer 실행 또는 CI 성공이 아니다.
    • 테스트 근거: tests/test_issue_12_regressions.py, tests/test_issue_12_review59_reports.py, tests/test_asset_snapshots.py, tests/test_issue_12_review63_assets.py
    • 판정 근거: 승인된 Discovery를 현재 immutable source 및 실제 named test 호출과 assertion에 대조해 충족했다. 기존 승인이나 delegate PASS만 상속하지 않고 source와 evidence provenance를 검증했다. 제품 pytest 및 browser는 spec reviewer가 실행하지 않았다.
  • C09-reconciliation — satisfied

    • 계약: 외부 확인값과 장부 계산값을 분리하고 검증된 시작잔고, 기준시점, 거래 포함 범위와 계산 완전성을 표시한다. 거래 없는 수동 투자 계좌의 대사 불가 및 거래 미수입과 평가 수동 관리 상태를 구분하고 가짜 거래를 만들지 않는다. 대사도 공통 평가 근거와 대출 대표 정의를 사용한다.
    • 구현 근거: jarca_ledger_mcp/application/reconciliation_service.py, jarca_ledger_mcp/application/monthly_settlement_service.py, jarca_ledger_mcp/application/account_valuation_service.py; 구현 위치 jarca_ledger_mcp/application/reconciliation_service.py:31-213, jarca_ledger_mcp/application/monthly_settlement_service.py:1-120; actual named test 호출과 assertion: tests/test_issue_12_review59_reports.py::test_reconciliation_uses_currency_and_loan_priority_and_canonical_provenance:58-72 asserts selected valuation ID/kind/date/status.; tests/test_issue_12_review59_reports.py::test_investment_without_verified_valuation_and_without_opening_balance_is_incomplete:74-83 asserts VALUATION_UNAVAILABLE, incomplete, null difference/value.; tests/test_issue_12_review59_reports.py::test_reconciliation_does_not_mark_last_balance_without_opening_evidence_complete:102-108 asserts INCOMPLETE_CALCULATION.; 정본 external evidence-manifest/v2의 source full SHA가 현재 head와 같고 plan 및 manifest digest와 3개 실행 입력 blob 및 5개 command/result binding을 독립 검증했다. 구현자 exact-head focused71 및 전체295통과와4skip 및1warning은 구현자 실행 증빙이며 reviewer 실행 또는 CI 성공이 아니다.
    • 테스트 근거: tests/test_issue_12_review59_reports.py, tests/test_issue_12_regressions.py, tests/test_service.py
    • 판정 근거: 승인된 Discovery를 현재 immutable source 및 실제 named test 호출과 assertion에 대조해 충족했다. 기존 승인이나 delegate PASS만 상속하지 않고 source와 evidence provenance를 검증했다. 제품 pytest 및 browser는 spec reviewer가 실행하지 않았다.
  • C10-report-monthly-evidence — satisfied

    • 계약: MCP와 Dashboard 및 월정산 보고에서 같은 기준일과 선택 근거 및 실제 평가일, 경과 일수, 확인 상태, 누락과 미확인 및 이월 경고, 마감 버전 및 조건부 승인 근거를 일관되게 전달한다.
    • 구현 근거: jarca_ledger_mcp/application/assets_service.py, jarca_ledger_mcp/application/monthly_settlement_service.py, dashboard/page_views/monthly_settlement.py, dashboard/page_views/accounts.py; 구현 위치 jarca_ledger_mcp/application/assets_service.py:965-1059, jarca_ledger_mcp/application/assets_service.py:1062-1131, jarca_ledger_mcp/application/monthly_settlement_service.py:1-120; actual named test 호출과 assertion: tests/test_issue_12_review59_reports.py::test_timeseries_and_monthly_expose_canonical_asset_provenance:85-100 asserts provenance in report, timeseries and monthly payloads.; tests/test_issue_12_review59_reports.py::test_monthly_settlement_propagates_snapshot_provenance_id_and_actual_valuation_date:111-119 asserts monthly_source_snapshot_id, actual valuation_date, warnings/exclusions/carry.; tests/test_issue_12_review59_reports.py::test_approved_carry_provenance_is_identical_across_closed_downstream_reports:122-149 asserts equality across report, timeseries and monthly outputs.; tests/test_legacy_snapshot_migration.py::test_schema11_closed_rows_are_frozen_in_monthly_settlement:83-98 asserts legacy frozen amount and provenance propagation.; 정본 external evidence-manifest/v2의 source full SHA가 현재 head와 같고 plan 및 manifest digest와 3개 실행 입력 blob 및 5개 command/result binding을 독립 검증했다. 구현자 exact-head focused71 및 전체295통과와4skip 및1warning은 구현자 실행 증빙이며 reviewer 실행 또는 CI 성공이 아니다. Review68 F006은 assets_service.py:327-358,974-1014,1077-1129의 row-level legacy run 선택과 frozen report 및 downstream 공유로 해소됐다. tests/test_legacy_snapshot_migration.py:39-146은 금액과 correction grouping 및 approval 비추론과 valuation_id 비추론, report 및 monthly 및 timeseries와 DB hash 불변을 assertion한다.
    • 테스트 근거: tests/test_issue_12_review59_reports.py, tests/test_legacy_snapshot_migration.py, tests/test_issue_12_regressions.py, tests/test_service.py, tests/test_issue_12_review63_assets.py
    • 판정 근거: 승인된 Discovery를 현재 immutable source 및 실제 named test 호출과 assertion에 대조해 충족했다. 기존 승인이나 delegate PASS만 상속하지 않고 source와 evidence provenance를 검증했다. 제품 pytest 및 browser는 spec reviewer가 실행하지 않았다.
  • C11-adapter-structure — satisfied

    • 계약: MCP와 Streamlit gateway는 공통 application을 사용하고 기존 공개 호출명과 기존 인수 및 success와 실패 error_code 및 error envelope를 가능한 한 유지한다. 새 Dashboard 인증 또는 MCP 인증을 도입하지 않는다.
    • 구현 근거: jarca_ledger_mcp/service.py, jarca_ledger_mcp/adapters/mcp/server.py, jarca_ledger_mcp/adapters/streamlit/accounts_gateway.py, jarca_ledger_mcp/adapters/streamlit/assets_gateway.py, dashboard/page_views/accounts.py, dashboard/page_views/assets.py, jarca_ledger_mcp/adapters/mcp/tool_contracts.py, jarca_ledger_mcp/application/__init__.py, dashboard/page_views/monthly_settlement.py; 구현 위치 jarca_ledger_mcp/service.py:1-100, jarca_ledger_mcp/adapters/mcp/server.py, jarca_ledger_mcp/adapters/streamlit/accounts_gateway.py, jarca_ledger_mcp/adapters/streamlit/assets_gateway.py, dashboard/page_views/accounts.py, dashboard/page_views/assets.py; actual named test 호출과 assertion: tests/test_mcp_http_runtime.py::test_mcp_runtime_config_defaults_to_stdio and ::test_mcp_runtime_config_accepts_streamable_http_env:6-35 assert transport configuration.; tests/test_contract_regression.py::test_list_report_and_mutation_success_envelope_contract:117-145 asserts success/error envelopes and public calls.; tests/test_dashboard_app.py::test_authenticated_dashboard_all_pages_are_no_write:167-197 asserts authenticated page rendering does not mutate DB.; 정본 external evidence-manifest/v2의 source full SHA가 현재 head와 같고 plan 및 manifest digest와 3개 실행 입력 blob 및 5개 command/result binding을 독립 검증했다. 구현자 exact-head focused71 및 전체295통과와4skip 및1warning은 구현자 실행 증빙이며 reviewer 실행 또는 CI 성공이 아니다.
    • 테스트 근거: tests/test_mcp_http_runtime.py, tests/test_contract_regression.py, tests/test_dashboard_app.py, tests/test_issue_12_regressions.py
    • 판정 근거: 승인된 Discovery를 현재 immutable source 및 실제 named test 호출과 assertion에 대조해 충족했다. 기존 승인이나 delegate PASS만 상속하지 않고 source와 evidence provenance를 검증했다. 제품 pytest 및 browser는 spec reviewer가 실행하지 않았다.
  • C12-migration-legacy — satisfied

    • 계약: schema 11의 기존 데이터와 마감 및 개인정보를 보존하고 additive하고 idempotent한 migration을 제공한다. 기준일 증거 없는 값을 임의 월말로 소급하거나 legacy snapshot에 valuation_id를 추측하여 생성하지 않는다.
    • 구현 근거: jarca_ledger_mcp/infrastructure/sqlite/migrations.py, jarca_ledger_mcp/application/assets_service.py, tests/test_legacy_snapshot_migration.py, jarca_ledger_mcp/infrastructure/sqlite/schema.py; 구현 위치 jarca_ledger_mcp/infrastructure/sqlite/migrations.py:19-173, jarca_ledger_mcp/application/assets_service.py:327-358, jarca_ledger_mcp/application/assets_service.py:974-1014, tests/test_legacy_snapshot_migration.py:39-146; actual named test 호출과 assertion: tests/test_issue_12_regressions.py::test_schema12_migration_preserves_legacy_rows_indexes_and_is_idempotent:86-125 asserts old account/transaction/snapshot rows, old and new indexes, schema_version=12 after init twice.; tests/test_legacy_snapshot_migration.py::test_schema11_closed_rows_remain_frozen_after_live_value_and_date_change:39-63 asserts source=legacy_asset_snapshots, closed=True, net_worth=100, frozen item amount and DB hash unchanged.; tests/test_legacy_snapshot_migration.py::test_schema11_latest_legacy_correction_run_is_selected_as_a_complete_group:101-146 asserts latest legacy run grouping, rows, amount 150, correction metadata, no invented valuation_id and unchanged DB hash.; 정본 external evidence-manifest/v2의 source full SHA가 현재 head와 같고 plan 및 manifest digest와 3개 실행 입력 blob 및 5개 command/result binding을 독립 검증했다. 구현자 exact-head focused71 및 전체295통과와4skip 및1warning은 구현자 실행 증빙이며 reviewer 실행 또는 CI 성공이 아니다. Review68 F006은 assets_service.py:327-358,974-1014,1077-1129의 row-level legacy run 선택과 frozen report 및 downstream 공유로 해소됐다. tests/test_legacy_snapshot_migration.py:39-146은 금액과 correction grouping 및 approval 비추론과 valuation_id 비추론, report 및 monthly 및 timeseries와 DB hash 불변을 assertion한다.
    • 테스트 근거: tests/test_issue_12_regressions.py, tests/test_legacy_snapshot_migration.py, tests/test_account_valuations.py, tests/test_ledger_categories.py, tests/test_review_decision_workbench.py
    • 판정 근거: 승인된 Discovery를 현재 immutable source 및 실제 named test 호출과 assertion에 대조해 충족했다. 기존 승인이나 delegate PASS만 상속하지 않고 source와 evidence provenance를 검증했다. 제품 pytest 및 browser는 spec reviewer가 실행하지 않았다.
  • C13-read-only — satisfied

    • 계약: preview와 조회 및 Dashboard 렌더링은 금융 쓰기를 실행하지 않는다. 명시적 등록, 정정, 승인 close 및 import 제출만 변경을 수행하고 실패 시 부분 쓰기를 남기지 않는다.
    • 구현 근거: jarca_ledger_mcp/infrastructure/sqlite/connection.py, jarca_ledger_mcp/application/assets_service.py, jarca_ledger_mcp/application/shared.py, jarca_ledger_mcp/application/system_services.py, jarca_ledger_mcp/application/account_valuation_service.py; 구현 위치 jarca_ledger_mcp/infrastructure/sqlite/connection.py:31-69, jarca_ledger_mcp/application/assets_service.py:672-697, jarca_ledger_mcp/application/assets_service.py:965-1131; actual named test 호출과 assertion: tests/test_issue_12_review59_readonly.py::test_read_queries_missing_nested_db_return_stable_error_without_creating_path:25-42 asserts stable missing-DB error and no path creation.; tests/test_issue_12_review59_readonly.py::test_read_only_connection_rejects_writes_and_does_not_commit:44-54 asserts read-only write rejection/no commit.; tests/test_issue_12_review59_readonly.py::test_read_suite_does_not_initialize_or_change_initialized_database:56-75 asserts hash and schema/rows unchanged.; 정본 external evidence-manifest/v2의 source full SHA가 현재 head와 같고 plan 및 manifest digest와 3개 실행 입력 blob 및 5개 command/result binding을 독립 검증했다. 구현자 exact-head focused71 및 전체295통과와4skip 및1warning은 구현자 실행 증빙이며 reviewer 실행 또는 CI 성공이 아니다.
    • 테스트 근거: tests/test_issue_12_review59_readonly.py, tests/test_dashboard_app.py, tests/test_dashboard_menu_transition.py
    • 판정 근거: 승인된 Discovery를 현재 immutable source 및 실제 named test 호출과 assertion에 대조해 충족했다. 기존 승인이나 delegate PASS만 상속하지 않고 source와 evidence provenance를 검증했다. 제품 pytest 및 browser는 spec reviewer가 실행하지 않았다.
  • C14-auth-menu-preservation — satisfied

    • 계약: Dashboard 인증은 DB보다 먼저이며 REQ-001의 cookie와 logout 및 REQ-002의 메뉴 label과 order, shell, query, error와 retry 및 명시적 금융 쓰기 계약을 유지한다.
    • 구현 근거: dashboard/app.py, dashboard/authentication.py, dashboard/page_views/accounts.py, dashboard/page_views/assets.py, dashboard/page_views/monthly_settlement.py, docs/interface-contract.md, docs/project-structure.md, docs/runtime-flow.md; 구현 위치 dashboard/app.py:37-72, dashboard/authentication.py, dashboard/page_views/accounts.py, dashboard/page_views/assets.py, dashboard/page_views/monthly_settlement.py; actual named test 호출과 assertion: tests/test_dashboard_authentication_app.py::test_main_does_not_resolve_database_or_dispatch_when_authentication_rejects:67-80 asserts rejected auth prevents DB/page dispatch.; tests/test_dashboard_authentication_app.py::test_invalid_cookie_blocks_database_and_page_dispatch:105-112 asserts invalid cookie blocks access.; tests/test_dashboard_menu_transition.py::test_dashboard_menu_labels_and_order_are_preserved:18-30 and ::test_streamlit_menu_click_updates_body_and_preserves_page_query_siblings:83-108 assert labels/order and query/shell behavior.; 정본 external evidence-manifest/v2의 source full SHA가 현재 head와 같고 plan 및 manifest digest와 3개 실행 입력 blob 및 5개 command/result binding을 독립 검증했다. 구현자 exact-head focused71 및 전체295통과와4skip 및1warning은 구현자 실행 증빙이며 reviewer 실행 또는 CI 성공이 아니다.
    • 테스트 근거: tests/test_dashboard_authentication_app.py, tests/test_dashboard_menu_transition.py, tests/test_dashboard_app.py
    • 판정 근거: 승인된 Discovery를 현재 immutable source 및 실제 named test 호출과 assertion에 대조해 충족했다. 기존 승인이나 delegate PASS만 상속하지 않고 source와 evidence provenance를 검증했다. 제품 pytest 및 browser는 spec reviewer가 실행하지 않았다.
  • C15-exclusions-privacy — satisfied

    • 계약: 증권사 자동 연동, 정확한 성과 또는 환율 엔진, 새 인증, 별도 월정산 제품, 거래 추론 및 기존 데이터 자동 재작성과 수기 비계좌 자산 전체 이력 재설계를 추가하지 않는다. 실제 계좌 및 금융 증빙과 credential을 로그와 문서 및 테스트에 기록하지 않는다.
    • 구현 근거: jarca_ledger_mcp/application/assets_service.py, jarca_ledger_mcp/application/account_valuation_service.py, jarca_ledger_mcp/provenance_policy.py, docs/requirements/req-003_account-valuation-history.md, jarca_ledger_mcp/application/imports_service.py, jarca_ledger_mcp/application/reconciliation_service.py, jarca_ledger_mcp/infrastructure/sqlite/schema.py, jarca_ledger_mcp/infrastructure/sqlite/migrations.py; 구현 위치 jarca_ledger_mcp/application/assets_service.py:62-75, jarca_ledger_mcp/application/account_valuation_service.py:29-30, jarca_ledger_mcp/provenance_policy.py, docs/requirements/req-003_account-valuation-history.md:163-185; actual named test 호출과 assertion: tests/test_issue_12_regressions.py::test_warning_candidate_public_payload_is_minimal:316-321 asserts only five non-sensitive candidate fields.; tests/test_issue_12_regressions.py::test_snapshot_report_redacts_unverified_candidate_sensitive_fields:324-336 asserts TOPSECRET/PASSWORD absent and candidate keys allowlisted.; tests/test_issue_12_review59_reports.py::test_preview_and_live_report_redact_excluded_source_note_and_memo:152-167 and ::test_public_included_items_redact_source_note_and_memo_recursively:190-206 assert recursive redaction.; 정본 external evidence-manifest/v2의 source full SHA가 현재 head와 같고 plan 및 manifest digest와 3개 실행 입력 blob 및 5개 command/result binding을 독립 검증했다. 구현자 exact-head focused71 및 전체295통과와4skip 및1warning은 구현자 실행 증빙이며 reviewer 실행 또는 CI 성공이 아니다.
    • 테스트 근거: tests/test_issue_12_regressions.py, tests/test_issue_12_review59_reports.py, scripts/ci_fixture_db.py
    • 판정 근거: 승인된 Discovery를 현재 immutable source 및 실제 named test 호출과 assertion에 대조해 충족했다. 기존 승인이나 delegate PASS만 상속하지 않고 source와 evidence provenance를 검증했다. 제품 pytest 및 browser는 spec reviewer가 실행하지 않았다.
  • D01-requirement-structure — satisfied

    • 계약: 신규 REQ-003을 배정 경로와 제목으로 작성하며 trusted harness README와 TEMPLATE의 JSON metadata, 연속 요구사항 및 AC, 필수 섹션, 판정 기준과 검증 및 검증 분류의 수준과 백엔드와 케이스 및 상태 불변조건을 충족한다. 초기 PR은 미정이며 PR 생성 후 실제 번호를 추적한다.
    • 구현 근거: docs/requirements/req-003_account-valuation-history.md; 구조: Front matter at lines 1-13 has gitea-agent.requirement/v1, REQ-003, exact title, revision 1.0, approved status, language ko; H1/title at 16; required sections 1-11 are present; requirements REQ-003.01 through .10 are contiguous at 53-173; ACs REQ-003.01-AC01 through .10-AC01 are contiguous at 189-297; traceability is at 311-317.; 의미: Discovery obligations: req-003 title/path/ID and lifecycle at discovery.md:76-87; document content at req-003:1-16, 311-317.; Core valuation, exact/as_of, future exclusion, loan definition and optional metrics at req-003:65-115, 175-185.; Conditional close and explicit approval at req-003:113-127, 244-264.; REQ-001/REQ-002 preservation and Issue12/PR13 traceability at req-003:307-317. PR PR13 is valid for this real PR; the trusted template's initial-writing default of 미정 is not a defect after PR creation.; 현재 full 문서와 trusted policy 및 pinned source와 named tests를 직접 대조했다. 이전 head의 전체 문서 bytes와 현재 bytes가 같고 REQ003 전체 AC 의미를 보존한다.
    • 테스트 근거: tests/test_requirement_docs.py
    • 판정 근거: 승인된 산출물의 구조와 의미를 별도로 검토했다. 초기 작성시 미정은 실제 PR 생성 후 PR13으로 추적되는 lifecycle 계약이며 새로운 실행 증빙 경로나 독립 browser 조합을 요구하지 않는다.
  • D02-requirement-semantics — satisfied

    • 계약: 요구사항에는 평가 근거와 지표 정의, 선택과 future 제외, 정정 및 idempotency 충돌, 대사 완전성, current 및 import 연계, 마감 상태와 불변성과 승인, shared adapter 및 인증, migration과 legacy를 소스 및 테스트에 대응한다. 모든 승인된 경계와 회귀 사례를 인수 기준으로 내린다.
    • 구현 근거: docs/requirements/req-003_account-valuation-history.md; 구조: Front matter at lines 1-13 has gitea-agent.requirement/v1, REQ-003, exact title, revision 1.0, approved status, language ko; H1/title at 16; required sections 1-11 are present; requirements REQ-003.01 through .10 are contiguous at 53-173; ACs REQ-003.01-AC01 through .10-AC01 are contiguous at 189-297; traceability is at 311-317.; 의미: Discovery obligations: req-003 title/path/ID and lifecycle at discovery.md:76-87; document content at req-003:1-16, 311-317.; Core valuation, exact/as_of, future exclusion, loan definition and optional metrics at req-003:65-115, 175-185.; Conditional close and explicit approval at req-003:113-127, 244-264.; REQ-001/REQ-002 preservation and Issue12/PR13 traceability at req-003:307-317. PR PR13 is valid for this real PR; the trusted template's initial-writing default of 미정 is not a defect after PR creation.; 현재 full 문서와 trusted policy 및 pinned source와 named tests를 직접 대조했다. 이전 head의 전체 문서 bytes와 현재 bytes가 같고 REQ003 전체 AC 의미를 보존한다.
    • 테스트 근거: tests/test_account_valuations.py, tests/test_asset_snapshots.py, tests/test_issue_12_regressions.py, tests/test_requirement_docs.py, tests/test_mcp_http_runtime.py, tests/test_dashboard_authentication_app.py
    • 판정 근거: 승인된 산출물의 구조와 의미를 별도로 검토했다. 초기 작성시 미정은 실제 PR 생성 후 PR13으로 추적되는 lifecycle 계약이며 새로운 실행 증빙 경로나 독립 browser 조합을 요구하지 않는다.
  • D03-data-model — satisfied

    • 계약: 신규 데이터 모델은 기존 entities 및 valuation과 마감의 관계, FK와 날짜 및 정확한 금액과 NULL 및 0과 선택 지표 및 대출 필수 정의, 계좌와 통화 및 목적과 기준일의 선택 및 index와 단일 유효 정정본, 고정 적용 분류 및 출처와 상태와 누락 및 이월 및 승인 버전, 분리된 정정과 schema11 이관 및 미상 날짜와 legacy 및 최신 캐시 동기화 책임을 정의한다.
    • 구현 근거: docs/data-model.md; docs/data-model.md:33-68은 실제 evaluation fields와 account 필수 및 currency/purpose 선택 필터, exact 또는 상한 basis-date, verified leaf 및 제외 규칙과 account/date 및 status/date 물리 index coverage와 한계를 명시한다. schema.py:264-267 및 account_valuation_service.py:270-312의 정본과 일치한다. :89-124 및 :147-157은 immutable run ID와 기존 run을 가리키는 correction 관계, insert-only 새 run/rows 및 latest-run authority, 각 run의 적용값과 approval evidence를 고정한다. docs/requirements/req-003_account-valuation-history.md:255-264는 기존 run/rows 보존 및 latest-run 단독 보고를 버전의 인수 기준으로 정한다. 전체 entity/FK/금액/loan/legacy/current-cache 계약은 :12-61 및 :70-176에 대응한다. tests/test_valuation_contract_docs.py:46-62와 테스트의 actual assertions를 확인했다.
    • 테스트 근거: tests/test_account_valuations.py, tests/test_asset_snapshots.py, tests/test_issue_12_regressions.py, tests/test_valuation_contract_docs.py
    • 판정 근거: DOC001은 문서가 명시한 선택 필터와 실제 index coverage/한계를 누락으로 오분류하고 특정 복합 물리 index를 새로 강제하므로 채택하지 않는다. DOC002는 immutable run identity와 correction chain으로 정의된 마감 버전을 누락으로 오분류하고 별도 version column을 강제하므로 채택하지 않는다. 승인 계약은 특정 복합 index나 숫자 version column을 지정하지 않으며 보존 및 새 run의 버전 관계가 문서와 source 및 인수 기준으로 확인된다.
  • D04-interface-contract — satisfied

    • 계약: 인터페이스 문서는 기존 auth 및 메뉴를 보존하고 평가 등록 및 조회 및 정정의 모든 입력과 유효본 및 원금 정의 출력, report 및 preview/close 및 월정산과 대사와 current API의 공통 선택, exact 기본과 실제 날짜 및 age 및 이월과 누락 및 미확인과 출처 및 버전과 승인 출력을 정의한다. 잘못된 입력과 scope 및 충돌과 부족 근거는 무변경 실패이며 기존 envelope와 required keys 및 의미 변경 정책을 명시한다.
    • 구현 근거: docs/interface-contract.md, docs/data-model.md; 구조: Existing auth and REQ-002 contract sections remain at 1-261; REQ-003 valuation/snapshot-close contract begins at 263 and includes inputs, outputs, errors, enums, signatures, compatibility and verification through 435.; 의미: REQ-001 auth/cookie/logout/gate preservation: 13-177.; REQ-002 menu/auth/shell/browser-evidence preservation: 225-261.; REQ-003 interfaces, errors, exact enums, signatures and no-write boundaries: 263-358, 401-435.; Named source/test references: 348, 393-398, 401-415.; 현재 full 문서와 trusted policy 및 pinned source와 named tests를 직접 대조했다. 이전 head의 전체 문서 bytes와 현재 bytes가 같고 REQ003 전체 AC 의미를 보존한다.
    • 테스트 근거: tests/test_account_valuations.py, tests/test_issue_12_regressions.py, tests/test_contract_regression.py, tests/test_valuation_contract_docs.py, tests/test_issue_12_review59_account.py
    • 판정 근거: 승인된 산출물의 구조와 의미를 별도로 검토했다. 초기 작성시 미정은 실제 PR 생성 후 PR13으로 추적되는 lifecycle 계약이며 새로운 실행 증빙 경로나 독립 browser 조합을 요구하지 않는다.
  • D05-project-structure — satisfied

    • 계약: 프로젝트 구조 문서는 기존 source와 test 및 evidence를 보존하고 SQLite schema와 migrations, application의 assets와 account writes 및 import와 reconciliation 및 monthly 책임, 공개 facade와 MCP 및 Streamlit과 기존 세 화면 및 tests를 exact 경로로 대응한다. adapter에서 선택 정책을 복제하지 않고 대출 정의와 verified as_of 및 conditional 승인 경계를 shared application에 배치한다.
    • 구현 근거: docs/project-structure.md; 구조: Existing Dashboard source/test/evidence/deployment placement is retained at 10-120; REQ-003 application, SQLite, MCP, Streamlit, test and document placement is specified at 122-165; ownership/regression map is at 171-212.; 의미: Existing auth/menu source-test-evidence placement: 10-120 and preservation inventory 166-196.; REQ-003 source ownership and adapter/application/SQLite boundaries: 122-165, 171-180, 198-208.; Actual named source/test references and D06 test names: 171-196.; 현재 full 문서와 trusted policy 및 pinned source와 named tests를 직접 대조했다. 이전 head의 전체 문서 bytes와 현재 bytes가 같고 REQ003 전체 AC 의미를 보존한다.
    • 테스트 근거: tests/test_requirement_docs.py
    • 판정 근거: 승인된 산출물의 구조와 의미를 별도로 검토했다. 초기 작성시 미정은 실제 PR 생성 후 PR13으로 추적되는 lifecycle 계약이며 새로운 실행 증빙 경로나 독립 browser 조합을 요구하지 않는다.
  • D06-runtime-flow — satisfied

    • 계약: 런타임 문서는 auth 및 메뉴를 보존하고 register/correct의 증빙 및 scope 검증과 append 및 유효본 확인 및 최신 캐시 동기화를 단일 트랜잭션으로 설명한다. 날짜 및 정책과 통화 및 대표 합산과 경고 read, preview 후 명시적 approval 및 원자적 freeze, reasoned reclose, 같은 근거의 monthly 및 대사, import와 이관 trigger 및 실패복구, retry와 concurrency 및 preview drift 재검증과 무부분쓰기, 비민감 valuation/run 상관 신호를 정의한다.
    • 구현 근거: docs/runtime-flow.md; 구조: Existing startup/login/restore/cleanup/logout and REQ-002 transition flows remain at 13-145; REQ-003 valuation, close, propagation, failure, concurrency, observability and database lifecycle flows are present at 147-241.; 의미: REQ-001 authentication lifecycle and failure semantics: 13-115.; REQ-002 auth-before-menu, query/shell preservation and browser evidence boundary: 116-145.; REQ-003 register/selection/correction and close flow: 147-185.; Failure, concurrency, observability and D06 guards: 187-241.; 현재 full 문서와 trusted policy 및 pinned source와 named tests를 직접 대조했다. 이전 head의 전체 문서 bytes와 현재 bytes가 같고 REQ003 전체 AC 의미를 보존한다.
    • 테스트 근거: tests/test_account_valuations.py, tests/test_asset_snapshots.py, tests/test_issue_12_regressions.py
    • 판정 근거: 승인된 산출물의 구조와 의미를 별도로 검토했다. 초기 작성시 미정은 실제 PR 생성 후 PR13으로 추적되는 lifecycle 계약이며 새로운 실행 증빙 경로나 독립 browser 조합을 요구하지 않는다.
  • C16-supporting-evidence-scope — satisfied

    • 계약: 모든 changed file은 승인된 기능과 필수 supporting change 또는 테스트 evidence로 설명되고 기존 requirement ID를 임의 갱신하거나 범위 밖 제품 및 설정을 변경하지 않는다.
    • 구현 근거: dashboard/app.py, dashboard/page_views/accounts.py, dashboard/page_views/assets.py, dashboard/page_views/monthly_settlement.py, docs/data-model.md, docs/interface-contract.md, docs/project-structure.md, docs/requirements/req-003_account-valuation-history.md, docs/runtime-flow.md, jarca_ledger_mcp/adapters/mcp/server.py, jarca_ledger_mcp/adapters/mcp/tool_contracts.py, jarca_ledger_mcp/adapters/streamlit/accounts_gateway.py, jarca_ledger_mcp/adapters/streamlit/overview_gateway.py, jarca_ledger_mcp/application/__init_.py, jarca_ledger_mcp/application/account_valuation_service.py, jarca_ledger_mcp/application/accounts_write_services.py, jarca_ledger_mcp/application/assets_service.py, jarca_ledger_mcp/application/categorization_services.py, jarca_ledger_mcp/application/cross_transfer_service.py, jarca_ledger_mcp/application/imports_service.py, jarca_ledger_mcp/application/monthly_settlement_service.py, jarca_ledger_mcp/application/reconciliation_service.py, jarca_ledger_mcp/application/review_decision_service.py, jarca_ledger_mcp/application/shared.py, jarca_ledger_mcp/application/system_services.py, jarca_ledger_mcp/application/transaction_report_services.py, jarca_ledger_mcp/application/uncategorized_workbench_service.py, jarca_ledger_mcp/infrastructure/sqlite/__init_.py, jarca_ledger_mcp/infrastructure/sqlite/connection.py, jarca_ledger_mcp/infrastructure/sqlite/migrations.py, jarca_ledger_mcp/infrastructure/sqlite/schema.py, jarca_ledger_mcp/service.py, scripts/ci_fixture_db.py, tests/test_account_basis_public_consumers.py, tests/test_account_valuation_edge_contracts.py, tests/test_account_valuations.py, tests/test_asset_snapshot_idempotency.py, tests/test_asset_snapshots.py, tests/test_contract_regression.py, tests/test_dashboard_app.py, tests/test_dashboard_menu_transition.py, tests/test_import_current_balance_authority.py, tests/test_import_provenance_policy.py, tests/test_issue_12_regressions.py, tests/test_issue_12_review59_account.py, tests/test_issue_12_review59_readonly.py, tests/test_issue_12_review59_reports.py, tests/test_issue_12_review63_accounts.py, tests/test_issue_12_review63_assets.py, tests/test_ledger_categories.py, tests/test_legacy_snapshot_migration.py, tests/test_requirement_docs.py, tests/test_review_decision_workbench.py, tests/test_seoulpay_xlsx.py, tests/test_service.py, tests/test_valuation_contract_docs.py; authoritative changed-file56개와 base-to-head Git tree가 일치하고 API diff166개 hunk의 immutable base/head 위치 및 bytes를 대조했다. Review67 및68의 head 이후 실제 실행 입력 변경은 assets_service.py의 legacy 보존과 새 test_legacy_snapshot_migration.py이며 나머지 실행 입력과 필수 문서5개는 이전 head와 동일하다. 변경분은 기존 마감 보존 및 additive 이관의 직접 승인 범위다. 이전 tracked operational evidence32개는 정본 external archive의 모든 bytes를 역사적 head blob과 비교해 보존을 확인했으며 현재 Git tree에는 docs/verification이 없다. 모든 changed path를 criterion 또는 필수 supporting change에 대응했다. 정본 external evidence-manifest/v2의 source full SHA가 현재 head와 같고 plan 및 manifest digest와 3개 실행 입력 blob 및 5개 command/result binding을 독립 검증했다. 구현자 exact-head focused71 및 전체295통과와4skip 및1warning은 구현자 실행 증빙이며 reviewer 실행 또는 CI 성공이 아니다. Exact-head status는 total_count0인 pending이며 CI 성공으로 사용하지 않는다.
    • 테스트 근거: tests/test_account_basis_public_consumers.py, tests/test_account_valuation_edge_contracts.py, tests/test_account_valuations.py, tests/test_asset_snapshot_idempotency.py, tests/test_asset_snapshots.py, tests/test_contract_regression.py, tests/test_dashboard_app.py, tests/test_dashboard_menu_transition.py, tests/test_import_current_balance_authority.py, tests/test_import_provenance_policy.py, tests/test_issue_12_regressions.py, tests/test_issue_12_review59_account.py, tests/test_issue_12_review59_readonly.py, tests/test_issue_12_review59_reports.py, tests/test_issue_12_review63_accounts.py, tests/test_issue_12_review63_assets.py, tests/test_ledger_categories.py, tests/test_legacy_snapshot_migration.py, tests/test_requirement_docs.py, tests/test_review_decision_workbench.py, tests/test_seoulpay_xlsx.py, tests/test_service.py, tests/test_valuation_contract_docs.py
    • 판정 근거: source-to-head 전체 변경과 외부 기록 무결성 및 모든 변경 경로를 대조했다. evidence 위치 변경은 테스트나 canonical 설계 문서를 삭제하지 않으며 금융 기능의 새 범위를 만들지 않는다.

범위 판정

  • 누락: 없음
  • 범위 초과: 없음
  • 명세 모순: 없음

결론

Issue12의 승인된 Discovery 계약24개를 현재 head에서 충족한다. Review68 F006 legacy 마감 보존은 row-level run/correction 선택과 frozen report 및 monthly/timeseries 회귀로 해소됐다. 문서 후보2건은 전체 문서와 source 및 AC를 대조한 결과 특정 복합 index와 별도 version column을 새 의무로 강제하는 해석이므로 채택하지 않았다. 구현자 exact-head focused71과 전체295통과 및4skip과1warning의 외부 기록을 독립 binding했으며 reviewer가 제품 테스트를 실행한 것으로 표현하지 않는다. reviewer 직접 실행은 하네스 helper31개 통과다. pending status를 CI 성공으로 사용하지 않는다. 지정된 명세 검토 범위에서 승인하며 merge 및 Issue close와 source 변경 또는 release/deployment는 수행하지 않는다.

## 구현 명세 적합성 검토 - Source Issue: #12 - Pull Request: #13 - Reviewed head: `4b8b74ba2adbc4a752c9139c5161b31e104da763` - Contract SHA-256: `6d86b591b022fcc722611bfec6d24e54a64216ab6f7c4098f357e25420218818` - Verdict: `approve` ### Acceptance criteria 판정 - `C01-history` — `satisfied` - 계약: 평가 계좌 FK, 기준일과 등록일, 대표 금액과 통화와 목적, 출처와 확인 상태, 증빙 식별자, 정정 연결과 사유 및 선택 시간 자료를 이력으로 보존한다. - 구현 근거: jarca_ledger_mcp/infrastructure/sqlite/schema.py, jarca_ledger_mcp/infrastructure/sqlite/migrations.py, jarca_ledger_mcp/application/account_valuation_service.py; 구현 위치 jarca_ledger_mcp/infrastructure/sqlite/schema.py:229-267, jarca_ledger_mcp/infrastructure/sqlite/migrations.py:157-173, jarca_ledger_mcp/application/account_valuation_service.py:133-257; actual named test 호출과 assertion: tests/test_account_valuations.py::test_account_valuation_schema_is_v12_and_idempotent:13-21 calls init_db twice and asserts schema_version=12 and all required valuation columns.; tests/test_account_valuations.py::test_register_same_idempotency_payload_reuses_row_and_changed_payload_conflicts:24-32 asserts same row/id reuse and changed-payload idempotency_conflict.; tests/test_account_valuations.py::test_correction_is_append_only_reasoned_and_single_child:48-59 asserts supersedes_id, correction_conflict, count=2, and corrected selection.; 정본 external evidence-manifest/v2의 source full SHA가 현재 head와 같고 plan 및 manifest digest와 3개 실행 입력 blob 및 5개 command/result binding을 독립 검증했다. 구현자 exact-head focused71 및 전체295통과와4skip 및1warning은 구현자 실행 증빙이며 reviewer 실행 또는 CI 성공이 아니다. - 테스트 근거: tests/test_account_valuations.py - 판정 근거: 승인된 Discovery를 현재 immutable source 및 실제 named test 호출과 assertion에 대조해 충족했다. 기존 승인이나 delegate PASS만 상속하지 않고 source와 evidence provenance를 검증했다. 제품 pytest 및 browser는 spec reviewer가 실행하지 않았다. - `C02-money-metrics` — `satisfied` - 계약: 금액 정밀도와 NULL 및 0을 보존하고 취득원가, 순납입액, 기관 표시 원금 금액과 정의 및 원문 명칭, 손익과 수익률의 계산 기준을 구분한다. 투자 대표 총평가액과 포함 현금 및 원금을 중복 합산하지 않는다. - 구현 근거: jarca_ledger_mcp/application/account_valuation_service.py, jarca_ledger_mcp/application/assets_service.py, jarca_ledger_mcp/infrastructure/sqlite/schema.py, docs/data-model.md, docs/requirements/req-003_account-valuation-history.md; 구현 위치 jarca_ledger_mcp/application/account_valuation_service.py:33-56, jarca_ledger_mcp/application/account_valuation_service.py:165-186, jarca_ledger_mcp/application/assets_service.py:486-525, jarca_ledger_mcp/infrastructure/sqlite/schema.py:229-267; actual named test 호출과 assertion: tests/test_issue_12_review59_account.py::test_valuation_round_trip_preserves_null_zero_and_physical_amount_mapping:11-34 asserts physical amount mapping and NULL/zero preservation.; tests/test_account_valuations.py::test_correction_preserves_optional_fields_unless_overridden:83-93 asserts cost_basis, net_contributed, profit, return_rate, principal, interest, fee, as_of_at and timezone preservation.; tests/test_issue_12_regressions.py::test_loan_representative_is_always_aggregated_as_liability:279-294 asserts total_assets=0, liabilities=100, net_worth=-100 and loan bucket.; 정본 external evidence-manifest/v2의 source full SHA가 현재 head와 같고 plan 및 manifest digest와 3개 실행 입력 blob 및 5개 command/result binding을 독립 검증했다. 구현자 exact-head focused71 및 전체295통과와4skip 및1warning은 구현자 실행 증빙이며 reviewer 실행 또는 CI 성공이 아니다. - 테스트 근거: tests/test_issue_12_review59_account.py, tests/test_account_valuations.py, tests/test_issue_12_regressions.py - 판정 근거: 승인된 Discovery를 현재 immutable source 및 실제 named test 호출과 assertion에 대조해 충족했다. 기존 승인이나 delegate PASS만 상속하지 않고 source와 evidence provenance를 검증했다. 제품 pytest 및 browser는 spec reviewer가 실행하지 않았다. - `N01-loan-balance-definition` — `satisfied` - 계약: 대출 평가 기록마다 대표 부채가 원금만인지 원금과 이자 및 수수료인지 필수로 명시하고 기본값으로 추정하지 않는다. 목적 alias가 필수 정의 계약을 우회하지 않는다. - 구현 근거: jarca_ledger_mcp/application/account_valuation_service.py, jarca_ledger_mcp/application/accounts_write_services.py, jarca_ledger_mcp/application/imports_service.py, docs/requirements/req-003_account-valuation-history.md, docs/data-model.md; 구현 위치 jarca_ledger_mcp/application/account_valuation_service.py:93-105, jarca_ledger_mcp/application/account_valuation_service.py:194-203, jarca_ledger_mcp/application/accounts_write_services.py:81-89, jarca_ledger_mcp/application/imports_service.py:37-41; actual named test 호출과 assertion: tests/test_account_valuation_edge_contracts.py::test_loan_balance_requires_representative_liability_definition:41-76 asserts missing definition validation_error and no persisted valuation.; tests/test_account_valuation_edge_contracts.py::test_direct_loan_candidate_requires_liability_definition_and_writes_nothing:133-147 and ::test_import_loan_candidate_requires_liability_definition_and_writes_nothing:148-158 assert both candidate paths fail without writes.; tests/test_account_valuation_edge_contracts.py::test_bank_to_loan_conversion_rejects_existing_undefined_valuation_without_mutation:8-29 asserts conversion rejection and unchanged account/history; ::test_bank_to_loan_conversion_without_valuations_remains_allowed:30-39 asserts compatibility.; 정본 external evidence-manifest/v2의 source full SHA가 현재 head와 같고 plan 및 manifest digest와 3개 실행 입력 blob 및 5개 command/result binding을 독립 검증했다. 구현자 exact-head focused71 및 전체295통과와4skip 및1warning은 구현자 실행 증빙이며 reviewer 실행 또는 CI 성공이 아니다. - 테스트 근거: tests/test_account_valuation_edge_contracts.py, tests/test_issue_12_regressions.py, tests/test_issue_12_review59_account.py - 판정 근거: 승인된 Discovery를 현재 immutable source 및 실제 named test 호출과 assertion에 대조해 충족했다. 기존 승인이나 delegate PASS만 상속하지 않고 source와 evidence provenance를 검증했다. 제품 pytest 및 browser는 spec reviewer가 실행하지 않았다. - `C03-selection` — `satisfied` - 계약: 계좌와 통화 및 평가 목적별 유효 자료를 선택한다. exact는 당일 확인 자료만, as_of는 기준일 이하 최신 확인 자료만 사용한다. 미래 자료는 제외하고 미확인 후보는 확인 자료를 대체하거나 합산하지 않는다. 실제 기준일과 경과 일수 및 이월 상태를 반환한다. - 구현 근거: jarca_ledger_mcp/application/account_valuation_service.py, jarca_ledger_mcp/application/assets_service.py; 구현 위치 jarca_ledger_mcp/application/account_valuation_service.py:270-312, jarca_ledger_mcp/application/assets_service.py:151-206; actual named test 호출과 assertion: tests/test_account_valuations.py::test_select_exact_and_as_of_excludes_unverified_and_reports_carry_forward:35-45 asserts exact returns no valuation with unverified warning, as_of selects 1000, carried_forward=True and age=19.; tests/test_issue_12_regressions.py::test_preview_warns_about_unverified_candidate_when_verified_value_is_selected:339-364 asserts warning candidate status and persisted excluded evidence.; 정본 external evidence-manifest/v2의 source full SHA가 현재 head와 같고 plan 및 manifest digest와 3개 실행 입력 blob 및 5개 command/result binding을 독립 검증했다. 구현자 exact-head focused71 및 전체295통과와4skip 및1warning은 구현자 실행 증빙이며 reviewer 실행 또는 CI 성공이 아니다. - 테스트 근거: tests/test_account_valuations.py, tests/test_issue_12_regressions.py - 판정 근거: 승인된 Discovery를 현재 immutable source 및 실제 named test 호출과 assertion에 대조해 충족했다. 기존 승인이나 delegate PASS만 상속하지 않고 source와 evidence provenance를 검증했다. 제품 pytest 및 browser는 spec reviewer가 실행하지 않았다. - `C04-correction-validation` — `satisfied` - 계약: 평가 정정은 append-only로 대상과 사유를 연결하며 다른 계좌, 통화, 목적을 참조하는 정정과 순환 및 동일 유효본의 동시 분기를 차단한다. - 구현 근거: jarca_ledger_mcp/application/account_valuation_service.py, jarca_ledger_mcp/infrastructure/sqlite/schema.py; 구현 위치 jarca_ledger_mcp/application/account_valuation_service.py:204-253, jarca_ledger_mcp/application/account_valuation_service.py:315-375, jarca_ledger_mcp/infrastructure/sqlite/schema.py:264-267; actual named test 호출과 assertion: tests/test_issue_12_review59_account.py::test_direct_correction_requires_matching_existing_parent_and_reason:36-53 asserts missing/wrong parent and missing reason failures and valid correction.; tests/test_issue_12_review59_account.py::test_correction_rejects_self_parent_and_cycles_without_write:167-178 asserts rejection and unchanged history.; tests/test_account_valuations.py::test_correction_is_append_only_reasoned_and_single_child:48-59 asserts one child and original immutable selection.; 정본 external evidence-manifest/v2의 source full SHA가 현재 head와 같고 plan 및 manifest digest와 3개 실행 입력 blob 및 5개 command/result binding을 독립 검증했다. 구현자 exact-head focused71 및 전체295통과와4skip 및1warning은 구현자 실행 증빙이며 reviewer 실행 또는 CI 성공이 아니다. - 테스트 근거: tests/test_issue_12_review59_account.py, tests/test_account_valuations.py, tests/test_issue_12_regressions.py - 판정 근거: 승인된 Discovery를 현재 immutable source 및 실제 named test 호출과 assertion에 대조해 충족했다. 기존 승인이나 delegate PASS만 상속하지 않고 source와 evidence provenance를 검증했다. 제품 pytest 및 browser는 spec reviewer가 실행하지 않았다. - `C05-current-import` — `satisfied` - 계약: 뒤늦은 과거 자료 등록으로 최신 표시값을 과거로 되돌리지 않는다. 기존 계좌 수정과 import의 최신 캐시 및 새 이력 권위를 연결하며 동기화 시각을 실제 평가일로 오인하지 않는다. - 구현 근거: jarca_ledger_mcp/application/accounts_write_services.py, jarca_ledger_mcp/application/imports_service.py, jarca_ledger_mcp/application/assets_service.py; 구현 위치 jarca_ledger_mcp/application/accounts_write_services.py:49-106, jarca_ledger_mcp/application/imports_service.py:37-49, jarca_ledger_mcp/application/assets_service.py:131-214; actual named test 호출과 assertion: tests/test_issue_12_regressions.py::test_historical_account_update_preserves_current_and_adds_one_candidate:76-83 asserts current 900/2026-06-30 remains and exactly one historical candidate is added.; tests/test_account_valuations.py::test_account_balance_write_records_unverified_candidate_only_with_real_basis_date:62-69 asserts dated candidate is unverified and undated balance creates none.; tests/test_import_current_balance_authority.py::test_account_write_sync_timestamp_does_not_infer_balance_basis_or_candidate:225-249 and ::test_unknown_legacy_balance_basis_is_not_reported_as_valuation_date:250-267 assert no inferred basis/candidate and unknown legacy date reporting.; 정본 external evidence-manifest/v2의 source full SHA가 현재 head와 같고 plan 및 manifest digest와 3개 실행 입력 blob 및 5개 command/result binding을 독립 검증했다. 구현자 exact-head focused71 및 전체295통과와4skip 및1warning은 구현자 실행 증빙이며 reviewer 실행 또는 CI 성공이 아니다. - 테스트 근거: tests/test_issue_12_regressions.py, tests/test_account_valuations.py, tests/test_import_current_balance_authority.py, tests/test_issue_12_review59_account.py, tests/test_import_provenance_policy.py, tests/test_account_basis_public_consumers.py, tests/test_issue_12_review63_accounts.py - 판정 근거: 승인된 Discovery를 현재 immutable source 및 실제 named test 호출과 assertion에 대조해 충족했다. 기존 승인이나 delegate PASS만 상속하지 않고 source와 evidence provenance를 검증했다. 제품 pytest 및 browser는 spec reviewer가 실행하지 않았다. - `C06-idempotency` — `satisfied` - 계약: 동일 증빙 또는 idempotency 재입력은 동일 기록을 재사용하며 같은 키의 다른 payload는 충돌이다. 동시 정정의 분기를 차단하고 UNIQUE 계좌 및 기준일 하나로 정정 추가를 막지 않는다. - 구현 근거: jarca_ledger_mcp/application/account_valuation_service.py, jarca_ledger_mcp/application/assets_service.py, jarca_ledger_mcp/infrastructure/sqlite/schema.py, jarca_ledger_mcp/infrastructure/sqlite/migrations.py, jarca_ledger_mcp/application/accounts_write_services.py, jarca_ledger_mcp/application/imports_service.py; 구현 위치 jarca_ledger_mcp/application/account_valuation_service.py:107-125, jarca_ledger_mcp/application/account_valuation_service.py:225-244, jarca_ledger_mcp/application/assets_service.py:729-826; actual named test 호출과 assertion: tests/test_account_valuations.py::test_register_same_idempotency_payload_reuses_row_and_changed_payload_conflicts:24-32 asserts reuse and conflict.; tests/test_issue_12_review59_account.py::test_source_ref_conflicts_even_when_idempotency_keys_differ:207-219 asserts source identity conflict.; tests/test_issue_12_regressions.py::test_snapshot_close_idempotency_fingerprint_and_concurrent_first_close:128-163 asserts exact replay equality, changed payload/evidence conflict and one concurrent run.; tests/test_issue_12_regressions.py::test_concurrent_correction_idempotency_reuses_same_payload:251-267 asserts one correction id and reused flags.; 정본 external evidence-manifest/v2의 source full SHA가 현재 head와 같고 plan 및 manifest digest와 3개 실행 입력 blob 및 5개 command/result binding을 독립 검증했다. 구현자 exact-head focused71 및 전체295통과와4skip 및1warning은 구현자 실행 증빙이며 reviewer 실행 또는 CI 성공이 아니다. - 테스트 근거: tests/test_account_valuations.py, tests/test_issue_12_review59_account.py, tests/test_issue_12_regressions.py, tests/test_account_valuation_edge_contracts.py - 판정 근거: 승인된 Discovery를 현재 immutable source 및 실제 named test 호출과 assertion에 대조해 충족했다. 기존 승인이나 delegate PASS만 상속하지 않고 source와 evidence provenance를 검증했다. 제품 pytest 및 browser는 spec reviewer가 실행하지 않았다. - `C07-close-immutability` — `satisfied` - 계약: 기존 asset_snapshots와 correction run을 보존하고 평가 정정 및 거래 추가로 기존 마감을 자동 변경하지 않는다. 동일 기준일 재마감은 사유와 이전 run 연결을 가진 새 버전을 원자적으로 추가한다. - 구현 근거: jarca_ledger_mcp/application/assets_service.py, jarca_ledger_mcp/infrastructure/sqlite/schema.py, jarca_ledger_mcp/infrastructure/sqlite/migrations.py; 구현 위치 jarca_ledger_mcp/application/assets_service.py:714-865, jarca_ledger_mcp/application/assets_service.py:889-939; actual named test 호출과 assertion: tests/test_asset_snapshots.py::test_snapshot_rows_are_append_only_and_timeseries_uses_same_formula:53-74 asserts old rows remain and timeseries uses the same formula.; tests/test_issue_12_review63_assets.py::test_f002_correction_replay_preserves_full_initial_response:67-94 asserts correction replay and initial replay equality.; tests/test_issue_12_review63_assets.py::test_f006_initial_replay_survives_multiple_later_corrections:97-138 asserts initial replay survives two corrections and unrelated live drift conflicts.; 정본 external evidence-manifest/v2의 source full SHA가 현재 head와 같고 plan 및 manifest digest와 3개 실행 입력 blob 및 5개 command/result binding을 독립 검증했다. 구현자 exact-head focused71 및 전체295통과와4skip 및1warning은 구현자 실행 증빙이며 reviewer 실행 또는 CI 성공이 아니다. Review68 F006은 assets_service.py:327-358,974-1014,1077-1129의 row-level legacy run 선택과 frozen report 및 downstream 공유로 해소됐다. tests/test_legacy_snapshot_migration.py:39-146은 금액과 correction grouping 및 approval 비추론과 valuation_id 비추론, report 및 monthly 및 timeseries와 DB hash 불변을 assertion한다. - 테스트 근거: tests/test_asset_snapshots.py, tests/test_issue_12_review63_assets.py, tests/test_issue_12_regressions.py, tests/test_legacy_snapshot_migration.py - 판정 근거: 승인된 Discovery를 현재 immutable source 및 실제 named test 호출과 assertion에 대조해 충족했다. 기존 승인이나 delegate PASS만 상속하지 않고 source와 evidence provenance를 검증했다. 제품 pytest 및 browser는 spec reviewer가 실행하지 않았다. - `N02-close-replay-run-binding` — `satisfied` - 계약: 마감 버전의 근거는 불변이며 동일 idempotency 요청은 원래 기록을 재사용한다. 재마감으로 과거 run 응답 및 evidence를 변경하지 않는다. - 구현 근거: jarca_ledger_mcp/application/assets_service.py, docs/interface-contract.md; 구현 위치 jarca_ledger_mcp/application/assets_service.py:272-324, jarca_ledger_mcp/application/assets_service.py:743-826, jarca_ledger_mcp/application/assets_service.py:827-939; actual named test 호출과 assertion: tests/test_asset_snapshot_idempotency.py::test_exact_run_replay_after_correction_reconstructs_original_persisted_run:131-207 asserts original run ID/rows/metadata are reconstructed after correction.; tests/test_asset_snapshot_idempotency.py::test_empty_run_replay_after_nonempty_correction_preserves_original_empty_payload:208-286 asserts zero-row original response remains exact after later nonempty correction.; tests/test_issue_12_review63_assets.py::test_f006_initial_replay_survives_multiple_later_corrections:97-138 asserts first replay equality and unrelated live-authority drift conflict.; 정본 external evidence-manifest/v2의 source full SHA가 현재 head와 같고 plan 및 manifest digest와 3개 실행 입력 blob 및 5개 command/result binding을 독립 검증했다. 구현자 exact-head focused71 및 전체295통과와4skip 및1warning은 구현자 실행 증빙이며 reviewer 실행 또는 CI 성공이 아니다. - 테스트 근거: tests/test_asset_snapshot_idempotency.py, tests/test_issue_12_review63_assets.py, tests/test_issue_12_review59_reports.py, tests/test_issue_12_regressions.py - 판정 근거: 승인된 Discovery를 현재 immutable source 및 실제 named test 호출과 assertion에 대조해 충족했다. 기존 승인이나 delegate PASS만 상속하지 않고 source와 evidence provenance를 검증했다. 제품 pytest 및 browser는 spec reviewer가 실행하지 않았다. - `C08-approved-conditional` — `satisfied` - 계약: 완전한 exact 마감, 미완료 초안, 별도 승인된 조건부 마감을 구분한다. 승인 전 누락 및 이월은 미완료 초안이고 승인 후에도 누락 제외 및 확인된 과거값 이월만 허용한다. 미확인, 미래, 기준일 미상 금액은 승인으로도 합산하지 않으며 적용과 제외와 이월 및 승인자와 시각과 사유와 근거를 고정한다. - 구현 근거: jarca_ledger_mcp/application/assets_service.py, jarca_ledger_mcp/infrastructure/sqlite/schema.py, dashboard/page_views/assets.py; 구현 위치 jarca_ledger_mcp/application/assets_service.py:672-697, jarca_ledger_mcp/application/assets_service.py:725-735, jarca_ledger_mcp/application/assets_service.py:887-937; actual named test 호출과 assertion: tests/test_issue_12_regressions.py::test_preview_marks_approval_eligible_missing_valuation_as_incomplete_draft:34-40 asserts incomplete_draft and missing valuation warning.; tests/test_issue_12_review59_reports.py::test_approved_carried_close_is_conditional_and_persists_provenance:22-55 asserts conditional status, persisted carry evidence and exact approval metadata.; tests/test_issue_12_regressions.py::test_empty_conditional_close_is_closed_and_second_close_requires_correction:16-31 asserts zero-row conditional closure and correction requirement.; 정본 external evidence-manifest/v2의 source full SHA가 현재 head와 같고 plan 및 manifest digest와 3개 실행 입력 blob 및 5개 command/result binding을 독립 검증했다. 구현자 exact-head focused71 및 전체295통과와4skip 및1warning은 구현자 실행 증빙이며 reviewer 실행 또는 CI 성공이 아니다. - 테스트 근거: tests/test_issue_12_regressions.py, tests/test_issue_12_review59_reports.py, tests/test_asset_snapshots.py, tests/test_issue_12_review63_assets.py - 판정 근거: 승인된 Discovery를 현재 immutable source 및 실제 named test 호출과 assertion에 대조해 충족했다. 기존 승인이나 delegate PASS만 상속하지 않고 source와 evidence provenance를 검증했다. 제품 pytest 및 browser는 spec reviewer가 실행하지 않았다. - `C09-reconciliation` — `satisfied` - 계약: 외부 확인값과 장부 계산값을 분리하고 검증된 시작잔고, 기준시점, 거래 포함 범위와 계산 완전성을 표시한다. 거래 없는 수동 투자 계좌의 대사 불가 및 거래 미수입과 평가 수동 관리 상태를 구분하고 가짜 거래를 만들지 않는다. 대사도 공통 평가 근거와 대출 대표 정의를 사용한다. - 구현 근거: jarca_ledger_mcp/application/reconciliation_service.py, jarca_ledger_mcp/application/monthly_settlement_service.py, jarca_ledger_mcp/application/account_valuation_service.py; 구현 위치 jarca_ledger_mcp/application/reconciliation_service.py:31-213, jarca_ledger_mcp/application/monthly_settlement_service.py:1-120; actual named test 호출과 assertion: tests/test_issue_12_review59_reports.py::test_reconciliation_uses_currency_and_loan_priority_and_canonical_provenance:58-72 asserts selected valuation ID/kind/date/status.; tests/test_issue_12_review59_reports.py::test_investment_without_verified_valuation_and_without_opening_balance_is_incomplete:74-83 asserts VALUATION_UNAVAILABLE, incomplete, null difference/value.; tests/test_issue_12_review59_reports.py::test_reconciliation_does_not_mark_last_balance_without_opening_evidence_complete:102-108 asserts INCOMPLETE_CALCULATION.; 정본 external evidence-manifest/v2의 source full SHA가 현재 head와 같고 plan 및 manifest digest와 3개 실행 입력 blob 및 5개 command/result binding을 독립 검증했다. 구현자 exact-head focused71 및 전체295통과와4skip 및1warning은 구현자 실행 증빙이며 reviewer 실행 또는 CI 성공이 아니다. - 테스트 근거: tests/test_issue_12_review59_reports.py, tests/test_issue_12_regressions.py, tests/test_service.py - 판정 근거: 승인된 Discovery를 현재 immutable source 및 실제 named test 호출과 assertion에 대조해 충족했다. 기존 승인이나 delegate PASS만 상속하지 않고 source와 evidence provenance를 검증했다. 제품 pytest 및 browser는 spec reviewer가 실행하지 않았다. - `C10-report-monthly-evidence` — `satisfied` - 계약: MCP와 Dashboard 및 월정산 보고에서 같은 기준일과 선택 근거 및 실제 평가일, 경과 일수, 확인 상태, 누락과 미확인 및 이월 경고, 마감 버전 및 조건부 승인 근거를 일관되게 전달한다. - 구현 근거: jarca_ledger_mcp/application/assets_service.py, jarca_ledger_mcp/application/monthly_settlement_service.py, dashboard/page_views/monthly_settlement.py, dashboard/page_views/accounts.py; 구현 위치 jarca_ledger_mcp/application/assets_service.py:965-1059, jarca_ledger_mcp/application/assets_service.py:1062-1131, jarca_ledger_mcp/application/monthly_settlement_service.py:1-120; actual named test 호출과 assertion: tests/test_issue_12_review59_reports.py::test_timeseries_and_monthly_expose_canonical_asset_provenance:85-100 asserts provenance in report, timeseries and monthly payloads.; tests/test_issue_12_review59_reports.py::test_monthly_settlement_propagates_snapshot_provenance_id_and_actual_valuation_date:111-119 asserts monthly_source_snapshot_id, actual valuation_date, warnings/exclusions/carry.; tests/test_issue_12_review59_reports.py::test_approved_carry_provenance_is_identical_across_closed_downstream_reports:122-149 asserts equality across report, timeseries and monthly outputs.; tests/test_legacy_snapshot_migration.py::test_schema11_closed_rows_are_frozen_in_monthly_settlement:83-98 asserts legacy frozen amount and provenance propagation.; 정본 external evidence-manifest/v2의 source full SHA가 현재 head와 같고 plan 및 manifest digest와 3개 실행 입력 blob 및 5개 command/result binding을 독립 검증했다. 구현자 exact-head focused71 및 전체295통과와4skip 및1warning은 구현자 실행 증빙이며 reviewer 실행 또는 CI 성공이 아니다. Review68 F006은 assets_service.py:327-358,974-1014,1077-1129의 row-level legacy run 선택과 frozen report 및 downstream 공유로 해소됐다. tests/test_legacy_snapshot_migration.py:39-146은 금액과 correction grouping 및 approval 비추론과 valuation_id 비추론, report 및 monthly 및 timeseries와 DB hash 불변을 assertion한다. - 테스트 근거: tests/test_issue_12_review59_reports.py, tests/test_legacy_snapshot_migration.py, tests/test_issue_12_regressions.py, tests/test_service.py, tests/test_issue_12_review63_assets.py - 판정 근거: 승인된 Discovery를 현재 immutable source 및 실제 named test 호출과 assertion에 대조해 충족했다. 기존 승인이나 delegate PASS만 상속하지 않고 source와 evidence provenance를 검증했다. 제품 pytest 및 browser는 spec reviewer가 실행하지 않았다. - `C11-adapter-structure` — `satisfied` - 계약: MCP와 Streamlit gateway는 공통 application을 사용하고 기존 공개 호출명과 기존 인수 및 success와 실패 error_code 및 error envelope를 가능한 한 유지한다. 새 Dashboard 인증 또는 MCP 인증을 도입하지 않는다. - 구현 근거: jarca_ledger_mcp/service.py, jarca_ledger_mcp/adapters/mcp/server.py, jarca_ledger_mcp/adapters/streamlit/accounts_gateway.py, jarca_ledger_mcp/adapters/streamlit/assets_gateway.py, dashboard/page_views/accounts.py, dashboard/page_views/assets.py, jarca_ledger_mcp/adapters/mcp/tool_contracts.py, jarca_ledger_mcp/application/__init__.py, dashboard/page_views/monthly_settlement.py; 구현 위치 jarca_ledger_mcp/service.py:1-100, jarca_ledger_mcp/adapters/mcp/server.py, jarca_ledger_mcp/adapters/streamlit/accounts_gateway.py, jarca_ledger_mcp/adapters/streamlit/assets_gateway.py, dashboard/page_views/accounts.py, dashboard/page_views/assets.py; actual named test 호출과 assertion: tests/test_mcp_http_runtime.py::test_mcp_runtime_config_defaults_to_stdio and ::test_mcp_runtime_config_accepts_streamable_http_env:6-35 assert transport configuration.; tests/test_contract_regression.py::test_list_report_and_mutation_success_envelope_contract:117-145 asserts success/error envelopes and public calls.; tests/test_dashboard_app.py::test_authenticated_dashboard_all_pages_are_no_write:167-197 asserts authenticated page rendering does not mutate DB.; 정본 external evidence-manifest/v2의 source full SHA가 현재 head와 같고 plan 및 manifest digest와 3개 실행 입력 blob 및 5개 command/result binding을 독립 검증했다. 구현자 exact-head focused71 및 전체295통과와4skip 및1warning은 구현자 실행 증빙이며 reviewer 실행 또는 CI 성공이 아니다. - 테스트 근거: tests/test_mcp_http_runtime.py, tests/test_contract_regression.py, tests/test_dashboard_app.py, tests/test_issue_12_regressions.py - 판정 근거: 승인된 Discovery를 현재 immutable source 및 실제 named test 호출과 assertion에 대조해 충족했다. 기존 승인이나 delegate PASS만 상속하지 않고 source와 evidence provenance를 검증했다. 제품 pytest 및 browser는 spec reviewer가 실행하지 않았다. - `C12-migration-legacy` — `satisfied` - 계약: schema 11의 기존 데이터와 마감 및 개인정보를 보존하고 additive하고 idempotent한 migration을 제공한다. 기준일 증거 없는 값을 임의 월말로 소급하거나 legacy snapshot에 valuation_id를 추측하여 생성하지 않는다. - 구현 근거: jarca_ledger_mcp/infrastructure/sqlite/migrations.py, jarca_ledger_mcp/application/assets_service.py, tests/test_legacy_snapshot_migration.py, jarca_ledger_mcp/infrastructure/sqlite/schema.py; 구현 위치 jarca_ledger_mcp/infrastructure/sqlite/migrations.py:19-173, jarca_ledger_mcp/application/assets_service.py:327-358, jarca_ledger_mcp/application/assets_service.py:974-1014, tests/test_legacy_snapshot_migration.py:39-146; actual named test 호출과 assertion: tests/test_issue_12_regressions.py::test_schema12_migration_preserves_legacy_rows_indexes_and_is_idempotent:86-125 asserts old account/transaction/snapshot rows, old and new indexes, schema_version=12 after init twice.; tests/test_legacy_snapshot_migration.py::test_schema11_closed_rows_remain_frozen_after_live_value_and_date_change:39-63 asserts source=legacy_asset_snapshots, closed=True, net_worth=100, frozen item amount and DB hash unchanged.; tests/test_legacy_snapshot_migration.py::test_schema11_latest_legacy_correction_run_is_selected_as_a_complete_group:101-146 asserts latest legacy run grouping, rows, amount 150, correction metadata, no invented valuation_id and unchanged DB hash.; 정본 external evidence-manifest/v2의 source full SHA가 현재 head와 같고 plan 및 manifest digest와 3개 실행 입력 blob 및 5개 command/result binding을 독립 검증했다. 구현자 exact-head focused71 및 전체295통과와4skip 및1warning은 구현자 실행 증빙이며 reviewer 실행 또는 CI 성공이 아니다. Review68 F006은 assets_service.py:327-358,974-1014,1077-1129의 row-level legacy run 선택과 frozen report 및 downstream 공유로 해소됐다. tests/test_legacy_snapshot_migration.py:39-146은 금액과 correction grouping 및 approval 비추론과 valuation_id 비추론, report 및 monthly 및 timeseries와 DB hash 불변을 assertion한다. - 테스트 근거: tests/test_issue_12_regressions.py, tests/test_legacy_snapshot_migration.py, tests/test_account_valuations.py, tests/test_ledger_categories.py, tests/test_review_decision_workbench.py - 판정 근거: 승인된 Discovery를 현재 immutable source 및 실제 named test 호출과 assertion에 대조해 충족했다. 기존 승인이나 delegate PASS만 상속하지 않고 source와 evidence provenance를 검증했다. 제품 pytest 및 browser는 spec reviewer가 실행하지 않았다. - `C13-read-only` — `satisfied` - 계약: preview와 조회 및 Dashboard 렌더링은 금융 쓰기를 실행하지 않는다. 명시적 등록, 정정, 승인 close 및 import 제출만 변경을 수행하고 실패 시 부분 쓰기를 남기지 않는다. - 구현 근거: jarca_ledger_mcp/infrastructure/sqlite/connection.py, jarca_ledger_mcp/application/assets_service.py, jarca_ledger_mcp/application/shared.py, jarca_ledger_mcp/application/system_services.py, jarca_ledger_mcp/application/account_valuation_service.py; 구현 위치 jarca_ledger_mcp/infrastructure/sqlite/connection.py:31-69, jarca_ledger_mcp/application/assets_service.py:672-697, jarca_ledger_mcp/application/assets_service.py:965-1131; actual named test 호출과 assertion: tests/test_issue_12_review59_readonly.py::test_read_queries_missing_nested_db_return_stable_error_without_creating_path:25-42 asserts stable missing-DB error and no path creation.; tests/test_issue_12_review59_readonly.py::test_read_only_connection_rejects_writes_and_does_not_commit:44-54 asserts read-only write rejection/no commit.; tests/test_issue_12_review59_readonly.py::test_read_suite_does_not_initialize_or_change_initialized_database:56-75 asserts hash and schema/rows unchanged.; 정본 external evidence-manifest/v2의 source full SHA가 현재 head와 같고 plan 및 manifest digest와 3개 실행 입력 blob 및 5개 command/result binding을 독립 검증했다. 구현자 exact-head focused71 및 전체295통과와4skip 및1warning은 구현자 실행 증빙이며 reviewer 실행 또는 CI 성공이 아니다. - 테스트 근거: tests/test_issue_12_review59_readonly.py, tests/test_dashboard_app.py, tests/test_dashboard_menu_transition.py - 판정 근거: 승인된 Discovery를 현재 immutable source 및 실제 named test 호출과 assertion에 대조해 충족했다. 기존 승인이나 delegate PASS만 상속하지 않고 source와 evidence provenance를 검증했다. 제품 pytest 및 browser는 spec reviewer가 실행하지 않았다. - `C14-auth-menu-preservation` — `satisfied` - 계약: Dashboard 인증은 DB보다 먼저이며 REQ-001의 cookie와 logout 및 REQ-002의 메뉴 label과 order, shell, query, error와 retry 및 명시적 금융 쓰기 계약을 유지한다. - 구현 근거: dashboard/app.py, dashboard/authentication.py, dashboard/page_views/accounts.py, dashboard/page_views/assets.py, dashboard/page_views/monthly_settlement.py, docs/interface-contract.md, docs/project-structure.md, docs/runtime-flow.md; 구현 위치 dashboard/app.py:37-72, dashboard/authentication.py, dashboard/page_views/accounts.py, dashboard/page_views/assets.py, dashboard/page_views/monthly_settlement.py; actual named test 호출과 assertion: tests/test_dashboard_authentication_app.py::test_main_does_not_resolve_database_or_dispatch_when_authentication_rejects:67-80 asserts rejected auth prevents DB/page dispatch.; tests/test_dashboard_authentication_app.py::test_invalid_cookie_blocks_database_and_page_dispatch:105-112 asserts invalid cookie blocks access.; tests/test_dashboard_menu_transition.py::test_dashboard_menu_labels_and_order_are_preserved:18-30 and ::test_streamlit_menu_click_updates_body_and_preserves_page_query_siblings:83-108 assert labels/order and query/shell behavior.; 정본 external evidence-manifest/v2의 source full SHA가 현재 head와 같고 plan 및 manifest digest와 3개 실행 입력 blob 및 5개 command/result binding을 독립 검증했다. 구현자 exact-head focused71 및 전체295통과와4skip 및1warning은 구현자 실행 증빙이며 reviewer 실행 또는 CI 성공이 아니다. - 테스트 근거: tests/test_dashboard_authentication_app.py, tests/test_dashboard_menu_transition.py, tests/test_dashboard_app.py - 판정 근거: 승인된 Discovery를 현재 immutable source 및 실제 named test 호출과 assertion에 대조해 충족했다. 기존 승인이나 delegate PASS만 상속하지 않고 source와 evidence provenance를 검증했다. 제품 pytest 및 browser는 spec reviewer가 실행하지 않았다. - `C15-exclusions-privacy` — `satisfied` - 계약: 증권사 자동 연동, 정확한 성과 또는 환율 엔진, 새 인증, 별도 월정산 제품, 거래 추론 및 기존 데이터 자동 재작성과 수기 비계좌 자산 전체 이력 재설계를 추가하지 않는다. 실제 계좌 및 금융 증빙과 credential을 로그와 문서 및 테스트에 기록하지 않는다. - 구현 근거: jarca_ledger_mcp/application/assets_service.py, jarca_ledger_mcp/application/account_valuation_service.py, jarca_ledger_mcp/provenance_policy.py, docs/requirements/req-003_account-valuation-history.md, jarca_ledger_mcp/application/imports_service.py, jarca_ledger_mcp/application/reconciliation_service.py, jarca_ledger_mcp/infrastructure/sqlite/schema.py, jarca_ledger_mcp/infrastructure/sqlite/migrations.py; 구현 위치 jarca_ledger_mcp/application/assets_service.py:62-75, jarca_ledger_mcp/application/account_valuation_service.py:29-30, jarca_ledger_mcp/provenance_policy.py, docs/requirements/req-003_account-valuation-history.md:163-185; actual named test 호출과 assertion: tests/test_issue_12_regressions.py::test_warning_candidate_public_payload_is_minimal:316-321 asserts only five non-sensitive candidate fields.; tests/test_issue_12_regressions.py::test_snapshot_report_redacts_unverified_candidate_sensitive_fields:324-336 asserts TOPSECRET/PASSWORD absent and candidate keys allowlisted.; tests/test_issue_12_review59_reports.py::test_preview_and_live_report_redact_excluded_source_note_and_memo:152-167 and ::test_public_included_items_redact_source_note_and_memo_recursively:190-206 assert recursive redaction.; 정본 external evidence-manifest/v2의 source full SHA가 현재 head와 같고 plan 및 manifest digest와 3개 실행 입력 blob 및 5개 command/result binding을 독립 검증했다. 구현자 exact-head focused71 및 전체295통과와4skip 및1warning은 구현자 실행 증빙이며 reviewer 실행 또는 CI 성공이 아니다. - 테스트 근거: tests/test_issue_12_regressions.py, tests/test_issue_12_review59_reports.py, scripts/ci_fixture_db.py - 판정 근거: 승인된 Discovery를 현재 immutable source 및 실제 named test 호출과 assertion에 대조해 충족했다. 기존 승인이나 delegate PASS만 상속하지 않고 source와 evidence provenance를 검증했다. 제품 pytest 및 browser는 spec reviewer가 실행하지 않았다. - `D01-requirement-structure` — `satisfied` - 계약: 신규 REQ-003을 배정 경로와 제목으로 작성하며 trusted harness README와 TEMPLATE의 JSON metadata, 연속 요구사항 및 AC, 필수 섹션, 판정 기준과 검증 및 검증 분류의 수준과 백엔드와 케이스 및 상태 불변조건을 충족한다. 초기 PR은 미정이며 PR 생성 후 실제 번호를 추적한다. - 구현 근거: docs/requirements/req-003_account-valuation-history.md; 구조: Front matter at lines 1-13 has gitea-agent.requirement/v1, REQ-003, exact title, revision 1.0, approved status, language ko; H1/title at 16; required sections 1-11 are present; requirements REQ-003.01 through .10 are contiguous at 53-173; ACs REQ-003.01-AC01 through .10-AC01 are contiguous at 189-297; traceability is at 311-317.; 의미: Discovery obligations: req-003 title/path/ID and lifecycle at discovery.md:76-87; document content at req-003:1-16, 311-317.; Core valuation, exact/as_of, future exclusion, loan definition and optional metrics at req-003:65-115, 175-185.; Conditional close and explicit approval at req-003:113-127, 244-264.; REQ-001/REQ-002 preservation and Issue12/PR13 traceability at req-003:307-317. PR PR13 is valid for this real PR; the trusted template's initial-writing default of 미정 is not a defect after PR creation.; 현재 full 문서와 trusted policy 및 pinned source와 named tests를 직접 대조했다. 이전 head의 전체 문서 bytes와 현재 bytes가 같고 REQ003 전체 AC 의미를 보존한다. - 테스트 근거: tests/test_requirement_docs.py - 판정 근거: 승인된 산출물의 구조와 의미를 별도로 검토했다. 초기 작성시 미정은 실제 PR 생성 후 PR13으로 추적되는 lifecycle 계약이며 새로운 실행 증빙 경로나 독립 browser 조합을 요구하지 않는다. - `D02-requirement-semantics` — `satisfied` - 계약: 요구사항에는 평가 근거와 지표 정의, 선택과 future 제외, 정정 및 idempotency 충돌, 대사 완전성, current 및 import 연계, 마감 상태와 불변성과 승인, shared adapter 및 인증, migration과 legacy를 소스 및 테스트에 대응한다. 모든 승인된 경계와 회귀 사례를 인수 기준으로 내린다. - 구현 근거: docs/requirements/req-003_account-valuation-history.md; 구조: Front matter at lines 1-13 has gitea-agent.requirement/v1, REQ-003, exact title, revision 1.0, approved status, language ko; H1/title at 16; required sections 1-11 are present; requirements REQ-003.01 through .10 are contiguous at 53-173; ACs REQ-003.01-AC01 through .10-AC01 are contiguous at 189-297; traceability is at 311-317.; 의미: Discovery obligations: req-003 title/path/ID and lifecycle at discovery.md:76-87; document content at req-003:1-16, 311-317.; Core valuation, exact/as_of, future exclusion, loan definition and optional metrics at req-003:65-115, 175-185.; Conditional close and explicit approval at req-003:113-127, 244-264.; REQ-001/REQ-002 preservation and Issue12/PR13 traceability at req-003:307-317. PR PR13 is valid for this real PR; the trusted template's initial-writing default of 미정 is not a defect after PR creation.; 현재 full 문서와 trusted policy 및 pinned source와 named tests를 직접 대조했다. 이전 head의 전체 문서 bytes와 현재 bytes가 같고 REQ003 전체 AC 의미를 보존한다. - 테스트 근거: tests/test_account_valuations.py, tests/test_asset_snapshots.py, tests/test_issue_12_regressions.py, tests/test_requirement_docs.py, tests/test_mcp_http_runtime.py, tests/test_dashboard_authentication_app.py - 판정 근거: 승인된 산출물의 구조와 의미를 별도로 검토했다. 초기 작성시 미정은 실제 PR 생성 후 PR13으로 추적되는 lifecycle 계약이며 새로운 실행 증빙 경로나 독립 browser 조합을 요구하지 않는다. - `D03-data-model` — `satisfied` - 계약: 신규 데이터 모델은 기존 entities 및 valuation과 마감의 관계, FK와 날짜 및 정확한 금액과 NULL 및 0과 선택 지표 및 대출 필수 정의, 계좌와 통화 및 목적과 기준일의 선택 및 index와 단일 유효 정정본, 고정 적용 분류 및 출처와 상태와 누락 및 이월 및 승인 버전, 분리된 정정과 schema11 이관 및 미상 날짜와 legacy 및 최신 캐시 동기화 책임을 정의한다. - 구현 근거: docs/data-model.md; docs/data-model.md:33-68은 실제 evaluation fields와 account 필수 및 currency/purpose 선택 필터, exact 또는 상한 basis-date, verified leaf 및 제외 규칙과 account/date 및 status/date 물리 index coverage와 한계를 명시한다. schema.py:264-267 및 account_valuation_service.py:270-312의 정본과 일치한다. :89-124 및 :147-157은 immutable run ID와 기존 run을 가리키는 correction 관계, insert-only 새 run/rows 및 latest-run authority, 각 run의 적용값과 approval evidence를 고정한다. docs/requirements/req-003_account-valuation-history.md:255-264는 기존 run/rows 보존 및 latest-run 단독 보고를 버전의 인수 기준으로 정한다. 전체 entity/FK/금액/loan/legacy/current-cache 계약은 :12-61 및 :70-176에 대응한다. tests/test_valuation_contract_docs.py:46-62와 테스트의 actual assertions를 확인했다. - 테스트 근거: tests/test_account_valuations.py, tests/test_asset_snapshots.py, tests/test_issue_12_regressions.py, tests/test_valuation_contract_docs.py - 판정 근거: DOC001은 문서가 명시한 선택 필터와 실제 index coverage/한계를 누락으로 오분류하고 특정 복합 물리 index를 새로 강제하므로 채택하지 않는다. DOC002는 immutable run identity와 correction chain으로 정의된 마감 버전을 누락으로 오분류하고 별도 version column을 강제하므로 채택하지 않는다. 승인 계약은 특정 복합 index나 숫자 version column을 지정하지 않으며 보존 및 새 run의 버전 관계가 문서와 source 및 인수 기준으로 확인된다. - `D04-interface-contract` — `satisfied` - 계약: 인터페이스 문서는 기존 auth 및 메뉴를 보존하고 평가 등록 및 조회 및 정정의 모든 입력과 유효본 및 원금 정의 출력, report 및 preview/close 및 월정산과 대사와 current API의 공통 선택, exact 기본과 실제 날짜 및 age 및 이월과 누락 및 미확인과 출처 및 버전과 승인 출력을 정의한다. 잘못된 입력과 scope 및 충돌과 부족 근거는 무변경 실패이며 기존 envelope와 required keys 및 의미 변경 정책을 명시한다. - 구현 근거: docs/interface-contract.md, docs/data-model.md; 구조: Existing auth and REQ-002 contract sections remain at 1-261; REQ-003 valuation/snapshot-close contract begins at 263 and includes inputs, outputs, errors, enums, signatures, compatibility and verification through 435.; 의미: REQ-001 auth/cookie/logout/gate preservation: 13-177.; REQ-002 menu/auth/shell/browser-evidence preservation: 225-261.; REQ-003 interfaces, errors, exact enums, signatures and no-write boundaries: 263-358, 401-435.; Named source/test references: 348, 393-398, 401-415.; 현재 full 문서와 trusted policy 및 pinned source와 named tests를 직접 대조했다. 이전 head의 전체 문서 bytes와 현재 bytes가 같고 REQ003 전체 AC 의미를 보존한다. - 테스트 근거: tests/test_account_valuations.py, tests/test_issue_12_regressions.py, tests/test_contract_regression.py, tests/test_valuation_contract_docs.py, tests/test_issue_12_review59_account.py - 판정 근거: 승인된 산출물의 구조와 의미를 별도로 검토했다. 초기 작성시 미정은 실제 PR 생성 후 PR13으로 추적되는 lifecycle 계약이며 새로운 실행 증빙 경로나 독립 browser 조합을 요구하지 않는다. - `D05-project-structure` — `satisfied` - 계약: 프로젝트 구조 문서는 기존 source와 test 및 evidence를 보존하고 SQLite schema와 migrations, application의 assets와 account writes 및 import와 reconciliation 및 monthly 책임, 공개 facade와 MCP 및 Streamlit과 기존 세 화면 및 tests를 exact 경로로 대응한다. adapter에서 선택 정책을 복제하지 않고 대출 정의와 verified as_of 및 conditional 승인 경계를 shared application에 배치한다. - 구현 근거: docs/project-structure.md; 구조: Existing Dashboard source/test/evidence/deployment placement is retained at 10-120; REQ-003 application, SQLite, MCP, Streamlit, test and document placement is specified at 122-165; ownership/regression map is at 171-212.; 의미: Existing auth/menu source-test-evidence placement: 10-120 and preservation inventory 166-196.; REQ-003 source ownership and adapter/application/SQLite boundaries: 122-165, 171-180, 198-208.; Actual named source/test references and D06 test names: 171-196.; 현재 full 문서와 trusted policy 및 pinned source와 named tests를 직접 대조했다. 이전 head의 전체 문서 bytes와 현재 bytes가 같고 REQ003 전체 AC 의미를 보존한다. - 테스트 근거: tests/test_requirement_docs.py - 판정 근거: 승인된 산출물의 구조와 의미를 별도로 검토했다. 초기 작성시 미정은 실제 PR 생성 후 PR13으로 추적되는 lifecycle 계약이며 새로운 실행 증빙 경로나 독립 browser 조합을 요구하지 않는다. - `D06-runtime-flow` — `satisfied` - 계약: 런타임 문서는 auth 및 메뉴를 보존하고 register/correct의 증빙 및 scope 검증과 append 및 유효본 확인 및 최신 캐시 동기화를 단일 트랜잭션으로 설명한다. 날짜 및 정책과 통화 및 대표 합산과 경고 read, preview 후 명시적 approval 및 원자적 freeze, reasoned reclose, 같은 근거의 monthly 및 대사, import와 이관 trigger 및 실패복구, retry와 concurrency 및 preview drift 재검증과 무부분쓰기, 비민감 valuation/run 상관 신호를 정의한다. - 구현 근거: docs/runtime-flow.md; 구조: Existing startup/login/restore/cleanup/logout and REQ-002 transition flows remain at 13-145; REQ-003 valuation, close, propagation, failure, concurrency, observability and database lifecycle flows are present at 147-241.; 의미: REQ-001 authentication lifecycle and failure semantics: 13-115.; REQ-002 auth-before-menu, query/shell preservation and browser evidence boundary: 116-145.; REQ-003 register/selection/correction and close flow: 147-185.; Failure, concurrency, observability and D06 guards: 187-241.; 현재 full 문서와 trusted policy 및 pinned source와 named tests를 직접 대조했다. 이전 head의 전체 문서 bytes와 현재 bytes가 같고 REQ003 전체 AC 의미를 보존한다. - 테스트 근거: tests/test_account_valuations.py, tests/test_asset_snapshots.py, tests/test_issue_12_regressions.py - 판정 근거: 승인된 산출물의 구조와 의미를 별도로 검토했다. 초기 작성시 미정은 실제 PR 생성 후 PR13으로 추적되는 lifecycle 계약이며 새로운 실행 증빙 경로나 독립 browser 조합을 요구하지 않는다. - `C16-supporting-evidence-scope` — `satisfied` - 계약: 모든 changed file은 승인된 기능과 필수 supporting change 또는 테스트 evidence로 설명되고 기존 requirement ID를 임의 갱신하거나 범위 밖 제품 및 설정을 변경하지 않는다. - 구현 근거: dashboard/app.py, dashboard/page_views/accounts.py, dashboard/page_views/assets.py, dashboard/page_views/monthly_settlement.py, docs/data-model.md, docs/interface-contract.md, docs/project-structure.md, docs/requirements/req-003_account-valuation-history.md, docs/runtime-flow.md, jarca_ledger_mcp/adapters/mcp/server.py, jarca_ledger_mcp/adapters/mcp/tool_contracts.py, jarca_ledger_mcp/adapters/streamlit/accounts_gateway.py, jarca_ledger_mcp/adapters/streamlit/overview_gateway.py, jarca_ledger_mcp/application/__init__.py, jarca_ledger_mcp/application/account_valuation_service.py, jarca_ledger_mcp/application/accounts_write_services.py, jarca_ledger_mcp/application/assets_service.py, jarca_ledger_mcp/application/categorization_services.py, jarca_ledger_mcp/application/cross_transfer_service.py, jarca_ledger_mcp/application/imports_service.py, jarca_ledger_mcp/application/monthly_settlement_service.py, jarca_ledger_mcp/application/reconciliation_service.py, jarca_ledger_mcp/application/review_decision_service.py, jarca_ledger_mcp/application/shared.py, jarca_ledger_mcp/application/system_services.py, jarca_ledger_mcp/application/transaction_report_services.py, jarca_ledger_mcp/application/uncategorized_workbench_service.py, jarca_ledger_mcp/infrastructure/sqlite/__init__.py, jarca_ledger_mcp/infrastructure/sqlite/connection.py, jarca_ledger_mcp/infrastructure/sqlite/migrations.py, jarca_ledger_mcp/infrastructure/sqlite/schema.py, jarca_ledger_mcp/service.py, scripts/ci_fixture_db.py, tests/test_account_basis_public_consumers.py, tests/test_account_valuation_edge_contracts.py, tests/test_account_valuations.py, tests/test_asset_snapshot_idempotency.py, tests/test_asset_snapshots.py, tests/test_contract_regression.py, tests/test_dashboard_app.py, tests/test_dashboard_menu_transition.py, tests/test_import_current_balance_authority.py, tests/test_import_provenance_policy.py, tests/test_issue_12_regressions.py, tests/test_issue_12_review59_account.py, tests/test_issue_12_review59_readonly.py, tests/test_issue_12_review59_reports.py, tests/test_issue_12_review63_accounts.py, tests/test_issue_12_review63_assets.py, tests/test_ledger_categories.py, tests/test_legacy_snapshot_migration.py, tests/test_requirement_docs.py, tests/test_review_decision_workbench.py, tests/test_seoulpay_xlsx.py, tests/test_service.py, tests/test_valuation_contract_docs.py; authoritative changed-file56개와 base-to-head Git tree가 일치하고 API diff166개 hunk의 immutable base/head 위치 및 bytes를 대조했다. Review67 및68의 head 이후 실제 실행 입력 변경은 assets_service.py의 legacy 보존과 새 test_legacy_snapshot_migration.py이며 나머지 실행 입력과 필수 문서5개는 이전 head와 동일하다. 변경분은 기존 마감 보존 및 additive 이관의 직접 승인 범위다. 이전 tracked operational evidence32개는 정본 external archive의 모든 bytes를 역사적 head blob과 비교해 보존을 확인했으며 현재 Git tree에는 docs/verification이 없다. 모든 changed path를 criterion 또는 필수 supporting change에 대응했다. 정본 external evidence-manifest/v2의 source full SHA가 현재 head와 같고 plan 및 manifest digest와 3개 실행 입력 blob 및 5개 command/result binding을 독립 검증했다. 구현자 exact-head focused71 및 전체295통과와4skip 및1warning은 구현자 실행 증빙이며 reviewer 실행 또는 CI 성공이 아니다. Exact-head status는 total_count0인 pending이며 CI 성공으로 사용하지 않는다. - 테스트 근거: tests/test_account_basis_public_consumers.py, tests/test_account_valuation_edge_contracts.py, tests/test_account_valuations.py, tests/test_asset_snapshot_idempotency.py, tests/test_asset_snapshots.py, tests/test_contract_regression.py, tests/test_dashboard_app.py, tests/test_dashboard_menu_transition.py, tests/test_import_current_balance_authority.py, tests/test_import_provenance_policy.py, tests/test_issue_12_regressions.py, tests/test_issue_12_review59_account.py, tests/test_issue_12_review59_readonly.py, tests/test_issue_12_review59_reports.py, tests/test_issue_12_review63_accounts.py, tests/test_issue_12_review63_assets.py, tests/test_ledger_categories.py, tests/test_legacy_snapshot_migration.py, tests/test_requirement_docs.py, tests/test_review_decision_workbench.py, tests/test_seoulpay_xlsx.py, tests/test_service.py, tests/test_valuation_contract_docs.py - 판정 근거: source-to-head 전체 변경과 외부 기록 무결성 및 모든 변경 경로를 대조했다. evidence 위치 변경은 테스트나 canonical 설계 문서를 삭제하지 않으며 금융 기능의 새 범위를 만들지 않는다. ### 범위 판정 - 누락: 없음 - 범위 초과: 없음 - 명세 모순: 없음 ### 결론 Issue12의 승인된 Discovery 계약24개를 현재 head에서 충족한다. Review68 F006 legacy 마감 보존은 row-level run/correction 선택과 frozen report 및 monthly/timeseries 회귀로 해소됐다. 문서 후보2건은 전체 문서와 source 및 AC를 대조한 결과 특정 복합 index와 별도 version column을 새 의무로 강제하는 해석이므로 채택하지 않았다. 구현자 exact-head focused71과 전체295통과 및4skip과1warning의 외부 기록을 독립 binding했으며 reviewer가 제품 테스트를 실행한 것으로 표현하지 않는다. reviewer 직접 실행은 하네스 helper31개 통과다. pending status를 CI 성공으로 사용하지 않는다. 지정된 명세 검토 범위에서 승인하며 merge 및 Issue close와 source 변경 또는 release/deployment는 수행하지 않는다. <!-- gitea-agent:implementation-spec-review/v1 owner=jsfamily repository=jarca-ledger-mcp issue=12 pr=13 head=4b8b74ba2adbc4a752c9139c5161b31e104da763 contract-sha256=6d86b591b022fcc722611bfec6d24e54a64216ab6f7c4098f357e25420218818 result-sha256=8cfb73cf78d68e9f89538765a22d913883ed4d5e26e1978e6c0deb6d91c08c04 correlation=c2c08b6a10389187e9d7b166bb39bba4e242828a6467add2fb6c89828e16c2f5 -->
gitea-review-agent left a comment
Owner
  • Verdict: approve

코드 재리뷰 — Issue #12 / PR #13

  • HEAD: 4b8b74ba2adbc4a752c9139c5161b31e104da763; base: 5813dd484196239ab1fac4ba066c5b4922fb33e6.
  • 계약 SHA-256: 6d86b591b022fcc722611bfec6d24e54a64216ab6f7c4098f357e25420218818; 현재 HEAD의 authoritative spec 승인: #69.
  • scoped gitea-code-review v0.1.2의 native admission/publication/readback을 사용했다.

범위와 근거

현재 전체 base-to-head diff는 56개 파일이다. 이전 review #68 HEAD와 byte-identical인 54개에 이전 검토를 이어 적용하고, 제품 로직 1개와 회귀 테스트 1개를 새로 검토했다. 제거된 실행 기록 32개는 canonical verification archive의 bytes/SHA-256을 원본 Git blob과 전부 대조해 보존을 확인했다. 변경 로직, report/timeseries/monthly callers, migration 및 tests를 검토했고 bounded static worker의 결과는 main reviewer의 코드 확인 및 실제 실행으로 대조했다. 별도 무관한 기능 검토로 범위를 넓히지 않았다.

기존 지적의 해소

  • F-006 해소: application/assets_service.py:327-357은 새 run record가 없는 schema11 legacy closed rows를 최신 row-based run identity로 그룹 선택한다. frozen 금액/정정 정보를 보존하고 legacy_read_only와 빈 approval로 표시하며 valuation ID나 승인 근거를 추측하지 않는다. :432, :974-1014 및 기존 timeseries/monthly 소비자와 함께 확인했다.
  • Reviewer는 실제 base public close API로 schema11 DB를 만들었다: 100으로 마감 → live 값을 200으로 변경. 복사본을 이전 HEAD로 이관하면 200/live_authority가 반환되지만, 현재 HEAD는 100/closed를 반환했다. 물리 snapshot도 100이다. 현재 report·timeseries·monthly 모두 100이며 반복 조회 전후 DB SHA-256이 동일했다.
  • 새 tests/test_legacy_snapshot_migration.py의 4개 회귀는 legacy report/시계열/월정산 및 최신 정정 run의 전체 그룹 선택, read-only, 비추론 경계를 확인한다.
  • F-001~F-005 유지 해소: 현재 HEAD에서 preview→close/replay, 최초·정정 exact replay, zero-row close timeseries, frozen currency/valuation identity, basis-only no-write 거부와 0원 허용을 독립 probe로 다시 확인했다.

실행 결과

  • 전체 pytest: 295 passed, 4 skipped, failures=0, errors=0; 총 299개, exit 0.
  • ruff check --no-cache ., 전체 base-to-head git diff --check, 독립 F001~F006 probe: 모두 exit 0.
  • 모든 새 근거는 checkout 밖 /opt/data/gitea-agent/repositories/jsfamily/jarca-ledger-mcp/worktrees/issue-12/verification/issue-12-pr-13-20261008T063847Z에 저장했다. evidence-manifest/v2의 current HEAD, 56개 source blob OID/SHA-256, plan/claim/command/출력/경계/clean status를 helper로 검증했다. Reviewer-owned 외부 venv와 credential-free child 환경을 사용했다.

비차단 경계와 한계

N-002 · baseline 의존성 호환 경계: 새 환경의 무제한 resolve는 MCP 2.3.0을 설치했고 mcp.server.fastmcp 제거로 pytest collection이 실패했다. 실패 manifest는 그대로 보존했다. Base에도 동일한 mcp>=1.0.0 및 FastMCP import가 있어 이번 delta 도입 결함으로 분류하지 않는다. 현재 검증은 선언 범위를 만족하는 MCP 1.30.0에서 반복한 결과이며, default fresh install 성공이라고 주장하지 않는다. 실제 package versions도 compatibility manifest의 별도 command로 기록했다. Baseline 유지보수에서 v1 상한을 명시하거나 v2 이관을 별도 범위로 다루는 것이 적절하다. PyMuPDF의 stdout 경고로 실패한 초기 probe parser는 정확히 하나의 JSON record를 구분하도록 reviewer wrapper만 수정했다.
기존 N-001(미출시 PR 중간 HEAD의 단일 SHA fingerprint replay 호환)은 이번 delta에서 바뀌지 않았다. 배포 baseline/schema11에는 해당 idempotency table/API가 없어 supported baseline 회귀로 분류하지 않으며 이 항목으로 승인 차단하지 않는다. 그 중간 버전 DB를 별도 지원한다면 fingerprint version 비교/no-write replay 경계를 명시할 필요가 있다.

작업자의 source 라벨 후보는 physical asset_snapshots 권위 및 legacy_read_only metadata가 유지되어 차단 결함으로 채택하지 않았다. Run record를 임의 삭제한 손상 DB가 legacy로 보일 가능성은 잔여 위험이다. 정상 close는 rows/run을 같은 BEGIN IMMEDIATE transaction으로 저장·rollback하며, 정상 public API의 partial-run 재현 경로는 확인되지 않았다. 임의 DB 손상 판별까지 검증했다고 주장하지 않는다.

4개 private KB/Toss PDF fixture/password 테스트는 자료 부재로 skip이다. 실제 금융 자료·운영 DB·배포·새 real-browser 탐색은 실행하지 않았다. 원격 CI 상태는 검토 snapshot에서 비어 있으며 reviewer의 직접 실행을 remote CI 성공으로 표현하지 않는다.

지정된 재리뷰 범위에서 material defect를 발견하지 않았고 F006의 frozen legacy report 보존이 직접 재현으로 확인돼 approve다. 이는 결함 부재의 증명이 아니다. Source/Issue/Discovery 변경, commit/push/merge/배포는 수행하지 않았다.

Redacted run 기록: /opt/data/gitea-agent/logs/gitea-review-agent/runs/issue-12-pr-13-20261008T063847Z.

<!-- gitea-agent:code-review/v1 owner=jsfamily repository=jarca-ledger-mcp issue=12 pr=13 head=4b8b74ba2adbc4a752c9139c5161b31e104da763 contract-sha256=6d86b591b022fcc722611bfec6d24e54a64216ab6f7c4098f357e25420218818 --> - Verdict: `approve` ## 코드 재리뷰 — Issue #12 / PR #13 - HEAD: `4b8b74ba2adbc4a752c9139c5161b31e104da763`; base: `5813dd484196239ab1fac4ba066c5b4922fb33e6`. - 계약 SHA-256: `6d86b591b022fcc722611bfec6d24e54a64216ab6f7c4098f357e25420218818`; 현재 HEAD의 authoritative spec 승인: **#69**. - scoped `gitea-code-review` v0.1.2의 native admission/publication/readback을 사용했다. ### 범위와 근거 현재 전체 base-to-head diff는 56개 파일이다. 이전 review #68 HEAD와 byte-identical인 54개에 이전 검토를 이어 적용하고, 제품 로직 1개와 회귀 테스트 1개를 새로 검토했다. 제거된 실행 기록 32개는 canonical verification archive의 bytes/SHA-256을 원본 Git blob과 전부 대조해 보존을 확인했다. 변경 로직, report/timeseries/monthly callers, migration 및 tests를 검토했고 bounded static worker의 결과는 main reviewer의 코드 확인 및 실제 실행으로 대조했다. 별도 무관한 기능 검토로 범위를 넓히지 않았다. ### 기존 지적의 해소 - **F-006 해소:** `application/assets_service.py:327-357`은 새 run record가 없는 schema11 legacy closed rows를 최신 row-based run identity로 그룹 선택한다. frozen 금액/정정 정보를 보존하고 `legacy_read_only`와 빈 approval로 표시하며 valuation ID나 승인 근거를 추측하지 않는다. `:432`, `:974-1014` 및 기존 timeseries/monthly 소비자와 함께 확인했다. - Reviewer는 **실제 base public close API**로 schema11 DB를 만들었다: 100으로 마감 → live 값을 200으로 변경. 복사본을 이전 HEAD로 이관하면 200/live_authority가 반환되지만, 현재 HEAD는 **100/closed**를 반환했다. 물리 snapshot도 100이다. 현재 report·timeseries·monthly 모두 100이며 반복 조회 전후 DB SHA-256이 동일했다. - 새 `tests/test_legacy_snapshot_migration.py`의 4개 회귀는 legacy report/시계열/월정산 및 최신 정정 run의 전체 그룹 선택, read-only, 비추론 경계를 확인한다. - **F-001~F-005 유지 해소:** 현재 HEAD에서 preview→close/replay, 최초·정정 exact replay, zero-row close timeseries, frozen currency/valuation identity, basis-only no-write 거부와 0원 허용을 독립 probe로 다시 확인했다. ### 실행 결과 - 전체 pytest: **295 passed, 4 skipped**, failures=0, errors=0; 총 299개, exit 0. - `ruff check --no-cache .`, 전체 base-to-head `git diff --check`, 독립 F001~F006 probe: 모두 exit 0. - 모든 새 근거는 checkout 밖 `/opt/data/gitea-agent/repositories/jsfamily/jarca-ledger-mcp/worktrees/issue-12/verification/issue-12-pr-13-20261008T063847Z`에 저장했다. `evidence-manifest/v2`의 current HEAD, 56개 source blob OID/SHA-256, plan/claim/command/출력/경계/clean status를 helper로 검증했다. Reviewer-owned 외부 venv와 credential-free child 환경을 사용했다. ### 비차단 경계와 한계 **N-002 · baseline 의존성 호환 경계:** 새 환경의 무제한 resolve는 MCP 2.3.0을 설치했고 `mcp.server.fastmcp` 제거로 pytest collection이 실패했다. 실패 manifest는 그대로 보존했다. Base에도 동일한 `mcp>=1.0.0` 및 FastMCP import가 있어 이번 delta 도입 결함으로 분류하지 않는다. 현재 검증은 선언 범위를 만족하는 **MCP 1.30.0**에서 반복한 결과이며, default fresh install 성공이라고 주장하지 않는다. 실제 package versions도 compatibility manifest의 별도 command로 기록했다. Baseline 유지보수에서 v1 상한을 명시하거나 v2 이관을 별도 범위로 다루는 것이 적절하다. PyMuPDF의 stdout 경고로 실패한 초기 probe parser는 정확히 하나의 JSON record를 구분하도록 reviewer wrapper만 수정했다. 기존 N-001(미출시 PR 중간 HEAD의 단일 SHA fingerprint replay 호환)은 이번 delta에서 바뀌지 않았다. 배포 baseline/schema11에는 해당 idempotency table/API가 없어 supported baseline 회귀로 분류하지 않으며 이 항목으로 승인 차단하지 않는다. 그 중간 버전 DB를 별도 지원한다면 fingerprint version 비교/no-write replay 경계를 명시할 필요가 있다. 작업자의 source 라벨 후보는 physical asset_snapshots 권위 및 `legacy_read_only` metadata가 유지되어 차단 결함으로 채택하지 않았다. Run record를 임의 삭제한 손상 DB가 legacy로 보일 가능성은 잔여 위험이다. 정상 close는 rows/run을 같은 BEGIN IMMEDIATE transaction으로 저장·rollback하며, 정상 public API의 partial-run 재현 경로는 확인되지 않았다. 임의 DB 손상 판별까지 검증했다고 주장하지 않는다. 4개 private KB/Toss PDF fixture/password 테스트는 자료 부재로 skip이다. 실제 금융 자료·운영 DB·배포·새 real-browser 탐색은 실행하지 않았다. 원격 CI 상태는 검토 snapshot에서 비어 있으며 reviewer의 직접 실행을 remote CI 성공으로 표현하지 않는다. 지정된 재리뷰 범위에서 material defect를 발견하지 않았고 F006의 frozen legacy report 보존이 직접 재현으로 확인돼 **approve**다. 이는 결함 부재의 증명이 아니다. Source/Issue/Discovery 변경, commit/push/merge/배포는 수행하지 않았다. Redacted run 기록: `/opt/data/gitea-agent/logs/gitea-review-agent/runs/issue-12-pr-13-20261008T063847Z`.
genichin merged commit 2ab68f9278 into main 2026-10-08 07:14:10 +00:00
genichin deleted branch gitea-agent/issue-12-account-valuation-history 2026-10-08 07:14:11 +00:00
Sign in to join this conversation.