69 lines
4.4 KiB
JSON
69 lines
4.4 KiB
JSON
{
|
|
"schema": "jarca.issue9.evidence-manifest.v2",
|
|
"issue": "jsfamily/jarca-ledger-mcp#9",
|
|
"captured_at": "2026-10-05T08:17:17.108Z",
|
|
"source": {
|
|
"git_head_base": "a02aceee416c5770dfd1f35ac94367f3c4e0c8c8",
|
|
"working_tree": true,
|
|
"files_sha256": {
|
|
"dashboard/app.py": "4c7b3a6264b4fb4ae0e445ddc04c625b295443816b198aa5a60615ac44846ff2",
|
|
"dashboard/common.py": "9a0b9dbb4ca88f27757fc293173821c48a56a30bc23f16b0f24731f246411c5a",
|
|
"scripts/streamlit_browser_evidence.py": "3cfb449ce1d6fae3abb795727d7ca1bc10dbb759bb811f121abd74fa42993dd7",
|
|
"tests/test_dashboard_menu_transition.py": "d23c35d88f6289b7c7e84a271df6ff3f6ff1f25a3a885aa696cc93db0b37035e",
|
|
"tests/test_streamlit_browser_evidence.py": "7f595ccf4009961225328486c19258bb0f7bc7dbfb584c60616860274112724a"
|
|
}
|
|
},
|
|
"execution": {
|
|
"browser_tool": "mcp__playwright__browser_evaluate + mcp__playwright__browser_run_code_unsafe",
|
|
"tool_status": "success",
|
|
"exit_code": null,
|
|
"exit_code_note": "Playwright MCP reports success/error instead of a numeric process exit code.",
|
|
"transition": "요약 -> 분류 규칙",
|
|
"sampling_interval_ms": 50,
|
|
"frame_count": 35,
|
|
"viewport": {
|
|
"width": 1280,
|
|
"height": 720
|
|
},
|
|
"browser": "HeadlessChrome/154.0.0.0",
|
|
"browser_architecture": {
|
|
"client_hint_architecture": "arm",
|
|
"client_hint_bitness": "64",
|
|
"navigator_platform": "Linux x86_64"
|
|
},
|
|
"fixture_host_architecture": "aarch64",
|
|
"python": "3.13.5",
|
|
"streamlit": "1.58.0",
|
|
"uvicorn": "0.49.0"
|
|
},
|
|
"checks": {
|
|
"document_identity_stable": true,
|
|
"sidebar_identity_stable": true,
|
|
"app_surface_background_stable": true,
|
|
"sidebar_surface_background_stable": true,
|
|
"app_surface_visible_all_frames": true,
|
|
"sidebar_surface_visible_all_frames": true,
|
|
"surface_backgrounds_observed": true,
|
|
"zero_full_document_loads": true,
|
|
"loading_observed": true,
|
|
"previous_body_absent_while_loading": true,
|
|
"query_sibling_preserved": true,
|
|
"final_agreement": true
|
|
},
|
|
"artifacts_sha256": {
|
|
"browser-observations.json": "414b62efb2f40483aae4227896040c1b5d887b2c31333f63046e6f34aec2fe8f",
|
|
"final-state.jpg": "cc4e1c28463f033ab1c26d1dc27c9bb93c6fc5495321c0cef73fdb1098221234"
|
|
},
|
|
"validator": {
|
|
"command": "python3 -c \"import hashlib,json,math,pathlib; r=pathlib.Path('.'); e=r/'docs/evidence/issue-9-dashboard-menu-transition'; m=json.loads((e/'manifest.json').read_text()); d=json.loads((e/'browser-observations.json').read_text()); frames=d['frames']; surfaces=('stAppViewContainer','stSidebar'); assert all(hashlib.sha256((r/p).read_bytes()).hexdigest()==h for p,h in m['source']['files_sha256'].items()); assert all(hashlib.sha256((e/p).read_bytes()).hexdigest()==h for p,h in m['artifacts_sha256'].items()); assert all(d['checks'].values()) and not d['document_load_events'] and len(frames)==35; assert all(isinstance(f['previous_body_visible'],bool) for f in frames); assert any(f['loading'] and f['previous_body_visible'] is False for f in frames); valid=lambda x: isinstance(x,dict) and str(x.get('backgroundImage','')).strip().lower() not in ('','none') and bool(str(x.get('backgroundColor','')).strip()) and x.get('visibility')=='visible' and x.get('display')!='none' and math.isfinite(float(x.get('opacity','nan'))) and float(x['opacity'])>0 and x.get('rendered') is True; assert all(valid(f['surfaces'][s]) for f in frames for s in surfaces); ss=d['stable_shell']; assert all(isinstance(ss[k]['pre'],str) and ss[k]['pre'] and ss[k]['pre']==ss[k]['post'] for k in ('document_marker','sidebar_marker','background')); assert ss['surfaces']['pre']==frames[0]['surfaces'] and ss['surfaces']['post']==d['post']['surfaces'] and ss['surfaces']['pre']==ss['surfaces']['post']; print('PASS source_hashes=5 artifact_hashes=2 checks=12/12 frames=%d full_document_loads=0 surfaces=2' % len(frames))\"",
|
|
"exit_code": 0,
|
|
"output": "PASS source_hashes=5 artifact_hashes=2 checks=12/12 frames=35 full_document_loads=0 surfaces=2"
|
|
},
|
|
"limitations": [
|
|
"Generated synthetic SQLite fixture only; no operating ledger data was used.",
|
|
"A temporary HTTPS ingress adapter normalized the trusted request scheme for repository same-origin authentication.",
|
|
"The ephemeral tunnel URL is expired provenance and is not a rerun target.",
|
|
"The same-document no-load assertion is bound to the uninterrupted Playwright evaluation context, stable document marker, and empty document-load event record."
|
|
]
|
|
}
|