From a3f49502e49379b2dec790bc13b1dc71e1a4dc38 Mon Sep 17 00:00:00 2001 From: Altair Li <137127498+Altairpaca@users.noreply.github.com> Date: Thu, 3 Sep 2026 01:39:51 -0700 Subject: [PATCH 01/24] feat(dsh): bridge session log reads across DSH releases --- packages/dsh/src/session-log-compat.ts | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) create mode 100644 packages/dsh/src/session-log-compat.ts diff --git a/packages/dsh/src/session-log-compat.ts b/packages/dsh/src/session-log-compat.ts new file mode 100644 index 0000000..ff00ce3 --- /dev/null +++ b/packages/dsh/src/session-log-compat.ts @@ -0,0 +1,26 @@ +import type { SessionEvent } from '@deepseek-ai/dsh-session' + +/** + * Narrow compatibility face for the DSH session-log read API. + * + * DSH 0.1.0-rc.x exposed `session.events`; the 0.1.2 line replaces that + * materialized getter with `snapshotEvents()` / `eventAt()` / `seq`. + * Keeping the bridge structural lets DSHelm run against both shapes while the + * npm dependency baseline is upgraded in one verified step. + */ +interface SessionLogCompat { + readonly events?: readonly SessionEvent[] + snapshotEvents?: () => readonly SessionEvent[] +} + +/** Return a stable session-event snapshot across legacy and current DSH APIs. */ +export function snapshotSessionLog(session: unknown): readonly SessionEvent[] { + const compatible = session as SessionLogCompat + if (typeof compatible.snapshotEvents === 'function') { + return compatible.snapshotEvents() + } + if (compatible.events !== undefined) { + return compatible.events + } + throw new Error('unsupported DSH session log API: expected snapshotEvents() or events') +} From 88365538aa0e13a89a4b68615768cd3835830e8e Mon Sep 17 00:00:00 2001 From: Altair Li <137127498+Altairpaca@users.noreply.github.com> Date: Thu, 3 Sep 2026 01:40:19 -0700 Subject: [PATCH 02/24] fix(dsh): read session logs through compatibility bridge --- packages/dsh/src/slice.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/packages/dsh/src/slice.ts b/packages/dsh/src/slice.ts index 20fd043..e525479 100644 --- a/packages/dsh/src/slice.ts +++ b/packages/dsh/src/slice.ts @@ -15,6 +15,7 @@ import { createUserMessage } from '@deepseek-ai/dsh-llm' import type { ResolvedAgentPolicy } from '@dshelm/core' import type { DSHelmPolicyServiceFace } from './service.ts' import { installDSHelmSelection, toModelSelection } from './model-selection.ts' +import { snapshotSessionLog } from './session-log-compat.ts' export interface SliceGoal { /** The task text delivered to the planner. */ @@ -134,7 +135,7 @@ export async function runRoleAgent(options: { function lastAssistantText(agent: Agent): string { let text = '' - for (const event of agent.session.events) { + for (const event of snapshotSessionLog(agent.session)) { if (event.type === 'assistant/message') { const joined = event.data.message.content .filter((block) => block.type === 'text') From 08e8a9d187e7e4e3539cf660ebe0a9328f03a688 Mon Sep 17 00:00:00 2001 From: Altair Li <137127498+Altairpaca@users.noreply.github.com> Date: Thu, 3 Sep 2026 01:40:47 -0700 Subject: [PATCH 03/24] feat(dsh): bridge subagent model options to DSH 0.1.2 --- packages/dsh/src/provider.ts | 35 +++++++++++++++++++++++++++++++---- 1 file changed, 31 insertions(+), 4 deletions(-) diff --git a/packages/dsh/src/provider.ts b/packages/dsh/src/provider.ts index 8673ee4..675f403 100644 --- a/packages/dsh/src/provider.ts +++ b/packages/dsh/src/provider.ts @@ -18,6 +18,20 @@ import type { DSHelmPolicyServiceFace } from './service.ts' export const DSHELM_PROVIDER_NAME = 'dshelm' const ROLE_LABEL_PREFIX = 'dshelm:' +/** + * DSH 0.1.2 adds the `agentOptions` start capability. The structural cast keeps + * this package compilable against the currently pinned 0.1.0-rc.7 types while + * exposing the new runtime flag to 0.1.2 hosts; legacy hosts ignore the extra + * property. + */ +const DSHELM_SUBAGENT_CAPABILITIES = { + agentOptions: true, + outputSchema: false, + depthLimit: true, + toolFilter: true, + persona: true, +} as unknown as SubagentProvider['capabilities'] + export interface DSHelmProviderOptions { readonly service: DSHelmPolicyServiceFace /** Resolve the category for a role label (e.g. planner/worker/reviewer). */ @@ -30,8 +44,8 @@ export interface DSHelmProviderOptions { * Build the child's first-request config seed. The session seed contract * accepts `request/header` events (validated at the seed boundary), and the * loop restores the explicit reasoningEffort from the persisted header when - * the route matches — the official mechanism for carrying DSHelm's - * reasoning effort into a subagent child's real request config. + * the route matches. This remains the legacy path for 0.1.0-rc.x hosts while + * 0.1.2 can also consume reasoningEffort from AgentOptions directly. */ export function childRequestHeaderSeed(resolved: ResolvedAgentPolicy): SessionEvent[] { const config: { provider: string; model: string; reasoningEffort?: string } = { @@ -49,10 +63,23 @@ export function childRequestHeaderSeed(resolved: ResolvedAgentPolicy): SessionEv ] } +/** + * Build AgentOptions understood by both DSH generations. `reasoningEffort` was + * added to AgentOptions in 0.1.2; the assertion deliberately preserves the + * runtime field when compiling against the legacy type surface. + */ +function resolvedAgentOptions(resolved: ResolvedAgentPolicy): NonNullable { + return { + provider: resolved.provider, + model: resolved.model, + ...(resolved.reasoning !== undefined ? { reasoningEffort: resolved.reasoning } : {}), + } as NonNullable +} + export function createDSHelmProvider(options: DSHelmProviderOptions): SubagentProvider { return { name: DSHELM_PROVIDER_NAME, - capabilities: { outputSchema: false, depthLimit: true, toolFilter: true, persona: true }, + capabilities: DSHELM_SUBAGENT_CAPABILITIES, inheritsParentContext: false, start: async (request: ResolvedSubagentStartRequest): Promise => { const role = roleFromLabel(request.label) @@ -63,7 +90,7 @@ export function createDSHelmProvider(options: DSHelmProviderOptions): SubagentPr options.service.recordDelegation(resolved, options.sessionIdOf(request)) const mapped: ResolvedSubagentStartRequest = { ...request, - agentOptions: { provider: resolved.provider, model: resolved.model }, + agentOptions: resolvedAgentOptions(resolved), ...(resolved.persona !== undefined ? { persona: resolved.persona } : {}), ...(resolved.tools !== undefined ? { toolFilter: toToolRestriction(resolved.tools) } : {}), ...(resolved.maxDepth !== undefined ? { maxDepth: resolved.maxDepth } : {}), From 96b033f068d73f96a89c32c215c6f3e06b71806e Mon Sep 17 00:00:00 2001 From: Altair Li <137127498+Altairpaca@users.noreply.github.com> Date: Thu, 3 Sep 2026 01:41:03 -0700 Subject: [PATCH 04/24] test(dsh): cover 0.1.2 compatibility bridges --- packages/dsh/tests/dsh-012-compat.test.ts | 46 +++++++++++++++++++++++ 1 file changed, 46 insertions(+) create mode 100644 packages/dsh/tests/dsh-012-compat.test.ts diff --git a/packages/dsh/tests/dsh-012-compat.test.ts b/packages/dsh/tests/dsh-012-compat.test.ts new file mode 100644 index 0000000..b0ed712 --- /dev/null +++ b/packages/dsh/tests/dsh-012-compat.test.ts @@ -0,0 +1,46 @@ +import { describe, expect, it, vi } from 'vitest' +import type { SessionEvent } from '@deepseek-ai/dsh-session' +import { createDSHelmProvider } from '../src/provider.ts' +import { snapshotSessionLog } from '../src/session-log-compat.ts' +import type { DSHelmPolicyServiceFace } from '../src/service.ts' + +const EVENT = { + type: 'fixture/event', + seq: 0, + time: 0, + data: {}, +} as unknown as SessionEvent + +describe('DSH 0.1.2 compatibility bridges', () => { + it('prefers snapshotEvents() when the current session API is present', () => { + const snapshotEvents = vi.fn(() => [EVENT] as readonly SessionEvent[]) + const legacyEvents = [] as readonly SessionEvent[] + + expect(snapshotSessionLog({ snapshotEvents, events: legacyEvents })).toEqual([EVENT]) + expect(snapshotEvents).toHaveBeenCalledOnce() + }) + + it('falls back to the legacy events snapshot for 0.1.0-rc.x hosts', () => { + expect(snapshotSessionLog({ events: [EVENT] })).toEqual([EVENT]) + }) + + it('fails loud for an unknown session log surface', () => { + expect(() => snapshotSessionLog({})).toThrow(/unsupported DSH session log API/) + }) + + it('advertises the agentOptions capability introduced in the 0.1.2 line', () => { + const provider = createDSHelmProvider({ + service: {} as DSHelmPolicyServiceFace, + categoryForRole: (role) => role, + sessionIdOf: () => 'compat-test', + }) + + expect(provider.capabilities).toMatchObject({ + agentOptions: true, + outputSchema: false, + depthLimit: true, + toolFilter: true, + persona: true, + }) + }) +}) From fc8d4c4819c4f8ee4ba22bc28d03e1494289d5d3 Mon Sep 17 00:00:00 2001 From: Altair Li <137127498+Altairpaca@users.noreply.github.com> Date: Thu, 3 Sep 2026 01:41:40 -0700 Subject: [PATCH 05/24] ci(dsh): cover forward-compatibility bridges --- .github/workflows/ci.yml | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index aabb61e..f34c2b0 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -44,8 +44,8 @@ jobs: run: pnpm vitest run packages/core/tests/config-loader.test.ts packages/core/tests/config-validation.test.ts packages/core/tests/policy-errors.test.ts packages/core/tests/policy-resolver.test.ts - name: Core property contracts run: pnpm vitest run packages/core/tests/core-property.test.ts - - name: DSH execution and host contracts - run: pnpm vitest run packages/dsh/tests/dsh-request-contract.test.ts packages/dsh/tests/host-composition.test.ts packages/dsh/tests/vertical-slice.test.ts packages/dsh/tests/keyless-vertical-slice.test.ts + - name: DSH execution, host, and release-bridge contracts + run: pnpm vitest run packages/dsh/tests/dsh-request-contract.test.ts packages/dsh/tests/host-composition.test.ts packages/dsh/tests/vertical-slice.test.ts packages/dsh/tests/keyless-vertical-slice.test.ts packages/dsh/tests/dsh-012-compat.test.ts - name: Auth, knowledge, CLI, and overlay contracts run: pnpm vitest run packages/auth/tests/auth.test.ts packages/model-knowledge/tests/knowledge.test.ts packages/cli/tests/user-commands.test.ts packages/dsh/tests/knowledge-overlay.test.ts - name: CLI package typecheck @@ -65,11 +65,12 @@ jobs: - run: pnpm install --frozen-lockfile - run: pnpm qa:pack-install - # Optional upstream source lane: explicit DSH_REFERENCE_DIR, never a - # default hermetic dependency. + # Optional upstream source lane: kept manual while the DSH 0.1.2 package set + # is rolling through npm. compatibility.json records the current source + # target separately from the verified install baseline. dsh-upstream-source-contract: runs-on: ubuntu-latest if: github.event_name == 'workflow_dispatch' steps: - uses: actions/checkout@v4 - - run: echo 'dsh-upstream-source-contract is informational; requires DSH_REFERENCE_DIR checkout' + - run: echo 'Use compatibility.json target.dshRelease as the source canary; promote it to the install baseline only after the npm package set and clean profile journey are verified.' From 401fd6160066de066e257734cdbe460ac9d34167 Mon Sep 17 00:00:00 2001 From: Altair Li <137127498+Altairpaca@users.noreply.github.com> Date: Thu, 3 Sep 2026 01:42:06 -0700 Subject: [PATCH 06/24] docs(compat): track DSH 0.1.2-rc.1 as current source target --- compatibility.json | 31 ++++++++++++++++++++++++------- 1 file changed, 24 insertions(+), 7 deletions(-) diff --git a/compatibility.json b/compatibility.json index ff8b08f..7520f74 100644 --- a/compatibility.json +++ b/compatibility.json @@ -12,6 +12,18 @@ "dshReferenceCheckout": "99f6f02fecdb7dff40c3fbc9470f5907c29f74ca (dsh-v0.1.0-rc.7, read-only reference)", "verifiedDate": "2026-08-18" }, + "target": { + "dshRelease": "0.1.2-rc.1", + "releaseTag": "dsh-v0.1.2-rc.1", + "sourceCommit": "a66e4702047846cdaa10c66c9d3df3951f5ea70d", + "releaseDate": "2026-09-03", + "status": "forward-compatible source bridges implemented; promotion to tested awaits complete npm publication plus clean-profile verification", + "auditedSeams": [ + "Session.snapshotEvents() replacing Session.events", + "SubagentCapabilities.agentOptions", + "AgentOptions.reasoningEffort" + ] + }, "seams": { "llm": [ "listProviders", @@ -22,16 +34,18 @@ ], "agent": [ "AgentRegistry.create", - "installModelSelection" + "installModelSelection", + "AgentOptions provider/model with 0.1.2 reasoningEffort bridge" ], "subagent": [ "SubagentRuntime.registerProvider", - "SubagentStartRequest (persona/toolFilter/maxDepth)", + "SubagentStartRequest (agentOptions/persona/toolFilter/maxDepth)", "startInProcessRun" ], "session": [ "SessionStore", "SessionEventMap augmentation via '@deepseek-ai/dsh-session/types'", + "snapshotEvents() with legacy events fallback", "request/header" ], "projection": [ @@ -44,10 +58,13 @@ "settingsNamespace" ] }, - "notes": [ - "dsh-client-runtime@0.1.0-rc.7 is browser-only and requires the DSH Web shell", - "public CLI tarball is named dshelm; workspace @dshelm packages are packed together for closure verification", - "clean journey uses an isolated HOME/DSH_HOME and verifies init, rc.7 dump-config, bounded boot, doctor, explain, and uninstall", - "native auth descriptors are version-gated evidence snapshots: Codex 0.147.0 and Claude Code 2.1.234; Gemini and Qwen shell login/logout are unsupported" + "notes": [ + "The verified npm/install baseline remains 0.1.0-rc.7 until the 0.1.2-rc.1 package set is fully published and the clean profile journey passes.", + "DSH 0.1.2 removes direct Session.events reads in favor of seq/eventAt()/snapshotEvents(); DSHelm now prefers snapshotEvents() and falls back to the legacy getter.", + "DSH 0.1.2 adds the SubagentCapabilities.agentOptions gate and AgentOptions.reasoningEffort; DSHelm advertises the capability at runtime while retaining the request/header seed for legacy hosts.", + "dsh-client-runtime@0.1.0-rc.7 is browser-only and requires the DSH Web shell.", + "public CLI tarball is named dshelm; workspace @dshelm packages are packed together for closure verification.", + "clean journey uses an isolated HOME/DSH_HOME and verifies init, dump-config, bounded boot, doctor, explain, and uninstall.", + "native auth descriptors are version-gated evidence snapshots: Codex 0.147.0 and Claude Code 2.1.234; Gemini and Qwen shell login/logout are unsupported." ] } From 90fc9aafd97db5274f24fdef0ee28d0c0502dd65 Mon Sep 17 00:00:00 2001 From: Altair Li <137127498+Altairpaca@users.noreply.github.com> Date: Thu, 3 Sep 2026 01:42:45 -0700 Subject: [PATCH 07/24] design(readme): redesign DSHelm hero banner --- docs/assets/banner.svg | 135 ++++++++++++++++++++++++++++++++--------- 1 file changed, 106 insertions(+), 29 deletions(-) diff --git a/docs/assets/banner.svg b/docs/assets/banner.svg index 31bef92..16084f6 100644 --- a/docs/assets/banner.svg +++ b/docs/assets/banner.svg @@ -1,33 +1,110 @@ - - DSHelm - DSHelm routes planning, execution, and review through an explainable control plane. - - - - - - - + + DSHelm — explainable model routing for DeepSeek Harness + A visual control plane routes tasks through planner, worker, and reviewer roles while preserving an observable Resolution Trace. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - DSHelm - DeepSeek Harness 的可解释多模型调度层 - - - 规划 - - - 执行 - - - 审核 + + + + DSHelm + Explainable model routing for DeepSeek Harness + DSH-NATIVE · EVIDENCE-BACKED · POLICY-FIRST + + + + + 0.3.0-alpha source + + + + + DSH 0.1.2-rc.1 target + - - - ROUTE / EXPLAIN - plannerv4-pro - workerv4-flash - reviewerv4-pro - - trace: visible + + + + + CONTROL PLANE / RESOLUTION TRACE + + + + TASK + + + + + POLICY + + + + + EVIDENCE + + + + + + + + + planner + reasoning-pro + + + + worker + fast-worker + + + + reviewer + reasoning-pro + + + + trace + + + + + selected · scored · explained + + + task requirements → hard gates → evidence → policy overrides → DSH execution → trace From 250d802760aa3a1334b6df846413913bde79391f Mon Sep 17 00:00:00 2001 From: Altair Li <137127498+Altairpaca@users.noreply.github.com> Date: Thu, 3 Sep 2026 01:43:15 -0700 Subject: [PATCH 08/24] design(readme): add routing flow visual --- docs/assets/routing-flow.svg | 98 ++++++++++++++++++++++++++++++++++++ 1 file changed, 98 insertions(+) create mode 100644 docs/assets/routing-flow.svg diff --git a/docs/assets/routing-flow.svg b/docs/assets/routing-flow.svg new file mode 100644 index 0000000..cf58c7c --- /dev/null +++ b/docs/assets/routing-flow.svg @@ -0,0 +1,98 @@ + + DSHelm routing flow + Task requirements pass through hard runtime gates, capability evidence, policy overrides, role-specific model selection, DeepSeek Harness execution, and an observable Resolution Trace. + + + + + + + + + + + + + + + + + + One task, explicit routing decisions + DSHelm owns policy and explanation. DeepSeek Harness owns execution. + + + + + + TASK REQUIREMENTS + latency · cost · context + planning · verification + + + + + HARD GATES + runtime · auth · limits + fail loud before scoring + + + + + EVIDENCE SCORE + capability · provenance + confidence · ranking + + + + + POLICY OVERRIDES + user · project · request + explicit wins over default + + + + + DSH EXECUTION + AgentRegistry · AgentLoop + sessions · tools · providers + + + + + + + + + + + planner + strong reasoning + plan artifact + + + + + workers + bounded parallelism + task results + + + + + reviewer + independent check + PASS / REVISE + + + + + RESOLUTION TRACE + + + + + candidate outcomes · field provenance · selected route + + + From 674398e0546a80708ce0b73e3621f8eca800c5b5 Mon Sep 17 00:00:00 2001 From: Altair Li <137127498+Altairpaca@users.noreply.github.com> Date: Thu, 3 Sep 2026 01:43:31 -0700 Subject: [PATCH 09/24] design(readme): add compatibility status visual --- docs/assets/compatibility-status.svg | 45 ++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) create mode 100644 docs/assets/compatibility-status.svg diff --git a/docs/assets/compatibility-status.svg b/docs/assets/compatibility-status.svg new file mode 100644 index 0000000..1865849 --- /dev/null +++ b/docs/assets/compatibility-status.svg @@ -0,0 +1,45 @@ + + DSHelm compatibility status + Three cards show the DSHelm source release, the verified DeepSeek Harness install baseline, and the current DeepSeek Harness source target. + + + + + + + + + Compatibility is evidence, not a version badge + Source target and verified install baseline stay separate until the full npm/profile journey passes. + + + + + DSHELM + 0.3.0-alpha + source preview · npm unpublished + + release graph + clean-install gates + + + + + + VERIFIED INSTALL + DSH 0.1.0-rc.7 + clean HOME · profile boot · pack/install + + current tested npm baseline + + + + + + SOURCE TARGET + DSH 0.1.2-rc.1 + session + subagent bridges landed + + npm promotion / clean-profile verification pending + + + From 8cadadf5b2409ea5dcb01785bd2fc1e7ae997d4b Mon Sep 17 00:00:00 2001 From: Altair Li <137127498+Altairpaca@users.noreply.github.com> Date: Thu, 3 Sep 2026 01:44:29 -0700 Subject: [PATCH 10/24] design(readme): rebuild project landing page around routing and compatibility evidence --- README.md | 183 ++++++++++++++++++++++++++++++++++++------------------ 1 file changed, 124 insertions(+), 59 deletions(-) diff --git a/README.md b/README.md index 8897f6a..415d66b 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,5 @@

- DSHelm - DeepSeek Harness 的可解释多模型调度层 + DSHelm — explainable model routing for DeepSeek Harness

English · 简体中文

@@ -7,66 +7,123 @@

CI Apache-2.0 - DSH plugin - status alpha + DeepSeek Harness plugin + status alpha +

+ +

+ 两分钟看懂 · + 零凭据体验 · + DSH 兼容性 · + 源码安装 · + 社区路线图

> [!IMPORTANT] -> DSHelm 目前是 `0.3.0-alpha` 源码预览版,npm 包尚未发布。当前适合 DSH 插件开发者和愿意反馈早期体验的用户,不建议用于生产环境。 +> DSHelm 当前是 `0.3.0-alpha` **源码预览版**,npm 包尚未发布,不建议用于生产环境。项目正在适配 DeepSeek Harness `0.1.2-rc.1`;该版本目前作为 **source target** 跟踪,完整 npm package set 与 clean-profile 验证完成前,不会把它标记为已验证安装基线。 -## DSHelm 解决什么问题 +

+ DSHelm compatibility status: source preview, verified DSH install baseline, and current DSH source target +

-当一个任务同时需要强规划、低成本并行执行和独立审核时,固定使用一个模型往往不是最合适的选择。DSHelm 为 [DeepSeek Harness](https://github.com/deepseek-ai/deepseek-harness) 增加一层可解释的调度能力: +## 两分钟看懂 DSHelm -- **按能力选择模型**:先检查运行时、认证、上下文和成本等硬条件,再对候选模型排序。 -- **让每次选择可追溯**:展示角色、模型、推理等级、覆盖来源和候选淘汰原因。 -- **复用 DSH 生态**:使用 DSH 官方扩展接口,不复制会话、工具、工作流或桌面运行时。 -- **尊重用户配置**:项目和请求级设置始终可以覆盖 DSHelm 的建议。 +DSHelm 是 [DeepSeek Harness](https://github.com/deepseek-ai/deepseek-harness) 上的一层**可解释多模型调度控制面**。它不复制 DSH 的 session、tool、workflow 或 agent runtime;它只负责在执行之前回答三个问题: -一句话概括:**让规划、执行和审核使用合适的模型,并告诉你为什么。** +1. **这一步应该交给哪个 role / provider / model?** +2. **哪些 runtime、认证、上下文或成本条件排除了其他候选?** +3. **最终选择来自默认策略、用户覆盖,还是当前请求?** -

DSHelm 控制面板展示 planner、worker 和 reviewer 的模型路由与 Resolution Trace

+

+ DSHelm routing flow from task requirements through hard gates, evidence, policy overrides, DSH execution and Resolution Trace +

-## 当前可以体验 +核心边界很简单: -| 能力 | 当前状态 | 你能看到什么 | -| --- | --- | --- | -| DSH 原生组合 | 已验证 | 独立 `dshelm` profile 和 `@dshelm/dsh` bundle | -| 模型路由 | Alpha | 硬条件过滤、证据评分、用户策略覆盖 | -| Resolution Trace | Alpha | 每个有效字段的来源和候选决策 | -| 账号发现 | Alpha | API key、provider OAuth 和部分产品登录状态,不复制产品凭据 | -| Web 控制面板 | Alpha | Roles × Models 与最近一次调度解释 | -| OmO 配置迁移 | 预览 | 只读分析,明确标出映射、损失和不支持项 | -| npm 一键安装 | 发布门槛 | 尚未开放,当前只能使用下方源码预览流程 | -| 桌面安装包 | 生态协作 | DSHelm 不另造桌面壳,跟随 DSH 桌面宿主的 profile/plugin 能力 | +| DSHelm 负责 | DeepSeek Harness 负责 | +| --- | --- | +| policy、routing、capability evidence | agent lifecycle、session、tool execution | +| provider/model/reasoning selection | provider adapters 与真实模型调用 | +| user/project/request overrides | profile/plugin composition | +| Resolution Trace 与选择解释 | host、Web、Headless、SDK 等执行面 | -## 2026 年 9 月维护进展 +**结果是:planner、worker、reviewer 可以使用不同模型,但每一次选择都保留可追溯证据。** -当前 `main` 已包含 `0.3.0-alpha` 的认证与模型编排、DSH profile 安装、`doctor` / `explain`、Resolution Trace、Web 控制面板和 OmO 只读迁移能力。下一阶段已经拆成可公开跟踪的社区任务: +### 真实控制面 -| 任务 | 目标 | -| --- | --- | -| [#7 npm alpha](https://github.com/Altairpaca/dshelm/issues/7) | 发布可验证的公共 alpha,并完成 clean-HOME 安装 / 卸载证据 | -| [#8 跨平台安装矩阵](https://github.com/Altairpaca/dshelm/issues/8) | 收集 Linux、macOS Apple Silicon、Windows 11 + WSL2 的可复现安装记录 | -| [#9 首次运行示例](https://github.com/Altairpaca/dshelm/issues/9) | 提供 planner → workers → reviewer 的 credential-light 示例和完整 trace | -| [#10 贡献者入口](https://github.com/Altairpaca/dshelm/issues/10) | 明确 provider/model evidence、平台验证、文档、示例和 bug 的贡献规范 | - -当前发布状态仍是**源码预览**。npm 包、三平台完整验证以及可复用首次运行 fixture 均以对应 Issue 的验收条件为准,不提前宣称完成。 +

+ DSHelm Web control plane showing Roles × Models and Resolution Trace +

-### 不配置 provider,先检查路由和执行链路 +## 零凭据体验 -仓库提供两个零凭据 fixture,分别验证两层契约: +仓库提供两层 deterministic fixture。两者都不需要 provider credential,但证明的东西不同: ```bash pnpm example:first-run pnpm example:dsh-execution ``` -`example:first-run` 只验证 **resolver 与 Resolution Trace**。`example:dsh-execution` 再向前一层:planner → 两个 bounded workers → reviewer 会通过真实 DSH `Context`、agent factory 与 `AgentLoop` 执行,同时使用 deterministic synthetic provider 生成模型响应。后者可以证明 DSHelm 解析出的 provider/model 确实进入真实 DSH request,但不代表任何外部 provider、网络、认证或模型质量已经验证。两者的证据边界和输出结构见 [`examples/README.md`](examples/README.md)。 +| 命令 | 真实执行到哪一层 | 明确不证明什么 | +| --- | --- | --- | +| `example:first-run` | DSHelm Core resolver + Resolution Trace | 不执行 DSH agent,不访问 provider | +| `example:dsh-execution` | 真实 DSH `Context` + `AgentRegistry` + `AgentLoop`,执行 planner → bounded workers → reviewer,并检查 actual request route | synthetic LLM adapter,不证明外部网络、OAuth 或模型质量 | + +第二个 fixture 会把实际进入 DSH adapter 的 `requestRoutes` 与 DSHelm resolution 逐项比较,因此它可以证明:**路由结果确实进入了真实 DSH request path**。详细输出与证据边界见 [`examples/README.md`](examples/README.md)。 + +
+为什么保留两个 fixture? + +resolver contract 与 execution contract 是两个不同的故障域。把它们拆开后,routing regression 可以在不启动 agent runtime 的情况下定位;而 execution fixture 专门验证 DSHelm → DSH 的边界,没有必要用真实 API key 才获得可重复证据。 + +
+ +## 当前能力 + +| 能力 | 状态 | 当前证据 | +| --- | --- | --- | +| DSH 原生 profile / bundle | Alpha | 独立 `dshelm` profile、`@dshelm/dsh` bundle、clean profile journey | +| 多模型路由 | Alpha | hard gates、evidence scoring、policy overrides | +| Resolution Trace | Alpha | candidate outcome、field provenance、selected route | +| 账号与认证发现 | Alpha | API key / provider OAuth / 部分产品登录状态;不复制产品凭据 | +| Web control plane | Alpha | Roles × Models、最近一次调度解释 | +| planner → workers → reviewer | Alpha | deterministic real-DSH execution fixture | +| OmO 配置迁移 | Preview | 只读分析;SUPPORTED / MAPPED / LOSSY / UNSUPPORTED | +| npm 安装 | Release gate | 尚未公开;[#7](https://github.com/Altairpaca/dshelm/issues/7) 跟踪 | +| 跨平台验证 | Community evidence | Linux / macOS Apple Silicon / Windows 11 + WSL2 持续收集 | + +## DeepSeek Harness 兼容性 + +### 当前状态 + +DSHelm 的兼容性声明采用两层口径: + +- **Verified install baseline — `0.1.0-rc.7`**:已经完成 package/runtime、clean HOME、profile composition、bounded boot、doctor / explain / uninstall 验证。 +- **Current source target — `0.1.2-rc.1`**:DeepSeek Harness 于 **2026-09-03** 发布的最新 source release。DSHelm 已针对已确认的 API 变化加入 forward-compatible bridge,但仍等待完整 npm package set 与 clean-profile promotion gate。 + +当前机器可读状态见 [`compatibility.json`](compatibility.json)。上游 source target 对应 [`dsh-v0.1.2-rc.1`](https://github.com/deepseek-ai/deepseek-harness/releases/tag/dsh-v0.1.2-rc.1)。 + +### 已处理的 0.1.2 API 变化 + +| 上游变化 | DSHelm 处理 | +| --- | --- | +| `Session.events` 被 `seq` / `eventAt()` / `snapshotEvents()` 取代 | 新增 session-log compatibility bridge:优先 `snapshotEvents()`,legacy host 回退 `events` | +| `SubagentCapabilities` 新增 `agentOptions` gate | DSHelm provider 在 runtime 声明 `agentOptions: true`,同时保持旧类型可编译 | +| `AgentOptions` 新增 `reasoningEffort` | 新 host 直接获得 reasoning option;legacy host 继续通过 `request/header` seed 恢复 reasoning | +| subagent caller 可显式选择 provider / model / reasoning / max output | DSHelm 保持 policy resolution 为来源,并映射到官方 `agentOptions` seam;max-output policy 尚未宣称实现 | + +这里刻意没有直接把所有 package manifest 改成 `0.1.2-rc.1`:上游 npm 发布在 2026-09-03 处于滚动状态,而且 DSHelm 当前 lockfile 仍属于已验证旧基线。**版本 promotion 必须和完整 package availability、lockfile regeneration、fresh install/profile boot 一起完成。** + +
+为什么不使用宽泛的“支持 0.1.x”声明? + +DSH 的 session、subagent、client 与 profile seams 在 prerelease 阶段仍会变化。DSHelm 将兼容性拆成具体 seam 与具体证据,避免一个 semver range 暗示并不存在的运行时保证。发布候选的精确流程见 [`docs/RELEASING.md`](docs/RELEASING.md)。 + +
## 从源码体验 -环境要求:Node.js `>=22.19.0`、pnpm `11.7.0`、可在 `PATH` 中调用的 DSH CLI。当前验证版本见 [`compatibility.json`](compatibility.json)。macOS、Linux 或 Windows 11 + WSL2 均可尝试,Windows 原生体验仍待社区验证。 +要求:Node.js `>=22.19.0`、pnpm `11.7.0`,以及当前已验证基线对应的 DSH CLI。准备升级到最新 DSH 时请先查看 [`compatibility.json`](compatibility.json)。 ```bash git clone https://github.com/Altairpaca/dshelm.git @@ -76,7 +133,7 @@ pnpm install --frozen-lockfile pnpm preview:init ``` -`preview:init` 会构建本地包,并把源码预览安装到 `$DSH_HOME/profiles/dshelm`。它不会自动登录,也不会复制 Codex、Claude 等产品的凭据。 +`preview:init` 会构建本地 packages,并把源码预览安装到 `$DSH_HOME/profiles/dshelm`;它不会自动登录,也不会复制 Codex、Claude 等产品凭据。 ```bash dsh --profile dshelm --dump-config @@ -86,45 +143,53 @@ node packages/cli/dist/index.js explain deepseek/deepseek-v4-flash dsh --profile dshelm ``` -卸载会移除项目发现信息和 `dshelm` profile,默认保留凭据: +卸载默认保留 credentials: ```bash node packages/cli/dist/index.js uninstall --yes ``` > [!NOTE] -> npm alpha 发布后的目标入口是 `npx dshelm init --yes`。在 npm 页面真实可用前,文档不会把它写成现有安装方式。 +> npm alpha 发布后的目标入口是 `npx dshelm init --yes`。在 registry artifacts 与 clean-install evidence 都真实存在之前,README 不会把它写成当前安装方式。 -## 它如何工作 +## 项目结构 ```text -任务需求 → 运行时与认证硬条件 → 模型能力与证据评分 → 用户/项目/请求策略覆盖 → DSH 执行 + Resolution Trace -``` - -DSHelm Core 只负责策略、配置、路由和解释;任务执行仍由 DSH 及其插件完成。详细边界见[架构说明](docs/ARCHITECTURE.md)。 +@dshelm/core policy schema · merge · resolver · Resolution Trace +@dshelm/model-knowledge capability evidence · provenance · confidence +@dshelm/auth provider/account capability discovery +@dshelm/dsh DSH adapter · host service · subagent provider · Web client +@dshelm/compat-omo read-only OmO migration -## 社区与兼容性 +dshelm CLI · init · doctor · auth · explain · uninstall +``` -项目同步维护简体中文和英文文档,并优先把兼容性结论建立在可复现证据上:DSH 版本、DeepSeek/Qwen/本地模型、Linux、macOS、Windows 11 + WSL2,以及密钥、费用、网络和数据位置等边界都应有明确记录。当前计划见[社区版本路线图](docs/community-roadmap.zh-CN.md),桌面方向见[桌面化策略](docs/desktop.zh-CN.md)。 +发布 package graph 由 [`release-packages.json`](release-packages.json) 维护,pack/install verification 由 `pnpm qa:pack-install` 复用。详细架构边界见 [`docs/ARCHITECTURE.md`](docs/ARCHITECTURE.md)。 -使用问题和渠道选择见 [`SUPPORT.md`](SUPPORT.md),贡献流程见 [`CONTRIBUTING.md`](CONTRIBUTING.md),社区参与规范见 [`CODE_OF_CONDUCT.md`](CODE_OF_CONDUCT.md)。中英文 Issue 和 PR 都欢迎。 +## 社区与路线图 -## 与 DSH 社区一起演进 +| Issue | 下一阶段 | +| --- | --- | +| [#7 — npm alpha](https://github.com/Altairpaca/dshelm/issues/7) | 完成 DSH dependency promotion、registry publish、clean-HOME install/uninstall evidence | +| [#8 — platform matrix](https://github.com/Altairpaca/dshelm/issues/8) | Linux、macOS Apple Silicon、Windows 11 + WSL2 可复现验证 | +| [#9 — first-run evidence](https://github.com/Altairpaca/dshelm/issues/9) | deterministic execution fixture 已落地;继续补 provider-backed evidence | +| [#10 — contributor entry points](https://github.com/Altairpaca/dshelm/issues/10) | provider/model evidence、平台验证、文档、routing examples、reproducible bugs | -DSHelm 是 DSH 生态的一部分,不是 DSH 的替代品。项目会优先在官方 Discussion 中讨论公共接口和可复用契约: +DSHelm 优先复用 DSH 的公共接口,并把通用 interface 问题反馈回上游。相关讨论: -- [模型规划与执行切换 #3297](https://github.com/deepseek-ai/deepseek-harness/discussions/3297) -- [DSH 桌面宿主 #3118](https://github.com/deepseek-ai/deepseek-harness/discussions/3118) -- [`dsh doctor` 社区契约 #1719](https://github.com/deepseek-ai/deepseek-harness/discussions/1719) -- [安全的 CLI provider 与 fallback #3283](https://github.com/deepseek-ai/deepseek-harness/discussions/3283) +- [模型规划与执行切换 · deepseek-harness discussion #3297](https://github.com/deepseek-ai/deepseek-harness/discussions/3297) +- [DSH 桌面宿主 · discussion #3118](https://github.com/deepseek-ai/deepseek-harness/discussions/3118) +- [`dsh doctor` 社区契约 · discussion #1719](https://github.com/deepseek-ai/deepseek-harness/discussions/1719) +- [CLI provider 与 fallback · discussion #3283](https://github.com/deepseek-ai/deepseek-harness/discussions/3283) -欢迎提交一个真实任务、一次安装记录、一个路由结果,或 Windows、WSL2、本地模型和 provider 的验证结果。请使用 [GitHub Issues](https://github.com/Altairpaca/dshelm/issues) 报告可复现问题;涉及 DSH 公共能力的讨论会同步回对应的官方 Discussion。 +贡献流程见 [`CONTRIBUTING.md`](CONTRIBUTING.md),使用与支持渠道见 [`SUPPORT.md`](SUPPORT.md),社区规范见 [`CODE_OF_CONDUCT.md`](CODE_OF_CONDUCT.md)。Issue / PR 可以使用英文或简体中文。 ## 安全与事实边界 -- 只有不透明的 `CredentialRef` 会进入策略和 trace;产品自有 secret 仍由产品管理。 -- 无法可靠确认的认证状态会显示为 `unknown`,不会猜测为已登录。 -- 模型软评分是带来源和置信度的维护者启发式,不是模型排行榜。 -- DSHelm 不隶属于 DeepSeek,也不代表文中提到的模型或厂商。 +- 只有不透明 `CredentialRef` 会进入策略和 trace;产品自有 secret 仍由产品管理。 +- 无法可靠确认的认证状态显示为 `unknown`,不会猜测为已登录。 +- 模型软评分是带来源与置信度的维护者启发式,不是模型排行榜。 +- synthetic fixture 只证明 routing / DSH execution contract,不证明外部 provider 的可用性或模型质量。 +- DSHelm 是独立社区项目,不隶属于 DeepSeek,也不代表文中提到的模型或厂商。 Apache License 2.0。 From 883b9c559b012cdddf08673f5b3493a3ad3d2a46 Mon Sep 17 00:00:00 2001 From: Altair Li <137127498+Altairpaca@users.noreply.github.com> Date: Thu, 3 Sep 2026 01:45:08 -0700 Subject: [PATCH 11/24] design(readme): align English landing page with visual compatibility story --- README.en.md | 167 ++++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 133 insertions(+), 34 deletions(-) diff --git a/README.en.md b/README.en.md index cc4bc64..6fcae5e 100644 --- a/README.en.md +++ b/README.en.md @@ -1,49 +1,127 @@ -# DSHelm - -[简体中文](README.md) - -DSHelm is an explainable multi-model routing layer for [DeepSeek Harness](https://github.com/deepseek-ai/deepseek-harness). It keeps model selection, policy overrides, and routing evidence explicit while leaving sessions, tools, workflows, and execution to the DSH ecosystem. +

+ DSHelm — explainable model routing for DeepSeek Harness +

+ +

English · 简体中文

+ +

+ CI + Apache-2.0 + DeepSeek Harness plugin + status alpha +

+ +

+ Overview · + First run · + DSH compatibility · + Source install · + Roadmap +

> [!IMPORTANT] -> DSHelm is currently a `0.3.0-alpha` source preview. npm packages have not been published yet, and the project should not be treated as production-ready. +> DSHelm is a `0.3.0-alpha` **source preview**. The npm packages are not published yet and the project is not production-ready. DeepSeek Harness `0.1.2-rc.1` is currently tracked as the **source target**; it will not be promoted to the verified install baseline until the complete npm package set and clean-profile journey are proven. -## What it provides +

+ DSHelm compatibility status: source preview, verified DSH install baseline, and current DSH source target +

-- **Capability-aware model routing**: apply runtime, authentication, context, and cost constraints before ranking candidates. -- **Resolution Trace**: record the selected role/model/reasoning level, override source, and candidate elimination reasons. -- **DSH-native integration**: use DSH extension surfaces instead of duplicating its session, tool, workflow, or desktop runtime. -- **Explicit user control**: project- and request-level configuration can override DSHelm recommendations. -- **Evidence-backed compatibility**: keep model and platform claims tied to reproducible runtime evidence rather than informal rankings. +## Understand DSHelm in two minutes -## Current status — September 2026 +DSHelm is an **explainable multi-model routing control plane** for [DeepSeek Harness](https://github.com/deepseek-ai/deepseek-harness). It does not replace DSH sessions, tools, workflows, providers, or agent execution. Before execution, it answers three questions: -The current `main` line contains the `0.3.0-alpha` authentication and model-orchestration work, DSH profile installation, `doctor` / `explain`, Resolution Trace, the Web control plane, and read-only OmO migration support. +1. **Which role / provider / model should handle this step?** +2. **Which runtime, authentication, context, or cost constraints eliminated alternatives?** +3. **Did the final choice come from defaults, a user/project override, or the current request?** -The next public milestones are tracked as community issues: +

+ DSHelm routing flow from task requirements through hard gates, evidence, policy overrides, DSH execution and Resolution Trace +

-| Issue | Goal | +| DSHelm owns | DeepSeek Harness owns | | --- | --- | -| [#7 — npm alpha](https://github.com/Altairpaca/dshelm/issues/7) | Publish a verifiable public alpha and capture clean-HOME install/uninstall evidence | -| [#8 — platform evidence matrix](https://github.com/Altairpaca/dshelm/issues/8) | Collect reproducible Linux, macOS Apple Silicon, and Windows 11 + WSL2 installation reports | -| [#9 — first-run example](https://github.com/Altairpaca/dshelm/issues/9) | Ship a credential-light planner → workers → reviewer example with an observable trace | -| [#10 — contributor entry points](https://github.com/Altairpaca/dshelm/issues/10) | Define contribution paths for provider/model evidence, platform verification, docs, examples, and reproducible bugs | +| policy, routing, capability evidence | agent lifecycle, sessions, tool execution | +| provider/model/reasoning selection | provider adapters and real model calls | +| user/project/request overrides | profile/plugin composition | +| Resolution Trace and selection explanation | host, Web, Headless, SDK execution surfaces | + +**Planner, worker, and reviewer roles can use different models while every decision remains inspectable.** + +### Real control plane -The project remains a **source preview** until those release and verification gates are actually satisfied. +

+ DSHelm Web control plane showing Roles × Models and Resolution Trace +

-### Inspect routing and execution before configuring a provider +## Credential-free first run -Two credential-free fixtures make the evidence boundary explicit: +The repository keeps two deterministic fixtures separate because they prove different layers: ```bash pnpm example:first-run pnpm example:dsh-execution ``` -`example:first-run` validates the **routing and explanation contract only**. `example:dsh-execution` goes one layer further: it uses the real DSH Context, agent factory and AgentLoop for planner → two bounded workers → reviewer, while keeping model responses deterministic through a synthetic provider. It therefore proves that resolved routes reach actual DSH requests without claiming external-provider connectivity or model quality. See [`examples/README.md`](examples/README.md) for the exact scope and output. +| Command | What is real | What it deliberately does not prove | +| --- | --- | --- | +| `example:first-run` | DSHelm Core resolver + Resolution Trace | no DSH agent execution, no provider call | +| `example:dsh-execution` | real DSH `Context` + `AgentRegistry` + `AgentLoop`; planner → bounded workers → reviewer; actual request routes captured | synthetic LLM adapter, so no external network/OAuth/model-quality claim | + +The execution fixture compares the routes received by the actual DSH adapter with the DSHelm resolutions one by one. It therefore proves that **DSHelm routing decisions reach the real DSH request path**. See [`examples/README.md`](examples/README.md) for the output contract and evidence boundary. + +
+Why keep two fixtures? + +Resolver and execution contracts are different failure domains. Keeping them separate makes routing regressions cheap to isolate while still providing a real DSH integration proof without requiring an API key. + +
+ +## Current capabilities + +| Capability | Status | Evidence today | +| --- | --- | --- | +| DSH-native profile / bundle | Alpha | isolated `dshelm` profile, `@dshelm/dsh` bundle, clean-profile journey | +| Multi-model routing | Alpha | hard gates, evidence scoring, policy overrides | +| Resolution Trace | Alpha | candidate outcomes, field provenance, selected route | +| Account/auth discovery | Alpha | API keys, provider OAuth, selected product login state; product credentials are not copied | +| Web control plane | Alpha | Roles × Models and latest routing explanation | +| planner → workers → reviewer | Alpha | deterministic real-DSH execution fixture | +| OmO migration | Preview | read-only SUPPORTED / MAPPED / LOSSY / UNSUPPORTED report | +| npm install | Release gate | unpublished; tracked in [#7](https://github.com/Altairpaca/dshelm/issues/7) | +| Cross-platform verification | Community evidence | Linux, macOS Apple Silicon, Windows 11 + WSL2 reports in progress | + +## DeepSeek Harness compatibility + +### Current state + +DSHelm deliberately separates a verified install baseline from the newest upstream source target: + +- **Verified install baseline — `0.1.0-rc.7`**: package/runtime, clean HOME, profile composition, bounded boot, doctor/explain/uninstall have been exercised. +- **Current source target — `0.1.2-rc.1`**: the latest DeepSeek Harness source release published on **September 3, 2026**. Forward-compatible bridges for confirmed API changes are now in DSHelm, while npm-package promotion and clean-profile verification remain pending. + +The machine-readable status lives in [`compatibility.json`](compatibility.json). The current upstream target is [`dsh-v0.1.2-rc.1`](https://github.com/deepseek-ai/deepseek-harness/releases/tag/dsh-v0.1.2-rc.1). + +### 0.1.2 changes already bridged + +| Upstream change | DSHelm handling | +| --- | --- | +| `Session.events` replaced by `seq` / `eventAt()` / `snapshotEvents()` | session-log bridge prefers `snapshotEvents()` and falls back to legacy `events` | +| `SubagentCapabilities` adds the `agentOptions` gate | DSHelm provider advertises `agentOptions: true` at runtime while remaining compilable against the legacy type surface | +| `AgentOptions` adds `reasoningEffort` | current hosts receive the reasoning option directly; legacy hosts retain the `request/header` seed path | +| callers may specify provider/model/reasoning/max output for subagents | DSHelm maps policy resolution onto the official `agentOptions` seam; max-output policy is not claimed yet | + +The package manifests are intentionally **not** force-bumped to `0.1.2-rc.1` in this step. Upstream npm publication is rolling on September 3, and the DSHelm lockfile still represents the verified legacy baseline. Promotion must happen together with complete package availability, lockfile regeneration, and a fresh install/profile boot. + +
+Why not claim generic “0.1.x support”? + +DSH prerelease session, subagent, client, and profile seams are still moving. DSHelm records compatibility per seam and per piece of evidence so a semver range does not imply a runtime guarantee that has not been measured. The exact release gate is documented in [`docs/RELEASING.md`](docs/RELEASING.md). + +
## Source preview -Requirements: Node.js `>=22.19.0`, pnpm `11.7.0`, and a DSH CLI available on `PATH`. See [`compatibility.json`](compatibility.json) for the currently verified stack. +Requirements: Node.js `>=22.19.0`, pnpm `11.7.0`, and a DSH CLI matching the verified baseline. Check [`compatibility.json`](compatibility.json) before trying a newer DSH train. ```bash git clone https://github.com/Altairpaca/dshelm.git @@ -53,7 +131,7 @@ pnpm install --frozen-lockfile pnpm preview:init ``` -Then inspect the installed profile and routing state: +`preview:init` builds the workspace and installs the source preview under `$DSH_HOME/profiles/dshelm`. It does not log into providers or copy Codex, Claude, or other product-owned credentials. ```bash dsh --profile dshelm --dump-config @@ -63,26 +141,47 @@ node packages/cli/dist/index.js explain deepseek/deepseek-v4-flash dsh --profile dshelm ``` -The source-preview installer does not copy Codex, Claude, or other product-owned credentials into DSHelm. Uninstall removes DSHelm-owned discovery/profile state while preserving credentials by default: +Uninstall preserves credentials by default: ```bash node packages/cli/dist/index.js uninstall --yes ``` -The intended post-publication entry point is `npx dshelm init --yes`; it is deliberately not presented as a runnable installation command until the npm release exists. +The intended post-publication entry point is `npx dshelm init --yes`; it remains documentation-only until registry artifacts and clean-install evidence exist. -## Architecture and community +## Workspace map ```text -task requirements → runtime/auth hard constraints → model capability evidence → user/project/request overrides → DSH execution + Resolution Trace +@dshelm/core policy schema · merge · resolver · Resolution Trace +@dshelm/model-knowledge capability evidence · provenance · confidence +@dshelm/auth provider/account capability discovery +@dshelm/dsh DSH adapter · host service · subagent provider · Web client +@dshelm/compat-omo read-only OmO migration + +dshelm CLI · init · doctor · auth · explain · uninstall ``` -DSHelm Core owns policy, configuration, routing, and explanation. DSH and its plugins remain responsible for task execution. See [`docs/ARCHITECTURE.md`](docs/ARCHITECTURE.md) for the boundary. +[`release-packages.json`](release-packages.json) owns the publishable package graph and `pnpm qa:pack-install` owns the reusable packed-install journey. See [`docs/ARCHITECTURE.md`](docs/ARCHITECTURE.md) for the full boundary. + +## Community roadmap + +| Issue | Next step | +| --- | --- | +| [#7 — npm alpha](https://github.com/Altairpaca/dshelm/issues/7) | DSH dependency promotion, registry publish, clean-HOME install/uninstall evidence | +| [#8 — platform matrix](https://github.com/Altairpaca/dshelm/issues/8) | reproducible Linux, macOS Apple Silicon, Windows 11 + WSL2 verification | +| [#9 — first-run evidence](https://github.com/Altairpaca/dshelm/issues/9) | deterministic execution fixture landed; add provider-backed evidence | +| [#10 — contributor entry points](https://github.com/Altairpaca/dshelm/issues/10) | provider/model evidence, platform verification, docs, routing examples, reproducible bugs | + +DSHelm prefers upstream public contracts over parallel undocumented APIs. Relevant DeepSeek Harness discussions include [model planning/execution #3297](https://github.com/deepseek-ai/deepseek-harness/discussions/3297), [desktop host #3118](https://github.com/deepseek-ai/deepseek-harness/discussions/3118), [`dsh doctor` #1719](https://github.com/deepseek-ai/deepseek-harness/discussions/1719), and [CLI provider/fallback #3283](https://github.com/deepseek-ai/deepseek-harness/discussions/3283). -Compatibility work is tracked through reproducible evidence across DSH versions, providers/models, Linux, macOS, Windows 11 + WSL2, and credential/network/data-location boundaries. Public DSH interface questions should be discussed against the corresponding upstream contract rather than maintained as a parallel undocumented API. +For contribution workflow, see [`CONTRIBUTING.md`](CONTRIBUTING.md); for support channels, [`SUPPORT.md`](SUPPORT.md); for participation expectations, [`CODE_OF_CONDUCT.md`](CODE_OF_CONDUCT.md). Issues and pull requests are welcome in English or Simplified Chinese. -For contribution workflow, use [`CONTRIBUTING.md`](CONTRIBUTING.md). For usage questions and channel selection, use [`SUPPORT.md`](SUPPORT.md). Community participation is covered by [`CODE_OF_CONDUCT.md`](CODE_OF_CONDUCT.md). Issues and pull requests are welcome in English or Simplified Chinese. +## Security and evidence boundaries -DSHelm is an independent project. It is not affiliated with or endorsed by DeepSeek or by any model/provider mentioned in the repository. +- Only opaque `CredentialRef` values enter policy and traces; product-owned secrets remain product-owned. +- Authentication state that cannot be confirmed is reported as `unknown`, never guessed as logged in. +- Soft model scores are maintainer heuristics with provenance and confidence, not a model leaderboard. +- Synthetic fixtures prove routing/execution contracts, not external-provider availability or model quality. +- DSHelm is an independent community project and is not affiliated with or endorsed by DeepSeek or any model/provider named in the repository. Apache License 2.0. From 882d3290f5aa110757839a5961e5c6da2d600a57 Mon Sep 17 00:00:00 2001 From: Altair Li <137127498+Altairpaca@users.noreply.github.com> Date: Thu, 3 Sep 2026 01:45:48 -0700 Subject: [PATCH 12/24] docs(compat): record DSH 0.1.2-rc.1 seam audit --- docs/compatibility/dsh-0.1.2-rc.1.md | 85 ++++++++++++++++++++++++++++ 1 file changed, 85 insertions(+) create mode 100644 docs/compatibility/dsh-0.1.2-rc.1.md diff --git a/docs/compatibility/dsh-0.1.2-rc.1.md b/docs/compatibility/dsh-0.1.2-rc.1.md new file mode 100644 index 0000000..34a5cab --- /dev/null +++ b/docs/compatibility/dsh-0.1.2-rc.1.md @@ -0,0 +1,85 @@ +# DeepSeek Harness 0.1.2-rc.1 compatibility audit + +Status: **source target — not yet promoted to the verified install baseline** + +Upstream release: [`dsh-v0.1.2-rc.1`](https://github.com/deepseek-ai/deepseek-harness/releases/tag/dsh-v0.1.2-rc.1) +Source commit: `a66e4702047846cdaa10c66c9d3df3951f5ea70d` +Release date: 2026-09-03 + +DSHelm's currently verified npm/install baseline remains `0.1.0-rc.7`. This document records the source-level audit used to prepare the next promotion. A source audit is evidence about API shape; it is not a substitute for a fresh npm install, profile composition, boot, and execution journey. + +## Promotion rule + +A DSH release becomes DSHelm's `tested.dshPackages` baseline only when all of the following hold together: + +- the required DSH npm packages exist at the exact candidate version; +- DSHelm manifests and `pnpm-lock.yaml` are regenerated coherently; +- workspace typecheck/build/tests pass against the candidate package graph; +- packed DSHelm packages install into a fresh project; +- an isolated `HOME` / `DSH_HOME` profile composes and boots; +- `doctor`, `explain`, first-run routing, real-DSH execution fixture, and uninstall remain valid; +- Web/client bundle seams used by `@dshelm/dsh` are available at the same candidate line. + +Do not promote only the version strings. + +## Audited seams + +| Seam | 0.1.0-rc.7 baseline | 0.1.2-rc.1 source | DSHelm action | State | +| --- | --- | --- | --- | --- | +| Session log reads | `session.events` immutable snapshot getter | `seq`, `eventAt()`, `snapshotEvents()`; direct `events` removed | `snapshotSessionLog()` prefers `snapshotEvents()` and falls back to `events` | bridged | +| Subagent capability gate | no `agentOptions` flag | `SubagentCapabilities.agentOptions` required | advertise `agentOptions: true` structurally at runtime | bridged | +| Agent model options | provider/model/maxTokens | provider/model/`reasoningEffort`/maxTokens | map DSHelm reasoning into AgentOptions on current hosts | bridged | +| Legacy reasoning transport | `request/header` seed restores reasoning | current AgentOptions can carry reasoning directly | retain seed as legacy fallback while direct option is present | bridged | +| Subagent selection | provider-specific start behavior | caller-authorized provider/model/reasoning/max-output selection is first-class | continue resolving policy first, then map the resolved route onto the official seam | audited; max-output policy deferred | +| Session persistence | external persistence plugins available | optional SQLite Session persistence backend removed | DSHelm owns no Session persistence backend | no direct impact | +| Profile execution | DSH profiles already used | product entry modes converge on DSH profiles | DSHelm profile/bundle architecture aligns with upstream direction | aligned | +| Remote API | legacy APIProxy still existed in earlier trains | old APIProxy removed after RPC unification | DSHelm does not depend on APIProxy | no direct impact | +| Provider login UI | no plugin model-settings login extension in baseline | plugins can add provider sign-in controls to Models settings | candidate future integration for DSHelm auth discovery; no support claim yet | opportunity | +| Continuable subagents | existing continuation seam | parent/continuable child can exchange later `send_message` traffic | current DSHelm reference slice remains bounded one-shot; evaluate separately | deferred | + +## Code changes in this compatibility pass + +### Session log bridge + +`packages/dsh/src/session-log-compat.ts` uses a structural compatibility face rather than importing one generation-specific Session shape: + +```text +0.1.2 host → snapshotEvents() → stable event snapshot +legacy host → events → stable event snapshot +unknown API → fail loud +``` + +`runRoleAgent()` now consumes this bridge when finding the final assistant message. + +### Subagent model-option bridge + +The DSHelm subagent provider now exposes an `agentOptions` capability at runtime. When policy resolves a reasoning effort, the mapped AgentOptions object includes `reasoningEffort` for current hosts. The `request/header` seed remains in place for the verified legacy line. + +This is intentionally redundant during the transition: both paths carry the same resolved route, which prevents a compatibility window from silently dropping reasoning configuration. + +## Evidence still missing before promotion + +The following are intentionally **not** claimed by this source audit: + +- successful installation of the entire `0.1.2-rc.1` npm dependency graph; +- absence of peer-dependency conflicts across DSH client/session/subagent packages; +- successful `@dshelm/dsh` Web client loading on the new package graph; +- clean-profile boot on the new exact package set; +- external-provider authentication or live model quality; +- Linux/macOS/WSL2 parity on the new train. + +These belong to the release and platform evidence gates, primarily issues [#7](https://github.com/Altairpaca/dshelm/issues/7) and [#8](https://github.com/Altairpaca/dshelm/issues/8). + +## Maintainer checklist for the next DSH release + +For later DSH trains, repeat the same sequence: + +1. read the upstream release notes and exact source tag; +2. diff every DSH package imported by `@dshelm/dsh`; +3. identify removed/added public seams before touching versions; +4. implement backward/forward bridges only where they preserve one semantic contract; +5. record source-target evidence separately from install evidence; +6. wait for the full npm package graph; +7. regenerate manifests/lockfile together; +8. run clean packed-install/profile evidence; +9. only then update `tested` and README compatibility claims. From 6b68ea0738ef24331db85cfb173d9ebe4c8b70ec Mon Sep 17 00:00:00 2001 From: Altair Li <137127498+Altairpaca@users.noreply.github.com> Date: Thu, 3 Sep 2026 01:47:32 -0700 Subject: [PATCH 13/24] docs(changelog): record DSH 0.1.2 compatibility and README redesign --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4ca096f..cefcabf 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,6 +14,8 @@ DSHelm is still in alpha. Entries before the first public npm publication are ** - Added a CI gate for publishable package metadata and reduced duplicate/stale branch runs. - Kept `dshelm init`'s default `@dshelm/dsh` bundle version aligned with the installed CLI package version. - Added a machine-readable publishable package graph and version-independent pack/install verification, removing release-version literals from CI and reading the verified DSH package baseline from `compatibility.json`. +- Audited DeepSeek Harness `0.1.2-rc.1` as the current source target and added forward-compatible bridges for the new Session snapshot API plus subagent `agentOptions` / `reasoningEffort` semantics, while keeping `0.1.0-rc.7` as the verified install baseline until the full npm graph and clean-profile journey pass. +- Rebuilt the bilingual README landing experience around a visual routing flow, explicit compatibility/evidence cards, a real control-plane screenshot, and clearer separation between demonstrated contracts and unverified provider/runtime claims. ## 0.3.0-alpha.0 — 2026-08-19 — source milestone From 9a167340394a220ff1370b8f548e404977da6282 Mon Sep 17 00:00:00 2001 From: Altair Li <137127498+Altairpaca@users.noreply.github.com> Date: Thu, 3 Sep 2026 01:50:30 -0700 Subject: [PATCH 14/24] feat(client): decouple control plane source from removed DSH client runtime package --- packages/dsh/src/client-rt/index.tsx | 75 ++++++++++++++++++---------- 1 file changed, 50 insertions(+), 25 deletions(-) diff --git a/packages/dsh/src/client-rt/index.tsx b/packages/dsh/src/client-rt/index.tsx index 4d57983..3e87681 100644 --- a/packages/dsh/src/client-rt/index.tsx +++ b/packages/dsh/src/client-rt/index.tsx @@ -1,52 +1,77 @@ /** - * DSHelm control-plane panel — REAL DSH client plugin (browser half). + * DSHelm control-plane panel — DSH client plugin (browser half). * * Consumes the canonical host projection (dshelm.controlPlane) through the - * official client runtime: the current session's projection store - * (sessions.binding(id).session.projections.faceOf(key) — the useProjection - * resolution path). No second UI-only explanation model exists: the value IS - * the canonical ResolutionTrace-derived snapshot. + * current session projection face (`sessions.binding(id).session.projections`). + * No second UI-only explanation model exists: the value IS the canonical + * ResolutionTrace-derived snapshot. * - * v0.2 surface: a body-mounted panel (the AgentTeams-validated pattern for - * surfaces without a native slot seat). Conversation-slot integration is a - * documented next increment. + * Compatibility note: DSH 0.1.2 replaces the old `dsh-client-runtime` package + * with the client module system and package-owned API/UI client extensions. + * This plugin therefore types only the small structural session face it uses; + * the package-manifest dependency/inject migration is promoted together with + * the 0.1.2 npm graph and lockfile, never as a source-only version bump. */ import { useEffect, useState, type ReactNode } from 'react' import { createRoot } from 'react-dom/client' -import type { ClientContext, SessionId } from '@deepseek-ai/dsh-client-runtime/client' import type { ControlPlaneProjectionValue } from '../session-events.ts' -/** Required services: the sessions domain (list + bindings). */ +/** Required service: the client session domain. */ export const inject = ['sessions'] as const +type ClientSessionId = string + type ProjectionFace = { getSnapshot(): unknown subscribe(fn: () => void): () => void } -function useControlPlane(sessions: ClientContext['sessions']): ControlPlaneProjectionValue | undefined { +type ClientSessionsFace = { + readonly list: { + getSnapshot(): { readonly current?: ClientSessionId } + subscribe(fn: () => void): () => void + } + binding(id: ClientSessionId): { + readonly session: { + readonly projections: { + faceOf(key: string): ProjectionFace | undefined + } + } + } | undefined +} + +export interface DSHelmWebClientContext { + readonly sessions: ClientSessionsFace + effect(cleanup: () => (() => void) | void, label?: string): void +} + +function useControlPlane(sessions: ClientSessionsFace): ControlPlaneProjectionValue | undefined { const [value, setValue] = useState(undefined) useEffect(() => { - let face: ProjectionFace | undefined - let unsubscribeList: (() => void) | undefined + let unsubscribeProjection: (() => void) | undefined + const rebind = (): void => { - const current: SessionId | undefined = sessions.list.getSnapshot().current + unsubscribeProjection?.() + unsubscribeProjection = undefined + + const current = sessions.list.getSnapshot().current const binding = current === undefined ? undefined : sessions.binding(current) const next = binding?.session.projections.faceOf('dshelm.controlPlane') - if (next !== undefined) { - face = next - const sync = (): void => setValue(next.getSnapshot() as ControlPlaneProjectionValue | undefined) - sync() - next.subscribe(sync) - } else { - face = undefined + if (next === undefined) { setValue(undefined) + return } + + const sync = (): void => setValue(next.getSnapshot() as ControlPlaneProjectionValue | undefined) + sync() + unsubscribeProjection = next.subscribe(sync) } + rebind() - unsubscribeList = sessions.list.subscribe(rebind) + const unsubscribeList = sessions.list.subscribe(rebind) return () => { - unsubscribeList?.() + unsubscribeProjection?.() + unsubscribeList() } }, [sessions]) return value @@ -159,7 +184,7 @@ function Inspector({ snapshot, copy }: { snapshot: ControlPlaneProjectionValue; ) } -function ControlPlanePanel({ sessions }: { sessions: ClientContext['sessions'] }): ReactNode { +function ControlPlanePanel({ sessions }: { sessions: ClientSessionsFace }): ReactNode { const snapshot = useControlPlane(sessions) const copy = labels() return ( @@ -177,7 +202,7 @@ function ControlPlanePanel({ sessions }: { sessions: ClientContext['sessions'] } ) } -export function apply(ctx: ClientContext): void { +export function apply(ctx: DSHelmWebClientContext): void { const host = document.createElement('aside') document.body.appendChild(host) const root = createRoot(host) From 0a0565c8bea07e314c15e4dffe13e389f4c57c5e Mon Sep 17 00:00:00 2001 From: Altair Li <137127498+Altairpaca@users.noreply.github.com> Date: Thu, 3 Sep 2026 01:50:56 -0700 Subject: [PATCH 15/24] docs(compat): record 0.1.2 client-module migration blocker --- compatibility.json | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/compatibility.json b/compatibility.json index 7520f74..f842006 100644 --- a/compatibility.json +++ b/compatibility.json @@ -17,11 +17,19 @@ "releaseTag": "dsh-v0.1.2-rc.1", "sourceCommit": "a66e4702047846cdaa10c66c9d3df3951f5ea70d", "releaseDate": "2026-09-03", - "status": "forward-compatible source bridges implemented; promotion to tested awaits complete npm publication plus clean-profile verification", + "status": "core/session/subagent source bridges implemented and browser source decoupled from removed dsh-client-runtime; package-manifest client-module migration plus complete npm/clean-profile verification remain before promotion", "auditedSeams": [ "Session.snapshotEvents() replacing Session.events", "SubagentCapabilities.agentOptions", - "AgentOptions.reasoningEffort" + "AgentOptions.reasoningEffort", + "@deepseek-ai/dsh-client-modules replacing the legacy dsh-client-runtime bootstrap package", + "package-owned dsh.client browser module graph" + ], + "promotionBlockers": [ + "the complete 0.1.2-rc.1 npm package graph must be available", + "@dshelm/dsh package.json still depends on and injects @deepseek-ai/dsh-client-runtime from the verified legacy baseline", + "the 0.1.2 client package graph must replace the legacy runtime dependency/inject coherently with pnpm-lock.yaml", + "fresh packed install, isolated profile boot, Web client bundle loading, doctor/explain/fixtures/uninstall must pass" ] }, "seams": { @@ -53,6 +61,11 @@ "ProjectionDefinition", "SessionProjectionMap augmentation" ], + "client": [ + "browser source consumes a structural sessions.binding(...).session.projections face", + "0.1.2 source uses @deepseek-ai/dsh-client-modules for browser plugin boot/composition", + "legacy @deepseek-ai/dsh-client-runtime dependency/inject remains only in the verified package graph until lockfile promotion" + ], "settings": [ "installSettingsSection(ctx, ns, schema, entry, hooks)", "settingsNamespace" @@ -62,7 +75,7 @@ "The verified npm/install baseline remains 0.1.0-rc.7 until the 0.1.2-rc.1 package set is fully published and the clean profile journey passes.", "DSH 0.1.2 removes direct Session.events reads in favor of seq/eventAt()/snapshotEvents(); DSHelm now prefers snapshotEvents() and falls back to the legacy getter.", "DSH 0.1.2 adds the SubagentCapabilities.agentOptions gate and AgentOptions.reasoningEffort; DSHelm advertises the capability at runtime while retaining the request/header seed for legacy hosts.", - "dsh-client-runtime@0.1.0-rc.7 is browser-only and requires the DSH Web shell.", + "DSH 0.1.2 source removes the old packages/client/runtime package and introduces @deepseek-ai/dsh-client-modules as the browser module/boot system. DSHelm browser source no longer imports dsh-client-runtime/client, but package metadata migration is intentionally deferred to the exact-version + lockfile promotion step.", "public CLI tarball is named dshelm; workspace @dshelm packages are packed together for closure verification.", "clean journey uses an isolated HOME/DSH_HOME and verifies init, dump-config, bounded boot, doctor, explain, and uninstall.", "native auth descriptors are version-gated evidence snapshots: Codex 0.147.0 and Claude Code 2.1.234; Gemini and Qwen shell login/logout are unsupported." From dbfb934ef7f7804ffebb0f5720c806880bcef123 Mon Sep 17 00:00:00 2001 From: Altair Li <137127498+Altairpaca@users.noreply.github.com> Date: Thu, 3 Sep 2026 01:51:35 -0700 Subject: [PATCH 16/24] docs(compat): add 0.1.2 client-module migration audit --- docs/compatibility/dsh-0.1.2-rc.1.md | 60 +++++++++++++++++++++++----- 1 file changed, 50 insertions(+), 10 deletions(-) diff --git a/docs/compatibility/dsh-0.1.2-rc.1.md b/docs/compatibility/dsh-0.1.2-rc.1.md index 34a5cab..639da29 100644 --- a/docs/compatibility/dsh-0.1.2-rc.1.md +++ b/docs/compatibility/dsh-0.1.2-rc.1.md @@ -6,7 +6,7 @@ Upstream release: [`dsh-v0.1.2-rc.1`](https://github.com/deepseek-ai/deepseek-ha Source commit: `a66e4702047846cdaa10c66c9d3df3951f5ea70d` Release date: 2026-09-03 -DSHelm's currently verified npm/install baseline remains `0.1.0-rc.7`. This document records the source-level audit used to prepare the next promotion. A source audit is evidence about API shape; it is not a substitute for a fresh npm install, profile composition, boot, and execution journey. +DSHelm's currently verified npm/install baseline remains `0.1.0-rc.7`. This document records the source-level audit used to prepare the next promotion. A source audit is evidence about API shape; it is not a substitute for a fresh npm install, profile composition, boot, Web-client load, and execution journey. ## Promotion rule @@ -17,6 +17,7 @@ A DSH release becomes DSHelm's `tested.dshPackages` baseline only when all of th - workspace typecheck/build/tests pass against the candidate package graph; - packed DSHelm packages install into a fresh project; - an isolated `HOME` / `DSH_HOME` profile composes and boots; +- the `@dshelm/dsh` browser bundle is discovered and materialized by the candidate client-module graph; - `doctor`, `explain`, first-run routing, real-DSH execution fixture, and uninstall remain valid; - Web/client bundle seams used by `@dshelm/dsh` are available at the same candidate line. @@ -31,6 +32,9 @@ Do not promote only the version strings. | Agent model options | provider/model/maxTokens | provider/model/`reasoningEffort`/maxTokens | map DSHelm reasoning into AgentOptions on current hosts | bridged | | Legacy reasoning transport | `request/header` seed restores reasoning | current AgentOptions can carry reasoning directly | retain seed as legacy fallback while direct option is present | bridged | | Subagent selection | provider-specific start behavior | caller-authorized provider/model/reasoning/max-output selection is first-class | continue resolving policy first, then map the resolved route onto the official seam | audited; max-output policy deferred | +| Browser client boot | `@deepseek-ai/dsh-client-runtime` supplied the browser runtime/types used by DSHelm | old `packages/client/runtime` is absent; `@deepseek-ai/dsh-client-modules@0.1.2-rc.1` owns `dsh.client` scanning, boot graph and plugin bundle delivery | remove browser-source type dependency on `dsh-client-runtime/client`; keep manifest migration for the exact package+lockfile promotion | source bridged; package graph blocked | +| Client session projection | DSHelm typed `ClientContext['sessions']` through the legacy runtime package | current official plugins use package-owned client extensions around `sessions.binding(id).session.projections.faceOf(...)` | type only the minimal structural sessions/projection face DSHelm actually consumes | bridged | +| Client plugin declaration | legacy package metadata injects runtime/UI packages | current module system scans package `dsh.client`, serves `./client`, and resolves client dependencies from the composed graph | retain verified metadata until candidate graph is available; migrate dependency/inject set with lockfile | pending promotion | | Session persistence | external persistence plugins available | optional SQLite Session persistence backend removed | DSHelm owns no Session persistence backend | no direct impact | | Profile execution | DSH profiles already used | product entry modes converge on DSH profiles | DSHelm profile/bundle architecture aligns with upstream direction | aligned | | Remote API | legacy APIProxy still existed in earlier trains | old APIProxy removed after RPC unification | DSHelm does not depend on APIProxy | no direct impact | @@ -57,13 +61,48 @@ The DSHelm subagent provider now exposes an `agentOptions` capability at runtime This is intentionally redundant during the transition: both paths carry the same resolved route, which prevents a compatibility window from silently dropping reasoning configuration. +### Browser client source bridge + +The previous browser entry imported `ClientContext` and `SessionId` from `@deepseek-ai/dsh-client-runtime/client`. The 0.1.2 source tree no longer contains the old client-runtime package; the new `@deepseek-ai/dsh-client-modules` package owns web plugin discovery, the `__DSH_BOOT__` graph, `/plugins` bundle delivery, and lazy module materialization. + +DSHelm's control-plane client does not need that removed package to express its own behavior. It now defines the narrow face it consumes: + +```text +sessions.list.current +sessions.binding(sessionId) + → session.projections.faceOf('dshelm.controlPlane') + → getSnapshot() / subscribe() +``` + +The refactor also owns and disposes the projection subscription when the current session changes; the previous implementation subscribed to each projection without retaining its cleanup. + +This is only the **source** half of the migration. `packages/dsh/package.json` still depends on and injects the legacy `@deepseek-ai/dsh-client-runtime@0.1.0-rc.7`, because changing that package graph without regenerating `pnpm-lock.yaml` would invalidate the verified install baseline. The manifest must move to the 0.1.2 client-module/API composition in the exact-version promotion PR. + +## Known promotion blocker: client package graph + +The source audit confirms the client architecture changed materially, not just by version number: + +```text +0.1.0-rc.7 + @deepseek-ai/dsh-client-runtime + ↓ +0.1.2-rc.1 + @deepseek-ai/dsh-client-modules + + package-owned API / UI client extensions +``` + +Official 0.1.2 plugins still use `dsh.client.inject` for service/plugin composition, while `@deepseek-ai/dsh-client-modules` owns discovery and loading. For DSHelm, the promotion must determine the minimal current inject set for the body-mounted control plane (at least the session-controller/provider of the `sessions` service) rather than mechanically replacing one package name with another. + +That migration belongs with the candidate npm graph and a real Web bundle-load assertion. + ## Evidence still missing before promotion The following are intentionally **not** claimed by this source audit: - successful installation of the entire `0.1.2-rc.1` npm dependency graph; - absence of peer-dependency conflicts across DSH client/session/subagent packages; -- successful `@dshelm/dsh` Web client loading on the new package graph; +- the final 0.1.2 `dsh.client.inject` set for `@dshelm/dsh`; +- successful `@dshelm/dsh` Web client discovery/materialization on the new module system; - clean-profile boot on the new exact package set; - external-provider authentication or live model quality; - Linux/macOS/WSL2 parity on the new train. @@ -75,11 +114,12 @@ These belong to the release and platform evidence gates, primarily issues [#7](h For later DSH trains, repeat the same sequence: 1. read the upstream release notes and exact source tag; -2. diff every DSH package imported by `@dshelm/dsh`; -3. identify removed/added public seams before touching versions; -4. implement backward/forward bridges only where they preserve one semantic contract; -5. record source-target evidence separately from install evidence; -6. wait for the full npm package graph; -7. regenerate manifests/lockfile together; -8. run clean packed-install/profile evidence; -9. only then update `tested` and README compatibility claims. +2. diff every DSH package imported or injected by `@dshelm/dsh`; +3. inspect the browser `dsh.client` graph separately from Node/runtime imports; +4. identify removed/added public seams before touching versions; +5. implement backward/forward bridges only where they preserve one semantic contract; +6. record source-target evidence separately from install evidence; +7. wait for the full npm package graph; +8. regenerate manifests/lockfile together; +9. run clean packed-install/profile/Web-client evidence; +10. only then update `tested` and README compatibility claims. From 3e752f39b550b88af0a2658678840d240d77f1d0 Mon Sep 17 00:00:00 2001 From: Altair Li <137127498+Altairpaca@users.noreply.github.com> Date: Thu, 3 Sep 2026 01:51:59 -0700 Subject: [PATCH 17/24] design(readme): show 0.1.2 client-graph promotion blocker --- docs/assets/compatibility-status.svg | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/assets/compatibility-status.svg b/docs/assets/compatibility-status.svg index 1865849..6323700 100644 --- a/docs/assets/compatibility-status.svg +++ b/docs/assets/compatibility-status.svg @@ -1,6 +1,6 @@ DSHelm compatibility status - Three cards show the DSHelm source release, the verified DeepSeek Harness install baseline, and the current DeepSeek Harness source target. + Three cards show the DSHelm source release, the verified DeepSeek Harness install baseline, and the current DeepSeek Harness source target with its remaining client-package promotion gate. @@ -10,7 +10,7 @@ Compatibility is evidence, not a version badge - Source target and verified install baseline stay separate until the full npm/profile journey passes. + Source target and verified install baseline stay separate until the full npm, client-module and profile journey passes. @@ -37,9 +37,9 @@ SOURCE TARGET DSH 0.1.2-rc.1 - session + subagent bridges landed + core + browser source bridges landed - npm promotion / clean-profile verification pending + client package graph + clean-profile promotion pending From baade0b8493af6d81a80fad18c1fb9bc1b48b110 Mon Sep 17 00:00:00 2001 From: Altair Li <137127498+Altairpaca@users.noreply.github.com> Date: Thu, 3 Sep 2026 01:52:28 -0700 Subject: [PATCH 18/24] ci(docs): protect README visual and compatibility contracts --- scripts/check-community-docs.mjs | 30 ++++++++++++++++++++++++++---- 1 file changed, 26 insertions(+), 4 deletions(-) diff --git a/scripts/check-community-docs.mjs b/scripts/check-community-docs.mjs index 2fac10d..0f39dca 100644 --- a/scripts/check-community-docs.mjs +++ b/scripts/check-community-docs.mjs @@ -11,6 +11,7 @@ const documents = [ 'docs/RELEASING.md', 'docs/community-roadmap.zh-CN.md', 'docs/desktop.zh-CN.md', + 'docs/compatibility/dsh-0.1.2-rc.1.md', ] const failures = [] @@ -25,15 +26,36 @@ for (const document of documents) { if (link.startsWith('http:') || link.startsWith('https:') || link.startsWith('mailto:')) continue if (!existsSync(resolve(dirname(document), link))) failures.push(`${document}: missing local target ${link}`) } + if (/Chinese-first/i.test(content)) { + failures.push(`${document}: region-priority project positioning is not allowed`) + } } const readme = readFileSync('README.md', 'utf8') -for (const required of ['docs/assets/banner.svg', 'docs/assets/control-plane.png', 'pnpm preview:init', 'npm 包尚未发布', 'deepseek-ai/deepseek-harness/discussions']) { +const englishReadme = readFileSync('README.en.md', 'utf8') +const landingAssets = [ + 'docs/assets/banner.svg', + 'docs/assets/compatibility-status.svg', + 'docs/assets/routing-flow.svg', + 'docs/assets/control-plane.png', +] +for (const asset of landingAssets) { + if (!readme.includes(asset)) failures.push(`README.md: missing landing-page visual ${asset}`) + if (!englishReadme.includes(asset)) failures.push(`README.en.md: missing landing-page visual ${asset}`) +} + +for (const required of ['pnpm preview:init', 'npm 包尚未发布', 'deepseek-ai/deepseek-harness/discussions', '0.1.0-rc.7', '0.1.2-rc.1']) { if (!readme.includes(required)) failures.push(`README.md: missing required community-release fact ${required}`) } -const runnableBlocks = [...readme.matchAll(/```(?:bash|sh)\n([\s\S]*?)```/g)].map((match) => match[1]) -if (runnableBlocks.some((block) => /(?:npx dshelm|npm install[^\n]*dshelm)/.test(block))) { - failures.push('README.md: unpublished npm install command appears in a runnable code block') +for (const required of ['pnpm preview:init', 'deepseek-ai/deepseek-harness/discussions', '0.1.0-rc.7', '0.1.2-rc.1']) { + if (!englishReadme.includes(required)) failures.push(`README.en.md: missing required community-release fact ${required}`) +} + +for (const [name, content] of [['README.md', readme], ['README.en.md', englishReadme]]) { + const runnableBlocks = [...content.matchAll(/```(?:bash|sh)\n([\s\S]*?)```/g)].map((match) => match[1]) + if (runnableBlocks.some((block) => /(?:npx dshelm|npm install[^\n]*dshelm)/.test(block))) { + failures.push(`${name}: unpublished npm install command appears in a runnable code block`) + } } if (failures.length > 0) { From 3c898229d6f84c37d8907b61b9b3c6253fd71d35 Mon Sep 17 00:00:00 2001 From: Altair Li <137127498+Altairpaca@users.noreply.github.com> Date: Thu, 3 Sep 2026 01:53:11 -0700 Subject: [PATCH 19/24] docs(readme): surface 0.1.2 client-module promotion gate --- README.md | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index 415d66b..4a92336 100644 --- a/README.md +++ b/README.md @@ -20,7 +20,7 @@

> [!IMPORTANT] -> DSHelm 当前是 `0.3.0-alpha` **源码预览版**,npm 包尚未发布,不建议用于生产环境。项目正在适配 DeepSeek Harness `0.1.2-rc.1`;该版本目前作为 **source target** 跟踪,完整 npm package set 与 clean-profile 验证完成前,不会把它标记为已验证安装基线。 +> DSHelm 当前是 `0.3.0-alpha` **源码预览版**,npm 包尚未发布,不建议用于生产环境。项目正在适配 DeepSeek Harness `0.1.2-rc.1`;core/session/subagent 与 browser source bridge 已经落地,但 0.1.2 的 client package graph 已从旧 `dsh-client-runtime` 迁移到新的 client module system。完整 npm package set、client manifest/lockfile migration 与 clean-profile/Web 验证完成前,不会把它标记为已验证安装基线。

DSHelm compatibility status: source preview, verified DSH install baseline, and current DSH source target @@ -99,11 +99,11 @@ resolver contract 与 execution contract 是两个不同的故障域。把它们 DSHelm 的兼容性声明采用两层口径: - **Verified install baseline — `0.1.0-rc.7`**:已经完成 package/runtime、clean HOME、profile composition、bounded boot、doctor / explain / uninstall 验证。 -- **Current source target — `0.1.2-rc.1`**:DeepSeek Harness 于 **2026-09-03** 发布的最新 source release。DSHelm 已针对已确认的 API 变化加入 forward-compatible bridge,但仍等待完整 npm package set 与 clean-profile promotion gate。 +- **Current source target — `0.1.2-rc.1`**:DeepSeek Harness 于 **2026-09-03** 发布的最新 source release。DSHelm 已完成已确认的 core/session/subagent bridge,并把 Web control-plane browser source 从已移除的 legacy runtime 类型依赖中解耦;**0.1.2 client package graph migration 与 Web bundle verification 仍是 promotion blocker**。 -当前机器可读状态见 [`compatibility.json`](compatibility.json)。上游 source target 对应 [`dsh-v0.1.2-rc.1`](https://github.com/deepseek-ai/deepseek-harness/releases/tag/dsh-v0.1.2-rc.1)。 +当前机器可读状态见 [`compatibility.json`](compatibility.json),完整 seam-by-seam 审计见 [`docs/compatibility/dsh-0.1.2-rc.1.md`](docs/compatibility/dsh-0.1.2-rc.1.md)。上游 source target 对应 [`dsh-v0.1.2-rc.1`](https://github.com/deepseek-ai/deepseek-harness/releases/tag/dsh-v0.1.2-rc.1)。 -### 已处理的 0.1.2 API 变化 +### 已处理 / 已定位的 0.1.2 变化 | 上游变化 | DSHelm 处理 | | --- | --- | @@ -111,8 +111,10 @@ DSHelm 的兼容性声明采用两层口径: | `SubagentCapabilities` 新增 `agentOptions` gate | DSHelm provider 在 runtime 声明 `agentOptions: true`,同时保持旧类型可编译 | | `AgentOptions` 新增 `reasoningEffort` | 新 host 直接获得 reasoning option;legacy host 继续通过 `request/header` seed 恢复 reasoning | | subagent caller 可显式选择 provider / model / reasoning / max output | DSHelm 保持 policy resolution 为来源,并映射到官方 `agentOptions` seam;max-output policy 尚未宣称实现 | +| 旧 `packages/client/runtime` / `@deepseek-ai/dsh-client-runtime` 从 0.1.2 source tree 消失 | browser source 改为只依赖实际使用的 `sessions.binding(...).session.projections` 结构;不再 import legacy runtime client types | +| `@deepseek-ai/dsh-client-modules` 成为 `dsh.client` 扫描、boot graph、`/plugins` bundle 与 lazy materialization 的模块系统 | 已审计新机制;`@dshelm/dsh` manifest 的 dependency/inject set 必须在 exact-version + lockfile promotion 时整体迁移并用真实 Web load 验证 | -这里刻意没有直接把所有 package manifest 改成 `0.1.2-rc.1`:上游 npm 发布在 2026-09-03 处于滚动状态,而且 DSHelm 当前 lockfile 仍属于已验证旧基线。**版本 promotion 必须和完整 package availability、lockfile regeneration、fresh install/profile boot 一起完成。** +这里刻意没有直接把所有 package manifest 改成 `0.1.2-rc.1`:上游 npm 发布在 2026-09-03 处于滚动状态,而且 DSHelm 当前 lockfile 仍属于已验证旧基线。**版本 promotion 必须和完整 package availability、client module graph、lockfile regeneration、fresh install/profile boot/Web client materialization 一起完成。**

为什么不使用宽泛的“支持 0.1.x”声明? @@ -170,7 +172,7 @@ dshelm CLI · init · doctor · auth · explain · uninstall | Issue | 下一阶段 | | --- | --- | -| [#7 — npm alpha](https://github.com/Altairpaca/dshelm/issues/7) | 完成 DSH dependency promotion、registry publish、clean-HOME install/uninstall evidence | +| [#7 — npm alpha](https://github.com/Altairpaca/dshelm/issues/7) | 完成 DSH dependency + client-module promotion、registry publish、clean-HOME/Web install/uninstall evidence | | [#8 — platform matrix](https://github.com/Altairpaca/dshelm/issues/8) | Linux、macOS Apple Silicon、Windows 11 + WSL2 可复现验证 | | [#9 — first-run evidence](https://github.com/Altairpaca/dshelm/issues/9) | deterministic execution fixture 已落地;继续补 provider-backed evidence | | [#10 — contributor entry points](https://github.com/Altairpaca/dshelm/issues/10) | provider/model evidence、平台验证、文档、routing examples、reproducible bugs | From eb6be3105c247f261295cad5823f58403ebfa1bc Mon Sep 17 00:00:00 2001 From: Altair Li <137127498+Altairpaca@users.noreply.github.com> Date: Thu, 3 Sep 2026 01:53:51 -0700 Subject: [PATCH 20/24] docs(readme): surface 0.1.2 client-module promotion gate in English --- README.en.md | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/README.en.md b/README.en.md index 6fcae5e..ac93458 100644 --- a/README.en.md +++ b/README.en.md @@ -20,7 +20,7 @@

> [!IMPORTANT] -> DSHelm is a `0.3.0-alpha` **source preview**. The npm packages are not published yet and the project is not production-ready. DeepSeek Harness `0.1.2-rc.1` is currently tracked as the **source target**; it will not be promoted to the verified install baseline until the complete npm package set and clean-profile journey are proven. +> DSHelm is a `0.3.0-alpha` **source preview**. The npm packages are not published yet and the project is not production-ready. DeepSeek Harness `0.1.2-rc.1` is the current **source target**: core/session/subagent and browser-source bridges are in place, but the 0.1.2 client package graph has moved away from the legacy `dsh-client-runtime` into the new client module system. It will not be promoted to the verified install baseline until the complete npm graph, client manifest/lockfile migration, and clean-profile/Web journey are proven.

DSHelm compatibility status: source preview, verified DSH install baseline, and current DSH source target @@ -97,11 +97,11 @@ Resolver and execution contracts are different failure domains. Keeping them sep DSHelm deliberately separates a verified install baseline from the newest upstream source target: - **Verified install baseline — `0.1.0-rc.7`**: package/runtime, clean HOME, profile composition, bounded boot, doctor/explain/uninstall have been exercised. -- **Current source target — `0.1.2-rc.1`**: the latest DeepSeek Harness source release published on **September 3, 2026**. Forward-compatible bridges for confirmed API changes are now in DSHelm, while npm-package promotion and clean-profile verification remain pending. +- **Current source target — `0.1.2-rc.1`**: the latest DeepSeek Harness source release published on **September 3, 2026**. Confirmed core/session/subagent changes are bridged and the Web control-plane source no longer imports the removed legacy runtime types; **the 0.1.2 client package graph migration and Web bundle verification remain promotion blockers**. -The machine-readable status lives in [`compatibility.json`](compatibility.json). The current upstream target is [`dsh-v0.1.2-rc.1`](https://github.com/deepseek-ai/deepseek-harness/releases/tag/dsh-v0.1.2-rc.1). +The machine-readable status lives in [`compatibility.json`](compatibility.json), and the full seam-by-seam audit is in [`docs/compatibility/dsh-0.1.2-rc.1.md`](docs/compatibility/dsh-0.1.2-rc.1.md). The current upstream target is [`dsh-v0.1.2-rc.1`](https://github.com/deepseek-ai/deepseek-harness/releases/tag/dsh-v0.1.2-rc.1). -### 0.1.2 changes already bridged +### 0.1.2 changes bridged or explicitly located | Upstream change | DSHelm handling | | --- | --- | @@ -109,8 +109,10 @@ The machine-readable status lives in [`compatibility.json`](compatibility.json). | `SubagentCapabilities` adds the `agentOptions` gate | DSHelm provider advertises `agentOptions: true` at runtime while remaining compilable against the legacy type surface | | `AgentOptions` adds `reasoningEffort` | current hosts receive the reasoning option directly; legacy hosts retain the `request/header` seed path | | callers may specify provider/model/reasoning/max output for subagents | DSHelm maps policy resolution onto the official `agentOptions` seam; max-output policy is not claimed yet | +| old `packages/client/runtime` / `@deepseek-ai/dsh-client-runtime` disappears from the 0.1.2 source tree | browser source now types only the `sessions.binding(...).session.projections` face it actually consumes; no legacy runtime client-type import remains | +| `@deepseek-ai/dsh-client-modules` now owns `dsh.client` discovery, boot graph, `/plugins` bundles and lazy materialization | mechanism audited; `@dshelm/dsh` dependency/inject metadata must migrate atomically with the exact-version lockfile and a real Web load assertion | -The package manifests are intentionally **not** force-bumped to `0.1.2-rc.1` in this step. Upstream npm publication is rolling on September 3, and the DSHelm lockfile still represents the verified legacy baseline. Promotion must happen together with complete package availability, lockfile regeneration, and a fresh install/profile boot. +The package manifests are intentionally **not** force-bumped to `0.1.2-rc.1` in this step. Upstream npm publication is rolling on September 3, and the DSHelm lockfile still represents the verified legacy baseline. Promotion must happen together with complete package availability, the client module graph, lockfile regeneration, and a fresh install/profile boot/Web-client materialization.

Why not claim generic “0.1.x support”? @@ -167,7 +169,7 @@ dshelm CLI · init · doctor · auth · explain · uninstall | Issue | Next step | | --- | --- | -| [#7 — npm alpha](https://github.com/Altairpaca/dshelm/issues/7) | DSH dependency promotion, registry publish, clean-HOME install/uninstall evidence | +| [#7 — npm alpha](https://github.com/Altairpaca/dshelm/issues/7) | DSH dependency + client-module promotion, registry publish, clean-HOME/Web install/uninstall evidence | | [#8 — platform matrix](https://github.com/Altairpaca/dshelm/issues/8) | reproducible Linux, macOS Apple Silicon, Windows 11 + WSL2 verification | | [#9 — first-run evidence](https://github.com/Altairpaca/dshelm/issues/9) | deterministic execution fixture landed; add provider-backed evidence | | [#10 — contributor entry points](https://github.com/Altairpaca/dshelm/issues/10) | provider/model evidence, platform verification, docs, routing examples, reproducible bugs | From d10d509e00da225939655502a7447df65a858f78 Mon Sep 17 00:00:00 2001 From: Altair Li <137127498+Altairpaca@users.noreply.github.com> Date: Thu, 3 Sep 2026 01:55:46 -0700 Subject: [PATCH 21/24] test(dsh): keep new capability assertion legacy-type safe --- packages/dsh/tests/dsh-012-compat.test.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/packages/dsh/tests/dsh-012-compat.test.ts b/packages/dsh/tests/dsh-012-compat.test.ts index b0ed712..fc02896 100644 --- a/packages/dsh/tests/dsh-012-compat.test.ts +++ b/packages/dsh/tests/dsh-012-compat.test.ts @@ -35,7 +35,9 @@ describe('DSH 0.1.2 compatibility bridges', () => { sessionIdOf: () => 'compat-test', }) - expect(provider.capabilities).toMatchObject({ + // The installed rc.7 type does not know the new field yet; assert the + // runtime shape explicitly so this test itself remains dual-generation. + expect(provider.capabilities as unknown as Record).toMatchObject({ agentOptions: true, outputSchema: false, depthLimit: true, From b29b4a87df175574f7981735d3339100b6c66936 Mon Sep 17 00:00:00 2001 From: Altair Li <137127498+Altairpaca@users.noreply.github.com> Date: Thu, 3 Sep 2026 02:00:57 -0700 Subject: [PATCH 22/24] feat(settings): bridge legacy and DSH 0.1.2 settings seams --- packages/dsh/src/config-files.ts | 143 +++++++++++++++++++++++++++---- 1 file changed, 127 insertions(+), 16 deletions(-) diff --git a/packages/dsh/src/config-files.ts b/packages/dsh/src/config-files.ts index 3fcc138..4d286d3 100644 --- a/packages/dsh/src/config-files.ts +++ b/packages/dsh/src/config-files.ts @@ -4,17 +4,27 @@ * * Precedence (tested): defaults → user → project → request → runtime * validation. The user layer comes from `ctx.settings` when a settings - * provider is composed (official settings-namespace seam); the project layer - * is the committed file; request layers come from the resolve call. + * provider is composed; the project layer is the committed file; request + * layers come from the resolve call. + * + * DSH compatibility: + * - 0.1.0-rc.x exports top-level `settingsNamespace()` and + * `installSettingsSection(ctx, ...)` helpers. + * - 0.1.2 moves optional-section installation onto + * `ctx.settings.installSection(owner, ...)` and accepts literal namespaces. + * + * Importing the settings package as a namespace avoids a static named-export + * dependency on helpers removed by 0.1.2. `installSettingsSectionCompat()` + * selects the legacy helper when present and otherwise wires the modern + * optional service through `ctx.inject(['settings'], ...)`. */ import { readFile } from 'node:fs/promises' import type { Context } from '@deepseek-ai/cordis' import { loadPolicyLayers, type PolicyDocument, type PolicyLayerValue } from '@dshelm/core' -import { installSettingsSection, settingsNamespace } from '@deepseek-ai/dsh-settings' +import * as DshSettings from '@deepseek-ai/dsh-settings' export const DSHELM_CONFIG_DIR = '.dshelm' export const DSHELM_CONFIG_FILE = 'config.jsonc' -export const DSHELM_SETTINGS_NAMESPACE = settingsNamespace('dshelm') /** Schema-backed user-level override document (optional fields). */ export interface DSHelmUserSettings { @@ -23,6 +33,113 @@ export interface DSHelmUserSettings { readonly categories?: Record } +type SettingsSourceHooks = { + setSource(current: () => T): void + onChange(): void + validate?: (value: T) => void +} + +type SettingsSchema = ((value: unknown) => T) & { toJSON(): unknown } + +type LegacySettingsModule = { + settingsNamespace?: (value: string) => unknown + installSettingsSection?: ( + owner: unknown, + namespace: unknown, + schema: SettingsSchema, + entry: T, + hooks: SettingsSourceHooks, + ) => void +} + +type ModernSettingsService = { + installSection( + owner: unknown, + namespace: string, + schema: SettingsSchema, + entry: T, + hooks: SettingsSourceHooks, + ): void +} + +type SettingsInjectContext = { + inject( + services: readonly string[], + callback: (ctx: { settings?: ModernSettingsService }) => void, + ): void +} + +const settingsModule = DshSettings as unknown as LegacySettingsModule +export const DSHELM_SETTINGS_NAMESPACE = settingsModule.settingsNamespace?.('dshelm') ?? 'dshelm' + +function isPlainObject(value: unknown): value is Record { + if (typeof value !== 'object' || value === null || Array.isArray(value)) return false + const proto = Object.getPrototypeOf(value) + return proto === Object.prototype || proto === null +} + +function validateSettingsSection(value: unknown, field: keyof DSHelmUserSettings): void { + if (value === undefined) return + if (!isPlainObject(value)) { + throw new TypeError(`dshelm settings.${field} must be an object when present`) + } +} + +/** + * Minimal callable schema accepted by both DSH settings generations. + * Deep policy validation deliberately remains owned by @dshelm/core. + */ +export const DSHELM_SETTINGS_SCHEMA: SettingsSchema = Object.assign( + (value: unknown): DSHelmUserSettings => { + if (!isPlainObject(value)) throw new TypeError('dshelm settings must be an object') + validateSettingsSection(value.profiles, 'profiles') + validateSettingsSection(value.agents, 'agents') + validateSettingsSection(value.categories, 'categories') + return value as DSHelmUserSettings + }, + { + toJSON: () => ({ + type: 'object', + properties: { + profiles: { type: 'object' }, + agents: { type: 'object' }, + categories: { type: 'object' }, + }, + additionalProperties: false, + }), + }, +) + +/** + * Install one optional settings section across the two DSH settings APIs. + * Exported for a small compatibility contract test; application code should + * normally call installDSHelmSettings(). + */ +export function installSettingsSectionCompat( + owner: Context, + namespace: string, + schema: SettingsSchema, + entry: T, + hooks: SettingsSourceHooks, + moduleFace: LegacySettingsModule = settingsModule, +): void { + if (typeof moduleFace.installSettingsSection === 'function') { + moduleFace.installSettingsSection(owner, namespace, schema, entry, hooks) + return + } + + const injectOwner = owner as unknown as SettingsInjectContext + if (typeof injectOwner.inject !== 'function') { + throw new Error('unsupported DSH settings API: expected legacy installSettingsSection() or Context.inject()') + } + injectOwner.inject(['settings'], (ctx) => { + if (ctx.settings === undefined || typeof ctx.settings.installSection !== 'function') { + throw new Error('unsupported DSH settings API: settings service has no installSection()') + } + ctx.settings.installSection(owner, namespace, schema, entry, hooks) + }) +} + /** * Load the project layer from `/.dshelm/config.jsonc` when present. * A missing file yields `undefined` (no project override); malformed @@ -39,25 +156,19 @@ export async function loadProjectPolicyLayer(cwd: string): Promise DSHelmUserSettings | undefined { let source: DSHelmUserSettings = base - installSettingsSection( + installSettingsSectionCompat( ctx, - DSHELM_SETTINGS_NAMESPACE, - // Minimal schema: free-form policy sections layered on the base document. - // Full schema validation happens in @dshelm/core at load time. - { profiles: { type: 'object' }, agents: { type: 'object' }, categories: { type: 'object' } } as never, + String(DSHELM_SETTINGS_NAMESPACE), + DSHELM_SETTINGS_SCHEMA, base, { setSource: (current) => { source = current() }, From 02aa32ebde807a605c6c824589d59f4de122e416 Mon Sep 17 00:00:00 2001 From: Altair Li <137127498+Altairpaca@users.noreply.github.com> Date: Thu, 3 Sep 2026 02:01:18 -0700 Subject: [PATCH 23/24] test(settings): cover legacy and 0.1.2 settings installation seams --- packages/dsh/tests/dsh-012-compat.test.ts | 59 +++++++++++++++++++++++ 1 file changed, 59 insertions(+) diff --git a/packages/dsh/tests/dsh-012-compat.test.ts b/packages/dsh/tests/dsh-012-compat.test.ts index fc02896..5813006 100644 --- a/packages/dsh/tests/dsh-012-compat.test.ts +++ b/packages/dsh/tests/dsh-012-compat.test.ts @@ -1,6 +1,11 @@ import { describe, expect, it, vi } from 'vitest' +import type { Context } from '@deepseek-ai/cordis' import type { SessionEvent } from '@deepseek-ai/dsh-session' import { createDSHelmProvider } from '../src/provider.ts' +import { + DSHELM_SETTINGS_SCHEMA, + installSettingsSectionCompat, +} from '../src/config-files.ts' import { snapshotSessionLog } from '../src/session-log-compat.ts' import type { DSHelmPolicyServiceFace } from '../src/service.ts' @@ -45,4 +50,58 @@ describe('DSH 0.1.2 compatibility bridges', () => { persona: true, }) }) + + it('keeps the DSHelm settings schema callable and serializable', () => { + const value = { profiles: { planner: { reasoning: 'high' } }, agents: {}, categories: {} } + expect(DSHELM_SETTINGS_SCHEMA(value)).toBe(value) + expect(DSHELM_SETTINGS_SCHEMA.toJSON()).toMatchObject({ + type: 'object', + properties: { + profiles: { type: 'object' }, + agents: { type: 'object' }, + categories: { type: 'object' }, + }, + }) + expect(() => DSHELM_SETTINGS_SCHEMA({ profiles: [] })).toThrow(/settings\.profiles must be an object/) + }) + + it('uses the rc.7 top-level settings helper when it exists', () => { + const legacyInstall = vi.fn() + const owner = {} as Context + const hooks = { setSource: vi.fn(), onChange: vi.fn() } + + installSettingsSectionCompat( + owner, + 'dshelm', + DSHELM_SETTINGS_SCHEMA, + {}, + hooks, + { installSettingsSection: legacyInstall }, + ) + + expect(legacyInstall).toHaveBeenCalledOnce() + expect(legacyInstall).toHaveBeenCalledWith(owner, 'dshelm', DSHELM_SETTINGS_SCHEMA, {}, hooks) + }) + + it('uses ctx.settings.installSection through Context.inject on the 0.1.2 seam', () => { + const modernInstall = vi.fn() + const inject = vi.fn((_services: readonly string[], callback: (ctx: unknown) => void) => { + callback({ settings: { installSection: modernInstall } }) + }) + const owner = { inject } as unknown as Context + const hooks = { setSource: vi.fn(), onChange: vi.fn() } + + installSettingsSectionCompat( + owner, + 'dshelm', + DSHELM_SETTINGS_SCHEMA, + {}, + hooks, + {}, + ) + + expect(inject).toHaveBeenCalledWith(['settings'], expect.any(Function)) + expect(modernInstall).toHaveBeenCalledOnce() + expect(modernInstall).toHaveBeenCalledWith(owner, 'dshelm', DSHELM_SETTINGS_SCHEMA, {}, hooks) + }) }) From d87ef2f6832d2a69370a37a2d2fe3223405fcbbd Mon Sep 17 00:00:00 2001 From: Altair Li <137127498+Altairpaca@users.noreply.github.com> Date: Thu, 3 Sep 2026 02:01:50 -0700 Subject: [PATCH 24/24] docs(compat): record settings API bridge for DSH 0.1.2 --- compatibility.json | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/compatibility.json b/compatibility.json index f842006..8a0042c 100644 --- a/compatibility.json +++ b/compatibility.json @@ -17,11 +17,13 @@ "releaseTag": "dsh-v0.1.2-rc.1", "sourceCommit": "a66e4702047846cdaa10c66c9d3df3951f5ea70d", "releaseDate": "2026-09-03", - "status": "core/session/subagent source bridges implemented and browser source decoupled from removed dsh-client-runtime; package-manifest client-module migration plus complete npm/clean-profile verification remain before promotion", + "status": "session/subagent/settings and browser-source compatibility bridges implemented; package-manifest client-module migration plus complete npm/clean-profile/Web verification remain before promotion", "auditedSeams": [ "Session.snapshotEvents() replacing Session.events", "SubagentCapabilities.agentOptions", "AgentOptions.reasoningEffort", + "SettingsProvider.installSection(owner, ...) replacing the legacy top-level installSettingsSection(ctx, ...)", + "literal settings namespaces replacing consumer dependence on settingsNamespace()", "@deepseek-ai/dsh-client-modules replacing the legacy dsh-client-runtime bootstrap package", "package-owned dsh.client browser module graph" ], @@ -29,7 +31,7 @@ "the complete 0.1.2-rc.1 npm package graph must be available", "@dshelm/dsh package.json still depends on and injects @deepseek-ai/dsh-client-runtime from the verified legacy baseline", "the 0.1.2 client package graph must replace the legacy runtime dependency/inject coherently with pnpm-lock.yaml", - "fresh packed install, isolated profile boot, Web client bundle loading, doctor/explain/fixtures/uninstall must pass" + "fresh packed install, isolated profile boot, Web client bundle loading, settings-provider registration, doctor/explain/fixtures/uninstall must pass" ] }, "seams": { @@ -67,14 +69,18 @@ "legacy @deepseek-ai/dsh-client-runtime dependency/inject remains only in the verified package graph until lockfile promotion" ], "settings": [ - "installSettingsSection(ctx, ns, schema, entry, hooks)", - "settingsNamespace" + "legacy top-level installSettingsSection(ctx, ns, schema, entry, hooks) fallback", + "0.1.2 ctx.settings.installSection(owner, ns, schema, entry, hooks) through optional Context.inject", + "literal dshelm namespace with legacy settingsNamespace() compatibility", + "callable + serializable DSHelm user-settings schema" ] }, "notes": [ "The verified npm/install baseline remains 0.1.0-rc.7 until the 0.1.2-rc.1 package set is fully published and the clean profile journey passes.", "DSH 0.1.2 removes direct Session.events reads in favor of seq/eventAt()/snapshotEvents(); DSHelm now prefers snapshotEvents() and falls back to the legacy getter.", "DSH 0.1.2 adds the SubagentCapabilities.agentOptions gate and AgentOptions.reasoningEffort; DSHelm advertises the capability at runtime while retaining the request/header seed for legacy hosts.", + "DSH 0.1.2 moves optional settings-section installation from the top-level installSettingsSection helper to SettingsProvider.installSection(owner, ...). DSHelm imports the settings package as a namespace, prefers the modern service method when the legacy helper is absent, and keeps the rc.7 helper path as a fallback.", + "DSHelm now supplies a real callable/toJSON settings schema instead of casting a plain object to the DSH settings schema type; deep policy validation still belongs to @dshelm/core.", "DSH 0.1.2 source removes the old packages/client/runtime package and introduces @deepseek-ai/dsh-client-modules as the browser module/boot system. DSHelm browser source no longer imports dsh-client-runtime/client, but package metadata migration is intentionally deferred to the exact-version + lockfile promotion step.", "public CLI tarball is named dshelm; workspace @dshelm packages are packed together for closure verification.", "clean journey uses an isolated HOME/DSH_HOME and verifies init, dump-config, bounded boot, doctor, explain, and uninstall.",