Skip to content

feat(data-warehouse): add trino monitoring endpoints and mcp tools - #110370

Merged
EDsCODE merged 4 commits into
eric/data-ops-trino-variant-backendfrom
eric/data-ops-trino-monitoring-backend
Oct 6, 2026
Merged

EDsCODE merged 4 commits into
eric/data-ops-trino-variant-backendfrom
eric/data-ops-trino-monitoring-backend

Conversation

@EDsCODE

@EDsCODE EDsCODE commented Oct 1, 2026 •

Copy link
Copy Markdown
Collaborator

Problem

Changes

  • A Trino organization can read its live query activity from managed-warehouse-trino-monitoring/: totals, concurrency and queue limits, and up to 200 in-flight queries.
  • Query text arrives with literal values already masked by the control plane.
  • managed-warehouse-trino-monitoring-timeseries/ returns one of nine metrics over a window from 1 hour to 30 days.
  • available: false on the live response means the data could not be read. Zero totals then do not mean an idle warehouse.
  • A DuckDB organization gets a 404 from both endpoints. The message names its own endpoints and MCP tools.
  • warehouse_status gains a trino block with the Trino state and connection. It stays null until the warehouse itself is ready.
  • An unknown Trino state maps to unavailable, never pending. A client then does not show an endless setup state.
  • The Postgres connection is null for a Trino organization, because its users connect through Trino only.
  • Two MCP tools, managed-warehouse-trino-monitoring-get and managed-warehouse-trino-metric-history-get, sit behind data-warehouse-scene-trino and the warehouse_view:read scope.

Where to look first: the serializers are an allow-list. They drop unknown upstream fields, and reject a response for another organization or a series with an unexpected label.

The Trino contract is separate from the DuckDB one on purpose. One shared contract would need optional worker and query fields on every response, and each path could not change without the other.

Mechanical: the generated OpenAPI types, the generated MCP files, and the internal monitoring doc.

Before:

flowchart LR
    Caller[Data ops or MCP tool] --> D[DuckDB monitoring endpoints]
    D -->|duckdb variant| CPW[Control plane worker routes]
    D -->|trino variant| N[404]
    classDef phBlue fill:#1d4aff,stroke:#1d4aff,color:#fff;
    classDef phRed fill:#f54e00,stroke:#f54e00,color:#fff;
    classDef phYellow fill:#f9bd2b,stroke:#f9bd2b,color:#000;
    classDef phGray fill:#e5e7eb,stroke:#c7ccd1,color:#000;
    class Caller phYellow;
    class D phBlue;
    class CPW phRed;
    class N phGray;
Loading

After:

flowchart LR
    Caller[Data ops or MCP tool] --> D[DuckDB monitoring endpoints]
    Caller --> T[Trino monitoring endpoints]
    D -->|duckdb variant| CPW[Control plane worker routes]
    D -->|trino variant| N[404 naming the other endpoints]
    T -->|duckdb variant| N
    T -->|trino variant| CPT[Control plane Trino routes]
    CPT --> Q[Live query list]
    CPT --> M[Metric history]
    classDef phBlue fill:#1d4aff,stroke:#1d4aff,color:#fff;
    classDef phRed fill:#f54e00,stroke:#f54e00,color:#fff;
    classDef phYellow fill:#f9bd2b,stroke:#f9bd2b,color:#000;
    classDef phGray fill:#e5e7eb,stroke:#c7ccd1,color:#000;
    class Caller phYellow;
    class D,T phBlue;
    class CPW,CPT phRed;
    class N,Q,M phGray;
Loading

How did you test this code?

Test rationale:

  • The snapshot tests catch an internal upstream field or another organization's data reaching the response. The closest existing tests cover the DuckDB contract only.
  • The timeseries tests catch an invalid metric or window reaching the control plane, and an unexpected series label reaching the client.
  • test_trino_monitoring_returns_404_for_a_duckdb_organization catches the wrong variant reading Trino data.
  • test_warehouse_status_skips_the_trino_read_until_the_warehouse_is_ready catches a Trino read against a warehouse that is still provisioning.
  • test_trino_status_for_presents_only_customer_safe_fields catches an internal upstream field in the trino block. It also catches an error, an unknown state, or another organization's answer shown as anything but unavailable.
  • The MCP filtering test catches the Trino tools appearing without their scope or flag.

Not checked: no request ran against a deployed control plane or a live Trino cell. Every upstream response is mocked from the contract in PostHog/duckgres#1248.

👉 Stay up-to-date with PostHog coding conventions for a smoother review.

Release status

  • No feature flag controls this change
  • This change is behind a feature flag and is not available to users
  • This change makes a previously flagged feature available to everyone

Automatic notifications

  • Publish to changelog?

Docs update

docs/internal/managed-warehouse-monitoring.md covers the Trino endpoints in this PR. No public docs change, because the variant is not available to users.

🤖 Agent context

Autonomy: Human-driven (agent-assisted)

Agent: Claude Code. Claude Sonnet 5.5 subagents wrote the code. Claude Opus 5.5 planned and coordinated the work.

  • The four layers came from one written design and plan. A separate subagent reviewed each task, and one more reviewed the whole stack.
  • Skills invoked: superpowers:brainstorming, superpowers:writing-plans, superpowers:subagent-driven-development, superpowers:using-git-worktrees, /stacking-prs, /writing-pr-descriptions, /reviewing-with-coderabbit.
  • CodeRabbit CLI pass: skipped. The CLI was signed out and setup was declined.
  • Bot review threads, all resolved: feat(data-warehouse): show trino connection in data ops settings #110372 handles both Greptile findings. It keeps the status poll running through Trino setup, and it shows the Trino connection details in Settings.
  • Restacked onto master on 2026-10-06. The MCP tool-filtering test conflicted on the flag count, and it now keeps the new master assertion and counts this layer's flag.
  • No duplicate: a search of open PRs for the Trino Data ops variant found nothing.
  • Public artifact: no customer material informed this work. Every fixture and screenshot uses invented names and example.com hosts.
  • The whole-stack review changed one thing here: an unknown Trino state mapped to pending and now maps to unavailable.

🤖 Generated with Claude Code

@EDsCODE
EDsCODE added this pull request to stack #110373 October 1, 2026 21:54
@github-actions

github-actions Bot commented Oct 1, 2026 •

Copy link
Copy Markdown
Contributor

🤖 CI report

⚠️ Trunk lane — backend Python lane

This PR is assigned to the backend Python lane. It runs backend Python tests and may merge in parallel with PRs in other lanes.

✅ Complexity (TypeScript) — clean

Cyclomatic complexity above the limit in changed typescript files (10 for production files, 15 for test files). Warn only: worth simplifying when you next touch these functions.

✅ Duplication (Python) — clean

New Python code duplication introduced by this branch. Fails at 70+ tokens in app code, or 150+ tokens when both copies live in test files. Advisory while the gate proves itself: extract a shared helper instead of copying.

✅ Duplication (TypeScript) — clean

New TypeScript code duplication introduced by this branch. Fails at 70+ tokens in app code, or 150+ tokens when both copies live in test files. Advisory while the gate proves itself: extract a shared helper instead of copying.

✅ Bundle size — no change

Uncompressed size of every built .js bundle, compared against the base branch.

Total: 76.04 MiB · no change

No file changed by more than 1000 B.

Posted automatically by build-bundle-size-report · uncompressed bytes from dist-report

⚠️ Eager graph — 2 over budget

How much code each root ships on the eager path — downloaded and parsed before the surface is interactive. Measured from the esbuild output chunks (post-tree-shake, static imports only); lazy import() / React.lazy chunks are not counted.

Root Eager (shipped) Δ vs base Budget
entry (logged-out pages, app bootstrap)
src/index.tsx
1.64 MiB · 23 files no change █████████░ 88.9% of 1.84 MiB
logged-out boot: index + App + bootApp (preloaded by every page, including /login)
src/index.tsx + src/scenes/App.tsx + src/scenes/bootApp.ts
3.72 MiB · 663 files no change █████████░ 92.3% of 4.03 MiB
authenticated shell (every logged-in page)
src/scenes/AuthenticatedShell.tsx
7.60 MiB · 2,404 files 🔺 +4 B (+0.0%) █████████░ 91.1% of 8.34 MiB
🟡 dashboard scene
src/scenes/dashboard/Dashboard.tsx
13.91 MiB · 4,917 files 🔺 +4 B (+0.0%) ██████████ 103.2% of 13.48 MiB
today home path
src/scenes/AuthenticatedShell.tsx + src/scenes/project-homepage/ProjectHomepage.tsx + src/scenes/project-homepage/today/TodayHome.tsx
7.62 MiB · 2,416 files 🔺 +4 B (+0.0%) █████████░ 88.8% of 8.58 MiB
🟡 events scene
src/scenes/activity/explore/EventsScene.tsx
13.64 MiB · 4,789 files 🔺 +4 B (+0.0%) ██████████ 108.0% of 12.64 MiB
replay detail scene
src/scenes/session-recordings/detail/SessionRecordingDetail.tsx
12.13 MiB · 4,142 files 🔺 +4 B (+0.0%) ████████░░ 77.2% of 15.72 MiB

🟢 node_modules/monaco-editor/ stays out of src/index.tsx
🟢 src/lib/components/ActivityLog/describers stays out of src/index.tsx
🟢 node_modules/@posthog/brand/dist/generated/hoggies/svg/ stays out of src/index.tsx
🟢 node_modules/@posthog/brand/dist/generated/hoggies/components/ stays out of src/index.tsx
🟢 node_modules/monaco-editor/ stays out of src/index.tsx + src/scenes/App.tsx + src/scenes/bootApp.ts
🟢 src/layout/navigation-3000/navigationLogic.tsx stays out of src/index.tsx + src/scenes/App.tsx + src/scenes/bootApp.ts
🟢 src/scenes/dashboard/dashboardLogic.tsx stays out of src/index.tsx + src/scenes/App.tsx + src/scenes/bootApp.ts
🟢 src/lib/lemon-ui/LemonMarkdown/ stays out of src/index.tsx + src/scenes/App.tsx + src/scenes/bootApp.ts
🟢 src/lib/components/RichContentEditor/ stays out of src/index.tsx + src/scenes/App.tsx + src/scenes/bootApp.ts
🟢 src/lib/components/CodeSnippet/ stays out of src/index.tsx + src/scenes/App.tsx + src/scenes/bootApp.ts
🟢 src/taxonomy/core-filter-definitions-by-group.json stays out of src/index.tsx + src/scenes/App.tsx + src/scenes/bootApp.ts
🟢 node_modules/monaco-editor/ stays out of src/scenes/AuthenticatedShell.tsx
🟢 src/lib/components/ActivityLog/describers stays out of src/scenes/AuthenticatedShell.tsx
🟢 products/dashboards/frontend/widgets/previews/ stays out of src/scenes/AuthenticatedShell.tsx
🟢 src/scenes/session-recordings/player/sessionRecordingPlayerLogic.ts stays out of src/scenes/AuthenticatedShell.tsx
🟢 zod/v4/locales/de.js stays out of src/scenes/AuthenticatedShell.tsx
🟢 node_modules/@posthog/brand/dist/generated/hoggies/svg/ stays out of src/scenes/AuthenticatedShell.tsx
🟢 node_modules/@posthog/brand/dist/generated/hoggies/components/ stays out of src/scenes/AuthenticatedShell.tsx
🟢 src/scenes/project-homepage/ai-first/AiFirstHomepage.tsx stays out of src/scenes/AuthenticatedShell.tsx + src/scenes/project-homepage/ProjectHomepage.tsx + src/scenes/project-homepage/today/TodayHome.tsx
🟢 src/scenes/project-homepage/today/TodayReportPage.tsx stays out of src/scenes/AuthenticatedShell.tsx + src/scenes/project-homepage/ProjectHomepage.tsx + src/scenes/project-homepage/today/TodayHome.tsx
🟢 src/queries/Query/Query.tsx stays out of src/scenes/AuthenticatedShell.tsx + src/scenes/project-homepage/ProjectHomepage.tsx + src/scenes/project-homepage/today/TodayHome.tsx

Largest files eagerly shipped from src/index.tsx
Size File
126.8 KiB ../node_modules/.pnpm/react-dom@18.3.1_react@18.3.1/node_modules/react-dom/cjs/react-dom.production.min.js
24.6 KiB ../node_modules/.pnpm/buffer@6.0.3/node_modules/buffer/index.js
6.3 KiB ../node_modules/.pnpm/react@18.3.1/node_modules/react/cjs/react.production.min.js
4.5 KiB ../node_modules/.pnpm/@jspm+core@2.1.0/node_modules/@jspm/core/nodelibs/browser/process.js
3.9 KiB ../node_modules/.pnpm/scheduler@0.23.2/node_modules/scheduler/cjs/scheduler.production.min.js
1.4 KiB ../node_modules/.pnpm/base64-js@1.5.1/node_modules/base64-js/index.js
1.3 KiB src/index.tsx
1.3 KiB src/RootErrorBoundary.tsx
912 B ../node_modules/.pnpm/ieee754@1.2.1/node_modules/ieee754/index.js
839 B src/scenes/ChunkLoadErrorBoundary.tsx
Largest files eagerly shipped from src/index.tsx + src/scenes/App.tsx + src/scenes/bootApp.ts
Size File
306.2 KiB ../node_modules/.pnpm/posthog-js@1.435.5_@types+react@18.3.27_react@18.3.1/node_modules/posthog-js/dist/module.mjs
220.3 KiB ../node_modules/.pnpm/@posthog+icons@0.38.0_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/@posthog/icons/dist/posthog-icons.es.js
126.8 KiB ../node_modules/.pnpm/react-dom@18.3.1_react@18.3.1/node_modules/react-dom/cjs/react-dom.production.min.js
99.7 KiB src/lib/api.ts
90.7 KiB src/products.tsx
68.7 KiB src/lib/lemon-ui/icons/icons.tsx
40.7 KiB src/lib/utils/eventUsageLogic.ts
38.7 KiB ../node_modules/.pnpm/@dnd-kit+core@6.0.8_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/@dnd-kit/core/dist/core.esm.js
33.9 KiB ../node_modules/.pnpm/kea@4.0.0-pre.6_patch_hash=139b8d1f1304f9d9da452a9a1244c94ea679dbcb85687d8999563146879fb6f5_react@18.3.1/node_modules/kea/lib/index.cjs.js
29.0 KiB ../node_modules/.pnpm/zod@4.3.6/node_modules/zod/v4/core/schemas.js
Largest files eagerly shipped from src/scenes/AuthenticatedShell.tsx
Size File
306.2 KiB ../node_modules/.pnpm/posthog-js@1.435.5_@types+react@18.3.27_react@18.3.1/node_modules/posthog-js/dist/module.mjs
280.3 KiB src/taxonomy/core-filter-definitions-by-group.json
220.3 KiB ../node_modules/.pnpm/@posthog+icons@0.38.0_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/@posthog/icons/dist/posthog-icons.es.js
153.7 KiB ../node_modules/.pnpm/re2js@0.4.1/node_modules/re2js/build/index.esm.js
126.8 KiB ../node_modules/.pnpm/react-dom@18.3.1_react@18.3.1/node_modules/react-dom/cjs/react-dom.production.min.js
112.3 KiB ../packages/quill/packages/quill/dist/index.js
99.7 KiB src/lib/api.ts
93.3 KiB ../node_modules/.pnpm/prosemirror-view@1.40.1/node_modules/prosemirror-view/dist/index.js
90.7 KiB src/products.tsx
90.6 KiB ../node_modules/.pnpm/@tiptap+core@3.20.6_@tiptap+pm@3.20.6/node_modules/@tiptap/core/dist/index.js
Largest files eagerly shipped from src/scenes/dashboard/Dashboard.tsx
Size File
315.5 KiB ../node_modules/.pnpm/posthog-js@1.435.5_@types+react@18.3.27_react@18.3.1/node_modules/posthog-js/dist/rrweb.js
306.2 KiB ../node_modules/.pnpm/posthog-js@1.435.5_@types+react@18.3.27_react@18.3.1/node_modules/posthog-js/dist/module.mjs
280.3 KiB src/taxonomy/core-filter-definitions-by-group.json
220.3 KiB ../node_modules/.pnpm/@posthog+icons@0.38.0_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/@posthog/icons/dist/posthog-icons.es.js
181.8 KiB src/queries/validators.js
153.7 KiB ../node_modules/.pnpm/re2js@0.4.1/node_modules/re2js/build/index.esm.js
126.8 KiB ../node_modules/.pnpm/react-dom@18.3.1_react@18.3.1/node_modules/react-dom/cjs/react-dom.production.min.js
112.3 KiB ../packages/quill/packages/quill/dist/index.js
99.7 KiB src/lib/api.ts
93.3 KiB ../node_modules/.pnpm/prosemirror-view@1.40.1/node_modules/prosemirror-view/dist/index.js
Largest files eagerly shipped from src/scenes/AuthenticatedShell.tsx + src/scenes/project-homepage/ProjectHomepage.tsx + src/scenes/project-homepage/today/TodayHome.tsx
Size File
306.2 KiB ../node_modules/.pnpm/posthog-js@1.435.5_@types+react@18.3.27_react@18.3.1/node_modules/posthog-js/dist/module.mjs
280.3 KiB src/taxonomy/core-filter-definitions-by-group.json
220.3 KiB ../node_modules/.pnpm/@posthog+icons@0.38.0_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/@posthog/icons/dist/posthog-icons.es.js
153.7 KiB ../node_modules/.pnpm/re2js@0.4.1/node_modules/re2js/build/index.esm.js
126.8 KiB ../node_modules/.pnpm/react-dom@18.3.1_react@18.3.1/node_modules/react-dom/cjs/react-dom.production.min.js
112.3 KiB ../packages/quill/packages/quill/dist/index.js
99.7 KiB src/lib/api.ts
93.3 KiB ../node_modules/.pnpm/prosemirror-view@1.40.1/node_modules/prosemirror-view/dist/index.js
90.7 KiB src/products.tsx
90.6 KiB ../node_modules/.pnpm/@tiptap+core@3.20.6_@tiptap+pm@3.20.6/node_modules/@tiptap/core/dist/index.js
Largest files eagerly shipped from src/scenes/activity/explore/EventsScene.tsx
Size File
315.5 KiB ../node_modules/.pnpm/posthog-js@1.435.5_@types+react@18.3.27_react@18.3.1/node_modules/posthog-js/dist/rrweb.js
306.2 KiB ../node_modules/.pnpm/posthog-js@1.435.5_@types+react@18.3.27_react@18.3.1/node_modules/posthog-js/dist/module.mjs
280.3 KiB src/taxonomy/core-filter-definitions-by-group.json
220.3 KiB ../node_modules/.pnpm/@posthog+icons@0.38.0_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/@posthog/icons/dist/posthog-icons.es.js
181.8 KiB src/queries/validators.js
153.7 KiB ../node_modules/.pnpm/re2js@0.4.1/node_modules/re2js/build/index.esm.js
126.8 KiB ../node_modules/.pnpm/react-dom@18.3.1_react@18.3.1/node_modules/react-dom/cjs/react-dom.production.min.js
112.3 KiB ../packages/quill/packages/quill/dist/index.js
99.7 KiB src/lib/api.ts
93.3 KiB ../node_modules/.pnpm/prosemirror-view@1.40.1/node_modules/prosemirror-view/dist/index.js
Largest files eagerly shipped from src/scenes/session-recordings/detail/SessionRecordingDetail.tsx
Size File
315.5 KiB ../node_modules/.pnpm/posthog-js@1.435.5_@types+react@18.3.27_react@18.3.1/node_modules/posthog-js/dist/rrweb.js
306.2 KiB ../node_modules/.pnpm/posthog-js@1.435.5_@types+react@18.3.27_react@18.3.1/node_modules/posthog-js/dist/module.mjs
280.3 KiB src/taxonomy/core-filter-definitions-by-group.json
220.3 KiB ../node_modules/.pnpm/@posthog+icons@0.38.0_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/@posthog/icons/dist/posthog-icons.es.js
181.8 KiB src/queries/validators.js
153.7 KiB ../node_modules/.pnpm/re2js@0.4.1/node_modules/re2js/build/index.esm.js
126.8 KiB ../node_modules/.pnpm/react-dom@18.3.1_react@18.3.1/node_modules/react-dom/cjs/react-dom.production.min.js
112.3 KiB ../packages/quill/packages/quill/dist/index.js
99.7 KiB src/lib/api.ts
93.3 KiB ../node_modules/.pnpm/prosemirror-view@1.40.1/node_modules/prosemirror-view/dist/index.js

Posted automatically by check-eager-graph · sizes are eager output bytes (shipped, post-tree-shake) from the esbuild metafile · part of #32479

✅ Toolbar bundle — eager 2.21 MiB within budget

What the toolbar ships to customer pages, measured from the esbuild output (minified, post-tree-shake). The eager set is the entry plus everything statically imported from it — fetched before any feature runs; deferred chunks load lazily. The eager guardrail is 5.72 MiB. Each output file must also stay below 10 MB, where CloudFront stops compressing it. The module boundary is enforced separately by check-toolbar-graph.

Metric Size Δ vs base Budget
Eager (shipped)
entry + static imports
2.21 MiB · 19 files no change ████░░░░░░ 38.7% of 5.72 MiB
Deferred (lazy) 2.12 MiB · 44 files no change n/a — loads on demand
Loader dist/toolbar.js 1.2 KiB no change █░░░░░░░░░ 6.0% of 19.5 KiB
Largest eagerly-shipped chunks
Size File
850.9 KiB dist/toolbar/toolbar-app-Y2YR4GWC.css
657.4 KiB dist/toolbar/chunk-chunk-XFBL4F6Z.js
259.4 KiB dist/toolbar/chunk-chunk-6EL3FW4B.js
138.2 KiB dist/toolbar/chunk-chunk-RA6AWHA2.js
131.8 KiB dist/toolbar/chunk-chunk-FDH2IBXT.js
75.2 KiB dist/toolbar/toolbar-app-CKJNSUZK.js
69.0 KiB dist/toolbar/chunk-chunk-TSAL54PB.js
35.6 KiB dist/toolbar/chunk-chunk-42S7SJLQ.js
21.0 KiB dist/toolbar/chunk-chunk-G6QDVBSH.js
6.8 KiB dist/toolbar/chunk-chunk-DV7IWQNF.js

Posted automatically by check-toolbar-size · sizes are toolbar output bytes (shipped, post-tree-shake) from the esbuild metafile

✅ Dist folder size — 🔺 +9.6 KiB (+0.0%)

Total size of the built frontend/dist folder (all assets), compared against the base branch.

Total: 998.88 MiB · 🔺 +9.6 KiB (+0.0%)

ℹ️ MCP UI apps size — 32 app(s), 17182.9 KB JS

Built size of each MCP UI app (main.js + styles.css).

App JS CSS
debug 597.9 KB 202.8 KB
action 454.2 KB 202.8 KB
action-list 564.3 KB 202.8 KB
cohort 453.2 KB 202.8 KB
cohort-list 563.2 KB 202.8 KB
email-template 453.0 KB 202.8 KB
error-details 469.7 KB 202.8 KB
error-issue 454.5 KB 202.8 KB
error-issue-list 564.9 KB 202.8 KB
experiment 561.4 KB 202.8 KB
experiment-list 565.0 KB 202.8 KB
experiment-results 566.4 KB 202.8 KB
feature-flag 566.8 KB 202.8 KB
feature-flag-list 570.6 KB 202.8 KB
feature-flag-testing 457.3 KB 202.8 KB
inline-scan 453.6 KB 202.8 KB
insight-actors 562.4 KB 202.8 KB
llm-costs 559.4 KB 202.8 KB
session-recording 455.4 KB 202.8 KB
survey 454.8 KB 202.8 KB
survey-global-stats 561.9 KB 202.8 KB
survey-list 565.0 KB 202.8 KB
survey-stats 561.9 KB 202.8 KB
trace-span 453.5 KB 202.8 KB
trace-span-list 564.2 KB 202.8 KB
vision-observation-list 563.3 KB 202.8 KB
workflow 453.5 KB 202.8 KB
workflow-list 563.6 KB 202.8 KB
loops-review 457.9 KB 202.8 KB
query-results 774.3 KB 202.8 KB
render-ui 857.7 KB 202.8 KB
visual-review-snapshots 458.0 KB 202.8 KB
ℹ️ MCP agent API — agent-facing tool changes

What this PR changes for agents, from the tool schema snapshots and tool definitions.

Tools added (2): managed-warehouse-trino-metric-history-get, managed-warehouse-trino-monitoring-get

@EDsCODE EDsCODE changed the title eric/data ops trino monitoring backend feat(data-warehouse): add trino monitoring endpoints and mcp tools Oct 1, 2026
@greptile-apps

greptile-apps Bot commented Oct 1, 2026 •

Copy link
Copy Markdown
Contributor

Retrigger

[Medium risk] Adds Trino variant monitoring endpoints to the data warehouse backend.

This PR is not ready to merge in its stack: Trino readiness can leave the monitoring tabs hidden, and the connection target is not displayed.

Reviews (1) · Last reviewed commit: "fix(data-warehouse): treat unknown trino..."

@coderabbitai

coderabbitai Bot commented Oct 1, 2026 •

Copy link
Copy Markdown
Contributor

Review in Change Stack →

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration
  • Configuration used: Repository: PostHog/posthog/.coderabbit.yaml
  • Review profile: QUIET
  • Plan: Enterprise
  • Run ID: 466fe312-bd81-4a49-9c13-7db151068bcc
📥 Commits

Reviewing files that changed from the base of the PR and between 11f2725 and dbf4c9e.

⛔ Files ignored due to path filters (4)
  • products/data_warehouse/frontend/generated/api.schemas.ts is excluded by !**/generated/**
  • products/data_warehouse/frontend/generated/api.ts is excluded by !**/generated/**
  • services/mcp/src/generated/data_warehouse/api.ts is excluded by !**/generated/**
  • services/mcp/src/tools/generated/data_warehouse.ts is excluded by !**/generated/**
📒 Files selected for processing (5)
  • products/data_warehouse/backend/presentation/views/data_warehouse.py
  • services/mcp/schema/generated-tool-definitions.json
  • services/mcp/schema/tool-definitions-all.json
  • services/mcp/src/api/generated.ts
  • services/mcp/tests/unit/tool-filtering.test.ts

Included review availability: This review used your included allowance. Your plan provides up to 12 included reviews per hour; 10 remain after this review.


📝 Walkthrough

Walkthrough

The warehouse status API and managed-warehouse monitoring now support Trino alongside DuckDB. Trino monitoring adds snapshot and time-series endpoints, validated response schemas, and two read-only MCP tools. The change also adds generated API types, endpoint and tool-filtering tests, and documentation for variant selection, endpoint separation, metrics, and data handling.

Priority: ➖ Normal

Severity of issue fixed: Medium

Merge Risk: ⚪ Minimal · up to dbf4c

This change adds feature-flagged Trino monitoring endpoints and tools with response validation and access scoping. No concrete merge-blocking issue was identified in the supplied context.

Security Architecture Review

Security architecture risk: 🔵 Low · up to dbf4c

The new monitoring access preserves organization identity and warehouse-read controls. No introduced vulnerability was established, but query privacy depends on upstream masking that could not be independently verified.

Retained concerns
No architecture-level concerns identified.

Security review details

Security Blast Radius

  • observed — The new access surface covers organization-wide query activity, including query text, usernames, client-reported source, and operational metrics. Both monitoring actions require warehouse_view:read and resource-level warehouse access; their new adapter calls read telemetry rather than execute or cancel queries.

Trust Boundaries and Controls

  • observed — Application-side controls bind monitoring requests and responses to the current organization. Test source covers denial before upstream access, rejection of mismatched organization IDs, removal of sensitive unknown fields, and rejection of unexpected series labels.
  • observed — SQL literal masking and comment removal are upstream responsibilities. The local query field accepts a string without redaction, and the inspected test supplies already-masked SQL. This establishes a producer trust dependency, but does not establish that production responses contain unmasked SQL.

Resilience and Maintainability Implications

  • observed — Invalid successful monitoring responses are rejected with 502 rather than returned as raw upstream payloads. Trino status separately falls back to unavailable and null connection details when identity or lifecycle interpretation fails.

Hardening Proposals

  • proposed — Validate the producer contract with cross-service evidence covering tenant isolation, literal and comment redaction, and fail-closed behavior when masking fails. This would close the decisive privacy coverage gap without treating a second local SQL masker as an established requirement.
🚥 Pre-merge checks | ✅ 1
✅ Passed checks (1 passed)
Check name Status Explanation
Description check ✅ Passed The description explains the problem, user-visible changes, test rationale, feature-flag status, documentation, and agent context. The release-status section does not follow the template: it uses chec…
✨ Finishing Touches
📝 Generate docstrings
  • Commit to this branch
  • Create a new PR
🧪 Generate unit tests (beta)
  • Commit to this branch
  • Create a new PR
  • Autopilot · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Autopilot is currently an internal CodeRabbit preview.


Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (2)
products/data_warehouse/backend/presentation/managed_warehouse_trino_monitoring.py (1)

153-172: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Duplicate of serialize_monitoring_series. Make the label map a parameter.

serialize_trino_monitoring_series repeats serialize_monitoring_series line for line. The only difference is the label allow-list. If one copy gets a fix to the metric or label validation, the other copy keeps the old behavior. The path instructions require that code "says everything once and only once."

♻️ Proposed refactor

In managed_warehouse_monitoring.py:

def serialize_monitoring_series(
    raw: object,
    *,
    expected_organization_id: str,
    expected_metric: str,
    allowed_labels_by_metric: Mapping[str, frozenset[str]] = MANAGED_WAREHOUSE_MONITORING_LABELS,
) -> dict[str, object]:
    ...
    allowed_labels = allowed_labels_by_metric[expected_metric]

In this file:

-    data = serialize_monitoring_response(
-        raw,
-        serializer_class=ManagedWarehouseMonitoringSeriesResponseSerializer,
-        expected_organization_id=expected_organization_id,
-    )
-    if data["metric"] != expected_metric:
-        raise ManagedWarehouseMonitoringUpstreamError("Monitoring service returned a different metric")
-    allowed_labels = MANAGED_WAREHOUSE_TRINO_MONITORING_LABELS[expected_metric]
-    for series in cast(list[object], data["series"]):
-        ...
-    return data
+    return serialize_monitoring_series(
+        raw,
+        expected_organization_id=expected_organization_id,
+        expected_metric=expected_metric,
+        allowed_labels_by_metric=MANAGED_WAREHOUSE_TRINO_MONITORING_LABELS,
+    )

Source: Path instructions

products/data_warehouse/backend/presentation/views/data_warehouse.py (1)

1537-1538: 🎯 Functional Correctness | 🔵 Trivial | 💤 Low value

The Trino endpoints accept organizations that have neither flag.

The guard rejects only data_ops_variant(...) == "duckdb". When an organization has neither flag, data_ops_variant returns None. That case passes the guard and continues to the upstream call. _request then returns 403 because is_enabled is false, so no data leaks. The result is still inconsistent:

  • An organization with no flag gets 403 "not available".
  • An organization on the wrong variant gets 404.

The DuckDB endpoints have the same asymmetry because they reject only "trino". Check for the matching variant instead (!= "trino") so that the response is predictable. Alternatively, keep the current behavior but state the 403 path in the schema description.

Also applies to: 1578-1579


ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository: PostHog/posthog/.coderabbit.yaml

Review profile: QUIET

Plan: Enterprise

Run ID: 03843c8a-ae75-4bfe-951b-004d9e3b14bc

📥 Commits

Reviewing files that changed from the base of the PR and between 94a785b and 11f2725.

⛔ Files ignored due to path filters (4)
  • products/data_warehouse/frontend/generated/api.schemas.ts is excluded by !**/generated/**
  • products/data_warehouse/frontend/generated/api.ts is excluded by !**/generated/**
  • services/mcp/src/generated/data_warehouse/api.ts is excluded by !**/generated/**
  • services/mcp/src/tools/generated/data_warehouse.ts is excluded by !**/generated/**
📒 Files selected for processing (14)
  • docs/internal/managed-warehouse-monitoring.md
  • products/data_warehouse/backend/presentation/managed_warehouse_monitoring.py
  • products/data_warehouse/backend/presentation/managed_warehouse_trino_monitoring.py
  • products/data_warehouse/backend/presentation/views/data_warehouse.py
  • products/data_warehouse/backend/tests/api/test_data_warehouse.py
  • products/data_warehouse/backend/tests/api/test_managed_warehouse_monitoring.py
  • products/data_warehouse/backend/tests/api/test_managed_warehouse_trino_monitoring.py
  • products/data_warehouse/mcp/tools.yaml
  • products/managed_warehouse/backend/presentation/views.py
  • products/managed_warehouse/backend/tests/api/test_presentation.py
  • services/mcp/schema/generated-tool-definitions.json
  • services/mcp/schema/tool-definitions-all.json
  • services/mcp/src/api/generated.ts
  • services/mcp/tests/unit/tool-filtering.test.ts

Included review availability: This review used your included allowance. Your plan provides up to 12 included reviews per hour; 8 remain after this review.

@trunk-io

trunk-io Bot commented Oct 1, 2026

Copy link
Copy Markdown

Static Badge   Static Badge   Static Badge

Failed Test Failure Summary Logs
personalAPIKeysLogic leaves the auto-selected feature_flag:write removable The test failed because it could not find the specified path 'scenes.PreflightCheck.preflightLogic' in the store. Logs ↗︎

View Full Report ↗︎ ⋅ Docs

EDsCODE and others added 4 commits October 6, 2026 11:00
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
@EDsCODE
EDsCODE force-pushed the eric/data-ops-trino-variant-backend branch from 94a785b to ddfc5e9 Compare October 6, 2026 09:11
@EDsCODE
EDsCODE force-pushed the eric/data-ops-trino-monitoring-backend branch from 11f2725 to dbf4c9e Compare October 6, 2026 09:13
@EDsCODE
EDsCODE removed this pull request from stack #110373 October 6, 2026 09:38
@EDsCODE
EDsCODE merged commit dbf4c9e into eric/data-ops-trino-variant-backend Oct 6, 2026
231 checks passed
@EDsCODE
EDsCODE deleted the eric/data-ops-trino-monitoring-backend branch October 6, 2026 09:39
@EDsCODE

EDsCODE commented Oct 6, 2026

Copy link
Copy Markdown
Collaborator Author

Combined into #110369, which carries the whole Trino Data ops variant against master. GitHub shows this PR as merged because its commits were pushed into its base branch, eric/data-ops-trino-variant-backend. Nothing from it is on master. Review it in #110369.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant