Răsfoiți Sursa

feat(release): use a private denylist for experimental packages

Tianyi Cui 1 lună în urmă
părinte
comite
6e30e1a300

+ 2 - 2
.agents/notes/implemented/architecture/2026-08-18-experimental-agent-teams-packages.i18n.yaml

@@ -2,5 +2,5 @@
 # side as of the last confirmed-consistent state. Both languages carry equal authority;
 # after editing either side, bring the other along and re-record with:
 #   pnpm run verify-translation-pairing --write .agents/notes/implemented/architecture/2026-08-18-experimental-agent-teams-packages.md
-2026-08-18-experimental-agent-teams-packages.md: c36760587979b234ffd7990035178b0acee53e35
-2026-08-18-experimental-agent-teams-packages.zh.md: 9502ad15ee776564423ccd398d5f77a98a51b730
+2026-08-18-experimental-agent-teams-packages.md: 2a00b651e0073434a5a68df13b9716adcab5fccf
+2026-08-18-experimental-agent-teams-packages.zh.md: df73ee5c05fd3a25bf843bee10b06535a1512783

+ 4 - 4
.agents/notes/implemented/architecture/2026-08-18-experimental-agent-teams-packages.md

@@ -8,13 +8,13 @@ English | [中文](2026-08-18-experimental-agent-teams-packages.zh.md)
 
 Agent Teams needs the real Session log, subagent lifecycle, tools, examples, snapshots, and repository checks while its service and tool contracts continue to change. Users also need to install the complete Team composition from npm without building a source checkout.
 
-Moving the packages into product-role groups would remove their experimental names and imply stable-package ownership. Publishing every package under `packages/experimental/` would instead expose unrelated internal prototypes. The release policy needs an explicit Agent Teams exception while preserving the private default.
+Moving the packages into product-role groups would remove their experimental names and imply stable-package ownership. Publishing every package under `packages/experimental/` would instead expose unrelated internal prototypes. The release policy must let users install Agent Teams while keeping internal-only prototypes private.
 
 ## Decision
 
-`packages/experimental/agent-team`, `packages/experimental/tool-agent-team`, `packages/experimental/agent-team-profile`, `packages/experimental/client-ui-agent-team`, and `packages/experimental/agent-team-web-profile` are public workspace packages. They retain their existing `@deepseek-ai/dsh-experimental-*` names and join the dsh release family. The [experimental package rules](../../../../packages/experimental/AGENTS.md) own the private default, this exception, and later promotion.
+`packages/experimental/agent-team`, `packages/experimental/tool-agent-team`, `packages/experimental/agent-team-profile`, `packages/experimental/client-ui-agent-team`, and `packages/experimental/agent-team-web-profile` are public workspace packages. They retain their existing `@deepseek-ai/dsh-experimental-*` names and join the dsh release family. The [publication denylist decision](../process/2026-09-12-experimental-publication-denylist.md) owns the public default and private exceptions; the [experimental package rules](../../../../packages/experimental/AGENTS.md) own dependency isolation and later promotion.
 
-The dsh pack and publish set and the local baseline publisher include the explicit experimental allowlist. These five Agent Teams directories and the [Cua Driver provider exceptions](2026-09-12-computer-use-provider-registration.md) omit `private`, set `publishConfig.access` to `public`, and keep the experimental npm prefix. Unlisted experimental packages remain private and excluded from publication by default. Release packages and apps outside the experimental group, plus the Python runtime, cannot name experimental packages in `dependencies`, `optionalDependencies`, or `peerDependencies`; experimental packages may depend on release packages and each other.
+The dsh pack and publish set and the local baseline publisher include these five Agent Teams directories and the [Cua Driver providers](2026-09-12-computer-use-provider-registration.md). Workspace constraints require them to omit `private`, set `publishConfig.access` to `public`, and keep the experimental npm prefix. Release packages and apps outside the experimental group, plus the Python runtime, cannot name experimental packages in `dependencies`, `optionalDependencies`, or `peerDependencies`; experimental packages may depend on release packages and each other.
 
 The generic caller-reserved continuable child identity and selective direct-child drain remain in the stable Subagent service. They own Subagent identity and Activation lifecycle without importing or naming Agent Teams; the experimental Team service consumes them in the permitted direction.
 
@@ -38,4 +38,4 @@ Experimental status changes compatibility and support expectations, not publicat
 
 Agent Teams publishes as five installable tarballs in the dsh release family without changing package names or enabling Team in a shipped profile. Public availability does not make the packages stable or supported by default, and stable release packages cannot take runtime dependencies on them.
 
-The release family carries explicitly named experimental exceptions. Promotion still creates path and npm-name churn as specified by the experimental package rules.
+The release family carries the experimental npm names. Promotion still creates path and npm-name churn as specified by the experimental package rules.

+ 4 - 4
.agents/notes/implemented/architecture/2026-08-18-experimental-agent-teams-packages.zh.md

@@ -8,13 +8,13 @@ Status: implemented
 
 Agent Teams 的服务与工具约定仍在变化,但它需要使用真实 Session 日志、subagent 生命周期、工具、示例、快照和仓库检查。用户还需要直接从 npm 安装完整 Team 组合,而无需构建源码 checkout。
 
-把这些包移入产品职责组会移除实验性名称,并暗示稳定包 owner 已经就位。发布 `packages/experimental/` 下的所有包又会暴露无关的内部原型。发布策略需要为 Agent Teams 设置显式例外,同时保留默认私有原则。
+把这些包移入产品职责组会移除实验性名称,并暗示稳定包 owner 已经就位。发布 `packages/experimental/` 下的所有包又会暴露无关的内部原型。发布策略必须让用户安装 Agent Teams,同时让内部专用原型保持私有。
 
 ## 决策
 
-`packages/experimental/agent-team`、`packages/experimental/tool-agent-team`、`packages/experimental/agent-team-profile`、`packages/experimental/client-ui-agent-team` 与 `packages/experimental/agent-team-web-profile` 是公开 workspace 包。它们保留现有 `@deepseek-ai/dsh-experimental-*` 名称并加入 dsh 发布系列。[实验性包规则](../../../../packages/experimental/AGENTS.md)负责默认私有原则、本例外与后续 promotion。
+`packages/experimental/agent-team`、`packages/experimental/tool-agent-team`、`packages/experimental/agent-team-profile`、`packages/experimental/client-ui-agent-team` 与 `packages/experimental/agent-team-web-profile` 是公开 workspace 包。它们保留现有 `@deepseek-ai/dsh-experimental-*` 名称并加入 dsh 发布系列。[发布拒绝列表决策](../process/2026-09-12-experimental-publication-denylist.zh.md)负责默认公开与私有例外;[实验性包规则](../../../../packages/experimental/AGENTS.md)负责依赖隔离与后续 promotion。
 
-dsh 打包与发布集合以及本地基线发布器包含显式实验包允许列表。这五个 Agent Teams 目录以及 [Cua Driver 提供方例外](2026-09-12-computer-use-provider-registration.zh.md)省略 `private`、将 `publishConfig.access` 设为 `public`,并保留实验性 npm 前缀。未列出的实验包默认保持私有且不参与发布。实验组之外的发布包、应用和 Python 运行时不能在 `dependencies`、`optionalDependencies` 或 `peerDependencies` 中引用实验包;实验包可以依赖发布包和彼此。
+dsh 打包与发布集合以及本地基线发布器包含这五个 Agent Teams 目录和 [Cua Driver 提供方](2026-09-12-computer-use-provider-registration.zh.md)。workspace 约束要求它们省略 `private`、将 `publishConfig.access` 设为 `public`,并保留实验性 npm 前缀。实验组之外的发布包、应用和 Python 运行时不能在 `dependencies`、`optionalDependencies` 或 `peerDependencies` 中引用实验包;实验包可以依赖发布包和彼此。
 
 通用的调用方预留 continuable child 身份和精确 direct-child drain 仍属于稳定 Subagent 服务。它们负责 Subagent 身份与 Activation 生命周期,不 import 或命名 Agent Teams;实验性 Team 服务沿允许的方向消费这些能力。
 
@@ -38,4 +38,4 @@ profile 安装通过自身 package manager 解析每个公开 bundle 及其依
 
 Agent Teams 会作为 dsh 发布系列中的五个可安装 tarball 发布,同时保持包名不变,也不会在随附 profile 中启用 Team。公开可用不代表这些包稳定或默认受支持,稳定发布包也不能对其建立运行时依赖。
 
-发布系列需要维护显式命名的实验性例外。promotion 仍会按照实验性包规则产生路径和 npm 名改动。
+发布系列保留实验性 npm 名称。promotion 仍会按照实验性包规则产生路径和 npm 名改动。

+ 2 - 2
.agents/notes/implemented/process/2026-08-10-npm-release-sequences.i18n.yaml

@@ -2,5 +2,5 @@
 # side as of the last confirmed-consistent state. Both languages carry equal authority;
 # after editing either side, bring the other along and re-record with:
 #   pnpm run verify-translation-pairing --write .agents/notes/implemented/process/2026-08-10-npm-release-sequences.md
-2026-08-10-npm-release-sequences.md: 3a52c01494921cacd5df3053fb515461831d6007
-2026-08-10-npm-release-sequences.zh.md: f973b442f2bbf6400ef0b75650392744a489ace3
+2026-08-10-npm-release-sequences.md: 77b73b8c461238ad80afd7abd609a68df0bcf058
+2026-08-10-npm-release-sequences.zh.md: f56234fc50d776658d2d9191056b0b04e1609f1e

+ 1 - 1
.agents/notes/implemented/process/2026-08-10-npm-release-sequences.md

@@ -22,7 +22,7 @@ Two hard blockers sat in the way. All 217 workspace manifests set `private: true
 
 | Sequence | Members | Version baseline | Tag | Workflow |
 |---|---|---|---|---|
-| dsh | Publish set: non-experimental `packages/*/*` + `apps/*`; private experimental packages join only the shared version bump | one version for the publish set, private dsh packages, and workspace root, `0.0.x` | `dsh-v<version>` | `release.yml` (pack) / `release-publish.yml` (publish) |
+| dsh | Publish set: public members of `packages/*/*` + `apps/*`, with [private experimental exceptions](2026-09-12-experimental-publication-denylist.md); private packages join only the shared version bump | one version for the publish set, private dsh packages, and workspace root, `0.0.x` | `dsh-v<version>` | `release.yml` (pack) / `release-publish.yml` (publish) |
 | vendored framework | the nine `vendor/*` packages | each package on its own version line | `vendor-<package>-v<version>` (one per package) | `release-vendor.yml` (pack) / `release-vendor-publish.yml` (publish) |
 | native | `native/system/packages/*` | its own `0.0.x` | `node-addon-system-v<version>` | `node-addon-system-release.yml` |
 

+ 1 - 1
.agents/notes/implemented/process/2026-08-10-npm-release-sequences.zh.md

@@ -22,7 +22,7 @@ Status: implemented
 
 | 序列 | 成员 | 版本基线 | tag | workflow |
 |---|---|---|---|---|
-| dsh | 发布集:非 experimental 的 `packages/*/*` + `apps/*`;私有实验性包仅加入共享版本 bump | 发布集、私有 dsh 包与 workspace 根共用一个 `0.0.x` | `dsh-v<版本>` | `release.yml`(pack)/ `release-publish.yml`(发布) |
+| dsh | 发布集:`packages/*/*` + `apps/*` 中的公开成员,保留[私有实验包例外](2026-09-12-experimental-publication-denylist.zh.md);私有包仅加入共享版本 bump | 发布集、私有 dsh 包与 workspace 根共用一个 `0.0.x` | `dsh-v<版本>` | `release.yml`(pack)/ `release-publish.yml`(发布) |
 | vendored framework | `vendor/*` 九个包 | 每包各自一条版本线 | `vendor-<包名>-v<版本>`(每包一个) | `release-vendor.yml`(pack)/ `release-vendor-publish.yml`(发布) |
 | native | `native/system/packages/*` | 自己的 `0.0.x` | `node-addon-system-v<版本>` | `node-addon-system-release.yml` |
 

+ 6 - 0
.agents/notes/implemented/process/2026-09-12-experimental-publication-denylist.i18n.yaml

@@ -0,0 +1,6 @@
+# Bilingual-pair consistency record (docs/i18n/README.md): the git blob hash of each
+# side as of the last confirmed-consistent state. Both languages carry equal authority;
+# after editing either side, bring the other along and re-record with:
+#   pnpm run verify-translation-pairing --write .agents/notes/implemented/process/2026-09-12-experimental-publication-denylist.md
+2026-09-12-experimental-publication-denylist.md: 2dafcc77a8e44fd608695e73c718e58b7a850a21
+2026-09-12-experimental-publication-denylist.zh.md: 36ac886ad1a5ec60436cf49fdf176918a85c4fb0

+ 27 - 0
.agents/notes/implemented/process/2026-09-12-experimental-publication-denylist.md

@@ -0,0 +1,27 @@
+# Agent Note: Publish experimental packages with explicit private exceptions
+
+Status: implemented
+
+English | [中文](2026-09-12-experimental-publication-denylist.zh.md)
+
+## Problem
+
+An allowlist for public experimental packages requires a policy edit whenever a new installable prototype joins the repository. Experimental status describes compatibility and support expectations, but internal-only prototypes still need an explicit publication exclusion.
+
+## Decision
+
+The local npm baseline publisher and the public dsh release family discover experimental packages by default. [`PRIVATE_EXPERIMENTAL_PACKAGE_DIRECTORIES`](../../../../scripts/experimental-package-policy.ts) excludes `auto-review`, `inspector`, `ptc-runtime-python`, `webworker-packer`, and `webworker-runtime` under `packages/experimental/`. These packages retain `private: true` and omit `publishConfig`. The Agent Teams packages and Cua Driver providers remain the current public experimental members, so the denylist preserves the existing publication set.
+
+Every experimental directory outside the denylist is public by default. Workspace constraints require public packages to omit `private` and set `publishConfig.access: public`; all experimental packages retain the `@deepseek-ai/dsh-experimental-*` npm prefix. Adding a private prototype requires a denylist entry as well as its private manifest.
+
+This decision supersedes the private publication default in the [Agent Teams package decision](../architecture/2026-08-18-experimental-agent-teams-packages.md). Its dependency isolation, opt-in composition, engineering requirements, and promotion rules remain active. Publication grants neither stability nor a support promise.
+
+## Alternatives considered
+
+**Retain a public allowlist.** Every new public experimental package needs another policy entry, even though the default publication path can discover it.
+
+**Publish every experimental package immediately.** This would expose the existing internal-only prototypes. An explicit private denylist changes the default for new packages while preserving their current publication status.
+
+## Consequences
+
+New experimental packages join both npm publication paths without an allowlist edit. Private exceptions have one shared owner, and workspace validation rejects manifests that disagree with it.

+ 27 - 0
.agents/notes/implemented/process/2026-09-12-experimental-publication-denylist.zh.md

@@ -0,0 +1,27 @@
+# Agent Note: 默认发布实验性包并保留显式私有例外
+
+Status: implemented
+
+[English](2026-09-12-experimental-publication-denylist.md) | 中文
+
+## 问题
+
+公开实验性包的允许列表要求每个新加入仓库的可安装原型都修改一次策略。实验性状态描述兼容性与支持预期,但内部专用原型仍需要显式排除发布。
+
+## 决策
+
+本地 npm baseline 发布器与公开 dsh 发布系列默认发现实验性包。[`PRIVATE_EXPERIMENTAL_PACKAGE_DIRECTORIES`](../../../../scripts/experimental-package-policy.ts) 排除 `packages/experimental/` 下的 `auto-review`、`inspector`、`ptc-runtime-python`、`webworker-packer` 与 `webworker-runtime`。这些包保留 `private: true`,并省略 `publishConfig`。Agent Teams 包与 Cua Driver 提供方仍是当前公开的实验性成员,因此拒绝列表保留现有发布集合。
+
+拒绝列表以外的每个实验性目录默认公开。workspace 约束要求公开包省略 `private` 并设置 `publishConfig.access: public`;所有实验性包保留 `@deepseek-ai/dsh-experimental-*` npm 前缀。添加私有原型需要拒绝列表条目及其私有 manifest(元数据清单)。
+
+本决策取代 [Agent Teams 包决策](../architecture/2026-08-18-experimental-agent-teams-packages.zh.md)中的默认私有发布原则。该决策的依赖隔离、显式启用组合、工程要求与 promotion 规则继续生效。发布不提供稳定性或支持承诺。
+
+## 曾考虑的替代方案
+
+**保留公开允许列表。** 即使默认发布路径能够发现新公开实验性包,每个包仍需要额外的策略条目。
+
+**立即发布所有实验性包。** 这会暴露现有的内部专用原型。显式私有拒绝列表改变新包的默认策略,同时保留这些原型的当前发布状态。
+
+## 后果
+
+新实验性包无需修改允许列表即可加入两条 npm 发布路径。私有例外有一个共享 owner,workspace 校验会拒绝与之不符的 manifest。

+ 1 - 1
AGENTS.md

@@ -62,7 +62,7 @@ packages/    @deepseek-ai/dsh-<pkg> workspaces at packages/<group>/<pkg>/
   host/                 GUI host
   client/               GUI client
   mcp/                  external tools
-  experimental/         pre-stable prototypes; private by default with explicit public exceptions
+  experimental/         pre-stable prototypes; public by default with explicit private exceptions
   test-support/         test infrastructure
   runtime-diagnostics/  runtime invariants
   util/                 zero-dependency utilities

+ 2 - 2
packages/README.i18n.yaml

@@ -2,5 +2,5 @@
 # side as of the last confirmed-consistent state. Both languages carry equal authority;
 # after editing either side, bring the other along and re-record with:
 #   pnpm run verify-translation-pairing --write packages/README.md
-README.md: eaea9ac6c9c18ebba9e01bcbaff3ae070b9a78de
-README.zh.md: 7941839c7fb924baaeb7df227c085265b66dac76
+README.md: b15d9b11822772702b92fac9be24afdbdd885785
+README.zh.md: 1f572953fffc2bbd7a55a9417ee179e43b64f300

+ 2 - 2
packages/README.md

@@ -50,7 +50,7 @@ Every package lives in exactly one group; new packages join existing groups, and
 | [`context/`](context/README.md) | Model-visible request context: workspace instructions, time context, references |
 | [`subagent/`](subagent/README.md) | Subagent capability family: provider-registry contract and model-facing delegation tools |
 | [`jobs/`](jobs/README.md) | Generic background-job runtime and model-facing job control tools |
-| [`experimental/`](experimental/README.md) | Experimental prototypes with explicit public npm exceptions |
+| [`experimental/`](experimental/README.md) | Pre-stable prototypes with explicit private exceptions |
 | [`workflow/`](workflow/README.md) | Workflow seam, worker-thread engine, and model-facing `workflow`/`ralph` tools |
 | [`webhook/`](webhook/README.md) | Verified external events, trusted rules, and fire-and-forget Workspace Sessions |
 | [`web/`](web/README.md) | Web capability family: seam, search/fetch providers, model-facing web tools |
@@ -85,7 +85,7 @@ Every package lives in exactly one group; new packages join existing groups, and
 <a id="release-expectations"></a>
 ## Release expectations
 
-Most groups are product — stable API. The exceptions: `experimental/` publishes only explicitly allowlisted packages, and `test-support/`, `runtime-diagnostics/`, and `util/` are support with lower compatibility expectations.
+Most groups are product — stable API. The exceptions: `experimental/` publishes without stability or support promises, and `test-support/`, `runtime-diagnostics/`, and `util/` are support with lower compatibility expectations.
 
 -----
 

+ 2 - 2
packages/README.zh.md

@@ -50,7 +50,7 @@ harness 由 `packages/` 下的 npm 包组装而成,按能力系列分组:会
 | [`context/`](context/README.zh.md) | 模型可见请求上下文:workspace 指令、时间上下文、引用 |
 | [`subagent/`](subagent/README.zh.md) | subagent 能力系列:提供方注册表约定和面向模型的委托工具 |
 | [`jobs/`](jobs/README.zh.md) | 通用后台任务运行时和面向模型的作业控制工具 |
-| [`experimental/`](experimental/README.zh.md) | 实验性原型和显式公开 npm 例外 |
+| [`experimental/`](experimental/README.zh.md) | 预稳定原型,包含显式私有例外 |
 | [`workflow/`](workflow/README.zh.md) | 工作流 seam、worker 线程引擎、面向模型的 `workflow`/`ralph` 工具 |
 | [`webhook/`](webhook/README.zh.md) | 已验证外部事件、受信规则与即发即弃 Workspace 会话 |
 | [`web/`](web/README.zh.md) | Web 能力系列:seam、搜索/获取提供方、面向模型的 Web 工具 |
@@ -85,7 +85,7 @@ harness 由 `packages/` 下的 npm 包组装而成,按能力系列分组:会
 <a id="release-expectations"></a>
 ## 发布预期
 
-大多数组属于产品组,提供稳定 API。例外:`experimental/` 仅发布显式允许列表中的包,`test-support/`、`runtime-diagnostics/` 与 `util/` 是兼容性预期较低的支持组。
+大多数组属于产品组,提供稳定 API。例外:`experimental/` 发布时不提供稳定性或支持承诺,`test-support/`、`runtime-diagnostics/` 与 `util/` 是兼容性预期较低的支持组。
 
 -----
 

+ 3 - 3
packages/experimental/AGENTS.md

@@ -1,9 +1,9 @@
 # AGENTS.md — Experimental packages
 
-These rules supplement the [package rules](../AGENTS.md). The [experimental Agent Teams package decision](../../.agents/notes/implemented/architecture/2026-08-18-experimental-agent-teams-packages.md) owns the rationale.
+These rules supplement the [package rules](../AGENTS.md). The [experimental publication decision](../../.agents/notes/implemented/process/2026-09-12-experimental-publication-denylist.md) owns the publication policy; the [Agent Teams package decision](../../.agents/notes/implemented/architecture/2026-08-18-experimental-agent-teams-packages.md) owns dependency isolation and promotion rationale.
 
 - A package belongs here only when its complete public contract is experimental or internal-only. An experimental option inside a release package stays with its owning product role.
-- Every package here uses the `@deepseek-ai/dsh-experimental-*` npm prefix. Packages are private by default and omit `publishConfig`; the allowlisted Agent Teams and computer-use provider packages are explicit public exceptions that keep their experimental names, set `publishConfig.access: public`, and join the dsh release family.
+- Every package here uses the `@deepseek-ai/dsh-experimental-*` npm prefix and joins the dsh release family by default: omit `private` and set `publishConfig.access: public`. Only directories in `PRIVATE_EXPERIMENTAL_PACKAGE_DIRECTORIES` in [the publication policy](../../scripts/experimental-package-policy.ts) stay private: set `private: true` and omit `publishConfig`.
 - Release packages and apps outside this group must not name experimental packages in `dependencies`, `optionalDependencies`, or `peerDependencies`. Experimental packages may depend on release packages and each other. Tests may use experimental packages through `devDependencies`; examples may load them explicitly.
 - Experimental status does not relax engineering, security, documentation, lifecycle, testing, invariant, or snapshot requirements.
-- Publishing an explicit exception does not promote it or add a stability promise. Promotion moves a package to its product-role group and removes `experimental-` from its npm name; update every import and configuration row atomically, then review its public contract, limitations, test evidence, release payload, runtime dependents, and named stable owner.
+- Publishing an experimental package does not promote it or add a stability promise. Promotion moves a package to its product-role group and removes `experimental-` from its npm name; update every import and configuration row atomically, then review its public contract, limitations, test evidence, release payload, runtime dependents, and named stable owner.

+ 2 - 2
packages/experimental/README.i18n.yaml

@@ -2,5 +2,5 @@
 # side as of the last confirmed-consistent state. Both languages carry equal authority;
 # after editing either side, bring the other along and re-record with:
 #   pnpm run verify-translation-pairing --write packages/experimental/README.md
-README.md: a3bba024b5f2dfa3609c54e9a6288463ac475412
-README.zh.md: 0b2ee06ec301c41ae73140300ace9d74510e9efc
+README.md: acf9d1d23bccbf046ca828618062b972c4f98ff5
+README.zh.md: 0ad08eba1e2212318ca9df259c20b86673970c54

+ 3 - 3
packages/experimental/README.md

@@ -1,5 +1,5 @@
 ---
-description: "The experimental group map: pre-stable prototypes that are private by default, with explicit public Agent Teams and computer-use packages."
+description: "The experimental group map: pre-stable prototypes that publish by default, with explicit private exceptions."
 kind: "package-group"
 ---
 
@@ -9,7 +9,7 @@ English | [中文](README.zh.md)
 
 ## Summary
 
-The experimental group contains prototype capabilities whose contracts can change and carry no support promise. Packages are private by default; the allowlisted Agent Teams and Cua Driver packages are published opt-in exceptions under their existing `@deepseek-ai/dsh-experimental-*` names. The group also holds the private cross-realm Inspector, CPython subprocess backend, and browser-worker preview packages. Released products outside this group must not depend on experimental packages.
+The experimental group contains prototype capabilities whose contracts can change and carry no support promise. Packages publish by default under their `@deepseek-ai/dsh-experimental-*` names; the Agent Teams composition and Cua Driver providers are installable opt-ins. Auto review, the cross-realm Inspector, the CPython subprocess backend, and the browser-worker preview packages remain explicit private exceptions. Released products outside this group must not depend on experimental packages.
 
 ## Table of Contents
 
@@ -42,7 +42,7 @@ The experimental group contains prototype capabilities whose contracts can chang
 <a id="related-documentation"></a>
 ## Related documentation
 
-- [Experimental package decision](../../.agents/notes/implemented/architecture/2026-08-18-experimental-agent-teams-packages.md) — private defaults, public Agent Teams exceptions, and dependency isolation.
+- [Experimental publication decision](../../.agents/notes/implemented/process/2026-09-12-experimental-publication-denylist.md) — public defaults and private exceptions.
 - [Computer use](../../docs/subsystems/computer-use.md) — desktop provider choices.
 - [Agent Teams subsystem](../../docs/subsystems/agent-team.md) — durable Team types and the `ctx.agentTeams` service API.
 - [Experimental subtree rules](AGENTS.md) — what experimental status does and does not relax.

+ 3 - 3
packages/experimental/README.zh.md

@@ -1,5 +1,5 @@
 ---
-description: "实验组地图:默认私有的预稳定原型,以及显式公开发布的 Agent Teams 和计算机操作包。"
+description: "实验组地图:默认发布的预稳定原型,以及显式私有例外。"
 kind: "package-group"
 ---
 
@@ -9,7 +9,7 @@ kind: "package-group"
 
 ## 概述
 
-实验组包含约定可能变更且不提供支持承诺的原型能力。包默认私有;允许列表中的 Agent Teams 和 Cua Driver 包是显式公开发布的例外,并保留现有 `@deepseek-ai/dsh-experimental-*` 名称。本组还包含私有的跨 realm Inspector、CPython 子进程后端与浏览器 worker 预览包。组外已发布产品不得依赖实验性包。
+实验组包含约定可能变更且不提供支持承诺的原型能力。包默认以 `@deepseek-ai/dsh-experimental-*` 名称发布;Agent Teams 组合和 Cua Driver 提供方可安装并显式启用。Auto review、跨 realm Inspector、CPython 子进程后端与浏览器 worker 预览包仍是显式私有例外。组外已发布产品不得依赖实验性包。
 
 ## 目录
 
@@ -42,7 +42,7 @@ kind: "package-group"
 <a id="related-documentation"></a>
 ## 相关文档
 
-- [实验包决策](../../.agents/notes/implemented/architecture/2026-08-18-experimental-agent-teams-packages.zh.md)——默认私有、Agent Teams 公开例外与依赖隔离。
+- [实验包发布决策](../../.agents/notes/implemented/process/2026-09-12-experimental-publication-denylist.zh.md)——默认公开与私有例外。
 - [计算机操作](../../docs/subsystems/computer-use.zh.md)——桌面提供方选择。
 - [Agent Teams 子系统](../../docs/subsystems/agent-team.zh.md)——持久 Team 类型与 `ctx.agentTeams` 服务 API。
 - [实验子树规则](AGENTS.md)——实验状态放宽了什么、不放宽什么。

+ 38 - 24
scripts/check-workspace-constraints.spec.ts

@@ -1,6 +1,10 @@
 /** Experimental-package publication and dependency constraints. */
 
 import { describe, expect, it } from 'vitest'
+import {
+  isPublicExperimentalPackageDirectory,
+  PRIVATE_EXPERIMENTAL_PACKAGE_DIRECTORIES,
+} from './experimental-package-policy.ts'
 import {
   checkDshFamilyVersion,
   checkExperimentalDependencyIsolation,
@@ -9,18 +13,13 @@ import {
   type WorkspaceManifest,
 } from './check-workspace-constraints.ts'
 
-const experimental: WorkspaceManifest = {
+const experimental = {
   dir: 'packages/experimental/prototype',
-  manifest: { name: '@deepseek-ai/dsh-experimental-prototype', private: true },
-}
-
-const publicExperimental: WorkspaceManifest = {
-  dir: 'packages/experimental/agent-team',
   manifest: {
-    name: '@deepseek-ai/dsh-experimental-agent-team',
+    name: '@deepseek-ai/dsh-experimental-prototype',
     publishConfig: { access: 'public' },
   },
-}
+} satisfies WorkspaceManifest
 
 describe('experimental workspace constraints', () => {
   it('requires the experimental package-name prefix', () => {
@@ -32,29 +31,44 @@ describe('experimental workspace constraints', () => {
     ])
   })
 
-  it('requires private manifests without publication metadata', () => {
+  it('requires public metadata for unlisted experimental packages', () => {
     expect(checkExperimentalManifest(experimental)).toEqual([])
     expect(checkExperimentalManifest({
       ...experimental,
-      manifest: { ...experimental.manifest, private: false, publishConfig: { access: 'public' } },
+      manifest: { name: experimental.manifest.name, private: true },
     })).toEqual([
-      '@deepseek-ai/dsh-experimental-prototype: experimental package must set "private": true',
-      '@deepseek-ai/dsh-experimental-prototype: experimental package must omit publishConfig',
+      '@deepseek-ai/dsh-experimental-prototype: public experimental package must not set "private": true',
+      '@deepseek-ai/dsh-experimental-prototype: public experimental package must set publishConfig.access to "public"',
     ])
   })
 
-  it('requires public metadata only for the Agent Teams exceptions', () => {
-    expect(checkExperimentalManifest(publicExperimental)).toEqual([])
-    expect(checkExperimentalManifest({
-      ...publicExperimental,
-      manifest: {
-        name: '@deepseek-ai/dsh-experimental-agent-team',
-        private: true,
-      },
-    })).toEqual([
-      '@deepseek-ai/dsh-experimental-agent-team: public experimental package must not set "private": true',
-      '@deepseek-ai/dsh-experimental-agent-team: public experimental package must set publishConfig.access to "public"',
-    ])
+  it.each(PRIVATE_EXPERIMENTAL_PACKAGE_DIRECTORIES)(
+    'requires private metadata for denylisted %s',
+    (dir) => {
+      const name = `@deepseek-ai/dsh-experimental-${dir.split('/').at(-1)}`
+      expect(checkExperimentalManifest({ dir, manifest: { name, private: true } })).toEqual([])
+      expect(checkExperimentalManifest({
+        dir,
+        manifest: { name, publishConfig: { access: 'public' } },
+      })).toEqual([
+        `${name}: experimental package must set "private": true`,
+        `${name}: experimental package must omit publishConfig`,
+      ])
+    },
+  )
+
+  it('limits the public default to experimental package directories', () => {
+    expect(isPublicExperimentalPackageDirectory(experimental.dir)).toBe(true)
+    for (const dir of [
+      'packages/core/session',
+      'apps/cli',
+      'vendor/cordis',
+      'packages/experimental',
+      'packages/experimental/prototype/src',
+      ...PRIVATE_EXPERIMENTAL_PACKAGE_DIRECTORIES,
+    ]) {
+      expect(isPublicExperimentalPackageDirectory(dir)).toBe(false)
+    }
   })
 
   it.each(['dependencies', 'optionalDependencies', 'peerDependencies'] as const)(

+ 1 - 1
scripts/check-workspace-constraints.ts

@@ -276,7 +276,7 @@ function usesEmittedTreeDefaults(manifest: PackageManifest): boolean {
     exportDefault(manifest, subpath)?.startsWith('./lib/types/') === true)
 }
 
-/** Experimental manifest requirements, including explicit public exceptions. */
+/** Experimental manifest requirements, including explicit private exceptions. */
 export function checkExperimentalManifest({ dir, manifest }: WorkspaceManifest): string[] {
   if (!experimentalPackageDirectory.test(dir)) return []
   const label = manifest.name ?? dir

+ 11 - 12
scripts/experimental-package-policy.ts

@@ -1,21 +1,20 @@
-/** Experimental packages that publish with the dsh release family without changing names. */
-export const PUBLIC_EXPERIMENTAL_PACKAGE_DIRECTORIES = [
-  'packages/experimental/agent-team',
-  'packages/experimental/agent-team-profile',
-  'packages/experimental/agent-team-web-profile',
-  'packages/experimental/client-ui-agent-team',
-  'packages/experimental/tool-agent-team',
-  'packages/experimental/computer-use-cua-driver-mcp',
-  'packages/experimental/computer-use-cua-driver-native',
+/** Experimental packages excluded from public releases and npm baselines. */
+export const PRIVATE_EXPERIMENTAL_PACKAGE_DIRECTORIES = [
+  'packages/experimental/auto-review',
+  'packages/experimental/inspector',
+  'packages/experimental/ptc-runtime-python',
+  'packages/experimental/webworker-packer',
+  'packages/experimental/webworker-runtime',
 ] as const
 
-const publicExperimentalPackageDirectories = new Set<string>(PUBLIC_EXPERIMENTAL_PACKAGE_DIRECTORIES)
+const privateExperimentalPackageDirectories = new Set<string>(PRIVATE_EXPERIMENTAL_PACKAGE_DIRECTORIES)
 
 /**
- * Whether an experimental package is an explicit public-release exception.
+ * Whether an experimental package publishes under the default-public policy.
  * @param directory - repository-relative package directory.
  * @returns Whether the package publishes with the dsh family.
  */
 export function isPublicExperimentalPackageDirectory(directory: string): boolean {
-  return publicExperimentalPackageDirectories.has(directory)
+  return /^packages\/experimental\/[^/]+$/.test(directory)
+    && !privateExperimentalPackageDirectories.has(directory)
 }

+ 6 - 4
scripts/publish-npm-baseline.ts

@@ -18,16 +18,15 @@ import { basename, dirname, isAbsolute, join, normalize, relative, resolve, sep
 import { createInterface } from 'node:readline/promises'
 import { pathToFileURL } from 'node:url'
 import { parseArgs } from 'node:util'
-import { PUBLIC_EXPERIMENTAL_PACKAGE_DIRECTORIES } from './experimental-package-policy.ts'
+import { PRIVATE_EXPERIMENTAL_PACKAGE_DIRECTORIES } from './experimental-package-policy.ts'
 import { validateTarballPayload } from './publication-payload.ts'
 
 const DEFAULT_REGISTRY = 'https://registry.npm.harnessment.com'
 const DEFAULT_OUTPUT_DIRECTORY = '.artifacts/npm-baseline'
 const PACKAGE_PATTERNS = [
   'vendor/*/package.json',
-  'packages/!(experimental)/*/package.json',
+  'packages/*/*/package.json',
   'apps/*/package.json',
-  ...PUBLIC_EXPERIMENTAL_PACKAGE_DIRECTORIES.map(directory => `${directory}/package.json`),
 ] as const
 const DEPENDENCY_SECTIONS = [
   'dependencies',
@@ -244,7 +243,10 @@ class WorkspacePackageSet {
   ) {}
 
   static discover(root: string): WorkspacePackageSet {
-    const manifestPaths = globSync(PACKAGE_PATTERNS, { cwd: root }).sort()
+    const manifestPaths = globSync(PACKAGE_PATTERNS, {
+      cwd: root,
+      exclude: PRIVATE_EXPERIMENTAL_PACKAGE_DIRECTORIES.map(directory => `${directory}/package.json`),
+    }).sort()
     if (manifestPaths.length === 0) {
       throw new Error('no package manifests found under vendor/, packages/, or apps/')
     }

+ 20 - 1
scripts/release/families.spec.ts

@@ -42,7 +42,7 @@ afterEach(() => {
 })
 
 describe('release families', () => {
-  it('publishes allowlisted experimental packages while excluding private prototypes', () => {
+  it('retains public experimental packages while excluding private prototypes', () => {
     const members = releaseFamily('dsh').members(resolve(import.meta.dirname, '../..'))
 
     expect(members
@@ -68,6 +68,25 @@ describe('release families', () => {
     expect(releaseFamily('dsh').members(root).map(entry => entry.name)).toEqual(['@deepseek-ai/dsh-public'])
   })
 
+  it('publishes unlisted experimental packages while retaining private exclusions', () => {
+    const root = mkdtempSync(join(tmpdir(), 'dsh-release-experimental-'))
+    roots.push(root)
+    write(join(root, 'packages/experimental/prototype/package.json'), JSON.stringify({
+      name: '@deepseek-ai/dsh-experimental-prototype',
+      version: '0.0.1',
+      publishConfig: { access: 'public' },
+    }))
+    write(join(root, 'packages/experimental/inspector/package.json'), JSON.stringify({
+      name: '@deepseek-ai/dsh-experimental-inspector',
+      version: '0.0.1',
+      private: true,
+    }))
+
+    expect(releaseFamily('dsh').members(root).map(entry => entry.name)).toEqual([
+      '@deepseek-ai/dsh-experimental-prototype',
+    ])
+  })
+
   it('bumps private dsh workspaces without adding release tags', () => {
     const root = mkdtempSync(join(tmpdir(), 'dsh-release-version-'))
     roots.push(root)

+ 1 - 3
scripts/release/families.ts

@@ -15,7 +15,6 @@ import {
   officialClientBuildEnvironment,
   readClientBuildRecord,
 } from '../client-build-environment.ts'
-import { PUBLIC_EXPERIMENTAL_PACKAGE_DIRECTORIES } from '../experimental-package-policy.ts'
 import { validateTarballPayload } from '../publication-payload.ts'
 
 /**
@@ -323,9 +322,8 @@ export abstract class ReleaseFamily {
 class DshFamily extends ReleaseFamily {
   readonly id = 'dsh'
   readonly patterns = [
-    'packages/!(experimental)/*/package.json',
+    'packages/*/*/package.json',
     'apps/*/package.json',
-    ...PUBLIC_EXPERIMENTAL_PACKAGE_DIRECTORIES.map(directory => `${directory}/package.json`),
   ] as const
   readonly tagPrefix = 'dsh-v'