Replace document navigation with native Streamlit state transitions, preserve dashboard contracts, and add regression plus authenticated browser evidence for Issue #9.
계약: 기존 10개 메뉴의 표시명과 순서 및 선택 표시를 유지하고 정상 전환 완료 시 선택과 본문이 일치해야 한다.
구현 근거: dashboard/app.py, dashboard/common.py; app의 pages와 dispatch는 기존 10개 항목을 보존한다. common 365-378의 radio는 선택값을 반환한다. 메뉴 순서 unit test와 authenticated AppTest의 분류 규칙 본문 검증 및 구현자 테스트 보고가 대응한다.
테스트 근거: tests/test_dashboard_menu_transition.py
판정 근거: 일반 HTML 링크를 승인된 widget 기반 입력으로 바꾸고 선택 상태를 표시한다. 금융 page dispatch 구성은 유지된다.
AC-002 — indeterminate
계약: document 전체 이동을 피하고 메뉴와 공통 배경을 유지하며 본문만 전환해야 한다. 실제 Dashboard 브라우저에서 클릭 전과 전환 중 및 완료 후 frame과 DOM 및 스타일을 관찰하고 한계를 기록해야 한다.
구현 근거: dashboard/app.py, dashboard/common.py, scripts/streamlit_browser_evidence.py, docs/evidence/issue-9-dashboard-menu-transition/manifest.json, docs/evidence/issue-9-dashboard-menu-transition/browser-observations.json, docs/evidence/issue-9-dashboard-menu-transition/final-state.jpg; 구현자의 인증된 실제 Dashboard 관찰은 35개 frame과 document 및 sidebar marker 보존과 load event 0건을 기록한다. 다섯 실행 입력 hash와 두 artifact hash는 head blob과 일치한다. 그러나 frames의 background는 흰색 RGB 하나이며 앱과 sidebar의 실제 gradient 및 전환 중 가시성 필드는 없다. browser script 459 및 469는 document.body.backgroundColor만 조회하지만 common 211-233의 공통 배경은 stAppViewContainer와 stSidebar에 적용된다.
테스트 근거: tests/test_dashboard_menu_transition.py, tests/test_streamlit_browser_evidence.py
판정 근거: document 동일성 및 본문 교체 근거는 인정한다. 흰 body 색과 DOM marker 동일성은 실제 공통 화면이 보이는지 및 실제 배경이 유지되는지를 판정하지 못한다. 구현 실패를 단정하지 않지만 핵심 승인 인수 조건의 관찰 대상이 불일치한다. synthetic 실제 Dashboard 클릭 구간에서 앱 및 sidebar의 실제 backgroundImage와 backgroundColor 및 가시성을 대응하는 DOM 스타일 또는 연속 화면 근거만 보완해야 한다. 특정 저장 경로나 JSON 형식 및 모든 순간의 pixel 연속성은 요구하지 않는다.
AC-003 — satisfied
계약: 느린 조회는 이전 본문 대신 대상 페이지 로딩 안내를 본문 영역에 표시하고 완료 시 대상 본문으로 교체해야 한다.
구현 근거: dashboard/app.py, dashboard/common.py, docs/evidence/issue-9-dashboard-menu-transition/browser-observations.json; common 381-395는 placeholder를 비우고 대상 로딩을 먼저 보낸다. loading alert가 있을 때 dashboard_content를 숨기는 CSS가 추가됐다. 구현자 브라우저 frame 22개에서 loading=true와 previous_body_visible=false가 함께 기록되며 최종 loading=false이다. unit test는 로딩과 renderer 순서를 검사한다.
테스트 근거: tests/test_dashboard_menu_transition.py
판정 근거: 실제 Dashboard에 fixture-only 2초 지연을 넣은 관찰을 승인된 느린 조회 근거로 인정한다. reviewer의 독립 browser 실행으로 표현하지 않으며 표본 사이 순간까지 보장하지 않는다.
AC-004 — satisfied
계약: 조회 또는 렌더링 실패 시 본문 영역에 비민감 오류와 재시도 안내를 표시해야 한다.
구현 근거: dashboard/app.py, dashboard/common.py; common 396-401은 부분 본문을 제거하고 generic error와 페이지별 retry button을 표시한다. test_body_error_is_local_and_retry_rerenders_target은 secret details 비노출과 retry rerun을 검증한다.
테스트 근거: tests/test_dashboard_menu_transition.py
판정 근거: 예외 상세를 출력하지 않고 기존 인증과 공통 shell 바깥이 아닌 body placeholder에서 실패를 처리한다. 구현자 unit 보고와 source를 함께 인정한다.
AC-005 — satisfied
계약: 연속 메뉴 클릭 후에는 최종 선택과 표시된 본문이 일치해야 한다.
구현 근거: dashboard/app.py, dashboard/common.py; test_rapid_menu_clicks_commit_latest_selection_only는 callback 연속 호출의 최종 Import query를 검사한다. app 43-47은 그 query에서 선택을 정하고 73의 dispatch를 동일 page로 호출한다. 정상 AppTest는 실제 query 변경과 대상 renderer 연결을 검사한다.
테스트 근거: tests/test_dashboard_menu_transition.py
판정 근거: 연속 callback의 최종 query 검증과 동일 선택값을 사용하는 동기 dispatch 및 정상 AppTest를 합쳐 직렬화된 최종 상태의 일치를 확인한다. 실제 browser의 모든 경쟁 interleaving을 검증했다고 주장하지 않는다.
AC-006 — satisfied
계약: 기존 page query 직접 접속과 부가 query 해석을 유지하고 page가 없거나 알 수 없는 값이면 요약을 표시해야 한다. history 보장과 경로 URL 전환 및 bridge는 제외한다.
구현 근거: dashboard/app.py, dashboard/common.py; validate_dashboard_page와 direct query unit test가 fallback과 known page를 검증한다. callback은 page만 변경한다. AppTest와 구현자 browser에서 sibling query가 유지된다. 금융 page_views는 변경되지 않았으며 monthly fixture test의 month 해석이 유지된다.
테스트 근거: tests/test_dashboard_menu_transition.py, tests/test_dashboard_app.py
판정 근거: 기존 직접 접속 및 페이지별 query 소비자를 보존했다. history API를 제품 기능으로 추가하지 않고 검증 도구에서만 관찰한다.
AC-007 — satisfied
계약: 인증 성공 전 DB path와 gateway 및 page dispatch를 차단하고 인증 거부 시 보호 데이터를 노출하지 않아야 한다. 기존 cookie 만료와 rotation 및 logout과 cleanup 계약을 유지해야 한다.
구현 근거: dashboard/app.py, dashboard/common.py; app main의 인증 return은 get_db_path 및 스타일과 dispatch보다 먼저 유지된다. auth source와 auth server는 diff에 없다. 기존 invalid cookie와 rotation AppTest 및 expiry와 logout 및 cleanup tests를 읽었고 PR의 전체 테스트 성공 보고에 대응한다.
테스트 근거: tests/test_dashboard_authentication_app.py, tests/test_dashboard_persistent_authentication.py, tests/test_dashboard_auth_server.py
판정 근거: 승인된 보안 경계와 기존 인증 계약을 source 및 negative-path tests로 확인했다. 브라우저 통합은 구현자 authenticated 실행 근거이며 reviewer 독립 실행 또는 CI로 표현하지 않는다.
AC-008 — satisfied
계약: 기존 금융 동작과 새로고침 cache clear를 유지하고 synthetic DB로 핵심 페이지 회귀를 검증해야 한다.
구현 근거: dashboard/app.py, dashboard/common.py; page_views와 gateway 및 DB schema는 변경되지 않았다. 기존 핵심 5개 페이지 synthetic fixture AppTest와 새 refresh test가 대응한다. refresh는 clear_cache 후 rerun 순서를 유지한다. PR은 139 passed 및 4 skipped를 보고한다.
테스트 근거: tests/test_dashboard_menu_transition.py, tests/test_dashboard_app.py
판정 근거: 금융 모델이나 멱등성 계약을 추가하지 않고 승인된 page 회귀와 cache clear 동작을 유지했다. 구현자 보고는 인정하되 head-bound CI status는 0건이고 reviewer 제품 실행은 수행하지 않았다.
DOC-001 — unsatisfied
계약: REQ-002를 지정 경로와 제목으로 신규 작성하고 requirement v1 정본 README 및 TEMPLATE의 필수 구조와 데이터 및 인터페이스 계약과 하위 호환성 및 추적성 정보를 채워야 한다.
구현 근거: docs/requirements/req-002_dashboard-menu-transition.md; front matter의 schema와 ID 및 제목과 revision과 status 및 Issue 9와 PR 10은 맞다. 그러나 251의 9. 추적성으로 문서가 끝나며 정본 TEMPLATE 83-96의 9. 데이터 및 인터페이스 계약과 10. 하위 호환성과 11. 추적성의 관련 설계 문서가 누락됐다. 각 요구사항의 영향 범위와 AC별 상태 불변조건 및 케이스 블록도 없다.
테스트 근거: 없음
판정 근거: 현재 자료가 있는 공통 내용은 재사용하되 지정된 정본 구조와 각 항목의 영향 범위 및 판정 불변조건을 채워야 한다. 구현 PR이 생성된 뒤 별도 문서 commit으로 PR 10을 기록한 것은 적합하며 미정으로 되돌릴 필요가 없다.
DOC-002 — unsatisfied
계약: REQ-002에는 정상 전환과 로딩과 오류 및 연속 선택과 query 및 인증 차단과 cookie 만료와 rotation 및 logout 회귀와 금융 기능 및 cache clear 및 synthetic 실제 Dashboard 관찰과 AppTest 및 실행 근거 추적성을 포함하고 history와 URL 체계 변경을 필수로 넣지 않아야 한다.
구현 근거: docs/requirements/req-002_dashboard-menu-transition.md; REQ-002 24-96과 102-245는 메뉴와 query와 본문 및 오류와 최신 선택 및 gate와 금융 및 refresh를 대응한다. 199-213의 auth AC는 valid cookie와 pre-gate 차단만 연결한다. 22와 34 및 96은 기존 auth 계약 보존을 선언하지만 만료와 rotation 및 logout 회귀에 대한 검증 대응은 없다.
테스트 근거: tests/test_dashboard_authentication_app.py, tests/test_dashboard_persistent_authentication.py, tests/test_dashboard_auth_server.py
판정 근거: 기존 인증 기능의 source 실패를 주장하는 finding이 아니다. Discovery의 요구사항명세서 포함할 내용에 지정된 cookie 만료와 rotation 및 logout 회귀를 이미 있는 테스트 및 REQ-001 계약에 연결해 문서 인수 추적성을 보완해야 한다. 새 인증 방식 또는 모든 실패 조합의 browser 시험은 요구하지 않는다.
DOC-003 — satisfied
계약: 인터페이스 정본을 제자리 갱신해 메뉴 입력과 선택 및 본문 출력과 로딩과 오류 및 재시도와 직접 page query 및 fallback과 부가 query 호환성을 기술하고 기존 인증 및 MCP 계약을 유지해야 한다. 데이터 모델은 영향 없으므로 신규 작성하지 않는다.
구현 근거: docs/interface-contract.md; interface 225-261의 dashboard-menu-transition은 해당 입력과 출력 및 오류와 query 및 직렬화 계약을 추가한다. 기존 signed cookie와 login과 cleanup과 logout 및 gate 내용은 그대로이고 data-model 문서는 변경 파일에 없다.
테스트 근거: 없음
판정 근거: 정본 문서 갱신과 비영향 영역을 확인했다. DB schema 및 MCP 변경이나 데이터 모델 신규 산출물은 없다.
DOC-004 — unsatisfied
계약: 프로젝트 구조 정본에 app의 인증 후 선택 및 dispatch와 공통 화면 및 본문 렌더링 경계와 common의 메뉴 입력 및 스타일 책임과 page_views 금융 UI 및 의존 방향을 명시하고 REQ-002와 기존 AppTest 및 실제 browser 검증 경로를 배치해야 한다.
구현 근거: docs/project-structure.md; project-structure 14-29의 source tree와 책임 표에는 common.py가 없고 app은 gate then page dispatch로만 기술된다. 80-89의 의존 표는 app에서 common의 menu/query/body helpers를 호출한다고만 한다. 31-78과 91-108의 테스트 및 browser 도구와 REQ-002 및 배치 규칙은 추가됐다.
테스트 근거: 없음
판정 근거: 파일 위치와 테스트 배치는 충족하나 common의 스타일 책임과 app의 공통 화면 및 본문 경계라는 명시된 문서 의무가 남았다. 현재 common의 CSS 및 sidebar와 body helper 책임과 app의 auth 후 조립 및 dispatch 경계를 source tree 및 책임 표에 반영하는 최소 갱신이 필요하다.
DOC-005 — unsatisfied
계약: 런타임 정본을 제자리 갱신해 메뉴 입력과 인증 및 선택과 공통 화면 유지와 본문 교체 및 로딩과 오류 및 retry와 최종 선택과 인증 거부와 기존 startup 및 cookie TTL과 cleanup 및 logout을 설명하고 기존 금융 쓰기 및 외부 호출의 의도치 않은 재실행 방지 제약과 비민감 관찰을 기술해야 한다.
구현 근거: docs/runtime-flow.md; runtime 116-144는 callback과 query 및 placeholder와 로딩 및 오류 및 최신 선택을 기술하고 기존 인증 및 TTL과 cleanup 및 logout 흐름은 유지한다. 125는 기존 financial SQLite 규칙 유지라고만 하고 131은 page/gateway 읽기 및 쓰기를 나열한다. 메뉴 전환 및 rerun이 사용자 금융 쓰기 또는 외부 호출을 의도치 않게 다시 실행하지 않아야 한다는 제약은 없다.
테스트 근거: 없음
판정 근거: 기존 금융 동작 보존을 선언하는 것과 승인된 재실행 방지 경계를 설명하는 것은 다르다. 전환과 명시적 금융 action의 경계를 현 구현 기준으로 문서화해야 한다. 새로운 금융 멱등성 보장 또는 동시성 계약을 요구하지 않는다.
SCOPE-001 — satisfied
계약: 현재 Streamlit dependency 범위 안에서 최소 수정하며 전면 framework 및 디자인 재설계와 새 메뉴와 금융 및 DB 및 MCP 변경과 인증 체계 변경은 제외한다.
구현 근거: dashboard/app.py, dashboard/common.py, 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/interface-contract.md, docs/project-structure.md, docs/requirements/req-002_dashboard-menu-transition.md, docs/runtime-flow.md, scripts/streamlit_browser_evidence.py, tests/test_dashboard_menu_transition.py, tests/test_streamlit_browser_evidence.py; 13개 changed file은 app/common 전환과 테스트 및 browser 검증 도구와 임의로 선택한 실행 증거 저장 및 필수 4종 문서에 대응한다. dependency와 lockfile 및 auth source와 page_views와 DB 및 MCP는 변경되지 않았다.
테스트 근거: 없음
판정 근거: 추가 evidence 파일은 승인된 검증의 지원 산출물로 설명된다. 그 경로 또는 JSON 형식을 새 제품 산출물 의무로 요구하지 않는다.
범위 판정
누락: 공통 화면과 실제 앱 및 sidebar 배경의 전환 중 관찰 대상 보완, REQ-002 정본 구조와 항목별 영향 및 인수 불변조건 및 인증 회귀 검증 대응 보완, 프로젝트 구조의 common 스타일과 공통 화면 및 본문 책임 경계 보완, 런타임의 금융 쓰기 및 외부 호출 재실행 방지 제약 보완
범위 초과: 없음
명세 모순: 없음
결론
문서 이동 없는 widget 전환과 본문 로딩 및 오류 처리와 query 및 인증 회귀의 구현 방향은 승인 범위에 맞는다. 그러나 실제 공통 배경 및 가시성 인수 관찰의 대상 불일치와 필수 문서 계약 누락이 남아 request_changes로 판정한다. 지적한 최소 문서 및 관찰 근거만 보완하고 history 기능과 새로운 금융 멱등성 또는 CI 및 별도 증거 저장 형식은 추가 요구하지 않는다. 구현자의 테스트와 browser 실행 보고를 검토했으며 reviewer 독립 제품 실행은 수행하지 않았다.
## 구현 명세 적합성 검토
- Source Issue: #9
- Pull Request: #10
- Reviewed head: `a02aceee416c5770dfd1f35ac94367f3c4e0c8c8`
- Contract SHA-256: `63f6c1538b1defa2fd0e944c75dee264d9d11ee01409aa05ff22784c19640aa3`
- Verdict: `request_changes`
### Acceptance criteria 판정
- `AC-001` — `satisfied`
- 계약: 기존 10개 메뉴의 표시명과 순서 및 선택 표시를 유지하고 정상 전환 완료 시 선택과 본문이 일치해야 한다.
- 구현 근거: dashboard/app.py, dashboard/common.py; app의 pages와 dispatch는 기존 10개 항목을 보존한다. common 365-378의 radio는 선택값을 반환한다. 메뉴 순서 unit test와 authenticated AppTest의 분류 규칙 본문 검증 및 구현자 테스트 보고가 대응한다.
- 테스트 근거: tests/test_dashboard_menu_transition.py
- 판정 근거: 일반 HTML 링크를 승인된 widget 기반 입력으로 바꾸고 선택 상태를 표시한다. 금융 page dispatch 구성은 유지된다.
- `AC-002` — `indeterminate`
- 계약: document 전체 이동을 피하고 메뉴와 공통 배경을 유지하며 본문만 전환해야 한다. 실제 Dashboard 브라우저에서 클릭 전과 전환 중 및 완료 후 frame과 DOM 및 스타일을 관찰하고 한계를 기록해야 한다.
- 구현 근거: dashboard/app.py, dashboard/common.py, scripts/streamlit_browser_evidence.py, docs/evidence/issue-9-dashboard-menu-transition/manifest.json, docs/evidence/issue-9-dashboard-menu-transition/browser-observations.json, docs/evidence/issue-9-dashboard-menu-transition/final-state.jpg; 구현자의 인증된 실제 Dashboard 관찰은 35개 frame과 document 및 sidebar marker 보존과 load event 0건을 기록한다. 다섯 실행 입력 hash와 두 artifact hash는 head blob과 일치한다. 그러나 frames의 background는 흰색 RGB 하나이며 앱과 sidebar의 실제 gradient 및 전환 중 가시성 필드는 없다. browser script 459 및 469는 document.body.backgroundColor만 조회하지만 common 211-233의 공통 배경은 stAppViewContainer와 stSidebar에 적용된다.
- 테스트 근거: tests/test_dashboard_menu_transition.py, tests/test_streamlit_browser_evidence.py
- 판정 근거: document 동일성 및 본문 교체 근거는 인정한다. 흰 body 색과 DOM marker 동일성은 실제 공통 화면이 보이는지 및 실제 배경이 유지되는지를 판정하지 못한다. 구현 실패를 단정하지 않지만 핵심 승인 인수 조건의 관찰 대상이 불일치한다. synthetic 실제 Dashboard 클릭 구간에서 앱 및 sidebar의 실제 backgroundImage와 backgroundColor 및 가시성을 대응하는 DOM 스타일 또는 연속 화면 근거만 보완해야 한다. 특정 저장 경로나 JSON 형식 및 모든 순간의 pixel 연속성은 요구하지 않는다.
- `AC-003` — `satisfied`
- 계약: 느린 조회는 이전 본문 대신 대상 페이지 로딩 안내를 본문 영역에 표시하고 완료 시 대상 본문으로 교체해야 한다.
- 구현 근거: dashboard/app.py, dashboard/common.py, docs/evidence/issue-9-dashboard-menu-transition/browser-observations.json; common 381-395는 placeholder를 비우고 대상 로딩을 먼저 보낸다. loading alert가 있을 때 dashboard_content를 숨기는 CSS가 추가됐다. 구현자 브라우저 frame 22개에서 loading=true와 previous_body_visible=false가 함께 기록되며 최종 loading=false이다. unit test는 로딩과 renderer 순서를 검사한다.
- 테스트 근거: tests/test_dashboard_menu_transition.py
- 판정 근거: 실제 Dashboard에 fixture-only 2초 지연을 넣은 관찰을 승인된 느린 조회 근거로 인정한다. reviewer의 독립 browser 실행으로 표현하지 않으며 표본 사이 순간까지 보장하지 않는다.
- `AC-004` — `satisfied`
- 계약: 조회 또는 렌더링 실패 시 본문 영역에 비민감 오류와 재시도 안내를 표시해야 한다.
- 구현 근거: dashboard/app.py, dashboard/common.py; common 396-401은 부분 본문을 제거하고 generic error와 페이지별 retry button을 표시한다. test_body_error_is_local_and_retry_rerenders_target은 secret details 비노출과 retry rerun을 검증한다.
- 테스트 근거: tests/test_dashboard_menu_transition.py
- 판정 근거: 예외 상세를 출력하지 않고 기존 인증과 공통 shell 바깥이 아닌 body placeholder에서 실패를 처리한다. 구현자 unit 보고와 source를 함께 인정한다.
- `AC-005` — `satisfied`
- 계약: 연속 메뉴 클릭 후에는 최종 선택과 표시된 본문이 일치해야 한다.
- 구현 근거: dashboard/app.py, dashboard/common.py; test_rapid_menu_clicks_commit_latest_selection_only는 callback 연속 호출의 최종 Import query를 검사한다. app 43-47은 그 query에서 선택을 정하고 73의 dispatch를 동일 page로 호출한다. 정상 AppTest는 실제 query 변경과 대상 renderer 연결을 검사한다.
- 테스트 근거: tests/test_dashboard_menu_transition.py
- 판정 근거: 연속 callback의 최종 query 검증과 동일 선택값을 사용하는 동기 dispatch 및 정상 AppTest를 합쳐 직렬화된 최종 상태의 일치를 확인한다. 실제 browser의 모든 경쟁 interleaving을 검증했다고 주장하지 않는다.
- `AC-006` — `satisfied`
- 계약: 기존 page query 직접 접속과 부가 query 해석을 유지하고 page가 없거나 알 수 없는 값이면 요약을 표시해야 한다. history 보장과 경로 URL 전환 및 bridge는 제외한다.
- 구현 근거: dashboard/app.py, dashboard/common.py; validate_dashboard_page와 direct query unit test가 fallback과 known page를 검증한다. callback은 page만 변경한다. AppTest와 구현자 browser에서 sibling query가 유지된다. 금융 page_views는 변경되지 않았으며 monthly fixture test의 month 해석이 유지된다.
- 테스트 근거: tests/test_dashboard_menu_transition.py, tests/test_dashboard_app.py
- 판정 근거: 기존 직접 접속 및 페이지별 query 소비자를 보존했다. history API를 제품 기능으로 추가하지 않고 검증 도구에서만 관찰한다.
- `AC-007` — `satisfied`
- 계약: 인증 성공 전 DB path와 gateway 및 page dispatch를 차단하고 인증 거부 시 보호 데이터를 노출하지 않아야 한다. 기존 cookie 만료와 rotation 및 logout과 cleanup 계약을 유지해야 한다.
- 구현 근거: dashboard/app.py, dashboard/common.py; app main의 인증 return은 get_db_path 및 스타일과 dispatch보다 먼저 유지된다. auth source와 auth server는 diff에 없다. 기존 invalid cookie와 rotation AppTest 및 expiry와 logout 및 cleanup tests를 읽었고 PR의 전체 테스트 성공 보고에 대응한다.
- 테스트 근거: tests/test_dashboard_authentication_app.py, tests/test_dashboard_persistent_authentication.py, tests/test_dashboard_auth_server.py
- 판정 근거: 승인된 보안 경계와 기존 인증 계약을 source 및 negative-path tests로 확인했다. 브라우저 통합은 구현자 authenticated 실행 근거이며 reviewer 독립 실행 또는 CI로 표현하지 않는다.
- `AC-008` — `satisfied`
- 계약: 기존 금융 동작과 새로고침 cache clear를 유지하고 synthetic DB로 핵심 페이지 회귀를 검증해야 한다.
- 구현 근거: dashboard/app.py, dashboard/common.py; page_views와 gateway 및 DB schema는 변경되지 않았다. 기존 핵심 5개 페이지 synthetic fixture AppTest와 새 refresh test가 대응한다. refresh는 clear_cache 후 rerun 순서를 유지한다. PR은 139 passed 및 4 skipped를 보고한다.
- 테스트 근거: tests/test_dashboard_menu_transition.py, tests/test_dashboard_app.py
- 판정 근거: 금융 모델이나 멱등성 계약을 추가하지 않고 승인된 page 회귀와 cache clear 동작을 유지했다. 구현자 보고는 인정하되 head-bound CI status는 0건이고 reviewer 제품 실행은 수행하지 않았다.
- `DOC-001` — `unsatisfied`
- 계약: REQ-002를 지정 경로와 제목으로 신규 작성하고 requirement v1 정본 README 및 TEMPLATE의 필수 구조와 데이터 및 인터페이스 계약과 하위 호환성 및 추적성 정보를 채워야 한다.
- 구현 근거: docs/requirements/req-002_dashboard-menu-transition.md; front matter의 schema와 ID 및 제목과 revision과 status 및 Issue 9와 PR 10은 맞다. 그러나 251의 9. 추적성으로 문서가 끝나며 정본 TEMPLATE 83-96의 9. 데이터 및 인터페이스 계약과 10. 하위 호환성과 11. 추적성의 관련 설계 문서가 누락됐다. 각 요구사항의 영향 범위와 AC별 상태 불변조건 및 케이스 블록도 없다.
- 테스트 근거: 없음
- 판정 근거: 현재 자료가 있는 공통 내용은 재사용하되 지정된 정본 구조와 각 항목의 영향 범위 및 판정 불변조건을 채워야 한다. 구현 PR이 생성된 뒤 별도 문서 commit으로 PR 10을 기록한 것은 적합하며 미정으로 되돌릴 필요가 없다.
- `DOC-002` — `unsatisfied`
- 계약: REQ-002에는 정상 전환과 로딩과 오류 및 연속 선택과 query 및 인증 차단과 cookie 만료와 rotation 및 logout 회귀와 금융 기능 및 cache clear 및 synthetic 실제 Dashboard 관찰과 AppTest 및 실행 근거 추적성을 포함하고 history와 URL 체계 변경을 필수로 넣지 않아야 한다.
- 구현 근거: docs/requirements/req-002_dashboard-menu-transition.md; REQ-002 24-96과 102-245는 메뉴와 query와 본문 및 오류와 최신 선택 및 gate와 금융 및 refresh를 대응한다. 199-213의 auth AC는 valid cookie와 pre-gate 차단만 연결한다. 22와 34 및 96은 기존 auth 계약 보존을 선언하지만 만료와 rotation 및 logout 회귀에 대한 검증 대응은 없다.
- 테스트 근거: tests/test_dashboard_authentication_app.py, tests/test_dashboard_persistent_authentication.py, tests/test_dashboard_auth_server.py
- 판정 근거: 기존 인증 기능의 source 실패를 주장하는 finding이 아니다. Discovery의 요구사항명세서 포함할 내용에 지정된 cookie 만료와 rotation 및 logout 회귀를 이미 있는 테스트 및 REQ-001 계약에 연결해 문서 인수 추적성을 보완해야 한다. 새 인증 방식 또는 모든 실패 조합의 browser 시험은 요구하지 않는다.
- `DOC-003` — `satisfied`
- 계약: 인터페이스 정본을 제자리 갱신해 메뉴 입력과 선택 및 본문 출력과 로딩과 오류 및 재시도와 직접 page query 및 fallback과 부가 query 호환성을 기술하고 기존 인증 및 MCP 계약을 유지해야 한다. 데이터 모델은 영향 없으므로 신규 작성하지 않는다.
- 구현 근거: docs/interface-contract.md; interface 225-261의 dashboard-menu-transition은 해당 입력과 출력 및 오류와 query 및 직렬화 계약을 추가한다. 기존 signed cookie와 login과 cleanup과 logout 및 gate 내용은 그대로이고 data-model 문서는 변경 파일에 없다.
- 테스트 근거: 없음
- 판정 근거: 정본 문서 갱신과 비영향 영역을 확인했다. DB schema 및 MCP 변경이나 데이터 모델 신규 산출물은 없다.
- `DOC-004` — `unsatisfied`
- 계약: 프로젝트 구조 정본에 app의 인증 후 선택 및 dispatch와 공통 화면 및 본문 렌더링 경계와 common의 메뉴 입력 및 스타일 책임과 page_views 금융 UI 및 의존 방향을 명시하고 REQ-002와 기존 AppTest 및 실제 browser 검증 경로를 배치해야 한다.
- 구현 근거: docs/project-structure.md; project-structure 14-29의 source tree와 책임 표에는 common.py가 없고 app은 gate then page dispatch로만 기술된다. 80-89의 의존 표는 app에서 common의 menu/query/body helpers를 호출한다고만 한다. 31-78과 91-108의 테스트 및 browser 도구와 REQ-002 및 배치 규칙은 추가됐다.
- 테스트 근거: 없음
- 판정 근거: 파일 위치와 테스트 배치는 충족하나 common의 스타일 책임과 app의 공통 화면 및 본문 경계라는 명시된 문서 의무가 남았다. 현재 common의 CSS 및 sidebar와 body helper 책임과 app의 auth 후 조립 및 dispatch 경계를 source tree 및 책임 표에 반영하는 최소 갱신이 필요하다.
- `DOC-005` — `unsatisfied`
- 계약: 런타임 정본을 제자리 갱신해 메뉴 입력과 인증 및 선택과 공통 화면 유지와 본문 교체 및 로딩과 오류 및 retry와 최종 선택과 인증 거부와 기존 startup 및 cookie TTL과 cleanup 및 logout을 설명하고 기존 금융 쓰기 및 외부 호출의 의도치 않은 재실행 방지 제약과 비민감 관찰을 기술해야 한다.
- 구현 근거: docs/runtime-flow.md; runtime 116-144는 callback과 query 및 placeholder와 로딩 및 오류 및 최신 선택을 기술하고 기존 인증 및 TTL과 cleanup 및 logout 흐름은 유지한다. 125는 기존 financial SQLite 규칙 유지라고만 하고 131은 page/gateway 읽기 및 쓰기를 나열한다. 메뉴 전환 및 rerun이 사용자 금융 쓰기 또는 외부 호출을 의도치 않게 다시 실행하지 않아야 한다는 제약은 없다.
- 테스트 근거: 없음
- 판정 근거: 기존 금융 동작 보존을 선언하는 것과 승인된 재실행 방지 경계를 설명하는 것은 다르다. 전환과 명시적 금융 action의 경계를 현 구현 기준으로 문서화해야 한다. 새로운 금융 멱등성 보장 또는 동시성 계약을 요구하지 않는다.
- `SCOPE-001` — `satisfied`
- 계약: 현재 Streamlit dependency 범위 안에서 최소 수정하며 전면 framework 및 디자인 재설계와 새 메뉴와 금융 및 DB 및 MCP 변경과 인증 체계 변경은 제외한다.
- 구현 근거: dashboard/app.py, dashboard/common.py, 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/interface-contract.md, docs/project-structure.md, docs/requirements/req-002_dashboard-menu-transition.md, docs/runtime-flow.md, scripts/streamlit_browser_evidence.py, tests/test_dashboard_menu_transition.py, tests/test_streamlit_browser_evidence.py; 13개 changed file은 app/common 전환과 테스트 및 browser 검증 도구와 임의로 선택한 실행 증거 저장 및 필수 4종 문서에 대응한다. dependency와 lockfile 및 auth source와 page_views와 DB 및 MCP는 변경되지 않았다.
- 테스트 근거: 없음
- 판정 근거: 추가 evidence 파일은 승인된 검증의 지원 산출물로 설명된다. 그 경로 또는 JSON 형식을 새 제품 산출물 의무로 요구하지 않는다.
### 범위 판정
- 누락: 공통 화면과 실제 앱 및 sidebar 배경의 전환 중 관찰 대상 보완, REQ-002 정본 구조와 항목별 영향 및 인수 불변조건 및 인증 회귀 검증 대응 보완, 프로젝트 구조의 common 스타일과 공통 화면 및 본문 책임 경계 보완, 런타임의 금융 쓰기 및 외부 호출 재실행 방지 제약 보완
- 범위 초과: 없음
- 명세 모순: 없음
### 결론
문서 이동 없는 widget 전환과 본문 로딩 및 오류 처리와 query 및 인증 회귀의 구현 방향은 승인 범위에 맞는다. 그러나 실제 공통 배경 및 가시성 인수 관찰의 대상 불일치와 필수 문서 계약 누락이 남아 request_changes로 판정한다. 지적한 최소 문서 및 관찰 근거만 보완하고 history 기능과 새로운 금융 멱등성 또는 CI 및 별도 증거 저장 형식은 추가 요구하지 않는다. 구현자의 테스트와 browser 실행 보고를 검토했으며 reviewer 독립 제품 실행은 수행하지 않았다.
<!-- gitea-agent:implementation-spec-review/v1 owner=jsfamily repository=jarca-ledger-mcp issue=9 pr=10 head=a02aceee416c5770dfd1f35ac94367f3c4e0c8c8 contract-sha256=63f6c1538b1defa2fd0e944c75dee264d9d11ee01409aa05ff22784c19640aa3 result-sha256=d9b1f3f73518c6d3c82990c5b4a6202f71c0c72eb3b10f9ac5f9a1eb80731978 correlation=24e6910e7e5e93684da2bbfb10dd6d95a2984d810ed58df0e565d045a178b1a4 -->
Runtime/browser: authenticated real Dashboard 요약 → 분류 규칙; 35 frames; loading 2 frames; prior body absent in both; app/sidebar surfaces visible and stable; exact evidence at docs/evidence/issue-9-dashboard-menu-transition/manifest.json
Reviewer-accessible verification: docs/evidence/issue-9-dashboard-menu-transition/rework-verification.json, bound to source commit f01dc182ec4d9b04e30d1d5bc13652a561332f24; final head is its evidence-only descendant
Commit status: 없음 — head 1ebc53d152159958039c43401b9693a335eb66a5, status contexts 0
Actions runs: 없음 — repository workflow runs 0
다음 단계
Reviewer가 rework head를 새 snapshot으로 다시 검토해야 하며 이 comment는 기존 REQUEST_CHANGES를 해제하거나 승인을 의미하지 않는다.
## 구현 재작업 결과
- Source Issue: #9
- Pull Request: #10
- Source Review: #56
- Reviewed head: `a02aceee416c5770dfd1f35ac94367f3c4e0c8c8`
- Rework head: `1ebc53d152159958039c43401b9693a335eb66a5`
- Contract SHA-256: `63f6c1538b1defa2fd0e944c75dee264d9d11ee01409aa05ff22784c19640aa3`
- Result: `rework_delivered`
### 지적 처리
- `AC-002` — `resolved`
- 분류: `evidence_gap`
- 변경: `scripts/streamlit_browser_evidence.py`, `tests/test_streamlit_browser_evidence.py`, `docs/evidence/issue-9-dashboard-menu-transition/`
- 검증: authenticated Playwright browser, 35 frames at 50 ms; app/sidebar computed surfaces 2; checks 12/12; full-document loads 0
- 근거: 실제 `stAppViewContainer`와 `stSidebar`의 background, visibility, display, opacity와 rendered geometry를 모든 frame에서 기록하고 fail-closed 검증했다.
- `DOC-001` — `resolved`
- 분류: `valid_fix`
- 변경: `docs/requirements/req-002_dashboard-menu-transition.md`
- 검증: requirement inventory — requirements 9/9, Impact 9/9, Cases 9/9, State Invariants 9/9, missing 0, ambiguous 0
- 근거: requirement v1 canonical 구조와 항목별 판정 필드를 복원했다.
- `DOC-002` — `resolved`
- 분류: `valid_fix`
- 변경: `docs/requirements/req-002_dashboard-menu-transition.md`
- 검증: REQ-001 expiry, rotation, invalid-cookie cleanup, logout 및 기존 exact test 연결 확인
- 근거: 기존 인증 동작 변경 없이 명세 추적성을 보완했다.
- `DOC-004` — `resolved`
- 분류: `valid_fix`
- 변경: `docs/project-structure.md`
- 검증: `dashboard/app.py`와 `dashboard/common.py`의 shell/body/style 책임 및 의존 경계 정적 검사
- 근거: common style ownership과 app의 auth 이후 조립·dispatch 경계를 canonical 구조 문서에 반영했다.
- `DOC-005` — `resolved`
- 분류: `valid_fix`
- 변경: `docs/runtime-flow.md`
- 검증: menu/query rerun과 명시적 page user action 경계 정적 검사
- 근거: rerun/rendering이 금융 쓰기나 외부 호출을 암묵적으로 시작·재실행하지 않는 기존 경계를 문서화했다.
### 최종 검증
- Local checks: source commit `f01dc182ec4d9b04e30d1d5bc13652a561332f24`; `uv run --extra dashboard --extra dev pytest` exit 0 — 149 passed, 4 skipped, 0 failures/errors; Ruff exit 0; compile exit 0; evidence manifest validation exit 0
- Runtime/browser: authenticated real Dashboard `요약` → `분류 규칙`; 35 frames; loading 2 frames; prior body absent in both; app/sidebar surfaces visible and stable; exact evidence at `docs/evidence/issue-9-dashboard-menu-transition/manifest.json`
- Reviewer-accessible verification: `docs/evidence/issue-9-dashboard-menu-transition/rework-verification.json`, bound to source commit `f01dc182ec4d9b04e30d1d5bc13652a561332f24`; final head is its evidence-only descendant
- Commit status: 없음 — head `1ebc53d152159958039c43401b9693a335eb66a5`, status contexts 0
- Actions runs: 없음 — repository workflow runs 0
### 다음 단계
Reviewer가 rework head를 새 snapshot으로 다시 검토해야 하며 이 comment는 기존 `REQUEST_CHANGES`를 해제하거나 승인을 의미하지 않는다.
<!-- gitea-agent:implementation-rework/v1 owner=jsfamily repository=jarca-ledger-mcp issue=9 pr=10 review=56 reviewed-head=a02aceee416c5770dfd1f35ac94367f3c4e0c8c8 head=1ebc53d152159958039c43401b9693a335eb66a5 contract-sha256=63f6c1538b1defa2fd0e944c75dee264d9d11ee01409aa05ff22784c19640aa3 result-sha256=636e4382d1ec2a22269841e2983fe8088be698ca44ec22138076801053ff75e6 correlation=8ade35183dd401e9864cadbb16793497916212b1760deae3273047e9f08d0c0f -->
구현 근거: dashboard/app.py, dashboard/common.py; app main의 10개 dispatch와 common radio selected state 및 label order test를 확인했다
테스트 근거: tests/test_dashboard_menu_transition.py
판정 근거: 공통 dispatch와 기존 메뉴 정체성이 보존된다
AC-002 — satisfied
계약: document 전체 이동을 피하고 메뉴 공통 배경을 유지하며 본문만 전환한다
구현 근거: dashboard/app.py, dashboard/common.py, docs/evidence/issue-9-dashboard-menu-transition/browser-observations.json, docs/evidence/issue-9-dashboard-menu-transition/manifest.json, docs/evidence/issue-9-dashboard-menu-transition/final-state.jpg; 실제 authenticated Dashboard 구현자 관찰의 35개 frame에서 앱 sidebar gradient 스타일 가시성 geometry document sidebar identity가 동일하고 document load는 0건이다. 입력 hash 5개와 artifact hash 2개를 reviewed head blob과 직접 대조했다. 이전 review 56 배경 관찰 누락을 해소했다
테스트 근거: tests/test_dashboard_menu_transition.py, tests/test_streamlit_browser_evidence.py
판정 근거: 최종 screenshot만 아닌 전환 중 스타일 근거로 충족한다. 50 ms 표본과 임시 HTTPS ingress의 한계를 인정하며 모든 순간 pixel 연속성으로 과장하지 않는다
AC-003 — satisfied
계약: 느린 조회 중 이전 본문 대신 대상 로딩 안내를 표시한다
구현 근거: dashboard/common.py; render_dashboard_body가 이전 placeholder를 비우고 대상 loading을 먼저 표시한다. 실제 browser loading frame 2개 모두 previous body visible이 false이고 완료 후 loading이 제거된다
테스트 근거: tests/test_dashboard_menu_transition.py
판정 근거: 정적 source ordered unit events와 실제 전환 관찰을 함께 확인했다
구현 근거: dashboard/app.py, dashboard/common.py; callback은 마지막 dashboard_page만 query에 기록하고 main은 그 선택의 dispatch를 수행한다. rapid callback test는 Import 최종 선택과 sibling 보존을 확인하며 AppTest는 선택된 page body를 확인한다
테스트 근거: tests/test_dashboard_menu_transition.py
판정 근거: 직렬화된 callback의 최종 선택이 dispatch로 연결된다
AC-006 — satisfied
계약: 기존 page 직접 접속 요약 fallback과 페이지별 query 호환성을 유지한다
구현 근거: dashboard/app.py, dashboard/common.py; known direct page unknown missing fallback tests와 sibling query mapping 및 AppTest month 보존을 확인했다. 기존 page_views는 변경되지 않았다
테스트 근거: tests/test_dashboard_menu_transition.py, tests/test_dashboard_app.py
판정 근거: page key 외 query 해석을 변경하지 않는다
AC-007 — satisfied
계약: 인증 전 DB gateway page 접근 차단 cookie 만료 rotation logout cleanup과 보호 데이터 비노출을 유지한다
구현 근거: dashboard/app.py; main의 gate는 DB path 및 page dispatch보다 먼저 종료한다. 기존 authentication server token 구현은 변경되지 않았다. invalid cookie gate no cookie expiry rotation cleanup logout와 UI state 비노출 테스트 내용을 검토했다
테스트 근거: tests/test_dashboard_authentication_app.py, tests/test_dashboard_persistent_authentication.py, tests/test_dashboard_auth_server.py
판정 근거: 기존 인증 실패 경계와 회귀 의미가 보존된다. 구현자 full suite 실행을 인정하며 reviewer 독립 실행으로 표현하지 않는다
AC-008 — satisfied
계약: 금융 기능과 cache clear를 유지하고 synthetic DB로 핵심 페이지 회귀를 검증한다
구현 근거: dashboard/app.py, dashboard/common.py; finance renderer gateway schema는 변경되지 않았고 main은 기존 dispatch callable을 그대로 사용한다. refresh test는 clear cache 후 rerun을 검증하며 기존 synthetic core page expected text metric assertions를 확인했다
테스트 근거: tests/test_dashboard_menu_transition.py, tests/test_dashboard_app.py
판정 근거: 새 금융 멱등성이나 운영 DB 검증을 요구하지 않으며 기존 금융 의미를 보존한다
AC-009 — satisfied
계약: 기존 dependency 최소 수정 범위를 유지하고 승인된 실제 Dashboard browser 관찰과 AppTest 회귀를 수행한다
구현 근거: dashboard/app.py, dashboard/common.py, scripts/streamlit_browser_evidence.py, docs/evidence/issue-9-dashboard-menu-transition/README.md, docs/evidence/issue-9-dashboard-menu-transition/rework-verification-plan.json, docs/evidence/issue-9-dashboard-menu-transition/rework-verification.json; pyproject uv lock은 불변이다. 구현자 source f01dc182ec full suite 149 passed 4 skipped exit 0 및 lint compile 결과를 확인했다. source to reviewed head 전체 diff는 실행 기록 JSON 2개뿐이다. browser는 exact hash 입력으로 연결했다
테스트 근거: tests/test_dashboard_menu_transition.py, tests/test_streamlit_browser_evidence.py
판정 근거: 실행 입력과 후속 evidence-only 변경을 대조하여 근거를 재사용한다. 현재 head CI 성공이나 reviewer 제품 테스트 실행은 주장하지 않는다
DOC-001 — satisfied
계약: 정확한 REQ-002 경로 제목 canonical 요구사항 계약 Issue 구현 PR 실행 증거 추적성을 신규 작성한다
구현 근거: docs/requirements/req-002_dashboard-menu-transition.md; REQ-002 metadata 목적 배경 범위 용어 요구사항 제약 AC 오류 데이터 인터페이스 하위호환 검증 추적성 결정 질문 승인 기록을 확인했다. 9개 Impact 및 AC Cases State Invariants가 명시됐다
계약: REQ-002에 모든 메뉴 전환 인증 금융 cache clear 브라우저 AppTest 조건과 제외 범위를 기록한다
구현 근거: docs/requirements/req-002_dashboard-menu-transition.md; 요구사항 5와 인수 기준 7 및 하위호환성 10은 REQ-001 expiry rotation cleanup logout AC와 실제 테스트로 연결한다. history URL 금융 재설계를 제외한다
테스트 근거: tests/test_dashboard_authentication_app.py, tests/test_dashboard_persistent_authentication.py, tests/test_dashboard_auth_server.py, tests/test_dashboard_menu_transition.py
판정 근거: review 56 인증 회귀 추적성 누락을 기존 REQ-001 의미와 테스트 참조로 해소했다
DOC-003 — satisfied
계약: 인터페이스 정본을 제자리 갱신하며 메뉴 본문 로딩 오류 query를 기술하고 기존 인증 MCP 계약을 보존한다
구현 근거: docs/interface-contract.md; Dashboard 메뉴 전환 계약에서 10개 options selected state query sibling loading generic error retry serialized selection을 기록하고 기존 인증 부분을 유지했다
테스트 근거: tests/test_dashboard_menu_transition.py
판정 근거: 신규 history path URL 계약을 추가하지 않는다
DOC-004 — satisfied
계약: 프로젝트 구조에 app common page_views 책임 의존 방향 REQ-002 AppTest browser 배치 규칙을 기록한다
구현 근거: docs/project-structure.md; dashboard-source 책임 표와 common theme ownership 문단 및 verification browser deployment docs 의존 방향 변경 규칙을 확인했다
테스트 근거: tests/test_dashboard_menu_transition.py, tests/test_streamlit_browser_evidence.py
판정 근거: review 56 common style 및 app shell body 책임 누락을 해소했다
DOC-005 — satisfied
계약: 런타임에 인증 후 선택 공통 화면 본문 로딩 오류 최신 선택 금융 재실행 방지와 비민감 관찰 경계를 기록한다
구현 근거: docs/runtime-flow.md; transition 01부터 04 error와 invariants verification boundary에 gate 선행 query body loading retry와 명시적 금융 action 경계를 기록했다
테스트 근거: tests/test_dashboard_menu_transition.py
판정 근거: review 56 의도치 않은 금융 쓰기 외부 호출 재실행 방지 제약을 보완했으며 기존 auth startup TTL logout flow를 유지한다
DOC-006 — satisfied
계약: 데이터 모델 영향 없음과 모든 제외 범위를 지킨다
구현 근거: 없음; data model 문서는 생성되지 않았고 변경 15개는 메뉴 구현 문서 테스트 검증 도구와 실행 artifact로 설명된다. 금융 schema 인증 route dependency MCP history bridge는 변경되지 않았다
테스트 근거: 없음
판정 근거: 필수 supporting evidence 추가를 범위 초과로 오인하지 않으며 새 요구사항을 만들지 않는다
범위 판정
누락: 없음
범위 초과: 없음
명세 모순: 없음
결론
승인된 Issue 9 계약의 필수 구현 문서 테스트와 실제 Dashboard 브라우저 관찰을 충족한다. 이전 review 56의 배경 관찰 및 요구사항 인증 추적성 책임 경계 금융 재실행 방지 문서 지적은 해소됐다. 구현자 실행 보고를 source revision과 전체 후속 diff 및 exact 입력 hash로 연결했으며 reviewer 독립 제품 테스트나 현재 head CI 성공으로 표현하지 않는다. 표본 관찰과 synthetic fixture 및 임시 HTTPS ingress의 한계를 유지한다.
## 구현 명세 적합성 검토
- Source Issue: #9
- Pull Request: #10
- Reviewed head: `1ebc53d152159958039c43401b9693a335eb66a5`
- Contract SHA-256: `63f6c1538b1defa2fd0e944c75dee264d9d11ee01409aa05ff22784c19640aa3`
- Verdict: `approve`
### Acceptance criteria 판정
- `AC-001` — `satisfied`
- 계약: 기존 10개 메뉴의 표시명 순서 선택 강조와 정상 전환을 유지한다
- 구현 근거: dashboard/app.py, dashboard/common.py; app main의 10개 dispatch와 common radio selected state 및 label order test를 확인했다
- 테스트 근거: tests/test_dashboard_menu_transition.py
- 판정 근거: 공통 dispatch와 기존 메뉴 정체성이 보존된다
- `AC-002` — `satisfied`
- 계약: document 전체 이동을 피하고 메뉴 공통 배경을 유지하며 본문만 전환한다
- 구현 근거: dashboard/app.py, dashboard/common.py, docs/evidence/issue-9-dashboard-menu-transition/browser-observations.json, docs/evidence/issue-9-dashboard-menu-transition/manifest.json, docs/evidence/issue-9-dashboard-menu-transition/final-state.jpg; 실제 authenticated Dashboard 구현자 관찰의 35개 frame에서 앱 sidebar gradient 스타일 가시성 geometry document sidebar identity가 동일하고 document load는 0건이다. 입력 hash 5개와 artifact hash 2개를 reviewed head blob과 직접 대조했다. 이전 review 56 배경 관찰 누락을 해소했다
- 테스트 근거: tests/test_dashboard_menu_transition.py, tests/test_streamlit_browser_evidence.py
- 판정 근거: 최종 screenshot만 아닌 전환 중 스타일 근거로 충족한다. 50 ms 표본과 임시 HTTPS ingress의 한계를 인정하며 모든 순간 pixel 연속성으로 과장하지 않는다
- `AC-003` — `satisfied`
- 계약: 느린 조회 중 이전 본문 대신 대상 로딩 안내를 표시한다
- 구현 근거: dashboard/common.py; render_dashboard_body가 이전 placeholder를 비우고 대상 loading을 먼저 표시한다. 실제 browser loading frame 2개 모두 previous body visible이 false이고 완료 후 loading이 제거된다
- 테스트 근거: tests/test_dashboard_menu_transition.py
- 판정 근거: 정적 source ordered unit events와 실제 전환 관찰을 함께 확인했다
- `AC-004` — `satisfied`
- 계약: 본문 실패는 비민감 오류와 재시도 안내로 국소 처리한다
- 구현 근거: dashboard/common.py; renderer exception에서 body만 clear하고 generic error와 retry control을 제공한다. test_body_error_is_local_and_retry_rerenders_target는 secret detail 미노출과 rerun을 확인한다
- 테스트 근거: tests/test_dashboard_menu_transition.py
- 판정 근거: 인증 shell과 오류 본문의 책임이 분리되며 민감 예외를 공개하지 않는다
- `AC-005` — `satisfied`
- 계약: 연속 메뉴 클릭 후 최종 선택과 본문이 일치한다
- 구현 근거: dashboard/app.py, dashboard/common.py; callback은 마지막 dashboard_page만 query에 기록하고 main은 그 선택의 dispatch를 수행한다. rapid callback test는 Import 최종 선택과 sibling 보존을 확인하며 AppTest는 선택된 page body를 확인한다
- 테스트 근거: tests/test_dashboard_menu_transition.py
- 판정 근거: 직렬화된 callback의 최종 선택이 dispatch로 연결된다
- `AC-006` — `satisfied`
- 계약: 기존 page 직접 접속 요약 fallback과 페이지별 query 호환성을 유지한다
- 구현 근거: dashboard/app.py, dashboard/common.py; known direct page unknown missing fallback tests와 sibling query mapping 및 AppTest month 보존을 확인했다. 기존 page_views는 변경되지 않았다
- 테스트 근거: tests/test_dashboard_menu_transition.py, tests/test_dashboard_app.py
- 판정 근거: page key 외 query 해석을 변경하지 않는다
- `AC-007` — `satisfied`
- 계약: 인증 전 DB gateway page 접근 차단 cookie 만료 rotation logout cleanup과 보호 데이터 비노출을 유지한다
- 구현 근거: dashboard/app.py; main의 gate는 DB path 및 page dispatch보다 먼저 종료한다. 기존 authentication server token 구현은 변경되지 않았다. invalid cookie gate no cookie expiry rotation cleanup logout와 UI state 비노출 테스트 내용을 검토했다
- 테스트 근거: tests/test_dashboard_authentication_app.py, tests/test_dashboard_persistent_authentication.py, tests/test_dashboard_auth_server.py
- 판정 근거: 기존 인증 실패 경계와 회귀 의미가 보존된다. 구현자 full suite 실행을 인정하며 reviewer 독립 실행으로 표현하지 않는다
- `AC-008` — `satisfied`
- 계약: 금융 기능과 cache clear를 유지하고 synthetic DB로 핵심 페이지 회귀를 검증한다
- 구현 근거: dashboard/app.py, dashboard/common.py; finance renderer gateway schema는 변경되지 않았고 main은 기존 dispatch callable을 그대로 사용한다. refresh test는 clear cache 후 rerun을 검증하며 기존 synthetic core page expected text metric assertions를 확인했다
- 테스트 근거: tests/test_dashboard_menu_transition.py, tests/test_dashboard_app.py
- 판정 근거: 새 금융 멱등성이나 운영 DB 검증을 요구하지 않으며 기존 금융 의미를 보존한다
- `AC-009` — `satisfied`
- 계약: 기존 dependency 최소 수정 범위를 유지하고 승인된 실제 Dashboard browser 관찰과 AppTest 회귀를 수행한다
- 구현 근거: dashboard/app.py, dashboard/common.py, scripts/streamlit_browser_evidence.py, docs/evidence/issue-9-dashboard-menu-transition/README.md, docs/evidence/issue-9-dashboard-menu-transition/rework-verification-plan.json, docs/evidence/issue-9-dashboard-menu-transition/rework-verification.json; pyproject uv lock은 불변이다. 구현자 source f01dc182ec4d9b04e30d1d5bc13652a561332f24 full suite 149 passed 4 skipped exit 0 및 lint compile 결과를 확인했다. source to reviewed head 전체 diff는 실행 기록 JSON 2개뿐이다. browser는 exact hash 입력으로 연결했다
- 테스트 근거: tests/test_dashboard_menu_transition.py, tests/test_streamlit_browser_evidence.py
- 판정 근거: 실행 입력과 후속 evidence-only 변경을 대조하여 근거를 재사용한다. 현재 head CI 성공이나 reviewer 제품 테스트 실행은 주장하지 않는다
- `DOC-001` — `satisfied`
- 계약: 정확한 REQ-002 경로 제목 canonical 요구사항 계약 Issue 구현 PR 실행 증거 추적성을 신규 작성한다
- 구현 근거: docs/requirements/req-002_dashboard-menu-transition.md; REQ-002 metadata 목적 배경 범위 용어 요구사항 제약 AC 오류 데이터 인터페이스 하위호환 검증 추적성 결정 질문 승인 기록을 확인했다. 9개 Impact 및 AC Cases State Invariants가 명시됐다
- 테스트 근거: tests/test_dashboard_menu_transition.py
- 판정 근거: review 56 canonical 구조 누락을 보완하며 구현 PR이 존재하므로 10으로 연결한다
- `DOC-002` — `satisfied`
- 계약: REQ-002에 모든 메뉴 전환 인증 금융 cache clear 브라우저 AppTest 조건과 제외 범위를 기록한다
- 구현 근거: docs/requirements/req-002_dashboard-menu-transition.md; 요구사항 5와 인수 기준 7 및 하위호환성 10은 REQ-001 expiry rotation cleanup logout AC와 실제 테스트로 연결한다. history URL 금융 재설계를 제외한다
- 테스트 근거: tests/test_dashboard_authentication_app.py, tests/test_dashboard_persistent_authentication.py, tests/test_dashboard_auth_server.py, tests/test_dashboard_menu_transition.py
- 판정 근거: review 56 인증 회귀 추적성 누락을 기존 REQ-001 의미와 테스트 참조로 해소했다
- `DOC-003` — `satisfied`
- 계약: 인터페이스 정본을 제자리 갱신하며 메뉴 본문 로딩 오류 query를 기술하고 기존 인증 MCP 계약을 보존한다
- 구현 근거: docs/interface-contract.md; Dashboard 메뉴 전환 계약에서 10개 options selected state query sibling loading generic error retry serialized selection을 기록하고 기존 인증 부분을 유지했다
- 테스트 근거: tests/test_dashboard_menu_transition.py
- 판정 근거: 신규 history path URL 계약을 추가하지 않는다
- `DOC-004` — `satisfied`
- 계약: 프로젝트 구조에 app common page_views 책임 의존 방향 REQ-002 AppTest browser 배치 규칙을 기록한다
- 구현 근거: docs/project-structure.md; dashboard-source 책임 표와 common theme ownership 문단 및 verification browser deployment docs 의존 방향 변경 규칙을 확인했다
- 테스트 근거: tests/test_dashboard_menu_transition.py, tests/test_streamlit_browser_evidence.py
- 판정 근거: review 56 common style 및 app shell body 책임 누락을 해소했다
- `DOC-005` — `satisfied`
- 계약: 런타임에 인증 후 선택 공통 화면 본문 로딩 오류 최신 선택 금융 재실행 방지와 비민감 관찰 경계를 기록한다
- 구현 근거: docs/runtime-flow.md; transition 01부터 04 error와 invariants verification boundary에 gate 선행 query body loading retry와 명시적 금융 action 경계를 기록했다
- 테스트 근거: tests/test_dashboard_menu_transition.py
- 판정 근거: review 56 의도치 않은 금융 쓰기 외부 호출 재실행 방지 제약을 보완했으며 기존 auth startup TTL logout flow를 유지한다
- `DOC-006` — `satisfied`
- 계약: 데이터 모델 영향 없음과 모든 제외 범위를 지킨다
- 구현 근거: 없음; data model 문서는 생성되지 않았고 변경 15개는 메뉴 구현 문서 테스트 검증 도구와 실행 artifact로 설명된다. 금융 schema 인증 route dependency MCP history bridge는 변경되지 않았다
- 테스트 근거: 없음
- 판정 근거: 필수 supporting evidence 추가를 범위 초과로 오인하지 않으며 새 요구사항을 만들지 않는다
### 범위 판정
- 누락: 없음
- 범위 초과: 없음
- 명세 모순: 없음
### 결론
승인된 Issue 9 계약의 필수 구현 문서 테스트와 실제 Dashboard 브라우저 관찰을 충족한다. 이전 review 56의 배경 관찰 및 요구사항 인증 추적성 책임 경계 금융 재실행 방지 문서 지적은 해소됐다. 구현자 실행 보고를 source revision과 전체 후속 diff 및 exact 입력 hash로 연결했으며 reviewer 독립 제품 테스트나 현재 head CI 성공으로 표현하지 않는다. 표본 관찰과 synthetic fixture 및 임시 HTTPS ingress의 한계를 유지한다.
<!-- gitea-agent:implementation-spec-review/v1 owner=jsfamily repository=jarca-ledger-mcp issue=9 pr=10 head=1ebc53d152159958039c43401b9693a335eb66a5 contract-sha256=63f6c1538b1defa2fd0e944c75dee264d9d11ee01409aa05ff22784c19640aa3 result-sha256=7966a0bcc06ad5a2519f38e2f81d46ea0402279c8f835f4fd3774963124baa9a correlation=160c083eee2e9748fc03a5a6d9303729d3ab6e4f272e9c9bd451397f91f7c443 -->
Reviewer: gitea-review-agent (stable account ID 7); spec ID 5와 impl ID 6과 독립
차단 finding: 0. 비차단 finding: 2.
검토 범위와 판정
전체 15개 변경 파일과 binary screenshot을 포함한 diff, app/common 주변 코드, page renderer와 금융 action caller, 인증 gate·cookie·expiry/rotation/logout/cleanup 테스트, 신규 전환/증거 테스트 및 문서를 검토했다. 현재 worktree의 tracked 128개 파일을 reviewed-head Git blob과 비교해 불일치 0을 확인했다.
기존 10개 메뉴와 allowlist/fallback, page-only query 갱신, 인증 이후 DB path/dispatch 순서, 본문 placeholder의 로딩/오류/재시도, 기존 cache-clear와 금융 renderer 연결을 확인했다. 승인된 history/back-forward 제외 범위를 확대하지 않았다. 미해결 중요 구현 결함 또는 이번 승인에 필요한 검증 공백은 발견하지 않았다. 아래 증거 도구 개선은 현재 저장된 실행 근거를 독립 재검증했으므로 별도 후속 작업으로 다룰 수 있다.
Reviewer 직접 실행
전체 suite: PYTHONDONTWRITEBYTECODE=1 timeout --signal=TERM --kill-after=5s 420s .venv/bin/python -B -m pytest -p no:cacheprovider --basetemp=<review-run>/pytest-retry-tmp --junitxml=<review-run>/pytest-retry.xml -rs -vv -o faulthandler_timeout=45 — exit 0, 149 passed / 4 skipped / 153 total, failures/errors 0, 301.75초. JUnit의 개수와 skip 원인을 대조했다. KB PDF/password 및 Toss PDF 실물 sample 부재에 따른 기존 4개 skip은 변경 영역 밖이며 운영 자료로 보완하지 않았다.
첫 동일 suite 시도는 240초 timeout, exit 124, 결과 미완료였다. 통과로 간주하지 않고 보존했다. /opt/data 및 fixture scratch가 NFS인 실행 조건을 확인했고 상세 로그를 켠 재실행에서 완료했다. 최초 timeout 원인의 단일 인과는 확정하지 않는다.
격리된 synthetic DB의 실제 AppTest: 기존 10개 radio 메뉴를 모두 순차 전환해 selection/query/sibling/완료 후 loading 제거 및 예외·error 0을 확인했다. renderer fault injection으로 부분 본문 제거·민감 예외 상세 비노출·retry 후 실제 target 복원을 확인했다. 메뉴 rerun 시 cookie를 거부하면 보호 본문과 메뉴가 사라지는 것도 확인했다. 실행 exit 0; 임시 DB는 정리됐다. 이는 browser 검증이 아니다.
.venv/bin/python -B의 AST parse — exit 0, Python 파일 46개 통과. source/bytecode 쓰기 없이 수행했다.
committed browser validator와 documentation inventory를 current head에서 재실행 — 각각 exit 0. input hash 5개, artifact hash 2개, 문서 항목/Impact/Cases/State Invariants 각 9개를 확인했다.
환경: Linux aarch64, Python 3.13.5, Streamlit 1.58.0, pytest 9.1.1. 기존 clean·detached·registered·locked impl worktree를 검증 전용으로 사용했고 source/test/Git refs/state를 수정하지 않았다.
재사용 근거와 한계
구현자의 full-suite 기록은 source f01dc182ec4d9b04e30d1d5bc13652a561332f24의 149 passed/4 skipped다. current head까지 전체 후속 diff는 실행 기록 JSON 두 개뿐이다. reviewer의 직접 실행과 구분한다.
구현자의 실제 authenticated Dashboard 브라우저 요약 → 분류 규칙 관찰은 35 frames, nominal 50 ms, 1280×720, loading 2 frames다. source/artifact hash가 current head와 일치한다. 모든 frame의 app/sidebar surface 값과 document/sidebar marker를 직접 대조했고, 모든 loading frame의 이전 본문 부재 및 최종 selected/query/target-body/sibling 일치를 확인했다. 저장된 데이터는 아래 F-001/F-002 영향을 받지 않는다.
이 리뷰에서 새 browser capture를 수행한 것은 아니다. 해당 실행은 synthetic fixture와 임시 HTTPS ingress를 사용했고 tunnel은 만료된 provenance다. 표본 사이 모든 순간의 pixel 연속성 또는 모든 경쟁 interleaving을 증명하지 않는다. 최종 screenshot은 완료 화면 보조 근거일 뿐이다.
head status contexts는 0이다. CI 성공으로 표현하지 않는다. 병렬 static worker가 요청 범위를 벗어나 실행한 테스트 보고는 reviewer 직접 통과 수에 포함하지 않았다.
비차단 findings
F-001 — 중간 frame 배경 변경을 놓치는 local evidence validator (Low, non-blocking)
조건: pre/post surface는 동일하고 중간 frame만 다른 non-none gradient로 바뀌되 visible/rendered 상태는 유지한다.
실패/영향: 각 frame은 유효한 배경의 존재만 검사하고 style equality는 endpoints만 검사한다. 3-frame deterministic probe에서 중간 app background를 완전 흰 gradient로 바꿔도 validate_transition_manifest()가 통과했다. 따라서 향후 capture에서 전환 중 공통 배경 변화의 false-positive 승인 가능성이 있다.
계약 관계: Issue #9의 공통 배경 유지 관찰을 지원하는 verifier의 검출력 문제이지, 이번 Dashboard가 흰 화면으로 전환한다는 증거가 아니다. current 저장된 35개 frame은 모든 surface가 baseline과 동일함을 reviewer가 별도로 확인해 이번 승인 근거에는 공백이 없다.
제한된 보완: 유지돼야 하는 computed background/style 값을 모든 frame에서 baseline과 비교하고 intermediate-only drift 회귀 테스트를 추가한다. viewport geometry 변화 등 허용할 필드는 별도로 정의한다.
실패/영향: validator는 target와 Boolean agreement만 검사하며 final_url을 parse하거나 pre/post query를 대조하지 않는다. wrong-origin/wrong-page URL의 deterministic probe도 통과했다. 향후 artifact 내부의 URL/selection 모순을 검출하지 못한다.
계약 관계: 기존 page/sibling query 보존 근거의 검출력 문제다. 현재 앱의 callback은 page만 변경하고 direct AppTest 및 저장된 browser pre/post URL은 실제 일치하므로 이번 구현에 대한 변경 요청 사유는 아니다.
제한된 보완: pre/post URL을 함께 기록하고 origin/path, target page, page 이외 query의 원문 key/value 목록을 검증한다. wrong-page/sibling-loss 회귀 테스트를 추가한다. history/back-forward 기능 보장은 추가하지 않는다.
경계와 후속 조치
source 수정, commit/push/merge/deploy, Issue 변경, review dismiss는 수행하지 않았다. 리뷰 기록만 게시한다. 두 비차단 항목은 별도 추적 가능하며 rework blocker로 확대하지 않는다. 이 승인은 stated scope에서 중요 결함을 발견하지 않았다는 뜻이고 무결함 또는 merge/release 승인이라는 뜻이 아니다.
<!-- gitea-agent:code-review/v1 owner=jsfamily repository=jarca-ledger-mcp issue=9 pr=10 head=1ebc53d152159958039c43401b9693a335eb66a5 contract-sha256=63f6c1538b1defa2fd0e944c75dee264d9d11ee01409aa05ff22784c19640aa3 -->
## 독립 코드 리뷰 — Issue #9 / PR #10
- Verdict: `approve`
- Reviewed head: `1ebc53d152159958039c43401b9693a335eb66a5`
- Base: `ffd943fe65875e67148c28ba44bae32918e338c9`
- Contract SHA-256: `63f6c1538b1defa2fd0e944c75dee264d9d11ee01409aa05ff22784c19640aa3`
- Spec approval: native review #57, exact head/contract, nonstale/nondismissed
- Reviewer: `gitea-review-agent` (stable account ID 7); spec ID 5와 impl ID 6과 독립
- 차단 finding: 0. 비차단 finding: 2.
### 검토 범위와 판정
전체 15개 변경 파일과 binary screenshot을 포함한 diff, app/common 주변 코드, page renderer와 금융 action caller, 인증 gate·cookie·expiry/rotation/logout/cleanup 테스트, 신규 전환/증거 테스트 및 문서를 검토했다. 현재 worktree의 tracked 128개 파일을 reviewed-head Git blob과 비교해 불일치 0을 확인했다.
기존 10개 메뉴와 allowlist/fallback, page-only query 갱신, 인증 이후 DB path/dispatch 순서, 본문 placeholder의 로딩/오류/재시도, 기존 cache-clear와 금융 renderer 연결을 확인했다. 승인된 history/back-forward 제외 범위를 확대하지 않았다. 미해결 중요 구현 결함 또는 이번 승인에 필요한 검증 공백은 발견하지 않았다. 아래 증거 도구 개선은 현재 저장된 실행 근거를 독립 재검증했으므로 별도 후속 작업으로 다룰 수 있다.
### Reviewer 직접 실행
- 전체 suite: `PYTHONDONTWRITEBYTECODE=1 timeout --signal=TERM --kill-after=5s 420s .venv/bin/python -B -m pytest -p no:cacheprovider --basetemp=<review-run>/pytest-retry-tmp --junitxml=<review-run>/pytest-retry.xml -rs -vv -o faulthandler_timeout=45` — exit 0, **149 passed / 4 skipped / 153 total**, failures/errors 0, 301.75초. JUnit의 개수와 skip 원인을 대조했다. KB PDF/password 및 Toss PDF 실물 sample 부재에 따른 기존 4개 skip은 변경 영역 밖이며 운영 자료로 보완하지 않았다.
- 첫 동일 suite 시도는 240초 timeout, exit 124, 결과 미완료였다. 통과로 간주하지 않고 보존했다. /opt/data 및 fixture scratch가 NFS인 실행 조건을 확인했고 상세 로그를 켠 재실행에서 완료했다. 최초 timeout 원인의 단일 인과는 확정하지 않는다.
- 격리된 synthetic DB의 실제 AppTest: 기존 10개 radio 메뉴를 모두 순차 전환해 selection/query/sibling/완료 후 loading 제거 및 예외·error 0을 확인했다. renderer fault injection으로 부분 본문 제거·민감 예외 상세 비노출·retry 후 실제 target 복원을 확인했다. 메뉴 rerun 시 cookie를 거부하면 보호 본문과 메뉴가 사라지는 것도 확인했다. 실행 exit 0; 임시 DB는 정리됐다. 이는 browser 검증이 아니다.
- `.venv/bin/ruff check --no-cache dashboard tests scripts` — exit 0, All checks passed.
- `.venv/bin/python -B`의 AST parse — exit 0, Python 파일 46개 통과. source/bytecode 쓰기 없이 수행했다.
- committed browser validator와 documentation inventory를 current head에서 재실행 — 각각 exit 0. input hash 5개, artifact hash 2개, 문서 항목/Impact/Cases/State Invariants 각 9개를 확인했다.
환경: Linux aarch64, Python 3.13.5, Streamlit 1.58.0, pytest 9.1.1. 기존 clean·detached·registered·locked impl worktree를 검증 전용으로 사용했고 source/test/Git refs/state를 수정하지 않았다.
### 재사용 근거와 한계
- 구현자의 full-suite 기록은 source `f01dc182ec4d9b04e30d1d5bc13652a561332f24`의 149 passed/4 skipped다. current head까지 전체 후속 diff는 실행 기록 JSON 두 개뿐이다. reviewer의 직접 실행과 구분한다.
- 구현자의 실제 authenticated Dashboard 브라우저 `요약 → 분류 규칙` 관찰은 35 frames, nominal 50 ms, 1280×720, loading 2 frames다. source/artifact hash가 current head와 일치한다. 모든 frame의 app/sidebar surface 값과 document/sidebar marker를 직접 대조했고, 모든 loading frame의 이전 본문 부재 및 최종 selected/query/target-body/sibling 일치를 확인했다. 저장된 데이터는 아래 F-001/F-002 영향을 받지 않는다.
- 이 리뷰에서 새 browser capture를 수행한 것은 아니다. 해당 실행은 synthetic fixture와 임시 HTTPS ingress를 사용했고 tunnel은 만료된 provenance다. 표본 사이 모든 순간의 pixel 연속성 또는 모든 경쟁 interleaving을 증명하지 않는다. 최종 screenshot은 완료 화면 보조 근거일 뿐이다.
- head status contexts는 0이다. CI 성공으로 표현하지 않는다. 병렬 static worker가 요청 범위를 벗어나 실행한 테스트 보고는 reviewer 직접 통과 수에 포함하지 않았다.
### 비차단 findings
#### F-001 — 중간 frame 배경 변경을 놓치는 local evidence validator (Low, non-blocking)
- 위치: `scripts/streamlit_browser_evidence.py:330-347,378-384`.
- 조건: pre/post surface는 동일하고 중간 frame만 다른 non-none gradient로 바뀌되 visible/rendered 상태는 유지한다.
- 실패/영향: 각 frame은 유효한 배경의 존재만 검사하고 style equality는 endpoints만 검사한다. 3-frame deterministic probe에서 중간 app background를 완전 흰 gradient로 바꿔도 `validate_transition_manifest()`가 통과했다. 따라서 향후 capture에서 전환 중 공통 배경 변화의 false-positive 승인 가능성이 있다.
- 계약 관계: Issue #9의 공통 배경 유지 관찰을 지원하는 verifier의 검출력 문제이지, 이번 Dashboard가 흰 화면으로 전환한다는 증거가 아니다. current 저장된 35개 frame은 모든 surface가 baseline과 동일함을 reviewer가 별도로 확인해 이번 승인 근거에는 공백이 없다.
- 제한된 보완: 유지돼야 하는 computed background/style 값을 모든 frame에서 baseline과 비교하고 intermediate-only drift 회귀 테스트를 추가한다. viewport geometry 변화 등 허용할 필드는 별도로 정의한다.
#### F-002 — 수집한 URL과 target/query 계약의 일관성을 verifier가 검사하지 않음 (Low, non-blocking)
- 위치: `scripts/streamlit_browser_evidence.py:392-395,507-517`.
- 조건: `final_agreement=True`인 manifest의 `final_url`을 다른 origin/다른 page로 바꾸거나 sibling query를 누락한다.
- 실패/영향: validator는 target와 Boolean agreement만 검사하며 `final_url`을 parse하거나 pre/post query를 대조하지 않는다. wrong-origin/wrong-page URL의 deterministic probe도 통과했다. 향후 artifact 내부의 URL/selection 모순을 검출하지 못한다.
- 계약 관계: 기존 page/sibling query 보존 근거의 검출력 문제다. 현재 앱의 callback은 page만 변경하고 direct AppTest 및 저장된 browser pre/post URL은 실제 일치하므로 이번 구현에 대한 변경 요청 사유는 아니다.
- 제한된 보완: pre/post URL을 함께 기록하고 origin/path, target `page`, page 이외 query의 원문 key/value 목록을 검증한다. wrong-page/sibling-loss 회귀 테스트를 추가한다. history/back-forward 기능 보장은 추가하지 않는다.
### 경계와 후속 조치
source 수정, commit/push/merge/deploy, Issue 변경, review dismiss는 수행하지 않았다. 리뷰 기록만 게시한다. 두 비차단 항목은 별도 추적 가능하며 rework blocker로 확대하지 않는다. 이 승인은 stated scope에서 중요 결함을 발견하지 않았다는 뜻이고 무결함 또는 merge/release 승인이라는 뜻이 아니다.
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
요약
?page=직접 접근, sibling query, dispatch와 refresh/cache 동작을 보존합니다.Review #56 재작업
backgroundImage,backgroundColor, visibility, display, opacity, rendered geometry를 35개 frame에 기록하고 fail-closed validator를 보강했습니다.app.py/common.py의 shell/body/style 책임 경계를 명시했습니다.검증
f01dc182ec4d9b04e30d1d5bc13652a561332f241ebc53d152159958039c43401b9693a335eb66a5uv run --extra dashboard --extra dev pytest— 149 passed, 4 skipped, 0 failures/errors (153 total), exit 0증거
docs/evidence/issue-9-dashboard-menu-transition/rework-verification.jsondocs/evidence/issue-9-dashboard-menu-transition/rework-verification-plan.jsondocs/evidence/issue-9-dashboard-menu-transition/manifest.jsondocs/evidence/issue-9-dashboard-menu-transition/browser-observations.jsondocs/evidence/issue-9-dashboard-menu-transition/final-state.jpgCloses #9
구현 명세 적합성 검토
a02aceee416c5770dfd1f35ac94367f3c4e0c8c863f6c1538b1defa2fd0e944c75dee264d9d11ee01409aa05ff22784c19640aa3request_changesAcceptance criteria 판정
AC-001—satisfiedAC-002—indeterminateAC-003—satisfiedAC-004—satisfiedAC-005—satisfiedAC-006—satisfiedAC-007—satisfiedAC-008—satisfiedDOC-001—unsatisfiedDOC-002—unsatisfiedDOC-003—satisfiedDOC-004—unsatisfiedDOC-005—unsatisfiedSCOPE-001—satisfied범위 판정
결론
문서 이동 없는 widget 전환과 본문 로딩 및 오류 처리와 query 및 인증 회귀의 구현 방향은 승인 범위에 맞는다. 그러나 실제 공통 배경 및 가시성 인수 관찰의 대상 불일치와 필수 문서 계약 누락이 남아 request_changes로 판정한다. 지적한 최소 문서 및 관찰 근거만 보완하고 history 기능과 새로운 금융 멱등성 또는 CI 및 별도 증거 저장 형식은 추가 요구하지 않는다. 구현자의 테스트와 browser 실행 보고를 검토했으며 reviewer 독립 제품 실행은 수행하지 않았다.
구현 재작업 결과
a02aceee416c5770dfd1f35ac94367f3c4e0c8c81ebc53d152159958039c43401b9693a335eb66a563f6c1538b1defa2fd0e944c75dee264d9d11ee01409aa05ff22784c19640aa3rework_delivered지적 처리
AC-002—resolvedevidence_gapscripts/streamlit_browser_evidence.py,tests/test_streamlit_browser_evidence.py,docs/evidence/issue-9-dashboard-menu-transition/stAppViewContainer와stSidebar의 background, visibility, display, opacity와 rendered geometry를 모든 frame에서 기록하고 fail-closed 검증했다.DOC-001—resolvedvalid_fixdocs/requirements/req-002_dashboard-menu-transition.mdDOC-002—resolvedvalid_fixdocs/requirements/req-002_dashboard-menu-transition.mdDOC-004—resolvedvalid_fixdocs/project-structure.mddashboard/app.py와dashboard/common.py의 shell/body/style 책임 및 의존 경계 정적 검사DOC-005—resolvedvalid_fixdocs/runtime-flow.md최종 검증
f01dc182ec4d9b04e30d1d5bc13652a561332f24;uv run --extra dashboard --extra dev pytestexit 0 — 149 passed, 4 skipped, 0 failures/errors; Ruff exit 0; compile exit 0; evidence manifest validation exit 0요약→분류 규칙; 35 frames; loading 2 frames; prior body absent in both; app/sidebar surfaces visible and stable; exact evidence atdocs/evidence/issue-9-dashboard-menu-transition/manifest.jsondocs/evidence/issue-9-dashboard-menu-transition/rework-verification.json, bound to source commitf01dc182ec4d9b04e30d1d5bc13652a561332f24; final head is its evidence-only descendant1ebc53d152159958039c43401b9693a335eb66a5, status contexts 0다음 단계
Reviewer가 rework head를 새 snapshot으로 다시 검토해야 하며 이 comment는 기존
REQUEST_CHANGES를 해제하거나 승인을 의미하지 않는다.구현 명세 적합성 검토
1ebc53d152159958039c43401b9693a335eb66a563f6c1538b1defa2fd0e944c75dee264d9d11ee01409aa05ff22784c19640aa3approveAcceptance criteria 판정
AC-001—satisfiedAC-002—satisfiedAC-003—satisfiedAC-004—satisfiedAC-005—satisfiedAC-006—satisfiedAC-007—satisfiedAC-008—satisfiedAC-009—satisfiedf01dc182ecfull suite 149 passed 4 skipped exit 0 및 lint compile 결과를 확인했다. source to reviewed head 전체 diff는 실행 기록 JSON 2개뿐이다. browser는 exact hash 입력으로 연결했다DOC-001—satisfiedDOC-002—satisfiedDOC-003—satisfiedDOC-004—satisfiedDOC-005—satisfiedDOC-006—satisfied범위 판정
결론
승인된 Issue 9 계약의 필수 구현 문서 테스트와 실제 Dashboard 브라우저 관찰을 충족한다. 이전 review 56의 배경 관찰 및 요구사항 인증 추적성 책임 경계 금융 재실행 방지 문서 지적은 해소됐다. 구현자 실행 보고를 source revision과 전체 후속 diff 및 exact 입력 hash로 연결했으며 reviewer 독립 제품 테스트나 현재 head CI 성공으로 표현하지 않는다. 표본 관찰과 synthetic fixture 및 임시 HTTPS ingress의 한계를 유지한다.
독립 코드 리뷰 — Issue #9 / PR #10
approve1ebc53d152159958039c43401b9693a335eb66a5ffd943fe65875e67148c28ba44bae32918e338c963f6c1538b1defa2fd0e944c75dee264d9d11ee01409aa05ff22784c19640aa3gitea-review-agent(stable account ID 7); spec ID 5와 impl ID 6과 독립검토 범위와 판정
전체 15개 변경 파일과 binary screenshot을 포함한 diff, app/common 주변 코드, page renderer와 금융 action caller, 인증 gate·cookie·expiry/rotation/logout/cleanup 테스트, 신규 전환/증거 테스트 및 문서를 검토했다. 현재 worktree의 tracked 128개 파일을 reviewed-head Git blob과 비교해 불일치 0을 확인했다.
기존 10개 메뉴와 allowlist/fallback, page-only query 갱신, 인증 이후 DB path/dispatch 순서, 본문 placeholder의 로딩/오류/재시도, 기존 cache-clear와 금융 renderer 연결을 확인했다. 승인된 history/back-forward 제외 범위를 확대하지 않았다. 미해결 중요 구현 결함 또는 이번 승인에 필요한 검증 공백은 발견하지 않았다. 아래 증거 도구 개선은 현재 저장된 실행 근거를 독립 재검증했으므로 별도 후속 작업으로 다룰 수 있다.
Reviewer 직접 실행
PYTHONDONTWRITEBYTECODE=1 timeout --signal=TERM --kill-after=5s 420s .venv/bin/python -B -m pytest -p no:cacheprovider --basetemp=<review-run>/pytest-retry-tmp --junitxml=<review-run>/pytest-retry.xml -rs -vv -o faulthandler_timeout=45— exit 0, 149 passed / 4 skipped / 153 total, failures/errors 0, 301.75초. JUnit의 개수와 skip 원인을 대조했다. KB PDF/password 및 Toss PDF 실물 sample 부재에 따른 기존 4개 skip은 변경 영역 밖이며 운영 자료로 보완하지 않았다..venv/bin/ruff check --no-cache dashboard tests scripts— exit 0, All checks passed..venv/bin/python -B의 AST parse — exit 0, Python 파일 46개 통과. source/bytecode 쓰기 없이 수행했다.환경: Linux aarch64, Python 3.13.5, Streamlit 1.58.0, pytest 9.1.1. 기존 clean·detached·registered·locked impl worktree를 검증 전용으로 사용했고 source/test/Git refs/state를 수정하지 않았다.
재사용 근거와 한계
f01dc182ec4d9b04e30d1d5bc13652a561332f24의 149 passed/4 skipped다. current head까지 전체 후속 diff는 실행 기록 JSON 두 개뿐이다. reviewer의 직접 실행과 구분한다.요약 → 분류 규칙관찰은 35 frames, nominal 50 ms, 1280×720, loading 2 frames다. source/artifact hash가 current head와 일치한다. 모든 frame의 app/sidebar surface 값과 document/sidebar marker를 직접 대조했고, 모든 loading frame의 이전 본문 부재 및 최종 selected/query/target-body/sibling 일치를 확인했다. 저장된 데이터는 아래 F-001/F-002 영향을 받지 않는다.비차단 findings
F-001 — 중간 frame 배경 변경을 놓치는 local evidence validator (Low, non-blocking)
scripts/streamlit_browser_evidence.py:330-347,378-384.validate_transition_manifest()가 통과했다. 따라서 향후 capture에서 전환 중 공통 배경 변화의 false-positive 승인 가능성이 있다.F-002 — 수집한 URL과 target/query 계약의 일관성을 verifier가 검사하지 않음 (Low, non-blocking)
scripts/streamlit_browser_evidence.py:392-395,507-517.final_agreement=True인 manifest의final_url을 다른 origin/다른 page로 바꾸거나 sibling query를 누락한다.final_url을 parse하거나 pre/post query를 대조하지 않는다. wrong-origin/wrong-page URL의 deterministic probe도 통과했다. 향후 artifact 내부의 URL/selection 모순을 검출하지 못한다.page, page 이외 query의 원문 key/value 목록을 검증한다. wrong-page/sibling-loss 회귀 테스트를 추가한다. history/back-forward 기능 보장은 추가하지 않는다.경계와 후속 조치
source 수정, commit/push/merge/deploy, Issue 변경, review dismiss는 수행하지 않았다. 리뷰 기록만 게시한다. 두 비차단 항목은 별도 추적 가능하며 rework blocker로 확대하지 않는다. 이 승인은 stated scope에서 중요 결함을 발견하지 않았다는 뜻이고 무결함 또는 merge/release 승인이라는 뜻이 아니다.