* feat(amr): forward Open Design device id to AMR for cross-product account linking To link an Open Design install to the AMR account a user registers after the handoff (so paid AMR users can be traced back to Open Design), pass the Open Design device id (installation/anonymous id) on the AMR handoff URL as `od_device_id`. This gives AMR a stable, direct join key rather than relying only on the one-shot entry id. - `attributedAmrUrl` takes an optional `deviceId`; emits `od_device_id` only when provided. - The ChatPane recharge handoff passes the device id ONLY when the user has opted into metrics (`telemetry.metrics === true`); otherwise it is omitted. AMR is Open Design's own official model service, so this is a same-owner cross-product link, but it still respects the telemetry opt-in. The handoff already opens with `noreferrer`, so the URL is not leaked via Referer. - PRIVACY.md: add an "Open Design AMR" section disclosing that AMR is Open Design's official first-party model service and that information may be shared between the two same-owner products to provide and improve the experience. Surface area: UI (handoff behavior) + docs (PRIVACY.md). No new capability or CLI surface; analytics-forwarding + disclosure only. * fix(amr): forward the canonical telemetry device id, not the bootstrap UUID Review (nettee, elihahah666 — CHANGES_REQUESTED): the handoff sourced od_device_id from analytics.anonymousId, which is the mount-time getAnonymousId() bootstrap UUID — not the id telemetry keys on. Once /api/analytics/config resolves, applyIdentity(installationId) re-registers device_id=installationId for PostHog/Langfuse, and the two diverge before hydration and after a Delete-my-data installationId rotation. AMR would then store a join key that never matches the telemetry device id, weakening the cross-product link this change exists to strengthen. Extract amrHandoffDeviceId() which returns the canonical resolved device id (getResolvedDeviceId(), = installationId once hydrated) when metrics consent is on, falling back to config.installationId, never the bootstrap UUID; null otherwise. Use it from the ChatPane recharge handoff and unit-test the gating: consent off → null; consent on → resolved id; resolved not hydrated → falls back to installationId; neither → null. * fix(amr): prefer the freshly rotated installationId in the handoff device id Review (nettee — non_blocking follow-up): amrHandoffDeviceId() preferred resolvedDeviceId over installationId, but resolvedDeviceId is a module global in the analytics client that only updates later, when the App-level setIdentity effect runs applyIdentity(). config.installationId, by contrast, is the fresh source-of-truth in the current render. During a Delete-my-data rotation the new installationId is live while resolvedDeviceId still holds the deleted id until that effect runs, so the handoff could forward the stale pre-rotation id and break the exact cross-product join this helper exists to preserve. Flip the precedence to installationId ?? resolvedDeviceId ?? null. In steady state the two agree (the client seeds resolvedDeviceId from cfg.installationId), so PostHog/Langfuse parity is unchanged; neither input is the mount-time bootstrap UUID, so this does not regress the earlier fix. Extend the helper test matrix with a rotation case where the two ids differ and assert the fresh installationId wins. --------- Co-authored-by: Mason <jinmeihong0201@gmail.com>
3.5 KiB
Privacy
This page describes what data the Open Design desktop and web app collects, when it collects it, and how you stay in control. It documents the behavior shipped in the app — the same controls live under Settings → Privacy.
Open Design is local-first. Your projects, generated files, and BYOK API keys stay on your machine. The app works fully offline; nothing in this page applies unless you explicitly turn telemetry on.
Telemetry is opt-in
Usage telemetry is off by default. On first run the app shows a privacy consent banner asking you to make a choice — it never starts sending anything before you do. You can change your decision at any time under Settings → Privacy, where each category below has its own toggle.
What is collected when you opt in
When telemetry is enabled, the app may send the following to the Open Design team. Each category is independently controllable in Settings.
- Anonymous metrics — run counts, token usage, error rate, and duration. No prompts and no project data.
- Conversation and tool content — your prompts, assistant responses, tool inputs, and tool outputs (truncated before send). API keys, tokens, JWTs, emails, IP addresses, and credit-card numbers are stripped automatically before anything leaves your machine.
- Project artifacts manifest — filenames, types, and sizes of generated files. The contents of those files are never sent.
What is never collected
- The contents of your generated artifact files.
- Your BYOK API keys, tokens, or other secrets — these are redacted before send and are never part of telemetry.
- Anything at all while telemetry is turned off.
How telemetry is sent
Redacted telemetry batches are sent to a Cloudflare Worker relay operated by the Open Design team, which forwards them to Langfuse for analysis. The relay holds the Langfuse write credentials server-side, so packaged clients only ever ship a public relay URL — no secret keys. If the relay is unavailable the app retries quietly and keeps working; telemetry never blocks your workflow.
Your anonymous ID
When telemetry is enabled the app generates a random, opaque installation ID so related events can be grouped. It is not tied to your name, email, or account, and it carries no personal information.
Deleting your data
Settings → Privacy → Delete my data rotates your anonymous ID and stops sending. Telemetry already received ages out under the team's retention policy.
Bring your own key
Open Design is BYOK at every layer. The API keys you configure for coding agents and model providers are stored locally and used only to talk to those providers directly. They are never sent to the Open Design team.
Open Design AMR
“Open Design AMR” is Open Design’s official, first-party model service. Because the two are part of the same product family operated by the same team, we may share information between them as needed to provide, connect, and improve the combined experience — for example, to recognize that you arrived from Open Design, to help you get set up, and to keep the products working well together. This sharing is between our own products, not with unrelated third parties, and any data involved still follows the controls described on this page.
Changes to this page
This document tracks the data handling of the shipped app. When the telemetry behavior changes, this page is updated alongside it. For questions, open a GitHub Discussion.