pingdotgg / pingdotgg/t3code

Cloud link hardcodes notificationsEnabled: true, contradicting the privacy policy's "if you enable notifications"

Open
#9,886 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
TypeScript
Stars
23k
Forks
5.9k
Avg merge
11h 14m
Merged PRs (30d)
357

Description

Summary

The privacy policy says agent-activity data is processed "if you enable notifications or Live Activities." In the cloud-link flow, notificationsEnabled is a hardcoded true — the user never enables it. The liveActivitiesEnabled flag sitting immediately beside it does respect a user preference, which is what makes this look unintended rather than deliberate.

Steps to reproduce

apps/mobile/src/features/cloud/linkEnvironment.ts, in linkEnvironmentToCloudWithPreference — both relay calls, :272-278 and :303-311:

const liveActivitiesEnabled = input.liveActivitiesEnabled;   // ← from preferences
const challenge = yield* relayClient
  .createEnvironmentLinkChallenge({
    clerkToken: input.clerkToken,
    payload: {
      notificationsEnabled: true,                            // ← hardcoded
      liveActivitiesEnabled,
      managedTunnelsEnabled: true,
    },
  })
const link = yield* relayClient
  .linkEnvironment({
    clerkToken: input.clerkToken,
    payload: {
      deviceId,
      proof,
      notificationsEnabled: true,                            // ← hardcoded
      liveActivitiesEnabled,
      managedTunnelsEnabled: true,
    },
  })

The function's own signature takes { readonly liveActivitiesEnabled: boolean } and :353 reads preferences.liveActivitiesEnabled !== false. There is no equivalent for notifications, and no notificationsEnabled reference anywhere in apps/mobile/src/**/*.tsx — no UI writes it.

The other code path already does this correctly. apps/mobile/src/features/agent-awareness/remoteRegistration.ts:255-271 derives the flag:

if (!canRegisterRemoteLiveActivities() || !supportsAgentAwarenessPush()) {
  return { notificationsEnabled: false, pushToken: null };
}
...
if (!permissions.granted) {
  return { notificationsEnabled: false, pushToken: null };
}

So the same field is computed from real permission state in one place and asserted as true in another.

Expected behavior

notificationsEnabled reflects a user choice, the way liveActivitiesEnabled does beside it — matching the privacy policy's "if you enable."

Actual behavior

It is true for every cloud link, unconditionally.

What flows as a result

infra/relay/src/agentActivity/ publishes and persists per-thread activity. AgentActivityPublisher.ts:211-212 carries projectTitle and threadTitle; ApnsDeliveries.ts:288 builds the push as { title: row.threadTitle, body: "<status>: <projectTitle>" }; agentActivityPayloads.ts:71-72 truncates them rather than removing them. They are stored server-side in relay_agent_activity_rows.state_json (infra/relay/src/persistence/schema.ts:135-149), not just passed through.

Credit where it is due

The privacy policy is genuinely good here and names these fields precisely — apps/marketing/src/pages/privacy-policy.astro:78-83:

Agent activity and notifications. If you enable notifications or Live Activities, we process push tokens and limited activity information needed to provide those features, such as project and thread titles, model name, status, and activity headline.

That is an accurate description of exactly what agentActivityPayloads.ts sends. This issue is only that the leading conditional is not true of the link flow: the disclosure is right, the gate is missing.

Impact

Thread and project titles routinely contain the substance of the work — client names, ticket IDs, unreleased feature names. iOS still gates delivery behind its own push-permission prompt, so nothing appears on a lock screen without consent. But the flag sent at link time is what turns on server-side collection and retention of the titles, and that happens before, and independently of, any prompt the user sees.

Suggested fix

Thread a notificationsEnabled preference through linkEnvironmentToCloudWithPreference the way liveActivitiesEnabled already is, defaulting to whatever you intend — and if the intent really is on-by-default, the privacy policy's "if you enable notifications" should say so instead.

Version

d7cf8aaa (main).

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start in apps/mobile/src/features/cloud/linkEnvironment.ts at linkEnvironmentToCloudWithPreference and inspect both relay payloads around lines 272-278 and 303-311. Compare their notification flag handling with apps/mobile/src/features/agent-awareness/remoteRegistration.ts:255-271 and the existing liveActivitiesEnabled preference; done means cloud-link payloads reflect the intended notification state and remain consistent with the privacy-policy disclosure.

Written by the indexing model from the issue text.

Assessment

Tech stack
typescript
Domain
mobile-dev, security
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Active
Clarity
Mostly clear
Newbie friendliness
65/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.