feat: telemetry carries the backend user id and tenant when signed in

RA
1d ago
+717-30

Closes #1498

What

Telemetry events carry the backend user uuid and tenant when the machine is signed in to Altimate, and the CLI names itself on backend calls.

  • New telemetry/identity.ts: resolves the signed-in user once per credential (GET /users/me, the call the workspace client already makes) and caches { user_id, tenant } at ~/.altimate/telemetry-identity.json under a fingerprint of the credential, owner-only. A changed credential, a sign-out or a forced refresh invalidates it. Every failure resolves to nothing; telemetry never waits on the backend.
  • telemetry/index.ts: stamps user_id and tenant on every event's properties and uses the uuid as ai.user.id, with the machine id as the fallback for anonymous use. The hashed account email is gone: no email, hashed or not, leaves the client. refreshIdentity() re-resolves after a sign-in in the same process; shutdown() clears it.
  • plugin/altimate.ts: the browser sign-in calls refreshIdentity() after it saves the credential.
  • api/client.ts and workspace/api-client.ts: every backend call sends x-altimate-client: altimate-code/<version>.

Why

Web events are keyed by the backend user uuid; CLI events were keyed by the machine only, so nothing joined a CLI session to the account that created or linked the workspace it uses. One key on both sides lets the dashboards follow a user from the web into the CLI. The client header lets the backend tell which client made a create or link call.

Verification

  • bun test test/altimate/telemetry/identity.test.ts: 3 tests, 46 assertions. Resolution, caching and cache invalidation against a stubbed /users/me; the request headers; the cache file's mode; envelopes posted to a stubbed ingest endpoint carry user_id, tenant and ai.user.id = uuid when signed in, and only the machine id after sign-out; no email in any property.
  • Existing telemetry suites (first-run health, onboarding, safety, install telemetry, trace context): 76 pass.
  • tsgo --noEmit clean; oxlint and prettier clean on the changed files.

Anonymous sessions are unchanged apart from the removed email hash, which in practice was never set.

Review log (claims and residuals Codex reviews against): https://github.com/AltimateAI/altimate-code/pull/1500#issuecomment-6186948236

🤖 Generated with Claude Code

https://claude.ai/code/session_011AhtJPr3nmT1Po92ZQk4VE


Summary by cubic

Telemetry events now carry the backend user UUID and tenant when the machine is signed in to Altimate, so CLI events join web events on the same account key. The hashed account email is no longer sent.

Behavior

  • Identity is resolved once per credential via GET /users/me and cached in ~/.altimate/telemetry-identity.json (owner-only, keyed by a credential fingerprint); a changed credential, sign-out, or forced refresh invalidates it.
  • Credentials are read like the provider: the ~/.altimate/altimate.json file first, else the altimate-backend auth-store key, normalised to drop a trailing slash. Credential changes on disk are noticed at the next flush; a buffered batch keeps the identity it was tracked under, a 401 or 403 drops the cache, and a failed lookup is retried after a 60 s backoff instead of on every flush.
  • In-flight resolutions are generation-guarded, so a stale response — for a previous credential or one removed mid-flight — can never overwrite a newer sign-in or a shutdown.
  • Backend calls from the CLI now send x-altimate-client: altimate-code/<version> so the server can attribute create and link calls.
  • Anonymous sessions are unchanged apart from the removed email hash, which in practice was never set.
  • Source-guard tests now assert Account.active() is no longer called, since identity comes from the stored credential.

Summary by CodeRabbit

  • New Features

    • Telemetry events can now include the signed-in Altimate account and tenant when available, with the machine identity used when no account identity is available.
    • Altimate API requests now identify the CLI and its installation version.
    • Telemetry refreshes its account identity after gateway credentials are saved.
  • Bug Fixes

    • Identity lookup and refresh failures no longer interrupt credential setup or telemetry operation.