Skip to content

[comp] Production Deploy#2707

Merged
Marfuen merged 5 commits intoreleasefrom
main
Apr 29, 2026
Merged

[comp] Production Deploy#2707
Marfuen merged 5 commits intoreleasefrom
main

Conversation

@github-actions
Copy link
Copy Markdown
Contributor

@github-actions github-actions Bot commented Apr 29, 2026

This is an automated pull request to release the candidate branch into production, which will trigger a deployment.
It was created by the [Production PR] action.


Summary by cubic

Integrates Sentry across apps/app and apps/portal for error tracking, tracing, and session replay. Adds client, server, and edge setup with source map upload and a /monitoring tunnel.

  • New Features

    • Added @sentry/nextjs on server, edge, and client with env-driven DSN and dev/prod trace sampling; removed sendDefaultPii and gated includeLocalVariables to non-production.
    • Wrapped Next configs with withSentryConfig for source maps, debug-log treeshake, and /monitoring tunnel; apps/app also enables automaticVercelMonitors.
    • Captures exceptions in each app’s global-error.tsx; exports onRequestError and router transition capture.
    • Session replay enabled (10% sessions; 100% on error). Unmasks text and media by default, with .sentry-mask, [data-sentry-mask], and [data-sentry-block] selectors for selective masking/blocking.
    • Merged botid init into apps/app/src/instrumentation-client.ts alongside Sentry.
    • Allowed Sentry env vars through Turbo (NEXT_PUBLIC_SENTRY_DSN, SENTRY_AUTH_TOKEN, SENTRY_DSN); added .mcp.json for the Sentry MCP server.
  • Migration

    • Set SENTRY_AUTH_TOKEN in CI/Vercel to upload source maps.
    • Set SENTRY_DSN (server) and NEXT_PUBLIC_SENTRY_DSN (client) for production; dev falls back to the default DSN.
    • Ensure /monitoring does not clash with middleware or rewrites.
    • Use .sentry-mask / data-sentry-mask to hide sensitive UI in replays, or data-sentry-block to exclude sections.

Written for commit e985b8b. Summary will update on new commits. Review in cubic

github-actions Bot and others added 2 commits April 29, 2026 18:08
* feat(observability): integrate Sentry into app and portal

Wire @sentry/nextjs into apps/app (via wizard) and apps/portal (manual setup
mirroring the wizard). Both apps push to Sentry org=comp-ai, project=comp.

- Add server, edge, and client init files plus instrumentation.ts in both apps
- Wrap each app's next.config.ts with withSentryConfig (tunnelRoute /monitoring,
  widenClientFileUpload, source map upload, debug-log treeshake)
- Use env-var-driven DSN with the literal as fallback so dev still works without
  setup, and gate tracesSampleRate by NODE_ENV (1.0 dev / 0.1 prod)
- Set includeLocalVariables on server init for richer stack frames
- Capture render errors via Sentry.captureException in both global-error.tsx
- Consolidate apps/app instrumentation-client.ts to src/, merging the existing
  botid init alongside Sentry init (avoids Next.js loading only one of two)
- Place the wizard's sample page inside the [orgId] route group so it isn't
  redirected by the org-scoped layout

Source maps require SENTRY_AUTH_TOKEN to be set in Vercel env (Production +
Preview) for both projects; same token works since it's org-scoped.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* chore(turbo): allow Sentry env vars through to next build

Turbo filters env vars to only what's listed in globalEnv. Without this,
the Sentry webpack plugin can't see SENTRY_AUTH_TOKEN at build time and
silently skips source map upload + release creation, even when the var is
set in Vercel.

Adds NEXT_PUBLIC_SENTRY_DSN, SENTRY_AUTH_TOKEN, SENTRY_DSN to globalEnv.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* fix(sentry): drop sendDefaultPii and remove example pages

P1 from cubic review: Sentry's sendDefaultPii: true auto-attaches IPs,
cookies, and request headers to every event sent to a third-party
processor. For a compliance product that's not the right default; turn
it off across all six init files (server, edge, client × app, portal).
Per-user attribution can still be added explicitly via Sentry.setUser.

P2 from cubic review: the wizard's sentry-example-page used next/head
which doesn't work in App Router. Page was scaffolding intended for
deletion before merge anyway — removed both the page and its companion
API route instead of migrating to the Metadata API.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@vercel
Copy link
Copy Markdown

vercel Bot commented Apr 29, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
app (staging) Ready Ready Preview, Comment Apr 29, 2026 9:32pm
comp-framework-editor (staging) Canceled Canceled Apr 29, 2026 9:32pm
portal (staging) Ready Ready Preview, Comment Apr 29, 2026 9:32pm

Request Review

Copy link
Copy Markdown
Contributor

@cubic-dev-ai cubic-dev-ai Bot left a comment

Choose a reason for hiding this comment

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

3 issues found across 18 files

Prompt for AI agents (unresolved issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.


<file name="apps/app/sentry.server.config.ts">

<violation number="1" location="apps/app/sentry.server.config.ts:14">
P1: `includeLocalVariables` is enabled unconditionally on the server, which can leak sensitive request-scoped values in error payloads and add avoidable overhead in production.</violation>
</file>

<file name="apps/portal/sentry.server.config.ts">

<violation number="1" location="apps/portal/sentry.server.config.ts:14">
P2: `includeLocalVariables` is enabled for all environments; this adds debugger-based overhead on exceptions and can capture request-local data in production. Gate it to development (or an explicit opt-in env var).</violation>
</file>

<file name="apps/app/src/instrumentation-client.ts">

<violation number="1" location="apps/app/src/instrumentation-client.ts:12">
P1: Use route paths (e.g. `/api/...`) in BotID `protect` rules instead of absolute URLs; absolute URL patterns can fail to match and leave these POST calls unprotected.</violation>
</file>

Reply with feedback, questions, or to request a fix. Tag @cubic-dev-ai to re-run a review.

Comment thread apps/app/sentry.server.config.ts Outdated
protect: [
{ path: '/api/chat', method: 'POST' },
{
path: `${process.env.NEXT_PUBLIC_ENTERPRISE_API_URL}/api/tasks-automations/chat`,
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.

P1: Use route paths (e.g. /api/...) in BotID protect rules instead of absolute URLs; absolute URL patterns can fail to match and leave these POST calls unprotected.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At apps/app/src/instrumentation-client.ts, line 12:

<comment>Use route paths (e.g. `/api/...`) in BotID `protect` rules instead of absolute URLs; absolute URL patterns can fail to match and leave these POST calls unprotected.</comment>

<file context>
@@ -0,0 +1,38 @@
+  protect: [
+    { path: '/api/chat', method: 'POST' },
+    {
+      path: `${process.env.NEXT_PUBLIC_ENTERPRISE_API_URL}/api/tasks-automations/chat`,
+      method: 'POST',
+    },
</file context>

Comment thread apps/portal/sentry.server.config.ts Outdated
* feat(observability): integrate Sentry into app and portal

Wire @sentry/nextjs into apps/app (via wizard) and apps/portal (manual setup
mirroring the wizard). Both apps push to Sentry org=comp-ai, project=comp.

- Add server, edge, and client init files plus instrumentation.ts in both apps
- Wrap each app's next.config.ts with withSentryConfig (tunnelRoute /monitoring,
  widenClientFileUpload, source map upload, debug-log treeshake)
- Use env-var-driven DSN with the literal as fallback so dev still works without
  setup, and gate tracesSampleRate by NODE_ENV (1.0 dev / 0.1 prod)
- Set includeLocalVariables on server init for richer stack frames
- Capture render errors via Sentry.captureException in both global-error.tsx
- Consolidate apps/app instrumentation-client.ts to src/, merging the existing
  botid init alongside Sentry init (avoids Next.js loading only one of two)
- Place the wizard's sample page inside the [orgId] route group so it isn't
  redirected by the org-scoped layout

Source maps require SENTRY_AUTH_TOKEN to be set in Vercel env (Production +
Preview) for both projects; same token works since it's org-scoped.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* chore(turbo): allow Sentry env vars through to next build

Turbo filters env vars to only what's listed in globalEnv. Without this,
the Sentry webpack plugin can't see SENTRY_AUTH_TOKEN at build time and
silently skips source map upload + release creation, even when the var is
set in Vercel.

Adds NEXT_PUBLIC_SENTRY_DSN, SENTRY_AUTH_TOKEN, SENTRY_DSN to globalEnv.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* fix(sentry): drop sendDefaultPii and remove example pages

P1 from cubic review: Sentry's sendDefaultPii: true auto-attaches IPs,
cookies, and request headers to every event sent to a third-party
processor. For a compliance product that's not the right default; turn
it off across all six init files (server, edge, client × app, portal).
Per-user attribution can still be added explicitly via Sentry.setUser.

P2 from cubic review: the wizard's sentry-example-page used next/head
which doesn't work in App Router. Page was scaffolding intended for
deletion before merge anyway — removed both the page and its companion
API route instead of migrating to the Metadata API.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* revert(sentry): re-enable sendDefaultPii across both apps

Reversing the conservative default after team review: app does not
collect SSN-style typed PII, and IP / user-agent / cookie context is
useful for debugging real production incidents. Sentry's default ingest
scrubbers continue to mask Authorization, Cookie, and X-Api-Key by key;
session replay still masks <input type="password"> by default.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Mariano <marfuen98@gmail.com>
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Copy link
Copy Markdown
Contributor

@cubic-dev-ai cubic-dev-ai Bot left a comment

Choose a reason for hiding this comment

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

1 issue found across 6 files (changes from recent commits).

Prompt for AI agents (unresolved issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.


<file name="apps/portal/sentry.server.config.ts">

<violation number="1" location="apps/portal/sentry.server.config.ts:18">
P1: `sendDefaultPii` is enabled unconditionally on the server, which can leak user PII (for example IP address and request metadata) to Sentry. This should be explicitly opt-in (env-gated) rather than always on.</violation>
</file>

Reply with feedback, questions, or to request a fix. Tag @cubic-dev-ai to re-run a review.

Comment thread apps/portal/sentry.server.config.ts Outdated
…oks (#2709)

Sentry session replay defaults to masking all text and blocking all media,
which produces unreadable rows of asterisks on every replay. Turn both off
so replays are actually useful for debugging, and add .sentry-mask /
[data-sentry-mask] / [data-sentry-block] selectors so we can opt specific
customer-sensitive elements (risk descriptions, secret values, policy
markdown) back into masking as we identify them. <input type="password">
remains masked automatically by the SDK regardless.

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@Marfuen
Copy link
Copy Markdown
Contributor

Marfuen commented Apr 29, 2026

Reviewed cubic's three findings:

P1 — includeLocalVariables: true (server, both apps) — agreed, fixed in #2710. The original skill recommendation didn't account for the fact that local variable scope at throw time can include DB rows, auth tokens being validated, and request bodies — broader exposure than sendDefaultPii. Now gated to process.env.NODE_ENV !== 'production' so it only runs in dev/test.

P1 — sendDefaultPii: true (server) — also dropping in #2710. It was originally added under the (mistaken) assumption it would unblur session replay text; that's actually controlled by replayIntegration({ maskAllText, blockAllMedia }) (handled in #2709). With replays already showing real text, all this flag adds is IP / UA / Referer metadata — not worth the sub-processor data exposure for a compliance product.

P1 — botid absolute URLs in instrumentation-client.ts — pre-existing dead config that fundamentally can't work. Verified by reading node_modules/botid/dist/client/core/index.js: the path matcher compares against c.pathname only (so absolute URLs never match), and a same-origin gate (l = c.origin === location.origin) bails before even reaching the matcher for cross-origin requests. The two cross-origin entries can't be protected from this app's initBotId regardless of path format. Tracked as ENG-226 for follow-up; the proper fix is bot protection on enterprise-api itself.

* fix(sentry): gate includeLocalVariables to non-production

includeLocalVariables uses Node's debugger inspector to attach every
local variable in scope at the moment an error throws. In production
that scope can include DB rows, auth tokens being validated, request
bodies, and session state — far broader than sendDefaultPii. Off in
prod, on in dev/test where the debugging value justifies the exposure.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* fix(sentry): drop sendDefaultPii now that replay unmask is the right knob

sendDefaultPii was originally added to make session replay text
readable, but that's actually controlled by replayIntegration's
maskAllText / blockAllMedia (handled in #2709). With replays already
showing real text, the only thing sendDefaultPii adds is per-event IP
addresses and User-Agent — useful triage signal but not worth the
sub-processor data exposure for a compliance product.

Errors still carry full stack traces, breadcrumbs, source-mapped
frames, and replay context; only the IP/UA metadata layer goes away.
Removing across all six init files (server, edge, client × app, portal).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Mariano <marfuen98@gmail.com>
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@Marfuen Marfuen merged commit 23a49e2 into release Apr 29, 2026
8 of 11 checks passed
@claudfuen
Copy link
Copy Markdown
Contributor

🎉 This PR is included in version 3.38.0 🎉

The release is available on GitHub release

Your semantic-release bot 📦🚀

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

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants