Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
6a820da
feat(observability): honor OpenTelemetry export kill switch
rynfar Sep 24, 2026
3af7c5a
docs(upstream): record OTLP kill switch disposition
rynfar Sep 24, 2026
7ed3f71
fix(server): release orphaned input after provider session stops (#739)
rynfar Sep 24, 2026
762792d
fix(server): preserve pending turn admission during provider bind (#752)
rynfar Sep 24, 2026
a8d9041
feat(chat): deliver buffered prose at natural boundaries (#757)
rynfar Sep 24, 2026
9cadbaa
fix(server): show Claude subagent tool progress (#745)
rynfar Sep 24, 2026
a675fa8
fix(server): show Relay workers from installed CLI results (#744)
rynfar Sep 24, 2026
90129e7
fix(relay): accept delegated thread IDs in activity routes (#756)
rynfar Sep 24, 2026
29e57cf
feat(prime): show child progress notes in Agents view (#748)
rynfar Sep 24, 2026
ccb8854
fix(server): bypass provider caches on explicit refresh (#743)
rynfar Sep 24, 2026
91e5166
fix(git): prevent stale ref checkout from restoring files (#751)
rynfar Sep 24, 2026
7cd8bb3
fix(shared): preserve final quoted empty CSV records (#761)
rynfar Sep 24, 2026
b7f9179
fix(server): reduce background GitHub PR quota use (#749)
rynfar Sep 24, 2026
b264cfb
fix(cursor): preserve internal agent errors (#754)
rynfar Sep 24, 2026
e82750e
fix(ci): compare transfer ceilings only within a scenario (#759)
rynfar Sep 24, 2026
298d788
fix(usage): retain saved totals after transcript cleanup (#762)
rynfar Sep 24, 2026
e4434e5
fix(ssh): find Linuxbrew Node on WSL hosts (#769)
rynfar Sep 24, 2026
08e6f51
fix(server): generate PR diffs from branch changes (#13170) (#742)
rynfar Sep 24, 2026
7e59c37
Merge commit '3af7c5a17a46582f64740c4f542d327523bb40fb' into verify/u…
rynfar Sep 24, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .agents/upstream-review.md

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions .github/scripts/thread-transfer-report.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ function validateResult(value) {
}

assertExactKeys(value.scenario, SCENARIO_KEYS, "result.scenario");
if (value.scenario.id !== "thread-transfer-v1") {
if (!["thread-transfer-v1", "thread-transfer-v2"].includes(value.scenario.id)) {
throw new Error("result.scenario.id is not supported");
}
for (const key of SCENARIO_KEYS.slice(1)) {
Expand Down Expand Up @@ -157,7 +157,7 @@ function renderComment(input) {
`| ${provider === "codex" ? "Codex" : "Claude"} | ${metric.label} | ${baselineObserved === undefined ? "—" : formatValue(baselineObserved, metric.kind)} | ${formatValue(observed, metric.kind)} | ${formatImpact(observed, baselineObserved, metric.kind)} | ${formatValue(ceiling, metric.kind)} | ${pass ? "✅" : "❌"} |`,
);

if (baseline && baseline.providers[provider].ceiling[metric.key] !== ceiling) {
if (comparable && baseline.providers[provider].ceiling[metric.key] !== ceiling) {
ceilingChanges.push(
`- ${provider === "codex" ? "Codex" : "Claude"} ${metric.label}: ${formatValue(baseline.providers[provider].ceiling[metric.key], metric.kind)} → ${formatValue(ceiling, metric.kind)}`,
);
Expand Down
18 changes: 18 additions & 0 deletions .github/scripts/thread-transfer-report.test.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -290,3 +290,21 @@ test("preserves a successful result when a same-SHA rerun has no artifact", asyn
assert.equal(published, true);
assert.equal(updatedComment, false);
});

test("accepts V2 without comparing it to the V1 scenario", () => {
const current = result();
current.scenario.id = "thread-transfer-v2";
current.providers.codex.ceiling = { ...current.providers.codex.ceiling, totalWireBytes: 3000000 };
assert.equal(validateResult(current), current);
const comment = renderComment({
current,
baseline: result(),
currentRun: { sha: "bbbbbbbb", conclusion: "success", url: "https://example.com/current" },
baselineRun: { sha: "aaaaaaaa", matchesBase: true, url: "https://example.com/baseline" },
});
assert.match(comment, /fixture changed/);
assert.doesNotMatch(comment, /This PR changes transfer ceilings/);
assert.doesNotMatch(comment, /[+-]\d+\.\d+%/);
current.scenario.id = "unrecognized";
assert.throws(() => validateResult(current), /not supported/);
});
64 changes: 64 additions & 0 deletions apps/desktop/src/app/DesktopObservability.test.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import * as NodeHttpClient from "@effect/platform-node/NodeHttpClient";
import * as NodeServices from "@effect/platform-node/NodeServices";
import { assert, describe, it } from "@effect/vitest";
import * as ConfigProvider from "effect/ConfigProvider";
import * as Effect from "effect/Effect";
import * as FileSystem from "effect/FileSystem";
import * as Layer from "effect/Layer";
Expand Down Expand Up @@ -427,6 +428,36 @@ describe("DesktopObservability", () => {
);
});

it.effect("exports kill switch warnings through the configured logger", () => {
const requests: Array<ExportedRequest> = [];
return Effect.gen(function* () {
const fileSystem = yield* FileSystem.FileSystem;
const baseDir = yield* fileSystem.makeTempDirectoryScoped({
prefix: "t3-desktop-observability-test-",
});
const environmentLayer = makeEnvironmentLayer(baseDir, true, {
T3CODE_OTLP_LOGS_URL: "https://collector.example.com/v1/logs",
});

yield* Effect.scoped(
Effect.void.pipe(
Effect.provide(DesktopObservability.layer.pipe(Layer.provideMerge(environmentLayer))),
),
);

assert.include(requests[0]?.body ?? "", "OTEL_SDK_DISABLED=1 was read as false");
}).pipe(
Effect.scoped,
Effect.provide(
Layer.mergeAll(
NodeServices.layer,
collectorLayer(requests),
ConfigProvider.layer(ConfigProvider.fromEnv({ env: { OTEL_SDK_DISABLED: "1" } })),
),
),
);
});

it.effect("reads every signal endpoint from Settings when the environment names none", () => {
const requests: Array<ExportedRequest> = [];
return Effect.gen(function* () {
Expand Down Expand Up @@ -491,4 +522,37 @@ describe("DesktopObservability", () => {
Effect.provide(Layer.mergeAll(NodeServices.layer, collectorLayer(requests))),
);
});

it.effect("stops every export when the OpenTelemetry SDK is disabled", () => {
const requests: Array<ExportedRequest> = [];
return Effect.gen(function* () {
const fileSystem = yield* FileSystem.FileSystem;
const baseDir = yield* fileSystem.makeTempDirectoryScoped({
prefix: "t3-desktop-observability-test-",
});
const environmentLayer = makeEnvironmentLayer(baseDir);
yield* writeObservabilitySettings(environmentLayer, {
otlpTracesUrl: "https://settings.example.com/v1/traces",
otlpLogsUrl: "https://settings.example.com/v1/logs",
});

yield* Effect.scoped(
Effect.logInfo("desktop log stays local when disabled").pipe(
Effect.withSpan("desktop-disabled-test"),
Effect.provide(DesktopObservability.layer.pipe(Layer.provideMerge(environmentLayer))),
),
);

assert.lengthOf(requests, 0);
}).pipe(
Effect.scoped,
Effect.provide(
Layer.mergeAll(
NodeServices.layer,
collectorLayer(requests),
ConfigProvider.layer(ConfigProvider.fromEnv({ env: { OTEL_SDK_DISABLED: "true" } })),
),
),
);
});
});
14 changes: 13 additions & 1 deletion apps/desktop/src/app/DesktopObservability.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import {
makeTraceSink,
otlpSerializationLayer,
} from "@t3tools/shared/observability";
import * as OtelEnvironment from "@t3tools/shared/otelEnvironment";
import {
parsePersistedServerObservabilitySettings,
type PersistedServerObservabilitySettings,
Expand Down Expand Up @@ -353,12 +354,18 @@ const readPersistedObservabilitySettings: Effect.Effect<
* resolve traces against one revision of the file and logs against another.
*/
const resolveOtlpEndpoints = Effect.gen(function* () {
const otel = yield* OtelEnvironment.load;
if (otel.disabled) {
return { traces: undefined, metrics: undefined, logs: undefined, warnings: otel.warnings };
}

const environment = yield* DesktopEnvironment.DesktopEnvironment;
const persisted = yield* readPersistedObservabilitySettings;
return {
traces: Option.getOrUndefined(environment.otlpTracesUrl) ?? persisted.otlpTracesUrl,
metrics: Option.getOrUndefined(environment.otlpMetricsUrl) ?? persisted.otlpMetricsUrl,
logs: Option.getOrUndefined(environment.otlpLogsUrl) ?? persisted.otlpLogsUrl,
warnings: otel.warnings,
};
});

Expand Down Expand Up @@ -671,7 +678,12 @@ const telemetryLayer = Layer.unwrap(
// resource,
// }).pipe(Layer.provide(serializationLayer));

return Layer.mergeAll(loggerLayer, tracerLayer);
// Logged once the loggers above are installed, so the warnings use them.
const otelWarningsLayer = Layer.effectDiscard(
Effect.forEach(endpoints.warnings, (warning) => Effect.logWarning(warning)),
);

return otelWarningsLayer.pipe(Layer.provideMerge(Layer.mergeAll(loggerLayer, tracerLayer)));
}),
);

Expand Down
43 changes: 43 additions & 0 deletions apps/desktop/src/backend/DesktopBackendConfiguration.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1055,6 +1055,49 @@ describe("DesktopBackendConfiguration", () => {
}).pipe(Effect.scoped, Effect.provide(NodeServices.layer)),
);

it.effect("resolveWsl carries the kill switch into the distro", () =>
Effect.gen(function* () {
const fileSystem = yield* FileSystem.FileSystem;
const baseDir = yield* fileSystem.makeTempDirectoryScoped({
prefix: "t3-desktop-backend-config-test-",
});

const previousWslEnv = process.env.WSLENV;
const previousDisabled = process.env.OTEL_SDK_DISABLED;
try {
delete process.env.WSLENV;
process.env.OTEL_SDK_DISABLED = "true";

yield* Effect.gen(function* () {
const configuration = yield* DesktopBackendConfiguration.DesktopBackendConfiguration;
const config = yield* configuration.resolveWsl({ port: 5050, distro: null });

assert.equal(config.env.OTEL_SDK_DISABLED, "true");
assert.include((config.env.WSLENV ?? "").split(":"), "OTEL_SDK_DISABLED");
}).pipe(
Effect.provide(
DesktopBackendConfiguration.layer.pipe(
Layer.provideMerge(serverExposureLayer),
Layer.provideMerge(DesktopAppSettings.layerTest()),
Layer.provideMerge(DesktopWslServerTree.layerTest()),
Layer.provideMerge(
DesktopWslEnvironment.layerTest({
isAvailable: true,
windowsToWslPath: () => Option.some("/mnt/c/repo/apps/server/src/index.ts"),
getDistroIp: () => Option.some("172.27.0.99"),
}),
),
Layer.provideMerge(makeEnvironmentLayer(baseDir, { platform: "win32" })),
),
),
);
} finally {
restoreEnv("WSLENV", previousWslEnv);
restoreEnv("OTEL_SDK_DISABLED", previousDisabled);
}
}).pipe(Effect.scoped, Effect.provide(NodeServices.layer)),
);

it.effect("resolveWsl preserves existing WSLENV entries when forwarding backend secrets", () =>
Effect.gen(function* () {
const fileSystem = yield* FileSystem.FileSystem;
Expand Down
3 changes: 3 additions & 0 deletions apps/desktop/src/backend/DesktopBackendConfiguration.ts
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,9 @@ const DESKTOP_BACKEND_ENV_NAMES = [
const WSL_FORWARDED_ENV_NAMES = [
"OPENAI_API_KEY",
"ANTHROPIC_API_KEY",
// Otherwise the WSL server keeps exporting to endpoints from the bootstrap.
"T3CODE_OTEL_SDK_DISABLED",
"OTEL_SDK_DISABLED",
"T3CODE_OTLP_HEADERS",
"T3CODE_OTLP_PROTOCOL",
] as const;
Expand Down
2 changes: 2 additions & 0 deletions apps/server/src/bin.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import {
import * as NetService from "@t3tools/shared/Net";
import { HostProcessEnvironment } from "@t3tools/shared/hostProcess";
import { DEFAULT_SIGNAL_EXPORT } from "@t3tools/shared/observability";
import * as OtelEnvironment from "@t3tools/shared/otelEnvironment";
import { assert, it } from "@effect/vitest";
import * as Effect from "effect/Effect";
import * as DateTime from "effect/DateTime";
Expand Down Expand Up @@ -106,6 +107,7 @@ const makeCliTestServerConfig = (baseDir: string) =>
otlpMetricsExport: DEFAULT_SIGNAL_EXPORT,
otlpLogsExport: DEFAULT_SIGNAL_EXPORT,
otlpServiceName: "t3-server",
otelEnvironment: OtelEnvironment.none,
mode: "web",
port: 0,
host: "127.0.0.1",
Expand Down
107 changes: 106 additions & 1 deletion apps/server/src/cli/config.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import {
} from "@t3tools/contracts";
import * as NetService from "@t3tools/shared/Net";
import { DEFAULT_SIGNAL_EXPORT } from "@t3tools/shared/observability";
import * as OtelEnvironment from "@t3tools/shared/otelEnvironment";
import * as NodeServices from "@effect/platform-node/NodeServices";
import * as TestConsole from "effect/testing/TestConsole";
import { Command } from "effect/unstable/cli";
Expand Down Expand Up @@ -58,7 +59,8 @@ it.layer(NodeServices.layer)("cli config resolution", (it) => {
otlpTracesExport: DEFAULT_SIGNAL_EXPORT,
otlpMetricsExport: DEFAULT_SIGNAL_EXPORT,
otlpLogsExport: DEFAULT_SIGNAL_EXPORT,
otlpServiceName: "t3-server",
otlpServiceName: "pylon-server",
otelEnvironment: OtelEnvironment.none,
devAllowedOrigins: [],
} as const;

Expand Down Expand Up @@ -582,6 +584,109 @@ it.layer(NodeServices.layer)("cli config resolution", (it) => {
}),
);

it.effect("zeroes an endpoint stored in Settings when the SDK is disabled", () =>
Effect.gen(function* () {
const fs = yield* FileSystem.FileSystem;
const path = yield* Path.Path;
const baseDir = yield* fs.makeTempDirectoryScoped({ prefix: "t3-cli-config-otel-off-" });
const derivedPaths = yield* deriveExplicitServerPaths(baseDir, undefined);
yield* fs.makeDirectory(path.dirname(derivedPaths.settingsPath), { recursive: true });
yield* fs.writeFileString(
derivedPaths.settingsPath,
// @effect-diagnostics-next-line preferSchemaOverJson:off
`${JSON.stringify({
observability: {
otlpTracesUrl: "http://localhost:4318/v1/traces",
otlpMetricsUrl: "http://localhost:4318/v1/metrics",
otlpLogsUrl: "http://localhost:4318/v1/logs",
},
})}\n`,
);

const resolved = yield* resolveServerConfig(
{
mode: Option.some("desktop"),
port: Option.some(4888),
host: Option.none(),
baseDir: Option.some(baseDir),
cwd: Option.none(),
devUrl: Option.none(),
noBrowser: Option.none(),
bootstrapFd: Option.none(),
autoBootstrapProjectFromCwd: Option.none(),
logWebSocketEvents: Option.none(),
tailscaleServeEnabled: Option.none(),
tailscaleServePort: Option.none(),
},
Option.none(),
).pipe(
Effect.provide(
Layer.mergeAll(
ConfigProvider.layer(ConfigProvider.fromEnv({ env: { OTEL_SDK_DISABLED: "true" } })),
NetService.layer,
),
),
);

// The switch beats every source, including an endpoint stored in Settings.
expect(resolved.otlpTracesUrl).toBeUndefined();
expect(resolved.otlpMetricsUrl).toBeUndefined();
expect(resolved.otlpLogsUrl).toBeUndefined();
expect(resolved.otelEnvironment.disabled).toBe(true);
}),
);

it.effect("lets T3CODE_OTEL_SDK_DISABLED=false override an ambient OTEL_SDK_DISABLED=true", () =>
Effect.gen(function* () {
const fs = yield* FileSystem.FileSystem;
const path = yield* Path.Path;
const baseDir = yield* fs.makeTempDirectoryScoped({ prefix: "t3-cli-config-otel-on-" });
const derivedPaths = yield* deriveExplicitServerPaths(baseDir, undefined);
yield* fs.makeDirectory(path.dirname(derivedPaths.settingsPath), { recursive: true });
yield* fs.writeFileString(
derivedPaths.settingsPath,
// @effect-diagnostics-next-line preferSchemaOverJson:off
`${JSON.stringify({
observability: {
otlpTracesUrl: "http://localhost:4318/v1/traces",
},
})}\n`,
);

const resolved = yield* resolveServerConfig(
{
mode: Option.some("desktop"),
port: Option.some(4888),
host: Option.none(),
baseDir: Option.some(baseDir),
cwd: Option.none(),
devUrl: Option.none(),
noBrowser: Option.none(),
bootstrapFd: Option.none(),
autoBootstrapProjectFromCwd: Option.none(),
logWebSocketEvents: Option.none(),
tailscaleServeEnabled: Option.none(),
tailscaleServePort: Option.none(),
},
Option.none(),
).pipe(
Effect.provide(
Layer.mergeAll(
ConfigProvider.layer(
ConfigProvider.fromEnv({
env: { T3CODE_OTEL_SDK_DISABLED: "false", OTEL_SDK_DISABLED: "true" },
}),
),
NetService.layer,
),
),
);

expect(resolved.otelEnvironment.disabled).toBe(false);
expect(resolved.otlpTracesUrl).toBe("http://localhost:4318/v1/traces");
}),
);

it.effect("forces noBrowser and disables auto-bootstrap for headless startup presentation", () =>
Effect.gen(function* () {
const { join } = yield* Path.Path;
Expand Down
Loading
Loading