Add BAT-014 browser evidence artifacts

This commit is contained in:
Jarca
2026-07-03 10:07:16 +09:00
parent f42bc4aa7d
commit c8777d8ba4
12 changed files with 1722 additions and 11 deletions
Binary file not shown.

After

Width:  |  Height:  |  Size: 292 KiB

@@ -0,0 +1,74 @@
{
"success": true,
"base_url": "http://127.0.0.1:18501",
"output_dir": "/root/projects/jarca-ledger-mcp/docs/batches/bat-014_20260703_adapter-surface-narrowing-baseline-refresh/evidence/run-20260703-100358",
"fixture": {
"account_id": "acct_2e22ac8ac63a",
"transaction_ids": [
"tx_14dd02c2fe6c",
"tx_8a75d20fcd87",
"tx_88bdacc43404",
"tx_c0418db6d784",
"tx_7b21f4085a1d"
],
"db_path": "docs/batches/bat-014_20260703_adapter-surface-narrowing-baseline-refresh/evidence/run-20260703-100358/fixture.sqlite3"
},
"chrome": "/usr/bin/google-chrome-stable",
"streamlit": ".venv/bin/streamlit",
"pages": [
{
"page": "요약",
"url": "http://127.0.0.1:18501/?page=%EC%9A%94%EC%95%BD",
"screenshot": "docs/batches/bat-014_20260703_adapter-surface-narrowing-baseline-refresh/evidence/run-20260703-100358/overview.png",
"screenshot_bytes": 340145,
"snapshot": "docs/batches/bat-014_20260703_adapter-surface-narrowing-baseline-refresh/evidence/run-20260703-100358/overview.dom.html",
"snapshot_bytes": 31902,
"devtools_port": 19222,
"inner_text_head": "💰 Jarca Ledger\n\n가계부 · 분류 · Import 운영 콘솔\n\n메뉴\n요약\n자산/마감\n거래내역\n확인필요 큐\n미분류\n분류 규칙\n카테고리\n계좌\nImport\n\n새로고침\n\nStop\nDeploy\n📊 요약\n가계부 운영 대시보드\n\n이번 달 실제 현금흐름, 자산 유동성, 운영 경고를 우선순위대로 확인합니다.\n\nschema v10\nKST 이번 달\nlast_balance 기준 자산\n\nDB: /root/projects/jarca-ledger-mcp/docs/batches/bat-014_20260703_adapter-surface-narrowing-baseline-refresh/evidence/run-20260703-100358/fixture.sqlite3\n\n💎\n이번 달 수입/지출 현황\n\n기준: KST 현재 월 2026-07, transactions.transaction_date, ledger_categories.cashflow_kind 실제 현금흐름\n\n실제 수입\n\n0원\n\n실제 지출\n\n0원\n\n순"
},
{
"page": "분류 규칙",
"url": "http://127.0.0.1:18501/?page=%EB%B6%84%EB%A5%98%20%EA%B7%9C%EC%B9%99",
"screenshot": "docs/batches/bat-014_20260703_adapter-surface-narrowing-baseline-refresh/evidence/run-20260703-100358/rules.png",
"screenshot_bytes": 366052,
"snapshot": "docs/batches/bat-014_20260703_adapter-surface-narrowing-baseline-refresh/evidence/run-20260703-100358/rules.dom.html",
"snapshot_bytes": 165223,
"devtools_port": 19223,
"inner_text_head": "💰 Jarca Ledger\n\n가계부 · 분류 · Import 운영 콘솔\n\n메뉴\n요약\n자산/마감\n거래내역\n확인필요 큐\n미분류\n분류 규칙\n카테고리\n계좌\nImport\nStop\nDeploy\n⚙️ Rule Engine\n분류 규칙\n\n반복되는 사용처와 거래 패턴을 규칙으로 관리해 분류 자동화 품질을 높입니다.\n\n자동 분류\nPreview\nSeed/Update\nkeyboard_arrow_right\n\n🟢 환급 · merchant/contains → 수입 / 환급 · p10 · income\n\nkeyboard_arrow_right\n\n🟢 급여 · merchant/contains → 수입 / 급여 · p10 · income\n\nkeyboard_arrow_right\n\n🟢 이자 · merchant/contains → 수입 / 이자 · p10 · income\n\nkeyboard_arrow_right\n\n🟢 국민카드 · raw_summary/equals → 금융 / 카드대금 · p20 · expense\n\nkeyboard"
},
{
"page": "확인필요 큐",
"url": "http://127.0.0.1:18501/?page=%ED%99%95%EC%9D%B8%ED%95%84%EC%9A%94%20%ED%81%90",
"screenshot": "docs/batches/bat-014_20260703_adapter-surface-narrowing-baseline-refresh/evidence/run-20260703-100358/transfer-review.png",
"screenshot_bytes": 303427,
"snapshot": "docs/batches/bat-014_20260703_adapter-surface-narrowing-baseline-refresh/evidence/run-20260703-100358/transfer-review.dom.html",
"snapshot_bytes": 25158,
"devtools_port": 19224,
"inner_text_head": "💰 Jarca Ledger\n\n가계부 · 분류 · Import 운영 콘솔\n\n메뉴\n요약\n자산/마감\n거래내역\n확인필요 큐\n미분류\n분류 규칙\n카테고리\n계좌\nImport\n\n새로고침\n\nStop\nDeploy\n🔁 Transfer Review\nKB↔토스뱅크 확인필요 큐\n\n날짜·금액·상대 기준으로 계좌 간 이동 후보를 대조하고, 드라이런 후 안전하게 매칭합니다.\n\n드라이런 우선\n본인계좌이동\n수동 검토\n\n미리보기(드라이런)\n\n자동 매칭 실행\n\n📌\n확인필요 큐\n\n거래 ID: tx_7b21f4085a1d\n\n2026-06-29 · SYNTHETIC_TRANSFER · 120,000원"
},
{
"page": "Import",
"url": "http://127.0.0.1:18501/?page=Import",
"screenshot": "docs/batches/bat-014_20260703_adapter-surface-narrowing-baseline-refresh/evidence/run-20260703-100358/import.png",
"screenshot_bytes": 298860,
"snapshot": "docs/batches/bat-014_20260703_adapter-surface-narrowing-baseline-refresh/evidence/run-20260703-100358/import.dom.html",
"snapshot_bytes": 25118,
"devtools_port": 19225,
"inner_text_head": "💰 Jarca Ledger\n\n가계부 · 분류 · Import 운영 콘솔\n\n메뉴\n요약\n자산/마감\n거래내역\n확인필요 큐\n미분류\n분류 규칙\n카테고리\n계좌\nImport\nStop\nDeploy\n📥 Statement Import\nImport\n\nPDF/XLSX 거래내역을 먼저 Preview로 검증한 뒤 원장에 반영합니다.\n\nPreview 우선\n중복 skip\nImport 이력\n📈\n토스증권 거래내역 PDF 가져오기\n\n토스증권 거래내역서 PDF를 업로드하면 투자계좌 거래로 가져옵니다. 매수/매도/환전/입출금은 이체/투자이동, 배당/이자는 실제 수입으로 분류합니다.\n\n🏦\n토스뱅크 거래내역 PDF 가져오기\n\n토스뱅크 계좌 거래내역 PDF를 업로드하면 입출금/이체/카드결제를 가져옵니다. 타인 이체/출금은 이체/확인필요로 분류됩니다.\n\n🧾\nImport 이력"
}
],
"server_command": [
".venv/bin/streamlit",
"run",
"dashboard/app.py",
"--server.address",
"127.0.0.1",
"--server.port",
"18501",
"--server.headless",
"true",
"--browser.gatherUsageStats",
"false"
],
"server_log_tail": ""
}
Binary file not shown.

After

Width:  |  Height:  |  Size: 358 KiB

@@ -4,7 +4,7 @@
Status: PASS
All required code-path checks for BAT-014 passed. A manual local browser-evidence launch was attempted but blocked by the runtime’s consent guard for long-running local server startup, so the close-out evidence uses AppTest + full pytest + MCP discovery + structural call-site verification. No production ledger DB or real financial files were used.
All required code-path checks for BAT-014 passed, and local browser-level screenshot/DOM evidence was successfully captured against a synthetic fixture DB. No production ledger DB, real financial statement files, passwords, or raw financial payloads were used.
## Acceptance criteria evidence
@@ -18,26 +18,57 @@ All required code-path checks for BAT-014 passed. A manual local browser-evidenc
- `search_files(pattern='service\\.', path='dashboard', file_glob='app.py')` returned 0 matches after rewiring.
- Dynamic hot-reload lookup now targets passed gateway modules (`categorization_gateway`, `transfers_gateway`) instead of a flat `service` binding.
### AC-3. Regression and adapter verification pass
### AC-3. Regression, adapter verification, and browser smoke pass
- `python3 -m py_compile jarca_ledger_mcp/adapters/mcp/*.py jarca_ledger_mcp/adapters/streamlit/*.py dashboard/app.py` → PASS
- `pytest -q tests/test_dashboard_app.py` → PASS (`....`)
- `pytest -q` → PASS (`........................ss...............ss...`)
- `hermes mcp test jarca-ledger` → PASS, 56 tools discovered
- `.venv/bin/python scripts/streamlit_browser_evidence.py` → PASS
- Output dir: `docs/batches/bat-014_20260703_adapter-surface-narrowing-baseline-refresh/evidence/run-20260703-100358/`
- Artifacts: `overview.png`, `rules.png`, `transfer-review.png`, `import.png` plus matching `*.dom.html` and `manifest.json`
- Cleanup check: `search_files('chrome-profile-*')` under the run dir returned 0 results after the retry-cleanup fix
### AC-4. Baseline docs and discovery metadata reflect completion
### AC-4. Baseline docs, discovery metadata, and BAT-local evidence tooling reflect completion
- Evidence:
- `docs/project-structure.md` updated with new owning services, parser seam, MCP contract helper, and Streamlit page/domain gateways.
- `docs/runtime-flows.md` updated with import/parser seam, MCP contract routing, and dashboard gateway flow.
- `docs/runbooks/streamlit-browser-evidence.md` now points at the BAT-014 evidence root and includes `요약` in the default capture set.
- dcy-011 metadata and close-out notes updated to reference `REQ-015`~`REQ-018` / `BAT-011`~`BAT-014` completion.
## Browser evidence note
## Browser evidence details
- Attempted: synthetic local dashboard browser/HTTP smoke.
- Result: blocked by terminal consent guard for long-running local server startup in this session.
- Impact: none on code correctness regression; AppTest remained green and no UI functional regression was detected in test coverage.
Evidence source: `docs/batches/bat-014_20260703_adapter-surface-narrowing-baseline-refresh/evidence/run-20260703-100358/manifest.json`
### Captured pages
- `요약`
- Screenshot: `overview.png`
- DOM: `overview.dom.html`
- Evidence text included `📊 요약`, `가계부 운영 대시보드`, and the synthetic fixture DB path under the BAT-014 evidence directory.
- `분류 규칙`
- Screenshot: `rules.png`
- DOM: `rules.dom.html`
- Evidence text included `⚙️ Rule Engine`, `분류 규칙`, and seeded default categorization rules.
- `확인필요 큐`
- Screenshot: `transfer-review.png`
- DOM: `transfer-review.dom.html`
- Evidence text included `🔁 Transfer Review`, `KB↔토스뱅크 확인필요 큐`, and a synthetic transfer-review row for `2026-06-29` / `SYNTHETIC_TRANSFER` / `120,000원` / `이체` / `확인필요`.
- `Import`
- Screenshot: `import.png`
- DOM: `import.dom.html`
- Evidence text included `📥 Statement Import`, Toss Securities import copy, and Toss Bank import copy.
### Automation script close-out
- Script: `scripts/streamlit_browser_evidence.py`
- Behavior:
- Generates a synthetic fixture DB under the BAT-014 evidence run directory.
- Starts Streamlit against that fixture DB only.
- Uses local Chrome DevTools Protocol to capture screenshots and DOM snapshots.
- Writes `manifest.json` with page/url/path/byte-size evidence.
- Retries Chrome profile cleanup and leaves only the intended evidence artifacts in the final run directory.
## Safety boundary
- Synthetic/temp DBs only.
- No destructive migration.
- No production ledger DB mutation.
- No real statement files, passwords, or raw payloads in screenshots, DOM snapshots, or manifest output.
+4 -1
View File
@@ -14,9 +14,11 @@ cd /root/projects/jarca-ledger-mcp
기본 산출물 위치:
```text
docs/batches/bat-004_20260629_browser-streamlit-e2e-evidence/evidence/run-YYYYMMDD-HHMMSS/
docs/batches/bat-014_20260703_adapter-surface-narrowing-baseline-refresh/evidence/run-YYYYMMDD-HHMMSS/
├── fixture.sqlite3
├── manifest.json
├── overview.png
├── overview.dom.html
├── rules.png
├── rules.dom.html
├── transfer-review.png
@@ -45,6 +47,7 @@ docs/batches/bat-004_20260629_browser-streamlit-e2e-evidence/evidence/run-YYYYMM
기본 대상:
- `요약`
- `분류 규칙`
- `확인필요 큐`
- `Import`
+14 -3
View File
@@ -29,10 +29,10 @@ import websockets
from jarca_ledger_mcp import service
from jarca_ledger_mcp.db import init_db
DEFAULT_PAGES = ["분류 규칙", "확인필요 큐", "Import"]
DEFAULT_PAGES = ["요약", "분류 규칙", "확인필요 큐", "Import"]
DEFAULT_CHROME = "/usr/bin/google-chrome-stable"
DEFAULT_STREAMLIT = Path(".venv/bin/streamlit")
DEFAULT_OUTPUT_ROOT = Path("docs/batches/bat-004_20260629_browser-streamlit-e2e-evidence/evidence")
DEFAULT_OUTPUT_ROOT = Path("docs/batches/bat-014_20260703_adapter-surface-narrowing-baseline-refresh/evidence")
def parse_args() -> argparse.Namespace:
@@ -181,6 +181,16 @@ def wait_for_devtools(port: int, timeout_seconds: int = 15) -> str:
raise SystemExit(f"Chrome DevTools endpoint did not become ready on port {port}: {last_error}")
def remove_tree_with_retries(path: Path, attempts: int = 5, delay_seconds: float = 0.5) -> None:
for attempt in range(1, attempts + 1):
shutil.rmtree(path, ignore_errors=True)
if not path.exists():
return
time.sleep(delay_seconds * attempt)
if path.exists():
raise SystemExit(f"temporary Chrome profile cleanup failed: {path}")
class CdpClient:
def __init__(self, ws: websockets.ClientConnection) -> None:
self.ws = ws
@@ -265,7 +275,8 @@ def capture_page(chrome: str, base_url: str, page: str, output_dir: Path, devtoo
chrome_proc.wait(timeout=8)
except subprocess.TimeoutExpired:
chrome_proc.kill()
shutil.rmtree(profile_dir, ignore_errors=True)
chrome_proc.wait(timeout=5)
remove_tree_with_retries(profile_dir)
if not screenshot.exists() or screenshot.stat().st_size <= 0:
raise SystemExit(f"Screenshot was not created for {page}: {screenshot}")