feat(analytics): threads and turns now know which client started them - #7774
Conversation
Clients announce surface (web/desktop/mobile) and app version as optional query params on the /ws upgrade. The server stamps them onto PostHog events (client.connected, client.thread.started, client.turn.requested), refreshes auth_sessions on every connect, and records the origin in orchestration event metadata. All fields optional both ways: old clients and old servers keep working unchanged. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
Important Review skippedAuto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: Repository UI Review profile: CHILL Plan: Pro Plus Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
One convention issue found: the new AnalyticsService imports use a named tag import instead of the local service-module namespace import used everywhere else in this repo (server.ts, serverRuntimeStartup.ts, provider/Layers/ProviderService.ts). Everything else in the diff (dispatch origin plumbing, SessionStore.recordClientConnection, AuthSessionRepository.setClientConnection, migration 041, contracts schemas) follows the service, error, and dependency-acquisition conventions.
Posted via Macroscope — Effect Service Conventions
Thread transfer impact✅ Thread transfer remains within every enforced ceiling.
Baseline: Scenario and decoded snapshot size10 historical turns, 5 command tools per turn, 878.9 KiB retained MCP result per historical turn, and a 1.05 MiB retained result in the measured turn.
Updated in place by a trusted workflow. PR artifacts are strictly validated and never executed. |
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes using high effort and found 1 potential issue.
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit 36694fb. Configure here.
ApprovabilityVerdict: Not approved Macroscope's review found this PR not approvable — This PR introduces a new client origin tracking feature with database schema changes, new analytics events, and modifications to the core orchestration dispatch flow. Additionally, there is an unresolved medium-severity finding about analytics firing before dispatch succeeds. Human review is warranted. You can add or adjust custom eligibility rules. Learn more. |
…eads - Analytics: threads e turns passam a registrar qual cliente os iniciou, com novos campos nos contratos de orchestration e baseSchemas (pingdotgg#7774) - Servidor: SessionStore e persistence/AuthSessions ganham rastreio da conexão do cliente, com nova migration 041_AuthSessionClientConnection - WebSocket (ws.ts) e OrchestrationEngine (Layers/Services) propagam a informação de cliente ao criar threads e turns - Client-runtime: authorization (remote/service) e connection/resolver atualizados para expor os metadados do cliente - Mobile e web: platform.ts e authClientMetadata.ts ajustados para informar a plataforma de origem - Cobertura de testes ampliada em server.test.ts, SessionStore.test.ts, OrchestrationEngine.test.ts, connection.test.ts e resolver.test.ts Sync automatico t3code-sync em 2026-08-22T03:03:04-03:00
## What's Changed * feat(analytics): threads and turns now know which client started them by @t3dotgg in pingdotgg/t3code#7774 **Full Changelog**: pingdotgg/t3code@v0.0.34-nightly.20260822.1156...v0.0.34-nightly.20260822.1157 Upstream release: https://github.com/pingdotgg/t3code/releases/tag/v0.0.34-nightly.20260822.1157
Resolve client-origin analytics (pingdotgg#7774) against teleport: keep AuthSessionClientConnection as 041 and renumber teleport to 042, stamp WS dispatch origin while still gating turns on native revision, and keep both origin-stamping and teleport atomicity tests. Co-authored-by: aanishbhirud <aanishbhirud@gmail.com>
…pingdotgg#7774) Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
…pingdotgg#7774) Co-authored-by: Claude Fable 5 <noreply@anthropic.com>

We can't answer basic product questions like "how many people use mobile" or "are threads started on desktop or phone". The server never learns which client sent a request: pairing metadata lumps web and desktop together as "desktop", nothing carries an app version, and events, turns, and PostHog have no client attribution at all.
Now every client announces itself with two optional query params on the /ws upgrade, next to the existing wsTicket: clientSurface (web / desktop / mobile) and clientAppVersion. The server applies them in three places.
client.connected,client.thread.started, andclient.turn.requestedcarry surface and app version. Client rotation, multi-client users, and per-surface thread starts become plain PostHog queries.auth_sessionsgets nullableclient_surfaceandclient_app_versioncolumns, refreshed on every connect, so rows track the client's current build instead of freezing at pairing.origininto the metadata of every event a client-dispatched command produces. The decider stays pure, and per-thread attribution is queryable in local SQLite.Every new field is optional on both ends. Old clients send nothing and everything behaves as before. Old servers ignore the unknown params. No UI changes on any surface.
Tested: engine origin stamping, session store partial-update semantics, migration columns, the full server integration suite (125 tests), and typechecks across contracts, client-runtime, server, web, and mobile.
Built by Claude Fable 5 running in Claude Code.
Note
Medium Risk
Touches WebSocket auth, session persistence, orchestration event metadata, and analytics. Fields are optional and connect-path failures are best-effort, but this is core connection and event-store plumbing.
Overview
Clients now send optional
clientSurfaceandclientAppVersionon the/wsupgrade so the server can tell web, desktop, and mobile apart (and which build).On connect, the server records those values on
auth_sessions(new nullable columns, COALESCE so partial reports do not wipe earlier data) and emitsclient.connected. Successfulthread.create/thread.turn.startcommands emitclient.thread.startedandclient.turn.requestedwith the same properties.The orchestration engine stamps an optional
originonto event metadata for client-dispatched commands (including bootstrap sub-commands). The command decider stays pure. Old clients and old servers keep working: missing params are ignored.Reviewed by Cursor Bugbot for commit 487ea2c. Bugbot is set up for automated code reviews on this repo. Configure here.
Note
Track client surface and app version on websocket connections and orchestration events
ClientSurface('web'|'desktop'|'mobile') andOrchestrationClientOrigincontract types; extendsAuthClientPresentationMetadataandOrchestrationEventMetadatawith optionalsurface,appVersion, andoriginfieldssurfaceandappVersionin presentation metadata, and the client runtime appends these asclientSurface/clientAppVersionquery params on websocket URLs/wsupgrade, the server parses origin from the URL, persists it to the session viaSessionStore.recordClientConnection, passes it throughmakeWsRpcLayertoOrchestrationEngine.dispatch, and stampsoriginonto all events produced by that commandclient.connected,client.thread.started, andclient.turn.requestedanalytics events with origin props after successful dispatch041_AuthSessionClientConnectionfor nullableclient_surface/client_app_versioncolumns onauth_sessions, withCOALESCEupdates that preserve prior values when nulls are suppliedOrchestrationEngine.dispatchaccepts an optionaloptions.originargument; events now carrymetadata.originwhen the originating command had one. Invalid or missing origin params are ignored without failing the connectionMacroscope summarized 487ea2c.