feat(dashboard): complete governed semantic evidence paths - #614
Conversation
…hor-consumer # Conflicts: # backend/app/analysis_run_start.py
…perations-dashboard # Conflicts: # docs/adr/README.md
…r' into feat/evidence-operations-dashboard
…ions-dashboard feat(dashboard): add evidence-grounded operations workspace
# Conflicts: # backend/app/lineage_ingestion.py # backend/app/main.py # docs/product-technical-gap-baseline.md # frontend/src/App.tsx
This reverts commit bc182f1.
…r' into feat/tepp-lineage-anchor-consumer
…r' into feat/dashboard-live-evidence # Conflicts: # backend/app/post_chat_ingestion.py # backend/tests/test_api.py # docs/product-technical-gap-baseline.md # frontend/src/App.tsx # tests/test_global_ask_sources.py
|
Warning Review limit reachedNext included review available in 27 minutes. View limit detailsLimit details: You’ve used the included review currently available. You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository. Review configuration: ⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (42)
ℹ️ Recent review info⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (51)
Included review availability: Your plan provides up to 1 included review per hour; 0 remain after this review. 📝 WalkthroughWalkthroughTEPP lineage anchor 검증과 영속화를 추가했습니다. Global Ask를 embedding 검색으로 전환했습니다. 운영 사례 분석, Dashboard, Similar VOC API와 분석가용 UI를 추가했습니다. ChangesTEPP lineage anchor
Global Ask semantic retrieval
Evidence Operations Dashboard
Estimated code review effort: 5 (Critical) | ~120 minutes Merge Risk: 🟠 High · up to This PR changes semantic retrieval, live VOC comparison, dashboard access scoping, and evidence persistence, but the current implementation still permits out-of-scope dashboard data, can make Similar VOC slow or unavailable when a provider call fails, and can persist invalid or mismatched evidence. These correctness, privacy, and availability risks should be fixed before merge. Sequence Diagram(s)sequenceDiagram
participant Analyst
participant OperationsDashboard
participant DashboardAPI
participant OperationsDatabase
Analyst->>OperationsDashboard: select period
OperationsDashboard->>DashboardAPI: GET /api/dashboard
DashboardAPI->>OperationsDatabase: query visible posts and evidence
OperationsDatabase-->>DashboardAPI: metrics, cases, and facts
DashboardAPI-->>OperationsDashboard: dashboard response
OperationsDashboard-->>Analyst: render metrics and evidence cards
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
Full details: Docstring CoverageExplanation Docstring coverage is 57.04% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 135 functions across 35 files. (16 skipped: 16 unsupported.) ✨ Finishing Touches 💡 2📝 Generate docstrings 💡
⚔️ Resolve merge conflicts 💡
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
# Conflicts: # backend/app/analysis_run_start.py # backend/app/global_ask_queue.py # docs/adr/0205-tepp-lineage-anchor.md # docs/adr/0206-evidence-operations-dashboard.md # docs/product-technical-gap-baseline.md # frontend/src/App.css # frontend/src/App.tsx # frontend/src/api.ts # frontend/src/components/OperationsDashboard.tsx # frontend/src/components/SimilarVocPanel.css # frontend/src/components/SimilarVocPanel.stories.tsx # frontend/src/components/SimilarVocPanel.test.tsx # frontend/src/components/SimilarVocPanel.tsx # lineageweave/similar_voc.py # tests/test_analysis_run_start.py # tests/test_similar_voc.py
… HEAD # Conflicts: # backend/app/main.py # backend/tests/test_similar_voc_api.py # tests/test_global_ask_sources.py
…textualWisdomLab/LineageWeave into HEAD # Conflicts: # frontend/src/App.tsx
Co-authored-by: seonghobae <seonghobae@users.noreply.github.com>
| @app.get("/api/posts/{post_id}/similar-voc") | ||
| async def read_similar_voc( | ||
| post_id: str, | ||
| offset: int = Query(0, ge=0), | ||
| account: CurrentAccount = Depends(get_current_account), |
There was a problem hiding this comment.
📝 Info: Similar VOC fires orchestrator work on every post open
Opening any post detail auto-calls read_similar_voc (backend/app/main.py:1800), which runs up to 8 concurrent orchestrator adjudications inline with a 180s timeout. Bounded and ADR-0206-authorized, but every post open now issues expensive LLM work against the shared gateway.
Was this helpful? React with 👍 or 👎 to provide feedback.
| try: | ||
| results = await asyncio.wait_for( | ||
| asyncio.gather(*(_adjudicate(candidate) for candidate in candidates), return_exceptions=True), | ||
| timeout=_SIMILAR_VOC_REQUEST_TIMEOUT_SECONDS, | ||
| ) | ||
| except TimeoutError: | ||
| results = () |
There was a problem hiding this comment.
📝 Info: Batch timeout discards completed Similar VOC results
On asyncio.wait_for timeout at backend/app/main.py:1863, results becomes () and all completed per-candidate adjudications are dropped, returning empty items even when some finished. Per-candidate errors are kept via return_exceptions, but a batch timeout loses partial work.
Was this helpful? React with 👍 or 👎 to provide feedback.
| if item["case_kind_code"] in seen_case_kinds: | ||
| return None | ||
| seen_case_kinds.add(item["case_kind_code"]) |
There was a problem hiding this comment.
📝 Info: Duplicate case kind rejects the whole response
parse_operations_case_response returns None when two items share a case_kind_code (lineageweave/operations_case_analysis.py:119), failing the entire job. A post genuinely supporting two instances of one case kind can never persist and stays in failed_analysis_count.
Was this helpful? React with 👍 or 👎 to provide feedback.
| rows = await conn.fetch( | ||
| f""" | ||
| select post.post_id, post.post_title, post.post_body, | ||
| post.visibility_code, post.corporate_entity_id, post.process_unit_id, | ||
| coalesce(post.event_occurred_at, post.created_at) as occurred_at | ||
| from operations_case_classification classification | ||
| join source_post post on post.post_id = classification.post_id | ||
| where classification.case_kind_code = 'repeat_issue' | ||
| and post.post_id <> $1 | ||
| and post.post_body <> '' | ||
| and (post.visibility_code = 'public' | ||
| or (post.corporate_entity_id::text = any($2::text[]) | ||
| and (cardinality($3::text[]) = 0 | ||
| or post.process_unit_id::text = any($3::text[])))) | ||
| and {SOURCE_POST_ELIGIBILITY_SQL.format(alias='post')} | ||
| order by coalesce(post.event_occurred_at, post.created_at) desc, post.post_id | ||
| offset $4 limit $5 | ||
| """, | ||
| post_id, | ||
| list(account.corporate_entity_ids), | ||
| list(account.process_unit_ids), | ||
| offset, | ||
| _SIMILAR_VOC_PAGE_SIZE + 1, | ||
| ) |
| rows = await conn.fetch( | ||
| f""" | ||
| select post.post_id, post.post_title, post.post_body, | ||
| post.visibility_code, post.corporate_entity_id, post.process_unit_id, | ||
| coalesce(post.event_occurred_at, post.created_at) as occurred_at | ||
| from operations_case_classification classification | ||
| join source_post post on post.post_id = classification.post_id | ||
| where classification.case_kind_code = 'repeat_issue' | ||
| and post.post_id <> $1 | ||
| and post.post_body <> '' | ||
| and (post.visibility_code = 'public' | ||
| or (post.corporate_entity_id::text = any($2::text[]) | ||
| and (cardinality($3::text[]) = 0 | ||
| or post.process_unit_id::text = any($3::text[])))) | ||
| and {SOURCE_POST_ELIGIBILITY_SQL.format(alias='post')} | ||
| order by coalesce(post.event_occurred_at, post.created_at) desc, post.post_id | ||
| offset $4 limit $5 | ||
| """, | ||
| post_id, | ||
| list(account.corporate_entity_ids), | ||
| list(account.process_unit_ids), | ||
| offset, | ||
| _SIMILAR_VOC_PAGE_SIZE + 1, | ||
| ) |
Summary
Measurement boundary
Verification
PR #606 is merged; this PR now targets protected main directly.
Summary by CodeRabbit