# Phase 4 Evidence: Feedback and Case Library Run Binding ## Scope Phase 4 implements run-scoped feedback and run-based automatic case creation: - Feedback request accepts preferred `runId`. - Feedback validates run/session ownership. - Missing `runId` falls back to the latest run and returns `fallbackToLatestRun=true` plus the bound `runId`. - New feedback persists to `diagnosis_run.feedback`. - Useful feedback creates or reuses `case_library` from `diagnosis_run.query` and `diagnosis_run.answer`. - New automatic `case_library.diagnosis_id` values store `run_id`; old `session_id` values remain supported through the legacy `DiagnosisSession` path. ## Focused Tests Focused tests: ```text mvn -q "-Dtest=FeedbackServiceTest,CaseLibraryServiceTest,FeedbackControllerTest" test ``` Result: passed. Coverage: - exact `sessionId + runId` feedback updates the specified run; - missing `runId` binds to latest run and returns `fallbackToLatestRun=true`; - wrong-session `runId` fails without saving feedback or case data; - useful feedback creates a case from the run; - case creation is idempotent by `diagnosis_id`; - legacy `DiagnosisSession` case creation still stores `diagnosis_id=session_id`; - `FeedbackController` passes `request.runId` to `FeedbackService`. ## E2E Feedback API Check Maven startup: ```text mvn spring-boot:run -Dspring-boot.run.profiles=mvp-demo ``` Captured artifacts: - `target/e2e/phase4-mvn-20260710-2016.out.log` - `target/e2e/phase4-mvn-20260710-2016.err.log` - `target/e2e/phase4-feedback-exact-run.json` - `target/e2e/phase4-feedback-fallback-latest.json` - `target/e2e/phase4-feedback-wrong-session.json` - `target/e2e/phase4-summary.json` The Maven process was stopped after evidence collection. Inputs reused the Phase 3 E2E session: ```text sessionId = e2e-phase3-codex-20260710-1912 run1 = run-fdccbe21-e050-4f92-a741-a062aef59644 run2 = run-a9b883ab-9cab-4eec-accf-38129bd2eb94 ``` API responses: ```text exact run feedback: status=200 runId=run-fdccbe21-e050-4f92-a741-a062aef59644 fallbackToLatestRun=false caseId=428b0cf8-d3b4-4f8a-a82e-4e815999d3ff legacy fallback feedback: status=200 runId=run-a9b883ab-9cab-4eec-accf-38129bd2eb94 fallbackToLatestRun=true caseId=null wrong-session feedback: status=400 success=false message=runId does not belong to sessionId ``` Log evidence from `phase4-mvn-20260710-2016.out.log`: - `反馈已记录: sessionId=e2e-phase3-codex-20260710-1912, runId=run-fdccbe21-e050-4f92-a741-a062aef59644, feedback=useful, fallbackToLatestRun=false, caseId=428b0cf8-d3b4-4f8a-a82e-4e815999d3ff` - `反馈已记录: sessionId=e2e-phase3-codex-20260710-1912, runId=run-a9b883ab-9cab-4eec-accf-38129bd2eb94, feedback=not_useful, fallbackToLatestRun=true, caseId=null` ## Database Inspection Queried through `scripts/query_mysql.py`. `diagnosis_run.feedback`: ```text run-a9b883ab-9cab-4eec-accf-38129bd2eb94 | feedback=not_useful | status=SUCCESS run-fdccbe21-e050-4f92-a741-a062aef59644 | feedback=useful | status=SUCCESS ``` `case_library`: ```text case_id=428b0cf8-d3b4-4f8a-a82e-4e815999d3ff diagnosis_id=run-fdccbe21-e050-4f92-a741-a062aef59644 source_type=AUTO title=支付接口最近出现超时,请结合知识库、日志和指标判断可能原因,并给出修复建议。 ``` No automatic case was created for the fallback `not_useful` feedback on run2. ## Final Gate The final Phase 4 gate was rerun after document review follow-up: ```text mvn -q clean test-compile mvn -q "-Dtest=FeedbackServiceTest,CaseLibraryServiceTest,FeedbackControllerTest,DiagnosisTraceServiceTest,ChatControllerTest" test openspec validate session-run-trace-isolation --strict git diff --check ``` Result: passed. ## Conclusion Phase 4 satisfies run-scoped feedback, observable latest-run fallback, run-based useful case creation, and transitional old-data compatibility for `case_library.diagnosis_id`.