docs(telemetry): state anonymous id as per-harness-home, not per-machine
The consolidated resolver scopes the anonymous id to $DSH_HOME rather than the machine. Update the module contract, README, and Agent Note to say per-harness-home explicitly instead of over-claiming a machine-global identity, and record why DSH_HOME scoping is the intended single-root meaning rather than a regression.
This commit is contained in:
@@ -7,7 +7,7 @@ Launcher-side telemetry primitives for the dsh-sdk toolchain. This is a plain li
|
||||
| `SecretRedactor` | Conservative safety backstop: replaces secret-shaped values (secret-like keys, known token shapes, PEM blocks, URL credentials, high-entropy opaque tokens) with a placeholder in both parsed values (`redactValue`) and raw text (`redactText`). Never drops a field or line. |
|
||||
| `ConsentResolver` | Parses (never boots) a project `cordis.yml` and reads the telemetry entry's enabled/disabled state as consent; `DO_NOT_TRACK`/CI env force a hard opt-out. |
|
||||
| `buildTelemetryPayload` | Assembles `{command, durationMs, success, cordisYmlContent, packageJsonContent}`, running the redactor over the full `cordis.yml` and `package.json` text. Never reads `.env`; `package.json` ships only alongside a `cordis.yml`, so a command run in a non-SDK directory never uploads that directory's unrelated manifest. |
|
||||
| `getOrCreateAnonymousId` | Random UUID persisted in the per-user harness home resolved by [`@deepseek-ai/dsh-paths`](../../util/paths/README.md) (never in the project, never derived from git). |
|
||||
| `getOrCreateAnonymousId` | Random UUID persisted in the harness home resolved by [`@deepseek-ai/dsh-paths`](../../util/paths/README.md) (`$DSH_HOME` > `~/.dsh`), scoped to that home rather than the machine, never derived from git. |
|
||||
| `TelemetryReporter` | Fire-and-forget send: `report()` never blocks or throws; delivery resolves on every path; `flush()` optionally drains in-flight sends within a cap. |
|
||||
|
||||
Consent is carried by the telemetry entry in `cordis.yml`, so disabling telemetry is disabling that entry. Telemetry reports by default and is off only when a present telemetry entry is explicitly `disabled`: a missing `cordis.yml` (first `create`), an enabled entry, or a `cordis.yml` with no telemetry entry all report. `DO_NOT_TRACK`/CI always deny. The no-config and absent-entry defaults are configurable on `ConsentResolver`.
|
||||
|
||||
@@ -1,11 +1,14 @@
|
||||
/**
|
||||
* Per-machine anonymous telemetry id.
|
||||
* Per-harness-home anonymous telemetry id.
|
||||
*
|
||||
* The id is a random UUID persisted in the per-user harness home — never in
|
||||
* the project, and never derived from the git remote, repository URL, or any
|
||||
* other identifying source (a derived id would make "anonymous" a fiction). The
|
||||
* same id is reused across projects on one machine so telemetry counts machines,
|
||||
* not repositories.
|
||||
* The id is a random UUID persisted directly in the harness home resolved by
|
||||
* {@link resolveDshHome} (`$DSH_HOME` > `~/.dsh`), and never derived from the
|
||||
* git remote, repository URL, or any other identifying source (a derived id
|
||||
* would make "anonymous" a fiction). The id is scoped to the harness home, not
|
||||
* the machine: every command sharing one `$DSH_HOME` reuses the same id, so the
|
||||
* default `~/.dsh` counts per-OS-user home directories, while a relocated
|
||||
* `$DSH_HOME` moves the id with the rest of the harness data — the single-root
|
||||
* convention this package shares, not a telemetry-specific policy.
|
||||
*
|
||||
* @module @deepseek-ai/dsh-telemetry/anonymous-id
|
||||
*/
|
||||
@@ -16,7 +19,7 @@ import { dirname, join } from 'node:path'
|
||||
import type { Branded } from '@deepseek-ai/dsh-brand'
|
||||
import { resolveDshHome } from '@deepseek-ai/dsh-paths'
|
||||
|
||||
/** A machine-scoped anonymous telemetry id (random UUID v4). */
|
||||
/** A harness-home-scoped anonymous telemetry id (random UUID v4). */
|
||||
export type AnonymousId = Branded<'AnonymousId'>
|
||||
|
||||
/** Default file, inside the harness home, storing the anonymous id. */
|
||||
@@ -68,11 +71,11 @@ async function readPersistedId(file: string): Promise<AnonymousId | undefined> {
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the machine's anonymous id, creating and persisting one on first use.
|
||||
* Return the harness home's anonymous id, creating and persisting one on first use.
|
||||
* Persistence is best-effort: a write failure still returns a usable id for the
|
||||
* current run so telemetry is never blocked by config-dir permissions.
|
||||
* @param options - config-location and UUID-generation seams.
|
||||
* @returns the stable per-machine anonymous id.
|
||||
* @returns the stable per-harness-home anonymous id.
|
||||
*/
|
||||
export async function getOrCreateAnonymousId(options: AnonymousIdOptions = {}): Promise<AnonymousId> {
|
||||
const file = join(globalConfigDir(options), ANONYMOUS_ID_FILE_NAME)
|
||||
|
||||
Reference in New Issue
Block a user