# BAT-008 Implementation ## Plan summary BAT-008 implemented the new valuation authority model in `service.py`/`db.py`, exposed read-only MCP tools in `server.py`, aligned the Streamlit overview with the shared valuation helper, and updated baseline docs to match the confirmed Discovery/REQ scope. ## Changed files - `jarca_ledger_mcp/db.py` - `SCHEMA_VERSION` → `9` - additive/idempotent tables: `manual_assets`, `asset_snapshots` - migration path updated so existing DBs create the new tables safely - `jarca_ledger_mcp/service.py` - shared valuation helpers for account/manual-asset/snapshot authority sources - new service APIs: `create_manual_asset`, `list_manual_assets`, `create_asset_snapshot`, `get_asset_snapshot_report`, `get_net_worth_timeseries` - `get_asset_liquidity_report` aligned to the same valuation policy while preserving REQ-005 fallback semantics - `jarca_ledger_mcp/server.py` - new read MCP tools: `list_manual_assets`, `get_asset_snapshot_report`, `get_net_worth_timeseries` - `get_asset_liquidity_report` contract text updated for shared valuation source behavior - `dashboard/app.py` - overview asset section now explains the valuation authority source and shows `manual_assets` rows when present - existing account-only fallback remains when new tables are empty - Documentation - `docs/data-model.md` - `docs/interface-contract.md` - `docs/runtime-flows.md` - `docs/project-structure.md` - Tests - new: `tests/test_asset_snapshots.py` - adjusted: `tests/test_service.py` ## Execution log - 2026-06-30 21:26 KST: BAT-008 standard batch scaffold created from approved REQ-009/REQ-010. - 2026-06-30 21:3x~21:4x KST: implementation landed in `db.py`, `service.py`, `server.py`, `dashboard/app.py`, docs, and regression tests via `jarcaledgerdev` handoff + local verification orchestration. - 2026-06-30 21:40 KST: targeted compile/test validation passed. - 2026-06-30 21:41 KST: MCP stdio contract smoke check passed and discovered the three new read tools. - 2026-06-30 21:42 KST: synthetic end-to-end service probe confirmed live-authority fallback, snapshot read behavior, and net-worth timeseries output. ## Validation ### Command 1 ```bash cd /root/projects/jarca-ledger-mcp source .venv/bin/activate python -m py_compile jarca_ledger_mcp/*.py dashboard/app.py pytest tests/test_asset_snapshots.py tests/test_service.py tests/test_contract_regression.py -q ``` Result: - `................. [100%]` - exit code `0` ### Command 2 ```bash cd /root/projects/jarca-ledger-mcp source .venv/bin/activate hermes mcp test jarca-ledger ``` Result: - stdio connection success - tools discovered: `51` - new BAT-008 read tools discovered: - `list_manual_assets` - `get_asset_snapshot_report` - `get_net_worth_timeseries` ### Command 3 ```bash cd /root/projects/jarca-ledger-mcp source .venv/bin/activate python - <<'PY' from tempfile import TemporaryDirectory from pathlib import Path from jarca_ledger_mcp import service with TemporaryDirectory() as td: db_path = str(Path(td) / 'ledger.sqlite3') service.create_ledger_account('현금', last_balance=1000000, last_synced_at='2026-06-30', liquidity_bucket='cash', db_path=db_path) service.create_ledger_account('투자', type='investment', last_balance=2000000, liquidity_bucket='investment', db_path=db_path) service.create_manual_asset('전세보증금', 300000000, '2026-06-30', 'real_estate', source_note='synthetic appraisal', db_path=db_path) service.create_manual_asset('주담대', 120000000, '2026-06-30', 'loan', source_note='synthetic loan balance', db_path=db_path) print(service.list_manual_assets(db_path=db_path)) print(service.get_asset_snapshot_report('2026-06-30', db_path=db_path)) service.create_asset_snapshot('2026-05-31', 'account', 'acct-a', '현금', 1000000, 'cash', source_note='synthetic', db_path=db_path) service.create_asset_snapshot('2026-05-31', 'manual_asset', 'manual-home', '부동산', 200000000, 'real_estate', source_note='synthetic', db_path=db_path) service.create_asset_snapshot('2026-05-31', 'manual_asset', 'manual-loan', '대출', 80000000, 'loan', source_note='synthetic', db_path=db_path) print(service.get_asset_snapshot_report('2026-05-31', db_path=db_path)) print(service.get_net_worth_timeseries(start_date='2026-05-01', end_date='2026-06-30', db_path=db_path)) PY ``` Key result excerpts: - `list_manual_assets` returned `count=2` and `authority_source='manual_assets'` - live fallback snapshot report returned `source='live_authority'`, `total_assets=303000000`, `total_liabilities=120000000`, `net_worth=183000000` - stored snapshot report returned `source='asset_snapshots'`, `snapshot_count=3`, `net_worth=121000000` - timeseries returned `points[0].basis_date='2026-05-31'`, `points[0].net_worth=121000000` ## Remaining risks / follow-up notes - Snapshot creation is intentionally service-only in BAT-008. MCP mutation exposure remains future scope by Discovery decision. - Manual-asset edit/delete workflows and month-end operator UX are still procedural/document-driven rather than exposed as first-class CRUD flows. - QC gate still needs to confirm REQ Implemented promotion before commit-stage handoff.