The user-global instruction scope now reads two roots: $DSH_HOME/AGENTS.md first, then the shared agents root that other agent tools use ($DSH_AGENTS_HOME, else ~/.agents). Both resolve from the process environment through @deepseek-ai/dsh-home-paths; no config field is added, because the stack base (PR #5718) removed the per-row home override. The two files are candidates of one candidate group: identical trimmed content renders once from the harness home, an unobservable candidate preserves the group's last-good state, and reconciliation probes both roots so external edits, removals, and new files become visible change notices. A candidate dropped as a duplicate keeps being reconciled, so deleting or changing the retained candidate promotes it. The harness-home file keeps its recorded `user-global` scope key; the shared file carries `agents-global`. A user-global delta states `These user-global instructions apply to all work.` instead of naming its reconciliation scope, and a project path whose first component would collide with a user-global scope directory renders with a leading `.` so it keeps its own scope.
4.0 KiB
Agent Note: 单一 harness home 解析器
Status: implemented
English | 中文
问题
对于"DeepSeek Harness 用户数据存放在哪里",harness 里存在两套互不一致的约定:
@deepseek-ai/dsh-home按configured ?? $DSH_HOME ?? ~/.dsh解析。@deepseek-ai/dsh-home-paths又提供了第二个resolveDshHome,优先级相同但额外做了波浪号展开——它几乎是dsh-home的重复实现,却没有任何门禁发现,因为两者分属不同的包,而且早已漂移(只有一个会展开波浪号)。
同一条横切事实有两个解析器,意味着不存在单一的 home 策略。
决策
由一个解析器统一掌管 harness home,落在 @deepseek-ai/dsh-home-paths,采用单一根目录:
explicit configured path > $DSH_HOME > ~/.dsh
空或仅含空白的 $DSH_HOME 被当作未设置处理;否则,resolve('') 会悄悄把 home 落在当前工作目录。harness 把所有用户数据都放在同一个根目录下;不存在 XDG 的 config/data/cache 拆分。dshHomePath(...segments) 将部署负责的子路径拼接到该根目录下,dsh-app-boot 在挂载条目前向 Loader !!js 配置表达式暴露它,因此出厂组合无需复制解析器即可派生 sessions 和 storages。dshHomeDisplay() 为面向用户的路径以符号形式命名已解析的根目录——默认 home 显示为 ~/.dsh,任何已配置的 home 显示为 $DSH_HOME——这样用户全局的 AGENTS.md 标签就绝不会泄露机器上的绝对路径。它取代了 agent-instructions 中自定义的「默认值 vs $DSH_HOME」判断。home 属于进程策略而非配置行:dsh-agent-instructions 不接受 home 覆盖,因此组合无法把指令加载指向会话、skill 与存储不会读取的根目录。resolveAgentsHome() 与 agentsHomeDisplay() 对共享 agent 配置根目录($DSH_AGENTS_HOME 或 ~/.agents)采用相同的优先级、波浪号展开与符号化标签;该根目录位于 harness home 之外,因为其他 agent 工具会共享它(共享 agents 根目录);dsh-skill-filesystem 仍接受自己的 dshHome 与 agentsHome 字段,用于选择它自己的 skill 根目录,并在指令加载改动中改用共享解析器。
dshCachePath(...segments) 在解析出的主目录下的 cache 目录中派生路径。首个 { dshHome } 选项保留提供方显式配置的主目录覆盖值。它只解析路径,不创建目录;目录创建由调用方负责。attachment-local 将此函数用于可重新生成的请求图片版本,持久附件对象仍保留在其带版本的存储树中,因此清空缓存不会删除 Session 附件。已有请求图片缓存条目保留在原处,不再读取或复制;缓存未命中时从持久附件重新生成请求版本。
@deepseek-ai/dsh-home 被删除。拥有 home 配置的提供方与 boot 包从 dsh-home-paths 导入 resolveDshHome;组合包只包含解析后的配置行。
dsh-telemetry 及其独立 home 策略已随 SDK 项目工具链移除一并消失,因此该解析器是唯一的 home 策略。
备选方案
保留两份 resolveDshHome 副本。 它们早已漂移(一个展开波浪号,一个不展开),并把同一条横切事实编码了两遍。util/ 层的意义正是在于合并,重复的解析器是一个潜在的分歧 bug。
采用 XDG(遵从 $XDG_CONFIG_HOME,或把 config/data/cache 拆分到各自的目录树)。 经过考虑后放弃,转而采用一个显而易见的根目录。单一的 $DSH_HOME || ~/.dsh 基准事实与 ~/.claude / ~/.aws 一致,无需对每个 ~/.dsh 消费方按类别重新归类,也不留下任何需要协调的解析器不对称。
影响
- 单一 home 事实,单一解析器。
dsh-home-paths是唯一归属方;util/组失去了home包。