Releases: GuoMonth/dsh-multi-tenant
Release list
dsh-multi-tenant 0.8.0
0.8.0 — One-command local experience / 一行启动
Release notes for 0.8.0. Availability is determined by npm and the matching GitHub Release, not by this source file. Related issue: #78.
Adds dsh-multi-tenant start, status, stop, and doctor. Published artifacts bind a verified prebuilt runtime digest; source builds require an explicit local image. No checkout, pnpm, user-side image build or handwritten profile is required for the published experience.
The local launcher provisions Alice and Bob with distinct origins, single-use sign-in tickets, native DSH Web and persistent Docker volumes. An explicitly deterministic demo model exercises native MCP/file/subagent paths without API keys. Real model credentials and selection remain native DSH features.
A new Docker provider uses daemon-owned volumes and an authenticated loopback relay, removing host bind-path/Unix-socket/UID coupling from the CLI. The existing Linux SDK provider retains its API. The relay denies unauthenticated access even to native login endpoints.
Native Linux amd64 and arm64 have passed installed-CLI verification. Quality checks now run locally; GitHub only builds release images and publishes on manual dispatch. Docker Desktop support requires platform verification; do not infer certification from its transport design. Remote Docker contexts and Windows containers are rejected.
0.7 platform users retain their API. CLI data is separate and image-pinned; no legacy or cross-runtime data migration is introduced. Demo identity selection is local-only and is not a production login system. Registry publication remains a separate manual workflow. Maintainers verify the bound tarball and published npm CLI locally without an image override; the workflow checks artifact identity and delivery without rerunning native/browser tests.
README now leads with the local CLI and links to an AI project guide shipped in the npm package. Root AGENTS.md maps repository changes to development and verification commands.
中文
新增一行启动入口,自动准备固定运行镜像、域和 profile,打开本机体验页。Alice/Bob 使用独立原生 DSH 工作台;默认演示模型明确标识,无需密钥。停止后保留数据,重复启动复用入口。
新增 Docker 命名卷与受认证本机转发实现,既有平台 SDK 保持可用。真实模型通过原生设置接入。镜像由发布流水线预构建、验证并绑定 digest,源码中的空 manifest 不冒充已发布镜像。
本机 Linux 验证、arm64 CI 与 Desktop 实机证据分别记录;不声明尚未执行的平台验证。发布状态以 npm 与 GitHub Release 为准,不自动部署公网。
README 以 CLI 体验为入口;新增随包 AI 导航和根目录 AGENTS.md,覆盖项目理解、集成、开发与验证。绑定镜像后的 tarball 和 npm 真实 CLI 验证改为本地执行;GitHub 只保留手动构建发布和轻量产物核验,不再重复跑 CI。
dsh-multi-tenant 0.7.1
dsh-multi-tenant 0.7.1
中文
本版本让独立 DSH 工作台可以默认访问外部模型 API 和远程 MCP,并提供可直接构建的运行时镜像配方,减少接入平台自行准备基础环境的工作。
变化
- 默认允许出站: Docker Provider 默认使用 bridge。需要离线运行时设置
network: 'none',对应 Docker 的--network none。 - 随包提供 Dockerfile: 包含 DSH 0.1.5-rc.2、依赖锁和构建过滤文件,不包含测试模型、测试 MCP 或凭据。
- 常用工具开箱可用: Bash、Git/SSH、curl/wget、jq、ripgrep、文本/归档工具、Python 3/venv/pip、C/C++ 编译工具和 Node/npm。其他语言 SDK、浏览器和 AI CLI 可通过派生镜像补充。
安装与升级
npm install dsh-multi-tenant@0.7.1
docker build -f node_modules/dsh-multi-tenant/runtime/Dockerfile -t dsh-domain-runtime:local node_modules/dsh-multi-tenant
docker image inspect dsh-domain-runtime:local --format '{{.Id}}'将输出的镜像 ID 配置到 Provider,并按中文 README准备每域 profile 和认证入口。
从 0.7.0 升级无需迁移域数据,平台 API 沿用现有结构。默认网络行为发生变化:需要继续离线的部署,应在升级前显式配置 network: 'none'。采用新镜像时,停止旧 Host 后更新镜像 ID,再启动。0.5.x 及更早版本仍需按 README 完成架构迁移。
边界与验证
bridge 允许访问网络可达的宿主机、内网和同桥容器,不提供网络级租户隔离;部署方可通过防火墙控制访问范围。原生入口仍通过私有 Unix Socket 转发,不发布容器端口。平台管理权限仍位于用户域之外,域内会话之间不承诺独立访问授权。外部模型/MCP 需要相应配置和凭据。
基础镜像 digest 和 npm 依赖固定;系统工具获取 Debian 当前安全更新,部署时固定最终镜像 ID。运行时根目录只读,项目依赖应安装在 /domain,详细限制见 README。
验证包括 Node 22/24 发布检查、36 项平台测试、安装产物构建真实用户镜像、原生 DSH 就绪、工具与 Python venv、默认 HTTPS 出站与显式离线阻断,以及原生浏览器、隔离和恢复回归。不调用真实模型 API。
English
0.7.1 enables outbound access for external model APIs and remote MCP by default and ships a ready-to-build native runtime Dockerfile in the npm package.
- Docker defaults to bridge networking. Select
network: 'none'for offline operation. - The image includes pinned DSH 0.1.5-rc.2 and locked npm dependencies, plus Bash, Git/SSH, curl/wget, jq, ripgrep, text/archive utilities, Python/venv/pip, C/C++ build tools and Node/npm. No fixture models, fixture MCP or credentials are included.
- Existing 0.7.0 domain data needs no migration. The network default changes: configure
nonebefore upgrading if offline restrictions must remain. Stop existing Hosts before switching the image ID and restarting.
Use the installation/build commands above and follow the README for profiles and authentication. Bridge permits reachable host/LAN and same-bridge container access; it is not a network tenant boundary. Apply deployment firewall policy as needed. Private Unix ingress and no published ports remain in place. Sessions inside one Principal do not gain independent access authorization.
Validation covers Node 22/24 release checks, 36 platform tests, an image built from the installed package, native readiness, tool/venv usability, HTTPS egress and offline blocking, plus native browser/isolation/recovery regressions. No live model API calls are made.
dsh-multi-tenant 0.7.0
dsh-multi-tenant 0.7.0
Give each signed-in user their own native DeepSeek Harness environment. This release is for developers embedding DSH in an internal workbench or multi-tenant application: users retain the official chat, workspaces, files, presets and subagents; the platform separates their data and execution by (tenantId, principalId).
What changes for users and integrators
- Native DSH Web replaces the custom panel. Preset/MCP/child-agent composition follows the native runtime, addressing #68 and #71 through independently hosted Principal domains.
- Host startup is reused within a domain. Suspension and revocation close live admissions; persistent desired state prevents accidental reactivation after restart.
- Verified recovery removes the previous container before storage is reused. Cleanup retains ownership on failure and covers detached MCP descendants, replacing #65's old per-Agent acquisition path.
- Platform administration stays outside native Hosts. The ingress protects native cookies, rejects cross-origin framing and pins the private Unix socket against workload path substitution.
Who should use this version
Developers with an existing login system who want to provide independently hosted DSH environments. This is an integration library, with a constrained runtime reference and extension interfaces. The embedding platform supplies login/SSO, TLS, per-domain hostnames, profile provisioning, resource policy and operations.
The included Docker provider has no outbound network. It can run local/keyless fixtures, but external model APIs and remote MCP require a reviewed network-capable RuntimeProvider. The local process provider is for trusted development. There is no bundled account-management UI or ready-made hosted service.
Inside one Principal's domain, DSH permissions and lifecycle semantics apply. Workspaces and sessions are not independently confidential authorization domains. Project ACLs, team sharing, automatic idle eviction and multi-machine scheduling are not part of 0.7.0.
Install and upgrade
npm install dsh-multi-tenant@0.7.0
node node_modules/dsh-multi-tenant/examples/native-domains/smoke.mjsThe smoke checks the installed platform APIs using a simulated runtime; it does not start native DSH. Follow the README to provision a real Host and connect authentication.
Breaking change from the previously published 0.5.x line. The shared-Host Cordis bundle, per-Agent facade, custom panel and /mcp, /web, /starter, /deliveries, /sqlite, /testing exports are removed. Import the platform APIs from dsh-multi-tenant; install DSH inside the runtime rather than as platform peers. Start with a fresh platform directory, replace the integration code and preserve old data separately. There is no automatic legacy database migration. The 0.6.0 source milestone was not published to npm.
Compatibility and evidence
Platform: Node 22.19 or Node 24+; included providers: Linux, local Docker engine with the coordinator's non-root UID/GID. Native runtime is fixed to DSH 0.1.5-rc.2, source fb2c4b9e698e30edb738bca4cf0618587db7d203; floating DSH versions are not implicitly supported.
Validation includes 32 platform tests, 2 release-gate tests, an independently installed tarball consumer and 16 groups against real native Hosts and a browser. Coverage includes native children/forks/filtering/cold continuation, credentials, uploads, reconnection, cross-domain rejection, framing, socket substitution, suspension/revocation, controller SIGKILL and resource cleanup. Evidence and limits.
These are tested contracts, not a production capacity guarantee or general security certification. Resource measurements and the offline provider boundary are documented so deployers can decide what additional validation they need.
中文说明
0.7.0 面向搭建企业研发工作台或多租户应用的开发者,让每位登录用户获得独立的原生 DSH 环境。用户保留官方聊天、workspace、文件、preset 和子代理;平台按 (tenantId, principalId) 隔离数据与执行环境。
主要变化: 用原生 Web 和原生能力组合替换旧面板及逐 Agent facade;新增持久化域目录、启动复用、暂停/撤销和崩溃恢复。登录凭据留在平台,限制跨域页面嵌入,避免容器替换 socket 路径后重定向平台连接。资源清理失败会保留所有权,确认旧容器及 MCP 后代已退出后才复用存储。
使用边界: 这是开发者集成库。部署方提供登录/SSO、TLS、独立主机名、profile、资源策略和运维。内置 Docker provider 没有出站网络,不能直接连接外部模型 API 或远程 MCP;这些场景需要经过审查的 runtime provider。本包不提供现成账号 UI、项目 ACL、团队共享、自动空闲回收或跨机调度。同一 Principal 内的会话和 workspace 不承诺互相保密,权限控制沿用 DSH 原生语义,平台管理权限始终位于域外。
升级方式: 从已发布的 0.5.x 升级属于破坏性变更,需要替换接入代码、新建平台目录并单独保留旧数据,不提供自动迁移。0.6.0 只是源码里程碑,没有发布 npm。安装和镜像/profile 说明见中文 README。安装后的 smoke 使用模拟 runtime;真实原生验证另见证据文档。
固定 DSH 0.1.5-rc.2,Node 22.19/24 发布检查、独立安装消费者及 16 组真实原生验收均属于发布门禁。验证不代表通用安全认证或生产容量承诺。
dsh-multi-tenant 0.5.0
dsh-multi-tenant 0.5.0
0.5.0 moves the plugin to DSH 0.1.5-alpha.1 and fixes newly created empty Agents failing to resume after restart. The release identity is v0.5.0, using the npm latest dist-tag.
DSH compatibility baseline
dsh-multi-tenant@0.5.0 supports exactly DSH 0.1.5-alpha.1, source commit 5dda764ed3aa172535a7967b06ff95d9cbfe536a. It replaces the 0.4.0 dependency baseline of DSH 0.1.2-rc.1. All DSH direct dependencies and lockfile resolutions are pinned, including the newly introduced format and HTTP proxy packages. @deepseek-ai/dsh-llm becomes an explicit peer because the driver now uses the official identifier constructors.
The upstream comparison includes breaking persistence, Agent, Inbox, and session-format changes. DSH remains an alpha. Only the new exact baseline is supported by this version; no old/new runtime adapter or historical log converter is introduced.
Release decision
The minor version advances because the required DSH peer baseline changes incompatibly. The shared driver also now refuses creation without a working session durability checkpoint, preventing ready resources whose empty session disappears on restart. The Principal API, provider protocols, public export paths, SQLite tenant_agents_v04 schema, and logical/strong isolation negotiation remain unchanged. Historical 0.4.0 release documents retain their original claims rather than being relabeled as 0.5.0.
Stop the host before backing up the Agent Directory, DSH data, and configuration together. Upgrade the complete DSH graph and verify native create/resume/MCP/shutdown. Rollback requires the corresponding old runtime and pre-upgrade data. In the review experiment, RC.1 reopened the retained V0 log while omitting messages added to the V3 generation; successful reopening is not proof of a lossless downgrade.
Refactoring decisions
| Area | Decision and implementation |
|---|---|
| DSH driver | Replace the hand-written Record<string, unknown> registry surface with the real AgentRegistry method types and AgentSetup. Use SessionId, ToolCallId, and ReasoningEffortId constructors at the DSH boundary. The public host options remain plain validated values. |
| Durable Agent publication | Before returning a created handle, await the native per-session sessions.flush(agent.session). DSH can otherwise discard an empty unmaterialized session while SQLite already says ready. Missing/failed durability checkpoints dispose the Agent and fail publication; custom persistent drivers must honor this lifecycle boundary too. |
| Persistence verification | Replace removed load() calls with explicit flush, open('read'), read, and close in finally. Assert V3 and test reader/writer contention plus release after Agent disposal. whenIdle() remains an activity boundary, not a durability promise. |
| Release gates | Read plugin version from package.json and upstream identity from scripts/dsh-target.mjs; remove duplicate hard-coded identities from contract/preflight scripts. Keep exact lockfile checks and independent upstream source verification. |
| Ownership and provider contracts | Retain Principal-scoped Directory, CAS, leases, and host isolation protocols. The upstream writer lock does not replace single-active-process SQLite deployment or provide distributed authority. No evidence calls for rebuilding this layer. |
| Tenant runtime surface | Keep raw Agent/SessionHandle/context/disposer capabilities private. Do not add persistence or distributed orchestration APIs merely to mirror an upstream refactor. |
| Historical data and UI | Let DSH own its supported log migrations. Host profile/plugin compatibility is reviewed separately. The CRUD Web adapter does not depend on the removed Detail UI. |
Evidence
The release gate runs frozen dependency installation separately, followed by package/contract/preflight checks, peer checks, typecheck, unit/contract/Web tests, native AgentLoop + V3 JSONL + official MCP lifecycle, build, SQLite restart/CAS/default-permission probe, and installed-tarball consumer/typecheck. CI runs the contract on Node 22.19 and Node 24 and verifies the exact upstream commit/version in a separate job.
The native integration uses real factories and sessions. It verifies two Principals using the same MCP namespace without credential mixing, empty-session restart/resume, refusal without a durability listener, cleanup after a checkpoint failure, authorization denial, delete retaining the durable log, readable flushed history under a live writer, rejection of a second writer, and successful resume after disposal. It does not call a paid model or establish coverage of arbitrary host plugins or all historical log variants.
Local Node matrix and full release-check results are recorded in the alignment review. GitHub CI and registry publication are independently verifiable actions.
Explicit limits
- SQLite remains local, single-node, and single-active-process; the host enforces this topology.
- Shared runtime provides logical isolation, not a hostile-code boundary.
- Authentication, secrets, configured-path ACLs, and strong isolation remain host responsibilities.
- Stock DSH
/apistays private/administrative; there is no public Typert ingress. - Agent idleness does not acknowledge durable writes. Cancellation and shutdown are cooperative.
- Delete does not physically erase DSH logs. Cross-version rollback is not lossless data conversion.
0.3ownership data and retired unpublished schemas are not migrated.
中文复盘
dsh-multi-tenant@0.5.0 / v0.5.0 的唯一基线为 DSH 0.1.5-alpha.1,commit 5dda764ed3aa172535a7967b06ff95d9cbfe536a。本版本通过 npm latest dist-tag 分发,修复空 Agent 创建成功后重启无法恢复的问题。
需要推进的重构已落在四个具体边界:新建 Agent 在 ready 前完成单 session 持久化检查,失败则清理 handle;driver 使用真实 registry/setup 类型和官方 branded ID 构造器;持久化验证改用显式 flush/read/close 并检查 V3 与 writer 释放;发布门禁从 package manifest 和 DSH target 读取唯一版本来源。@deepseek-ai/dsh-llm 因新增直接运行时导入成为 exact peer。
Principal 授权、SQLite Directory schema、provider 方法签名和租户 runtime 公共方法没有变化;自定义持久化 driver 的 create 成功边界须保证 session 已可恢复,也没有证据要求重写这些层。DSH writer 锁不能代替多租户授权、SQLite 单活动进程约束或分布式 fencing。暂不扩张租户接口、不引入跨版本适配层、不自建日志迁移器。
升级必须整体切换 DSH 依赖,升级前停止宿主并一致备份 Directory、DSH 数据和配置。回滚同时恢复对应的旧 runtime 与旧数据;RC.1 可能成功打开旧日志,却遗漏 V3 新消息。项目只维护一条精确基线,不承担无限期兼容承诺。
原生验收覆盖真实 Agent/MCP、V3 持久化、空会话重启、缺失 listener 拒绝、flush 失败清理、越权拒绝、删除保留日志、活跃 writer 下读取、第二个 writer 拒绝及 dispose 后恢复。完整发布检查包括 Node 22/24、构建与安装后 tarball consumer;不包含付费模型或任意宿主扩展。现有 0.4.0 发布记录继续作为历史记录保留。
dsh-multi-tenant 0.4.0
dsh-multi-tenant 0.4.0
Release posture: first non-prerelease release of the clean DSH multi-tenant plugin line. The matching source tag is v0.4.0, and npm distribution uses the latest dist-tag.
DSH compatibility baseline
dsh-multi-tenant@0.4.0 supports exactly DSH 0.1.2-rc.1 at release commit a66e4702047846cdaa10c66c9d3df3951f5ea70d. Every direct DSH peer and development dependency is exact, and the lockfile gate rejects any different resolved DSH version.
DSH 0.1.2-rc.1 is an upstream release candidate, not a stable DSH release. This plugin release does not relabel it or claim forward compatibility with later RC or stable builds. A DSH baseline change requires a new plugin compatibility release and the same source-identity and lifecycle evidence.
The official DSH alpha.5-to-RC.1 comparison contains only release metadata changes. Agent registry/loop, Session, persistence, Session projection, MCP client, Tools, Cordis integration, and API/Web source are unchanged across that delta.
Stable release decision
The documented 0.4 plugin API, provider contracts, SQLite Agent Directory schema, Web input surface, and lifecycle semantics are the reviewed public contract for this release. 0.4.0 is not a 1.0-level promise against future evolution; incompatible changes must be explicitly versioned and documented instead of entering an existing artifact silently.
The project remains specifically a DSH multi-tenant plugin. It owns the path from a server-minted Principal to a Principal-scoped Agent resource and controlled DSH Agent/MCP execution. It does not grow into an authentication gateway, distributed ownership coordinator, sandbox, or process supervisor.
0.4 is intentionally incompatible with 0.3. Session claims, credentials, Operations, RuntimeComposition, compatibility facades, and the old ownership table were removed and are not migrated. Users of the 0.4.0-alpha.* line can adopt 0.4.0 without a public API or SQLite schema change.
Evidence
The release contract verifies frozen installation, exact DSH peers and source identity, Node 22.19 and Node 24, type declarations, all unit/contract/Web tests, native DSH AgentLoop + JSONL + official MCP create/restart/resume/delete, SQLite restart/CAS/default permissions and abandoned-provisioning recovery, lifecycle cancellation, secret-leak probes, and a clean installed-tarball consumer.
The release workflow requires successful CI for the exact main commit, publishes through npm Trusted Publishing with provenance, verifies dsh-multi-tenant@0.4.0 and the latest dist-tag, and creates the matching non-prerelease Git tag and GitHub Release.
Explicit limits
- The built-in SQLite directory is local, single-node, and requires the host to guarantee a single active process.
- The bundled shared runtime provides logical isolation, not a hostile-code boundary.
- Authentication, secret storage, configured-path ACLs, and the truth of a strong-isolation provider remain host responsibilities.
- Stock DSH
/apiremains private/administrative; no public Typert ingress is provided. - Delete does not physically erase DSH logs, and cooperative shutdown cannot force unresponsive host code to stop.
0.3data and prior unpublished candidate schemas are not migrated.
中文复盘
dsh-multi-tenant@0.4.0 是全新 DSH 多租户插件产品线首个不带 prerelease 标识的正式分发版本,对应源码 tag v0.4.0,通过 npm latest dist-tag 发布。它是当前已审查、受支持的公共入口,不等于 1.0 级别的永久兼容承诺;不兼容变更必须通过新版本和文档显式说明。
本版本唯一支持的 Harness 基线是 DSH 0.1.2-rc.1,对应 release commit a66e4702047846cdaa10c66c9d3df3951f5ea70d。所有直接 DSH peer/dev dependency 与 lockfile resolution 都使用精确版本。DSH RC.1 本身仍是上游预发布版本;插件正式版不会把它描述成 DSH 稳定版,也不承诺兼容后续 RC 或 stable。升级 DSH 必须通过新的插件兼容版本、源码身份核验和真实生命周期门禁。
“正式版”承诺的是插件已经公开的 0.4 API、provider 契约、SQLite Agent Directory schema、Web 输入和生命周期语义。项目定位不变:只负责从服务端 Principal 到 Principal-scoped Agent 资源及受控 DSH Agent/MCP 执行,不扩张成认证网关、分布式协调器、sandbox 或进程管理器。
0.4 不兼容 0.3,也不迁移旧数据;但从 0.4.0-alpha.* 升级到 0.4.0 不修改公共 API 或 SQLite schema。默认边界继续保持:本地 single-node/single-active-process SQLite、进程内逻辑隔离、宿主负责认证与强隔离、公网不得使用 stock DSH /api、删除不物理擦除 DSH 日志、合作式取消不能强制终止不响应的宿主代码。
dsh-multi-tenant 0.4.0-alpha.2
dsh-multi-tenant 0.4.0-alpha.2
Release posture: alpha integration release. The focused implementation and adversarial closure review completed on 2026-09-03. Git tag v0.4.0-alpha.2 identifies the reviewed source; npm distribution belongs on the alpha dist-tag and must not move latest. A GitHub prerelease and the npm artifact are separate, explicitly created distribution records.
Who should use it
Alpha.2 is intended for DSH host authors who can provide authenticated Principal identities, keep the built-in SQLite directory single-active-process, and treat the shared runtime as logical rather than hostile-code isolation. It is suitable for integrating Agent CRUD, restart/resume, and Agent-scoped MCP before the 0.4 API is declared stable.
Use an exact version for reproducible environments. Expect later alphas to refine host provider contracts. Do not deploy stock DSH /api as the tenant ingress, and do not rely on this plugin to authenticate requests, certify strong isolation, coordinate multiple active processes, or forcibly terminate uncooperative host code.
Stable direction
The project remains a DSH multi-tenant plugin. Its authority path is unchanged:
trusted PrincipalContext
-> plugin-minted AgentId
-> Principal-scoped Agent directory
-> host capability/isolation protocols
-> native DSH Agent / Session / MCP lifecycle
Alpha.2 improves operational correctness inside that boundary. It does not turn the plugin into a process manager, distributed ownership service, secret broker, sandbox, or public ingress.
Abandoned provisioning
The built-in SQLite repository now reconciles every persisted provisioning record to terminal failed when it opens. The update is atomic, revisioned, and completed before the repository can back a MultiTenantService. Ready, already-failed, and deleted records remain unchanged.
Reconciled resources stay indistinguishable from unknown or foreign resources at the product boundary. They are never resumed, and a retry receives fresh Agent and internal session identities. The repository state type and both reference implementations enforce only provisioning -> ready | failed and ready -> ready | deleted.
This behavior relies on the documented host invariant that one process is active for the built-in database. It deliberately adds no lock, PID record, heartbeat, lease, fencing token, takeover, or multi-replica coordination. Custom repositories own recovery for their topology before service registration.
Cooperative provider lifecycle
TenantMcpProvider.load, SecretProvider.acquire, RuntimePartitionRequest, and DshAgentSpecification now carry required lifecycle signals. MCP and Secret acquisition receive the service signal. Runtime-partition acquisition and DSH create/resume receive its combination with SecretLease revocation.
The service validates and freezes MCP snapshots, Secret leases, runtime-partition leases, drivers, and Agent handles before trusting them. Invalid capability results fail closed with stable errors and are disposed when a usable disposer exists. Reference disposers are idempotent.
Shutdown stops admission, aborts pending cooperative acquisition, invalidates callback scopes, cancels live Agents, drains accepted work, then disposes handle, partition, and secret in order. Secret revocation keeps its existing behavior: cancel the live Agent and resume the same session with a fresh lease on the next authorized use.
AbortSignal is a cooperation contract, not forced interruption. A provider or callback that ignores abort or never settles may still delay delete or shutdown indefinitely. No generic timeout, retry framework, provider certification harness, attestation system, or second DI layer was added.
Accepted evidence
- #49: SQLite restart proves abandoned provisioning becomes failed before service use, never reaches DSH, and retries with new identities; both repositories run the legal-state/CAS/Principal-scope contract.
- #50: adversarial tests cover lifecycle propagation through MCP, Secret, partition, create and resume; malformed results, Secret revocation, shutdown mapping, capability invalidation, and cleanup order.
- #54: the final adversarial review checks code, types, documentation, upstream identity, release controls, and the exact final main CI before milestone closure.
- The existing native DSH alpha.5 AgentLoop/JSONL/official-MCP create, restart, same-session resume, and delete evidence remains green.
- Installed-tarball smoke typechecks the required provider signal contracts and exercises every public subpath.
- The latest upstream release was re-queried at review time; it remains DSH
0.1.2-alpha.5atdb6bdc3576c2d4e7c965e8e3ed0c2a731eed87f5.
Explicit limits
- The shared runtime is same-process logical isolation, not a hostile-code boundary.
- Built-in SQLite supports local, single-node, host-enforced single-active-process use only.
- Typert public ingress is absent; stock DSH
/apiremains private/administrative. - Strong isolation is a host provider claim; the plugin only negotiates the declared level.
- Delete revokes plugin access but does not claim physical erasure of DSH logs.
- Host-managed database paths retain host-owned ACL, backup, and encryption policy.
- No
0.3API/data migration or unpublished candidate-schema migration is provided. - Non-cooperative callbacks and providers may prevent bounded shutdown.
中文复盘
发布定位:用于集成的 alpha 预发布版本。v0.4.0-alpha.2 标识完成审查的源码;npm 只应通过 alpha dist-tag 分发,不得移动 latest。GitHub prerelease 与 npm artifact 是独立、显式创建的分发记录。
Alpha.2 面向能够提供已认证 Principal identity、保证内置 SQLite single-active-process,并且把 shared runtime 视为逻辑隔离而不是 hostile-code 边界的 DSH 宿主。它适合在 0.4 API 稳定前接入 Agent CRUD、restart/resume 和 Agent-scoped MCP;需要可复现部署时应固定精确版本,并预期后续 alpha 仍可能调整宿主 provider 契约。
0.4.0-alpha.2 没有改变项目定位,仍然只负责 PrincipalContext -> AgentId -> Principal-scoped Directory -> DSH Agent/Session/MCP。不要把 stock DSH /api 用作租户入口,也不要依赖本插件完成请求认证、强隔离认证、多活动进程协调或强制终止不合作的宿主代码。
#49 在内置 SQLite 打开时,用一次原子更新把全部遗留 provisioning 转为终态 failed,revision 加一;ready、failed、deleted 不受影响。恢复后的资源对产品 API 仍是 not-found,不会触发 DSH resume,重试使用新的 AgentId 和 session。类型和两个参考 Repository 只允许 provisioning -> ready | failed 与 ready -> ready | deleted。
该恢复建立在宿主保证 single-active-process 的明确前提上。插件不实现 lock、PID、heartbeat、lease、fencing、自动 takeover 或分布式协调;自定义 Repository 必须在注册前完成自己的拓扑恢复。
#50 将 service lifecycle AbortSignal 传入 MCP、Secret、runtime partition 和 DSH setup,并把它与 SecretLease revoke signal 组合。所有 provider 返回值会先被校验和冻结;malformed capability 在 DSH 前 fail closed,可用 disposer 会被调用。Shutdown 先停止 admission 和 abort acquisition,再失效 callback、cancel Agent、合作式 drain,最后按 handle、partition、secret 顺序清理。
Abort 不是强制终止。忽略 signal 或永不结束的宿主 provider/callback 仍可能无限延迟 delete/shutdown。本版本不增加默认 timeout、重试框架、provider 认证工具、隔离 attestation、sandbox 或第二套 DI。
其他限制保持不变:shared provider 只有进程内逻辑隔离;SQLite 只支持 local/single-node/宿主保证单活;无 Typert 公网入口;stock DSH /api 仅限私有/管理用途;strong isolation 的真实性由宿主负责;删除不物理擦除 DSH 日志;不迁移 0.3 或旧候选 schema。
dsh-multi-tenant 0.3.0-rc.2
dsh-multi-tenant 0.3.0-rc.2 — First Product Experience
0.3.0-rc.2 moves the v0.3 line from a strong multi-tenant Framework Core to a product-facing MVP that a developer can actually try, understand and copy without first learning the internal composition graph.
What changes for a product developer
The supported first-success path is now:
existing JWT / Cookie / req.user
-> product-owned authentication
-> TrustedSubject
-> canonical Tenant / Principal
-> Tenant MCP config + Principal credentials
-> Principal-aware Agent create/resume
-> official @deepseek-ai/dsh-mcp-client
-> real MCP Tool
-> visible Session / identity isolation
The package still does not own authentication. Products continue to verify JWTs, cookies, OIDC sessions or other credentials using their existing auth stack, then map the trusted result into the multi-tenant Runtime.
Highlights
Runnable First Product Experience on real DSH Web
Install the package into the shipped Web profile and explicitly opt in to the starter:
dsh plugin --profile web add dsh-multi-tenant
DSH_MULTI_TENANT_STARTER=1 dsh webOpen the printed DSH URL plus /_dsh-multi-tenant.
The starter is dormant by default and demonstrates three identities:
Acme / Alice
Acme / Bob
Globex / Alice
The demo uses a real DSH Agent, the official DSH MCP client and a real stdio MCP JSON-RPC server. Its who_am_i Tool proves that the correct Tenant/Principal and Principal credential reached the MCP process without returning the raw credential.
The same flow proves owner Session resume, denied cross-Principal resume, and a second Tenant.
Short product-facing API
createMcpSaaSRuntime() composes the already-proven Core into an opinionated MCP-specific product facade. First-time product code mainly owns four things:
- trusted identity mapping;
- Tenant MCP configuration;
- Principal credentials;
- Agent create/resume.
The Core architecture remains available for advanced composition; this facade does not introduce a second Runtime or DI/lifecycle system.
Thin Web identity/admission bridge
mountMcpSaaSWebBridge() mounts product-aware routes into the existing DSH ctx.webServer.
readBearerToken() and readCookie() are transport extractors only. JWT verification, server-session lookup, OAuth/OIDC, refresh and req.user construction remain product-owned.
First-use diagnostics
Product-facing failures now carry stable, secret-safe stages for identity, Tenant MCP config, Principal credentials, Session ownership, MCP setup and explicit post-create discovery checks.
Raw underlying auth/vendor/credential causes remain server-side and are not serialized by toProductDiagnostic().
Executable release evidence
The permanent First Product Experience proof:
pnpm probe:fpepacks the current candidate, installs it into a clean pinned DSH Web profile, boots real dsh web, then proves over HTTP:
- anonymous identity is rejected;
- Acme/Alice resolves to the correct canonical Principal;
- real Agent creation succeeds;
- official MCP initial connect +
tools/list+ Tool registration succeeds; - real
ToolRuntime.execute()-> MCPtools/callsucceeds; - the Principal credential reaches MCP without being exposed;
- Acme/Alice can resume the persisted Session;
- Acme/Bob is denied Alice's Session before DSH resume runs;
- Globex/Alice proves a second Tenant;
- HTTP/stdout/stderr do not expose the raw starter credential.
pnpm release:check now includes this real-Web FPE proof, so publication cannot succeed if the headline rc.2 product experience regresses.
Public rc.2 product surface
The release preflight and packed-artifact smoke now explicitly protect these public subpaths:
dsh-multi-tenant/product
dsh-multi-tenant/web
dsh-multi-tenant/diagnostics
dsh-multi-tenant/starter
alongside the existing Runtime, composition, ingress, credentials, MCP, store and testing surfaces.
Known boundaries
This release is deliberately an MVP/value-validation prerelease. It does not claim that every stock DSH Web RPC automatically carries a product-authenticated Principal authority. The pinned DSH Web carrier does not yet expose that request-scoped product Principal seam across all existing business RPC dispatch.
Also intentionally non-blocking for rc.2:
- production Redis/Postgres/MySQL
TenantSessionStoreimplementations; - universal Credential Broker /
Capability-as-Authoritypublic contract; - generic OAuth/OIDC/token refresh framework;
- Permission/Policy plugin;
- full Audit/OTel product;
- second ERP/direct-business-API integration;
- hostile-code process/Pod isolation;
- MCP Resources/Prompts beyond the pinned Harness consumer seams.
These gaps should be prioritized from real product usage rather than pulled into the Runtime spec preemptively.
Compatibility
- Node:
^22.19.0 || >=24.0.0 - Cordis:
>=4.0.1 <5 - pinned DSH baseline:
0.1.1-rc.2@b150a551b8d465e31e418e1b2eaf5e79bbb7d28e
0.3.0-rc.2 remains a prerelease. Deliberate breaking changes remain acceptable when real integrations prove a better product or authority contract.
dsh-multi-tenant 0.3.0-rc.1
dsh-multi-tenant 0.3.0-rc.1
0.3.0-rc.1 is the first v0.3 prerelease intended to be used as a complete multi-tenant SaaS Agent foundation rather than only as a low-level Runtime contract.
What problem it solves
A single-user Agent can get away with:
request -> Agent -> MCP -> backend
A SaaS product cannot. Once one Runtime serves multiple organizations and users, identity, credentials, MCP configuration, Session ownership and long-lived Agent lifecycle must remain attributable and isolated.
The supported product path is now:
trusted product subject
-> Product Ingress
-> bound RuntimeComposition
-> canonical Tenant / Principal
-> Tenant MCP config + Principal Credentials
-> one-shot create/resume Operation
-> Principal-owned DSH Agent
-> official @deepseek-ai/dsh-mcp-client
-> native Agent-scoped MCP Tools
A product remains responsible for authentication and loading its own Tenant configuration / Principal credentials. The framework owns Runtime identity, composition integrity, one-shot create/resume decisions, Session ownership checks and DSH-native MCP Agent composition.
Highlights
Product-facing multi-tenant Runtime
- trusted product subject -> validated
TenantPrincipal-> canonical Principal; - deterministic
SaaSDefinition -> CompositionPlan; - exact
CompositionPlan <-> RuntimeCompositionattestation; - scope-local canonical Tenant / Principal identity;
- replaceable Principal-scoped
PrincipalCredentials; - Tenant-scoped MCP configuration;
- immutable fail-closed Session ownership.
Real DSH-native MCP Agent integration
- per-Tenant stdio / Streamable HTTP MCP configuration;
- explicit Principal credential bindings into MCP env / headers during Agent setup;
- high-level
createMcpAgentIntegration(principal)create/resume path; - official
@deepseek-ai/dsh-mcp-clientonly — no parallel MCP protocol implementation; - MCP startup and initial
tools/listcomplete before Agent publication; - native Agent-scoped MCP Tools;
- deterministic per-Principal-Session physical MCP namespaces to coexist with the pinned upstream client's root-wide
serverNamereservation; - Resources / Prompts remain deferred because the pinned Harness has no stable consumer seam for them.
Session safety and lifecycle
- create reserves immutable Session ownership before DSH creation;
- downstream startup failure leaves the Session id fail-closed to the original Principal rather than making it stealable;
- resume validates ownership before DSH persistence/setup is invoked;
- the one-shot Operation owns only the create/resume decision and snapshot;
- the live Agent is Principal-owned, survives the short Operation and is drained by Principal teardown.
v0.3 generation cleanup
This release deliberately resets the active repository around the current product contract.
The live tree no longer preserves superseded prerelease archaeology just because it once existed:
- old v0.1 / v0.2 release notes were removed from
docs/releases/; ROADMAP*was retired in favor of the shorterDIRECTION*;- milestone-named M4/M5 specs were replaced by product-contract names;
- retired one-shot probes and package smoke scripts were removed or consolidated;
- temporary release-audit workflow was deleted after its conclusion became a permanent installed-artifact smoke;
- contribution and release policies explicitly treat the active repository as a live product tree, not a historical archive;
- release preflight rejects retired artifacts if they accidentally return.
Historical value remains available through Git history and tags. The active tree is intentionally optimized for the current 0.3 product and rapid prerelease evolution.
Product-first documentation
The GitHub README and the README shipped to npm now follow the product journey instead of the implementation journey:
what problem does this solve?
-> concrete SaaS scenario
-> what changes after installing it
-> installation
-> minimal product flow
-> architecture / security / evidence
The npm page therefore tells a product developer why the package exists before exposing framework internals.
Executable release evidence
The release-candidate CI proves on Node 22.19 and Node 24:
- exact pinned DSH
0.1.1-rc.2source identity; - current package / architecture / release-tree contract;
- typecheck, tests and build;
- clean installed-artifact smoke beside a real compatible DSH installation;
- packaged resolution of the official MCP client;
- Cordis lifecycle and one-shot Operation assumptions;
- real DSH caller-bound Agent ownership;
- real stdio MCP server via the MCP SDK;
- official MCP client
tools/listdiscovery; - real DSH
ToolRuntime.execute()-> MCPtools/callexecution; - concurrent Acme/Alice, Acme/Bob and Globex/Alice config / credential isolation;
- cross-Principal resume denial before the DSH factory;
- failed MCP startup without half-published Agent;
- Agent / Principal MCP teardown.
The publication workflow additionally installs the exact npm artifact into a clean consumer, verifies package identity/integrity and asserts npm latest points to this exact version.
Compatibility
- Node:
^22.19.0 || >=24.0.0 - Cordis:
>=4.0.1 <5 - pinned DSH compatibility baseline:
0.1.1-rc.2@b150a551b8d465e31e418e1b2eaf5e79bbb7d28e
This remains a prerelease. Deliberate breaking changes are still allowed when real usage proves a better contract, especially around the longer-term Capability-as-Authority / Broker direction.
dsh-multi-tenant 0.2.0-rc.3
dsh-multi-tenant 0.2.0-rc.3
0.2.0-rc.3 is the v0.2 convergence candidate: it brings the final canonical Runtime Contract onto the main release path, refreshes the DeepSeek Harness baseline, and simplifies publication for rapid iteration.
Runtime Contract
The runtime is a canonical ownership tree:
Root -> Tenant -> Principal -> derived integration fibers -> DSH operations
Tenant and Principal share one ensure/get/state/dispose vocabulary. Principal identity is structurally nested under Tenant. Creation is transactionally unpublished until setup/optional commit succeeds.
Preparing creations are first-class cancellable lifecycle resources. Registry shutdown closes admission, cancels unpublished transactions, then drains published scopes. This avoids teardown waiting on work that only teardown itself can cancel.
Agent composition
Principal Contexts remain capability roots. Operations needing extra services derive a Cordis integration fiber and explicitly inject those services. Agent creation therefore uses a Principal-derived fiber injecting agents; DSH carries the caller-bound Context into the Agent factory as ownerCtx.
The project does not fake direct Tenant service inheritance into Agent.ctx or copy private Cordis isolation maps.
Provider contract
dsh-multi-tenant/testing includes an executable Runtime Capability Provider Contract covering tenant/principal A/B isolation, parent/root leakage, inheritance, siblings, disposal, recreation and unpublished setup ownership.
DeepSeek Harness baseline
The explicit compatibility baseline is refreshed to:
- version:
0.1.1-rc.2 - release commit:
b150a551b8d465e31e418e1b2eaf5e79bbb7d28e
CI proves both the exact upstream source identity and behavior of the exact published npm packages. The baseline remains manually advanced; CI does not follow floating upstream state.
Release model
The project now maintains one npm channel during rapid iteration:
- package version is the single release identity;
- npm dist-tag is
latest; - the manual GitHub release workflow reads the version from
package.jsoninstead of asking for duplicate input; - registry smoke verifies
latestresolves to the published version; - SemVer itself expresses prerelease/stable status.
Verification
Before publication the release requires:
- frozen dependency install;
- package/architecture verification;
- release manifest preflight;
- TypeScript typecheck;
- unit + contract tests;
- build;
- packed external-consumer smoke;
- DSH source-baseline verification;
- session genesis proof;
- Agent admission/publication proof;
- Agent owner/composition proof;
- registry smoke after publication.
Next
Once this candidate is merged and published, v0.2 is treated as the Runtime Contract foundation and the main development line moves to v0.3: an opinionated SaaS Framework assembled from a replaceable Plugin Family.
dsh-multi-tenant 0.1.0-rc.2
dsh-multi-tenant 0.1.0-rc.2
0.1.0-rc.2 is a convergence release, not a feature release. It removes one
speculative public API field before the 0.1 contract is considered for stable.
API subtraction
TenantPrincipal is now exactly:
interface TenantPrincipal {
tenantId: string
userId: string
}The required roles field from rc.1 has been removed, together with role-count /
role-length validation. The ownership kernel never consumed roles; retaining the
field would have forced every integration to adopt RBAC vocabulary that the
kernel explicitly does not own.
Callers that only supplied roles to satisfy the rc.1 type should simply remove
that property. Code that actually depended on principal.roles must move that
policy into its authentication/authorization layer rather than the ownership
kernel.
The security invariants are unchanged:
- claim-once immutable
(tenantId, userId)ownership; - unconditional cross-tenant denial;
- same tenant + different user denied in v0.1;
- unknown and foreign sessions fail closed;
- public denial remains non-enumerating;
TenantSessionStoreremains replaceable and contract-tested.
Publishing convergence
The release workflow is now OIDC-only through npm Trusted Publishing. The
one-time NPM_BOOTSTRAP_TOKEN fallback used to create the package for rc.1 is no
longer referenced by the repository.
The workflow still requires:
- dispatch from
mainwith the exact version; - GitHub Environment
npm-release; id-token: write;- full
pnpm release:checkbefore publication; - registry ownership/version preflight;
- registry external-consumer smoke before creating the Git tag / GitHub prerelease.
Compatibility baseline
- DeepSeek Harness target:
0.1.0-rc.7 - Node:
^22.19.0 || >=24.0.0 - npm channel:
next
Explicit boundary
This package still does not provide production multi-user DSH Web transport,
authentication, durable storage, MCP credential isolation, audit persistence,
general RBAC/team ACLs, or shell/filesystem/process/container/network isolation.
After rc.2, the project should stop adding speculative kernel API. Without a real
bug, upstream compatibility change, or concrete user feedback requiring another
contract change, the next release decision is whether to publish 0.1.0 stable.