DSH / Atlas
2026-09-08proposedfeature

Desktop mandatory-update API

Desktop 强制更新接口

Desktop requires mandatory-update decisions when its business server is local and when the user is not signed in. Mobile ordinary-update responses do not define Desktop artifact installation. Backend and Desktop owners need a self-contained protocol with explicit success, blocking, and error semantics, separate from updater artifact selection.

English

Problem

Desktop requires mandatory-update decisions when its business server is local and when the user is not signed in. Mobile ordinary-update responses do not define Desktop artifact installation. Backend and Desktop owners need a self-contained protocol with explicit success, blocking, and error semantics, separate from updater artifact selection.

Proposal

Use a guest-accessible policy endpoint. This document owns its Desktop request and response fields; the initial update proposal owns client scheduling, UI, release ordering, and installation. Backend integration is in progress; API origins and gateway details are deployment inputs, not evidence of a live service. No sibling repository or local document is needed to interpret this protocol.

Endpoint and access

The client reference owns the implemented polling and blocking UI. This API proposal remains active for backend deployment and live integration; local fixtures do not certify the service.

GET /api/v0/check_client_update

The query itself must return the complete mandatory response; do not rely on intercepting unrelated business APIs. Preserve Android and iOS behavior without requiring existing mobile versions to send new Desktop fields. Desktop receives mandatory policy only, not ordinary-update prompts, installer metadata, updater target versions, device IDs, installation IDs, or per-installation rollout assignments.

Request

GET /api/v0/check_client_update?scenario=launch
x-client-platform: desktop-win
x-client-version: 0.1.3-rc.2
x-client-bundle-id:
x-client-locale: zh_CN
x-client-timezone-offset: 28800
x-client-arch: x64
x-client-update-channel: nightly
x-client-bundled-dsh-version: 0.1.3-rc.2

All listed headers are required on every Desktop request; a required header may still carry an empty value, as x-client-bundle-id does. The values describing installed software come from the application and its release metadata, not editable UI fields.

HeaderMeaning and allowed values
x-client-platformdesktop-win or desktop-mac
x-client-versionShared client build version, inlined as DSH_CLIENT_VERSION at packaging; full SemVer retaining prerelease identifiers, initially equal to the bundled dsh version
x-client-bundle-idPlatform uses this field to identify the Chat application; the field does not apply to Harness, so Desktop sends it empty
x-client-localezh_CN or en_US, taken from the active UI language's primary subtag; selects localized content, not region
x-client-timezone-offsetWhole-second offset from UTC, positive east of Greenwich, sampled from the shell for every request
x-client-archWindows x64; macOS x64 or arm64
x-client-update-channelInitially always nightly, independent of version suffix
x-client-bundled-dsh-versionFull bundled dsh version from release metadata
QueryClient behaviorInitial backend behavior
scenarioCarry the query source; launch is a startup exampleIgnore; final desktop enumeration does not block integration
regionOptional; send only when trustworthy region information existsIgnore; do not infer it from UI locale

Neither query affects initial policy matching or parameter validation. Changing or omitting either query must not change the decision for otherwise identical client conditions. Lifecycle triggers and query enum values need not have a one-to-one mapping; enumeration and analytics can be agreed before backend use is enabled.

No mandatory update

{
  "code": 0,
  "msg": "",
  "data": {
    "biz_code": 0,
    "biz_msg": "",
    "biz_data": null
  }
}

This means the current client does not require a mandatory update, not that its installed version is latest. A fresh valid response for the current client conditions may clear a known block. Desktop does not consume mobile ordinary-update payloads in this response.

Mandatory update

{
  "code": 40005,
  "msg": "Client version too low",
  "data": {
    "show_content": {
      "title": "请更新 DeepSeek Harness",
      "detail": "当前版本已停止支持,请下载并安装新版本。"
    },
    "desktop_app_link": "https://example.com/harness/download"
  }
}

The example URL is a placeholder, not an approved deployment destination. Desktop uses the flattened data fields, with no alt_app or biz_data wrapper. No Desktop has shipped, so no compatibility parser for the earlier nested proposal is required. Mobile alt_app, Android links, and iOS app identifiers retain their existing format.

FieldRequirement
code40005 is the response-body code, not an HTTP status
msgDiagnostics only, not dialog copy
data.show_content.titleRequired localized plain-text title
data.show_content.detailRequired localized plain-text detail
data.desktop_app_linkRequired HTTPS page matching product, platform, architecture, and channel; must satisfy the client allowlist

Do not add mode, force_update, show_key, target_version, button copy, or updater metadata initially. 40005 determines that upgrading is mandatory; updater metadata determines the actual version and package. The client does not perform an additional mandatory-target version check from this API. Client state selects localized actions, and every download still requires user action. The page remains a fallback after in-app updater integration. The HTTP status mapping follows gateway integration and must be confirmed; the gateway must preserve the JSON body instead of replacing it with generic text or HTML.

Errors and policy matching

Missing required headers, invalid SemVer, and unsupported platform/architecture/channel combinations return explicit parameter errors, not no-force success or a mandatory policy. Prefer the existing business meanings of biz_code = 1 for a missing version and biz_code = 2 for an invalid version; final error allocation belongs to the backend. Service failures must not masquerade as success because success may remove an existing block.

Match platform, architecture, Desktop version, bundled dsh version, and channel using server-owned ranges and precedence. Use complete SemVer, not lexical sorting or truncated prerelease values. Initially the two versions are equal and channel is fixed Nightly; independent revisions and channel switching are deferred. Do not require a downgrade or stop returning 40005 merely because a client has queried or displayed it before.

Policy publication and current decisions

Every active policy requires deterministic matching conditions, localized title/detail, and a valid destination. The server evaluates current client conditions on every query. These are server configuration requirements, not extra response fields or an artifact revocation mechanism.

  • Publish and verify a higher release that resolves the mandatory requirement before enabling its policy; the matching page and platform package must be available.
  • For clients with in-app mandatory updating, publish the resolving version to their updater feed before activating the mandatory requirement. Release owners coordinate this ordering; the API does not supply a separate installer target, artifact eligibility response, or ordinary-update rollout.
  • Match links to the product, platform, architecture, and channel; reject policy activation when content or an allowed HTTPS destination is missing.
  • Return no-force success when the current client no longer matches, including after upgrading. Continue returning mandatory policy while it still matches.

Handle a defective release by publishing a higher fixed version and updating updater metadata. Do not add a revoked-version list, pre-install artifact-revocation query, or target-version validation to this API. A fresh no-force response can clear the UI block but does not select, replace, or invalidate an updater package. Artifact hash/signature checks remain required independently of the mandatory decision.

Capacity and caching

Capacity and rate limits must account for recurring guest requests, client-side coalescing, and failure backoff. Policy delivery does not depend on chat requests or SSE. Online delivery latency depends on polling and connectivity; offline clients cannot receive new policy immediately. Prefer Cache-Control: no-store. A gateway must not share responses across client versions, platforms, architectures, or channels based only on URL; future caching must specify all policy/content keys and decision freshness.

Alternatives considered

Relying on remote business interception. Local dsh requests need not reach the remote gateway; an independent guest query is necessary.

Reusing the mobile nested payload for Desktop. The backend agreement flattens Desktop fields. Preserve mobile compatibility by platform, without making new Desktop clients support an undistributed nested variant.

Adding installation identity and ordinary-update metadata. Initial policy needs neither per-installation rollout nor a second installer feed. Keep artifact discovery in the updater.

Acceptance criteria

CaseExpected result
Unauthenticated DesktopQuery works without business login
Windows x64, macOS x64 and arm64Correct platform policy and page
No policy matchcode = 0, biz_code = 0, biz_data = null
Policy matchTop-level 40005, direct content and page under data
Changed or omitted query parametersSame decision for otherwise identical conditions
Equal prerelease Desktop/dsh versions, fixed NightlyFull SemVer matching, no downgrade or channel-switch requirement
Client no longer matches, including after upgradingNo-force success; does not invalidate updater artifacts
Unavailable resolving release, page, or applicable feedPolicy activation rejected
Invalid required fields or service failureExplicit error, not false no-force success
Sequential requests from different client conditionsNo cross-client cache leakage
Existing mobile requestsExisting requirements and response structure preserved

Risks

Backend owners must provide test/production origins, guest gateway access, final HTTP/error-code mapping, limits, real page destinations, allowed domains, fallback locale, and policy configuration ownership. Release owners must coordinate available updater releases and mandatory-policy activation per platform. These inputs remain pending and must not be filled with developer credentials or guessed URLs.

中文

问题

Desktop 在业务 server 为本地进程、用户尚未登录时也需要获取强制更新判定。移动端普通更新响应不定义 Desktop 产物安装。后端与 Desktop 需要一份自包含协议,明确成功、阻断和错误语义,与 updater 的产物选择分开。

提案

使用未登录可访问的策略接口。本文负责 Desktop 请求响应字段,一期更新提案负责客户端调度、界面、发布顺序与安装。后端正在接入;API 地址与网关细节是部署输入,不表示服务已经可用。理解本协议不依赖旁边的仓库或本机文档。

接口与访问

客户端参考负责已实现的轮询和阻塞界面。本接口提案仍负责后端部署与真实联调;本地 fixture(测试前置数据)不能认证服务。

GET /api/v0/check_client_update

查询接口本身必须返回完整强制响应,不能依赖拦截其他业务接口。保持 Android 与 iOS 既有行为,不要求旧移动端补传 Desktop 新字段。Desktop 仅接收强制策略,不接收普通更新提示、安装包元数据、updater 目标版本、设备 ID、安装实例 ID 或按实例灰度分配。

请求

GET /api/v0/check_client_update?scenario=launch
x-client-platform: desktop-win
x-client-version: 0.1.3-rc.2
x-client-bundle-id:
x-client-locale: zh_CN
x-client-timezone-offset: 28800
x-client-arch: x64
x-client-update-channel: nightly
x-client-bundled-dsh-version: 0.1.3-rc.2

以上 header 在每次 Desktop 请求中均为必填;必填 header 的取值可以为空,x-client-bundle-id 即如此。描述已安装软件的值来自应用与发布元数据,不来自可编辑 UI 字段。

Header含义与取值
x-client-platformdesktop-win 或 desktop-mac
x-client-version共享的客户端构建版本,在打包时内联为 DSH_CLIENT_VERSION;完整 SemVer,保留预发布标识,一期等于内置 dsh 版本
x-client-bundle-idPlatform 用该字段标识 Chat 应用;该字段对 Harness 不适用,因此 Desktop 发送空值
x-client-localezh_CN 或 en_US,取自当前 UI 语言的主语言子标签;选择本地化内容,不代表区域
x-client-timezone-offset与 UTC 的整秒偏移,东为正,每次请求时从壳采样
x-client-archWindows 为 x64;macOS 为 x64 或 arm64
x-client-update-channel一期固定 nightly,独立于版本后缀
x-client-bundled-dsh-version发布元数据中的完整内置 dsh 版本
Query客户端行为后端一期行为
scenario携带查询来源;launch 是启动示例忽略;桌面最终枚举不阻塞接入
region可选;仅在有可信区域信息时携带忽略;不从 UI 语言推断

两个 query 都不参与一期策略匹配或参数校验。其他客户端条件相同时,改变或省略任一 query 不得改变判定。生命周期触发点与 query 枚举不必一一对应;后端启用使用前再约定枚举与统计。

无需强制更新

{
  "code": 0,
  "msg": "",
  "data": {
    "biz_code": 0,
    "biz_msg": "",
    "biz_data": null
  }
}

这表示当前客户端无需强制更新,不表示已安装版本最新。针对当前客户端条件的新鲜有效响应可以清除已有阻断。Desktop 不消费此响应中的移动端普通更新载荷。

需要强制更新

{
  "code": 40005,
  "msg": "Client version too low",
  "data": {
    "show_content": {
      "title": "请更新 DeepSeek Harness",
      "detail": "当前版本已停止支持,请下载并安装新版本。"
    },
    "desktop_app_link": "https://example.com/harness/download"
  }
}

示例 URL 是占位符,不是获准部署的目标地址。Desktop 使用拍平的 data 字段,不包裹 alt_app 或 biz_data。尚无已分发 Desktop,因此不需要兼容较早嵌套提案的解析器。移动端 alt_app、Android 链接与 iOS 应用标识保持既有格式。

字段要求
code40005 是响应体错误码,不是 HTTP 状态
msg仅用于诊断,不作弹窗文案
data.show_content.title必填,本地化纯文本标题
data.show_content.detail必填,本地化纯文本正文
data.desktop_app_link必填,匹配产品、平台、架构与通道的 HTTPS 页面,必须符合客户端允许列表

一期不增加 mode、force_update、show_key、target_version、按钮文案或 updater 元数据。40005 决定必须升级,实际版本与安装包由 updater 元数据决定。客户端不依据本接口另做强制目标版本校验。客户端状态决定本地化操作,每次下载仍需用户操作。接入应用内 updater 后,页面仍作为兜底。HTTP 状态映射按网关联调确认;网关必须保留 JSON 错误体,不能替换为通用文本或 HTML。

错误与策略匹配

缺少必填 header、非法 SemVer 或不支持的平台/架构/通道组合返回明确参数错误,不能伪装为无强制成功或强制策略。优先沿用 biz_code = 1 表示缺少版本、biz_code = 2 表示版本非法的既有业务含义;最终错误码分配由后端负责。服务异常不得伪装成成功,因为成功可能解除已有阻断。

按平台、架构、Desktop 版本、内置 dsh 版本与通道匹配,由服务端维护版本范围和优先级。使用完整 SemVer,不按字符串排序或截断预发布部分。一期两个版本相等、通道固定 Nightly,独立修订与通道切换延后。不得要求降级,也不得仅因客户端曾查询或展示过就停止返回 40005。

策略发布与当前判定

每条生效策略需要可确定的匹配条件、本地化标题正文和有效目标页面。服务端每次查询均判定当前客户端条件。这些是服务端配置要求,不增加响应字段,也不是安装包撤回机制。

  • 启用策略前发布并验证能解除强制要求的更高版本,确保匹配的页面与平台安装包可用。
  • 对启用应用内强制更新的客户端,先向其 updater feed 发布能解除要求的版本,再启用强制要求。发布负责人协调该顺序;API 不提供独立安装目标、产物适用性响应或普通更新灰度。
  • 链接匹配产品、平台、架构与通道;缺少文案或获准 HTTPS 目标时拒绝启用策略。
  • 当前客户端不再命中时返回无强制成功响应,包括升级后;仍命中时持续返回强制策略。

问题版本通过发布更高修复版本并更新 updater 元数据处理。不向本接口增加作废版本清单、安装前产物撤回查询或目标版本校验。新鲜的无强制响应可以解除 UI 阻断,但不选择、替换或作废 updater 安装包。产物哈希/签名校验仍独立于强制判定执行。

容量与缓存

容量与限流需覆盖持续未登录请求,并考虑客户端合并与失败退避。策略触达不依赖聊天请求或 SSE(Server-Sent Events)。在线触达延迟受轮询和网络影响,离线客户端无法立即获知新策略。建议 Cache-Control: no-store。网关不得仅按 URL 跨客户端版本、平台、架构或通道共用响应;后续缓存必须定义所有策略与文案维度和判定新鲜度。

考虑过的替代方案

依赖远程业务拦截。 本地 dsh 请求不一定到达远程网关,需要独立的未登录查询。

Desktop 复用移动端嵌套载荷。 后端约定拍平 Desktop 字段。按平台保留移动端兼容,不让新 Desktop 支持从未分发的嵌套变体。

增加安装身份与普通更新元数据。 初期策略不需要按安装实例灰度或第二个安装器 feed。产物发现继续由 updater 负责。

验收标准

用例预期结果
未登录 Desktop无需业务登录即可查询
Windows x64、macOS x64 和 arm64正确的平台策略与页面
不命中策略code = 0、biz_code = 0、biz_data = null
命中策略顶层 40005,文案与页面直接位于 data 下
改变或省略 query 参数其他条件相同时判定一致
相等的 Desktop/dsh 预发布版本、固定 Nightly完整 SemVer 匹配,不要求降级或切换通道
客户端不再命中,包括升级后返回无强制成功,不作废 updater 产物
可解除要求的发布、页面或适用 feed 不可用拒绝启用策略
必填字段非法或服务失败明确错误,不伪装为无强制成功
不同客户端条件连续请求不跨客户端串用缓存
现有移动端请求保持既有要求与响应结构

风险

后端需提供测试/生产地址、未登录网关访问、最终 HTTP/错误码映射、限流、真实页面、允许域名、兜底语言和策略配置负责人。发布负责人需逐平台协调 updater 版本可用与强制策略启用。这些输入仍待提供,不得用开发者凭据或猜测 URL 填充。