diff --git a/docs/verification/issue-12-review-66/contract-preservation-inventory.json b/docs/verification/issue-12-review-66/contract-preservation-inventory.json new file mode 100644 index 0000000..100b925 --- /dev/null +++ b/docs/verification/issue-12-review-66/contract-preservation-inventory.json @@ -0,0 +1,59 @@ +{ + "schema": "contract-preservation-inventory/v1", + "issue": 12, + "pull_request": 13, + "review_id": 66, + "reviewed_head": "3bf9b77c6cc167a4e2a8706271bdf8e848d2c4fe", + "source_revision": "31d1c11dcf397ddf6a23e98d6d9062f96bab0194", + "contracts": [ + { + "contract": "last_balance is an exact integer or NULL-compatible unknown value; boolean and floating-point coercion are invalid while zero and signed integer text remain valid", + "status": "preserved", + "preserved_by": [ + "test_update_rejects_bool_or_float_dated_balance_without_mutation", + "test_update_rejects_empty_undated_balance_without_mutation", + "test_update_preserves_zero_and_signed_integer_balance_semantics" + ] + }, + { + "contract": "invalid account updates return validation_error before changing account cache or valuation history", + "status": "preserved", + "preserved_by": [ + "test_update_rejects_bool_or_float_dated_balance_without_mutation", + "test_update_rejects_empty_undated_balance_without_mutation" + ] + }, + { + "contract": "a historical dated candidate is append-only and cannot roll back a newer current cache", + "status": "preserved", + "preserved_by": [ + "test_historical_account_update_preserves_current_and_adds_one_candidate", + "test_late_import_current_balance_is_authoritative_by_evidence_basis_date" + ] + }, + { + "contract": "unknown basis remains distinct from last_synced_at and an undated valid balance write creates no dated candidate", + "status": "preserved", + "preserved_by": [ + "test_account_write_sync_timestamp_does_not_infer_balance_basis_or_candidate", + "test_unknown_legacy_balance_basis_is_not_reported_as_valuation_date" + ] + }, + { + "contract": "Review 65 create validation, actual zero, valid import recovery, public consumer, valuation selection, snapshot replay, read-only, migration, privacy, authentication, and menu semantics remain intact", + "status": "preserved", + "preserved_by": [ + "review66-focused-regressions", + "review66-full-suite", + "review66-ruff", + "review66-compileall", + "review66-diff-check" + ] + } + ], + "missing": 0, + "ambiguous": 0, + "limitations": [ + "Four fixture-dependent PDF tests remain skipped because private KB Bank and Toss Securities fixtures are unavailable." + ] +} diff --git a/docs/verification/issue-12-review-66/evidence-plan.json b/docs/verification/issue-12-review-66/evidence-plan.json new file mode 100644 index 0000000..7e280c9 --- /dev/null +++ b/docs/verification/issue-12-review-66/evidence-plan.json @@ -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/account_valuation_service.py", + "tests/test_import_current_balance_authority.py", + "tests/test_account_basis_public_consumers.py", + "tests/test_issue_12_review63_accounts.py", + "tests/test_account_valuation_edge_contracts.py", + "tests/test_account_valuations.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": "review66-focused-regressions", + "purpose": "Run Review 66 and preserved account authority regressions", + "argv": ["uv", "run", "--frozen", "--extra", "dev", "--extra", "dashboard", "pytest", "-o", "addopts=", "-q", "tests/test_import_current_balance_authority.py", "tests/test_account_basis_public_consumers.py", "tests/test_issue_12_review63_accounts.py", "tests/test_account_valuation_edge_contracts.py", "tests/test_account_valuations.py", "tests/test_issue_12_regressions.py"], + "expected_exit_code": 0, + "max_output_bytes": 65536, + "claims": ["review66-findings-green"] + }, + { + "id": "review66-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": ["review66-full-suite"] + }, + { + "id": "review66-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": ["review66-ruff"] + }, + { + "id": "review66-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": ["review66-compileall"] + }, + { + "id": "review66-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": ["review66-diff-check"] + } + ], + "limitations": [ + "Four PDF fixture tests are skipped because private KB Bank and Toss Securities PDF fixtures are unavailable." + ] +} diff --git a/docs/verification/issue-12-review-66/finding-matrix.json b/docs/verification/issue-12-review-66/finding-matrix.json new file mode 100644 index 0000000..905d22e --- /dev/null +++ b/docs/verification/issue-12-review-66/finding-matrix.json @@ -0,0 +1,24 @@ +{ + "schema": "review-finding-matrix/v1", + "issue": 12, + "pull_request": 13, + "review_id": 66, + "reviewed_head": "3bf9b77c6cc167a4e2a8706271bdf8e848d2c4fe", + "source_revision": "31d1c11dcf397ddf6a23e98d6d9062f96bab0194", + "contract_sha256": "6d86b591b022fcc722611bfec6d24e54a64216ab6f7c4098f357e25420218818", + "findings": [ + { + "id": "C05-account-update-balance-authority", + "classification": "valid_fix", + "status": "resolved", + "production": "jarca_ledger_mcp/application/accounts_write_services.py", + "regressions": [ + "test_update_rejects_bool_or_float_dated_balance_without_mutation", + "test_update_rejects_empty_undated_balance_without_mutation", + "test_update_preserves_zero_and_signed_integer_balance_semantics" + ], + "claim": "account updates reject boolean, floating-point, empty, whitespace, and non-integer balance values before account or valuation mutation while preserving zero, signed integer text, dated candidates, historical cache authority, and unknown-basis semantics" + } + ], + "green_evidence": "evidence-manifest.json" +} diff --git a/docs/verification/issue-12-review-66/red-evidence.json b/docs/verification/issue-12-review-66/red-evidence.json new file mode 100644 index 0000000..45299b4 --- /dev/null +++ b/docs/verification/issue-12-review-66/red-evidence.json @@ -0,0 +1,23 @@ +{ + "schema": "review-red-evidence/v1", + "issue": 12, + "pull_request": 13, + "review_id": 66, + "reviewed_head": "3bf9b77c6cc167a4e2a8706271bdf8e848d2c4fe", + "contract_sha256": "6d86b591b022fcc722611bfec6d24e54a64216ab6f7c4098f357e25420218818", + "reproductions": [ + { + "id": "C05-account-update-balance-authority", + "command": "uv run --frozen --extra dev --extra dashboard pytest -o addopts= -q tests/test_import_current_balance_authority.py::test_update_rejects_bool_or_float_dated_balance_without_mutation tests/test_import_current_balance_authority.py::test_update_rejects_empty_undated_balance_without_mutation", + "exit_code": 1, + "observed": "2 failed: dated bool and float values returned success after coercion and appended candidates; an undated empty string returned success and replaced the integer cache" + }, + { + "id": "C05-exact-head-synthetic-probe", + "command": "uv run --frozen --extra dev --extra dashboard python ", + "exit_code": 0, + "observed": "True, False, 1.2, and -1.2 were persisted as 1, 0, 1, and -1 with dated candidates; an undated empty string was persisted and cleared the basis; all invalid requests mutated state" + } + ], + "sensitive_data": "synthetic temporary databases only; no credentials or real financial data" +}