From 4b8b74ba2adbc4a752c9139c5161b31e104da763 Mon Sep 17 00:00:00 2001 From: gitea-impl-agent Date: Thu, 8 Oct 2026 03:30:59 +0000 Subject: [PATCH] fix: preserve migrated legacy snapshot closes --- .../contract-preservation-inventory.json | 486 ------------------ .../issue-12-review-60/evidence-manifest.json | 1 - .../issue-12-review-60/evidence-plan.json | 181 ------- .../final-independent-review.json | 16 - .../issue-12-review-60/finding-matrix.json | 148 ------ .../issue-12-review-60/red-evidence.json | 82 --- .../contract-preservation-inventory.json | 50 -- .../issue-12-review-61/evidence-manifest.json | 208 -------- .../issue-12-review-61/evidence-plan.json | 61 --- .../issue-12-review-61/finding-matrix.json | 56 -- .../issue-12-review-61/green-evidence.json | 30 -- .../issue-12-review-61/red-evidence.json | 9 - .../contract-preservation-inventory.json | 36 -- .../issue-12-review-63/evidence-manifest.json | 1 - .../issue-12-review-63/evidence-plan.json | 62 --- .../issue-12-review-63/finding-matrix.json | 59 --- .../issue-12-review-63/red-evidence.json | 74 --- .../contract-preservation-inventory.json | 72 --- .../issue-12-review-64/evidence-manifest.json | 1 - .../issue-12-review-64/evidence-plan.json | 64 --- .../issue-12-review-64/finding-matrix.json | 47 -- .../issue-12-review-64/red-evidence.json | 35 -- .../contract-preservation-inventory.json | 58 --- .../issue-12-review-65/evidence-manifest.json | 1 - .../issue-12-review-65/evidence-plan.json | 62 --- .../issue-12-review-65/finding-matrix.json | 31 -- .../issue-12-review-65/red-evidence.json | 23 - .../contract-preservation-inventory.json | 59 --- .../issue-12-review-66/evidence-manifest.json | 1 - .../issue-12-review-66/evidence-plan.json | 64 --- .../issue-12-review-66/finding-matrix.json | 24 - .../issue-12-review-66/red-evidence.json | 23 - .../application/assets_service.py | 35 +- tests/test_legacy_snapshot_migration.py | 146 ++++++ 34 files changed, 178 insertions(+), 2128 deletions(-) delete mode 100644 docs/verification/issue-12-review-60/contract-preservation-inventory.json delete mode 100644 docs/verification/issue-12-review-60/evidence-manifest.json delete mode 100644 docs/verification/issue-12-review-60/evidence-plan.json delete mode 100644 docs/verification/issue-12-review-60/final-independent-review.json delete mode 100644 docs/verification/issue-12-review-60/finding-matrix.json delete mode 100644 docs/verification/issue-12-review-60/red-evidence.json delete mode 100644 docs/verification/issue-12-review-61/contract-preservation-inventory.json delete mode 100644 docs/verification/issue-12-review-61/evidence-manifest.json delete mode 100644 docs/verification/issue-12-review-61/evidence-plan.json delete mode 100644 docs/verification/issue-12-review-61/finding-matrix.json delete mode 100644 docs/verification/issue-12-review-61/green-evidence.json delete mode 100644 docs/verification/issue-12-review-61/red-evidence.json delete mode 100644 docs/verification/issue-12-review-63/contract-preservation-inventory.json delete mode 100644 docs/verification/issue-12-review-63/evidence-manifest.json delete mode 100644 docs/verification/issue-12-review-63/evidence-plan.json delete mode 100644 docs/verification/issue-12-review-63/finding-matrix.json delete mode 100644 docs/verification/issue-12-review-63/red-evidence.json delete mode 100644 docs/verification/issue-12-review-64/contract-preservation-inventory.json delete mode 100644 docs/verification/issue-12-review-64/evidence-manifest.json delete mode 100644 docs/verification/issue-12-review-64/evidence-plan.json delete mode 100644 docs/verification/issue-12-review-64/finding-matrix.json delete mode 100644 docs/verification/issue-12-review-64/red-evidence.json delete mode 100644 docs/verification/issue-12-review-65/contract-preservation-inventory.json delete mode 100644 docs/verification/issue-12-review-65/evidence-manifest.json delete mode 100644 docs/verification/issue-12-review-65/evidence-plan.json delete mode 100644 docs/verification/issue-12-review-65/finding-matrix.json delete mode 100644 docs/verification/issue-12-review-65/red-evidence.json delete mode 100644 docs/verification/issue-12-review-66/contract-preservation-inventory.json delete mode 100644 docs/verification/issue-12-review-66/evidence-manifest.json delete mode 100644 docs/verification/issue-12-review-66/evidence-plan.json delete mode 100644 docs/verification/issue-12-review-66/finding-matrix.json delete mode 100644 docs/verification/issue-12-review-66/red-evidence.json create mode 100644 tests/test_legacy_snapshot_migration.py diff --git a/docs/verification/issue-12-review-60/contract-preservation-inventory.json b/docs/verification/issue-12-review-60/contract-preservation-inventory.json deleted file mode 100644 index 40acbe3..0000000 --- a/docs/verification/issue-12-review-60/contract-preservation-inventory.json +++ /dev/null @@ -1,486 +0,0 @@ -{ - "baseline_revision": "5813dd484196239ab1fac4ba066c5b4922fb33e6", - "reviewed_head": "6a8a27a74ece9a9cce6f9772259677813d91ddf8", - "items": [ - { - "path": "docs/requirements/req-003_account-valuation-history.md", - "baseline_id": "REQ-003.01", - "semantic_key": "additive_schema_migration_and_legacy_preservation", - "meaning": "Schema 11 tables, fields, rows, and transactions remain readable; schema 12 adds valuation and snapshot structures and migration is idempotent.", - "reviewed_ids": [ - "REQ-003.01", - "REQ-003.01-AC01" - ], - "reviewed_status": "present_and_approved", - "planned_ids": [ - "N01" - ], - "planned_status": "strengthen_verification_only; semantics_unchanged", - "authorization": "Preserve additive migration, old-row retention, and repeatability; rework may make evidence stricter but may not delete, infer-migrate, or rename legacy data.", - "evidence_paths": [ - "jarca_ledger_mcp/infrastructure/sqlite/migrations.py", - "docs/data-model.md", - "tests/test_account_valuations.py::test_account_valuation_schema_is_v12_and_idempotent", - "tests/test_issue_12_regressions.py::test_schema12_migration_preserves_legacy_rows_indexes_and_is_idempotent" - ], - "verification": "Reviewed head contains schema-12 documentation and named tests; REQ-001/REQ-002 requirement files are unchanged from baseline." - }, - { - "path": "docs/requirements/req-003_account-valuation-history.md", - "baseline_id": "REQ-003.02", - "semantic_key": "verified_leaf_exact_as_of_selection", - "meaning": "Selection is scoped by account, currency, and valuation kind; exact selects same-date verified leaf, as_of selects latest prior verified leaf, and future/unverified/rejected/unknown evidence is excluded or warned.", - "reviewed_ids": [ - "REQ-003.02", - "REQ-003.02-AC01" - ], - "reviewed_status": "present_and_approved", - "planned_ids": [ - "C05" - ], - "planned_status": "strengthen_authority_and_warning_contract; semantics_unchanged", - "authorization": "Only verified leaves remain authoritative; rework may expose more explicit warnings, exclusions, age, and scope but cannot broaden authority.", - "evidence_paths": [ - "jarca_ledger_mcp/application/account_valuation_service.py", - "jarca_ledger_mcp/application/assets_service.py", - "docs/interface-contract.md", - "tests/test_account_valuations.py::test_select_exact_and_as_of_excludes_unverified_and_reports_carry_forward", - "tests/test_issue_12_regressions.py::test_preview_warns_about_unverified_candidate_when_verified_value_is_selected" - ], - "verification": "Selection terminology, scope, and exclusion rules are documented and backed by focused tests." - }, - { - "path": "docs/requirements/req-003_account-valuation-history.md", - "baseline_id": "REQ-003.03", - "semantic_key": "idempotency_and_append_only_correction", - "meaning": "Equal payloads reuse existing rows or runs; changed payloads conflict; corrections append one reasoned child without mutating the parent; invalid parent scope, cycles, self-parent, duplicate child, and source/key conflicts are no-write failures.", - "reviewed_ids": [ - "REQ-003.03", - "REQ-003.03-AC01" - ], - "reviewed_status": "present_and_approved", - "planned_ids": [ - "C06", - "D03" - ], - "planned_status": "strengthen_conflict_and_replay_evidence; semantics_unchanged", - "authorization": "Preserve immutable history, one-child cardinality, request-fingerprint equality, and no-write conflict behavior.", - "evidence_paths": [ - "jarca_ledger_mcp/application/account_valuation_service.py", - "jarca_ledger_mcp/application/assets_service.py", - "docs/data-model.md", - "tests/test_account_valuations.py::test_register_same_idempotency_payload_reuses_row_and_changed_payload_conflicts", - "tests/test_account_valuations.py::test_correction_is_append_only_reasoned_and_single_child", - "tests/test_issue_12_review59_account.py::test_direct_correction_requires_matching_existing_parent_and_reason", - "tests/test_issue_12_review59_account.py::test_correction_rejects_self_parent_and_cycles_without_write", - "tests/test_issue_12_review59_reports.py::test_idempotent_snapshot_close_replay_returns_original_immutable_response" - ], - "verification": "Current source and tests cover valuation correction, evidence identity, close replay, and no-write conflicts." - }, - { - "path": "docs/requirements/req-003_account-valuation-history.md", - "baseline_id": "REQ-003.04", - "semantic_key": "integer_amounts_nullable_optional_metrics_and_representative_liability", - "meaning": "Amounts and optional monetary fields use exact integers; NULL means not provided and zero means explicit zero; investment metrics are not double-counted; only the defined representative loan amount enters liabilities.", - "reviewed_ids": [ - "REQ-003.04", - "REQ-003.04-AC01" - ], - "reviewed_status": "present_and_approved", - "planned_ids": [ - "N02" - ], - "planned_status": "strengthen_field_mapping_and_formula_assertions; semantics_unchanged", - "authorization": "Preserve physical principal fields, NULL/zero distinction, loan definition requirement, and no double sum.", - "evidence_paths": [ - "docs/data-model.md", - "docs/interface-contract.md", - "jarca_ledger_mcp/application/account_valuation_service.py", - "jarca_ledger_mcp/application/assets_service.py", - "tests/test_issue_12_review59_account.py::test_valuation_round_trip_preserves_null_zero_and_physical_amount_mapping", - "tests/test_issue_12_regressions.py::test_loan_representative_is_always_aggregated_as_liability", - "tests/test_issue_12_regressions.py::test_loan_balance_fallback_without_representative_definition_is_excluded" - ], - "verification": "The reviewed contract explicitly distinguishes NULL, zero, principal meanings, and representative liability." - }, - { - "path": "docs/requirements/req-003_account-valuation-history.md", - "baseline_id": "REQ-003.05", - "semantic_key": "current_display_and_historical_authority_separation", - "meaning": "Historical dated evidence does not roll back newer current balance display; account/import writes create only dated unverified candidates when real evidence exists; name-only updates create none.", - "reviewed_ids": [ - "REQ-003.05", - "REQ-003.05-AC01" - ], - "reviewed_status": "present_and_approved", - "planned_ids": [ - "N01", - "C05" - ], - "planned_status": "strengthen_current_cache_and_candidate_provenance; semantics_unchanged", - "authorization": "Preserve separate current and historical decisions, unverified candidate status, and no inferred evidence.", - "evidence_paths": [ - "jarca_ledger_mcp/application/accounts_write_services.py", - "jarca_ledger_mcp/application/imports_service.py", - "docs/runtime-flow.md", - "tests/test_account_valuations.py::test_account_balance_write_records_unverified_candidate_only_with_real_basis_date", - "tests/test_account_valuations.py::test_account_name_only_update_does_not_create_candidate", - "tests/test_issue_12_regressions.py::test_historical_account_update_preserves_current_and_adds_one_candidate", - "tests/test_issue_12_review59_account.py::test_import_historical_kb_does_not_replace_newer_current_balance" - ], - "verification": "The reviewed head has explicit late-history/current-cache regression tests and runtime decision guards." - }, - { - "path": "docs/requirements/req-003_account-valuation-history.md", - "baseline_id": "REQ-003.06", - "semantic_key": "read_only_preview_and_explicit_conditional_close", - "meaning": "Preview performs no database write and reports complete, incomplete, or conditional state; unsafe evidence requires explicit approval metadata; close persists immutable run evidence atomically.", - "reviewed_ids": [ - "REQ-003.06", - "REQ-003.06-AC01" - ], - "reviewed_status": "present_and_approved", - "planned_ids": [ - "D03", - "D04" - ], - "planned_status": "strengthen_preview_fingerprint_and_approval_boundary; semantics_unchanged", - "authorization": "Preserve no-write preview, explicit approval, rejection of unsafe evidence, and atomic close.", - "evidence_paths": [ - "jarca_ledger_mcp/application/assets_service.py", - "jarca_ledger_mcp/adapters/streamlit/assets_gateway.py", - "docs/interface-contract.md", - "tests/test_issue_12_regressions.py::test_preview_marks_approval_eligible_missing_valuation_as_incomplete_draft", - "tests/test_issue_12_review59_reports.py::test_dated_manual_asset_is_verified_and_preview_needs_approval", - "tests/test_issue_12_review59_reports.py::test_approved_carried_close_is_conditional_and_persists_provenance", - "tests/test_issue_12_review59_reports.py::test_close_rejects_authority_drift_since_preview" - ], - "verification": "Preview/close boundaries, approval fields, drift rejection, and no-partial-write behavior are documented and tested." - }, - { - "path": "docs/requirements/req-003_account-valuation-history.md", - "baseline_id": "REQ-003.07", - "semantic_key": "immutable_close_correction_and_net_worth_formula", - "meaning": "Same-basis re-close requires a reason and creates a new run and rows; old runs remain; latest run is report authority; net worth is asset buckets minus representative loan and excludes missing valuations.", - "reviewed_ids": [ - "REQ-003.07", - "REQ-003.07-AC01" - ], - "reviewed_status": "present_and_approved", - "planned_ids": [ - "C06", - "D03" - ], - "planned_status": "strengthen_latest-run_and_formula_provenance; semantics_unchanged", - "authorization": "Preserve append-only runs, correction linkage, latest-run authority, and exact formula.", - "evidence_paths": [ - "jarca_ledger_mcp/application/assets_service.py", - "docs/data-model.md", - "tests/test_issue_12_regressions.py::test_empty_conditional_close_is_closed_and_second_close_requires_correction", - "tests/test_issue_12_regressions.py::test_legacy_snapshot_requires_explicit_correction_before_new_close", - "tests/test_issue_12_review59_reports.py::test_asset_close_and_report_expose_provenance_aliases" - ], - "verification": "Run correction fields, latest authority, and formula semantics are present in canonical docs and tests." - }, - { - "path": "docs/requirements/req-003_account-valuation-history.md", - "baseline_id": "REQ-003.08", - "semantic_key": "reconciliation_and_monthly_read_model_propagation", - "meaning": "Verified investment uses VALUATION_MANAGED without fake transactions; incomplete evidence reports unavailable/incomplete calculation; monthly and downstream reports propagate actual valuation date, age, carry, verification, run, approval, correction, warnings, and exclusions.", - "reviewed_ids": [ - "REQ-003.08", - "REQ-003.08-AC01" - ], - "reviewed_status": "present_and_approved", - "planned_ids": [ - "C05", - "D04" - ], - "planned_status": "strengthen_cross_read_model_alias_and_completeness_contract; semantics_unchanged", - "authorization": "Preserve read-only propagation, explicit incompleteness, no inferred balance, and monthly_source_snapshot_id as a read-model alias only.", - "evidence_paths": [ - "jarca_ledger_mcp/application/reconciliation_service.py", - "jarca_ledger_mcp/application/monthly_settlement_service.py", - "jarca_ledger_mcp/adapters/streamlit/overview_gateway.py", - "docs/data-model.md", - "tests/test_issue_12_regressions.py::test_reconciliation_uses_corrected_investment_leaf_without_transaction_count_change", - "tests/test_issue_12_review59_reports.py::test_investment_without_verified_valuation_and_without_opening_balance_is_incomplete", - "tests/test_issue_12_review59_reports.py::test_timeseries_and_monthly_expose_canonical_asset_provenance", - "tests/test_issue_12_review59_reports.py::test_monthly_settlement_propagates_snapshot_provenance_id_and_actual_valuation_date" - ], - "verification": "Named source owners and report propagation tests cover reconciliation and monthly semantics." - }, - { - "path": "docs/requirements/req-003_account-valuation-history.md", - "baseline_id": "REQ-003.09", - "semantic_key": "shared_application_adapters_and_auth_boundary", - "meaning": "MCP and Dashboard delegate to shared services, retain success/error envelopes, require Dashboard authentication before DB access, and keep render/read paths non-mutating.", - "reviewed_ids": [ - "REQ-003.09", - "REQ-003.09-AC01" - ], - "reviewed_status": "present_and_approved", - "planned_ids": [ - "N01", - "D04" - ], - "planned_status": "strengthen_adapter_and_auth-order assertions; semantics_unchanged", - "authorization": "Preserve shared policy ownership, thin adapters, auth-before-DB, and existing MCP authentication scope.", - "evidence_paths": [ - "jarca_ledger_mcp/adapters/mcp/server.py", - "jarca_ledger_mcp/adapters/streamlit/accounts_gateway.py", - "jarca_ledger_mcp/adapters/streamlit/overview_gateway.py", - "dashboard/app.py", - "tests/test_contract_regression.py", - "tests/test_dashboard_app.py", - "tests/test_dashboard_menu_transition.py" - ], - "verification": "The reviewed head retains named adapter paths and existing REQ-001/REQ-002 gates; requirement files are unchanged from baseline." - }, - { - "path": "docs/requirements/req-003_account-valuation-history.md", - "baseline_id": "REQ-003.10", - "semantic_key": "synthetic_privacy_and_excluded_scope", - "meaning": "Docs, tests, fixtures, and evidence contain only synthetic/redacted data; credentials, tokens, cookies, real financial data, external prices, FX, automatic approval, inferred transactions, and redesign remain out of scope.", - "reviewed_ids": [ - "REQ-003.10", - "REQ-003.10-AC01" - ], - "reviewed_status": "present_and_approved", - "planned_ids": [ - "N02", - "D04" - ], - "planned_status": "strengthen_recursive_redaction_and_static_inventory; semantics_unchanged", - "authorization": "Preserve privacy boundary and excluded scope; rework may add redaction checks but may not introduce real data or new financial inference.", - "evidence_paths": [ - "docs/project-structure.md", - "docs/interface-contract.md", - "tests/test_requirement_docs.py", - "tests/test_issue_12_review59_reports.py::test_close_metadata_is_allowlisted_recursively", - "tests/test_issue_12_review59_reports.py::test_public_included_items_redact_source_note_and_memo_recursively" - ], - "verification": "Canonical docs state synthetic-only and recursive redaction; focused tests validate metadata and evidence redaction." - }, - { - "path": "docs/requirements/req-003_account-valuation-history.md", - "baseline_id": "REQ-003-INV01", - "semantic_key": "authority_and_safety_invariants", - "meaning": "Only verified leaves are authority; future/unverified/rejected/unknown evidence is not summed; preview/render do not write; close is transactional; current and historical authority remain separate.", - "reviewed_ids": [ - "REQ-003-INV01" - ], - "reviewed_status": "present_and_approved", - "planned_ids": [ - "C05", - "D03", - "D04" - ], - "planned_status": "strengthen explicit invariant checks; semantics_unchanged", - "authorization": "All listed invariants are preservation constraints, not permission to alter business meaning.", - "evidence_paths": [ - "docs/requirements/req-003_account-valuation-history.md", - "docs/data-model.md", - "docs/runtime-flow.md", - "tests/test_issue_12_regressions.py", - "tests/test_issue_12_review59_reports.py" - ], - "verification": "The requirement, data model, and runtime flow repeat the same authority and no-write invariants." - }, - { - "path": "docs/requirements/req-003_account-valuation-history.md", - "baseline_id": "REQ-003-INV02", - "semantic_key": "database_read_lifecycle_boundary", - "meaning": "Writer/bootstrap explicitly calls init_db; read_db uses SQLite mode=ro; missing DB returns db_not_initialized without mkdir/migrate/commit; initialized read failure returns db_error.", - "reviewed_ids": [ - "REQ-003-INV02" - ], - "reviewed_status": "present_and_approved", - "planned_ids": [ - "N01" - ], - "planned_status": "strengthen_no_create_and_error_classification; semantics_unchanged", - "authorization": "Preserve explicit initialization and stable read-only failure envelopes.", - "evidence_paths": [ - "jarca_ledger_mcp/infrastructure/sqlite/connection.py", - "jarca_ledger_mcp/infrastructure/sqlite/migrations.py", - "docs/interface-contract.md", - "docs/runtime-flow.md", - "tests/test_issue_12_review59_readonly.py::test_read_queries_missing_nested_db_return_stable_error_without_creating_path", - "tests/test_issue_12_review59_readonly.py::test_read_schema_error_is_not_misreported_as_uninitialized" - ], - "verification": "C13 database-boundary documentation and focused read-only tests exist at reviewed head." - }, - { - "path": "docs/requirements/req-001_dashboard-administrator-authentication.md", - "baseline_id": "REQ-001.01-REQ-001.11", - "semantic_key": "dashboard_auth_gate_cookie_cleanup_logout_and_rotation", - "meaning": "REQ-001 authentication remains fail-closed before DB/page dispatch, with server-only credential binding, hardened persistent cookie, absolute TTL, invalid-cookie cleanup, explicit logout, rotation invalidation, and no DB-backed session.", - "reviewed_ids": [ - "REQ-001.01", - "REQ-001.05", - "REQ-001.06", - "REQ-001.07", - "REQ-001.08", - "REQ-001.09", - "REQ-001.10" - ], - "reviewed_status": "unchanged_from_baseline", - "planned_ids": [ - "N01" - ], - "planned_status": "must_remain_unchanged", - "authorization": "Issue #12 rework is additive and cannot modify authentication semantics or claim MCP authentication.", - "evidence_paths": [ - "docs/requirements/req-001_dashboard-administrator-authentication.md", - "docs/interface-contract.md", - "dashboard/authentication.py", - "dashboard/auth_server.py", - "tests/test_dashboard_authentication.py", - "tests/test_dashboard_persistent_authentication.py", - "tests/test_dashboard_auth_server.py", - "tests/test_dashboard_authentication_app.py" - ], - "verification": "Git diff confirms REQ-001 file has no changes between baseline and reviewed head." - }, - { - "path": "docs/requirements/req-002_dashboard-menu-transition.md", - "baseline_id": "REQ-002.01-REQ-002.09", - "semantic_key": "dashboard_menu_identity_query_and_stable_shell", - "meaning": "The exact ten menu labels/order, selected state, page-only query update with sibling preservation, stable shell/background, local loading/error/retry, latest serialized selection, auth gate, finance pages, and clear_cache contract remain unchanged.", - "reviewed_ids": [ - "REQ-002.01", - "REQ-002.02", - "REQ-002.03", - "REQ-002.04", - "REQ-002.05", - "REQ-002.06", - "REQ-002.07", - "REQ-002.08", - "REQ-002.09" - ], - "reviewed_status": "unchanged_from_baseline", - "planned_ids": [ - "N01" - ], - "planned_status": "must_remain_unchanged", - "authorization": "Issue #12 rework may add valuation content behind existing pages but may not alter menu identity, query semantics, shell continuity, or browser evidence requirements.", - "evidence_paths": [ - "docs/requirements/req-002_dashboard-menu-transition.md", - "docs/interface-contract.md", - "dashboard/app.py", - "dashboard/common.py", - "tests/test_dashboard_menu_transition.py", - "tests/test_dashboard_app.py", - "tests/test_dashboard_authentication_app.py", - "docs/evidence/issue-9-dashboard-menu-transition/" - ], - "verification": "Git diff confirms REQ-002 file has no changes between baseline and reviewed head." - }, - { - "path": "docs/interface-contract.md", - "baseline_id": "COMMON-IFACE-01", - "semantic_key": "success_error_envelope_and_public_service_signatures", - "meaning": "Existing success/error envelopes remain; valuation, snapshot, MCP, Dashboard gateway, and service signatures are additive and re-exported through the established service boundary.", - "reviewed_ids": [ - "COMMON-IFACE-01" - ], - "reviewed_status": "preserved_with_additive_REQ003_contract", - "planned_ids": [ - "D04" - ], - "planned_status": "strengthen_exact_output_and_replay_contract; semantics_unchanged", - "authorization": "No existing response key may be renamed or removed.", - "evidence_paths": [ - "docs/interface-contract.md", - "jarca_ledger_mcp/service.py", - "jarca_ledger_mcp/adapters/mcp/server.py", - "tests/test_contract_regression.py" - ], - "verification": "Reviewed contract explicitly lists signatures, envelopes, top-level aliases, nested provenance, and replay rules." - }, - { - "path": "docs/data-model.md", - "baseline_id": "COMMON-DATA-01", - "semantic_key": "legacy_entities_and_storage_ownership", - "meaning": "Existing ledger entities and relationships remain; valuation and snapshot history are append-only; monthly alias is not a persistence field; application services own policy and SQLite owns storage.", - "reviewed_ids": [ - "COMMON-DATA-01" - ], - "reviewed_status": "preserved_with_additive_REQ003_model", - "planned_ids": [ - "N02", - "D03" - ], - "planned_status": "strengthen_physical_field_and_ownership_checks; semantics_unchanged", - "authorization": "No guessed migration, cascade deletion, fake transaction, or alternate policy boundary is authorized.", - "evidence_paths": [ - "docs/data-model.md", - "jarca_ledger_mcp/infrastructure/sqlite/schema.py", - "jarca_ledger_mcp/application/assets_service.py", - "jarca_ledger_mcp/application/reconciliation_service.py" - ], - "verification": "Data model names legacy preservation, append-only relationships, physical fields, and canonical owners." - }, - { - "path": "docs/runtime-flow.md", - "baseline_id": "COMMON-RUNTIME-01", - "semantic_key": "auth_before_db_and_explicit_write_boundaries", - "meaning": "Dashboard auth precedes DB access; read/preview paths are read-only; first-use writer initialization is explicit; approval precedes atomic close; downstream reports are reads.", - "reviewed_ids": [ - "COMMON-RUNTIME-01" - ], - "reviewed_status": "preserved_with_additive_REQ003_flow", - "planned_ids": [ - "N01", - "D03", - "D04" - ], - "planned_status": "strengthen_transition_guards_and_drift_revalidation; semantics_unchanged", - "authorization": "Preserve ordering, transaction boundaries, stable missing-DB behavior, and no implicit writes.", - "evidence_paths": [ - "docs/runtime-flow.md", - "dashboard/app.py", - "jarca_ledger_mcp/infrastructure/sqlite/connection.py", - "jarca_ledger_mcp/application/assets_service.py", - "tests/test_issue_12_review59_readonly.py" - ], - "verification": "Runtime flow explicitly records auth-before-DB, read-only database lifecycle, preview drift revalidation, and atomic close." - }, - { - "path": "docs/project-structure.md", - "baseline_id": "COMMON-STRUCTURE-01", - "semantic_key": "canonical_module_ownership_and_regression_map", - "meaning": "Valuation/snapshot policy remains in application services; adapters remain thin; Dashboard pages do not own SQL or policy; named tests and documentation validators are required evidence.", - "reviewed_ids": [ - "COMMON-STRUCTURE-01" - ], - "reviewed_status": "preserved_with_REQ003_ownership_map", - "planned_ids": [ - "N01", - "C06" - ], - "planned_status": "strengthen ownership and named-test traceability; semantics_unchanged", - "authorization": "Rework must preserve canonical owners and may not introduce duplicate business logic in adapters.", - "evidence_paths": [ - "docs/project-structure.md", - "jarca_ledger_mcp/application/account_valuation_service.py", - "jarca_ledger_mcp/application/assets_service.py", - "jarca_ledger_mcp/application/monthly_settlement_service.py", - "jarca_ledger_mcp/infrastructure/sqlite/connection.py", - "tests/test_requirement_docs.py" - ], - "verification": "Reviewed structure document contains explicit ownership, dependency, preservation, and named regression-test sections." - } - ], - "missing_count": 0, - "ambiguous_count": 0, - "notes": [ - "REQ-001 and REQ-002 requirement files are byte-for-byte unchanged from baseline; common docs were extended additively for REQ-003.", - "Source contract digest supplied by the caller is 6d86b591b022fcc722611bfec6d24e54a64216ab6f7c4098f357e25420218818.", - "The checked-out repository does not define a canonical glossary mapping finding labels N01, C05, C06, N02, D03, and D04 to independent issue descriptions; planned mappings above are therefore preservation-oriented semantic associations inferred from the reviewed contract text.", - "No files were created or modified; no commit, push, fetch, or Gitea call was performed.", - "Main-agent resolution: Review #60 body is the authoritative glossary for N01/C05/C06/N02/D03/D04; each label and prose was read from admission-snapshot.json, so the delegate-reported label-mapping ambiguity is resolved without changing contract meaning." - ], - "schema": "gitea-agent.contract-preservation-inventory/v1" -} diff --git a/docs/verification/issue-12-review-60/evidence-manifest.json b/docs/verification/issue-12-review-60/evidence-manifest.json deleted file mode 100644 index fc690ed..0000000 --- a/docs/verification/issue-12-review-60/evidence-manifest.json +++ /dev/null @@ -1 +0,0 @@ -{"claims":{"adversarial-compatibility-green":["/commands/1/argv","/commands/1/exit_code","/commands/1/expected_exit_code","/commands/1/output","/commands/1/started_at_utc","/commands/1/finished_at_utc"],"compileall-green":["/commands/4/argv","/commands/4/exit_code","/commands/4/expected_exit_code","/commands/4/output","/commands/4/started_at_utc","/commands/4/finished_at_utc"],"diff-check-green":["/commands/5/argv","/commands/5/exit_code","/commands/5/expected_exit_code","/commands/5/output","/commands/5/started_at_utc","/commands/5/finished_at_utc"],"full-suite-green":["/commands/2/argv","/commands/2/exit_code","/commands/2/expected_exit_code","/commands/2/output","/commands/2/started_at_utc","/commands/2/finished_at_utc"],"review60-and-independent-regressions-green":["/commands/0/argv","/commands/0/exit_code","/commands/0/expected_exit_code","/commands/0/output","/commands/0/started_at_utc","/commands/0/finished_at_utc"],"ruff-green":["/commands/3/argv","/commands/3/exit_code","/commands/3/expected_exit_code","/commands/3/output","/commands/3/started_at_utc","/commands/3/finished_at_utc"]},"commands":[{"argv":["uv","run","--frozen","--extra","dev","--extra","dashboard","pytest","-q","tests/test_account_valuation_edge_contracts.py","tests/test_import_current_balance_authority.py","tests/test_asset_snapshot_idempotency.py","tests/test_valuation_contract_docs.py","tests/test_account_basis_public_consumers.py","tests/test_issue_12_regressions.py"],"claim_ids":["review60-and-independent-regressions-green"],"duration_seconds":35.29543927125633,"exit_code":0,"expected_exit_code":0,"finished_at_utc":"2026-10-07T00:13:28.258578Z","id":"review60-regressions","max_output_bytes":65536,"output":"................................................ [100%]\n","purpose":"Run Review 60 and all independent-review named RED-to-GREEN regressions","started_at_utc":"2026-10-07T00:12:52.963748Z"},{"argv":["uv","run","--frozen","--extra","dev","--extra","dashboard","pytest","-q","tests/test_account_valuation_edge_contracts.py","tests/test_import_current_balance_authority.py","tests/test_asset_snapshot_idempotency.py","tests/test_valuation_contract_docs.py","tests/test_issue_12_regressions.py","tests/test_account_valuations.py","tests/test_asset_snapshots.py","tests/test_issue_12_review59_account.py","tests/test_issue_12_review59_reports.py","tests/test_issue_12_review59_readonly.py","tests/test_contract_regression.py","tests/test_requirement_docs.py"],"claim_ids":["adversarial-compatibility-green"],"duration_seconds":37.867423550225794,"exit_code":0,"expected_exit_code":0,"finished_at_utc":"2026-10-07T00:14:06.126414Z","id":"adversarial-compatibility","max_output_bytes":65536,"output":"........................................................................ [ 61%]\n............................................. [100%]\n","purpose":"Run correction, replay, current authority, read-only, provenance, contract and documentation compatibility coverage","started_at_utc":"2026-10-07T00:13:28.259305Z"},{"argv":["uv","run","--frozen","--extra","dev","--extra","dashboard","pytest","-q","-rs"],"claim_ids":["full-suite-green"],"duration_seconds":102.22078723087907,"exit_code":0,"expected_exit_code":0,"finished_at_utc":"2026-10-07T00:15:48.345538Z","id":"full-suite","max_output_bytes":65536,"output":"........................................................................ [ 26%]\n........................................................................ [ 53%]\n......................................................ss................ [ 80%]\n............................................ss..... [100%]\n=============================== warnings summary ===============================\ntests/test_dashboard_auth_server.py:11\n /opt/data/gitea-agent/repositories/jsfamily/jarca-ledger-mcp/worktrees/issue-12/checkout/tests/test_dashboard_auth_server.py:11: StarletteDeprecationWarning: Using `httpx` with `starlette.testclient` is deprecated; install `httpx2` instead.\n from starlette.testclient import TestClient\n\n-- Docs: https://docs.pytest.org/en/stable/how-to/capture-warnings.html\n=========================== short test summary info ============================\nSKIPPED [1] tests/test_kb_bank_pdf.py:26: sample KB Bank PDF/password is not available\nSKIPPED [1] tests/test_kb_bank_pdf.py:42: sample KB Bank PDF/password is not available\nSKIPPED [1] tests/test_toss_securities_pdf.py:20: sample Toss Securities PDF is not available\nSKIPPED [1] tests/test_toss_securities_pdf.py:32: sample Toss Securities PDF is not available\n","purpose":"Run the repository full test suite with declared optional dependencies","started_at_utc":"2026-10-07T00:14:06.126872Z"},{"argv":["uv","run","--frozen","--extra","dev","--extra","dashboard","ruff","check","."],"claim_ids":["ruff-green"],"duration_seconds":0.209128737449646,"exit_code":0,"expected_exit_code":0,"finished_at_utc":"2026-10-07T00:15:48.556797Z","id":"ruff","max_output_bytes":65536,"output":"All checks passed!\n","purpose":"Run repository lint gate","started_at_utc":"2026-10-07T00:15:48.347721Z"},{"argv":["python3","-m","compileall","-q","jarca_ledger_mcp","dashboard","tests","scripts"],"claim_ids":["compileall-green"],"duration_seconds":0.374801566824317,"exit_code":0,"expected_exit_code":0,"finished_at_utc":"2026-10-07T00:15:48.931640Z","id":"compileall","max_output_bytes":65536,"output":"","purpose":"Compile Python sources, dashboard, tests and scripts","started_at_utc":"2026-10-07T00:15:48.556968Z"},{"argv":["git","diff","--check","HEAD^","HEAD"],"claim_ids":["diff-check-green"],"duration_seconds":0.10184518899768591,"exit_code":0,"expected_exit_code":0,"finished_at_utc":"2026-10-07T00:15:49.033586Z","id":"commit-diff-check","max_output_bytes":65536,"output":"","purpose":"Validate committed rework diff whitespace","started_at_utc":"2026-10-07T00:15:48.931808Z"}],"environment":{"architecture":"aarch64","kernel":"6.18.34+rpt-rpi-v8","os":"Linux","python":"3.13.5","uv":"uv 0.11.6 (aarch64-unknown-linux-musl)"},"excluded_paths":["docs/verification/issue-12-review-60/evidence-plan.json","docs/verification/issue-12-review-60/evidence-manifest.json"],"files":[{"blob_oid":"481181d5e4ffcd42ae3abaeb728dad3ff12f88a6","path":"dashboard/page_views/accounts.py","sha256":"8e2653b6ca94b134eb8539b35e0b75267a3e2e14b428d4843e2b2383de7bfa96"},{"blob_oid":"e293fe8cb1893ba5f0088bcaf88162d006eae7c0","path":"docs/data-model.md","sha256":"544f6dbc02875789484039b748b906d762adde7a215334b61d6743cf160e8a6e"},{"blob_oid":"86c8d297e0852dbb8aebbf84f912877e0cf6f30c","path":"docs/interface-contract.md","sha256":"1b7f795734ca1993268d565f55ef9cd297bdfebab786f53bad1436ac196a840e"},{"blob_oid":"acc3bcdc928f9fde71b300a8f9ee7f921a5a83eb","path":"jarca_ledger_mcp/application/account_valuation_service.py","sha256":"870ea5ffa41408d4e86220490c46fa63ea1d40143a5ea66a2a1e265dd09aac67"},{"blob_oid":"f923fb07b4151f25cc6e25a5fd02b24b4ad44b6c","path":"jarca_ledger_mcp/application/accounts_write_services.py","sha256":"93608890353fb5b7f64f8dd65e33349ba7dd1cfa91064972ad7ce30af34ce77b"},{"blob_oid":"eaabf1e5f39344780c60c5e1cbefed5f2bc879dd","path":"jarca_ledger_mcp/application/assets_service.py","sha256":"a3933c8759433c392979bab8e1ac71a5f545a1cebd1522e5d8e1a1f33dd5be73"},{"blob_oid":"e4ff70ee668e8977accc2c2699ea3864dbe012d6","path":"jarca_ledger_mcp/application/imports_service.py","sha256":"615058c973970d60a2dc260eb44694ed000e2efb7668d647fadc6bf7a71e1b23"},{"blob_oid":"aad592c511727d9bae105819c93cae25c3e5bcb0","path":"jarca_ledger_mcp/infrastructure/sqlite/schema.py","sha256":"d50d504b2e39ce123328a563a69327bb3126809ea1da682cd967abc30166001c"},{"blob_oid":"37bc5337956a72d7b7272b8a99b52fd4a36ec6e0","path":"scripts/ci_fixture_db.py","sha256":"47058455bed43973a7e2bb0dcef32cff482d2fbf7c372d48ac87b272bee9d10f"},{"blob_oid":"1e18454fbde9ebc58a6ae98cd3f7dbe8ba665cc5","path":"tests/test_account_valuations.py","sha256":"aa3f831acba0317b6f49764042927026715ff5f6e729b945a22aa2b13490a6bf"},{"blob_oid":"83c76f65ad122e8409abd3420c97b4c375e144d5","path":"tests/test_issue_12_regressions.py","sha256":"7dc8fbd7a7b0cb718de115f4d1f69b2e024cf1af641573e4cb04c00196017f29"},{"blob_oid":"a1610d357212d8997daeb40c0da6d786bab3f56c","path":"tests/test_issue_12_review59_account.py","sha256":"92603ee3f758d1480da422d3e1fdae6fd1ce02f2c2ae4608defd867b1e9d5e58"},{"blob_oid":"4b8e7e3351aec34d83b817b4cba83a62aa273789","path":"tests/test_account_valuation_edge_contracts.py","sha256":"2206e4a8316400cc34c70fe7544e130b6129891109f65580d27e9a64266ab0d8"},{"blob_oid":"17be3e1e9b62e1ec63767dfa7920c78546d43e38","path":"tests/test_asset_snapshot_idempotency.py","sha256":"9a66f7d56b56cf3a9a85950813a56bdd06eafc07f592a1cb77133ad5f36ff09c"},{"blob_oid":"97672cb80b853c01d85c6b662affd89260f7434f","path":"tests/test_import_current_balance_authority.py","sha256":"004409e510fb4270e1c71722ce8ea8f8558b846f9f9cd0ecbcf7091217d2e3ef"},{"blob_oid":"8b656efd98691338eba303afb7b5a815c3d3c99f","path":"tests/test_valuation_contract_docs.py","sha256":"f278dca439d6c5c95f7774e66fad8a4216148b01feafa5c937126c5b5cdca103"},{"blob_oid":"20028ab102b8c2b5b6b154a2fdafbd8807be9cb2","path":"jarca_ledger_mcp/adapters/mcp/server.py","sha256":"6a9712dfec4f863e22300a07dae714a5f5c2ea83029a611593e668db5d3e5cb0"},{"blob_oid":"8433866ca0eb5dcf512b6e84e23931b37f1035f8","path":"tests/test_account_basis_public_consumers.py","sha256":"1b719d3318d376c69ca0f0af39e2d6027b0e3b46b136ce8079bec856ef7871af"}],"generated_at":"2026-10-07T00:15:49.181398Z","limitations":["Four external PDF fixture tests are expected to skip when private sample files/passwords are unavailable.","No actual financial data or production credential is used; tests use synthetic fixtures.","Review 60 does not require a new real-browser observation; existing synthetic Streamlit/AppTest regressions remain in the full suite."],"plan":{"path":"docs/verification/issue-12-review-60/evidence-plan.json","sha256":"7d0bfb0c32f68c8e54afbd58d43ce4b5a54964dc17a33b322b96d976340e85d8"},"redaction":{"checked":true,"violations":[]},"result":"success","schema":"evidence-manifest/v1","source_revision":"f25b30c750e191e056814d6131a8b1141949736d","source_tree_clean":true} diff --git a/docs/verification/issue-12-review-60/evidence-plan.json b/docs/verification/issue-12-review-60/evidence-plan.json deleted file mode 100644 index bbb49b2..0000000 --- a/docs/verification/issue-12-review-60/evidence-plan.json +++ /dev/null @@ -1,181 +0,0 @@ -{ - "environment": [ - "os", - "kernel", - "architecture", - "python", - "uv" - ], - "command_env_allowlist": [ - "PATH", - "HOME", - "TMPDIR", - "LANG", - "VIRTUAL_ENV", - "UV_CACHE_DIR" - ], - "secret_env_names": [], - "forbidden_regexes": [], - "hash_paths": [ - "dashboard/page_views/accounts.py", - "docs/data-model.md", - "docs/interface-contract.md", - "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/infrastructure/sqlite/schema.py", - "scripts/ci_fixture_db.py", - "tests/test_account_valuations.py", - "tests/test_issue_12_regressions.py", - "tests/test_issue_12_review59_account.py", - "tests/test_account_valuation_edge_contracts.py", - "tests/test_asset_snapshot_idempotency.py", - "tests/test_import_current_balance_authority.py", - "tests/test_valuation_contract_docs.py", - "jarca_ledger_mcp/adapters/mcp/server.py", - "tests/test_account_basis_public_consumers.py" - ], - "commands": [ - { - "id": "review60-regressions", - "purpose": "Run Review 60 and all independent-review named RED-to-GREEN regressions", - "argv": [ - "uv", - "run", - "--frozen", - "--extra", - "dev", - "--extra", - "dashboard", - "pytest", - "-q", - "tests/test_account_valuation_edge_contracts.py", - "tests/test_import_current_balance_authority.py", - "tests/test_asset_snapshot_idempotency.py", - "tests/test_valuation_contract_docs.py", - "tests/test_account_basis_public_consumers.py", - "tests/test_issue_12_regressions.py" - ], - "expected_exit_code": 0, - "max_output_bytes": 65536, - "claims": [ - "review60-and-independent-regressions-green" - ] - }, - { - "id": "adversarial-compatibility", - "purpose": "Run correction, replay, current authority, read-only, provenance, contract and documentation compatibility coverage", - "argv": [ - "uv", - "run", - "--frozen", - "--extra", - "dev", - "--extra", - "dashboard", - "pytest", - "-q", - "tests/test_account_valuation_edge_contracts.py", - "tests/test_import_current_balance_authority.py", - "tests/test_asset_snapshot_idempotency.py", - "tests/test_valuation_contract_docs.py", - "tests/test_issue_12_regressions.py", - "tests/test_account_valuations.py", - "tests/test_asset_snapshots.py", - "tests/test_issue_12_review59_account.py", - "tests/test_issue_12_review59_reports.py", - "tests/test_issue_12_review59_readonly.py", - "tests/test_contract_regression.py", - "tests/test_requirement_docs.py" - ], - "expected_exit_code": 0, - "max_output_bytes": 65536, - "claims": [ - "adversarial-compatibility-green" - ] - }, - { - "id": "full-suite", - "purpose": "Run the repository full test suite with declared optional dependencies", - "argv": [ - "uv", - "run", - "--frozen", - "--extra", - "dev", - "--extra", - "dashboard", - "pytest", - "-q", - "-rs" - ], - "expected_exit_code": 0, - "max_output_bytes": 65536, - "claims": [ - "full-suite-green" - ] - }, - { - "id": "ruff", - "purpose": "Run repository lint gate", - "argv": [ - "uv", - "run", - "--frozen", - "--extra", - "dev", - "--extra", - "dashboard", - "ruff", - "check", - "." - ], - "expected_exit_code": 0, - "max_output_bytes": 65536, - "claims": [ - "ruff-green" - ] - }, - { - "id": "compileall", - "purpose": "Compile Python sources, dashboard, tests and scripts", - "argv": [ - "python3", - "-m", - "compileall", - "-q", - "jarca_ledger_mcp", - "dashboard", - "tests", - "scripts" - ], - "expected_exit_code": 0, - "max_output_bytes": 65536, - "claims": [ - "compileall-green" - ] - }, - { - "id": "commit-diff-check", - "purpose": "Validate committed rework diff whitespace", - "argv": [ - "git", - "diff", - "--check", - "HEAD^", - "HEAD" - ], - "expected_exit_code": 0, - "max_output_bytes": 65536, - "claims": [ - "diff-check-green" - ] - } - ], - "limitations": [ - "Four external PDF fixture tests are expected to skip when private sample files/passwords are unavailable.", - "No actual financial data or production credential is used; tests use synthetic fixtures.", - "Review 60 does not require a new real-browser observation; existing synthetic Streamlit/AppTest regressions remain in the full suite." - ] -} diff --git a/docs/verification/issue-12-review-60/final-independent-review.json b/docs/verification/issue-12-review-60/final-independent-review.json deleted file mode 100644 index 83e76bc..0000000 --- a/docs/verification/issue-12-review-60/final-independent-review.json +++ /dev/null @@ -1,16 +0,0 @@ -{ - "specification_gate": { - "passed": true, - "findings": [], - "summary": "Exact-current-diff specification gate passed. Review60 semantics N01, C05, C06, N02, D03, D04; prior defects; documentation, adapters, dashboard consumers, fixtures, and named regressions were rechecked. Full pytest suite, Ruff, compileall, and git diff --check passed." - }, - "code_security_gate": { - "passed": true, - "security_concerns": [], - "logic_errors": [], - "suggestions": [], - "summary": "Final current-diff code/security gate passed. Full pytest suite passed with four fixture-dependent skips and one existing Starlette deprecation warning; Ruff, compileall, diff-check, migration/idempotency/consumer tests, and added-line security scan passed." - }, - "reviewed_parent_sha": "6a8a27a74ece9a9cce6f9772259677813d91ddf8", - "delegation_id": "deleg_49abf596" -} diff --git a/docs/verification/issue-12-review-60/finding-matrix.json b/docs/verification/issue-12-review-60/finding-matrix.json deleted file mode 100644 index 3127be2..0000000 --- a/docs/verification/issue-12-review-60/finding-matrix.json +++ /dev/null @@ -1,148 +0,0 @@ -{ - "schema": "gitea-agent.finding-matrix/v1", - "review_id": 60, - "review_author": "gitea-spec-agent", - "review_state": "REQUEST_CHANGES", - "reviewed_head": "6a8a27a74ece9a9cce6f9772259677813d91ddf8", - "contract_sha256": "6d86b591b022fcc722611bfec6d24e54a64216ab6f7c4098f357e25420218818", - "findings": [ - { - "finding": "60/N01-loan-balance-definition", - "reviewed_head": "6a8a27a74ece9a9cce6f9772259677813d91ddf8", - "contract": "Issue #12 확정 결정 8; REQ-003.04/05", - "classification": "valid_fix", - "implementation_paths": [ - "jarca_ledger_mcp/application/account_valuation_service.py" - ], - "test_paths": [ - "tests/test_account_valuation_edge_contracts.py" - ], - "verification": "named RED→GREEN test plus consolidated adversarial suite", - "result": "pending", - "reason": "Loan account balance alias bypasses mandatory representative liability definition." - }, - { - "finding": "60/C05-current-import", - "reviewed_head": "6a8a27a74ece9a9cce6f9772259677813d91ddf8", - "contract": "Issue #12 현재값과 과거값; REQ-003.05", - "classification": "valid_fix", - "implementation_paths": [ - "jarca_ledger_mcp/application/imports_service.py", - "jarca_ledger_mcp/application/accounts_write_services.py", - "jarca_ledger_mcp/infrastructure/sqlite/schema.py", - "jarca_ledger_mcp/infrastructure/sqlite/migrations.py" - ], - "test_paths": [ - "tests/test_import_current_balance_authority.py" - ], - "verification": "named RED→GREEN sequential late-import test plus migration/full suite", - "result": "pending", - "reason": "Import compares actual evidence date against synchronization timestamp and loses current-cache basis authority." - }, - { - "finding": "60/C06-idempotency", - "reviewed_head": "6a8a27a74ece9a9cce6f9772259677813d91ddf8", - "contract": "Issue #12 중복 및 정정; REQ-003.03", - "classification": "valid_fix", - "implementation_paths": [ - "jarca_ledger_mcp/application/account_valuation_service.py" - ], - "test_paths": [ - "tests/test_account_valuation_edge_contracts.py" - ], - "verification": "named RED→GREEN same-evidence correction replay and changed-payload conflict tests", - "result": "pending", - "reason": "A same source_ref/parent/effective payload correction retry without explicit key conflicts instead of reusing the child." - }, - { - "finding": "60/N02-close-replay-run-binding", - "reviewed_head": "6a8a27a74ece9a9cce6f9772259677813d91ddf8", - "contract": "Issue #12 마감 불변성; REQ-003.03/07", - "classification": "valid_fix", - "implementation_paths": [ - "jarca_ledger_mcp/application/assets_service.py" - ], - "test_paths": [ - "tests/test_asset_snapshot_idempotency.py" - ], - "verification": "named RED→GREEN old-key replay-after-correction exact response binding test", - "result": "pending", - "reason": "Replay identifies the old run but loads latest-run rows and metadata." - }, - { - "finding": "60/D03-data-model", - "reviewed_head": "6a8a27a74ece9a9cce6f9772259677813d91ddf8", - "contract": "Issue #12 데이터 모델 산출물; REQ-003.05", - "classification": "evidence_gap", - "implementation_paths": [ - "docs/data-model.md" - ], - "test_paths": [ - "tests/test_valuation_contract_docs.py" - ], - "verification": "named RED→GREEN canonical data-model contract assertion", - "result": "pending", - "reason": "Data model does not fix actual cache basis versus sync timestamp authority and no-rollback owner." - }, - { - "finding": "60/D04-interface-contract", - "reviewed_head": "6a8a27a74ece9a9cce6f9772259677813d91ddf8", - "contract": "Issue #12 인터페이스 계약 산출물; REQ-003.04/09", - "classification": "evidence_gap", - "implementation_paths": [ - "docs/interface-contract.md" - ], - "test_paths": [ - "tests/test_valuation_contract_docs.py" - ], - "verification": "named RED→GREEN exact enum/conditional/output mapping assertion", - "result": "pending", - "reason": "Public interface delegates allowed values and loan definition/output mapping to source." - }, - { - "finding": "independent-spec/C05-account-write-no-inference", - "reviewed_head": "6a8a27a74ece9a9cce6f9772259677813d91ddf8", - "contract": "Issue #12 current/history separation and no inferred basis; REQ-003.05", - "classification": "valid_fix", - "implementation_paths": [ - "jarca_ledger_mcp/application/accounts_write_services.py" - ], - "test_paths": [ - "tests/test_import_current_balance_authority.py" - ], - "verification": "named RED→GREEN explicit-basis and no-candidate account-write regression", - "result": "pending", - "reason": "Account writes inferred evidence basis and historical candidate from sync timestamp." - }, - { - "finding": "independent-code/legacy-unknown-basis-reporting", - "reviewed_head": "6a8a27a74ece9a9cce6f9772259677813d91ddf8", - "contract": "Issue #12 unknown-basis non-retroactivity; REQ-003.05", - "classification": "valid_fix", - "implementation_paths": [ - "jarca_ledger_mcp/application/assets_service.py" - ], - "test_paths": [ - "tests/test_import_current_balance_authority.py" - ], - "verification": "named RED→GREEN legacy unknown-basis report regression", - "result": "pending", - "reason": "Live report exposed last_synced_at as valuation_date despite unknown evidence basis." - }, - { - "finding": "independent-code/zero-row-run-replay", - "reviewed_head": "6a8a27a74ece9a9cce6f9772259677813d91ddf8", - "contract": "Issue #12 immutable close evidence; REQ-003.03/07", - "classification": "valid_fix", - "implementation_paths": [ - "jarca_ledger_mcp/application/assets_service.py" - ], - "test_paths": [ - "tests/test_asset_snapshot_idempotency.py" - ], - "verification": "named RED→GREEN empty-run replay after nonempty correction exact equality", - "result": "pending", - "reason": "Empty persisted applied_evidence triggered fallback to latest correction rows." - } - ] -} diff --git a/docs/verification/issue-12-review-60/red-evidence.json b/docs/verification/issue-12-review-60/red-evidence.json deleted file mode 100644 index ee646ac..0000000 --- a/docs/verification/issue-12-review-60/red-evidence.json +++ /dev/null @@ -1,82 +0,0 @@ -{ - "schema": "gitea-agent.red-regression-evidence/v1", - "reviewed_head": "6a8a27a74ece9a9cce6f9772259677813d91ddf8", - "environment": { - "runner": "uv run --frozen --extra dev --extra dashboard pytest", - "fixture_policy": "synthetic only" - }, - "results": [ - { - "finding": "60/N01-loan-balance-definition", - "test": "tests/test_account_valuation_edge_contracts.py::test_loan_balance_requires_representative_liability_definition", - "exit_code": 1, - "failure": "missing_definition success was True; expected validation_error and no persisted valuation" - }, - { - "finding": "60/C06-idempotency", - "test": "tests/test_account_valuation_edge_contracts.py::test_correction_replays_by_evidence_and_conflicts_on_changed_payload", - "exit_code": 1, - "failure": "identical correction replay success was False; expected reused=True with the original child" - }, - { - "finding": "60/C05-current-import", - "test": "tests/test_import_current_balance_authority.py::test_late_import_current_balance_is_authoritative_by_evidence_basis_date", - "exit_code": 1, - "failure": "current last_balance was 700 after newer-basis late import; expected 900" - }, - { - "finding": "60/N02-close-replay-run-binding", - "test": "tests/test_asset_snapshot_idempotency.py::test_exact_run_replay_after_correction_reconstructs_original_persisted_run", - "exit_code": 1, - "failure": "old-key replay returned correction-run row IDs, approval and provenance instead of exact original response" - }, - { - "finding": "60/D03-data-model", - "test": "tests/test_valuation_contract_docs.py::test_data_model_documents_cache_authority_and_legacy_basis_migration", - "exit_code": 1, - "failure": "canonical last_balance current-cache contract marker was absent" - }, - { - "finding": "60/D04-interface-contract", - "test": "tests/test_valuation_contract_docs.py::test_interface_contract_documents_public_valuation_enums_validation_and_mapping", - "exit_code": 1, - "failure": "interface contract still delegated allowed values to 'actual enums in source'" - }, - { - "finding": "independent-spec/C05-account-write-no-inference", - "test": "tests/test_import_current_balance_authority.py::test_account_write_sync_timestamp_does_not_infer_balance_basis_or_candidate", - "exit_code": 1, - "failure": "account creation inferred last_balance_basis_date=2026-07-01 from last_synced_at; expected unknown basis and no candidate" - }, - { - "finding": "independent-code/legacy-unknown-basis-reporting", - "test": "tests/test_import_current_balance_authority.py::test_unknown_legacy_balance_basis_is_not_reported_as_valuation_date", - "exit_code": 1, - "failure": "excluded valuation_date exposed last_synced_at timestamp; expected empty unknown basis" - }, - { - "finding": "independent-code/zero-row-run-replay", - "test": "tests/test_asset_snapshot_idempotency.py::test_empty_run_replay_after_nonempty_correction_preserves_original_empty_payload", - "exit_code": 1, - "failure": "old empty run replay fell back to later run items and returned total_assets/net_worth=100 instead of exact original empty response" - }, - { - "finding": "independent-code/historical-explicit-basis-no-rollback", - "test": "tests/test_issue_12_regressions.py::test_historical_account_update_preserves_current_and_adds_one_candidate", - "exit_code": 1, - "failure": "historical explicit update replaced the newer current cache instead of retaining current state while adding one historical candidate" - }, - { - "finding": "independent-code/dashboard-basis-consumer", - "test": "tests/test_account_basis_public_consumers.py::test_dashboard_valuation_basis_never_uses_sync_timestamp", - "exit_code": 1, - "failure": "Dashboard page_accounts used last_synced_at for valuation selection and registration defaults" - }, - { - "finding": "independent-code/mcp-basis-forwarding", - "test": "tests/test_account_basis_public_consumers.py::test_mcp_account_write_tools_forward_explicit_balance_basis", - "exit_code": 1, - "failure": "MCP account-write tools rejected/dropped last_balance_basis_date" - } - ] -} diff --git a/docs/verification/issue-12-review-61/contract-preservation-inventory.json b/docs/verification/issue-12-review-61/contract-preservation-inventory.json deleted file mode 100644 index 20b9fa6..0000000 --- a/docs/verification/issue-12-review-61/contract-preservation-inventory.json +++ /dev/null @@ -1,50 +0,0 @@ -{ - "schema": "gitea-agent.contract-preservation-inventory/v1", - "owner": "jsfamily", - "repository": "jarca-ledger-mcp", - "issue": 12, - "pull_request": 13, - "contract_sha256": "6d86b591b022fcc722611bfec6d24e54a64216ab6f7c4098f357e25420218818", - "review_id": 61, - "reviewed_parent_sha": "5e721b0ddd648f3e80f341a3c304d1cc3ca47ee8", - "reviewed_head": "1b9eda683c66d3c7129716b9899eddf61df3362d", - "preserved_semantics": [ - { - "criterion": "N01-loan-balance-definition", - "required": "Every valuation attached to a loan account explicitly records principal_only or principal_interest_fees; no writer or account-type transition may infer or bypass it.", - "evidence": [ - "tests/test_account_valuation_edge_contracts.py", - "tests/test_issue_12_review59_account.py" - ] - }, - { - "criterion": "C05-current-import", - "required": "Loan cache and import operations remain successful without creating definition-less history, and late evidence never rolls back newer current cache.", - "evidence": [ - "test_dated_loan_create_and_historical_update_preserve_current_cache_without_valuations", - "test_loan_import_preserves_transactions_and_current_cache_without_valuation_candidate" - ] - }, - { - "criterion": "C13-read-only-and-no-partial-write", - "required": "Validation failure changes neither account state nor append-only valuation history.", - "evidence": [ - "test_bank_to_loan_conversion_rejects_existing_undefined_valuation_without_mutation" - ] - }, - { - "criterion": "compatibility", - "required": "A non-loan account with no valuation history may still be converted to loan; non-loan candidate insertion and replay are unchanged.", - "evidence": [ - "test_bank_to_loan_conversion_without_valuations_remains_allowed", - "test_non_loan_candidate_still_succeeds_and_reuses_idempotently" - ] - } - ], - "excluded_scope": [ - "No inferred or automatic liability-definition migration.", - "No schema change.", - "No changes to snapshot, reconciliation, dashboard, authentication, or menu behavior.", - "No merge, Issue close, or release operation." - ] -} diff --git a/docs/verification/issue-12-review-61/evidence-manifest.json b/docs/verification/issue-12-review-61/evidence-manifest.json deleted file mode 100644 index 05fc0a9..0000000 --- a/docs/verification/issue-12-review-61/evidence-manifest.json +++ /dev/null @@ -1,208 +0,0 @@ -{ - "schema": "gitea-agent.evidence-manifest/v1", - "owner": "jsfamily", - "repository": "jarca-ledger-mcp", - "issue": 12, - "pull_request": 13, - "review": 61, - "reviewed_parent_sha": "5e721b0ddd648f3e80f341a3c304d1cc3ca47ee8", - "source_head_sha": "1b9eda683c66d3c7129716b9899eddf61df3362d", - "contract_sha256": "6d86b591b022fcc722611bfec6d24e54a64216ab6f7c4098f357e25420218818", - "environment": { - "platform": "Linux-6.18.34+rpt-rpi-v8-aarch64-with-glibc2.41", - "python": "3.13.5", - "uv": "uv 0.11.6 (aarch64-unknown-linux-musl)", - "fixture_policy": "synthetic repository fixtures only; no credentials or real financial data" - }, - "commands": [ - { - "id": "conversion-regression", - "argv": [ - "uv", - "run", - "--frozen", - "--extra", - "dev", - "--extra", - "dashboard", - "pytest", - "-q", - "-rs", - "tests/test_account_valuation_edge_contracts.py::test_bank_to_loan_conversion_rejects_existing_undefined_valuation_without_mutation", - "tests/test_account_valuation_edge_contracts.py::test_bank_to_loan_conversion_without_valuations_remains_allowed" - ], - "purpose": "Verify conversion rejection is atomic and history-free conversion remains compatible", - "started_at_utc": "2026-10-07T03:59:49.130624Z", - "finished_at_utc": "2026-10-07T03:59:51.888407Z", - "duration_seconds": 2.757882494479418, - "exit_code": 0, - "expected_exit_code": 0, - "output": ".. [100%]\n" - }, - { - "id": "review61-regressions", - "argv": [ - "uv", - "run", - "--frozen", - "--extra", - "dev", - "--extra", - "dashboard", - "pytest", - "-q", - "-rs", - "tests/test_account_valuation_edge_contracts.py", - "tests/test_issue_12_review59_account.py", - "tests/test_valuation_contract_docs.py" - ], - "purpose": "Run Review 61 and independent-review named regressions", - "started_at_utc": "2026-10-07T03:59:51.888570Z", - "finished_at_utc": "2026-10-07T03:59:58.351942Z", - "duration_seconds": 6.463426006026566, - "exit_code": 0, - "expected_exit_code": 0, - "output": "........................ [100%]\n" - }, - { - "id": "full-suite", - "argv": [ - "uv", - "run", - "--frozen", - "--extra", - "dev", - "--extra", - "dashboard", - "pytest", - "-q", - "-rs" - ], - "purpose": "Run the complete repository test suite at the exact source head", - "started_at_utc": "2026-10-07T03:59:58.352023Z", - "finished_at_utc": "2026-10-07T04:01:03.222283Z", - "duration_seconds": 64.87031899858266, - "exit_code": 0, - "expected_exit_code": 0, - "output": "........................................................................ [ 25%]\n........................................................................ [ 51%]\n...............................................................ss....... [ 77%]\n.....................................................ss...... [100%]\n=============================== warnings summary ===============================\ntests/test_dashboard_auth_server.py:11\n /opt/data/gitea-agent/repositories/jsfamily/jarca-ledger-mcp/worktrees/issue-12/checkout/tests/test_dashboard_auth_server.py:11: StarletteDeprecationWarning: Using `httpx` with `starlette.testclient` is deprecated; install `httpx2` instead.\n from starlette.testclient import TestClient\n\n-- Docs: https://docs.pytest.org/en/stable/how-to/capture-warnings.html\n=========================== short test summary info ============================\nSKIPPED [1] tests/test_kb_bank_pdf.py:26: sample KB Bank PDF/password is not available\nSKIPPED [1] tests/test_kb_bank_pdf.py:42: sample KB Bank PDF/password is not available\nSKIPPED [1] tests/test_toss_securities_pdf.py:20: sample Toss Securities PDF is not available\nSKIPPED [1] tests/test_toss_securities_pdf.py:32: sample Toss Securities PDF is not available\n" - }, - { - "id": "ruff", - "argv": [ - "uv", - "run", - "--frozen", - "--extra", - "dev", - "--extra", - "dashboard", - "ruff", - "check", - "." - ], - "purpose": "Run Python lint checks", - "started_at_utc": "2026-10-07T04:01:03.222360Z", - "finished_at_utc": "2026-10-07T04:01:03.426930Z", - "duration_seconds": 0.20462407637387514, - "exit_code": 0, - "expected_exit_code": 0, - "output": "All checks passed!\n" - }, - { - "id": "compileall", - "argv": [ - "python3", - "-m", - "compileall", - "-q", - "jarca_ledger_mcp", - "dashboard", - "tests", - "scripts" - ], - "purpose": "Compile production, dashboard, test, and script Python surfaces", - "started_at_utc": "2026-10-07T04:01:03.427003Z", - "finished_at_utc": "2026-10-07T04:01:03.684488Z", - "duration_seconds": 0.25754371751099825, - "exit_code": 0, - "expected_exit_code": 0, - "output": "" - }, - { - "id": "diff-check", - "argv": [ - "git", - "diff", - "--check", - "5e721b0ddd648f3e80f341a3c304d1cc3ca47ee8..1b9eda683c66d3c7129716b9899eddf61df3362d" - ], - "purpose": "Check the complete rework diff for whitespace errors", - "started_at_utc": "2026-10-07T04:01:03.684567Z", - "finished_at_utc": "2026-10-07T04:01:03.730543Z", - "duration_seconds": 0.04603164829313755, - "exit_code": 0, - "expected_exit_code": 0, - "output": "" - } - ], - "changed_files": [ - { - "path": "docs/data-model.md", - "sha256": "f9932a04f3c74907da1c21d754a16e1401f64fd948945017d410de7d91494dca", - "git_blob": "70f26ce1522b8609a93471655c9506040a4078f1" - }, - { - "path": "docs/interface-contract.md", - "sha256": "01a3f37e23ee17b2b928b44e3e07d4d6982faead1ab6f0298889225b0c5ce916", - "git_blob": "4304427a604949b8295b4f93cb6054357805fe92" - }, - { - "path": "docs/requirements/req-003_account-valuation-history.md", - "sha256": "f5a3bf9f69d622451a1a08854062218382f03355a3464538a35b1e270ca5b70f", - "git_blob": "2a7be4d780999fce47402f15f0b05d0b92990715" - }, - { - "path": "docs/verification/issue-12-review-61/red-evidence.json", - "sha256": "567c03d28e6de74b6adfc0f6141dd96e9e129bab9d4455761615a1655870b4bf", - "git_blob": "b5f4bc9286b4ea443671ab0744935a11c295b124" - }, - { - "path": "jarca_ledger_mcp/application/account_valuation_service.py", - "sha256": "f7f5bac1e224401dfd02efb321b7e7bd87e02875b727a5366bcc223bf633fb57", - "git_blob": "0dfd7b7ce94a699b855e40b336afa7bf5cdc2595" - }, - { - "path": "jarca_ledger_mcp/application/accounts_write_services.py", - "sha256": "41dd6579dc422549316da05347c6d5e33d89da1e1502d6065b5b78a0160776d3", - "git_blob": "48a1dd5acfe782c9cc35e8bd615dc71671dadf6f" - }, - { - "path": "tests/test_account_valuation_edge_contracts.py", - "sha256": "fed17aec3518e2380d00b46252402ad69a71e7d265961a6264b03d790d579f42", - "git_blob": "0b08cb32af63084225e01642d333ca291c7445c4" - }, - { - "path": "tests/test_issue_12_review59_account.py", - "sha256": "a8a7491c7b78841c2be0dbc66913c1e076bdd231281fd64818493a0f3a1de550", - "git_blob": "f5cee3e993f189e688f8e8ab3829b5c4ab34cf5a" - }, - { - "path": "tests/test_valuation_contract_docs.py", - "sha256": "7443b8425d6b733e0e95d21b3c460a42dceeb2f99f84e1fb8fadcd88f6b77514", - "git_blob": "c473ee14a530496e11c28e33008b0d8a50d774cb" - } - ], - "added_line_security_scan": { - "hardcoded_secret": [], - "shell_injection": [], - "dynamic_eval": [], - "pickle": [], - "interpolated_sql": [] - }, - "worktree_clean_after": true, - "limitations": [ - "Four external private PDF fixture tests may be skipped when fixtures are unavailable.", - "Gitea status/readiness is not functional acceptance evidence." - ], - "changed_files_scope": "Behavior-bearing source, tests, normative docs, and immutable RED evidence at source_head_sha; mutable verification metadata and generated GREEN/manifest artifacts are intentionally excluded from hash binding." -} diff --git a/docs/verification/issue-12-review-61/evidence-plan.json b/docs/verification/issue-12-review-61/evidence-plan.json deleted file mode 100644 index a563ac5..0000000 --- a/docs/verification/issue-12-review-61/evidence-plan.json +++ /dev/null @@ -1,61 +0,0 @@ -{ - "schema": "gitea-agent.evidence-plan/v1", - "owner": "jsfamily", - "repository": "jarca-ledger-mcp", - "issue": 12, - "pull_request": 13, - "review_id": 61, - "reviewed_parent_sha": "5e721b0ddd648f3e80f341a3c304d1cc3ca47ee8", - "reviewed_head": "1b9eda683c66d3c7129716b9899eddf61df3362d", - "implementation_parent": "b8b8811a2a50371795a02e4fa65f097c9d9508ac", - "contract_sha256": "6d86b591b022fcc722611bfec6d24e54a64216ab6f7c4098f357e25420218818", - "manifest_generator": { - "path": "/opt/data/gitea-agent/.run/i12-r61/run_final_evidence.py", - "execution": "python3 /opt/data/gitea-agent/.run/i12-r61/run_final_evidence.py" - }, - "commands": [ - { - "id": "conversion-regression", - "argv": ["uv", "run", "--frozen", "--extra", "dev", "--extra", "dashboard", "pytest", "-q", "-rs", "tests/test_account_valuation_edge_contracts.py::test_bank_to_loan_conversion_rejects_existing_undefined_valuation_without_mutation", "tests/test_account_valuation_edge_contracts.py::test_bank_to_loan_conversion_without_valuations_remains_allowed"] - }, - { - "id": "review61-regressions", - "argv": ["uv", "run", "--frozen", "--extra", "dev", "--extra", "dashboard", "pytest", "-q", "-rs", "tests/test_account_valuation_edge_contracts.py", "tests/test_issue_12_review59_account.py", "tests/test_valuation_contract_docs.py"] - }, - { - "id": "full-suite", - "argv": ["uv", "run", "--frozen", "--extra", "dev", "--extra", "dashboard", "pytest", "-q", "-rs"] - }, - { - "id": "ruff", - "argv": ["uv", "run", "--frozen", "--extra", "dev", "--extra", "dashboard", "ruff", "check", "."] - }, - { - "id": "compileall", - "argv": ["python3", "-m", "compileall", "-q", "jarca_ledger_mcp", "dashboard", "tests", "scripts"] - }, - { - "id": "diff-check", - "argv": ["git", "diff", "--check", "5e721b0ddd648f3e80f341a3c304d1cc3ca47ee8..1b9eda683c66d3c7129716b9899eddf61df3362d"] - } - ], - "bound_paths": [ - "jarca_ledger_mcp/application/account_valuation_service.py", - "jarca_ledger_mcp/application/accounts_write_services.py", - "tests/test_account_valuation_edge_contracts.py", - "tests/test_issue_12_review59_account.py", - "tests/test_valuation_contract_docs.py", - "docs/data-model.md", - "docs/interface-contract.md", - "docs/requirements/req-003_account-valuation-history.md", - "docs/verification/issue-12-review-61/red-evidence.json", - "docs/verification/issue-12-review-61/finding-matrix.json", - "docs/verification/issue-12-review-61/contract-preservation-inventory.json", - "docs/verification/issue-12-review-61/evidence-plan.json" - ], - "redaction": "Synthetic fixtures only; no credentials, real account identifiers, financial documents, or environment secrets.", - "limitations": [ - "External private PDF fixtures may be skipped when unavailable.", - "Gitea commit status is readiness metadata, not functional acceptance evidence." - ] -} diff --git a/docs/verification/issue-12-review-61/finding-matrix.json b/docs/verification/issue-12-review-61/finding-matrix.json deleted file mode 100644 index 4c33a00..0000000 --- a/docs/verification/issue-12-review-61/finding-matrix.json +++ /dev/null @@ -1,56 +0,0 @@ -{ - "schema": "gitea-agent.finding-matrix/v1", - "owner": "jsfamily", - "repository": "jarca-ledger-mcp", - "issue": 12, - "pull_request": 13, - "review_id": 61, - "reviewed_parent_sha": "5e721b0ddd648f3e80f341a3c304d1cc3ca47ee8", - "reviewed_head": "1b9eda683c66d3c7129716b9899eddf61df3362d", - "implementation_parent": "b8b8811a2a50371795a02e4fa65f097c9d9508ac", - "findings": [ - { - "id": "N01-loan-balance-definition", - "classification": "implementation_defect", - "status": "resolved_and_verified_at_source_head", - "root_cause": "Internal candidate writers could persist loan balance evidence without an explicit representative liability definition, and unsupported loan purposes could bypass the definition rule.", - "tests": [ - "test_direct_loan_candidate_requires_liability_definition_and_writes_nothing", - "test_import_loan_candidate_requires_liability_definition_and_writes_nothing", - "test_dated_loan_create_and_historical_update_preserve_current_cache_without_valuations", - "test_loan_cash_balance_and_total_value_are_rejected_without_writes", - "test_loan_import_preserves_transactions_and_current_cache_without_valuation_candidate" - ], - "changed_paths": [ - "jarca_ledger_mcp/application/account_valuation_service.py", - "tests/test_account_valuation_edge_contracts.py", - "tests/test_issue_12_review59_account.py", - "docs/data-model.md", - "docs/interface-contract.md", - "docs/requirements/req-003_account-valuation-history.md" - ] - }, - { - "id": "N01-account-type-conversion-bypass", - "classification": "implementation_defect", - "status": "resolved", - "root_cause": "update_ledger_account allowed a non-loan account with definition-less historical valuations to become a loan account without validating the persisted history.", - "named_regression": "test_bank_to_loan_conversion_rejects_existing_undefined_valuation_without_mutation", - "positive_regression": "test_bank_to_loan_conversion_without_valuations_remains_allowed", - "red_evidence": "docs/verification/issue-12-review-61/red-evidence.json", - "minimal_fix": "Reject non-loan to loan conversion before mutation when any attached valuation lacks one of the two explicit valid representative liability definitions.", - "changed_paths": [ - "jarca_ledger_mcp/application/accounts_write_services.py", - "tests/test_account_valuation_edge_contracts.py", - "docs/data-model.md", - "docs/interface-contract.md", - "docs/requirements/req-003_account-valuation-history.md" - ], - "risks": [ - "Do not infer or backfill a liability definition.", - "Do not reject conversion when no valuation history exists.", - "Do not partially mutate account or valuation history on rejection." - ] - } - ] -} diff --git a/docs/verification/issue-12-review-61/green-evidence.json b/docs/verification/issue-12-review-61/green-evidence.json deleted file mode 100644 index 347d00e..0000000 --- a/docs/verification/issue-12-review-61/green-evidence.json +++ /dev/null @@ -1,30 +0,0 @@ -{ - "schema": "gitea-agent.green-evidence/v1", - "finding": "N01-account-type-conversion-bypass", - "source_commit": "1b9eda683c66d3c7129716b9899eddf61df3362d", - "tests": [ - "test_bank_to_loan_conversion_rejects_existing_undefined_valuation_without_mutation", - "test_bank_to_loan_conversion_without_valuations_remains_allowed" - ], - "argv": [ - "uv", - "run", - "--frozen", - "--extra", - "dev", - "--extra", - "dashboard", - "pytest", - "-q", - "-rs", - "tests/test_account_valuation_edge_contracts.py::test_bank_to_loan_conversion_rejects_existing_undefined_valuation_without_mutation", - "tests/test_account_valuation_edge_contracts.py::test_bank_to_loan_conversion_without_valuations_remains_allowed" - ], - "started_at_utc": "2026-10-07T03:59:49.130624Z", - "finished_at_utc": "2026-10-07T03:59:51.888407Z", - "exit_code": 0, - "expected_exit_code": 0, - "result": "GREEN", - "output": ".. [100%]\n", - "fixture_policy": "synthetic only; no credentials or real financial data" -} diff --git a/docs/verification/issue-12-review-61/red-evidence.json b/docs/verification/issue-12-review-61/red-evidence.json deleted file mode 100644 index b5f4bc9..0000000 --- a/docs/verification/issue-12-review-61/red-evidence.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "gate": "independent-bank-to-loan-conversion", - "source_sha": "b8b8811a2a50371795a02e4fa65f097c9d9508ac", - "test": "tests/test_account_valuation_edge_contracts.py::test_bank_to_loan_conversion_rejects_existing_undefined_valuation_without_mutation", - "command": "uv run --frozen --extra dev --extra dashboard pytest tests/test_account_valuation_edge_contracts.py::test_bank_to_loan_conversion_rejects_existing_undefined_valuation_without_mutation -q", - "exit_code": 1, - "result": "RED", - "output": "F [100%]\n=================================== FAILURES ===================================\n_ test_bank_to_loan_conversion_rejects_existing_undefined_valuation_without_mutation _\n\n assert rejected[\"success\"] is False\nE assert True is False\n=========================== short test summary info ============================\nFAILED tests/test_account_valuation_edge_contracts.py::test_bank_to_loan_conversion_rejects_existing_undefined_valuation_without_mutation" -} diff --git a/docs/verification/issue-12-review-63/contract-preservation-inventory.json b/docs/verification/issue-12-review-63/contract-preservation-inventory.json deleted file mode 100644 index a670e8a..0000000 --- a/docs/verification/issue-12-review-63/contract-preservation-inventory.json +++ /dev/null @@ -1,36 +0,0 @@ -{ - "schema": "contract-preservation-inventory/v1", - "issue": 12, - "pull_request": 13, - "review_id": 63, - "source_revision": "3db086a7fd15e9152a57fb95ab7942c6dc3be2b1", - "contracts": [ - { - "contract": "append-only immutable snapshot runs and corrections", - "preserved_by": ["test_f002_correction_replay_preserves_full_initial_response", "test_f006_initial_replay_survives_multiple_later_corrections", "tests/test_asset_snapshot_idempotency.py"] - }, - { - "contract": "preview-to-close authority drift protection", - "preserved_by": ["test_f001_preview_fingerprint_uses_same_unredacted_authority_and_rejects_drift"] - }, - { - "contract": "conditional zero-row closes remain visible historical authority", - "preserved_by": ["test_f003_zero_row_conditional_runs_are_timeseries_authority_with_aliases"] - }, - { - "contract": "closed consumers use frozen valuation identity rather than live valuation state", - "preserved_by": ["test_f004_closed_report_restores_frozen_valuation_identity_without_legacy_invention"] - }, - { - "contract": "NULL and zero remain distinct and balance basis dates require an actual balance", - "preserved_by": ["test_create_rejects_basis_only_without_mutation", "test_basis_only_create_cannot_block_later_dated_import"] - }, - { - "contract": "existing Issue 12 behavior outside Review 63 remains intact", - "preserved_by": ["review63-full-suite", "review63-ruff", "review63-compileall", "review63-diff-check"] - } - ], - "limitations": [ - "Private KB Bank and Toss Securities PDF fixtures were unavailable; four fixture-dependent tests are reported as skips." - ] -} diff --git a/docs/verification/issue-12-review-63/evidence-manifest.json b/docs/verification/issue-12-review-63/evidence-manifest.json deleted file mode 100644 index dc7327e..0000000 --- a/docs/verification/issue-12-review-63/evidence-manifest.json +++ /dev/null @@ -1 +0,0 @@ -{"claims":{"review63-compileall":["/commands/3/argv","/commands/3/exit_code","/commands/3/expected_exit_code","/commands/3/output","/commands/3/started_at_utc","/commands/3/finished_at_utc"],"review63-diff-check":["/commands/4/argv","/commands/4/exit_code","/commands/4/expected_exit_code","/commands/4/output","/commands/4/started_at_utc","/commands/4/finished_at_utc"],"review63-findings-green":["/commands/0/argv","/commands/0/exit_code","/commands/0/expected_exit_code","/commands/0/output","/commands/0/started_at_utc","/commands/0/finished_at_utc"],"review63-full-suite":["/commands/1/argv","/commands/1/exit_code","/commands/1/expected_exit_code","/commands/1/output","/commands/1/started_at_utc","/commands/1/finished_at_utc"],"review63-ruff":["/commands/2/argv","/commands/2/exit_code","/commands/2/expected_exit_code","/commands/2/output","/commands/2/started_at_utc","/commands/2/finished_at_utc"]},"commands":[{"argv":["uv","run","--frozen","--extra","dev","--extra","dashboard","pytest","-o","addopts=","-q","tests/test_issue_12_review63_accounts.py","tests/test_issue_12_review63_assets.py"],"claim_ids":["review63-findings-green"],"duration_seconds":3.989052458666265,"exit_code":0,"expected_exit_code":0,"finished_at_utc":"2026-10-07T08:38:49.778896Z","id":"review63-regressions","max_output_bytes":65536,"output":"........ [100%]\n8 passed in 2.40s\n","purpose":"Verify all named Review 63 RED to GREEN regressions","started_at_utc":"2026-10-07T08:38:45.789981Z"},{"argv":["uv","run","--frozen","--extra","dev","--extra","dashboard","pytest","-o","addopts=","-ra"],"claim_ids":["review63-full-suite"],"duration_seconds":79.06492502894253,"exit_code":0,"expected_exit_code":0,"finished_at_utc":"2026-10-07T08:40:08.842244Z","id":"full-suite","max_output_bytes":65536,"output":"============================= test session starts ==============================\nplatform linux -- Python 3.13.5, pytest-9.1.1, pluggy-1.6.0\nrootdir: /opt/data/gitea-agent/repositories/jsfamily/jarca-ledger-mcp/worktrees/issue-12/checkout\nconfigfile: pyproject.toml\ntestpaths: tests\nplugins: anyio-4.14.0\ncollected 285 items\n\ntests/test_account_basis_public_consumers.py .. [ 0%]\ntests/test_account_valuation_edge_contracts.py .......... [ 4%]\ntests/test_account_valuations.py ........ [ 7%]\ntests/test_asset_snapshot_idempotency.py .. [ 7%]\ntests/test_asset_snapshots.py ..... [ 9%]\ntests/test_backup_workflow.py ... [ 10%]\ntests/test_categorization.py ... [ 11%]\ntests/test_category_rule_filters.py ... [ 12%]\ntests/test_contract_regression.py ... [ 13%]\ntests/test_cross_account_transfer_matching.py ... [ 14%]\ntests/test_dashboard_app.py ....... [ 17%]\ntests/test_dashboard_auth_server.py .................. [ 23%]\ntests/test_dashboard_authentication.py .............. [ 28%]\ntests/test_dashboard_authentication_app.py ......... [ 31%]\ntests/test_dashboard_menu_transition.py ......... [ 34%]\ntests/test_dashboard_persistent_authentication.py ............... [ 40%]\ntests/test_import_current_balance_authority.py ... [ 41%]\ntests/test_import_provenance_policy.py ........... [ 44%]\ntests/test_issue_12_regressions.py ..................................... [ 57%]\n [ 57%]\ntests/test_issue_12_review59_account.py ........... [ 61%]\ntests/test_issue_12_review59_readonly.py ............ [ 65%]\ntests/test_issue_12_review59_reports.py ................... [ 72%]\ntests/test_issue_12_review63_accounts.py .. [ 73%]\ntests/test_issue_12_review63_assets.py ...... [ 75%]\ntests/test_kb_bank_pdf.py ss [ 76%]\ntests/test_ledger_categories.py ... [ 77%]\ntests/test_mcp_http_runtime.py ... [ 78%]\ntests/test_requirement_docs.py .............. [ 83%]\ntests/test_review_decision_workbench.py .... [ 84%]\ntests/test_seoulpay_xlsx.py .. [ 85%]\ntests/test_service.py ............ [ 89%]\ntests/test_streamlit_browser_evidence.py ...................... [ 97%]\ntests/test_toss_securities_pdf.py ss [ 97%]\ntests/test_uncategorized_workbench.py ... [ 98%]\ntests/test_valuation_contract_docs.py ... [100%]\n\n=============================== warnings summary ===============================\ntests/test_dashboard_auth_server.py:11\n /opt/data/gitea-agent/repositories/jsfamily/jarca-ledger-mcp/worktrees/issue-12/checkout/tests/test_dashboard_auth_server.py:11: StarletteDeprecationWarning: Using `httpx` with `starlette.testclient` is deprecated; install `httpx2` instead.\n from starlette.testclient import TestClient\n\n-- Docs: https://docs.pytest.org/en/stable/how-to/capture-warnings.html\n=========================== short test summary info ============================\nSKIPPED [1] tests/test_kb_bank_pdf.py:26: sample KB Bank PDF/password is not available\nSKIPPED [1] tests/test_kb_bank_pdf.py:42: sample KB Bank PDF/password is not available\nSKIPPED [1] tests/test_toss_securities_pdf.py:20: sample Toss Securities PDF is not available\nSKIPPED [1] tests/test_toss_securities_pdf.py:32: sample Toss Securities PDF is not available\n============= 281 passed, 4 skipped, 1 warning in 75.64s (0:01:15) =============\n","purpose":"Run the canonical full repository suite at the functional source revision","started_at_utc":"2026-10-07T08:38:49.779135Z"},{"argv":["uv","run","--frozen","--extra","dev","--extra","dashboard","ruff","check","."],"claim_ids":["review63-ruff"],"duration_seconds":0.3837073100730777,"exit_code":0,"expected_exit_code":0,"finished_at_utc":"2026-10-07T08:40:09.227746Z","id":"ruff","max_output_bytes":65536,"output":"All checks passed!\n","purpose":"Run repository lint checks","started_at_utc":"2026-10-07T08:40:08.844129Z"},{"argv":["uv","run","--frozen","--extra","dev","--extra","dashboard","python","-m","compileall","-q","jarca_ledger_mcp","dashboard","tests","scripts"],"claim_ids":["review63-compileall"],"duration_seconds":0.5016606021672487,"exit_code":0,"expected_exit_code":0,"finished_at_utc":"2026-10-07T08:40:09.729201Z","id":"compileall","max_output_bytes":65536,"output":"","purpose":"Compile package, dashboard, tests, and scripts","started_at_utc":"2026-10-07T08:40:09.227906Z"},{"argv":["git","diff","--check","main...HEAD"],"claim_ids":["review63-diff-check"],"duration_seconds":0.33338297344744205,"exit_code":0,"expected_exit_code":0,"finished_at_utc":"2026-10-07T08:40:10.062914Z","id":"diff-check","max_output_bytes":65536,"output":"","purpose":"Check the complete pull-request diff for whitespace errors","started_at_utc":"2026-10-07T08:40:09.729621Z"}],"environment":{"architecture":"aarch64","kernel":"6.18.34+rpt-rpi-v8","os":"Linux","python":"3.13.5","uv":"uv 0.11.6 (aarch64-unknown-linux-musl)"},"excluded_paths":["docs/verification/issue-12-review-63/evidence-plan.json","docs/verification/issue-12-review-63/evidence-manifest.json"],"files":[{"blob_oid":"4cb38a511c9a348aa5039378c3f59c1aced1889d","path":"jarca_ledger_mcp/application/accounts_write_services.py","sha256":"45dbbf367b9857cfe899574526f0a7120e28b0bf3d6d2814e795e9701a1a14b7"},{"blob_oid":"f2ecb7b6109e3837e01c41c286720ee435885313","path":"jarca_ledger_mcp/application/assets_service.py","sha256":"852fc3ced2bb388ccb42d3ffc9675106817cb80487493cd2818cd170e0922cd2"},{"blob_oid":"690b2fbee633eecbfdb2d7ed8fda78cea1b14b96","path":"tests/test_issue_12_review63_accounts.py","sha256":"9004db79795ef4963b87646e9b5c486c073febd3ae6c2ba313633574e03582a9"},{"blob_oid":"7ad8ba4c1a6f183af8e0f4d8ba093ad548f644c2","path":"tests/test_issue_12_review63_assets.py","sha256":"5695ed00dd7704cd989044cb2d9c2ed1f4a286a0b33dd1babba4e2e6aa4a148c"},{"blob_oid":"17be3e1e9b62e1ec63767dfa7920c78546d43e38","path":"tests/test_asset_snapshot_idempotency.py","sha256":"9a66f7d56b56cf3a9a85950813a56bdd06eafc07f592a1cb77133ad5f36ff09c"},{"blob_oid":"83c76f65ad122e8409abd3420c97b4c375e144d5","path":"tests/test_issue_12_regressions.py","sha256":"7dc8fbd7a7b0cb718de115f4d1f69b2e024cf1af641573e4cb04c00196017f29"},{"blob_oid":"4304427a604949b8295b4f93cb6054357805fe92","path":"docs/interface-contract.md","sha256":"01a3f37e23ee17b2b928b44e3e07d4d6982faead1ab6f0298889225b0c5ce916"},{"blob_oid":"70f26ce1522b8609a93471655c9506040a4078f1","path":"docs/data-model.md","sha256":"f9932a04f3c74907da1c21d754a16e1401f64fd948945017d410de7d91494dca"},{"blob_oid":"2a7be4d780999fce47402f15f0b05d0b92990715","path":"docs/requirements/req-003_account-valuation-history.md","sha256":"f5a3bf9f69d622451a1a08854062218382f03355a3464538a35b1e270ca5b70f"}],"generated_at":"2026-10-07T08:40:10.168998Z","limitations":["Four PDF fixture tests are skipped because private KB Bank and Toss Securities PDF fixtures are unavailable."],"plan":{"path":"docs/verification/issue-12-review-63/evidence-plan.json","sha256":"d7cb66cba7ec082e4637d38d534ac75e6509b900e77689c74a484ce9c6a37e87"},"redaction":{"checked":true,"violations":[]},"result":"success","schema":"evidence-manifest/v1","source_revision":"3db086a7fd15e9152a57fb95ab7942c6dc3be2b1","source_tree_clean":true} diff --git a/docs/verification/issue-12-review-63/evidence-plan.json b/docs/verification/issue-12-review-63/evidence-plan.json deleted file mode 100644 index b91f7dc..0000000 --- a/docs/verification/issue-12-review-63/evidence-plan.json +++ /dev/null @@ -1,62 +0,0 @@ -{ - "environment": ["os", "kernel", "architecture", "python", "uv"], - "command_env_allowlist": ["PATH", "HOME", "TMPDIR", "LANG", "VIRTUAL_ENV", "UV_CACHE_DIR"], - "secret_env_names": [], - "forbidden_regexes": [], - "hash_paths": [ - "jarca_ledger_mcp/application/accounts_write_services.py", - "jarca_ledger_mcp/application/assets_service.py", - "tests/test_issue_12_review63_accounts.py", - "tests/test_issue_12_review63_assets.py", - "tests/test_asset_snapshot_idempotency.py", - "tests/test_issue_12_regressions.py", - "docs/interface-contract.md", - "docs/data-model.md", - "docs/requirements/req-003_account-valuation-history.md" - ], - "commands": [ - { - "id": "review63-regressions", - "purpose": "Verify all named Review 63 RED to GREEN regressions", - "argv": ["uv", "run", "--frozen", "--extra", "dev", "--extra", "dashboard", "pytest", "-o", "addopts=", "-q", "tests/test_issue_12_review63_accounts.py", "tests/test_issue_12_review63_assets.py"], - "expected_exit_code": 0, - "max_output_bytes": 65536, - "claims": ["review63-findings-green"] - }, - { - "id": "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=", "-ra"], - "expected_exit_code": 0, - "max_output_bytes": 65536, - "claims": ["review63-full-suite"] - }, - { - "id": "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": ["review63-ruff"] - }, - { - "id": "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": ["review63-compileall"] - }, - { - "id": "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": ["review63-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-63/finding-matrix.json b/docs/verification/issue-12-review-63/finding-matrix.json deleted file mode 100644 index 4a82227..0000000 --- a/docs/verification/issue-12-review-63/finding-matrix.json +++ /dev/null @@ -1,59 +0,0 @@ -{ - "schema": "review-finding-matrix/v1", - "issue": 12, - "pull_request": 13, - "review_id": 63, - "reviewed_head": "3b5101128d5a2cf038b8fb84facfd9d176928c26", - "source_revision": "3db086a7fd15e9152a57fb95ab7942c6dc3be2b1", - "findings": [ - { - "id": "F-001", - "status": "resolved", - "production": "jarca_ledger_mcp/application/assets_service.py", - "regression": "test_f001_preview_fingerprint_uses_same_unredacted_authority_and_rejects_drift", - "claim": "preview and close hash the same private authority representation; real drift is rejected without a run write" - }, - { - "id": "F-002", - "status": "resolved", - "production": "jarca_ledger_mcp/application/assets_service.py", - "regressions": [ - "test_f002_close_replay_is_byte_for_byte_equal_for_mixed_account_manual_as_of", - "test_f002_correction_replay_preserves_full_initial_response" - ], - "claim": "initial and correction replays reconstruct the original immutable response, warning set, provenance, item ordering, and IDs" - }, - { - "id": "F-003", - "status": "resolved", - "production": "jarca_ledger_mcp/application/assets_service.py", - "regression": "test_f003_zero_row_conditional_runs_are_timeseries_authority_with_aliases", - "claim": "timeseries enumerates both legacy snapshot and run-only basis dates and exposes the latest zero-row conditional run" - }, - { - "id": "F-004", - "status": "resolved", - "production": "jarca_ledger_mcp/application/assets_service.py", - "regression": "test_f004_closed_report_restores_frozen_valuation_identity_without_legacy_invention", - "claim": "closed reports restore persisted valuation identity and currency without consulting live authority or inventing legacy IDs" - }, - { - "id": "F-005", - "status": "resolved", - "production": "jarca_ledger_mcp/application/accounts_write_services.py", - "regressions": [ - "test_create_rejects_basis_only_without_mutation", - "test_basis_only_create_cannot_block_later_dated_import" - ], - "claim": "basis-only creates fail before mutation while zero-with-basis and unknown pairs remain valid" - }, - { - "id": "F-006", - "status": "resolved", - "production": "jarca_ledger_mcp/application/assets_service.py", - "regression": "test_f006_initial_replay_survives_multiple_later_corrections", - "claim": "an immutable run can be replayed through the complete later correction chain while unrelated live-authority drift still conflicts" - } - ], - "green_evidence": "evidence-manifest.json" -} diff --git a/docs/verification/issue-12-review-63/red-evidence.json b/docs/verification/issue-12-review-63/red-evidence.json deleted file mode 100644 index 07618bc..0000000 --- a/docs/verification/issue-12-review-63/red-evidence.json +++ /dev/null @@ -1,74 +0,0 @@ -{ - "schema": "review-red-evidence/v1", - "issue": 12, - "pull_request": 13, - "review_id": 63, - "reviewed_head": "3b5101128d5a2cf038b8fb84facfd9d176928c26", - "review_state": "REQUEST_CHANGES", - "findings": [ - { - "id": "F-001", - "test": "test_f001_preview_fingerprint_uses_same_unredacted_authority_and_rejects_drift", - "red_observation": "unchanged preview fingerprint was rejected with authority_drift" - }, - { - "id": "F-002", - "tests": [ - "test_f002_close_replay_is_byte_for_byte_equal_for_mixed_account_manual_as_of", - "test_f002_correction_replay_preserves_full_initial_response" - ], - "red_observation": "replay responses differed in warnings/provenance/items or conflicted" - }, - { - "id": "F-003", - "test": "test_f003_zero_row_conditional_runs_are_timeseries_authority_with_aliases", - "red_observation": "zero-row closed run produced no timeseries point" - }, - { - "id": "F-004", - "test": "test_f004_closed_report_restores_frozen_valuation_identity_without_legacy_invention", - "red_observation": "closed report omitted persisted valuation_id and currency" - }, - { - "id": "F-005", - "tests": [ - "test_create_rejects_basis_only_without_mutation", - "test_basis_only_create_cannot_block_later_dated_import" - ], - "red_observation": "basis-only account creation succeeded and could suppress a real dated import balance" - }, - { - "id": "F-006", - "test": "test_f006_initial_replay_survives_multiple_later_corrections", - "red_observation": "replaying the initial key first conflicted after two corrections; after that path was enabled, unrelated live-authority drift after the correction chain was incorrectly accepted" - } - ], - "red_runs": [ - { - "argv": ["pytest", "-q", "tests/test_issue_12_review63_assets.py"], - "exit_code": 1, - "result": "5 failed before production changes", - "limitation": "isolated development environment used by the delegated TDD worker" - }, - { - "argv": ["uv", "run", "pytest", "-q", "tests/test_issue_12_review63_accounts.py"], - "exit_code": 1, - "result": "2 failed before production changes" - }, - { - "argv": ["uv", "run", "--frozen", "--extra", "dev", "--extra", "dashboard", "pytest", "-o", "addopts=", "-q", "tests/test_issue_12_review63_assets.py::test_f002_correction_replay_preserves_full_initial_response"], - "exit_code": 1, - "result": "correction replay omitted existing_snapshot_rows and differed from the original response" - }, - { - "argv": ["uv", "run", "--frozen", "--extra", "dev", "--extra", "dashboard", "pytest", "-o", "addopts=", "-q", "tests/test_issue_12_review63_assets.py::test_f006_initial_replay_survives_multiple_later_corrections"], - "exit_code": 1, - "result": "initial replay after two later corrections returned idempotency_conflict" - }, - { - "argv": ["uv", "run", "--frozen", "--extra", "dev", "--extra", "dashboard", "pytest", "-o", "addopts=", "-q", "tests/test_issue_12_review63_assets.py::test_f006_initial_replay_survives_multiple_later_corrections"], - "exit_code": 1, - "result": "unrelated live-authority drift after the correction chain returned success instead of idempotency_conflict" - } - ] -} diff --git a/docs/verification/issue-12-review-64/contract-preservation-inventory.json b/docs/verification/issue-12-review-64/contract-preservation-inventory.json deleted file mode 100644 index 2a32917..0000000 --- a/docs/verification/issue-12-review-64/contract-preservation-inventory.json +++ /dev/null @@ -1,72 +0,0 @@ -{ - "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." - ] -} diff --git a/docs/verification/issue-12-review-64/evidence-manifest.json b/docs/verification/issue-12-review-64/evidence-manifest.json deleted file mode 100644 index ccbe5ae..0000000 --- a/docs/verification/issue-12-review-64/evidence-manifest.json +++ /dev/null @@ -1 +0,0 @@ -{"claims":{"review64-compileall":["/commands/3/argv","/commands/3/exit_code","/commands/3/expected_exit_code","/commands/3/output","/commands/3/started_at_utc","/commands/3/finished_at_utc"],"review64-diff-check":["/commands/4/argv","/commands/4/exit_code","/commands/4/expected_exit_code","/commands/4/output","/commands/4/started_at_utc","/commands/4/finished_at_utc"],"review64-findings-green":["/commands/0/argv","/commands/0/exit_code","/commands/0/expected_exit_code","/commands/0/output","/commands/0/started_at_utc","/commands/0/finished_at_utc"],"review64-full-suite":["/commands/1/argv","/commands/1/exit_code","/commands/1/expected_exit_code","/commands/1/output","/commands/1/started_at_utc","/commands/1/finished_at_utc"],"review64-ruff":["/commands/2/argv","/commands/2/exit_code","/commands/2/expected_exit_code","/commands/2/output","/commands/2/started_at_utc","/commands/2/finished_at_utc"]},"commands":[{"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"],"claim_ids":["review64-findings-green"],"duration_seconds":35.864721942692995,"exit_code":0,"expected_exit_code":0,"finished_at_utc":"2026-10-07T13:44:20.612362Z","id":"review64-focused-regressions","max_output_bytes":65536,"output":".................................................................... [100%]\n68 passed in 30.58s\n","purpose":"Run Review 64 and preserved Review 63 regression coverage","started_at_utc":"2026-10-07T13:43:44.752577Z"},{"argv":["uv","run","--frozen","--extra","dev","--extra","dashboard","pytest","-o","addopts=","-q"],"claim_ids":["review64-full-suite"],"duration_seconds":126.04733155481517,"exit_code":0,"expected_exit_code":0,"finished_at_utc":"2026-10-07T13:46:26.664274Z","id":"review64-full-suite","max_output_bytes":65536,"output":"........................................................................ [ 24%]\n........................................................................ [ 49%]\n........................................................................ [ 74%]\n...ss............................................................ss..... [ 99%]\n.. [100%]\n=============================== warnings summary ===============================\ntests/test_dashboard_auth_server.py:11\n /opt/data/gitea-agent/repositories/jsfamily/jarca-ledger-mcp/worktrees/issue-12/checkout/tests/test_dashboard_auth_server.py:11: StarletteDeprecationWarning: Using `httpx` with `starlette.testclient` is deprecated; install `httpx2` instead.\n from starlette.testclient import TestClient\n\n-- Docs: https://docs.pytest.org/en/stable/how-to/capture-warnings.html\n286 passed, 4 skipped, 1 warning in 120.29s (0:02:00)\n","purpose":"Run the canonical full repository suite at the functional source revision","started_at_utc":"2026-10-07T13:44:20.617439Z"},{"argv":["uv","run","--frozen","--extra","dev","--extra","dashboard","ruff","check","."],"claim_ids":["review64-ruff"],"duration_seconds":0.3705855421721935,"exit_code":0,"expected_exit_code":0,"finished_at_utc":"2026-10-07T13:46:27.035408Z","id":"review64-ruff","max_output_bytes":65536,"output":"All checks passed!\n","purpose":"Run repository lint checks","started_at_utc":"2026-10-07T13:46:26.664920Z"},{"argv":["uv","run","--frozen","--extra","dev","--extra","dashboard","python","-m","compileall","-q","jarca_ledger_mcp","dashboard","tests","scripts"],"claim_ids":["review64-compileall"],"duration_seconds":0.8566651344299316,"exit_code":0,"expected_exit_code":0,"finished_at_utc":"2026-10-07T13:46:27.892099Z","id":"review64-compileall","max_output_bytes":65536,"output":"","purpose":"Compile package, dashboard, tests, and scripts","started_at_utc":"2026-10-07T13:46:27.035581Z"},{"argv":["git","diff","--check","main...HEAD"],"claim_ids":["review64-diff-check"],"duration_seconds":0.42741929925978184,"exit_code":0,"expected_exit_code":0,"finished_at_utc":"2026-10-07T13:46:28.319537Z","id":"review64-diff-check","max_output_bytes":65536,"output":"","purpose":"Check the complete pull-request diff for whitespace errors","started_at_utc":"2026-10-07T13:46:27.892281Z"}],"environment":{"architecture":"aarch64","kernel":"6.18.34+rpt-rpi-v8","os":"Linux","python":"3.13.5","uv":"uv 0.11.6 (aarch64-unknown-linux-musl)"},"excluded_paths":["docs/verification/issue-12-review-64/evidence-plan.json","docs/verification/issue-12-review-64/evidence-manifest.json"],"files":[{"blob_oid":"fd8399fa536e794b40358721a7a9cf26c4671a3e","path":"jarca_ledger_mcp/application/accounts_write_services.py","sha256":"d1f7465ab94eb95152ff99ebd532aef871528044d687b45feca41eb30c3ba283"},{"blob_oid":"f3bb109f5492f8aa4b86357adc322a254252957c","path":"jarca_ledger_mcp/application/assets_service.py","sha256":"7dcab775b1918b4f71f4efecf5f811a32578915678101e6fff96ce2e7c498cb8"},{"blob_oid":"fa60d163dcb4322cd9bf9c97ebad90949ec6b9a9","path":"tests/test_import_current_balance_authority.py","sha256":"3d9871d27c62cae20d6972410ac6f02f631ce53c2e96bb67f5dd48ca05d76686"},{"blob_oid":"e9958a7d0cbc935bb0552b0e9740e9c9152fd0b0","path":"tests/test_asset_snapshot_idempotency.py","sha256":"1739e2a5f0f1171155009c66ea0cf3ef9482ed44b8b538562121ea93dd0f577d"},{"blob_oid":"f3ca20f72cec9b740f9fb55eeed589ac302a611f","path":"tests/test_valuation_contract_docs.py","sha256":"f23b5e2e3a2ac4de280f372bdf4f3bbd2795812f93fb8d15b5b4b1c5d0dcae43"},{"blob_oid":"690b2fbee633eecbfdb2d7ed8fda78cea1b14b96","path":"tests/test_issue_12_review63_accounts.py","sha256":"9004db79795ef4963b87646e9b5c486c073febd3ae6c2ba313633574e03582a9"},{"blob_oid":"7ad8ba4c1a6f183af8e0f4d8ba093ad548f644c2","path":"tests/test_issue_12_review63_assets.py","sha256":"5695ed00dd7704cd989044cb2d9c2ed1f4a286a0b33dd1babba4e2e6aa4a148c"},{"blob_oid":"83c76f65ad122e8409abd3420c97b4c375e144d5","path":"tests/test_issue_12_regressions.py","sha256":"7dc8fbd7a7b0cb718de115f4d1f69b2e024cf1af641573e4cb04c00196017f29"},{"blob_oid":"7234106e986eb528ef12e60a915a403fd2db6eff","path":"docs/data-model.md","sha256":"39e94f245d2934b68c968844cfcb565110f39732d8a32550644c95fb837b41c7"},{"blob_oid":"4304427a604949b8295b4f93cb6054357805fe92","path":"docs/interface-contract.md","sha256":"01a3f37e23ee17b2b928b44e3e07d4d6982faead1ab6f0298889225b0c5ce916"},{"blob_oid":"2a7be4d780999fce47402f15f0b05d0b92990715","path":"docs/requirements/req-003_account-valuation-history.md","sha256":"f5a3bf9f69d622451a1a08854062218382f03355a3464538a35b1e270ca5b70f"}],"generated_at":"2026-10-07T13:46:28.438463Z","limitations":["Four PDF fixture tests are skipped because private KB Bank and Toss Securities PDF fixtures are unavailable."],"plan":{"path":"docs/verification/issue-12-review-64/evidence-plan.json","sha256":"097b2916a5f82dc48e8557b9df4236e88de47c9b54842c6b105545e1f268f526"},"redaction":{"checked":true,"violations":[]},"result":"success","schema":"evidence-manifest/v1","source_revision":"d258cfdeb490637232e4a2860bade341dc86a2b5","source_tree_clean":true} diff --git a/docs/verification/issue-12-review-64/evidence-plan.json b/docs/verification/issue-12-review-64/evidence-plan.json deleted file mode 100644 index 4ba2bcf..0000000 --- a/docs/verification/issue-12-review-64/evidence-plan.json +++ /dev/null @@ -1,64 +0,0 @@ -{ - "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." - ] -} diff --git a/docs/verification/issue-12-review-64/finding-matrix.json b/docs/verification/issue-12-review-64/finding-matrix.json deleted file mode 100644 index b017f02..0000000 --- a/docs/verification/issue-12-review-64/finding-matrix.json +++ /dev/null @@ -1,47 +0,0 @@ -{ - "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" -} diff --git a/docs/verification/issue-12-review-64/red-evidence.json b/docs/verification/issue-12-review-64/red-evidence.json deleted file mode 100644 index e84108e..0000000 --- a/docs/verification/issue-12-review-64/red-evidence.json +++ /dev/null @@ -1,35 +0,0 @@ -{ - "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" -} diff --git a/docs/verification/issue-12-review-65/contract-preservation-inventory.json b/docs/verification/issue-12-review-65/contract-preservation-inventory.json deleted file mode 100644 index 150d1af..0000000 --- a/docs/verification/issue-12-review-65/contract-preservation-inventory.json +++ /dev/null @@ -1,58 +0,0 @@ -{ - "schema": "contract-preservation-inventory/v1", - "issue": 12, - "pull_request": 13, - "review_id": 65, - "reviewed_head": "fc2d2a6faeac3c64c0ed604f2aa1ad7c37c65570", - "source_revision": "8caf1f8379171a128a2c12971a2eadc9a324309a", - "contracts": [ - { - "contract": "current cache balance is an exact integer or unknown NULL; zero remains a valid known balance", - "status": "preserved", - "preserved_by": [ - "test_create_rejects_whitespace_or_non_integer_dated_balance_without_mutation", - "test_zero_dated_balance_and_valid_import_recovery" - ] - }, - { - "contract": "invalid dated account creation fails with validation_error before account or valuation mutation", - "status": "preserved", - "preserved_by": [ - "test_create_rejects_whitespace_or_non_integer_dated_balance_without_mutation" - ] - }, - { - "contract": "a valid dated import can establish current cache and append a valuation after invalid create attempts are rejected", - "status": "preserved", - "preserved_by": [ - "test_zero_dated_balance_and_valid_import_recovery", - "test_late_import_current_balance_is_authoritative_by_evidence_basis_date" - ] - }, - { - "contract": "unknown basis remains distinct from last_synced_at and historical imports cannot roll back a newer usable cache", - "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", - "review65-focused-regressions" - ] - }, - { - "contract": "all prior Issue 12 and Review 64 public envelopes, valuation selection, snapshot replay, read-only, migration, privacy, authentication, and menu semantics remain intact", - "status": "preserved", - "preserved_by": [ - "review65-focused-regressions", - "review65-full-suite", - "review65-ruff", - "review65-compileall", - "review65-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-65/evidence-manifest.json b/docs/verification/issue-12-review-65/evidence-manifest.json deleted file mode 100644 index 513de61..0000000 --- a/docs/verification/issue-12-review-65/evidence-manifest.json +++ /dev/null @@ -1 +0,0 @@ -{"claims":{"review65-compileall":["/commands/3/argv","/commands/3/exit_code","/commands/3/expected_exit_code","/commands/3/output","/commands/3/started_at_utc","/commands/3/finished_at_utc"],"review65-diff-check":["/commands/4/argv","/commands/4/exit_code","/commands/4/expected_exit_code","/commands/4/output","/commands/4/started_at_utc","/commands/4/finished_at_utc"],"review65-findings-green":["/commands/0/argv","/commands/0/exit_code","/commands/0/expected_exit_code","/commands/0/output","/commands/0/started_at_utc","/commands/0/finished_at_utc"],"review65-full-suite":["/commands/1/argv","/commands/1/exit_code","/commands/1/expected_exit_code","/commands/1/output","/commands/1/started_at_utc","/commands/1/finished_at_utc"],"review65-ruff":["/commands/2/argv","/commands/2/exit_code","/commands/2/expected_exit_code","/commands/2/output","/commands/2/started_at_utc","/commands/2/finished_at_utc"]},"commands":[{"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_account_valuation_edge_contracts.py","tests/test_account_valuations.py","tests/test_issue_12_regressions.py","tests/test_issue_12_review63_accounts.py"],"claim_ids":["review65-findings-green"],"duration_seconds":132.6845943974331,"exit_code":0,"expected_exit_code":0,"finished_at_utc":"2026-10-07T15:26:45.333187Z","id":"review65-focused-regressions","max_output_bytes":65536,"output":"................................................................. [100%]\n65 passed in 110.48s (0:01:50)\n","purpose":"Run Review 65 and preserved account authority regression coverage","started_at_utc":"2026-10-07T15:24:32.649106Z"},{"argv":["uv","run","--frozen","--extra","dev","--extra","dashboard","pytest","-o","addopts=","-q"],"claim_ids":["review65-full-suite"],"duration_seconds":247.0696819210425,"exit_code":0,"expected_exit_code":0,"finished_at_utc":"2026-10-07T15:30:52.403241Z","id":"review65-full-suite","max_output_bytes":65536,"output":"........................................................................ [ 24%]\n........................................................................ [ 49%]\n........................................................................ [ 73%]\n.....ss............................................................ss... [ 98%]\n.... [100%]\n=============================== warnings summary ===============================\ntests/test_dashboard_auth_server.py:11\n /opt/data/gitea-agent/repositories/jsfamily/jarca-ledger-mcp/worktrees/issue-12/checkout/tests/test_dashboard_auth_server.py:11: StarletteDeprecationWarning: Using `httpx` with `starlette.testclient` is deprecated; install `httpx2` instead.\n from starlette.testclient import TestClient\n\n-- Docs: https://docs.pytest.org/en/stable/how-to/capture-warnings.html\n288 passed, 4 skipped, 1 warning in 234.48s (0:03:54)\n","purpose":"Run the canonical full repository suite at the functional source revision","started_at_utc":"2026-10-07T15:26:45.333911Z"},{"argv":["uv","run","--frozen","--extra","dev","--extra","dashboard","ruff","check","."],"claim_ids":["review65-ruff"],"duration_seconds":2.0587579123675823,"exit_code":0,"expected_exit_code":0,"finished_at_utc":"2026-10-07T15:30:54.462776Z","id":"review65-ruff","max_output_bytes":65536,"output":"All checks passed!\n","purpose":"Run repository lint checks","started_at_utc":"2026-10-07T15:30:52.404090Z"},{"argv":["uv","run","--frozen","--extra","dev","--extra","dashboard","python","-m","compileall","-q","jarca_ledger_mcp","dashboard","tests","scripts"],"claim_ids":["review65-compileall"],"duration_seconds":0.859572078101337,"exit_code":0,"expected_exit_code":0,"finished_at_utc":"2026-10-07T15:30:55.322302Z","id":"review65-compileall","max_output_bytes":65536,"output":"","purpose":"Compile package, dashboard, tests, and scripts","started_at_utc":"2026-10-07T15:30:54.462966Z"},{"argv":["git","diff","--check","main...HEAD"],"claim_ids":["review65-diff-check"],"duration_seconds":0.6653668954968452,"exit_code":0,"expected_exit_code":0,"finished_at_utc":"2026-10-07T15:30:55.987806Z","id":"review65-diff-check","max_output_bytes":65536,"output":"","purpose":"Check the complete pull-request diff for whitespace errors","started_at_utc":"2026-10-07T15:30:55.322579Z"}],"environment":{"architecture":"aarch64","kernel":"6.18.34+rpt-rpi-v8","os":"Linux","python":"3.13.5","uv":"uv 0.11.6 (aarch64-unknown-linux-musl)"},"excluded_paths":["docs/verification/issue-12-review-65/evidence-plan.json","docs/verification/issue-12-review-65/evidence-manifest.json"],"files":[{"blob_oid":"9d3e9b11c4ecf6cdfeff1cbd99dc84c57d506f36","path":"jarca_ledger_mcp/application/accounts_write_services.py","sha256":"404c3b5b2fbe2dfe224351a3384a6357c31556535962a06dcc35a78ad8d2668f"},{"blob_oid":"1b9a32e87c208f8ded38cbe08c63200331cb3157","path":"tests/test_import_current_balance_authority.py","sha256":"8b25322ada2cbbea4a621b7dc021e43d64d4f444698a0f6a1e2d5f4d2a2ad232"},{"blob_oid":"8433866ca0eb5dcf512b6e84e23931b37f1035f8","path":"tests/test_account_basis_public_consumers.py","sha256":"1b719d3318d376c69ca0f0af39e2d6027b0e3b46b136ce8079bec856ef7871af"},{"blob_oid":"0b08cb32af63084225e01642d333ca291c7445c4","path":"tests/test_account_valuation_edge_contracts.py","sha256":"fed17aec3518e2380d00b46252402ad69a71e7d265961a6264b03d790d579f42"},{"blob_oid":"1e18454fbde9ebc58a6ae98cd3f7dbe8ba665cc5","path":"tests/test_account_valuations.py","sha256":"aa3f831acba0317b6f49764042927026715ff5f6e729b945a22aa2b13490a6bf"},{"blob_oid":"83c76f65ad122e8409abd3420c97b4c375e144d5","path":"tests/test_issue_12_regressions.py","sha256":"7dc8fbd7a7b0cb718de115f4d1f69b2e024cf1af641573e4cb04c00196017f29"},{"blob_oid":"690b2fbee633eecbfdb2d7ed8fda78cea1b14b96","path":"tests/test_issue_12_review63_accounts.py","sha256":"9004db79795ef4963b87646e9b5c486c073febd3ae6c2ba313633574e03582a9"},{"blob_oid":"7234106e986eb528ef12e60a915a403fd2db6eff","path":"docs/data-model.md","sha256":"39e94f245d2934b68c968844cfcb565110f39732d8a32550644c95fb837b41c7"},{"blob_oid":"2a7be4d780999fce47402f15f0b05d0b92990715","path":"docs/requirements/req-003_account-valuation-history.md","sha256":"f5a3bf9f69d622451a1a08854062218382f03355a3464538a35b1e270ca5b70f"}],"generated_at":"2026-10-07T15:30:56.089005Z","limitations":["Four PDF fixture tests are skipped because private KB Bank and Toss Securities PDF fixtures are unavailable."],"plan":{"path":"docs/verification/issue-12-review-65/evidence-plan.json","sha256":"62ebaec1130ceed82bda1da1678296e894ec50b33aa8caf6c7efe5ad094b9823"},"redaction":{"checked":true,"violations":[]},"result":"success","schema":"evidence-manifest/v1","source_revision":"f49568273e74b89dc3e83da21ce2ae12ed110543","source_tree_clean":true} diff --git a/docs/verification/issue-12-review-65/evidence-plan.json b/docs/verification/issue-12-review-65/evidence-plan.json deleted file mode 100644 index 763953a..0000000 --- a/docs/verification/issue-12-review-65/evidence-plan.json +++ /dev/null @@ -1,62 +0,0 @@ -{ - "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", - "tests/test_import_current_balance_authority.py", - "tests/test_account_basis_public_consumers.py", - "tests/test_account_valuation_edge_contracts.py", - "tests/test_account_valuations.py", - "tests/test_issue_12_regressions.py", - "tests/test_issue_12_review63_accounts.py", - "docs/data-model.md", - "docs/requirements/req-003_account-valuation-history.md" - ], - "commands": [ - { - "id": "review65-focused-regressions", - "purpose": "Run Review 65 and preserved account authority regression coverage", - "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_account_valuation_edge_contracts.py", "tests/test_account_valuations.py", "tests/test_issue_12_regressions.py", "tests/test_issue_12_review63_accounts.py"], - "expected_exit_code": 0, - "max_output_bytes": 65536, - "claims": ["review65-findings-green"] - }, - { - "id": "review65-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": ["review65-full-suite"] - }, - { - "id": "review65-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": ["review65-ruff"] - }, - { - "id": "review65-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": ["review65-compileall"] - }, - { - "id": "review65-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": ["review65-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-65/finding-matrix.json b/docs/verification/issue-12-review-65/finding-matrix.json deleted file mode 100644 index d9c908a..0000000 --- a/docs/verification/issue-12-review-65/finding-matrix.json +++ /dev/null @@ -1,31 +0,0 @@ -{ - "schema": "review-finding-matrix/v1", - "issue": 12, - "pull_request": 13, - "review_id": 65, - "reviewed_head": "fc2d2a6faeac3c64c0ed604f2aa1ad7c37c65570", - "source_revision": "8caf1f8379171a128a2c12971a2eadc9a324309a", - "contract_sha256": "6d86b591b022fcc722611bfec6d24e54a64216ab6f7c4098f357e25420218818", - "findings": [ - { - "id": "C05-current-import-create", - "classification": "valid_fix", - "status": "resolved", - "production": "jarca_ledger_mcp/application/accounts_write_services.py", - "regressions": [ - "test_create_rejects_whitespace_or_non_integer_dated_balance_without_mutation", - "test_zero_dated_balance_and_valid_import_recovery" - ], - "claim": "account creation rejects unusable dated balances before mutation while preserving zero and later valid dated import authority" - }, - { - "id": "IR-001-strict-integer-create", - "classification": "valid_fix", - "status": "resolved", - "production": "jarca_ledger_mcp/application/accounts_write_services.py", - "regression": "test_create_rejects_whitespace_or_non_integer_dated_balance_without_mutation", - "claim": "boolean and floating-point balances are rejected instead of coercing or truncating; canonical signed integer text remains compatible" - } - ], - "green_evidence": "evidence-manifest.json" -} diff --git a/docs/verification/issue-12-review-65/red-evidence.json b/docs/verification/issue-12-review-65/red-evidence.json deleted file mode 100644 index dbea24e..0000000 --- a/docs/verification/issue-12-review-65/red-evidence.json +++ /dev/null @@ -1,23 +0,0 @@ -{ - "schema": "review-red-evidence/v1", - "issue": 12, - "pull_request": 13, - "review_id": 65, - "reviewed_head": "fc2d2a6faeac3c64c0ed604f2aa1ad7c37c65570", - "contract_sha256": "6d86b591b022fcc722611bfec6d24e54a64216ab6f7c4098f357e25420218818", - "reproductions": [ - { - "id": "C05-current-import-create", - "command": "uv run pytest -q tests/test_import_current_balance_authority.py::test_create_rejects_whitespace_or_non_integer_dated_balance_without_mutation tests/test_import_current_balance_authority.py::test_zero_dated_balance_and_valid_import_recovery", - "exit_code": 1, - "observed": "invalid whitespace or non-integer dated balance creation returned success, persisted unusable cache authority, omitted its valuation candidate, and exposed ValueError to a public liquidity consumer" - }, - { - "id": "IR-001-strict-integer-create", - "command": "uv run pytest -o addopts= -q tests/test_import_current_balance_authority.py::test_create_rejects_whitespace_or_non_integer_dated_balance_without_mutation", - "exit_code": 1, - "observed": "boolean and floating-point balances were accepted through int coercion and persisted values different from caller input" - } - ], - "sensitive_data": "synthetic fixtures only; no credentials or real financial data" -} diff --git a/docs/verification/issue-12-review-66/contract-preservation-inventory.json b/docs/verification/issue-12-review-66/contract-preservation-inventory.json deleted file mode 100644 index 100b925..0000000 --- a/docs/verification/issue-12-review-66/contract-preservation-inventory.json +++ /dev/null @@ -1,59 +0,0 @@ -{ - "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-manifest.json b/docs/verification/issue-12-review-66/evidence-manifest.json deleted file mode 100644 index ece481a..0000000 --- a/docs/verification/issue-12-review-66/evidence-manifest.json +++ /dev/null @@ -1 +0,0 @@ -{"claims":{"review66-compileall":["/commands/3/argv","/commands/3/exit_code","/commands/3/expected_exit_code","/commands/3/output","/commands/3/started_at_utc","/commands/3/finished_at_utc"],"review66-diff-check":["/commands/4/argv","/commands/4/exit_code","/commands/4/expected_exit_code","/commands/4/output","/commands/4/started_at_utc","/commands/4/finished_at_utc"],"review66-findings-green":["/commands/0/argv","/commands/0/exit_code","/commands/0/expected_exit_code","/commands/0/output","/commands/0/started_at_utc","/commands/0/finished_at_utc"],"review66-full-suite":["/commands/1/argv","/commands/1/exit_code","/commands/1/expected_exit_code","/commands/1/output","/commands/1/started_at_utc","/commands/1/finished_at_utc"],"review66-ruff":["/commands/2/argv","/commands/2/exit_code","/commands/2/expected_exit_code","/commands/2/output","/commands/2/started_at_utc","/commands/2/finished_at_utc"]},"commands":[{"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"],"claim_ids":["review66-findings-green"],"duration_seconds":52.35116841085255,"exit_code":0,"expected_exit_code":0,"finished_at_utc":"2026-10-07T22:10:39.166837Z","id":"review66-focused-regressions","max_output_bytes":65536,"output":".................................................................... [100%]\n68 passed in 44.37s\n","purpose":"Run Review 66 and preserved account authority regressions","started_at_utc":"2026-10-07T22:09:46.815953Z"},{"argv":["uv","run","--frozen","--extra","dev","--extra","dashboard","pytest","-o","addopts=","-q"],"claim_ids":["review66-full-suite"],"duration_seconds":146.94252483453602,"exit_code":0,"expected_exit_code":0,"finished_at_utc":"2026-10-07T22:13:06.108583Z","id":"review66-full-suite","max_output_bytes":65536,"output":"........................................................................ [ 24%]\n........................................................................ [ 48%]\n........................................................................ [ 73%]\n........ss............................................................ss [ 97%]\n....... [100%]\n=============================== warnings summary ===============================\ntests/test_dashboard_auth_server.py:11\n /opt/data/gitea-agent/repositories/jsfamily/jarca-ledger-mcp/worktrees/issue-12/checkout/tests/test_dashboard_auth_server.py:11: StarletteDeprecationWarning: Using `httpx` with `starlette.testclient` is deprecated; install `httpx2` instead.\n from starlette.testclient import TestClient\n\n-- Docs: https://docs.pytest.org/en/stable/how-to/capture-warnings.html\n291 passed, 4 skipped, 1 warning in 140.26s (0:02:20)\n","purpose":"Run the canonical full repository suite at the functional source revision","started_at_utc":"2026-10-07T22:10:39.167246Z"},{"argv":["uv","run","--frozen","--extra","dev","--extra","dashboard","ruff","check","."],"claim_ids":["review66-ruff"],"duration_seconds":0.8703100401908159,"exit_code":0,"expected_exit_code":0,"finished_at_utc":"2026-10-07T22:13:06.980053Z","id":"review66-ruff","max_output_bytes":65536,"output":"All checks passed!\n","purpose":"Run repository lint checks","started_at_utc":"2026-10-07T22:13:06.109877Z"},{"argv":["uv","run","--frozen","--extra","dev","--extra","dashboard","python","-m","compileall","-q","jarca_ledger_mcp","dashboard","tests","scripts"],"claim_ids":["review66-compileall"],"duration_seconds":0.8389266040176153,"exit_code":0,"expected_exit_code":0,"finished_at_utc":"2026-10-07T22:13:07.819027Z","id":"review66-compileall","max_output_bytes":65536,"output":"","purpose":"Compile package, dashboard, tests, and scripts","started_at_utc":"2026-10-07T22:13:06.980288Z"},{"argv":["git","diff","--check","main...HEAD"],"claim_ids":["review66-diff-check"],"duration_seconds":0.7061800975352526,"exit_code":0,"expected_exit_code":0,"finished_at_utc":"2026-10-07T22:13:08.525376Z","id":"review66-diff-check","max_output_bytes":65536,"output":"","purpose":"Check the complete pull-request diff for whitespace errors","started_at_utc":"2026-10-07T22:13:07.819274Z"}],"environment":{"architecture":"aarch64","kernel":"6.18.34+rpt-rpi-v8","os":"Linux","python":"3.13.5","uv":"uv 0.11.6 (aarch64-unknown-linux-musl)"},"excluded_paths":["docs/verification/issue-12-review-66/evidence-plan.json","docs/verification/issue-12-review-66/evidence-manifest.json"],"files":[{"blob_oid":"6cc90ce4358ab6241baf9cde7a783439b312166d","path":"jarca_ledger_mcp/application/accounts_write_services.py","sha256":"fb95381201beb100ed15960e1f066eee33d040a5f64c220bb257cb1e91abfb0d"},{"blob_oid":"0dfd7b7ce94a699b855e40b336afa7bf5cdc2595","path":"jarca_ledger_mcp/application/account_valuation_service.py","sha256":"f7f5bac1e224401dfd02efb321b7e7bd87e02875b727a5366bcc223bf633fb57"},{"blob_oid":"31e00a4ee69b188432659ab73878adf8b0c27992","path":"tests/test_import_current_balance_authority.py","sha256":"151b522879ee06c118f9be8f0f226c7b3503857d083b0fa1c49fdc2b3e1cac02"},{"blob_oid":"8433866ca0eb5dcf512b6e84e23931b37f1035f8","path":"tests/test_account_basis_public_consumers.py","sha256":"1b719d3318d376c69ca0f0af39e2d6027b0e3b46b136ce8079bec856ef7871af"},{"blob_oid":"690b2fbee633eecbfdb2d7ed8fda78cea1b14b96","path":"tests/test_issue_12_review63_accounts.py","sha256":"9004db79795ef4963b87646e9b5c486c073febd3ae6c2ba313633574e03582a9"},{"blob_oid":"0b08cb32af63084225e01642d333ca291c7445c4","path":"tests/test_account_valuation_edge_contracts.py","sha256":"fed17aec3518e2380d00b46252402ad69a71e7d265961a6264b03d790d579f42"},{"blob_oid":"1e18454fbde9ebc58a6ae98cd3f7dbe8ba665cc5","path":"tests/test_account_valuations.py","sha256":"aa3f831acba0317b6f49764042927026715ff5f6e729b945a22aa2b13490a6bf"},{"blob_oid":"83c76f65ad122e8409abd3420c97b4c375e144d5","path":"tests/test_issue_12_regressions.py","sha256":"7dc8fbd7a7b0cb718de115f4d1f69b2e024cf1af641573e4cb04c00196017f29"},{"blob_oid":"7234106e986eb528ef12e60a915a403fd2db6eff","path":"docs/data-model.md","sha256":"39e94f245d2934b68c968844cfcb565110f39732d8a32550644c95fb837b41c7"},{"blob_oid":"4304427a604949b8295b4f93cb6054357805fe92","path":"docs/interface-contract.md","sha256":"01a3f37e23ee17b2b928b44e3e07d4d6982faead1ab6f0298889225b0c5ce916"},{"blob_oid":"2a7be4d780999fce47402f15f0b05d0b92990715","path":"docs/requirements/req-003_account-valuation-history.md","sha256":"f5a3bf9f69d622451a1a08854062218382f03355a3464538a35b1e270ca5b70f"}],"generated_at":"2026-10-07T22:13:08.652602Z","limitations":["Four PDF fixture tests are skipped because private KB Bank and Toss Securities PDF fixtures are unavailable."],"plan":{"path":"docs/verification/issue-12-review-66/evidence-plan.json","sha256":"e5d10f27e58e809944ddde2d661b6118481174798410b11c1336c3545e1162c5"},"redaction":{"checked":true,"violations":[]},"result":"success","schema":"evidence-manifest/v1","source_revision":"63fba3670c536824f91b59262d60240bdfb0db94","source_tree_clean":true} diff --git a/docs/verification/issue-12-review-66/evidence-plan.json b/docs/verification/issue-12-review-66/evidence-plan.json deleted file mode 100644 index 7e280c9..0000000 --- a/docs/verification/issue-12-review-66/evidence-plan.json +++ /dev/null @@ -1,64 +0,0 @@ -{ - "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 deleted file mode 100644 index 905d22e..0000000 --- a/docs/verification/issue-12-review-66/finding-matrix.json +++ /dev/null @@ -1,24 +0,0 @@ -{ - "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 deleted file mode 100644 index 45299b4..0000000 --- a/docs/verification/issue-12-review-66/red-evidence.json +++ /dev/null @@ -1,23 +0,0 @@ -{ - "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" -} diff --git a/jarca_ledger_mcp/application/assets_service.py b/jarca_ledger_mcp/application/assets_service.py index f3bb109..660c674 100644 --- a/jarca_ledger_mcp/application/assets_service.py +++ b/jarca_ledger_mcp/application/assets_service.py @@ -328,6 +328,32 @@ def _snapshot_rows_for_latest_run(conn: sqlite3.Connection, basis_date: str) -> rows = conn.execute("SELECT rowid AS _rowid, * FROM asset_snapshots WHERE basis_date=? ORDER BY created_at ASC, name ASC", (basis_date,)).fetchall() run = conn.execute("SELECT * FROM asset_snapshot_runs WHERE basis_date=? ORDER BY rowid DESC LIMIT 1", (basis_date,)).fetchone() if not run: + legacy_run_rows = [row for row in rows if row["closed_at"] and row["snapshot_run_id"]] + if legacy_run_rows: + # Schema 11 persisted run identity only on the snapshot rows. Keep + # its rowid-based latest-run rule rather than falling back to live + # authority merely because schema 12 has no matching run record. + latest = max( + legacy_run_rows, + key=lambda row: ( + int(row["_rowid"]), + row["closed_at"] or row["created_at"] or "", + row["snapshot_run_id"], + ), + ) + latest_run_id = latest["snapshot_run_id"] + latest_rows = [row for row in legacy_run_rows if row["snapshot_run_id"] == latest_run_id] + return latest_rows, { + "snapshot_run_id": latest_run_id, + "legacy_closed": True, + "is_correction": bool(latest["is_correction"]), + "correction_of_run_id": latest["correction_of_run_id"] or "", + "correction_reason": latest["correction_reason"] or "", + "close_status": "legacy_read_only", + "selection_policy": latest["selection_policy"] or "exact", + "closed_at": latest["closed_at"] or latest["created_at"] or "", + "total_snapshot_rows_for_basis_date": len(rows), + } return rows, {"snapshot_run_id": "", "is_correction": False, "correction_of_run_id": "", "correction_reason": "", "total_snapshot_rows_for_basis_date": len(rows)} if rows else {} return _snapshot_rows_for_run(conn, run["id"]) @@ -403,7 +429,7 @@ def _closed_run_metadata(metadata: dict[str, Any]) -> dict[str, Any]: "snapshot_run_id": metadata.get("snapshot_run_id", ""), "close_status": metadata.get("close_status", ""), "selection_policy": metadata.get("selection_policy", ""), - "approval": {k: metadata.get(k, "") for k in ("approved_by", "approved_at", "approval_reason", "approval_reference")}, + "approval": {} if metadata.get("legacy_closed") else {k: metadata.get(k, "") for k in ("approved_by", "approved_at", "approval_reason", "approval_reference")}, "correction": {k: metadata.get(k, "") for k in ("is_correction", "correction_of_run_id", "correction_reason")}, } @@ -949,16 +975,19 @@ def get_asset_snapshot_report(basis_date: str = "", db_path: str | None = None, if close_metadata.get("evidence_integrity_error"): return fail("data_integrity_error", "snapshot evidence is malformed", snapshot_run_id=close_metadata.get("snapshot_run_id", "")) has_close_run = bool(close_metadata.get("snapshot_run_id")) + legacy_closed = bool(close_metadata.get("legacy_closed")) snapshots = _snapshot_items(conn, basis) if rows else [] legacy_snapshots = snapshots if rows and not has_close_run else [] - if has_close_run: + if has_close_run or legacy_closed: run_public = _closed_run_metadata(close_metadata) run_public["warnings"] = _closed_warnings(close_metadata, basis, rows) + if legacy_closed: + run_public["approval"] = {} summary = _summarize_valuation_items(snapshots, run_public["excluded_items"]) evidence_provenance = _evidence_provenance(close_metadata.get("applied_evidence", []), basis) return _ok_with_provenance_aliases( basis_date=basis, - source="asset_snapshots", + source="legacy_asset_snapshots" if legacy_closed else "asset_snapshots", is_closed_snapshot=True, snapshot_run_id=close_metadata.get("snapshot_run_id", ""), snapshot_count=len(snapshots), diff --git a/tests/test_legacy_snapshot_migration.py b/tests/test_legacy_snapshot_migration.py new file mode 100644 index 0000000..a6b1537 --- /dev/null +++ b/tests/test_legacy_snapshot_migration.py @@ -0,0 +1,146 @@ +from __future__ import annotations + +import hashlib +import sqlite3 +from pathlib import Path + +from jarca_ledger_mcp import service +from jarca_ledger_mcp.db import init_db + + +BASIS = "2026-06-30" + + +def _legacy_closed_db(tmp_path): + path = str(tmp_path / "legacy.sqlite3") + init_db(path) + asset = service.create_manual_asset("legacy cash", 100, "2026-06-01", "cash", db_path=path)["manual_asset"] + with sqlite3.connect(path) as conn: + # These are schema-11 close rows after the additive schema-12 migration: + # run identity is absent, but row close/correction fields remain frozen. + conn.execute( + """INSERT INTO asset_snapshots + (id, basis_date, source_type, source_id, name, amount, liquidity_bucket, + valuation_source, snapshot_run_id, correction_of_run_id, correction_reason, + is_correction, closed_at, created_at) + VALUES (?, ?, 'manual_asset', ?, ?, 100, 'cash', 'manual_assets', 'legacy-run-correction', + 'legacy-initial', 'legacy correction', 1, '2026-06-30T12:00:00+09:00', + '2026-06-30T12:00:00+09:00')""", + ("legacy-row", BASIS, asset["id"], asset["name"]), + ) + conn.execute("DROP TABLE asset_snapshot_runs") + conn.execute("UPDATE schema_meta SET value='11' WHERE key='schema_version'") + init_db(path) + with sqlite3.connect(path) as conn: + assert conn.execute("SELECT COUNT(*) FROM asset_snapshot_runs").fetchone()[0] == 0 + return path, asset["id"] + + +def test_schema11_closed_rows_remain_frozen_after_live_value_and_date_change(tmp_path): + path, asset_id = _legacy_closed_db(tmp_path) + service.update_manual_asset(asset_id, valuation_amount=900, valuation_date="2026-06-30", db_path=path) + before = hashlib.sha256(Path(path).read_bytes()).hexdigest() + + report = service.get_asset_snapshot_report(BASIS, db_path=path) + + after = hashlib.sha256(Path(path).read_bytes()).hexdigest() + + assert report["success"] is True + assert report["source"] == "legacy_asset_snapshots" + assert report["is_closed_snapshot"] is True + assert report["close_status"] == "legacy_read_only" + assert report["net_worth"] == 100 + assert report["included_items"][0]["amount"] == 100 + assert report["correction"] == { + "is_correction": True, + "correction_of_run_id": "legacy-initial", + "correction_reason": "legacy correction", + } + assert report["snapshot_run_id"] == "legacy-run-correction" + assert report["approval"] == {} + assert "valuation_id" not in report["included_items"][0] + assert after == before + + +def test_schema11_closed_rows_are_frozen_in_timeseries(tmp_path): + path, asset_id = _legacy_closed_db(tmp_path) + service.update_manual_asset(asset_id, valuation_amount=900, valuation_date="2026-07-01", db_path=path) + + point = service.get_net_worth_timeseries(BASIS, BASIS, db_path=path)["points"][0] + + assert point["net_worth"] == 100 + assert point["item_count"] == 1 + assert point["close_status"] == "legacy_read_only" + assert point["snapshot_run_id"] == "legacy-run-correction" + assert point["approval"] == {} + assert point["correction"] == { + "is_correction": True, + "correction_of_run_id": "legacy-initial", + "correction_reason": "legacy correction", + } + + +def test_schema11_closed_rows_are_frozen_in_monthly_settlement(tmp_path): + path, asset_id = _legacy_closed_db(tmp_path) + service.update_manual_asset(asset_id, valuation_amount=900, valuation_date="2026-07-01", db_path=path) + + monthly = service.get_monthly_settlement_summary("2026-06", db_path=path) + assets = monthly["reports"]["assets"] + coverage = monthly["source_coverage"]["assets"] + + assert assets["net_worth"] == 100 + assert assets["is_closed_snapshot"] is True + assert coverage["net_worth"] == 100 + assert coverage["is_closed_snapshot"] is True + assert coverage["monthly_source_snapshot_id"] == "legacy-run-correction" + assert assets["approval"] == {} + assert coverage["approval"] == {} + assert coverage["correction"] == assets["correction"] + + +def test_schema11_latest_legacy_correction_run_is_selected_as_a_complete_group(tmp_path): + path = str(tmp_path / "legacy-corrections.sqlite3") + init_db(path) + with sqlite3.connect(path) as conn: + rows = [ + ("old-a", "legacy-run-1", "", "", 0, "2026-06-30T10:00:00+09:00", 40), + ("old-b", "legacy-run-1", "", "", 0, "2026-06-30T10:00:00+09:00", 60), + ("new-a", "legacy-run-2", "legacy-run-1", "correct frozen close", 1, "2026-07-01T10:00:00+09:00", 70), + ("new-b", "legacy-run-2", "legacy-run-1", "correct frozen close", 1, "2026-07-01T10:00:00+09:00", 80), + ] + for row_id, run_id, prior, reason, correction, closed_at, amount in rows: + conn.execute( + """INSERT INTO asset_snapshots + (id, basis_date, source_type, source_id, name, amount, currency, + liquidity_bucket, valuation_source, snapshot_run_id, + correction_of_run_id, correction_reason, is_correction, + closed_at, created_at) + VALUES (?, ?, 'manual_asset', ?, ?, ?, 'KRW', 'cash', + 'manual_assets', ?, ?, ?, ?, ?, ?)""", + (row_id, BASIS, row_id, row_id, amount, run_id, prior, reason, + correction, closed_at, closed_at), + ) + conn.execute("DROP TABLE asset_snapshot_runs") + conn.execute("UPDATE schema_meta SET value='11' WHERE key='schema_version'") + init_db(path) + with sqlite3.connect(path) as conn: + assert conn.execute("SELECT COUNT(*) FROM asset_snapshot_runs").fetchone()[0] == 0 + + before = hashlib.sha256(Path(path).read_bytes()).hexdigest() + report = service.get_asset_snapshot_report(BASIS, db_path=path) + after = hashlib.sha256(Path(path).read_bytes()).hexdigest() + + assert report["success"] is True + assert report["source"] == "legacy_asset_snapshots" + assert report["snapshot_run_id"] == "legacy-run-2" + assert report["snapshot_count"] == 2 + assert [item["id"] for item in report["included_items"]] == ["new-a", "new-b"] + assert report["net_worth"] == 150 + assert report["correction"] == { + "is_correction": True, + "correction_of_run_id": "legacy-run-1", + "correction_reason": "correct frozen close", + } + assert report["approval"] == {} + assert all("valuation_id" not in item for item in report["included_items"]) + assert after == before