Clarify inert plugin telemetry helpers

This commit is contained in:
2026-04-04 03:21:59 +08:00
parent 3e5461df9b
commit eb96764770

View File

@@ -1,14 +1,10 @@
/**
* Plugin telemetry helpers shared field builders for plugin lifecycle events.
* Legacy plugin metadata helpers shared by call sites that still assemble
* analytics-compatible payload shapes.
*
* Implements the twin-column privacy pattern: every user-defined-name field
* emits both a raw value (routed to PII-tagged _PROTO_* BQ columns) and a
* redacted twin (real name iff marketplace ∈ allowlist, else 'third-party').
*
* plugin_id_hash provides an opaque per-plugin aggregation key with no privacy
* dependency — sha256(name@marketplace + FIXED_SALT) truncated to 16 chars.
* This answers distinct-count and per-plugin-trend questions that the
* redacted column can't, without exposing user-defined names.
* In this fork the downstream analytics sinks are disabled, so these helpers
* only normalize/redact fields for local compatibility code; they do not
* imply an active telemetry export path.
*/
import { createHash } from 'crypto'
@@ -25,18 +21,14 @@ import {
// through commands.js. Marketplace schemas.ts enforces 'builtin' is reserved.
const BUILTIN_MARKETPLACE_NAME = 'builtin'
// Fixed salt for plugin_id_hash. Same constant across all repos and emission
// sites. Not per-org, not rotated — per-org salt would defeat cross-org
// distinct-count, rotation would break trend lines. Customers can compute the
// same hash on their known plugin names to reverse-match their own telemetry.
// Fixed salt for plugin_id_hash. Kept stable so legacy field shapes that still
// use this helper continue to derive the same opaque key.
const PLUGIN_ID_HASH_SALT = 'claude-plugin-telemetry-v1'
/**
* Opaque per-plugin aggregation key. Input is the name@marketplace string as
* it appears in enabledPlugins keys, lowercased on the marketplace suffix for
* reproducibility. 16-char truncation keeps BQ GROUP BY cardinality manageable
* while making collisions negligible at projected 10k-plugin scale. Name case
* is preserved in both branches (enabledPlugins keys are case-sensitive).
* Opaque per-plugin compatibility key derived from the name@marketplace
* string. The 16-char truncation keeps the identifier short while preserving
* a stable grouping key for local compatibility code.
*/
export function hashPluginId(name: string, marketplace?: string): string {
const key = marketplace ? `${name}@${marketplace.toLowerCase()}` : name
@@ -90,9 +82,9 @@ export type InstallSource =
| 'deep-link'
/**
* Common plugin telemetry fields keyed off name@marketplace. Returns the
* hash, scope enum, and the redacted-twin columns. Callers add the raw
* _PROTO_* fields separately (those require the PII-tagged marker type).
* Common plugin metadata fields keyed off name@marketplace. Keeps the legacy
* field set in one place so no-op analytics compatibility callers do not have
* to duplicate redaction logic.
*/
export function buildPluginTelemetryFields(
name: string,
@@ -144,9 +136,7 @@ export function buildPluginCommandTelemetryFields(
}
/**
* Bounded-cardinality error bucket for CLI plugin operation failures.
* Maps free-form error messages to 5 stable categories so dashboard
* GROUP BY stays tractable.
* Stable error buckets for CLI plugin operation failures.
*/
export type PluginCommandErrorCategory =
| 'network'