From 1ebc53d152159958039c43401b9693a335eb66a5 Mon Sep 17 00:00:00 2001 From: gitea-impl-agent Date: Mon, 5 Oct 2026 08:45:31 +0000 Subject: [PATCH] docs(evidence): bind PR 10 rework verification --- .../rework-verification-plan.json | 122 ++++++++++++++++++ .../rework-verification.json | 1 + 2 files changed, 123 insertions(+) create mode 100644 docs/evidence/issue-9-dashboard-menu-transition/rework-verification-plan.json create mode 100644 docs/evidence/issue-9-dashboard-menu-transition/rework-verification.json diff --git a/docs/evidence/issue-9-dashboard-menu-transition/rework-verification-plan.json b/docs/evidence/issue-9-dashboard-menu-transition/rework-verification-plan.json new file mode 100644 index 0000000..36bf446 --- /dev/null +++ b/docs/evidence/issue-9-dashboard-menu-transition/rework-verification-plan.json @@ -0,0 +1,122 @@ +{ + "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": [ + "docs/evidence/issue-9-dashboard-menu-transition/README.md", + "docs/evidence/issue-9-dashboard-menu-transition/browser-observations.json", + "docs/evidence/issue-9-dashboard-menu-transition/final-state.jpg", + "docs/evidence/issue-9-dashboard-menu-transition/manifest.json", + "docs/project-structure.md", + "docs/requirements/req-002_dashboard-menu-transition.md", + "docs/runtime-flow.md", + "scripts/streamlit_browser_evidence.py", + "tests/test_streamlit_browser_evidence.py" + ], + "commands": [ + { + "id": "full-suite", + "purpose": "Run the repository full test suite at the rework source revision", + "argv": [ + "uv", + "run", + "--extra", + "dashboard", + "--extra", + "dev", + "pytest" + ], + "expected_exit_code": 0, + "max_output_bytes": 65536, + "claims": [ + "full-suite-result" + ] + }, + { + "id": "browser-evidence-validator", + "purpose": "Validate checked-in authenticated browser evidence, source and artifact hashes", + "argv": [ + "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))" + ], + "expected_exit_code": 0, + "max_output_bytes": 8192, + "claims": [ + "browser-evidence-result" + ] + }, + { + "id": "documentation-inventory", + "purpose": "Validate canonical requirement and documentation remediation coverage", + "argv": [ + "python3", + "-c", + "from pathlib import Path\nimport re\nq=Path('docs/requirements/req-002_dashboard-menu-transition.md').read_text(); p=Path('docs/project-structure.md').read_text(); f=Path('docs/runtime-flow.md').read_text()\nrb=re.split(r'(?=^### REQ-002\\.\\d{2}(?!-AC)\\b)',q,flags=re.M)[1:]; ab=re.split(r'(?=^### REQ-002\\.\\d{2}-AC01\\b)',q,flags=re.M)[1:]\nassert len(rb)==len(ab)==9 and all('**Impact**' in x for x in rb) and all('**Cases**' in x and '**State Invariants**' in x for x in ab)\nassert all(x in q for x in ('REQ-001.05-AC01','REQ-001.07-AC01','REQ-001.08-AC01','REQ-001.09-AC01'))\nassert all(x in p for x in ('dashboard/common.py','inject_app_css()','JARCA_COLORS','JARCA_PLOTLY_TEMPLATE','outside the replaceable body'))\nassert all(x in f for x in ('do not initiate or replay financial writes or external calls','explicit page user actions','no new idempotency contract'))\nprint('PASS requirements=9 impact=9 acceptance_criteria=9 cases=9 state_invariants=9 missing=0 ambiguous=0')" + ], + "expected_exit_code": 0, + "max_output_bytes": 8192, + "claims": [ + "documentation-contract-result" + ] + }, + { + "id": "ruff", + "purpose": "Run static lint checks", + "argv": [ + "uv", + "run", + "--extra", + "dashboard", + "--extra", + "dev", + "ruff", + "check", + "dashboard", + "tests", + "scripts" + ], + "expected_exit_code": 0, + "max_output_bytes": 8192, + "claims": [ + "lint-result" + ] + }, + { + "id": "compile", + "purpose": "Compile Python sources and tests", + "argv": [ + "python3", + "-m", + "compileall", + "-q", + "dashboard", + "tests", + "scripts" + ], + "expected_exit_code": 0, + "max_output_bytes": 8192, + "claims": [ + "compile-result" + ] + } + ], + "limitations": [ + "The authenticated browser transition was captured before this clean source commit from byte-identical hashed files; this manifest validates the tracked browser artifacts and their exact source hashes rather than rerunning the browser.", + "Gitea commit status and Actions state are authoritative external readbacks and are not produced by this local manifest." + ] +} diff --git a/docs/evidence/issue-9-dashboard-menu-transition/rework-verification.json b/docs/evidence/issue-9-dashboard-menu-transition/rework-verification.json new file mode 100644 index 0000000..a52c5d3 --- /dev/null +++ b/docs/evidence/issue-9-dashboard-menu-transition/rework-verification.json @@ -0,0 +1 @@ +{"claims":{"browser-evidence-result":["/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"],"compile-result":["/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"],"documentation-contract-result":["/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"],"full-suite-result":["/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"],"lint-result":["/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","--extra","dashboard","--extra","dev","pytest"],"claim_ids":["full-suite-result"],"duration_seconds":89.70536988321692,"exit_code":0,"expected_exit_code":0,"finished_at_utc":"2026-10-05T08:44:42.787954Z","id":"full-suite","max_output_bytes":65536,"output":"........................................................................ [ 47%]\n............................ss.......................................... [ 94%]\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-9/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\n149 passed, 4 skipped, 1 warning in 82.58s (0:01:22)\n","purpose":"Run the repository full test suite at the rework source revision","started_at_utc":"2026-10-05T08:43:13.082951Z"},{"argv":["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))"],"claim_ids":["browser-evidence-result"],"duration_seconds":0.13439339399337769,"exit_code":0,"expected_exit_code":0,"finished_at_utc":"2026-10-05T08:44:42.921955Z","id":"browser-evidence-validator","max_output_bytes":8192,"output":"PASS source_hashes=5 artifact_hashes=2 checks=12/12 frames=35 full_document_loads=0 surfaces=2\n","purpose":"Validate checked-in authenticated browser evidence, source and artifact hashes","started_at_utc":"2026-10-05T08:44:42.788428Z"},{"argv":["python3","-c","from pathlib import Path\nimport re\nq=Path('docs/requirements/req-002_dashboard-menu-transition.md').read_text(); p=Path('docs/project-structure.md').read_text(); f=Path('docs/runtime-flow.md').read_text()\nrb=re.split(r'(?=^### REQ-002\\.\\d{2}(?!-AC)\\b)',q,flags=re.M)[1:]; ab=re.split(r'(?=^### REQ-002\\.\\d{2}-AC01\\b)',q,flags=re.M)[1:]\nassert len(rb)==len(ab)==9 and all('**Impact**' in x for x in rb) and all('**Cases**' in x and '**State Invariants**' in x for x in ab)\nassert all(x in q for x in ('REQ-001.05-AC01','REQ-001.07-AC01','REQ-001.08-AC01','REQ-001.09-AC01'))\nassert all(x in p for x in ('dashboard/common.py','inject_app_css()','JARCA_COLORS','JARCA_PLOTLY_TEMPLATE','outside the replaceable body'))\nassert all(x in f for x in ('do not initiate or replay financial writes or external calls','explicit page user actions','no new idempotency contract'))\nprint('PASS requirements=9 impact=9 acceptance_criteria=9 cases=9 state_invariants=9 missing=0 ambiguous=0')"],"claim_ids":["documentation-contract-result"],"duration_seconds":0.09890262316912413,"exit_code":0,"expected_exit_code":0,"finished_at_utc":"2026-10-05T08:44:43.021294Z","id":"documentation-inventory","max_output_bytes":8192,"output":"PASS requirements=9 impact=9 acceptance_criteria=9 cases=9 state_invariants=9 missing=0 ambiguous=0\n","purpose":"Validate canonical requirement and documentation remediation coverage","started_at_utc":"2026-10-05T08:44:42.922902Z"},{"argv":["uv","run","--extra","dashboard","--extra","dev","ruff","check","dashboard","tests","scripts"],"claim_ids":["lint-result"],"duration_seconds":0.1826452910900116,"exit_code":0,"expected_exit_code":0,"finished_at_utc":"2026-10-05T08:44:43.204372Z","id":"ruff","max_output_bytes":8192,"output":"All checks passed!\n","purpose":"Run static lint checks","started_at_utc":"2026-10-05T08:44:43.021868Z"},{"argv":["python3","-m","compileall","-q","dashboard","tests","scripts"],"claim_ids":["compile-result"],"duration_seconds":0.2716978546231985,"exit_code":0,"expected_exit_code":0,"finished_at_utc":"2026-10-05T08:44:43.476143Z","id":"compile","max_output_bytes":8192,"output":"","purpose":"Compile Python sources and tests","started_at_utc":"2026-10-05T08:44:43.204547Z"}],"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/evidence/issue-9-dashboard-menu-transition/rework-verification-plan.json","docs/evidence/issue-9-dashboard-menu-transition/rework-verification.json"],"files":[{"blob_oid":"bba48c3353a6266b523e79f97f733869b8e9dcbb","path":"docs/evidence/issue-9-dashboard-menu-transition/README.md","sha256":"eb4fefbfce82299c1f5655f613911194362c474c812dc40a2d0f3e1a49948aac"},{"blob_oid":"8a18ae47915acece61ed4ca8372d5ec6e44a51e1","path":"docs/evidence/issue-9-dashboard-menu-transition/browser-observations.json","sha256":"414b62efb2f40483aae4227896040c1b5d887b2c31333f63046e6f34aec2fe8f"},{"blob_oid":"049ee017f96f80388cc2fee39ef452f38a5e93db","path":"docs/evidence/issue-9-dashboard-menu-transition/final-state.jpg","sha256":"cc4e1c28463f033ab1c26d1dc27c9bb93c6fc5495321c0cef73fdb1098221234"},{"blob_oid":"15eb3df527b5bec8d1ee0184460b740ffce4023e","path":"docs/evidence/issue-9-dashboard-menu-transition/manifest.json","sha256":"8190660fce780c072472b9e76e0ad1f3c71865c8aa3450edf332c9d8d8468d91"},{"blob_oid":"0c69b5ab20a46c527e8eb75a870e346e580b7328","path":"docs/project-structure.md","sha256":"2241b1f44ec8933e879c193e4be63dc7aa0fb06c235a8b1b225b1bbce52ca8fd"},{"blob_oid":"44da358850a6c911b9d3072ccf588f99b4f9cefb","path":"docs/requirements/req-002_dashboard-menu-transition.md","sha256":"6f1c7f6fde9c4dc2c001468c8e8aca3dbe198e2ac5ac6e94e53d72f92d3f1688"},{"blob_oid":"2b25cb84c53ecfa7915ab287ef808cd4d2daa65f","path":"docs/runtime-flow.md","sha256":"76141addb868dd1a7c1b27c881813bbd5b3e39915c72771d1a3057f06d6a7d56"},{"blob_oid":"3975fac9d359156e0ddb3c6ce4528f026d45dc8e","path":"scripts/streamlit_browser_evidence.py","sha256":"3cfb449ce1d6fae3abb795727d7ca1bc10dbb759bb811f121abd74fa42993dd7"},{"blob_oid":"b413fa48adc89796fbd994e3540d4cb0ac947433","path":"tests/test_streamlit_browser_evidence.py","sha256":"7f595ccf4009961225328486c19258bb0f7bc7dbfb584c60616860274112724a"}],"generated_at":"2026-10-05T08:44:43.540085Z","limitations":["The authenticated browser transition was captured before this clean source commit from byte-identical hashed files; this manifest validates the tracked browser artifacts and their exact source hashes rather than rerunning the browser.","Gitea commit status and Actions state are authoritative external readbacks and are not produced by this local manifest."],"plan":{"path":"docs/evidence/issue-9-dashboard-menu-transition/rework-verification-plan.json","sha256":"0421786d3b22bc806339681943dd97f3c68b62662fff38a3c2c513bc9b575385"},"redaction":{"checked":true,"violations":[]},"result":"success","schema":"evidence-manifest/v1","source_revision":"f01dc182ec4d9b04e30d1d5bc13652a561332f24","source_tree_clean":true}