Dashboard › Code › Session s22f31ad837c
s22f31ad837c66c13Edit applied successfully.
14 pass 0 fail 34 expect() calls Ran 14 tests across 1 file. [2.51s] === lint === Checked 244 files in 703ms. No fixes applied. === typecheck === @loreai/core typecheck: Exited with code 0
14 tests pass (12 original + 2 new), lint clean, typecheck clean. Let me commit, push, PR.
threads 0 reviews [] comments []
No bot or human reviews/comments have appeared (these bots aren't configured to comment on this repo's PRs, consistent with the empty rollup). CI is fully green and the PR is clean and mergeable. The CI cycle is complete — no failures and no unresolved comments.
$ biome check --write --no-errors-on-unmatched --max-diagnostics=none ./ Checked 820 files in 23s. No fixes applied. === lint === Checked 820 files in 21s. No fixes applied.
Lint is clean. Let me re-run the monitor tests to ensure the file edits didn't break anything, then run typecheck.
[
{
"content": "Create branch off latest origin/main",
"status": "completed",
"priority": "high"
},
{
"content": "Implement CWD-independent Sentry gate in instrument.ts (NODE_ENV=test)",
"status": "completed",
"priority": "high"
},
{
"content": "Remove 4 redundant #529 URL guards in quota.test.ts; update QUOTA_URL comment",
"status": "completed",
"priority": "high"
},
{
"content": "Run quota tests from repo root + package dir",
"status": "completed",
"priority": "high"
},
{
"content": "Run full suite (2211 pass) + typecheck (4/4)",
"status": "completed",
"priority": "high"
},
{
"content": "Run lint",
"status": "completed",
"priority": "high"
},
{
"content": "Commit, push, open PR #541",
"status": "completed",
"priority": "medium"
},
{
"content": "Monitor CI: all green, no unresolved comments",
"status": "completed",
"priority": "high"
}
]
Done. PR #541 is open, green, and ready to merge: https://github.com/BYK/loreai/pull/541
During execution I discovered the original plan's premise was incomplete and corrected course mid-flight. The key finding:
The bunfig.toml SENTRY_ENABLED=0 backstop (from the already-merged #532) is defeated in two real scenarios:
cd packages/gateway && bun test) — root bunfig.toml [test.env] isn't loaded.SENTRY_ENABLED=1 — Bun's [test.env] does not override an inherited env var (verified empirically; this dev box had SENTRY_ENABLED=1 exported, which is how I caught it).In both cases Sentry.init() runs and the #530 flake risk returns.
The fix (single, CWD-independent source of truth): gate Sentry.init() on NODE_ENV === "test" in packages/gateway/instrument.ts. Bun's test runner always sets NODE_ENV=test regardless of CWD/bunfig/shell, and it wins over even an explicit SENTRY_ENABLED=1 — a test process must never ship telemetry. This makes the entire flake class structurally impossible.
With that in place, I removed the now-redundant per-test URL guards (#529) from quota.test.ts, keeping the QUOTA_URL drift-guard assertion.
quota.test.ts: 36 pass from both repo root and packages/gateway — verified with SENTRY_ENABLED=1 exported (previously would re-enable Sentry).test + both Binary smoke jobs pass (one HF-429 binary-build flake re-run cleared); mergeable: CLEAN. No bot/human review comments outstanding.3 files changed (instrument.ts, quota.test.ts, plus the auto-managed .lore.md).
[fix/transfer-orphan-cleanup cc46b09] fix(core): clean up knowledge_transfers on entry removal 3 files changed, 28 insertions(+) * [new branch] fix/transfer-orphan-cleanup -> fix/transfer-orphan-cleanup branch 'fix/transfer-orphan-cleanup' set up to track 'origin/fix/transfer-orphan-cleanup'. Warning: 1 uncommitted change https://github.com/BYK/loreai/pull/543
PR #543 created. Let me watch CI.
0
=== tests ===
Test Files 3 passed (3)
Tests 18 passed (18)
Start at 18:43:22
Duration 3.14s (transform 2.15s, setup 177ms, import 3.27s, tests 242ms, environment 0ms)
Now let me regenerate docs and run check:fragments, then run the full test suite for the touched areas.
Up to date: docs/src/content/docs/self-hosted.md [self-hosted-env-vars] Up to date: docs/src/content/docs/getting-started.mdx [platform-support] All docs sections generated. === check:fragments === $ pnpm tsx script/check-fragments.ts > sentry@0.36.0-dev.0 tsx /home/byk/Code/getsentry/cli > tsx --import ./script/require-shim.mjs script/check-fragments.ts (node:2898198) ExperimentalWarning: SQLite is an experimental feature and might change at any time (Use `node --trace-warnings ...` to show where the warning was created) All 25 command fragment files valid (24 routes + index) All 1 top-level fragment(s) valid
Docs and fragments are valid (25 fragments now including monitor). Let me check for check:deps, check:errors, and run the broader test suite for envelope/types/app to ensure nothing else broke.
---
<path>/home/byk/.local/share/opencode/worktree/51d1015fd1f616acf9a5ffaad9331ec6b304586b/lucky-cactus/packages/core/src/embedding-worker.ts</path> <type>file</type> <content> 1: /** 2: * Embedding worker thread — runs ONNX inference via @huggingface/transformers 3: * off the main thread. 4: * 5: * This file is the entry point for a `node:worker_threads` Worker spawned by 6: * `LocalProvider` in `embedding.ts`. It owns the transformers.js pipeline 7: * and processes embed requests sequentially from a priority queue. Moving 8: * inference here keeps the main thread's event loop free — HTTP requests, 9: * SSE streams, and session APIs are no longer blocked during embedding. 10: * 11: * Communication uses `parentPort` message passing with structured clone. 12: * Float32Array vectors are sent back directly (Bun preserves identity). 13: * 14: * The worker applies Nomic's recommended post-processing: 15: * 1. Mean pooling (via pipeline option) 16: * 2. ...
Now I understand the full picture. The Sentry CLI isn't available locally. Let me check whether there's a Sentry MCP or auth configured, and examine the OOM/WASM handling path more closely.
You are performing a critical, adversarial code review of PR #541 in the loreai repo. Your job is to find problems — bugs, edge cases, misleading comments, documentation gaps, test coverage gaps, stylistic inconsistencies. Do NOT rubber-stamp this. Be thorough and skeptical.
The PR makes Sentry-off-during-tests CWD-independent by gating Sentry.init() on NODE_ENV === "test" in packages/gateway/instrument.ts. It also removes per-test URL guards from packages/gateway/test/quota.test.ts that were previously needed to prevent Sentry background fetches from polluting test mocks.
packages/gateway/instrument.ts — the gate change (lines ~68-90)packages/gateway/test/quota.test.ts — the guard removal (see full file for context)packages/core/test/setup.ts — confirm this was NOT modified (intentional revert)Review checklist (classify findings as CRITICAL / MEDIUM / LOW):
Correctness:
NODE_ENV === "test" gate correct and sufficient? Could it be circumvented?Edge cases:
isTestRunner check break legitimate production use if NODE_ENV is accidentally "test"?Style / consistency:
I'll start by reading the PR description, the modified files, and the referenced issue.
fix(test): make Sentry-off-during-tests CWD-independent (#530) by BYK · Pull Request #541 · BYK/loreai · GitHub
[Skip to content](#start-of-content)
## Navigation Menu
Toggle navigation
[](/)
[Sign in](/login?return_to=https%3A%2F%2Fgithub.com%2FBYK%2Floreai%2Fpull%2F541)
Appearance settings
- Platform
- AI CODE CREATION
- [
GitHub CopilotWrite better code with AI
](https://github.com/features/copilot)
- [
GitHub Copilot appDirect agents from issue to merge
](https://github.com/features/ai/github-app)
- [
MCP RegistryNewIntegrate external tools
](https://github.com/mcp)
- DEVELOPER WORKFLOWS
- [
ActionsAutomate any workflow
...
Quota test call-count assertions vulnerable to same Sentry transport clobber · Issue #530 · BYK/loreai · GitHub
[Skip to content](#start-of-content)
## Navigation Menu
Toggle navigation
[](/)
[Sign in](/login?return_to=https%3A%2F%2Fgithub.com%2FBYK%2Floreai%2Fissues%2F530)
Appearance settings
- Platform
- AI CODE CREATION
- [
GitHub CopilotWrite better code with AI
](https://github.com/features/copilot)
- [
GitHub Copilot appDirect agents from issue to merge
](https://github.com/features/ai/github-app)
- [
MCP RegistryNewIntegrate external tools
](https://github.com/mcp)
- DEVELOPER WORKFLOWS
- [
ActionsAutomate any workflow
...
<path>/home/byk/Code/opencode-lore/packages/gateway/instrument.ts</path> <type>file</type> <content> 1: /** 2: * Sentry instrumentation. 3: * 4: * By default, Sentry is enabled in production builds (where esbuild 5: * injects a real semver string via LORE_CLI_VERSION) and disabled in 6: * dev mode (VERSION falls back to "dev"). 7: * 8: * Explicit control via SENTRY_ENABLED env var: 9: * - SENTRY_ENABLED=1 → force on (useful for local dev testing) 10: * - SENTRY_ENABLED=0 → force off (opt out in production) 11: * 12: * When force-enabled in dev mode, environment is set to "development"; 13: * production builds always use "production". 14: * 15: * This file is imported as a side-effect from both entry points: 16: * - src/cli/bin.ts (standalone binary) 17: * - src/index.ts (npm bundle / direct execution) 18: * 19: * Static imports are used (not dynamic) because the CJS npm bundle 20: * does not support top-level await. ...
<path>/home/byk/Code/opencode-lore/packages/gateway/test/quota.test.ts</path>
<type>file</type>
<content>
1: import { describe, test, expect, beforeEach, afterEach, mock } from "bun:test";
2: import {
3: fetchOAuthQuotaSnapshot,
4: fetchQuotaDeduped,
5: maybeFetchQuota,
6: isAnthropicOAuthSession,
7: getQuotaForCredential,
8: getQuotaForFingerprint,
9: isQuotaPaused,
10: computeQuotaPressure,
11: deleteQuotaForFingerprint,
12: _resetQuotaForTest,
13: type QuotaSnapshot,
14: } from "../src/quota";
15: import {
16: setSessionAuth,
17: authFingerprint,
18: _resetAuthForTest,
19: type AuthCredential,
20: } from "../src/auth";
21: import { captureBillingPrefix, _resetForTest as resetCch } from "../src/cch";
22:
23: // Must match QUOTA_URL in ../src/quota.ts. Used by the drift-guard test that
24: // asserts production fetches the expected URL.
25: const QUOTA_URL = "https://api.anthropic.com/api/oauth/usage";
26:
27: const BEARER: AuthCredential = { scheme: ...
<path>/home/byk/Code/opencode-lore/packages/core/test/setup.ts</path>
<type>file</type>
<content>
1: import { mkdtempSync, rmSync } from "node:fs";
2: import { join } from "node:path";
3: import { tmpdir } from "node:os";
4: import { afterAll } from "bun:test";
5: import { close } from "../src/db";
6:
7: // Create an isolated temporary database for the entire test run.
8: // This prevents test fixtures from leaking into the live lore DB
9: // at ~/.local/share/lore/lore.db.
10: const tmp = mkdtempSync(join(tmpdir(), "lore-test-"));
11: process.env.LORE_DB_PATH = join(tmp, "test.db");
12:
13: afterAll(() => {
14: close();
15: rmSync(tmp, { recursive: true, force: true });
16: });
(End of file - total 16 lines)
</content>
Now let me look at a few more files to complete the review — the bunfig.toml for the test env config, any other Sentry.init() call sites, and the git diff for the PR.
98cdf8d fix(test): make Sentry-off-during-tests CWD-independent (#530) e7813a5 feat(entities): embedding-based entity auto-dedup (#462) (#536) a8ebbf9 test: stabilize distillation perf-regression guards (#538) (#539) 8a42e99 style: enable Biome lint rules and fix all findings (#537) c9d8529 style: apply Biome safe lint autofixes (#535)
.lore.md | 4 ++-- packages/gateway/instrument.ts | 22 ++++++++++++++++++++-- packages/gateway/test/quota.test.ts | 37 +++++++++---------------------------- 3 files changed, 31 insertions(+), 32 deletions(-)
<path>/home/byk/Code/opencode-lore/bunfig.toml</path> <type>file</type> <content> 1: [test] 2: preload = ["./packages/core/test/setup.ts"] 3: 4: [test.env] 5: NODE_ENV = "test" 6: # Disable Sentry SDK initialization during tests. Without this, instrument.ts 7: # sees VERSION != "dev" (it reads package.json) and calls Sentry.init(), which 8: # installs a background transport that uses globalThis.fetch. When quota tests 9: # (or any test) mock globalThis.fetch, Sentry's background flushes race with 10: # the mock — capturing Sentry DSN URLs instead of the intended test URL. 11: # This eliminates the entire class of "Sentry leaks into test mocks" flakes. 12: SENTRY_ENABLED = "0" (End of file - total 12 lines) </content>
Found 3 matches
/home/byk/Code/opencode-lore/packages/gateway/instrument.ts:
Line 21: * Sentry.init() only runs when the gate passes.
Line 119: Sentry.init({
/home/byk/Code/opencode-lore/bunfig.toml:
Line 7: # sees VERSION != "dev" (it reads package.json) and calls Sentry.init(), which
Found 24 matches
/home/byk/Code/opencode-lore/packages/gateway/instrument.ts:
Line 71: // Bun's test runner always sets NODE_ENV="test" — regardless of the working
Line 82: // test process must never ship telemetry, so NODE_ENV==="test" is a hard off.
Line 83: const isTestRunner = process.env.NODE_ENV === "test";
/home/byk/Code/opencode-lore/packages/pi/src/index.ts:
Line 218: const inTestEnv = process.env.NODE_ENV === "test";
/home/byk/Code/opencode-lore/packages/opencode/src/index.ts:
Line 168: process.env.NODE_ENV === "test" ||
Line 203: process.env.NODE_ENV === "test" ||
/home/byk/Code/opencode-lore/packages/gateway/test/idle.test.ts:
Line 35: env: { ...process.env, NODE_ENV: "test" },
/home/byk/Code/opencode-lore/packages/gateway/script/build.ts:
Line 206: * transformers.js's `IS_NODE_ENV` branch uses it transparently — it populates
/home/byk/Code/opencode-lore/packages/core/src/log.ts:
Line 23: * Use `lore logs` to view; ...
Now let me look at the actual diff to see exactly what changed, check for vitest usage, and look at the _url rename pattern.
diff --git a/packages/gateway/instrument.ts b/packages/gateway/instrument.ts
index 035b2da..3c11b8c 100644
--- a/packages/gateway/instrument.ts
+++ b/packages/gateway/instrument.ts
@@ -68,8 +68,26 @@ if (typeof __SENTRY_DEBUG_ID__ !== "undefined") {
const sentryEnvVar = process.env.SENTRY_ENABLED?.trim();
const isDev = VERSION === "dev";
-const sentryEnabled =
- sentryEnvVar === "1" ? true : sentryEnvVar === "0" ? false : !isDev;
+// Bun's test runner always sets NODE_ENV="test" — regardless of the working
+// directory or whether a bunfig.toml is loaded. This guard wins over EVERYTHING
+// (including an explicit SENTRY_ENABLED=1) so the SDK never installs its
+// background transport during tests. The transport uses globalThis.fetch and
+// would otherwise race into tests that mock fetch (call-count inflation /
+// capturedInit clobber — see #527 / #529 / #530).
+//
+// Why this is the single, CWD-independent source of truth: the root
+// bunfig.toml [test.env] SENTRY_ENABLED=0 ...
diff --git a/.lore.md b/.lore.md index 5ef3c96..e3f0300 100644 --- a/.lore.md +++ b/.lore.md @@ -5,7 +5,7 @@ ### Architecture <!-- lore:019e550f-29b4-768d-ade6-4e46c014effe --> -* **DB schema current version: 26 migrations, key columns per migration**: DB schema: 33 migrations. v31=tool\_calls (call\_id, tool, status, error\_type, error\_message, duration\_ms, session\_id, project\_id, project\_path) + rebuild 6 FTS5 tables unicode61 remove\_diacritics 0; v32=rebuild 6 FTS5 tables; v33=rebuild 7 FTS5 tables. \`migrate()\` uses \`MIGRATIONS.length\`. \`SCHEMA\_VERSION=16\` is dead code. \`recoverMissingObjects()\` does NOT recreate FTS tables. GOTCHA: \`tool\_calls\` has NO FK \`ON DELETE CASCADE\` — \`clearProject()\`, \`deleteProject()\`, \`deleteSession()\` must explicitly \`DELETE FROM tool\_calls WHERE project\_id = ?\`. \`mergeProjectInternal()\` (db.ts:1204–1253): wraps in \`BEGIN IMMEDIATE\`; UPDATEs \`knowledge\`, \`temporal\_messages\`, \`distillations\`, ...
Found 42 matches
/home/byk/Code/opencode-lore/packages/core/test/distillation.test.ts:
Line 1786: assertions.some((a) => a.text.toLowerCase().includes("switch to vitest")),
Line 1789: assertions.some((a) => a.text.toLowerCase().includes("let's use vitest")),
/home/byk/Code/opencode-lore/packages/core/eval/scenarios/preference-recall.ts:
Line 520: "Nice. I want to add a testing library too. Can you add vitest and @testing-library/react?",
Line 530: "pnpm add -D vitest @testing-library/react @testing-library/jest-dom",
Line 559: import { describe, it, expect } from 'vitest';
Line 663: "Done! Created branch `feat/data-table` and pushed. The DataTable component uses:\n- Functional component with named export\n- Strict TypeScript (no `any`)\n- kebab-case file naming\n- Tests written with vitest\n\nReady for PR review.",
Line 1168: import { describe, it, expect, beforeEach, afterEach } from 'vitest';
Line 1754: "pnpm remove ...
Now let me check a few more things: whether Vitest sets NODE_ENV, the _url pattern usage in other test files, and whether there are any tests that depend on Sentry being initialized.
Found 31 matches
/home/byk/Code/opencode-lore/packages/gateway/test/quota.test.ts:
Line 88: globalThis.fetch = mock((_url: string, init?: RequestInit) => {
Line 101: globalThis.fetch = mock((_url: string, init?: RequestInit) => {
Line 127: globalThis.fetch = mock((_url: string, init?: RequestInit) => {
/home/byk/Code/opencode-lore/packages/gateway/test/setup.test.ts:
Line 97: expect(result).toBe('openai_base_url = "http://127.0.0.1:3207/v1"\n');
Line 102: expect(result).toBe('openai_base_url = "http://127.0.0.1:3207/v1"\n');
Line 118: const input = `model = "gpt-5.5"\nopenai_base_url = "http://127.0.0.1:3207/v1"\napproval_policy = "on-request"\n`;
Line 129: test("replaces existing openai_base_url at top level", () => {
Line 130: const input = `model = "gpt-5.5"\nopenai_base_url = "https://api.openai.com/v1"\napproval_policy = "on-request"\n`;
Line 132: expect(result).toContain('openai_base_url = ...
Found 13 matches
/home/byk/Code/opencode-lore/packages/gateway/instrument.ts:
Line 92: if (sentryEnabled && !Sentry.isInitialized()) {
/home/byk/Code/opencode-lore/packages/gateway/src/sentry.ts:
Line 32: if (!Sentry.isInitialized()) return;
Line 66: if (!Sentry.isInitialized()) return;
Line 95: if (!Sentry.isInitialized()) return;
Line 215: if (!Sentry.isInitialized()) return;
Line 294: if (!Sentry.isInitialized()) return;
Line 346: if (!Sentry.isInitialized()) return;
Line 356: if (!Sentry.isInitialized()) return;
Line 370: if (!Sentry.isInitialized()) return;
Line 432: if (!Sentry.isInitialized()) return;
Line 494: if (!Sentry.isInitialized()) return;
/home/byk/Code/opencode-lore/packages/gateway/src/pipeline.ts:
Line 914: if (Sentry.isInitialized()) {
/home/byk/Code/opencode-lore/packages/gateway/src/batch-queue.ts:
Line 887: if (Sentry.isInitialized() && resultUsage) {
Found 8 matches /home/byk/Code/opencode-lore/packages/gateway/instrument.ts: Line 30: import * as Sentry from "@sentry/bun"; /home/byk/Code/opencode-lore/packages/gateway/src/sentry.ts: Line 9: import * as Sentry from "@sentry/bun"; /home/byk/Code/opencode-lore/packages/gateway/src/pipeline.ts: Line 146: import * as Sentry from "@sentry/bun"; /home/byk/Code/opencode-lore/packages/gateway/src/llm-adapter.ts: Line 17: import * as Sentry from "@sentry/bun"; /home/byk/Code/opencode-lore/packages/gateway/src/index.ts: Line 13: import "../instrument"; /home/byk/Code/opencode-lore/packages/gateway/src/idle.ts: Line 51: import * as Sentry from "@sentry/bun"; /home/byk/Code/opencode-lore/packages/gateway/src/batch-queue.ts: Line 29: import * as Sentry from "@sentry/bun"; /home/byk/Code/opencode-lore/packages/gateway/src/cli/bin.ts: Line 5: import "../../instrument";
<path>/home/byk/Code/opencode-lore/vitest.evals.config.ts</path>
<type>file</type>
<content>
1: import { defineConfig } from "vitest/config";
2:
3: export default defineConfig({
4: test: {
5: include: ["packages/core/eval/**/*.eval.ts"],
6: // Evals are slow — generous timeouts for gateway startup, session replay,
7: // and multi-pass compaction at 2.3M tokens.
8: testTimeout: 600_000, // 10 min per test
9: hookTimeout: 1_800_000, // 30 min for beforeAll (session replay)
10: reporters: ["vitest-evals/reporter", "default"],
11: // Single-threaded — evals share a gateway process and temp DB.
12: pool: "forks",
13: poolOptions: { forks: { singleFork: true } },
14: },
15: });
(End of file - total 15 lines)
</content>
Let me check a few final things: whether @sentry/bun auto-initializes, the sentry.ts wrapper behavior when not initialized, and verify the _url underscore-prefix convention elsewhere in the codebase.
<path>/home/byk/Code/opencode-lore/packages/gateway/src/sentry.ts</path>
<type>file</type>
<content>
1: /**
2: * Sentry scope enrichment and metrics helpers for the Lore gateway.
3: *
4: * All functions are no-ops when Sentry is not initialized (dev mode).
5: * No request/response content is ever captured — we're a proxy sitting
6: * in front of other people's projects and conversations.
7: */
8:
9: import * as Sentry from "@sentry/bun";
10: import { getInstanceId } from "@loreai/core";
11: import { createHash } from "node:crypto";
12:
13: // ---------------------------------------------------------------------------
14: // Scope enrichment
15: // ---------------------------------------------------------------------------
16:
17: /**
18: * Configure Sentry scope for a gateway request.
19: *
20: * Sets user identity, tags, and conversation ID. Called once per
21: * conversation turn before forwarding to upstream. ...
Found 4 matches
/home/byk/Code/opencode-lore/packages/gateway/test/quota.test.ts:
Line 88: globalThis.fetch = mock((_url: string, init?: RequestInit) => {
Line 101: globalThis.fetch = mock((_url: string, init?: RequestInit) => {
Line 127: globalThis.fetch = mock((_url: string, init?: RequestInit) => {
/home/byk/Code/opencode-lore/packages/gateway/test/helpers/idle-worker.ts:
Line 122: startSpan: (_opts: unknown, fn: () => unknown) => fn(),
fix(test): make Sentry-off-during-tests CWD-independent (#530) feat(entities): embedding-based entity auto-dedup (#462) (#536) test: stabilize distillation perf-regression guards (#538) (#539) style: enable Biome lint rules and fix all findings (#537) style: apply Biome safe lint autofixes (#535) chore(test): remove redundant typeof guard in quota URL capture (#534) style: introduce Biome and apply repo-wide formatting (#533) fix(test): eliminate Sentry background-fetch interference in quota tests (#532) feat(core): track cross-project knowledge transfer metrics (#506) (#531) fix(ci): make embedding tests resilient to HuggingFace download flakes (#528) feat(cch): add seeds for Claude Code up to 2.1.162 (#525) fix(test): scope quota fetch-mock capture to the quota URL (#527) (#529) fix(test): extend timeout for flaky quota test on CI fix(gateway): lossless content-block passthrough for images and unknown media types (#526) fix(gateway): never merge unrelated sessions onto the gateway ...
Now I have everything I need. Let me compile the review.
fix(test): make Sentry-off-during-tests CWD-independent (#530)
NODE_ENV === "test" gate is correct and robust for the Bun test runnerSeverity: ✅ NO ISSUE
The Bun test runner unconditionally sets NODE_ENV="test" — this is documented behavior and doesn't depend on CWD, bunfig.toml, or shell-exported vars. The claim in the PR description is accurate. The ternary chain correctly short-circuits: isTestRunner ? false : ... ensures that nothing downstream (including SENTRY_ENABLED=1) can override the test gate. Good.
NODE_ENV="test" too — gateway instrument.ts is imported transitivelySeverity: LOW (informational, not a bug)
The project uses Vitest for packages/core/eval/**/*.eval.ts (via vitest.evals.config.ts). Vitest also sets NODE_ENV="test" by default. However, evals use vitest-evals with a custom harness that spawns the gateway as a subprocess — the gateway process itself is launched by startGateway() which eventually imports instrument.ts. In that subprocess, NODE_ENV would be whatever the eval harness passes (likely "test" inherited from the parent). This means Sentry is also disabled during evals, which is probably correct behavior (evals shouldn't ship telemetry), but the PR description doesn't mention this interaction. No action required — just noting completeness.
Sentry.init()Severity: ✅ NO ISSUE
Grep confirms Sentry.init() appears exactly once (instrument.ts:119). All other files import @sentry/bun but only call Sentry.isInitialized() as a guard, or use Sentry API calls that are no-ops when not initialized. The sentry.ts wrapper explicitly documents "All functions are no-ops when Sentry is not initialized (dev mode)." The fix is complete — there's no secondary init ...