fix(telemetry): tighten codex trust-grant classification

This commit is contained in:
Brennan Benson
2026-07-22 14:53:24 -07:00
parent be162f35bc
commit 913200d2a0
4 changed files with 26 additions and 18 deletions
+3 -2
View File
@@ -6,6 +6,7 @@ import {
} from '../../shared/wsl-login-shell-command'
export const WSL_CODEX_AVAILABILITY_TIMEOUT_MS = 5_000
export const WSL_CODEX_NOT_FOUND_MESSAGE = 'Codex CLI not found in the WSL login-shell PATH.'
export function buildWslCodexAvailabilityArgs(distro: string): string[] {
const command = [buildCodexPathLookup(), '[ -n "$resolved" ]'].join('\n')
@@ -16,7 +17,7 @@ export function buildWslCodexIdentityArgs(distro: string): string[] {
const command = [
buildCodexPathLookup(),
'if [ -z "$resolved" ]; then',
" printf '%s\\n' 'Codex CLI not found in the WSL login-shell PATH.' >&2",
` printf '%s\\n' '${WSL_CODEX_NOT_FOUND_MESSAGE}' >&2`,
' exit 127',
'fi',
'printf \'%s\\n\' "$resolved"',
@@ -29,7 +30,7 @@ export function buildWslCodexAppServerArgs(distro: string, linuxHomePath: string
const command = [
buildCodexPathLookup(),
'if [ -z "$resolved" ]; then',
" printf '%s\\n' 'Codex CLI not found in the WSL login-shell PATH.' >&2",
` printf '%s\\n' '${WSL_CODEX_NOT_FOUND_MESSAGE}' >&2`,
' exit 127',
'fi',
`export CODEX_HOME=${quotePosixShell(linuxHomePath)}`,
+3 -10
View File
@@ -64,21 +64,14 @@ export type CodexManagedTrustGrantOutcome =
| { lane: 'rpc'; entries: CodexTrustEntry[] }
| { lane: 'fallback'; reason: CodexTrustGrantFallbackReason }
export type CodexTrustGrantDiagnostics = {
granted: number
ledgerHits: number
fellBack: number
verifyFailed: number
lastFallbackReason: CodexTrustGrantFallbackReason | null
}
const diagnostics: CodexTrustGrantDiagnostics = {
const diagnostics = {
granted: 0,
ledgerHits: 0,
fellBack: 0,
verifyFailed: 0,
lastFallbackReason: null
lastFallbackReason: null as CodexTrustGrantFallbackReason | null
}
export type CodexTrustGrantDiagnostics = typeof diagnostics
const transientRetryAfterByHost = new Map<string, number>()
export function getCodexTrustGrantDiagnostics(): CodexTrustGrantDiagnostics {
@@ -1,4 +1,5 @@
import { describe, expect, it } from 'vitest'
import { WSL_CODEX_NOT_FOUND_MESSAGE } from '../codex-accounts/wsl-codex-command'
import { CodexAppServerTimeoutError } from './codex-app-server-client'
import { classifyCodexTrustGrantError } from './codex-trust-grant-telemetry'
@@ -6,7 +7,18 @@ describe('classifyCodexTrustGrantError', () => {
it.each([
[new CodexAppServerTimeoutError('entry exceeded 20000ms session deadline'), 'timeout'],
[new Error('spawn codex ENOENT'), 'binary-missing'],
[new Error('spawn wsl.exe ENOENT'), 'binary-missing'],
[new Error('spawn /Users/ada/.local/bin/codex ENOENT'), 'binary-missing'],
[
new Error(
`codex app-server exited before completing the session: ${WSL_CODEX_NOT_FOUND_MESSAGE}`
),
'binary-missing'
],
[new Error('spawn wsl.exe ENOENT'), 'unexpected'],
[
new Error("ENOENT: no such file or directory, open '/home/ada/.codex/config.toml'"),
'unexpected'
],
[new Error('codex trust-grant entry bundle not found'), 'entry-failed'],
[new Error('codex trust-grant entry produced no result (exit 1)'), 'entry-failed'],
[
@@ -1,4 +1,5 @@
import type { CodexTrustGrantSessionVerifyClass } from './codex-app-server-client'
import { WSL_CODEX_NOT_FOUND_MESSAGE } from '../codex-accounts/wsl-codex-command'
/** Which install surface asked for the grant: the system-default real ~/.codex
* or a managed (mirror/per-account) home. Telemetry attribution only — the
@@ -44,17 +45,18 @@ export function classifyCodexTrustGrantError(error: unknown): CodexTrustGrantErr
if (message.includes('codex trust-grant entry')) {
return 'entry-failed'
}
// Why: ordered before the bare-ENOENT check — an early-exit message carries a
// stderr tail that could itself mention ENOENT after the binary already ran.
if (
/^spawn (?:.*[\\/])?codex(?:\.(?:cmd|exe|bat))? ENOENT$/.test(message) ||
message.includes(WSL_CODEX_NOT_FOUND_MESSAGE)
) {
return 'binary-missing'
}
if (message.includes('exited before completing the session')) {
return 'early-exit'
}
if (/codex app-server \S+ failed:/.test(message)) {
return 'rpc-failed'
}
if (message.includes('ENOENT')) {
return 'binary-missing'
}
return 'unexpected'
}