fix: workspace telemetry follow-up: kill-switch guard, `origin` on first events, review fixes

RA
4m ago
+421-49

Issue for this PR

Closes #1671
Closes #1698

Type of change

  • Bug fix
  • New feature
  • Refactor / code improvement
  • Documentation

What does this PR do?

Follow-up to #1672 and #1699, from their reviews.

  • Kill switch. With ALTIMATE_DISABLE_WORKSPACE on, routing never reads the IDE extension's pin, yet a turn's rows still validated it and waited up to 3 s. Now they skip it and name the project's link, as routing does.
  • origin on first_prompt_sent and first_job_completed: onboarding or workspace. Rows from older clients have none and are onboarding rows. Not source: the envelope stamps source on every row, and an event's own field would overwrite it.
  • Smaller fixes.
    • A subagent's turn isn't the workspace's first job.
    • A noReply prompt's attachments skip the pin's validation.
    • A directory attachment names the turn's workspace.
    • The mark is keyed by the tenant the turn resolved under.
    • A turn that ends before its loop clears its verdict.
    • An unwritable state directory logs once.

Claims, residuals and the complexity delta are in the review log comment.

How did you verify your code works?

Each fix has a test that fails without it, except the early-end clears and the once-only warning (R6 on the log). The tests are in routing-pin.test.ts, first-events.test.ts and onboarding.test.ts. The prompt-loop ones are in pinned-workspace-loop.test.ts and workspace-first-events-loop.test.ts, which now run with the workspace feature on. test/session, test/altimate/workspace and test/altimate/telemetry pass locally. The exceptions are two timing tests in prompt.test.ts (the exit flush, and concurrent loop callers at its 3 s limit), which fail the same way with main's source. Typecheck, Marker Guard, branding and the tracker-leak check pass.

Cost side effects

None. With the kill switch on, a turn sends one request fewer.

Screenshots / recordings

Not a UI change.

Checklist

  • I have tested my changes locally
  • I have not included unrelated changes in this PR
  • I checked for cost side effects (model calls, queries or cloud resources that grow with user data) and described them, or wrote "none"

🤖 Generated with Claude Code

https://claude.ai/code/session_01VEmKQswEEpkYFmMEngESx8


Summary by cubic

Follows up on the workspace telemetry PRs with fixes from their reviews. With ALTIMATE_DISABLE_WORKSPACE set, a turn's rows no longer validate the IDE extension's pin or wait up to 3 s on it; they name the project's link, as routing does. first_prompt_sent and first_job_completed now carry origin (onboarding or workspace), and rows from older clients — which have none — are treated as onboarding rows. The pin's verdict now carries the credential it was validated under, so a switch during validation can't key a first-event claim under another tenant.

Closes #1671 and #1698.

Smaller Fixes

  • A subagent's turn is not the workspace's first job; the parent's task call counts it.
  • noReply prompts' attachments skip the pin's validation and wait.
  • Directory attachments name the turn's workspace.
  • The claim mark is keyed by the tenant the turn resolved under.
  • A turn that ends before its loop clears its verdict.
  • An unwritable state directory logs once per process.

Summary by CodeRabbit

  • Bug Fixes
    • Improved workspace attribution for first-prompt and first-job activity, including projects linked to different accounts and cases where workspace pins are unavailable.
    • File and directory attachments now follow the applicable workspace binding, with consistent behavior when workspace features are disabled or pin validation is delayed.
    • Subagent activity no longer counts as a workspace’s first completed job.
  • Documentation
    • Clarified how onboarding and workspace events are distinguished, which prompts and jobs count, and how workspace scope and legacy events are handled.