# BAT-002 Verification ## Verification Status - Status: approved - Ready for Release: true - Verified At (KST): 2026-06-27 10:33 - Verified By: 렛저장인 ## Acceptance Mapping ### REQ-002 AC1 Backup creation must write timestamped SQLite files under `/root/.local/share/jarca/backups/ledger/` by default and return source/backup path, size, mtime, sha256, integrity, and table counts. Evidence: - `service.create_ledger_backup` uses default `DEFAULT_LEDGER_BACKUP_DIR = ~/.local/share/jarca/backups/ledger` and returns `source_db`, `backup`, `retention`, and `restore_policy`. - `tests/test_backup_workflow.py::test_create_list_and_status_ledger_backup_with_retention` verifies backup file creation, sha256 presence, `integrity_check == "ok"`, and source/backup table count equality on synthetic DB. Result: pass. ### REQ-002 AC2 Retention keeps recent 30 days or newest 20 backup files and reports pruned paths. Evidence: - `_apply_backup_retention` prunes only backups that are both outside newest count and older than day cutoff. - `tests/test_backup_workflow.py::test_backup_retention_keeps_recent_count_and_prunes_older_extras` verifies retention with synthetic old backup files and checks `pruned_paths` length. Result: pass. ### REQ-002 AC3 Backup list/status/hash is additive service/MCP surface and existing response shapes are preserved. Evidence: - New service functions: `list_ledger_backups`, `get_ledger_backup_status`, `get_ledger_db_status`. - New MCP tools are additive in `server.py`. - `hermes mcp test jarca-ledger` result: connected, `Tools discovered: 45`, including `get_ledger_db_status`, `create_ledger_backup`, `list_ledger_backups`, `get_ledger_backup_status`. Result: pass. ### REQ-002 AC4 Restore execution is not MCP-exposed and is script/runbook only with explicit approval for overwrite. Evidence: - `server.py` contains no restore MCP tool. - `hermes mcp test jarca-ledger` discovered backup/status tools and no restore tool. - `scripts/ledger_restore_smoke.py` requires `--allow-overwrite --approval-token RESTORE_APPROVED` before overwriting an existing target. - `docs/runbooks/ledger-backup-restore.md` documents restore as script-only and warns not to target the live operating DB without explicit user approval. Result: pass. ### REQ-002 AC5 Validation uses synthetic fixture DB first; operating DB copy evidence is metadata-only if used. Evidence: - All tests use pytest `tmp_path` synthetic SQLite DBs. - Restore smoke command used `/tmp/.../fixture.sqlite3`, `/tmp/.../backups/...sqlite3`, and `/tmp/.../restored.sqlite3`. - No operating DB copy was needed. Result: pass. ### REQ-002 AC6 Baseline docs reflect backup/status/list/hash/restore restrictions and sensitive evidence policy. Evidence: - `docs/runtime-flows.md` adds operational backup/validation/restore smoke flow and restore non-MCP constraint. - `docs/data-model.md` adds `LedgerBackupArtifact` and metadata-only evidence notes. - `docs/interface-contract.md` adds backup/status tools and restore non-exposure compatibility rule. - `docs/runbooks/ledger-backup-restore.md` lists allowed/forbidden evidence and QC checklist. Result: pass. ### REQ-002 AC7 Synthetic tests verify backup/status/list/hash/retention/restore smoke or health/status check without operating DB mutation. Evidence: - Command: `source .venv/bin/activate && pytest -ra` - Result: `20 passed, 4 skipped in 16.02s`. - Command: synthetic restore smoke with `scripts/ledger_restore_smoke.py`. - Result: `success: true`, backup/target `integrity_check: ok`, matching table counts, `health_check.success: true`. Result: pass. ### REQ-002 AC8 QC gate must verify operating DB mutation absence, restore MCP non-exposure, sensitive evidence absence, smoke evidence, tests/docs. Evidence: - This verification document and runbook include QC checklist. - `jarcaledgerqc` QC gate returned `PASS`. - QC summary confirmed no operating DB restore/direct mutation, backup/status/list/hash policy compliance, no restore MCP tool, synthetic restore smoke success, no real sensitive evidence exposure, and tests/docs evidence. Result: pass. ## Evidence Summary - Syntax: `python -m py_compile jarca_ledger_mcp/*.py dashboard/app.py` -> exit 0. - Targeted tests: `pytest tests/test_backup_workflow.py -q` -> `3 passed`. - Full tests: `pytest -ra` -> implementer `20 passed, 4 skipped in 16.02s`; QC rerun `20 passed, 4 skipped in 14.14s`. - Restore smoke: synthetic tmp DB restore -> `success: true`, `integrity_check: ok`, table counts `{accounts: 1, transactions: 1, budgets: 0, import_batches: 0, category_rules: 0, ledger_categories: 0}`. - MCP surface: `hermes mcp test jarca-ledger` -> connected, `Tools discovered: 45`, backup/status tools present, no restore tool listed. ## Sensitive Evidence Review - No transaction row dumps, merchant/counterparty full dumps, account numbers, `raw_payload`, source financial files, or passwords were written into docs/tests/logs. - Synthetic test data contains placeholder sentinel labels only and asserts those labels are not serialized in status evidence. ## QC Gate Result - Verdict: PASS - Reviewer: jarcaledgerqc - Reviewed At (KST): 2026-06-27 10:33 - Summary: 검수관은 원본 운영 DB restore/direct mutation 없음, backup/status/list/hash 정책 정합성, restore MCP 비노출, synthetic restore smoke 성공, 민감정보 비노출, tests/docs evidence를 확인했다. - Notes: 실제 backup MCP 호출은 운영 DB mutation을 피하기 위해 수행하지 않았고, service-level synthetic DB 테스트와 smoke로 대체 검증했다. 이는 비차단 참고사항이다. ## Blocking Issues - None.