Files
orca/src/shared/daemon-adoption-telemetry.test.ts
Jinwoo Hong a7fda48fe3 feat(telemetry): measure macOS stale-daemon adoption and cwd denials (#18043)
* feat(telemetry): measure macOS stale-daemon adoption and cwd denials

Adds two enum-only PostHog events so #17696 can be sized instead of guessed at:

- daemon_adopted: once per macOS launch that keeps a daemon an earlier app
  launch forked (invisible to daemon_lifecycle, which only sees replacements).
  Carries app-version match, spawner-path class (installed app / Squirrel
  ShipIt cache / other / missing), the existing TCC attribution verdict, and
  the bucketed live-session count.
- daemon_pty_cwd_denied: the symptom itself. The daemon probes the requested
  cwd in its own process (only its TCC context counts) and returns an additive
  cwdReadableByDaemon field; the app emits only when the daemon was denied AND
  the app can read the same path, so a missing or genuinely unreadable cwd
  never counts. Non-permission errors read as readable on purpose.

Both emitters swallow every failure; nothing here can delay or fail daemon
startup or a PTY spawn. Off macOS neither event fires. The new wire field is
optional, so older daemons and clients are unaffected.

* fix(telemetry): keep cwd-denial classification inside the swallow guard

Read the pid record at emit time (inside the try) rather than passing the
adapter's startup snapshot: a throwing app-environment read can no longer
escape spawn(), and a denial after a respawn is billed to the daemon that
actually spawned the PTY.
2026-09-01 22:33:39 -04:00

90 lines
3.6 KiB
TypeScript

import { describe, expect, it } from 'vitest'
import { classifyDaemonPtyCwd, classifyDaemonSpawnerPath } from './daemon-adoption-telemetry'
import { eventSchemas } from './telemetry-event-registry'
describe('classifyDaemonSpawnerPath', () => {
const alwaysExists = () => true
it('classifies the installed app, the ShipIt staging area, and everything else', () => {
expect(
classifyDaemonSpawnerPath('/Applications/Orca.app/Contents/MacOS/Orca', alwaysExists)
).toBe('applications')
expect(
classifyDaemonSpawnerPath('/private/Applications/Orca.app/Contents/MacOS/Orca', alwaysExists)
).toBe('applications')
expect(
classifyDaemonSpawnerPath(
'/Users/a/Library/Caches/com.stablyai.orca.ShipIt/update.abc/Orca.app/Contents/MacOS/Orca',
alwaysExists
)
).toBe('updater-cache')
expect(
classifyDaemonSpawnerPath('/Users/a/Applications/Orca.app/Contents/MacOS/Orca', alwaysExists)
).toBe('other')
expect(classifyDaemonSpawnerPath('/tmp/OrcaA.app/Contents/MacOS/Orca', alwaysExists)).toBe(
'other'
)
})
it('reports a deleted spawner as missing and an unrecorded one as unknown', () => {
expect(
classifyDaemonSpawnerPath('/Applications/Orca.app/Contents/MacOS/Orca', () => false)
).toBe('missing')
expect(classifyDaemonSpawnerPath(null, alwaysExists)).toBe('unknown')
})
})
describe('classifyDaemonPtyCwd', () => {
it('maps the TCC-protected home folders and separates the rest of home from outside it', () => {
expect(classifyDaemonPtyCwd('/Users/a/Documents/repo', '/Users/a')).toBe('documents')
expect(classifyDaemonPtyCwd('/Users/a/Desktop', '/Users/a/')).toBe('desktop')
expect(classifyDaemonPtyCwd('/Users/a/Downloads/x/y', '/Users/a')).toBe('downloads')
expect(classifyDaemonPtyCwd('/Users/a/projects/repo', '/Users/a')).toBe('other-home')
expect(classifyDaemonPtyCwd('/Users/a', '/Users/a')).toBe('other-home')
expect(classifyDaemonPtyCwd('/Volumes/ext/repo', '/Users/a')).toBe('outside-home')
// A sibling home that merely shares the prefix is not inside this home.
expect(classifyDaemonPtyCwd('/Users/ab/Documents', '/Users/a')).toBe('outside-home')
})
})
// Privacy invariant: enum-only. A raw path, version, or exact count must be rejected by .strict().
describe('daemon_adopted / daemon_pty_cwd_denied schemas', () => {
const adopted = {
app_version_match: 'different',
spawner_path_class: 'updater-cache',
tcc_attribution: 'intact',
live_session_count_bucket: '2-5'
}
const denied = {
cwd_class: 'documents',
app_version_match: 'different',
spawner_path_class: 'updater-cache'
}
it('accepts the enum payloads', () => {
expect(eventSchemas.daemon_adopted.safeParse(adopted).success).toBe(true)
expect(eventSchemas.daemon_pty_cwd_denied.safeParse(denied).success).toBe(true)
})
it('rejects leaked paths, versions, counts, and unknown enum values', () => {
for (const leak of [
{ spawner_exec_path: '/Users/alice/Library/Caches/ShipIt/Orca.app' },
{ app_version: '1.4.187' },
{ live_session_count: 3 },
{ cwd: '/Users/alice/Documents' }
]) {
expect(eventSchemas.daemon_adopted.safeParse({ ...adopted, ...leak }).success).toBe(false)
expect(eventSchemas.daemon_pty_cwd_denied.safeParse({ ...denied, ...leak }).success).toBe(
false
)
}
expect(
eventSchemas.daemon_adopted.safeParse({ ...adopted, spawner_path_class: '/Applications' })
.success
).toBe(false)
expect(
eventSchemas.daemon_pty_cwd_denied.safeParse({ ...denied, cwd_class: 'Documents' }).success
).toBe(false)
})
})