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
4 changed files with 218 additions and 0 deletions
Showing only changes of commit d258cfdeb4 - Show all commits
@@ -0,0 +1,72 @@
{
"schema": "contract-preservation-inventory/v1",
"issue": 12,
"pull_request": 13,
"review_id": 64,
"reviewed_head": "c7a9cfa50d25ac68b6b722b415dc89bea8f2ae24",
"source_revision": "e41db959e4aa0093ab254ec4bb8aafd7dd57aafa",
"contracts": [
{
"contract": "current display cache and historical valuation authority remain separate and an evidence basis date requires a usable integer balance",
"status": "preserved",
"preserved_by": [
"test_empty_balance_with_basis_date_is_rejected_without_mutation_before_import",
"tests/test_import_current_balance_authority.py"
]
},
{
"contract": "actual zero remains valid while empty, whitespace, and non-integer balances fail without mutation",
"status": "preserved",
"preserved_by": [
"tests/test_issue_12_review63_accounts.py",
"tests/test_import_current_balance_authority.py"
]
},
{
"contract": "snapshot runs and corrections are append-only and idempotent replay returns the original immutable public response",
"status": "preserved",
"preserved_by": [
"test_replay_preserves_redacted_unverified_candidates_after_correction",
"test_replay_preserves_blocking_candidate_warning_shape",
"tests/test_issue_12_review63_assets.py"
]
},
{
"contract": "unverified candidate metadata remains redacted and candidate state hashes bind persisted evidence",
"status": "preserved",
"preserved_by": [
"test_replay_preserves_redacted_unverified_candidates_after_correction"
]
},
{
"contract": "malformed immutable evidence fails closed without report, replay, timeseries, or snapshot mutation ambiguity",
"status": "preserved",
"preserved_by": [
"test_malformed_persisted_evidence_fails_closed_without_snapshot_writes"
]
},
{
"contract": "canonical documentation describes actual account, currency, purpose, and basis-date selection together with existing physical index limitations",
"status": "preserved",
"preserved_by": [
"test_data_model_documents_valuation_selection_contract_and_index_mapping"
]
},
{
"contract": "all remaining Issue 12 acceptance behavior and prior Review 63 regressions remain intact",
"status": "preserved",
"preserved_by": [
"review64-focused-regressions",
"review64-full-suite",
"review64-ruff",
"review64-compileall",
"review64-diff-check"
]
}
],
"missing": 0,
"ambiguous": 0,
"limitations": [
"Four fixture-dependent PDF tests remain skipped because private KB Bank and Toss Securities fixtures are unavailable."
]
}
@@ -0,0 +1,64 @@
{
"environment": ["os", "kernel", "architecture", "python", "uv"],
"command_env_allowlist": ["PATH", "HOME", "TMPDIR", "LANG", "VIRTUAL_ENV", "UV_CACHE_DIR"],
"secret_env_names": ["GITEA_TOKEN"],
"forbidden_regexes": [],
"hash_paths": [
"jarca_ledger_mcp/application/accounts_write_services.py",
"jarca_ledger_mcp/application/assets_service.py",
"tests/test_import_current_balance_authority.py",
"tests/test_asset_snapshot_idempotency.py",
"tests/test_valuation_contract_docs.py",
"tests/test_issue_12_review63_accounts.py",
"tests/test_issue_12_review63_assets.py",
"tests/test_issue_12_regressions.py",
"docs/data-model.md",
"docs/interface-contract.md",
"docs/requirements/req-003_account-valuation-history.md"
],
"commands": [
{
"id": "review64-focused-regressions",
"purpose": "Run Review 64 and preserved Review 63 regression coverage",
"argv": ["uv", "run", "--frozen", "--extra", "dev", "--extra", "dashboard", "pytest", "-o", "addopts=", "-q", "tests/test_import_current_balance_authority.py", "tests/test_asset_snapshot_idempotency.py", "tests/test_valuation_contract_docs.py", "tests/test_issue_12_review63_accounts.py", "tests/test_issue_12_review63_assets.py", "tests/test_account_valuation_edge_contracts.py", "tests/test_issue_12_regressions.py"],
"expected_exit_code": 0,
"max_output_bytes": 65536,
"claims": ["review64-findings-green"]
},
{
"id": "review64-full-suite",
"purpose": "Run the canonical full repository suite at the functional source revision",
"argv": ["uv", "run", "--frozen", "--extra", "dev", "--extra", "dashboard", "pytest", "-o", "addopts=", "-q"],
"expected_exit_code": 0,
"max_output_bytes": 65536,
"claims": ["review64-full-suite"]
},
{
"id": "review64-ruff",
"purpose": "Run repository lint checks",
"argv": ["uv", "run", "--frozen", "--extra", "dev", "--extra", "dashboard", "ruff", "check", "."],
"expected_exit_code": 0,
"max_output_bytes": 65536,
"claims": ["review64-ruff"]
},
{
"id": "review64-compileall",
"purpose": "Compile package, dashboard, tests, and scripts",
"argv": ["uv", "run", "--frozen", "--extra", "dev", "--extra", "dashboard", "python", "-m", "compileall", "-q", "jarca_ledger_mcp", "dashboard", "tests", "scripts"],
"expected_exit_code": 0,
"max_output_bytes": 65536,
"claims": ["review64-compileall"]
},
{
"id": "review64-diff-check",
"purpose": "Check the complete pull-request diff for whitespace errors",
"argv": ["git", "diff", "--check", "main...HEAD"],
"expected_exit_code": 0,
"max_output_bytes": 65536,
"claims": ["review64-diff-check"]
}
],
"limitations": [
"Four PDF fixture tests are skipped because private KB Bank and Toss Securities PDF fixtures are unavailable."
]
}
@@ -0,0 +1,47 @@
{
"schema": "review-finding-matrix/v1",
"issue": 12,
"pull_request": 13,
"review_id": 64,
"reviewed_head": "c7a9cfa50d25ac68b6b722b415dc89bea8f2ae24",
"source_revision": "e41db959e4aa0093ab254ec4bb8aafd7dd57aafa",
"contract_sha256": "6d86b591b022fcc722611bfec6d24e54a64216ab6f7c4098f357e25420218818",
"findings": [
{
"id": "C05-current-import",
"classification": "valid_fix",
"status": "resolved",
"production": "jarca_ledger_mcp/application/accounts_write_services.py",
"regression": "test_empty_balance_with_basis_date_is_rejected_without_mutation_before_import",
"claim": "an empty balance cannot acquire a basis date or block a later valid dated import; zero and valid integer balances remain distinct"
},
{
"id": "N02-close-replay-run-binding",
"classification": "valid_fix",
"status": "resolved",
"production": "jarca_ledger_mcp/application/assets_service.py",
"regressions": [
"test_replay_preserves_redacted_unverified_candidates_after_correction",
"test_replay_preserves_blocking_candidate_warning_shape"
],
"claim": "immutable close replay preserves redacted candidate metadata and exact blocking or nonblocking warning shape without additional writes"
},
{
"id": "D03-data-model",
"classification": "evidence_gap",
"status": "resolved",
"production": "docs/data-model.md",
"regression": "test_data_model_documents_valuation_selection_contract_and_index_mapping",
"claim": "the data model maps actual selection predicates to existing indexes and states their limitations without inventing new DDL"
},
{
"id": "IR-001-malformed-persisted-evidence",
"classification": "valid_fix",
"status": "resolved",
"production": "jarca_ledger_mcp/application/assets_service.py",
"regression": "test_malformed_persisted_evidence_fails_closed_without_snapshot_writes",
"claim": "malformed persisted evidence returns a controlled data_integrity_error from report, replay, and timeseries paths without snapshot writes"
}
],
"green_evidence": "evidence-manifest.json"
}
@@ -0,0 +1,35 @@
{
"schema": "review-red-evidence/v1",
"issue": 12,
"pull_request": 13,
"review_id": 64,
"reviewed_head": "c7a9cfa50d25ac68b6b722b415dc89bea8f2ae24",
"contract_sha256": "6d86b591b022fcc722611bfec6d24e54a64216ab6f7c4098f357e25420218818",
"reproductions": [
{
"id": "C05-current-import",
"command": "uv run pytest -q tests/test_import_current_balance_authority.py::test_empty_balance_with_basis_date_is_rejected_without_mutation_before_import",
"exit_code": 1,
"observed": "update_ledger_account accepted an empty balance paired with a basis date, persisted unusable cache authority, and could block a later valid dated import"
},
{
"id": "N02-close-replay-run-binding",
"command": "uv run python synthetic verified-plus-unverified close and replay probe",
"exit_code": 1,
"observed": "replay omitted included_items.unverified_candidates and the nonblocking warning marker, so replay differed from the first immutable response"
},
{
"id": "D03-data-model",
"command": "python -c tests.test_valuation_contract_docs.test_data_model_documents_valuation_selection_contract_and_index_mapping",
"exit_code": 1,
"observed": "the canonical data model did not document select_account_valuation predicates or existing index coverage and limitations"
},
{
"id": "IR-001-malformed-persisted-evidence",
"command": "uv run pytest -o addopts= -q tests/test_asset_snapshot_idempotency.py::test_malformed_persisted_evidence_fails_closed_without_snapshot_writes",
"exit_code": 1,
"observed": "malformed persisted excluded_evidence raised JSONDecodeError instead of a controlled fail-closed response"
}
],
"sensitive_data": "synthetic fixtures only; no credentials or real financial data"
}