feat: expose authenticated MCP Global Ask - #270
Conversation
|
Important Review skippedAuto reviews are disabled on base/target branches other than the default branch. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Plus Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
📝 WalkthroughWalkthrough인증된 MCP Streamable HTTP 서버와 읽기 전용 Changes인증된 MCP Global Ask
Estimated code review effort: 4 (Complex) | ~60 minutes Merge Risk: 🟠 High · up to This PR adds an authenticated MCP path to Global Ask, but private content can still be loaded before authorization, persisted identity configuration can reject valid clients after an audience change, and untrusted source text can weaken prompt isolation; an authorization race remains open as well. These concrete security and availability risks should be fixed before merge, alongside completion of the required exact-head checks. Sequence Diagram(s)sequenceDiagram
participant Client as MCP 클라이언트
participant MCP as MCP 서버
participant Keycloak as Keycloak
participant Database as 게시글 데이터베이스
participant Orchestrator as contextual-orchestrator
Client->>MCP: global_ask(question, access token)
MCP->>Keycloak: JWT audience·scope·subject 검증
Keycloak-->>MCP: 인증된 주체 반환
MCP->>Database: 권한 있는 게시글과 lineage 검색
Database-->>MCP: 소스 게시글과 타임라인 반환
MCP->>Orchestrator: JSON Schema 기반 답변 요청
Orchestrator-->>MCP: 답변과 인용 반환
MCP-->>Client: 구조화 결과와 콘텐츠 블록 반환
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing Touches 💡 1📝 Generate docstrings 💡
🧪 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 |
|
@opencode-agent Please review exact head |
|
Review exact current HEAD eb83c9c. The branch was advanced while preserving concurrent restack commits; current base feat/event-lineage-node-keeps-gnb-focus-v2170 is an ancestor of this head. Local locked dev+backend full suite: 823 passed, 16 skipped, 3 warnings. The uv.lock conflict with main was resolved by retaining the branch 2.13.0 metadata. Hosted Checks are queued for this exact head. Please re-run/review this SHA and publish the independent formal approval required by the protected ruleset; no merge claim until terminal Checks, required approvals, exact-head last-push approval, and post-merge SHA evidence. |
|
Fresh exact-head evidence for eb83c9c: frontend lint passed; frontend tests 15 files / 155 tests passed; production build passed; Storybook build passed (only the existing large-chunk warning). Backend remained 823 passed, 16 skipped, 3 warnings. Hosted required Checks are still queued after the branch update. Please bind any formal review to this exact SHA and complete the protected merge gate only after terminal hosted results and independent approvals. |
|
Review exact current HEAD 1881a3c (base 3ed21fe):
|
…b-focus-v2170' into agent/authenticated-mcp-global-ask # Conflicts: # CHANGELOG.md
…b-focus-v2170' into agent/authenticated-mcp-global-ask
…b-focus-v2170' into agent/authenticated-mcp-global-ask
* feat: queue post-content analysis durably * fix(import): allow repeated source lookup keys * fix(docs): assign post-content ADR a unique number * feat: add keyverse-bound mcp api key management * revert: keep MCP key management out of buyer root stack The prior commit added a second local MCP credential authority to #258 even though authenticated MCP Global Ask is owned by draft PR #270. Restore the exact pre-injection Buyer tree without rewriting history; the isolated commit remains available for separate evaluation against #270's OAuth resource-server contract. * security: document safe composed SQL * fix: preserve OIDC post deep links * ci: verify audited safe-SQL suppressions * ci: harden audited safe-SQL repair anchors * fix(ci): remove self-modifying SQL repair workflow * test(security): reject dynamic asyncpg statement construction * fix: render resolved post structure for ordinary paragraphs * fix: hide source offsets from image accessibility labels * fix: requeue incomplete post embeddings * fix: align static SQL contract with safe composition * ci: repair PR 258 static SQL review findings * ci: repair PR 258 one-shot template * fix: pass embedding model to backend * fix(ci): remove self-modifying PR 258 repair workflow * fix(ci): remove PR 258 workflow template * fix(security): bind customer-hint SQL to a static statement * fix(security): precompile demo-scope SQL statements * fix(security): precompile relationship-network SQL * fix(security): precompile Keyman backfill selectors * fix(security): precompile summary backfill selectors * test: apply image-region embedding migration in API fixture * fix(security): precompile content backfill selectors * fix(security): move synthetic cleanup identifiers into PostgreSQL * test(security): require static reviewed asyncpg statements * fix(backfill): preserve process-unit semantic hint name * fix: wire provider embeddings through orchestrator * fix: retain embedding provider URL during startup * fix: keep orchestrator provider URL for embedding startup * chore: stage exact SQL review repair payload * fix(security): keep relationship-network SQL literal * fix(security): keep demo-scope SQL literal * fix(security): keep customer-hint SQL literal * fix(security): keep Keyman selector SQL literal * fix(security): use one literal summary selector * fix(security): use one literal content selector * fix: requeue incomplete post content jobs * fix(security): keep synthetic cleanup SQL literal * test(security): require literal reviewed SQL statements * fix: keep ADR numbers unique and remove repair artifact * feat: queue real post content backfill through valkey * chore: configure project test import path * fix(security): keep queue backfill SQL literal * test(security): cover queue backfill SQL boundary * perf: parallelize visual region evidence * fix: require a majority of tokens for relation corroboration corroborating_evidence_url treated a single distinctive name token as enough corroboration for an organization's real-world footprint. An invented name containing an ordinary dictionary word (e.g. "Fictitious", "Nonexistent") could match unrelated search results on that one word alone, flipping a genuinely uncorroborated relation to corroborated. Now requires a majority of a multi-token name's tokens to co-occur in the same result; single-token names fall back to that one token since there is no majority to require. Also renumbers migrations/0012_role_responsibility_agent_type.sql to 0060 -- it collided with the already-mainlined 0012_report_leftover_pair.sql -- and updates every reference plus the migrate.sh replay allowlist. Co-Authored-By: Claude Sonnet 5 <[email protected]> * test(frontend): match embedded image accessibility label * docs: ground orchestration policy in primary sources * style: tokenize repeated colors and add dark-mode badge variants App.css hardcoded ~13 color sites (lineage-link accent colors, actor-type badges, verification-status badges, a subtle border) that duplicated the same values across the file with zero dark-mode coverage -- the pastel badge backgrounds would have stayed light in dark mode, clashing against the dark chrome. Promotes them to semantic tokens in styles/tokens.css with light and dark variants, following the file's existing --color-accent-* pattern, and points every App.css occurrence at the new custom properties. Co-Authored-By: Claude Sonnet 5 <[email protected]> * docs(adr): record buyer surface Figma file * docs+test: ADR and regression test for badge/accent tokens Adds ADR 0099 documenting the design-token pass (Figma File ID 1Su3lDRmiZdcUs47t1QwIX, reusing ADR 0002's already-cleared boundary) and a CHANGELOG.d fragment. Adds frontend/src/styles/tokens.test.ts so a future edit can't silently drop the dark-mode half of a badge token or reintroduce the retired inline hex colors. Also drops a duplicate 0060_* case arm in migrate.sh's replay allowlist left over from a concurrent edit. Co-Authored-By: Claude Sonnet 5 <[email protected]> * fix: keep 0060 migration allowlist entry as its own case arm My earlier cleanup merged 0060_* into the 0012-0050 case arm, but test_migration_replay_window_includes_post_content_queue asserts the exact substring "0050_*)" is present -- merging broke that literal match. Restores the separate appended arm, matching the pattern already used for 0051_*/0052_*. Co-Authored-By: Claude Sonnet 5 <[email protected]> * fix(security): audit every reviewed SQL composition site * fix: align embedded image accessibility assertion * fix: recover post content queue leases * fix: allow slow structured post adjudication * fix: bound post content queue retries * fix: align integration fixtures with current contracts * feat: persist requester and processor evidence * docs: record product gap baseline * fix: keep summaries available when enrichment times out * docs: align product gap evidence with current head * fix: fence stale post-content worker leases * test: apply action migration to projection fixtures * fix: stop failed evidence panels from loading forever * docs: record bounded summary refresh evidence * fix: document audited asyncpg queries * docs: track latest protected-head audit * docs: record entity-resolution PR correction * fix: preserve semantic source unit boundaries * fix: preserve oidc deep links across callback storage * fix: render buyer-facing image evidence * fix: label unavailable image evidence * docs: avoid oidc adr number collision * docs: avoid buyer image adr number collision * fix: bind summary actions to source-grounded projects * test: cover project-bound summary action round trip * docs: record buyer gap checkpoint evidence * docs: align image evidence ADR heading * docs: align OIDC ADR heading * fix: preserve legacy action evidence delimiters * docs: refresh buyer gap audit checkpoint * docs: record current project action head * feat: bind summary events to source-grounded projects * docs: record full checkpoint verification * fix(summary): normalize project keys before persistence * docs: refresh exact-head buyer gap audit * test(summary): cover project key sentinel normalization * test(image): cover source placement and OCR rendering * fix: preserve stale summary buyer continuity * fix: keep post content recovery alive * test(summary): cover stale continuity and retry * feat: add explicit post content retry * test(queue): cover explicit retry rejection * docs(queue): complete retry command docstrings * fix(ontology): align person mention direction with KG triples * docs: record audited safe SQL gate * fix: reconcile backfill content with job ledger * fix(ui): preserve indentation after mixed content * docs: record post content recovery evidence * docs(ui): clarify indentation matching boundary * test(ui): cover missing source unit fallback * fix: serialize per-post vision region analysis * fix(ui): preserve adjacent table boundaries * fix: preserve honest image evidence rendering * fix: separate source whitespace from explicit structure * docs: record source indentation buyer gap * fix: retain partial image regions * docs: record partial image region gap * test: cover partial parent vision failure * feat: enrich semantic hints from source catalogs * fix: reject non-decomposed vision regions * docs: refresh protected gate baseline * docs: record corrected image region evidence * fix: trim source catalog lookup codes * docs: record catalog hint boundary * docs: record exact-head validation evidence * docs: record live browser acceptance * docs: refresh live gate topology * fix: reject unbounded visual locator regions * docs: refresh exact-head product gap audit * test: cover visual region fallback branches * docs: refresh exact-head product gap audit * test: cover visual region fallback branches * docs: record current audit head * docs: repair stacked audit traceability * fix: fall back from malformed visual locator output * docs: refresh stacked PR exact heads * docs: record audit refresh head * docs: refresh visual locator exact-head evidence * style: normalize merged branch whitespace * docs: refresh current visual stack state * docs: record visual stack audit head * docs: align visual stack gate states * fix: preserve semantic footnote structure * docs: record footnote structure checkpoint * fix: classify OOXML footnote containers * fix: distinguish footnote citations from definitions * docs: record footnote citation guard * docs: record fresh runtime aggregate evidence * docs: align runtime evidence head * docs: record embedding provenance guard * docs: align stacked audit head * test: keep invalid locator fallback coordinate-free * docs: keep PR 320 status under its checkpoint * docs: refresh PR 324 exact-head evidence * fix: refresh content after summary ingestion * fix: bound OIDC return state parsing * fix: restrict synthetic cleanup to demo scopes * test: cover empty synthetic cleanup * fix: validate buyer image sources at render boundary * docs: record current exact-head gap checkpoint * docs: retain current buyer stack roots * fix: safely handle malformed region locator output * fix: expose unexpected content channel defects * fix: expose recoverable content batch failures * fix: safely handle malformed region locator output * docs: record current exact-head review gates * docs: align orchestrator runtime pin * docs: refresh current queue roots * docs: record buyer-stack restack * docs: record MCP key boundary closure * style: use deferred region result annotation * feat: enforce Korean UI standards on top of latest PR stack - Re-apply UI·UX Standard Guide Ver.3.0 layout (app-shell, login-card, footer) - Update i18n translation dictionary to match standard Korean vocabulary (조회, 티켓 작성, 로그인 등) - Preserve existing i18n localization hooks instead of hardcoding - Preserve all stacked PR functionality (BuyerNav, LLM extraction fixes, backend parsing) * feat: parameterize brand name for future admin configuration - Replaced hardcoded 'LineageWeave' and 'BRAND' with state. - Prepared for admin mode integration where tenant/brand name can be dynamically fetched. * feat: add admin screen for tenant configuration - Added Admin destination to BuyerNav - Created AdminPanel for configuring brandName dynamically - Wired up AdminPanel rendering in App.tsx - Added i18n support for new admin terms * feat: backend API and DB connection for admin tenant settings - Created migration 0103_tenant_settings for persistent brand name storage - Added GET/PATCH /api/settings endpoints in backend main.py - Wired App.tsx and AdminPanel.tsx to fetch and update via actual API * fix: revert bad chunking sed from uiux restack * fix: rename duplicate ADR 0117 to 0118 * docs: correct UI UX ADR number * feat: close extraction gaps (5W1H, events, Keymen) and update baseline --------- Co-authored-by: Claude Sonnet 5 <[email protected]> Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
|
@opencode-agent @devin-ai-integration Please review exact current head e1c31db against base bcdc459. Current MCP/auth/ABAC/Keycloak review findings were verified against this tree; local full and focused suites are green. |
…b-focus-v2170' into HEAD # Conflicts: # backend/app/auth.py # lineageweave/post_content_normalization.py
|
Restacked onto current Event Lineage head 39f2126 with normal merge commit 515bb0b. Local verification on the pushed tree: backend 871 passed, 17 skipped; frontend 177 passed; lint, build, Storybook build, compileall, actionlint, and diff checks passed. Provider diagnostics remain fail-closed, JWKS selection remains exact, and partial visual-region evidence retains parent context. Awaiting independent review and hosted Checks on the current head. |
| if regions: | ||
| region_results.extend( | ||
| _describe_image_region( | ||
| region_index, | ||
| chunk.image_data, | ||
| chunk.label, | ||
| region, | ||
| vision_client, | ||
| with ThreadPoolExecutor(max_workers=min(8, len(regions))) as executor: | ||
| region_results.extend( | ||
| executor.map( | ||
| _describe_image_region_in_context, | ||
| (copy_context() for _ in regions), | ||
| range(len(regions)), | ||
| repeat(chunk.image_data), | ||
| repeat(chunk.label), | ||
| regions, | ||
| repeat(vision_client), | ||
| repeat(session_id), | ||
| repeat(metadata), | ||
| ) | ||
| ) |
There was a problem hiding this comment.
🔴 Vision image analysis floods the gateway with nested parallel calls
When a post has several embedded images that each decompose into regions, the image-analysis step runs images and their regions in two stacked thread pools (ThreadPoolExecutor at post_content_normalization.py inside per-image tasks launched from another ThreadPoolExecutor at post_content_normalization.py), so up to 64 provider calls fire at once for one post.
Nested pools contradict the adjacent serialization decision
The inline ponytail note at post_content_normalization.py records that per-post VISION calls were deliberately serialized because "nested image/region pools overwhelmed the gateway and turned valid region evidence into failures" and that bounded concurrency should be reintroduced only after provider capacity is measured. This PR replaces both the previously sequential per-image loop (now the outer pool at line 370) and the previously sequential per-region generator (now the inner pool at line 256) with ThreadPoolExecutors, each max_workers=min(8, ...). Because each outer per-image worker opens its own inner region pool, effective concurrency reaches 8*8 = 64 simultaneous describe/locate_regions calls per post, exactly the nesting the note warns produced region-evidence failures. Region and chunk failures are swallowed and downgraded to "failed"/"content unavailable", so overload silently degrades extracted image evidence rather than erroring.
Prompt for agents
The image-analysis path in lineageweave/post_content_normalization.py reintroduces concurrency that the adjacent ponytail comment (lines 252-254) explicitly forbids until provider capacity is measured. normalize_post_body now runs image chunks in a ThreadPoolExecutor (around line 370), and _describe_image_chunk runs each chunk's regions in a second ThreadPoolExecutor (around line 256). Because the region pool is nested inside the per-image pool, worst-case concurrency is 8*8=64 concurrent gateway calls per post, which the comment says overwhelmed the gateway and turned valid region evidence into failures. Decide on a single bounded concurrency level: either keep the two loops serial (as documented) or cap total in-flight provider calls (e.g. a single shared bounded executor / semaphore across both image and region work) so nesting cannot multiply the worker counts. Also update or remove the now-inaccurate ponytail comment to reflect the chosen design.
Was this helpful? React with 👍 or 👎 to provide feedback.
Product result
Adds an authenticated Streamable HTTP MCP resource server so MCP clients can
ask LineageWeave Global Ask without direct SQL access, a second identity store,
or bearer-token forwarding.
Exact stack state
e1c31db3387ec051e6327332d373293242b9e5ebfeat/event-lineage-node-keeps-gnb-focus-v2170bcdc4594abe467627c71378adeceb61624d02d67merges and no force push or protected-branch bypass was used.
Contract and security boundary
global_askwith explicitverify_externalbehavior and no persisted side effect.authorized before post-scoped body/vision work, and Global Ask SQL applies
public/corporate scope before body disclosure.
post_readgrant immediately before bytes arereturned.
audience checks, bounded key rotation, and Host/Origin validation remain in
force.
MCP waits for that reconciler and SearxNG readiness.
capability/model selection; no provider API or model name is selected here.
Review disposition
Current review reports were checked against the exact tree. The previously
reported MCP auth, media indexing, external-verification parsing, source
prompt-boundary, SQL authorization, and Keycloak audience issues are addressed
in the branch or by the current database/compose boundary; no new source fix
was needed in this pass.
Verification
829 passed, 16 skipped, 3 warnings.95 passed.166 passed; lint, production build, and Storybook build passed.git diff --checkand CodeGraph sync passed.Merge gate
Review this exact head. Merge only after an independent formal approval, all
required Checks are terminal-success on this SHA, and no valid unresolved
review thread remains. If a Check fails, fix its root cause, validate locally,
push normally, and re-check the new exact head.