@xfcodeai/dsh-anonymous-user-id
v0.1.5-rc.5
Published
Shared anonymous user identity for DeepSeek Harness telemetry and feedback correlation
Readme
description: "面向用户与维护者的按 harness home 划分的匿名身份说明,用于追踪遥测、反馈确认与 DeepSeek 提供方请求如何关联记录。" kind: "package-library"
@xfcodeai/dsh-anonymous-user-id
English | 中文
概述
DeepSeek Harness 为每个 harness home 使用一个匿名标识符,以关联同一套安装产生的遥测、反馈与 DeepSeek 请求,同时不识别用户身份。该随机 UUID 存储在 $DSH_HOME/.anonymous-user-id($DSH_HOME 默认为 ~/.dsh)中,可跨重启保留,并在你删除文件后重新生成。不同 harness home 使用不同的标识符,且该值不包含机器或账户数据。内置功能会自动创建并附加该值;包消费方可以复用同一个值进行安装范围的关联,但无法跨 home 关联记录。
目录
使用本包
当你希望本机安装外发的记录能被识别为来自同一个 harness home——遥测、反馈与 DeepSeek 请求都携带同一个共享 id——本包就是提供它的地方。无需安装或配置任何东西:id 会自动出现,已随附的反馈、遥测与 DeepSeek 功能已经在使用它。不要用它来识别用户,也不要用它关联不同 home 之间的记录;它是匿名的且限定于单个 home。
该 id 能为你做什么
你的安装外发的三类内容携带同一个 id,因此记录在它们之间可以相互对应:
- 会话遥测——你的遥测导出会以
user.idResource 属性携带该 id,采集器因此可以按安装分组记录。 - 反馈——每条反馈确认都会标明记录该反馈的匿名安装。
- DeepSeek 请求——每次提供方请求都会携带
x-deepseek-harness-user-id标头,因此可以按安装归因用量。
查看与重置 id
该 id 存放在 $DSH_HOME/.anonymous-user-id($DSH_HOME 默认为 ~/.dsh)中,是一个纯 UUID 文本文件。删除该文件即可在下次启动时获得全新 id;正在运行的进程在退出前会一直保留当前 id。不同 harness home 各自保留独立 id,值中永远不会包含任何机器或账户信息。
在自己的包中使用
当你构建的功能需要共享该安装的匿名 id 时,导入一次并复用该值即可——遥测、反馈与 DeepSeek 已经在使用同一个 id,因此你的记录能与它们相互对应:
import { getOrCreateAnonymousUserId } from '@xfcodeai/dsh-anonymous-user-id'
const userId = getOrCreateAnonymousUserId() // stable for the process lifetime该值在进程内保持稳定,并与内置功能使用的值一致;只有当文件被删除、后续启动生成替代值时才会改变。即使 home 目录不可写,该值在本次运行中依然可用,记录因此不会中断。
理解实现
本节解释本包背后的设计决策,并指出实现它们的代码位置;可观察行为已在使用本包中完整说明。
设计理念
- 随机生成,绝不派生。 id 来自
crypto.randomUUID();绝不从 hostname、网络地址、git remote 或任何其他可识别来源派生,因此匿名性是生成过程的属性。 - 同步且记忆化。 一个进程对每个解析后的文件路径只触碰一次磁盘:读写都是同步的,结果按解析后的文件路径记忆化。
- Best-effort 持久化。 写入失败仍会为本次运行返回可用 id,遥测与反馈因此不会因 home 不可写而阻塞。
- 库而非插件。 没有 Cordis 插件入口或配置。不发布不变式伴生入口,因为本包不拥有任何事件流或公开可变关系,无法在不产生创建 id 这一副作用的情况下比较。
源码地图
| 文件 | 职责 |
|---|---|
| src/index.ts | 库入口:getOrCreateAnonymousUserId、文件持久化、按路径记忆化 |
| — | 不发布运行时不变式伴生入口;该 API 仅拥有一个私有记忆化值和一个 best-effort 文件,不存在独立事件流或公开可变关系可供伴生入口在不产生创建身份这一副作用的情况下比较。 |
| tests/anonymous-user-id.spec.ts | 测试覆盖的行为:生成、持久化、损坏、并发、记忆化 |
API
本包暴露一个函数,返回该安装的匿名 id,并在首次使用时生成并持久化;确切的签名、选项与默认值见 src/index.ts。
存储约定
文件是名为 ANONYMOUS_USER_ID_FILE_NAME 的裸 UUID 行,读取时按 UUID 模式校验。首个写入方使用独占创建(wx);并发落败方重新读取并采用胜出方的值。遇到损坏或不可读的文件时,系统会转而生成新值并覆盖该文件。记忆化按解析后的文件路径为键,因此不同 home 永远不会共享 id。
进一步探索
当包级约定不够用时阅读以下页面。它们从 identity 组映射逐步进入本包所依赖的 home 路径解析,以及使用该 id 的功能。
- identity 组映射——兄弟包与组范围。
- dsh-home-paths——负责
$DSH_HOME与~/.dsh的解析。 - dsh-session-telemetry-otel——将该 id 作为 OTel Resource
user.id上报。 - dsh-command-feedback——将 id 嵌入反馈确认。
- dsh-llm-deepseek——在提供方请求中发送
x-deepseek-harness-user-id。 - 会话遥测子系统——遥测 seam 及其后端约定。
模型体验
无,因为该共享标识符只会作为模型不可见的 HTTP 元数据发送给 DeepSeek,且不注册任何面向模型的内容。
KV Cache 影响
无;该传输标头既不会改变 token,也不会改变模型可见前缀。
已知限制与延期工作
这些限制说明该 id 何时不合适或需要特别注意。它们是当前包约束,不是匿名性方案的通用对比,也不是任务积压。
- 删除后无法恢复——文件丢失后会按设计生成新的匿名身份;恢复需要稳定的派生材料,这会削弱匿名性。
- Best-effort 并发——如果读取方恰好落在并发进程完成独占创建但尚未写完的狭窄时间窗内,本次运行可能使用不同的内存 UUID;后续启动会收敛到已持久化的值。
- 没有跨 home 身份——不同
$DSH_HOME值之间无法关联。 - 已配置的 DeepSeek 网关会收到该 id——
dsh-llm-deepseek会把稳定标头发送至解析后的baseURL(包括部署覆盖),且不受遥测共享模式影响。 - 删除文件不会重置当前进程——记忆化会让本次运行的 id 一直保留到下次启动。
开发备注
本开发备注是维护者的工作上下文:开放问题与尚未决定的探索方向。它明确不具权威性——已交付的行为、限制与既定理由以上文和包代码为准,结论一旦稳定就迁移到对应归属。
开放:文件格式演进
持久化约定是没有任何版本标记的裸 UUID 行。在 id 旁边增加第二个值,或用容器包裹该行,对现有文件都没有迁移方案;带版本的行格式是让此类变更安全的一种方式。
开放:不变式观测点
不发布不变式伴生入口,因为任何关系都无法在不产生创建 id 这一副作用的情况下检查。未来若有安全的观测点,可以把重新读取的持久化文件与记忆化的 id 进行比较。
