Просмотр исходного кода

Merge pull request #2787 from deepseek-harness/worktree-rename-team

refactor: mark Agent Teams packages as experimental
imccyu 1 месяц назад
Родитель
Сommit
b862725e74
94 измененных файлов с 749 добавлено и 604 удалено
  1. 2 2
      .agents/notes/implemented/architecture/2026-08-18-experimental-agent-teams-packages.i18n.yaml
  2. 3 5
      .agents/notes/implemented/architecture/2026-08-18-experimental-agent-teams-packages.md
  3. 3 5
      .agents/notes/implemented/architecture/2026-08-18-experimental-agent-teams-packages.zh.md
  4. 6 0
      .agents/notes/implemented/architecture/2026-08-19-experimental-package-name-prefix.i18n.yaml
  5. 29 0
      .agents/notes/implemented/architecture/2026-08-19-experimental-package-name-prefix.md
  6. 29 0
      .agents/notes/implemented/architecture/2026-08-19-experimental-package-name-prefix.zh.md
  7. 2 2
      .agents/notes/implemented/feature/2026-08-05-agent-teams.i18n.yaml
  8. 1 1
      .agents/notes/implemented/feature/2026-08-05-agent-teams.md
  9. 1 1
      .agents/notes/implemented/feature/2026-08-05-agent-teams.zh.md
  10. 2 2
      .agents/notes/implemented/process/2026-08-10-npm-release-sequences.i18n.yaml
  11. 2 2
      .agents/notes/implemented/process/2026-08-10-npm-release-sequences.md
  12. 2 2
      .agents/notes/implemented/process/2026-08-10-npm-release-sequences.zh.md
  13. 2 2
      .agents/notes/implemented/simplification/2026-08-12-trim-agent-teams-read-and-lifecycle-surface.i18n.yaml
  14. 1 1
      .agents/notes/implemented/simplification/2026-08-12-trim-agent-teams-read-and-lifecycle-surface.md
  15. 1 1
      .agents/notes/implemented/simplification/2026-08-12-trim-agent-teams-read-and-lifecycle-surface.zh.md
  16. 2 2
      docs/architecture.i18n.yaml
  17. 1 1
      docs/architecture.md
  18. 1 1
      docs/architecture.zh.md
  19. 2 2
      docs/capability-seams.i18n.yaml
  20. 6 6
      docs/capability-seams.md
  21. 6 6
      docs/capability-seams.zh.md
  22. 2 2
      docs/config-catalog.i18n.yaml
  23. 42 42
      docs/config-catalog.md
  24. 42 44
      docs/config-catalog.zh.md
  25. 2 2
      docs/event-producer-consumer.i18n.yaml
  26. 7 7
      docs/event-producer-consumer.md
  27. 7 7
      docs/event-producer-consumer.zh.md
  28. 2 2
      docs/module-graph.i18n.yaml
  29. 17 17
      docs/module-graph.md
  30. 17 17
      docs/module-graph.zh.md
  31. 2 2
      docs/persistence-catalog.i18n.yaml
  32. 8 8
      docs/persistence-catalog.md
  33. 8 8
      docs/persistence-catalog.zh.md
  34. 2 2
      docs/subsystems/README.i18n.yaml
  35. 1 1
      docs/subsystems/README.md
  36. 1 1
      docs/subsystems/README.zh.md
  37. 3 3
      docs/subsystems/agent-team.i18n.yaml
  38. 6 6
      docs/subsystems/agent-team.md
  39. 6 6
      docs/subsystems/agent-team.zh.md
  40. 2 2
      docs/tool-catalog.i18n.yaml
  41. 13 13
      docs/tool-catalog.md
  42. 12 12
      docs/tool-catalog.zh.md
  43. 4 4
      examples/headless-agent/team.cordis.snapshot.yml
  44. 2 2
      examples/package.json
  45. 2 2
      packages/experimental/AGENTS.md
  46. 2 2
      packages/experimental/README.i18n.yaml
  47. 2 2
      packages/experimental/README.md
  48. 2 2
      packages/experimental/README.zh.md
  49. 3 3
      packages/experimental/agent-team/README.i18n.yaml
  50. 5 5
      packages/experimental/agent-team/README.md
  51. 5 5
      packages/experimental/agent-team/README.zh.md
  52. 2 2
      packages/experimental/agent-team/package.json
  53. 0 0
      packages/experimental/agent-team/src/activity.ts
  54. 0 0
      packages/experimental/agent-team/src/error.ts
  55. 0 0
      packages/experimental/agent-team/src/fold.ts
  56. 3 3
      packages/experimental/agent-team/src/index.ts
  57. 1 1
      packages/experimental/agent-team/src/invariant.ts
  58. 0 0
      packages/experimental/agent-team/src/journal.ts
  59. 0 0
      packages/experimental/agent-team/src/lifecycle.ts
  60. 0 0
      packages/experimental/agent-team/src/mailbox.ts
  61. 0 0
      packages/experimental/agent-team/src/roster.ts
  62. 0 0
      packages/experimental/agent-team/src/session-message.ts
  63. 0 0
      packages/experimental/agent-team/src/task-board.ts
  64. 0 0
      packages/experimental/agent-team/src/task-graph.ts
  65. 0 0
      packages/experimental/agent-team/src/types.ts
  66. 0 0
      packages/experimental/agent-team/src/validation.ts
  67. 0 0
      packages/experimental/agent-team/tests/fold.spec.ts
  68. 2 2
      packages/experimental/agent-team/tests/invariant.spec.ts
  69. 5 5
      packages/experimental/agent-team/tests/persistence.spec.ts
  70. 128 128
      packages/experimental/agent-team/tests/team.spec.ts
  71. 0 0
      packages/experimental/agent-team/tsconfig.json
  72. 0 0
      packages/experimental/agent-team/tsdown.config.ts
  73. 3 3
      packages/experimental/tool-agent-team/README.i18n.yaml
  74. 6 6
      packages/experimental/tool-agent-team/README.md
  75. 6 6
      packages/experimental/tool-agent-team/README.zh.md
  76. 5 5
      packages/experimental/tool-agent-team/package.json
  77. 17 17
      packages/experimental/tool-agent-team/src/index.ts
  78. 1 1
      packages/experimental/tool-agent-team/src/invariant.ts
  79. 5 5
      packages/experimental/tool-agent-team/tests/tool-team.spec.ts
  80. 1 1
      packages/experimental/tool-agent-team/tsconfig.json
  81. 2 2
      packages/extensions/cordis-client-runner/src/client/api-catalog.ts
  82. 73 73
      packages/extensions/tool-cordis/src/api-catalog.ts
  83. 11 11
      pnpm-lock.yaml
  84. 18 9
      scripts/check-workspace-constraints.spec.ts
  85. 5 0
      scripts/check-workspace-constraints.ts
  86. 13 13
      scripts/gen-cordis-catalog.ts
  87. 4 4
      scripts/gen-doc-graphs.ts
  88. 5 5
      scripts/gen-persistence-catalog.ts
  89. 8 8
      scripts/gen-tool-catalog.ts
  90. 58 7
      scripts/release/bump.ts
  91. 20 2
      scripts/release/families.spec.ts
  92. 8 8
      scripts/type-equiv.manifest.json
  93. 4 0
      tsconfig.base.json
  94. 2 2
      tsconfig.host.json

+ 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: cec73be48a5cde25fae570587d2ecd17a4a87d01
-2026-08-18-experimental-agent-teams-packages.zh.md: 71b702daa8694fddec6e2a0972704f19955cb509
+2026-08-18-experimental-agent-teams-packages.md: cfaf7b23d03a1adecf8acc18a110717a62aa9ed1
+2026-08-18-experimental-agent-teams-packages.zh.md: 4491f4f638b7c5db26416aa88f2a6453c2a72ff6

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

@@ -12,9 +12,9 @@ An experimental directory without a current package previously imposed placement
 
 ## Decision
 
-`packages/experimental/team` and `packages/experimental/tool-team` are private workspace packages. Their npm names remain `@deepseek-ai/dsh-team` and `@deepseek-ai/dsh-tool-team`, so promotion changes paths and release metadata without renaming imports.
+`packages/experimental/agent-team` and `packages/experimental/tool-agent-team` are private workspace packages. The [experimental package naming decision](2026-08-19-experimental-package-name-prefix.md) owns their npm names and promotion rename; this note owns their placement, release exclusion, and dependency isolation.
 
-The dsh release family and local baseline publisher exclude every manifest below `packages/experimental/`. Workspace constraints require each experimental package to set `private: true` and omit `publishConfig`. The same top-level check rejects `dependencies`, `optionalDependencies`, and `peerDependencies` from release packages, release apps, or the Python runtime to an experimental package. Experimental packages may depend on release packages and each other; tests may use them through `devDependencies`, and examples may load them explicitly.
+The dsh pack and publish set and the local baseline publisher exclude every manifest below `packages/experimental/`. `release:dsh` still advances their manifest versions with the shared dsh version without creating release tags. Workspace constraints require each experimental package to set `private: true` and omit `publishConfig`. The same top-level check rejects `dependencies`, `optionalDependencies`, and `peerDependencies` from release packages, release apps, or the Python runtime to an experimental package. Experimental packages may depend on release packages and each other; tests may use them through `devDependencies`, and examples may load them explicitly.
 
 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.
 
@@ -28,10 +28,8 @@ Experimental status changes publication and compatibility expectations only. The
 
 **Move the Subagent prerequisites into the experimental directory.** Child identity allocation and Activation teardown belong to the Subagent owner and contain no Team-specific contract. Moving or duplicating them would invert the dependency or split one lifecycle across packages.
 
-**Publish experimental packages under different npm names.** Experimental suffixes would make promotion rename every import and configuration row without strengthening release exclusion; private manifests and release-family filtering enforce the actual requirement.
-
 ## Consequences
 
 Agent Teams can use the full repository graph and quality checks without entering official tarballs or becoming a supported runtime dependency. A release package cannot expose Team until the Team packages are promoted, so CLI and Web experiments use explicit example or experimental compositions instead of the shipped base bundles.
 
-The product-role grouping is less direct while the packages incubate, and promotion creates path churn. Keeping npm names stable limits that churn to repository paths, metadata, documentation, and composition.
+The product-role grouping is less direct while the packages incubate. Promotion creates path and npm-name churn as specified by the experimental package naming decision.

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

@@ -12,9 +12,9 @@ Agent Teams 的服务与工具约定仍在变化,但它需要使用真实 Sess
 
 ## 决策
 
-`packages/experimental/team` 与 `packages/experimental/tool-team` 是私有 workspace 包。其 npm 名仍为 `@deepseek-ai/dsh-team` 与 `@deepseek-ai/dsh-tool-team`,因此 promotion 只需修改路径与发布元数据,无需重命名 import。
+`packages/experimental/agent-team` 与 `packages/experimental/tool-agent-team` 是私有 workspace 包。[实验性包命名决策](2026-08-19-experimental-package-name-prefix.md)负责其 npm 名和 promotion 重命名;本记录负责其目录归属、发布排除与依赖隔离。
 
-dsh 发布系列与本地 baseline 发布器均排除 `packages/experimental/` 下的所有 manifest。workspace 约束要求每个实验性包设置 `private: true` 并省略 `publishConfig`。同一个顶层检查会拒绝发布包、发布 app 或 Python runtime 通过 `dependencies`、`optionalDependencies` 或 `peerDependencies` 依赖实验性包。实验性包可以依赖发布包和其他实验性包;测试可以通过 `devDependencies` 使用它们,示例可以显式加载它们。
+dsh pack 与 publish 集合以及本地 baseline 发布器均排除 `packages/experimental/` 下的所有 manifest。`release:dsh` 仍会让这些 manifest 跟随 dsh 共享版本递增,但不会创建发布 tag。workspace 约束要求每个实验性包设置 `private: true` 并省略 `publishConfig`。同一个顶层检查会拒绝发布包、发布 app 或 Python runtime 通过 `dependencies`、`optionalDependencies` 或 `peerDependencies` 依赖实验性包。实验性包可以依赖发布包和其他实验性包;测试可以通过 `devDependencies` 使用它们,示例可以显式加载它们。
 
 通用的调用方预留 continuable child 身份和精确 direct-child drain 仍属于稳定 Subagent 服务。它们负责 Subagent 身份与 Activation 生命周期,不 import 或命名 Agent Teams;实验性 Team 服务沿允许的方向消费这些能力。
 
@@ -28,10 +28,8 @@ dsh 发布系列与本地 baseline 发布器均排除 `packages/experimental/` 
 
 **把 Subagent 前置能力移入 experimental 目录。** child 身份分配与 Activation teardown 属于 Subagent owner,且不包含 Team 专用约定。移动或复制这些能力会反转依赖方向,或把同一个生命周期拆到多个包中。
 
-**使用不同的 npm 名发布实验性包。** experimental 后缀会让 promotion 重命名所有 import 与配置项,却不能加强发布排除;私有 manifest 与发布系列过滤已经强制执行实际要求。
-
 ## 后果
 
 Agent Teams 可以使用完整仓库依赖图与质量检查,而不进入正式 tarball,也不会成为受支持的运行时依赖。在 Team 包 promotion 前,发布包不能暴露 Team,因此 CLI 和 Web 实验使用显式示例或实验性组合,而不是已发布的基础组合包。
 
-孵化期间的产品职责分组不够直接,promotion 也会产生路径改动。保持 npm 名稳定后,改动范围仅包括仓库路径、元数据、文档和组合。
+孵化期间的产品职责分组不够直接。promotion 会按照实验性包命名决策产生路径和 npm 名改动。

+ 6 - 0
.agents/notes/implemented/architecture/2026-08-19-experimental-package-name-prefix.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/architecture/2026-08-19-experimental-package-name-prefix.md
+2026-08-19-experimental-package-name-prefix.md: 3420fa20a0dd9519af5684142fc8f3e70f2ed779
+2026-08-19-experimental-package-name-prefix.zh.md: b7e7d073157eab272baed4ffb75f987a685f53d7

+ 29 - 0
.agents/notes/implemented/architecture/2026-08-19-experimental-package-name-prefix.md

@@ -0,0 +1,29 @@
+# Agent Note: Mark experimental packages in npm names
+
+Status: implemented
+
+English | [中文](2026-08-19-experimental-package-name-prefix.zh.md)
+
+## Problem
+
+Directory placement, private manifests, and release-family filtering keep experimental packages out of releases, but an npm specifier or Cordis configuration row does not expose that status. A stable-looking package name can be copied into another composition without the reader seeing that its complete public contract remains experimental.
+
+## Decision
+
+Every package directly below `packages/experimental/` uses the `@deepseek-ai/dsh-experimental-*` npm prefix. The workspace constraints gate discovers those manifests and rejects a missing prefix alongside the existing `private: true` and omitted-`publishConfig` requirements.
+
+Agent Teams uses `@deepseek-ai/dsh-experimental-agent-team` from `packages/experimental/agent-team` and `@deepseek-ai/dsh-experimental-tool-agent-team` from `packages/experimental/tool-agent-team`. Package imports, Cordis configuration rows, generated catalogs, and repository metadata use those names without compatibility aliases.
+
+Promotion moves a package to its product-role group, removes `experimental-` from its npm name, and updates every repository reference atomically. The pre-release compatibility policy permits that rename without an alias package.
+
+## Alternatives considered
+
+**Keep stable-looking npm names while using only directory and release metadata for experimental status.** This minimizes promotion churn, but import specifiers and configuration rows hide the package status and cannot carry the repository-only placement rule into review.
+
+**Use an experimental suffix.** A prefix groups every experimental package under one searchable npm namespace and makes the status visible before the product role; a suffix would scatter that marker after role-specific names.
+
+## Consequences
+
+Experimental imports and configuration rows identify their support status without consulting repository layout. The top-level constraints command and its focused unit test prevent a newly added experimental package from omitting the prefix.
+
+Promotion deliberately renames imports, configuration, generated references, and metadata. No compatibility package preserves the experimental name.

+ 29 - 0
.agents/notes/implemented/architecture/2026-08-19-experimental-package-name-prefix.zh.md

@@ -0,0 +1,29 @@
+# Agent Note: 在 npm 名中标记实验性包
+
+Status: implemented
+
+[English](2026-08-19-experimental-package-name-prefix.md) | 中文
+
+## 问题
+
+目录归属、私有 manifest 与发布系列过滤可以阻止实验性包进入发布,但 npm specifier 或 Cordis 配置项无法体现该状态。外观稳定的包名可能被复制到其他组合中,而读者看不出其完整公开约定仍处于实验阶段。
+
+## 决策
+
+`packages/experimental/` 直属的每个包都使用 `@deepseek-ai/dsh-experimental-*` npm 前缀。workspace constraints 门禁会发现这些 manifest,并在现有 `private: true` 与省略 `publishConfig` 要求之外拒绝缺少该前缀的包。
+
+Agent Teams 使用位于 `packages/experimental/agent-team` 的 `@deepseek-ai/dsh-experimental-agent-team`,以及位于 `packages/experimental/tool-agent-team` 的 `@deepseek-ai/dsh-experimental-tool-agent-team`。包 import、Cordis 配置项、生成目录和仓库元数据直接使用这些名称,不提供兼容别名。
+
+promotion 会把包移至其产品职责组、从 npm 名中移除 `experimental-`,并原子更新全部仓库引用。预发布兼容策略允许该重命名不提供别名包。
+
+## 曾考虑的替代方案
+
+**保留外观稳定的 npm 名,仅通过目录和发布元数据表达实验状态。** 这种方式可以减少 promotion 改动,但 import specifier 与配置项会隐藏包状态,也无法在评审中携带仅存在于仓库内的目录规则。
+
+**使用 experimental 后缀。** 前缀会把所有实验性包归入一个可搜索的 npm 命名空间,并在产品职责之前显示状态;后缀会把该标记分散在各个职责名称之后。
+
+## 后果
+
+实验性 import 与配置项无需查阅仓库布局即可表明其支持状态。顶层 constraints 命令及其聚焦单元测试会阻止新实验性包遗漏该前缀。
+
+promotion 会明确重命名 import、配置、生成引用与元数据。不会有兼容包保留实验名称。

+ 2 - 2
.agents/notes/implemented/feature/2026-08-05-agent-teams.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/feature/2026-08-05-agent-teams.md
-2026-08-05-agent-teams.md: 43e92d4a9807e6a178436d96722b141b1bac45bb
-2026-08-05-agent-teams.zh.md: 72989623bb49334beae3b49ce2f6973781558c69
+2026-08-05-agent-teams.md: d37777a0cca467edcec5d38999aee53aaf14dc36
+2026-08-05-agent-teams.zh.md: 78bb212d687f89da0911983ea9d7fa5e5bbe95a7

+ 1 - 1
.agents/notes/implemented/feature/2026-08-05-agent-teams.md

@@ -16,7 +16,7 @@ The model-visible Team tools remain opt-in so the default tool catalog and simpl
 
 Every ordinary runtime root is the implicit Lead of a Team identified by that root's `SessionId`. The Team has no creation event: its Lead pseudo-row exists by identity, while durable state begins with the first member, message, or task event. A roster is flat and contains at most the configured number of immutable lowercase-kebab-case names. Each teammate is a continuable direct child with a reserved Session id; only the Lead creates or interrupts teammates. Ordinary provider-owned subagents outside the roster are not Team members, and an ordinary fork is a new root whose inherited Team records are excluded by their ancestor `TeamId`.
 
-The implementation is split into `@deepseek-ai/dsh-team`, which owns `ctx.teams` and durable semantics, and `@deepseek-ai/dsh-tool-team`, which owns scoped schemas and model guidance. Every Team tool declares its complete result schema and renders that value as compact JSON, so the compiler checks each `execute` against what the model is promised and no result spends tokens on indentation. Deployments mount both plugins explicitly and may disable legacy continuable controls with the same model-visible names. The explicit delegation policy permits Team creation only when the user asks for Agent Teams or teammates. Both packages are private members of `packages/experimental/`; the [experimental package decision](../architecture/2026-08-18-experimental-agent-teams-packages.md) owns release exclusion, dependency isolation, and promotion.
+The implementation is split into `@deepseek-ai/dsh-experimental-agent-team`, which owns `ctx.agentTeams` and durable semantics, and `@deepseek-ai/dsh-experimental-tool-agent-team`, which owns scoped schemas and model guidance. Every Team tool declares its complete result schema and renders that value as compact JSON, so the compiler checks each `execute` against what the model is promised and no result spends tokens on indentation. Deployments mount both plugins explicitly and may disable legacy continuable controls with the same model-visible names. The explicit delegation policy permits Team creation only when the user asks for Agent Teams or teammates. Both packages are private members of `packages/experimental/`; the [experimental package decision](../architecture/2026-08-18-experimental-agent-teams-packages.md) owns release exclusion, dependency isolation, and promotion.
 
 The Lead must wait for required work before its final answer. Process teardown remains the final lifecycle owner and drains continuation Activations; a Team task owner is durable state and is not automatically released by idle, interruption, or process exit.
 

+ 1 - 1
.agents/notes/implemented/feature/2026-08-05-agent-teams.zh.md

@@ -16,7 +16,7 @@ subagent seam 已提供 fresh/fork provider、持久 child Session、FIFO foll
 
 每个普通运行时 Root 都是一个隐式 Team 的 Lead,Team id 等于该 Root 的 `SessionId`。Team 没有 creation event:Lead pseudo-row 由身份直接存在,持久状态从第一条 member、message 或 task event 开始。roster 是扁平结构,最多包含配置数量、不可变且采用小写 kebab-case 的名字。每个 teammate 都是使用预留 Session id 的 continuable 直接 child;只有 Lead 可以创建或 interrupt teammate。roster 外由 provider 管理的普通 subagent 不是 Team member;普通 fork 是新的 Root,继承的 Team 记录会因 ancestor `TeamId` 被排除。
 
-实现拆分为 `@deepseek-ai/dsh-team` 与 `@deepseek-ai/dsh-tool-team`:前者负责 `ctx.teams` 和持久语义,后者负责 scoped schema 与模型指引。每个 Team 工具都声明完整的结果 schema,并把该值渲染为紧凑 JSON,因此编译器会检查每个 `execute` 是否符合对模型的承诺,也没有结果把 token 花在缩进上。部署显式挂载两个插件,并可禁用具有相同模型可见名称的旧 continuable control。显式 delegation 策略只允许在用户要求 Agent Teams 或 teammate 时创建 Team。 两个包都是 `packages/experimental/` 的私有成员;[实验性包决策](../architecture/2026-08-18-experimental-agent-teams-packages.md)负责发布排除、依赖隔离与 promotion。
+实现拆分为 `@deepseek-ai/dsh-experimental-agent-team` 与 `@deepseek-ai/dsh-experimental-tool-agent-team`:前者负责 `ctx.agentTeams` 和持久语义,后者负责 scoped schema 与模型指引。每个 Team 工具都声明完整的结果 schema,并把该值渲染为紧凑 JSON,因此编译器会检查每个 `execute` 是否符合对模型的承诺,也没有结果把 token 花在缩进上。部署显式挂载两个插件,并可禁用具有相同模型可见名称的旧 continuable control。显式 delegation 策略只允许在用户要求 Agent Teams 或 teammate 时创建 Team。 两个包都是 `packages/experimental/` 的私有成员;[实验性包决策](../architecture/2026-08-18-experimental-agent-teams-packages.md)负责发布排除、依赖隔离与 promotion。
 
 Lead 必须等待所需工作后才能给出最终答案。进程 teardown 仍是最终生命周期 owner,并会 drain continuation Activation;Team task owner 是持久状态,不会因 idle、interrupt 或进程退出自动释放。
 

+ 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: d8495f158482d5d6e06a1752a096d1e9200b6070
-2026-08-10-npm-release-sequences.zh.md: 24b466f6b7b10d31ac2e025da6e12ec3c91c7548
+2026-08-10-npm-release-sequences.md: efeda91b6a85e1316c563cc04411878122096953
+2026-08-10-npm-release-sequences.zh.md: d905ac4b58691890d2aad955b87713a278dcb4f8

+ 2 - 2
.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 | `packages/*/*` + `apps/*` (`@deepseek-ai/dsh` and `@deepseek-ai/dsh-web-frontend`) | one version for the family and the workspace root, `0.0.x` | `dsh-v<version>` | `release.yml` |
+| 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` |
 | vendored framework | the nine `vendor/*` packages | each package on its own version line | `vendor-<package>-v<version>` (one per package) | `release-vendor.yml` |
 | native | `native/landlock-run/packages/*` | its own `0.0.x` | `landlock-run-v<version>` | `landlock-run-release.yml` |
 
@@ -32,7 +32,7 @@ All three publish to the `@deepseek-ai` scope on npmjs.com, and access is per se
 
 Each sequence has one bump-and-commit command: it derives the target version, writes it into the relevant manifests, runs `pnpm install --lockfile-only`, and commits the manifests with the lockfile. The published version is therefore readable from the repository. A human creates the tag after the commit merges to master; CI never writes to the repository and needs no write permission.
 
-`release:dsh` accepts `major`, `minor`, `patch`, or an explicit version, and writes one version across the family **and the workspace root** — the workspace constraint requires every member's version to equal the root's, so the root carries the family version, and the root check accepts a prerelease segment. A prerelease such as `0.0.1-rc.1` drives pack, the installed-artifact probe, and one real private publication before numbered versions follow. The dist-tag decision is the one `landlock-run-release.yml` already made: a version with a prerelease segment publishes under `--tag next`, anything else takes `latest`.
+`release:dsh` accepts `major`, `minor`, `patch`, or an explicit version, and writes one version across the publishable family, every private package under `packages/*/*`, **and the workspace root**. Private packages receive no release tag and remain outside pack and publish; they follow the version because the workspace constraint requires every dsh package's version to equal the root's. The root check accepts a prerelease segment. A prerelease such as `0.0.1-rc.1` drives pack, the installed-artifact probe, and one real private publication before numbered versions follow. The dist-tag decision is the one `landlock-run-release.yml` already made: a version with a prerelease segment publishes under `--tag next`, anything else takes `latest`.
 
 ### vendor: publish what changed, and let tags be the ledger
 

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

@@ -22,7 +22,7 @@ Status: implemented
 
 | 序列 | 成员 | 版本基线 | tag | workflow |
 |---|---|---|---|---|
-| dsh | `packages/*/*` + `apps/*`(`@deepseek-ai/dsh` 与 `@deepseek-ai/dsh-web-frontend`) | 全族与 workspace 根共用一个 `0.0.x` | `dsh-v<版本>` | `release.yml` |
+| dsh | 发布集:非 experimental 的 `packages/*/*` + `apps/*`;私有实验性包仅加入共享版本 bump | 发布集、私有 dsh 包与 workspace 根共用一个 `0.0.x` | `dsh-v<版本>` | `release.yml` |
 | vendored framework | `vendor/*` 九个包 | 每包各自一条版本线 | `vendor-<包名>-v<版本>`(每包一个) | `release-vendor.yml` |
 | native | `native/landlock-run/packages/*` | 自己的 `0.0.x` | `landlock-run-v<版本>` | `landlock-run-release.yml` |
 
@@ -32,7 +32,7 @@ Status: implemented
 
 每条序列有一条 bump-and-commit 命令:算出目标版本,写进相关 manifest,跑 `pnpm install --lockfile-only`,再把 manifest 连 lockfile 一起 commit。发布版本因此在仓库里查得到。tag 由人工在 commit 合入 master 后打;CI 不写仓库,也不需要写权限。
 
-`release:dsh` 接受 `major`、`minor`、`patch` 或显式版本号,把同一个版本写进全族**以及 workspace 根**——workspace 约束要求每个成员的版本等于根版本,所以根承载族版本,而根的检查接受预发布段。像 `0.0.1-rc.1` 这样的预发布号先把 pack、已安装产物探针和一次真实私有发布跑通,数字版本随后。dist-tag 沿用 `landlock-run-release.yml` 已有的判定:版本带预发布段就 `--tag next`,否则进 `latest`。
+`release:dsh` 接受 `major`、`minor`、`patch` 或显式版本号,把同一个版本写进可发布族、`packages/*/*` 下的每个私有包**以及 workspace 根**。私有包不会获得发布 tag,仍位于 pack 与 publish 之外;它们跟随版本是因为 workspace 约束要求每个 dsh 包的版本等于根版本。根的检查接受预发布段。像 `0.0.1-rc.1` 这样的预发布号先把 pack、已安装产物探针和一次真实私有发布跑通,数字版本随后。dist-tag 沿用 `landlock-run-release.yml` 已有的判定:版本带预发布段就 `--tag next`,否则进 `latest`。
 
 ### vendor:谁改了谁发版,tag 就是账本
 

+ 2 - 2
.agents/notes/implemented/simplification/2026-08-12-trim-agent-teams-read-and-lifecycle-surface.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/simplification/2026-08-12-trim-agent-teams-read-and-lifecycle-surface.md
-2026-08-12-trim-agent-teams-read-and-lifecycle-surface.md: 736ed2587c8b2ffd9d824efa14dd0d249c43f669
-2026-08-12-trim-agent-teams-read-and-lifecycle-surface.zh.md: be30d9239d4dc0c44adda63d9488e7a25d217a9e
+2026-08-12-trim-agent-teams-read-and-lifecycle-surface.md: 69a54dae6e43ac4a93ebcf825bdeb1bad29a23fe
+2026-08-12-trim-agent-teams-read-and-lifecycle-surface.zh.md: f43dc680069855651a9087776987e8998790d829

+ 1 - 1
.agents/notes/implemented/simplification/2026-08-12-trim-agent-teams-read-and-lifecycle-surface.md

@@ -18,7 +18,7 @@ Durable member, task, message, and acknowledgement payloads copied timestamps al
 
 The Team service keeps the distinct product responsibilities: durable named roster, Lead-log mailbox, and task DAG. It does not merge with the generic subagent catalog or task service.
 
-Inside `@deepseek-ai/dsh-team`, `TeamService` is the Cordis-facing façade and disposal coordinator. `TeamJournal` owns per-Lead transaction order and append-plus-flush publication; `TeamRoster` owns membership and provisioning; `TeamMailbox` owns target-local dispatch, acknowledgement, and retry state; `TeamTaskBoard` owns task authorization, DAG transitions, and derived views; `TeamActivity` owns current waiters; and `TeamRuntimeLifecycle` owns the single admission cutoff and bounded settlement. These package-private collaborators share the existing service capability without publishing additional Cordis services.
+Inside `@deepseek-ai/dsh-experimental-agent-team`, `TeamService` is the Cordis-facing façade and disposal coordinator. `TeamJournal` owns per-Lead transaction order and append-plus-flush publication; `TeamRoster` owns membership and provisioning; `TeamMailbox` owns target-local dispatch, acknowledgement, and retry state; `TeamTaskBoard` owns task authorization, DAG transitions, and derived views; `TeamActivity` owns current waiters; and `TeamRuntimeLifecycle` owns the single admission cutoff and bounded settlement. These package-private collaborators share the existing service capability without publishing additional Cordis services.
 
 The unused snapshot API and global Team revision are removed. Host reads return only roster and task views; they do not repeat the already-addressed Team id. Member failures appear once in `diagnostics`. Task views expose `ownerName` but keep `ownerId` inside the durable service implementation. Spawn returns the member view only, and validated config is private.
 

+ 1 - 1
.agents/notes/implemented/simplification/2026-08-12-trim-agent-teams-read-and-lifecycle-surface.zh.md

@@ -18,7 +18,7 @@ Agent Teams 合理地拥有持久 roster、peer mailbox 与共享任务策略,
 
 Team 服务保留独立的产品职责:持久具名 roster、Lead-log mailbox 与 task DAG。它不会与通用 subagent catalog 或 task service 合并。
 
-在 `@deepseek-ai/dsh-team` 内,`TeamService` 是面向 Cordis 的 façade 与 disposal 协调者。`TeamJournal` 负责每个 Lead 的 transaction 顺序以及 append-plus-flush 发布;`TeamRoster` 负责 membership 与 provisioning;`TeamMailbox` 负责 target-local dispatch、acknowledgement 与 retry 状态;`TeamTaskBoard` 负责 task 授权、DAG transition 与派生 view;`TeamActivity` 负责当前 waiter;`TeamRuntimeLifecycle` 负责唯一的准入截止与有界 settlement。这些包内 collaborator 共享现有 service capability,不发布额外 Cordis service。
+在 `@deepseek-ai/dsh-experimental-agent-team` 内,`TeamService` 是面向 Cordis 的 façade 与 disposal 协调者。`TeamJournal` 负责每个 Lead 的 transaction 顺序以及 append-plus-flush 发布;`TeamRoster` 负责 membership 与 provisioning;`TeamMailbox` 负责 target-local dispatch、acknowledgement 与 retry 状态;`TeamTaskBoard` 负责 task 授权、DAG transition 与派生 view;`TeamActivity` 负责当前 waiter;`TeamRuntimeLifecycle` 负责唯一的准入截止与有界 settlement。这些包内 collaborator 共享现有 service capability,不发布额外 Cordis service。
 
 删除未使用的 snapshot API 与全局 Team revision。Host 读取只返回 roster 与 task view,不重复已经寻址的 Team id。member failure 只在 `diagnostics` 出现一次。task view 暴露 `ownerName`,把 `ownerId` 留在持久服务实现内部。spawn 只返回 member view,已校验 config 改为私有。
 

+ 2 - 2
docs/architecture.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 docs/architecture.md
-architecture.md: 2a51992a4f99d1827259c0a2ca2daa309f0ddd95
-architecture.zh.md: d1629a088ed8d2fe61a7e20ab2ab1fd3709abd50
+architecture.md: 622d074c3d873181d764cfe53f64485a2c2e0372
+architecture.zh.md: 2b38d9fb71fd358b78608680208c6071e59db89e

+ 1 - 1
docs/architecture.md

@@ -101,7 +101,7 @@ A **seam** is a swappable capability with three roles: a **Service Definition**
 
 Seams are why one provider swap changes the whole product. Filesystem and subprocess providers share one execution world, so pointing them at a remote sandbox moves Bash, PTY, and LSP with them, with no provider forks. [Subagent providers](subsystems/subagent.md) vary just as widely behind one interface, from a fresh child agent to a delegated turn in another product.
 
-[Experimental Agent Teams](subsystems/team.md) is a private opt-in coordination seam on `ctx.teams`, with a durable roster, task board, and mailbox layered over continuable subagents.
+[Experimental Agent Teams](subsystems/agent-team.md) is a private opt-in coordination seam on `ctx.agentTeams`, with a durable roster, task board, and mailbox layered over continuable subagents.
 
 ## Where new behavior goes
 

+ 1 - 1
docs/architecture.zh.md

@@ -105,7 +105,7 @@ turn/end
 
 seam 正是替换一个提供方就能改变整个产品的原因。文件系统与进程提供方共享同一个执行世界,因此把它们指向远程沙箱,也就把 Bash、PTY 和 LSP 一并搬了过去,无需提供方专用 fork。[subagent 提供方](subsystems/subagent.md)在同一个接口之后同样千差万别,从新建一个子 agent,到把一个轮次委派给另一个产品。
 
-[实验性 Agent Teams](subsystems/team.md) 是 `ctx.teams` 上的私有显式启用协作 seam,在可继续 subagent 之上提供持久 roster、任务板和 mailbox。
+[实验性 Agent Teams](subsystems/agent-team.md) 是 `ctx.agentTeams` 上的私有显式启用协作 seam,在可继续 subagent 之上提供持久 roster、任务板和 mailbox。
 
 ## 新行为的归属位置
 

+ 2 - 2
docs/capability-seams.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 docs/capability-seams.md
-capability-seams.md: 23fc498cc280518489aadbe752a1702d43f17972
-capability-seams.zh.md: 0a8822bc8d1f0296ac6698b59fda60666faaf54a
+capability-seams.md: a84a6d6e0836524e1f39f2fd067ae1f6570741a5
+capability-seams.zh.md: b6b0aba72729f9b9b752347ab00cd76a45c248d9

+ 6 - 6
docs/capability-seams.md

@@ -160,9 +160,9 @@ flowchart LR
   pkg_subagent_dsh_sdk["subagent-dsh-sdk"]
   pkg_tool_subagent_control["tool-subagent-control"]
   pkg_tool_ralph["tool-ralph"]
-  pkg_team["team"]
-  svc_teams["ctx.teams<br/>Agent Teams coordination domain"]
-  pkg_tool_team["tool-team"]
+  pkg_agent_team["agent-team"]
+  svc_agentTeams["ctx.agentTeams<br/>Agent Teams coordination domain"]
+  pkg_tool_agent_team["tool-agent-team"]
   pkg_jobs["jobs"]
   svc_jobs["ctx.jobs<br/>Background job registry"]
   pkg_jobs_local["jobs-local"]
@@ -204,6 +204,7 @@ flowchart LR
   pkg_agent_default_model --> svc_agentDefaultModel
   pkg_agent_loop --> svc_agentLoop
   pkg_agent_presets --> svc_agentPresets
+  pkg_agent_team --> svc_agentTeams
   pkg_api_gateway --> svc_typertGateway
   pkg_apiproxy --> svc_apiProxy
   pkg_approval --> svc_approval
@@ -287,7 +288,6 @@ flowchart LR
   pkg_subprocess_e2b --> svc_subprocess
   pkg_subprocess_local --> svc_subprocess
   pkg_system_prompt --> svc_systemPrompt
-  pkg_team --> svc_teams
   pkg_terminal --> svc_terminals
   pkg_terminal_bash --> svc_terminals
   pkg_token_meter --> svc_tokenMeter
@@ -306,6 +306,7 @@ flowchart LR
   svc_agentDefaultModel --> pkg_headless
   svc_agentDefaultModel --> pkg_host_apiproxy
   svc_agentLoop --> pkg_agent_spine_demo
+  svc_agentTeams --> pkg_tool_agent_team
   svc_agents --> pkg_acp
   svc_agents --> pkg_agent_loop
   svc_agents --> pkg_subagent_inprocess
@@ -392,7 +393,6 @@ flowchart LR
   svc_systemPrompt --> pkg_tool_terminal
   svc_systemPrompt --> pkg_tool_web
   svc_systemPrompt --> pkg_tools
-  svc_teams --> pkg_tool_team
   svc_terminals --> pkg_tool_terminal
   svc_tokenMeter --> pkg_compaction_basic
   svc_toolResultPruner --> pkg_compaction_basic
@@ -467,7 +467,7 @@ flowchart LR
 | `ctx.fs` | `seam` | [`fs`](../packages/fs/fs) | [`fs-local`](../packages/fs/fs-local), [`fs-sandbox`](../packages/fs/fs-sandbox), [`fs-e2b`](../packages/e2b/fs-e2b) | [`tool-fs`](../packages/fs/tool-fs) | [`fs-observation-policy`](../packages/fs/fs-observation-policy) | tool-fs executes read/write/edit through ctx.fs; fs-sandbox fences mutations by the shared sandbox mode; fs-observation-policy contributes observed-state checks through the fs/* event gate. |
 | `ctx.compaction` | `seam` | [`compaction`](../packages/compaction/compaction) | [`compaction-basic`](../packages/compaction/compaction-basic) | [`compaction-basic`](../packages/compaction/compaction-basic) | - | The basic backend consumes post-step pressure and request-error recovery events; there is no model-facing compact tool. |
 | `ctx.subagents` | `seam` | [`subagent`](../packages/subagent/subagent) | [`subagent-spawn-in-process`](../packages/subagent/subagent-spawn-in-process), [`subagent-fork-in-process`](../packages/subagent/subagent-fork-in-process), [`subagent-acp`](../packages/subagent/subagent-acp), [`subagent-codex`](../packages/subagent/subagent-codex), [`subagent-claude-code`](../packages/subagent/subagent-claude-code), [`subagent-dsh-sdk`](../packages/subagent/subagent-dsh-sdk) | [`tool-subagent`](../packages/subagent/tool-subagent), [`tool-subagent-control`](../packages/subagent/tool-subagent-control), [`tool-ralph`](../packages/workflow/tool-ralph) | - | Providers implement transports; the service also owns optional Activation-based continuation orchestration, tool-subagent selects one-shot or continuable delegation, tool-subagent-control delivers follow-ups, and tool-ralph requires one fresh structured-output route. |
-| `ctx.teams` | `core` | [`team`](../packages/experimental/team) | - | [`tool-team`](../packages/experimental/tool-team) | - | Owns the implicit-root roster, durable peer mailbox, shared task DAG, and continuable-child lifecycle; tool-team contributes the scoped model policy and controls. |
+| `ctx.agentTeams` | `core` | `agent-team` | - | `tool-agent-team` | - | Owns the implicit-root roster, durable peer mailbox, shared task DAG, and continuable-child lifecycle; tool-agent-team contributes the scoped model policy and controls. |
 | `ctx.jobs` | `seam` | [`jobs`](../packages/jobs/jobs) | [`jobs-local`](../packages/jobs/jobs-local) | [`tool-bash`](../packages/shell/tool-bash), [`tool-terminal`](../packages/terminal/tool-terminal), [`tool-subagent`](../packages/subagent/tool-subagent), [`tool-jobs`](../packages/jobs/tool-jobs) | - | Producers (background bash, PTY sends, and subagent delegations) register running work; tool-jobs is the model-facing controller that reads, lists, and kills it; jobs-local is the process-local registry. |
 | `ctx.web` | `seam` | [`web`](../packages/web/web) | [`web-search-exa`](../packages/web/web-search-exa), [`web-search-perplexity`](../packages/web/web-search-perplexity), [`web-search-deepseek`](../packages/web/web-search-deepseek), [`web-fetch-http`](../packages/web/web-fetch-http) | [`tool-web`](../packages/web/tool-web) | - | Search and fetch providers register into one ctx.web seam; tool-web owns the stable model-facing names. |
 | `ctx.spillStore` | `seam` | [`spill`](../packages/spill/spill) | [`spill-local`](../packages/spill/spill-local) | [`spill-policy`](../packages/spill/spill-policy) | - | The backend saves oversized tool text and returns a model-facing locator plus retrieval hint; spill-policy is the tools/post-execute consumer that decides when to spill. |

+ 6 - 6
docs/capability-seams.zh.md

@@ -162,9 +162,9 @@ flowchart LR
   pkg_subagent_dsh_sdk["subagent-dsh-sdk"]
   pkg_tool_subagent_control["tool-subagent-control"]
   pkg_tool_ralph["tool-ralph"]
-  pkg_team["team"]
-  svc_teams["ctx.teams<br/>Agent Teams coordination domain"]
-  pkg_tool_team["tool-team"]
+  pkg_agent_team["agent-team"]
+  svc_agentTeams["ctx.agentTeams<br/>Agent Teams coordination domain"]
+  pkg_tool_agent_team["tool-agent-team"]
   pkg_jobs["jobs"]
   svc_jobs["ctx.jobs<br/>Background job registry"]
   pkg_jobs_local["jobs-local"]
@@ -206,6 +206,7 @@ flowchart LR
   pkg_agent_default_model --> svc_agentDefaultModel
   pkg_agent_loop --> svc_agentLoop
   pkg_agent_presets --> svc_agentPresets
+  pkg_agent_team --> svc_agentTeams
   pkg_api_gateway --> svc_typertGateway
   pkg_apiproxy --> svc_apiProxy
   pkg_approval --> svc_approval
@@ -289,7 +290,6 @@ flowchart LR
   pkg_subprocess_e2b --> svc_subprocess
   pkg_subprocess_local --> svc_subprocess
   pkg_system_prompt --> svc_systemPrompt
-  pkg_team --> svc_teams
   pkg_terminal --> svc_terminals
   pkg_terminal_bash --> svc_terminals
   pkg_token_meter --> svc_tokenMeter
@@ -308,6 +308,7 @@ flowchart LR
   svc_agentDefaultModel --> pkg_headless
   svc_agentDefaultModel --> pkg_host_apiproxy
   svc_agentLoop --> pkg_agent_spine_demo
+  svc_agentTeams --> pkg_tool_agent_team
   svc_agents --> pkg_acp
   svc_agents --> pkg_agent_loop
   svc_agents --> pkg_subagent_inprocess
@@ -394,7 +395,6 @@ flowchart LR
   svc_systemPrompt --> pkg_tool_terminal
   svc_systemPrompt --> pkg_tool_web
   svc_systemPrompt --> pkg_tools
-  svc_teams --> pkg_tool_team
   svc_terminals --> pkg_tool_terminal
   svc_tokenMeter --> pkg_compaction_basic
   svc_toolResultPruner --> pkg_compaction_basic
@@ -469,7 +469,7 @@ flowchart LR
 | `ctx.fs` | `seam` | [`fs`](../packages/fs/fs) | [`fs-local`](../packages/fs/fs-local), [`fs-sandbox`](../packages/fs/fs-sandbox), [`fs-e2b`](../packages/e2b/fs-e2b) | [`tool-fs`](../packages/fs/tool-fs) | [`fs-observation-policy`](../packages/fs/fs-observation-policy) | tool-fs 通过 ctx.fs 执行读取/写入/编辑;fs-sandbox 按共享沙箱模式限制变更;fs-observation-policy 通过 fs/* 事件门禁贡献基于观测状态的检查。 |
 | `ctx.compaction` | `seam` | [`compaction`](../packages/compaction/compaction) | [`compaction-basic`](../packages/compaction/compaction-basic) | [`compaction-basic`](../packages/compaction/compaction-basic) | - | 基础后端消费步骤后的压力事件和请求错误恢复事件;不存在面向模型的压缩工具。 |
 | `ctx.subagents` | `seam` | [`subagent`](../packages/subagent/subagent) | [`subagent-spawn-in-process`](../packages/subagent/subagent-spawn-in-process), [`subagent-fork-in-process`](../packages/subagent/subagent-fork-in-process), [`subagent-acp`](../packages/subagent/subagent-acp), [`subagent-codex`](../packages/subagent/subagent-codex), [`subagent-claude-code`](../packages/subagent/subagent-claude-code), [`subagent-dsh-sdk`](../packages/subagent/subagent-dsh-sdk) | [`tool-subagent`](../packages/subagent/tool-subagent), [`tool-subagent-control`](../packages/subagent/tool-subagent-control), [`tool-ralph`](../packages/workflow/tool-ralph) | - | 提供方实现传输;该服务还负责可选的、基于 Activation 的延续编排,tool-subagent 选择一次性或可延续委派,tool-subagent-control 传递后续消息,而 tool-ralph 要求一条全新的结构化输出路由。 |
-| `ctx.teams` | `core` | [`team`](../packages/experimental/team) | - | [`tool-team`](../packages/experimental/tool-team) | - | 负责隐式 Root roster、持久 peer mailbox、共享任务 DAG 与 continuable child 生命周期;tool-team 提供作用域化模型策略和控制工具。 |
+| `ctx.agentTeams` | `core` | `agent-team` | - | `tool-agent-team` | - | 负责隐式 Root roster、持久 peer mailbox、共享任务 DAG 与 continuable child 生命周期;tool-agent-team 提供作用域化模型策略和控制工具。 |
 | `ctx.jobs` | `seam` | [`jobs`](../packages/jobs/jobs) | [`jobs-local`](../packages/jobs/jobs-local) | [`tool-bash`](../packages/shell/tool-bash), [`tool-terminal`](../packages/terminal/tool-terminal), [`tool-subagent`](../packages/subagent/tool-subagent), [`tool-jobs`](../packages/jobs/tool-jobs) | - | 生产方(后台 bash、PTY 发送和 subagent 委派)登记正在运行的工作;tool-jobs 是面向模型的控制器,用于读取、列出和终止这些工作;jobs-local 是进程本地注册表。 |
 | `ctx.web` | `seam` | [`web`](../packages/web/web) | [`web-search-exa`](../packages/web/web-search-exa), [`web-search-perplexity`](../packages/web/web-search-perplexity), [`web-search-deepseek`](../packages/web/web-search-deepseek), [`web-fetch-http`](../packages/web/web-fetch-http) | [`tool-web`](../packages/web/tool-web) | - | 搜索和抓取提供方注册到同一个 ctx.web seam;tool-web 负责稳定的面向模型名称。 |
 | `ctx.spillStore` | `seam` | [`spill`](../packages/spill/spill) | [`spill-local`](../packages/spill/spill-local) | [`spill-policy`](../packages/spill/spill-policy) | - | 后端保存过大的工具文本,并返回面向模型的定位信息和取回提示;spill-policy 是 tools/post-execute 消费方,负责决定何时 spill。 |

+ 2 - 2
docs/config-catalog.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 docs/config-catalog.md
-config-catalog.md: 83bd4760c9acff81f36234f88f63c86d09884add
-config-catalog.zh.md: f83e4c5ce223cb8f0d047e13193507efc154a46a
+config-catalog.md: 867ddd5ad8351a5cd25af92727466960c55c649a
+config-catalog.zh.md: 66fe15ee31018f3df95e62e69fe539cdd7570add

+ 42 - 42
docs/config-catalog.md

@@ -587,6 +587,48 @@ export interface Config {
 
 Source: [`packages/e2b/e2b/src/index.ts:43`](../packages/e2b/e2b/src/index.ts)
 
+<a id="deepseek-aidsh-experimental-agent-team"></a>
+
+## `@deepseek-ai/dsh-experimental-agent-team`
+
+Requires: `agents` · `sessions` · `sessionPersistence` · `subagents`
+
+```ts config-catalog
+/** Team-service deployment limits. */
+export interface Config {
+  /** Maximum immutable teammate names retained by one Team. */
+  readonly maxMembers?: number
+  /** Maximum non-deleted tasks retained by one Team. */
+  readonly maxTasks?: number
+  /** Maximum queued-minus-delivered messages for one target member. */
+  readonly maxPendingMessagesPerMember?: number
+  /** Maximum UTF-8 bytes in one complete sender-framed delivery. */
+  readonly maxMessageBytes?: number
+  /** Maximum milliseconds allowed for Team-owned runtime disposal. */
+  readonly disposalTimeoutMs?: number
+}
+```
+
+Source: [`packages/experimental/agent-team/src/types.ts:125`](../packages/experimental/agent-team/src/types.ts)
+
+<a id="deepseek-aidsh-experimental-tool-agent-team"></a>
+
+## `@deepseek-ai/dsh-experimental-tool-agent-team`
+
+Requires: `agents` · `agentTeams` · `tools` · `systemPrompt`
+
+```ts config-catalog
+/** Tool routing configuration. */
+export interface Config {
+  /** Continuable-subagent provider used for fresh teammates. */
+  readonly freshProvider?: string
+  /** Continuable-subagent provider used for completed-prefix fork teammates. */
+  readonly forkProvider?: string
+}
+```
+
+Source: [`packages/experimental/tool-agent-team/src/index.ts:17`](../packages/experimental/tool-agent-team/src/index.ts)
+
 <a id="deepseek-aidsh-file-reference-local"></a>
 
 ## `@deepseek-ai/dsh-file-reference-local`
@@ -2334,30 +2376,6 @@ export interface Config {
 
 Source: [`packages/core/system-prompt/src/index.ts:186`](../packages/core/system-prompt/src/index.ts)
 
-<a id="deepseek-aidsh-team"></a>
-
-## `@deepseek-ai/dsh-team`
-
-Requires: `agents` · `sessions` · `sessionPersistence` · `subagents`
-
-```ts config-catalog
-/** Team-service deployment limits. */
-export interface Config {
-  /** Maximum immutable teammate names retained by one Team. */
-  readonly maxMembers?: number
-  /** Maximum non-deleted tasks retained by one Team. */
-  readonly maxTasks?: number
-  /** Maximum queued-minus-delivered messages for one target member. */
-  readonly maxPendingMessagesPerMember?: number
-  /** Maximum UTF-8 bytes in one complete sender-framed delivery. */
-  readonly maxMessageBytes?: number
-  /** Maximum milliseconds allowed for Team-owned runtime disposal. */
-  readonly disposalTimeoutMs?: number
-}
-```
-
-Source: [`packages/experimental/team/src/types.ts:125`](../packages/experimental/team/src/types.ts)
-
 <a id="deepseek-aidsh-terminal-bash"></a>
 
 ## `@deepseek-ai/dsh-terminal-bash`
@@ -2817,24 +2835,6 @@ Depends on: [`SubagentReportDelivery`](subsystems/subagent.md)
 
 Source: [`packages/subagent/tool-subagent-report/src/index.ts:27`](../packages/subagent/tool-subagent-report/src/index.ts)
 
-<a id="deepseek-aidsh-tool-team"></a>
-
-## `@deepseek-ai/dsh-tool-team`
-
-Requires: `agents` · `teams` · `tools` · `systemPrompt`
-
-```ts config-catalog
-/** Tool routing configuration. */
-export interface Config {
-  /** Continuable-subagent provider used for fresh teammates. */
-  readonly freshProvider?: string
-  /** Continuable-subagent provider used for completed-prefix fork teammates. */
-  readonly forkProvider?: string
-}
-```
-
-Source: [`packages/experimental/tool-team/src/index.ts:17`](../packages/experimental/tool-team/src/index.ts)
-
 <a id="deepseek-aidsh-tool-terminal"></a>
 
 ## `@deepseek-ai/dsh-tool-terminal`

+ 42 - 44
docs/config-catalog.zh.md

@@ -589,6 +589,48 @@ export interface Config {
 
 来源:[`packages/e2b/e2b/src/index.ts:43`](../packages/e2b/e2b/src/index.ts)
 
+<a id="deepseek-aidsh-experimental-agent-team"></a>
+
+## `@deepseek-ai/dsh-experimental-agent-team`
+
+需要:`agents` · `sessions` · `sessionPersistence` · `subagents`
+
+```ts config-catalog
+/** Team-service deployment limits. */
+export interface Config {
+  /** Maximum immutable teammate names retained by one Team. */
+  readonly maxMembers?: number
+  /** Maximum non-deleted tasks retained by one Team. */
+  readonly maxTasks?: number
+  /** Maximum queued-minus-delivered messages for one target member. */
+  readonly maxPendingMessagesPerMember?: number
+  /** Maximum UTF-8 bytes in one complete sender-framed delivery. */
+  readonly maxMessageBytes?: number
+  /** Maximum milliseconds allowed for Team-owned runtime disposal. */
+  readonly disposalTimeoutMs?: number
+}
+```
+
+来源:[`packages/experimental/agent-team/src/types.ts:125`](../packages/experimental/agent-team/src/types.ts)
+
+<a id="deepseek-aidsh-experimental-tool-agent-team"></a>
+
+## `@deepseek-ai/dsh-experimental-tool-agent-team`
+
+需要:`agents` · `agentTeams` · `tools` · `systemPrompt`
+
+```ts config-catalog
+/** Tool routing configuration. */
+export interface Config {
+  /** Continuable-subagent provider used for fresh teammates. */
+  readonly freshProvider?: string
+  /** Continuable-subagent provider used for completed-prefix fork teammates. */
+  readonly forkProvider?: string
+}
+```
+
+来源:[`packages/experimental/tool-agent-team/src/index.ts:17`](../packages/experimental/tool-agent-team/src/index.ts)
+
 <a id="deepseek-aidsh-file-reference-local"></a>
 
 ## `@deepseek-ai/dsh-file-reference-local`
@@ -2336,31 +2378,6 @@ export interface Config {
 
 来源:[`packages/core/system-prompt/src/index.ts:186`](../packages/core/system-prompt/src/index.ts)
 
-<a id="deepseek-aidsh-team"></a>
-
-## `@deepseek-ai/dsh-team`
-
-需要:`agents` · `sessions` · `sessionPersistence` · `subagents`
-
-```ts config-catalog
-/** Team-service deployment limits. */
-export interface Config {
-  /** Maximum immutable teammate names retained by one Team. */
-  readonly maxMembers?: number
-  /** Maximum non-deleted tasks retained by one Team. */
-  readonly maxTasks?: number
-  /** Maximum queued-minus-delivered messages for one target member. */
-  readonly maxPendingMessagesPerMember?: number
-  /** Maximum UTF-8 bytes in one complete sender-framed delivery. */
-  readonly maxMessageBytes?: number
-  /** Maximum milliseconds allowed for Team-owned runtime disposal. */
-  readonly disposalTimeoutMs?: number
-}
-```
-
-来源:[`packages/experimental/team/src/types.ts:125`](../packages/experimental/team/src/types.ts)
-
-
 <a id="deepseek-aidsh-terminal-bash"></a>
 
 ## `@deepseek-ai/dsh-terminal-bash`
@@ -2820,25 +2837,6 @@ export interface Config {
 
 来源:[`packages/subagent/tool-subagent-report/src/index.ts:27`](../packages/subagent/tool-subagent-report/src/index.ts)
 
-<a id="deepseek-aidsh-tool-team"></a>
-
-## `@deepseek-ai/dsh-tool-team`
-
-需要:`agents` · `teams` · `tools` · `systemPrompt`
-
-```ts config-catalog
-/** Tool routing configuration. */
-export interface Config {
-  /** Continuable-subagent provider used for fresh teammates. */
-  readonly freshProvider?: string
-  /** Continuable-subagent provider used for completed-prefix fork teammates. */
-  readonly forkProvider?: string
-}
-```
-
-来源:[`packages/experimental/tool-team/src/index.ts:17`](../packages/experimental/tool-team/src/index.ts)
-
-
 <a id="deepseek-aidsh-tool-terminal"></a>
 
 ## `@deepseek-ai/dsh-tool-terminal`

+ 2 - 2
docs/event-producer-consumer.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 docs/event-producer-consumer.md
-event-producer-consumer.md: 2e4bec93f5b9f68ab885d50bab27e9a9a6036028
-event-producer-consumer.zh.md: e3f5602287d7b688a2191937871e1639dc271e65
+event-producer-consumer.md: d75d64b58b041c117bf2eaa1612c1b4683378a00
+event-producer-consumer.zh.md: adfc11782e179077b17199fc4ea6e8f52b3c465b

+ 7 - 7
docs/event-producer-consumer.md

@@ -9,8 +9,8 @@ This matrix shows which packages dispatch each harness-owned event and which pac
 | --- | --- | --- | --- | --- |
 | `agent-loop/config-start-failed` | `emit` | [`packages/core/agent-loop/src/index.ts:183`](../packages/core/agent-loop/src/index.ts) | [`agent-loop`](../packages/core/agent-loop) (`events.dispatch`) | - |
 | `agent-preset/selected` | `emit` | [`packages/preset/agent-presets/src/types.ts:13`](../packages/preset/agent-presets/src/types.ts) | [`agent-presets`](../packages/preset/agent-presets) (`emit`) | `apiproxy` |
-| `agent/created` | `emit` | [`packages/core/agent/src/runtime-types.ts:159`](../packages/core/agent/src/runtime-types.ts) | [`agent`](../packages/core/agent) (`events.dispatch`) | [`agent-presets`](../packages/preset/agent-presets), [`file-reference-local`](../packages/context/file-reference-local), [`goal-round-driver`](../packages/goal/goal-round-driver), [`schedule`](../packages/schedule/schedule), [`tool-team`](../packages/experimental/tool-team) |
-| `agent/disposed` | `emit` | [`packages/core/agent/src/runtime-types.ts:168`](../packages/core/agent/src/runtime-types.ts) | [`agent`](../packages/core/agent) (`events.dispatch`) | [`agent-loop`](../packages/core/agent-loop), [`file-reference-local`](../packages/context/file-reference-local), [`goal-round-driver`](../packages/goal/goal-round-driver), [`subagent`](../packages/subagent/subagent), [`tool-team`](../packages/experimental/tool-team) |
+| `agent/created` | `emit` | [`packages/core/agent/src/runtime-types.ts:159`](../packages/core/agent/src/runtime-types.ts) | [`agent`](../packages/core/agent) (`events.dispatch`) | [`agent-presets`](../packages/preset/agent-presets), [`file-reference-local`](../packages/context/file-reference-local), [`goal-round-driver`](../packages/goal/goal-round-driver), [`schedule`](../packages/schedule/schedule), `tool-agent-team` |
+| `agent/disposed` | `emit` | [`packages/core/agent/src/runtime-types.ts:168`](../packages/core/agent/src/runtime-types.ts) | [`agent`](../packages/core/agent) (`events.dispatch`) | [`agent-loop`](../packages/core/agent-loop), [`file-reference-local`](../packages/context/file-reference-local), [`goal-round-driver`](../packages/goal/goal-round-driver), [`subagent`](../packages/subagent/subagent), `tool-agent-team` |
 | `agent/error` | `emit` | [`packages/core/agent/src/runtime-types.ts:290`](../packages/core/agent/src/runtime-types.ts) | [`agent-loop`](../packages/core/agent-loop) (`emit`) | [`acp`](../packages/acp/acp), `apiproxy`, [`goal-round-driver`](../packages/goal/goal-round-driver), [`session-telemetry`](../packages/session/session-telemetry) |
 | `agent/inbox/claimed` | `emit` | [`packages/core/agent/src/runtime-types.ts:197`](../packages/core/agent/src/runtime-types.ts) | [`agent-loop`](../packages/core/agent-loop) (`emit`) | [`acp`](../packages/acp/acp), [`goal-round-driver`](../packages/goal/goal-round-driver), [`subagent`](../packages/subagent/subagent), [`tool-jobs`](../packages/jobs/tool-jobs) |
 | `agent/inbox/discarded` | `emit` | [`packages/core/agent/src/runtime-types.ts:205`](../packages/core/agent/src/runtime-types.ts) | [`agent-loop`](../packages/core/agent-loop) (`emit`) | [`goal-round-driver`](../packages/goal/goal-round-driver), [`subagent`](../packages/subagent/subagent) |
@@ -18,8 +18,8 @@ This matrix shows which packages dispatch each harness-owned event and which pac
 | `agent/pre-step` | `waterfall` | [`packages/core/agent/src/runtime-types.ts:231`](../packages/core/agent/src/runtime-types.ts) | [`agent-loop`](../packages/core/agent-loop) (`waterfall`) | [`agent-instructions`](../packages/context/agent-instructions), [`compaction-basic`](../packages/compaction/compaction-basic), [`goal-round-driver`](../packages/goal/goal-round-driver), [`hooks-claude-code`](../packages/hooks/hooks-claude-code), [`hooks-codex`](../packages/hooks/hooks-codex), [`plan-mode`](../packages/plan/plan-mode), [`repeat-tool-reminder`](../packages/guard/repeat-tool-reminder), [`session-checkpoint-policy`](../packages/session/session-checkpoint-policy), [`session-reference`](../packages/context/session-reference), [`subagent-in-process-driver`](../packages/subagent/subagent-in-process-driver), [`time-context`](../packages/context/time-context), [`tmux-context`](../packages/context/tmux-context), [`tool-cordis`](../packages/extensions/tool-cordis), [`tool-skill`](../packages/skill/tool-skill) |
 | `agent/request` | `waterfall` | [`packages/core/agent/src/runtime-types.ts:244`](../packages/core/agent/src/runtime-types.ts) | [`agent-loop`](../packages/core/agent-loop) (`waterfall`) | [`agent`](../packages/core/agent) |
 | `agent/request-error` | `waterfall` | [`packages/core/agent/src/runtime-types.ts:260`](../packages/core/agent/src/runtime-types.ts) | [`agent-loop`](../packages/core/agent-loop) (`waterfall`) | [`compaction-basic`](../packages/compaction/compaction-basic), [`llm-retry`](../packages/llm/llm-retry) |
-| `agent/session-start` | `emit` | [`packages/core/agent/src/runtime-types.ts:217`](../packages/core/agent/src/runtime-types.ts) | [`agent-loop`](../packages/core/agent-loop) (`emitAgentEvent`) | [`goal`](../packages/goal/goal), [`goal-round-driver`](../packages/goal/goal-round-driver), [`hooks-claude-code`](../packages/hooks/hooks-claude-code), [`hooks-codex`](../packages/hooks/hooks-codex), [`team`](../packages/experimental/team) |
-| `agent/status` | `emit` | [`packages/core/agent/src/runtime-types.ts:178`](../packages/core/agent/src/runtime-types.ts) | [`agent-loop`](../packages/core/agent-loop) (`emit`) | [`agent`](../packages/core/agent), `apiproxy`, [`compaction-basic`](../packages/compaction/compaction-basic), [`goal-round-driver`](../packages/goal/goal-round-driver), [`schedule`](../packages/schedule/schedule), `server`, [`team`](../packages/experimental/team) |
+| `agent/session-start` | `emit` | [`packages/core/agent/src/runtime-types.ts:217`](../packages/core/agent/src/runtime-types.ts) | [`agent-loop`](../packages/core/agent-loop) (`emitAgentEvent`) | `agent-team`, [`goal`](../packages/goal/goal), [`goal-round-driver`](../packages/goal/goal-round-driver), [`hooks-claude-code`](../packages/hooks/hooks-claude-code), [`hooks-codex`](../packages/hooks/hooks-codex) |
+| `agent/status` | `emit` | [`packages/core/agent/src/runtime-types.ts:178`](../packages/core/agent/src/runtime-types.ts) | [`agent-loop`](../packages/core/agent-loop) (`emit`) | [`agent`](../packages/core/agent), `agent-team`, `apiproxy`, [`compaction-basic`](../packages/compaction/compaction-basic), [`goal-round-driver`](../packages/goal/goal-round-driver), [`schedule`](../packages/schedule/schedule), `server` |
 | `agent/turn-stopping` | `serial` | [`packages/core/agent/src/runtime-types.ts:278`](../packages/core/agent/src/runtime-types.ts) | [`agent-loop`](../packages/core/agent-loop) (`serial`) | [`hooks-claude-code`](../packages/hooks/hooks-claude-code), [`hooks-codex`](../packages/hooks/hooks-codex) |
 | `approval/request` | `waterfall` | [`packages/interaction/user-approval/src/index.ts:30`](../packages/interaction/user-approval/src/index.ts) | [`user-approval`](../packages/interaction/user-approval) (`waterfall`) | [`acp`](../packages/acp/acp), `apiproxy` |
 | `commands/change` | `emit` | [`packages/interaction/commands/src/types.ts:80`](../packages/interaction/commands/src/types.ts) | [`commands`](../packages/interaction/commands) (`events.dispatch`) | `apiproxy` |
@@ -39,8 +39,8 @@ This matrix shows which packages dispatch each harness-owned event and which pac
 | `llm/stream` | `waterfall` | [`packages/llm/llm/src/index.ts:64`](../packages/llm/llm/src/index.ts) | [`llm`](../packages/llm/llm) (`waterfall`) | [`agent-loop`](../packages/core/agent-loop), [`llm`](../packages/llm/llm), [`llm-replay`](../packages/test-support/llm-replay), [`session-checkpoint-policy`](../packages/session/session-checkpoint-policy), [`session-title`](../packages/session/session-title) |
 | `session-telemetry/record` | `waterfall` | [`packages/session/session-telemetry/src/index.ts:43`](../packages/session/session-telemetry/src/index.ts) | [`session-telemetry`](../packages/session/session-telemetry) (`waterfall`) | - |
 | `session/created` | `emit` | [`packages/core/session/src/index.ts:54`](../packages/core/session/src/index.ts) | [`session`](../packages/core/session) (`events.dispatch`) | `apiproxy`, [`compaction`](../packages/compaction/compaction), [`goal`](../packages/goal/goal), [`hook-protocol`](../packages/hooks/hook-protocol), [`llm-retry`](../packages/llm/llm-retry), [`permission-presets`](../packages/interaction/permission-presets), [`plan-mode`](../packages/plan/plan-mode), [`schedule`](../packages/schedule/schedule), `server`, [`session`](../packages/core/session), [`session-persistence`](../packages/session/session-persistence), [`session-telemetry`](../packages/session/session-telemetry), [`time-context`](../packages/context/time-context), [`tool-workflow`](../packages/workflow/tool-workflow), [`tools`](../packages/core/tools), [`user-approval`](../packages/interaction/user-approval) |
-| `session/disposed` | `emit` | [`packages/core/session/src/index.ts:64`](../packages/core/session/src/index.ts) | [`session`](../packages/core/session) (`events.dispatch`) | [`agent-loop`](../packages/core/agent-loop), `apiproxy`, [`session-persistence`](../packages/session/session-persistence), [`session-projection-cache`](../packages/session/session-projection-cache), [`session-telemetry`](../packages/session/session-telemetry), [`session-title`](../packages/session/session-title), [`team`](../packages/experimental/team) |
-| `session/event` | `emit` | [`packages/core/session/src/index.ts:76`](../packages/core/session/src/index.ts) | [`session`](../packages/core/session) (`events.dispatch`) | [`acp`](../packages/acp/acp), [`agent-instructions`](../packages/context/agent-instructions), [`agent-loop`](../packages/core/agent-loop), [`agent-presets`](../packages/preset/agent-presets), `apiproxy`, [`compaction`](../packages/compaction/compaction), [`compaction-basic`](../packages/compaction/compaction-basic), [`file-reference-local`](../packages/context/file-reference-local), [`goal`](../packages/goal/goal), [`goal-round-driver`](../packages/goal/goal-round-driver), [`hook-protocol`](../packages/hooks/hook-protocol), [`loader-smoke`](../packages/test-support/loader-smoke), `server`, [`session`](../packages/core/session), [`session-persistence`](../packages/session/session-persistence), [`session-projection`](../packages/session/session-projection), [`session-projection-cache`](../packages/session/session-projection-cache), [`session-telemetry`](../packages/session/session-telemetry), [`session-telemetry-otel`](../packages/session/session-telemetry-otel), [`session-title`](../packages/session/session-title), [`team`](../packages/experimental/team), [`token-meter`](../packages/llm/token-meter), [`tool-workflow`](../packages/workflow/tool-workflow), [`tools`](../packages/core/tools), [`user-approval`](../packages/interaction/user-approval) |
+| `session/disposed` | `emit` | [`packages/core/session/src/index.ts:64`](../packages/core/session/src/index.ts) | [`session`](../packages/core/session) (`events.dispatch`) | [`agent-loop`](../packages/core/agent-loop), `agent-team`, `apiproxy`, [`session-persistence`](../packages/session/session-persistence), [`session-projection-cache`](../packages/session/session-projection-cache), [`session-telemetry`](../packages/session/session-telemetry), [`session-title`](../packages/session/session-title) |
+| `session/event` | `emit` | [`packages/core/session/src/index.ts:76`](../packages/core/session/src/index.ts) | [`session`](../packages/core/session) (`events.dispatch`) | [`acp`](../packages/acp/acp), [`agent-instructions`](../packages/context/agent-instructions), [`agent-loop`](../packages/core/agent-loop), [`agent-presets`](../packages/preset/agent-presets), `agent-team`, `apiproxy`, [`compaction`](../packages/compaction/compaction), [`compaction-basic`](../packages/compaction/compaction-basic), [`file-reference-local`](../packages/context/file-reference-local), [`goal`](../packages/goal/goal), [`goal-round-driver`](../packages/goal/goal-round-driver), [`hook-protocol`](../packages/hooks/hook-protocol), [`loader-smoke`](../packages/test-support/loader-smoke), `server`, [`session`](../packages/core/session), [`session-persistence`](../packages/session/session-persistence), [`session-projection`](../packages/session/session-projection), [`session-projection-cache`](../packages/session/session-projection-cache), [`session-telemetry`](../packages/session/session-telemetry), [`session-telemetry-otel`](../packages/session/session-telemetry-otel), [`session-title`](../packages/session/session-title), [`token-meter`](../packages/llm/token-meter), [`tool-workflow`](../packages/workflow/tool-workflow), [`tools`](../packages/core/tools), [`user-approval`](../packages/interaction/user-approval) |
 | `session/flush` | `parallel` | [`packages/core/session/src/index.ts:85`](../packages/core/session/src/index.ts) | [`session`](../packages/core/session) (`events.dispatch`) | [`session-persistence`](../packages/session/session-persistence), [`session-telemetry`](../packages/session/session-telemetry) |
 | `settings/document-updated` | `emit` | [`packages/settings/settings/src/types.ts:48`](../packages/settings/settings/src/types.ts) | [`settings`](../packages/settings/settings) (`events.dispatch`) | `apiproxy` |
 | `settings/updated` | `emit` | [`packages/settings/settings/src/types.ts:35`](../packages/settings/settings/src/types.ts) | [`settings`](../packages/settings/settings) (`events.dispatch`) | [`settings`](../packages/settings/settings) |
@@ -68,7 +68,7 @@ This matrix shows which packages dispatch each harness-owned event and which pac
 
 | Event string | Dispatchers | Listeners |
 | --- | --- | --- |
-| `internal/dispatch` | - | [`commands`](../packages/interaction/commands), [`compaction`](../packages/compaction/compaction), [`fs`](../packages/fs/fs), [`goal`](../packages/goal/goal), [`goal-round-driver`](../packages/goal/goal-round-driver), [`hook-protocol`](../packages/hooks/hook-protocol), [`llm-retry`](../packages/llm/llm-retry), [`permission-presets`](../packages/interaction/permission-presets), [`plan-mode`](../packages/plan/plan-mode), [`sandbox-policy`](../packages/sandbox/sandbox-policy), [`schedule`](../packages/schedule/schedule), [`scope`](../packages/core/scope), [`session`](../packages/core/session), [`session-title`](../packages/session/session-title), [`subagent`](../packages/subagent/subagent), [`team`](../packages/experimental/team), [`terminal-bash`](../packages/terminal/terminal-bash), [`time-context`](../packages/context/time-context), [`tool-todo`](../packages/todo/tool-todo), [`tool-workflow`](../packages/workflow/tool-workflow), [`tools`](../packages/core/tools), [`user-approval`](../packages/interaction/user-approval), [`workflow`](../packages/workflow/workflow) |
+| `internal/dispatch` | - | `agent-team`, [`commands`](../packages/interaction/commands), [`compaction`](../packages/compaction/compaction), [`fs`](../packages/fs/fs), [`goal`](../packages/goal/goal), [`goal-round-driver`](../packages/goal/goal-round-driver), [`hook-protocol`](../packages/hooks/hook-protocol), [`llm-retry`](../packages/llm/llm-retry), [`permission-presets`](../packages/interaction/permission-presets), [`plan-mode`](../packages/plan/plan-mode), [`sandbox-policy`](../packages/sandbox/sandbox-policy), [`schedule`](../packages/schedule/schedule), [`scope`](../packages/core/scope), [`session`](../packages/core/session), [`session-title`](../packages/session/session-title), [`subagent`](../packages/subagent/subagent), [`terminal-bash`](../packages/terminal/terminal-bash), [`time-context`](../packages/context/time-context), [`tool-todo`](../packages/todo/tool-todo), [`tool-workflow`](../packages/workflow/tool-workflow), [`tools`](../packages/core/tools), [`user-approval`](../packages/interaction/user-approval), [`workflow`](../packages/workflow/workflow) |
 | `internal/plugin` | - | `loader`, [`lsp-stdio`](../packages/lsp/lsp-stdio), `webserver` |
 | `internal/service` | - | [`agent-presets`](../packages/preset/agent-presets), `gateway` |
 | `internal/status` | - | [`agent`](../packages/core/agent) |

+ 7 - 7
docs/event-producer-consumer.zh.md

@@ -11,8 +11,8 @@
 | --- | --- | --- | --- | --- |
 | `agent-loop/config-start-failed` | `emit` | [`packages/core/agent-loop/src/index.ts:183`](../packages/core/agent-loop/src/index.ts) | [`agent-loop`](../packages/core/agent-loop) (`events.dispatch`) | - |
 | `agent-preset/selected` | `emit` | [`packages/preset/agent-presets/src/types.ts:13`](../packages/preset/agent-presets/src/types.ts) | [`agent-presets`](../packages/preset/agent-presets) (`emit`) | `apiproxy` |
-| `agent/created` | `emit` | [`packages/core/agent/src/runtime-types.ts:159`](../packages/core/agent/src/runtime-types.ts) | [`agent`](../packages/core/agent) (`events.dispatch`) | [`agent-presets`](../packages/preset/agent-presets), [`file-reference-local`](../packages/context/file-reference-local), [`goal-round-driver`](../packages/goal/goal-round-driver), [`schedule`](../packages/schedule/schedule), [`tool-team`](../packages/experimental/tool-team) |
-| `agent/disposed` | `emit` | [`packages/core/agent/src/runtime-types.ts:168`](../packages/core/agent/src/runtime-types.ts) | [`agent`](../packages/core/agent) (`events.dispatch`) | [`agent-loop`](../packages/core/agent-loop), [`file-reference-local`](../packages/context/file-reference-local), [`goal-round-driver`](../packages/goal/goal-round-driver), [`subagent`](../packages/subagent/subagent), [`tool-team`](../packages/experimental/tool-team) |
+| `agent/created` | `emit` | [`packages/core/agent/src/runtime-types.ts:159`](../packages/core/agent/src/runtime-types.ts) | [`agent`](../packages/core/agent) (`events.dispatch`) | [`agent-presets`](../packages/preset/agent-presets), [`file-reference-local`](../packages/context/file-reference-local), [`goal-round-driver`](../packages/goal/goal-round-driver), [`schedule`](../packages/schedule/schedule), `tool-agent-team` |
+| `agent/disposed` | `emit` | [`packages/core/agent/src/runtime-types.ts:168`](../packages/core/agent/src/runtime-types.ts) | [`agent`](../packages/core/agent) (`events.dispatch`) | [`agent-loop`](../packages/core/agent-loop), [`file-reference-local`](../packages/context/file-reference-local), [`goal-round-driver`](../packages/goal/goal-round-driver), [`subagent`](../packages/subagent/subagent), `tool-agent-team` |
 | `agent/error` | `emit` | [`packages/core/agent/src/runtime-types.ts:290`](../packages/core/agent/src/runtime-types.ts) | [`agent-loop`](../packages/core/agent-loop) (`emit`) | [`acp`](../packages/acp/acp), `apiproxy`, [`goal-round-driver`](../packages/goal/goal-round-driver), [`session-telemetry`](../packages/session/session-telemetry) |
 | `agent/inbox/claimed` | `emit` | [`packages/core/agent/src/runtime-types.ts:197`](../packages/core/agent/src/runtime-types.ts) | [`agent-loop`](../packages/core/agent-loop) (`emit`) | [`acp`](../packages/acp/acp), [`goal-round-driver`](../packages/goal/goal-round-driver), [`subagent`](../packages/subagent/subagent), [`tool-jobs`](../packages/jobs/tool-jobs) |
 | `agent/inbox/discarded` | `emit` | [`packages/core/agent/src/runtime-types.ts:205`](../packages/core/agent/src/runtime-types.ts) | [`agent-loop`](../packages/core/agent-loop) (`emit`) | [`goal-round-driver`](../packages/goal/goal-round-driver), [`subagent`](../packages/subagent/subagent) |
@@ -20,8 +20,8 @@
 | `agent/pre-step` | `waterfall` | [`packages/core/agent/src/runtime-types.ts:231`](../packages/core/agent/src/runtime-types.ts) | [`agent-loop`](../packages/core/agent-loop) (`waterfall`) | [`agent-instructions`](../packages/context/agent-instructions), [`compaction-basic`](../packages/compaction/compaction-basic), [`goal-round-driver`](../packages/goal/goal-round-driver), [`hooks-claude-code`](../packages/hooks/hooks-claude-code), [`hooks-codex`](../packages/hooks/hooks-codex), [`plan-mode`](../packages/plan/plan-mode), [`repeat-tool-reminder`](../packages/guard/repeat-tool-reminder), [`session-checkpoint-policy`](../packages/session/session-checkpoint-policy), [`session-reference`](../packages/context/session-reference), [`subagent-in-process-driver`](../packages/subagent/subagent-in-process-driver), [`time-context`](../packages/context/time-context), [`tmux-context`](../packages/context/tmux-context), [`tool-cordis`](../packages/extensions/tool-cordis), [`tool-skill`](../packages/skill/tool-skill) |
 | `agent/request` | `waterfall` | [`packages/core/agent/src/runtime-types.ts:244`](../packages/core/agent/src/runtime-types.ts) | [`agent-loop`](../packages/core/agent-loop) (`waterfall`) | [`agent`](../packages/core/agent) |
 | `agent/request-error` | `waterfall` | [`packages/core/agent/src/runtime-types.ts:260`](../packages/core/agent/src/runtime-types.ts) | [`agent-loop`](../packages/core/agent-loop) (`waterfall`) | [`compaction-basic`](../packages/compaction/compaction-basic), [`llm-retry`](../packages/llm/llm-retry) |
-| `agent/session-start` | `emit` | [`packages/core/agent/src/runtime-types.ts:217`](../packages/core/agent/src/runtime-types.ts) | [`agent-loop`](../packages/core/agent-loop) (`emitAgentEvent`) | [`goal`](../packages/goal/goal), [`goal-round-driver`](../packages/goal/goal-round-driver), [`hooks-claude-code`](../packages/hooks/hooks-claude-code), [`hooks-codex`](../packages/hooks/hooks-codex), [`team`](../packages/experimental/team) |
-| `agent/status` | `emit` | [`packages/core/agent/src/runtime-types.ts:178`](../packages/core/agent/src/runtime-types.ts) | [`agent-loop`](../packages/core/agent-loop) (`emit`) | [`agent`](../packages/core/agent), `apiproxy`, [`compaction-basic`](../packages/compaction/compaction-basic), [`goal-round-driver`](../packages/goal/goal-round-driver), [`schedule`](../packages/schedule/schedule), `server`, [`team`](../packages/experimental/team) |
+| `agent/session-start` | `emit` | [`packages/core/agent/src/runtime-types.ts:217`](../packages/core/agent/src/runtime-types.ts) | [`agent-loop`](../packages/core/agent-loop) (`emitAgentEvent`) | `agent-team`, [`goal`](../packages/goal/goal), [`goal-round-driver`](../packages/goal/goal-round-driver), [`hooks-claude-code`](../packages/hooks/hooks-claude-code), [`hooks-codex`](../packages/hooks/hooks-codex) |
+| `agent/status` | `emit` | [`packages/core/agent/src/runtime-types.ts:178`](../packages/core/agent/src/runtime-types.ts) | [`agent-loop`](../packages/core/agent-loop) (`emit`) | [`agent`](../packages/core/agent), `agent-team`, `apiproxy`, [`compaction-basic`](../packages/compaction/compaction-basic), [`goal-round-driver`](../packages/goal/goal-round-driver), [`schedule`](../packages/schedule/schedule), `server` |
 | `agent/turn-stopping` | `serial` | [`packages/core/agent/src/runtime-types.ts:278`](../packages/core/agent/src/runtime-types.ts) | [`agent-loop`](../packages/core/agent-loop) (`serial`) | [`hooks-claude-code`](../packages/hooks/hooks-claude-code), [`hooks-codex`](../packages/hooks/hooks-codex) |
 | `approval/request` | `waterfall` | [`packages/interaction/user-approval/src/index.ts:30`](../packages/interaction/user-approval/src/index.ts) | [`user-approval`](../packages/interaction/user-approval) (`waterfall`) | [`acp`](../packages/acp/acp), `apiproxy` |
 | `commands/change` | `emit` | [`packages/interaction/commands/src/types.ts:80`](../packages/interaction/commands/src/types.ts) | [`commands`](../packages/interaction/commands) (`events.dispatch`) | `apiproxy` |
@@ -41,8 +41,8 @@
 | `llm/stream` | `waterfall` | [`packages/llm/llm/src/index.ts:64`](../packages/llm/llm/src/index.ts) | [`llm`](../packages/llm/llm) (`waterfall`) | [`agent-loop`](../packages/core/agent-loop), [`llm`](../packages/llm/llm), [`llm-replay`](../packages/test-support/llm-replay), [`session-checkpoint-policy`](../packages/session/session-checkpoint-policy), [`session-title`](../packages/session/session-title) |
 | `session-telemetry/record` | `waterfall` | [`packages/session/session-telemetry/src/index.ts:43`](../packages/session/session-telemetry/src/index.ts) | [`session-telemetry`](../packages/session/session-telemetry) (`waterfall`) | - |
 | `session/created` | `emit` | [`packages/core/session/src/index.ts:54`](../packages/core/session/src/index.ts) | [`session`](../packages/core/session) (`events.dispatch`) | `apiproxy`, [`compaction`](../packages/compaction/compaction), [`goal`](../packages/goal/goal), [`hook-protocol`](../packages/hooks/hook-protocol), [`llm-retry`](../packages/llm/llm-retry), [`permission-presets`](../packages/interaction/permission-presets), [`plan-mode`](../packages/plan/plan-mode), [`schedule`](../packages/schedule/schedule), `server`, [`session`](../packages/core/session), [`session-persistence`](../packages/session/session-persistence), [`session-telemetry`](../packages/session/session-telemetry), [`time-context`](../packages/context/time-context), [`tool-workflow`](../packages/workflow/tool-workflow), [`tools`](../packages/core/tools), [`user-approval`](../packages/interaction/user-approval) |
-| `session/disposed` | `emit` | [`packages/core/session/src/index.ts:64`](../packages/core/session/src/index.ts) | [`session`](../packages/core/session) (`events.dispatch`) | [`agent-loop`](../packages/core/agent-loop), `apiproxy`, [`session-persistence`](../packages/session/session-persistence), [`session-projection-cache`](../packages/session/session-projection-cache), [`session-telemetry`](../packages/session/session-telemetry), [`session-title`](../packages/session/session-title), [`team`](../packages/experimental/team) |
-| `session/event` | `emit` | [`packages/core/session/src/index.ts:76`](../packages/core/session/src/index.ts) | [`session`](../packages/core/session) (`events.dispatch`) | [`acp`](../packages/acp/acp), [`agent-instructions`](../packages/context/agent-instructions), [`agent-loop`](../packages/core/agent-loop), [`agent-presets`](../packages/preset/agent-presets), `apiproxy`, [`compaction`](../packages/compaction/compaction), [`compaction-basic`](../packages/compaction/compaction-basic), [`file-reference-local`](../packages/context/file-reference-local), [`goal`](../packages/goal/goal), [`goal-round-driver`](../packages/goal/goal-round-driver), [`hook-protocol`](../packages/hooks/hook-protocol), [`loader-smoke`](../packages/test-support/loader-smoke), `server`, [`session`](../packages/core/session), [`session-persistence`](../packages/session/session-persistence), [`session-projection`](../packages/session/session-projection), [`session-projection-cache`](../packages/session/session-projection-cache), [`session-telemetry`](../packages/session/session-telemetry), [`session-telemetry-otel`](../packages/session/session-telemetry-otel), [`session-title`](../packages/session/session-title), [`team`](../packages/experimental/team), [`token-meter`](../packages/llm/token-meter), [`tool-workflow`](../packages/workflow/tool-workflow), [`tools`](../packages/core/tools), [`user-approval`](../packages/interaction/user-approval) |
+| `session/disposed` | `emit` | [`packages/core/session/src/index.ts:64`](../packages/core/session/src/index.ts) | [`session`](../packages/core/session) (`events.dispatch`) | [`agent-loop`](../packages/core/agent-loop), `agent-team`, `apiproxy`, [`session-persistence`](../packages/session/session-persistence), [`session-projection-cache`](../packages/session/session-projection-cache), [`session-telemetry`](../packages/session/session-telemetry), [`session-title`](../packages/session/session-title) |
+| `session/event` | `emit` | [`packages/core/session/src/index.ts:76`](../packages/core/session/src/index.ts) | [`session`](../packages/core/session) (`events.dispatch`) | [`acp`](../packages/acp/acp), [`agent-instructions`](../packages/context/agent-instructions), [`agent-loop`](../packages/core/agent-loop), [`agent-presets`](../packages/preset/agent-presets), `agent-team`, `apiproxy`, [`compaction`](../packages/compaction/compaction), [`compaction-basic`](../packages/compaction/compaction-basic), [`file-reference-local`](../packages/context/file-reference-local), [`goal`](../packages/goal/goal), [`goal-round-driver`](../packages/goal/goal-round-driver), [`hook-protocol`](../packages/hooks/hook-protocol), [`loader-smoke`](../packages/test-support/loader-smoke), `server`, [`session`](../packages/core/session), [`session-persistence`](../packages/session/session-persistence), [`session-projection`](../packages/session/session-projection), [`session-projection-cache`](../packages/session/session-projection-cache), [`session-telemetry`](../packages/session/session-telemetry), [`session-telemetry-otel`](../packages/session/session-telemetry-otel), [`session-title`](../packages/session/session-title), [`token-meter`](../packages/llm/token-meter), [`tool-workflow`](../packages/workflow/tool-workflow), [`tools`](../packages/core/tools), [`user-approval`](../packages/interaction/user-approval) |
 | `session/flush` | `parallel` | [`packages/core/session/src/index.ts:85`](../packages/core/session/src/index.ts) | [`session`](../packages/core/session) (`events.dispatch`) | [`session-persistence`](../packages/session/session-persistence), [`session-telemetry`](../packages/session/session-telemetry) |
 | `settings/document-updated` | `emit` | [`packages/settings/settings/src/types.ts:48`](../packages/settings/settings/src/types.ts) | [`settings`](../packages/settings/settings) (`events.dispatch`) | `apiproxy` |
 | `settings/updated` | `emit` | [`packages/settings/settings/src/types.ts:35`](../packages/settings/settings/src/types.ts) | [`settings`](../packages/settings/settings) (`events.dispatch`) | [`settings`](../packages/settings/settings) |
@@ -70,7 +70,7 @@
 
 | 事件字符串 | 派发方 | 监听方 |
 | --- | --- | --- |
-| `internal/dispatch` | - | [`commands`](../packages/interaction/commands), [`compaction`](../packages/compaction/compaction), [`fs`](../packages/fs/fs), [`goal`](../packages/goal/goal), [`goal-round-driver`](../packages/goal/goal-round-driver), [`hook-protocol`](../packages/hooks/hook-protocol), [`llm-retry`](../packages/llm/llm-retry), [`permission-presets`](../packages/interaction/permission-presets), [`plan-mode`](../packages/plan/plan-mode), [`sandbox-policy`](../packages/sandbox/sandbox-policy), [`schedule`](../packages/schedule/schedule), [`scope`](../packages/core/scope), [`session`](../packages/core/session), [`session-title`](../packages/session/session-title), [`subagent`](../packages/subagent/subagent), [`team`](../packages/experimental/team), [`terminal-bash`](../packages/terminal/terminal-bash), [`time-context`](../packages/context/time-context), [`tool-todo`](../packages/todo/tool-todo), [`tool-workflow`](../packages/workflow/tool-workflow), [`tools`](../packages/core/tools), [`user-approval`](../packages/interaction/user-approval), [`workflow`](../packages/workflow/workflow) |
+| `internal/dispatch` | - | `agent-team`, [`commands`](../packages/interaction/commands), [`compaction`](../packages/compaction/compaction), [`fs`](../packages/fs/fs), [`goal`](../packages/goal/goal), [`goal-round-driver`](../packages/goal/goal-round-driver), [`hook-protocol`](../packages/hooks/hook-protocol), [`llm-retry`](../packages/llm/llm-retry), [`permission-presets`](../packages/interaction/permission-presets), [`plan-mode`](../packages/plan/plan-mode), [`sandbox-policy`](../packages/sandbox/sandbox-policy), [`schedule`](../packages/schedule/schedule), [`scope`](../packages/core/scope), [`session`](../packages/core/session), [`session-title`](../packages/session/session-title), [`subagent`](../packages/subagent/subagent), [`terminal-bash`](../packages/terminal/terminal-bash), [`time-context`](../packages/context/time-context), [`tool-todo`](../packages/todo/tool-todo), [`tool-workflow`](../packages/workflow/tool-workflow), [`tools`](../packages/core/tools), [`user-approval`](../packages/interaction/user-approval), [`workflow`](../packages/workflow/workflow) |
 | `internal/plugin` | - | `loader`, [`lsp-stdio`](../packages/lsp/lsp-stdio), `webserver` |
 | `internal/service` | - | [`agent-presets`](../packages/preset/agent-presets), `gateway` |
 | `internal/status` | - | [`agent`](../packages/core/agent) |

+ 2 - 2
docs/module-graph.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 docs/module-graph.md
-module-graph.md: 55fbda46e76db21b5132f56716d3c300a3e469a0
-module-graph.zh.md: cd205a3f6d8d8ec3ddc8b07cce0f8d3b3eac9779
+module-graph.md: f8eff01aeedb83f6824a605faf86aeec2b0385ab
+module-graph.zh.md: 372deaba770e468327b570fc9d1e022799e5cf69

+ 17 - 17
docs/module-graph.md

@@ -193,8 +193,8 @@ flowchart TD
     pkg_sdk_jsonrpc_demo["sdk-jsonrpc-demo"]
   end
   subgraph group_experimental["packages/experimental"]
-    pkg_team["team"]
-    pkg_tool_team["tool-team"]
+    pkg_experimental_agent_team["experimental-agent-team"]
+    pkg_experimental_tool_agent_team["experimental-tool-agent-team"]
   end
   subgraph group_extensions["packages/extensions"]
     pkg_client_ui_cordis["client-ui-cordis"]
@@ -1032,13 +1032,13 @@ flowchart TD
   pkg_compaction_tool_result_pruner --> pkg_llm
   pkg_compaction_tool_result_pruner --> pkg_session
   pkg_compaction_tool_result_pruner --> pkg_token_meter
-  pkg_team --> pkg_agent
-  pkg_team --> pkg_brand
-  pkg_team --> pkg_invariants
-  pkg_team --> pkg_llm
-  pkg_team --> pkg_session
-  pkg_team --> pkg_session_persistence
-  pkg_team --> pkg_subagent
+  pkg_experimental_agent_team --> pkg_agent
+  pkg_experimental_agent_team --> pkg_brand
+  pkg_experimental_agent_team --> pkg_invariants
+  pkg_experimental_agent_team --> pkg_llm
+  pkg_experimental_agent_team --> pkg_session
+  pkg_experimental_agent_team --> pkg_session_persistence
+  pkg_experimental_agent_team --> pkg_subagent
   pkg_tool_cordis --> pkg_agent
   pkg_tool_cordis --> pkg_cordis_host_runner
   pkg_tool_cordis --> pkg_invariants
@@ -1137,12 +1137,12 @@ flowchart TD
   pkg_agent_spine_demo --> pkg_tool_jobs
   pkg_agent_spine_demo --> pkg_tool_skill
   pkg_agent_spine_demo --> pkg_tools
-  pkg_tool_team --> pkg_agent
-  pkg_tool_team --> pkg_invariants
-  pkg_tool_team --> pkg_session
-  pkg_tool_team --> pkg_system_prompt
-  pkg_tool_team --> pkg_team
-  pkg_tool_team --> pkg_tools
+  pkg_experimental_tool_agent_team --> pkg_agent
+  pkg_experimental_tool_agent_team --> pkg_experimental_agent_team
+  pkg_experimental_tool_agent_team --> pkg_invariants
+  pkg_experimental_tool_agent_team --> pkg_session
+  pkg_experimental_tool_agent_team --> pkg_system_prompt
+  pkg_experimental_tool_agent_team --> pkg_tools
   pkg_sdk_client --> pkg_invariants
   pkg_sdk_client --> pkg_llm
   pkg_sdk_client --> pkg_sdk_protocol
@@ -1621,7 +1621,7 @@ flowchart TD
 | [`hooks-claude-code`](../packages/hooks/hooks-claude-code) | `hooks` | [`agent`](../packages/core/agent), [`hook-protocol`](../packages/hooks/hook-protocol), [`invariants`](../packages/runtime-diagnostics/invariants), [`llm`](../packages/llm/llm), [`session`](../packages/core/session), [`session-persistence`](../packages/session/session-persistence), [`subagent`](../packages/subagent/subagent), [`tools`](../packages/core/tools) |
 | [`web-app`](../packages/bundle/web-app) | `bundle` | [`invariants`](../packages/runtime-diagnostics/invariants), [`shell-env`](../packages/shell/shell-env), [`system-prompt`](../packages/core/system-prompt) |
 | [`compaction-tool-result-pruner`](../packages/compaction/compaction-tool-result-pruner) | `compaction` | [`compaction`](../packages/compaction/compaction), [`invariants`](../packages/runtime-diagnostics/invariants), [`llm`](../packages/llm/llm), [`session`](../packages/core/session), [`token-meter`](../packages/llm/token-meter) |
-| [`team`](../packages/experimental/team) | `experimental` | [`agent`](../packages/core/agent), [`brand`](../packages/util/brand), [`invariants`](../packages/runtime-diagnostics/invariants), [`llm`](../packages/llm/llm), [`session`](../packages/core/session), [`session-persistence`](../packages/session/session-persistence), [`subagent`](../packages/subagent/subagent) |
+| [`experimental-agent-team`](../packages/experimental/agent-team) | `experimental` | [`agent`](../packages/core/agent), [`brand`](../packages/util/brand), [`invariants`](../packages/runtime-diagnostics/invariants), [`llm`](../packages/llm/llm), [`session`](../packages/core/session), [`session-persistence`](../packages/session/session-persistence), [`subagent`](../packages/subagent/subagent) |
 | [`tool-cordis`](../packages/extensions/tool-cordis) | `extensions` | [`agent`](../packages/core/agent), [`cordis-host-runner`](../packages/extensions/cordis-host-runner), [`invariants`](../packages/runtime-diagnostics/invariants), [`llm`](../packages/llm/llm), [`scope`](../packages/core/scope), [`session`](../packages/core/session), [`system-prompt`](../packages/core/system-prompt), [`tools`](../packages/core/tools) |
 | [`host-apiproxy`](../packages/host/apiproxy) | `host` | [`agent-presets`](../packages/preset/agent-presets), [`cordis-host-runner`](../packages/extensions/cordis-host-runner), [`invariants`](../packages/runtime-diagnostics/invariants) |
 | [`sdk-protocol`](../packages/sdk/protocol) | `sdk` | [`invariants`](../packages/runtime-diagnostics/invariants), [`llm`](../packages/llm/llm), [`session`](../packages/core/session), [`subagent`](../packages/subagent/subagent) |
@@ -1634,7 +1634,7 @@ flowchart TD
 | [`client-connection`](../packages/client/connection) | `client` | [`attachment`](../packages/attachment/attachment), [`commands`](../packages/interaction/commands), [`host-apiproxy`](../packages/host/apiproxy), [`host-webserver`](../packages/host/webserver), [`invariants`](../packages/runtime-diagnostics/invariants), [`llm`](../packages/llm/llm), [`session`](../packages/core/session), [`tools`](../packages/core/tools) |
 | [`compaction-basic`](../packages/compaction/compaction-basic) | `compaction` | [`agent`](../packages/core/agent), [`commands`](../packages/interaction/commands), [`compaction`](../packages/compaction/compaction), [`compaction-tool-result-pruner`](../packages/compaction/compaction-tool-result-pruner), [`invariants`](../packages/runtime-diagnostics/invariants), [`llm`](../packages/llm/llm), [`session`](../packages/core/session), [`token-meter`](../packages/llm/token-meter) |
 | [`agent-spine-demo`](../packages/examples/agent-spine-demo) | `examples` | [`agent`](../packages/core/agent), [`agent-instructions`](../packages/context/agent-instructions), [`agent-loop`](../packages/core/agent-loop), [`goal`](../packages/goal/goal), [`goal-round-driver`](../packages/goal/goal-round-driver), [`home-paths`](../packages/util/home-paths), [`invariants`](../packages/runtime-diagnostics/invariants), [`jobs-local`](../packages/jobs/jobs-local), [`llm`](../packages/llm/llm), [`llm-retry`](../packages/llm/llm-retry), [`scope`](../packages/core/scope), [`session`](../packages/core/session), [`session-title`](../packages/session/session-title), [`shell-env`](../packages/shell/shell-env), [`skill`](../packages/skill/skill), [`skill-filesystem`](../packages/skill/skill-filesystem), [`system-prompt`](../packages/core/system-prompt), [`tool-bash`](../packages/shell/tool-bash), [`tool-goal`](../packages/goal/tool-goal), [`tool-jobs`](../packages/jobs/tool-jobs), [`tool-skill`](../packages/skill/tool-skill), [`tools`](../packages/core/tools) |
-| [`tool-team`](../packages/experimental/tool-team) | `experimental` | [`agent`](../packages/core/agent), [`invariants`](../packages/runtime-diagnostics/invariants), [`session`](../packages/core/session), [`system-prompt`](../packages/core/system-prompt), [`team`](../packages/experimental/team), [`tools`](../packages/core/tools) |
+| [`experimental-tool-agent-team`](../packages/experimental/tool-agent-team) | `experimental` | [`agent`](../packages/core/agent), [`experimental-agent-team`](../packages/experimental/agent-team), [`invariants`](../packages/runtime-diagnostics/invariants), [`session`](../packages/core/session), [`system-prompt`](../packages/core/system-prompt), [`tools`](../packages/core/tools) |
 | [`sdk-client`](../packages/sdk/client) | `sdk` | [`invariants`](../packages/runtime-diagnostics/invariants), [`llm`](../packages/llm/llm), [`sdk-protocol`](../packages/sdk/protocol), [`session`](../packages/core/session) |
 | [`sdk-jsonrpc-server`](../packages/sdk/server) | `sdk` | [`agent`](../packages/core/agent), [`invariants`](../packages/runtime-diagnostics/invariants), [`llm`](../packages/llm/llm), [`llm-deepseek`](../packages/llm/llm-deepseek), [`scope`](../packages/core/scope), [`sdk-protocol`](../packages/sdk/protocol), [`session`](../packages/core/session), [`subagent`](../packages/subagent/subagent) |
 | [`subagent-dsh-sdk`](../packages/subagent/subagent-dsh-sdk) | `subagent` | [`agent`](../packages/core/agent), [`invariants`](../packages/runtime-diagnostics/invariants), [`llm`](../packages/llm/llm), [`sdk-client`](../packages/sdk/client), [`session`](../packages/core/session), [`subagent`](../packages/subagent/subagent), [`subprocess`](../packages/subprocess/subprocess) |

+ 17 - 17
docs/module-graph.zh.md

@@ -195,8 +195,8 @@ flowchart TD
     pkg_sdk_jsonrpc_demo["sdk-jsonrpc-demo"]
   end
   subgraph group_experimental["packages/experimental"]
-    pkg_team["team"]
-    pkg_tool_team["tool-team"]
+    pkg_experimental_agent_team["experimental-agent-team"]
+    pkg_experimental_tool_agent_team["experimental-tool-agent-team"]
   end
   subgraph group_extensions["packages/extensions"]
     pkg_client_ui_cordis["client-ui-cordis"]
@@ -1034,13 +1034,13 @@ flowchart TD
   pkg_compaction_tool_result_pruner --> pkg_llm
   pkg_compaction_tool_result_pruner --> pkg_session
   pkg_compaction_tool_result_pruner --> pkg_token_meter
-  pkg_team --> pkg_agent
-  pkg_team --> pkg_brand
-  pkg_team --> pkg_invariants
-  pkg_team --> pkg_llm
-  pkg_team --> pkg_session
-  pkg_team --> pkg_session_persistence
-  pkg_team --> pkg_subagent
+  pkg_experimental_agent_team --> pkg_agent
+  pkg_experimental_agent_team --> pkg_brand
+  pkg_experimental_agent_team --> pkg_invariants
+  pkg_experimental_agent_team --> pkg_llm
+  pkg_experimental_agent_team --> pkg_session
+  pkg_experimental_agent_team --> pkg_session_persistence
+  pkg_experimental_agent_team --> pkg_subagent
   pkg_tool_cordis --> pkg_agent
   pkg_tool_cordis --> pkg_cordis_host_runner
   pkg_tool_cordis --> pkg_invariants
@@ -1139,12 +1139,12 @@ flowchart TD
   pkg_agent_spine_demo --> pkg_tool_jobs
   pkg_agent_spine_demo --> pkg_tool_skill
   pkg_agent_spine_demo --> pkg_tools
-  pkg_tool_team --> pkg_agent
-  pkg_tool_team --> pkg_invariants
-  pkg_tool_team --> pkg_session
-  pkg_tool_team --> pkg_system_prompt
-  pkg_tool_team --> pkg_team
-  pkg_tool_team --> pkg_tools
+  pkg_experimental_tool_agent_team --> pkg_agent
+  pkg_experimental_tool_agent_team --> pkg_experimental_agent_team
+  pkg_experimental_tool_agent_team --> pkg_invariants
+  pkg_experimental_tool_agent_team --> pkg_session
+  pkg_experimental_tool_agent_team --> pkg_system_prompt
+  pkg_experimental_tool_agent_team --> pkg_tools
   pkg_sdk_client --> pkg_invariants
   pkg_sdk_client --> pkg_llm
   pkg_sdk_client --> pkg_sdk_protocol
@@ -1623,7 +1623,7 @@ flowchart TD
 | [`hooks-claude-code`](../packages/hooks/hooks-claude-code) | `hooks` | [`agent`](../packages/core/agent), [`hook-protocol`](../packages/hooks/hook-protocol), [`invariants`](../packages/runtime-diagnostics/invariants), [`llm`](../packages/llm/llm), [`session`](../packages/core/session), [`session-persistence`](../packages/session/session-persistence), [`subagent`](../packages/subagent/subagent), [`tools`](../packages/core/tools) |
 | [`web-app`](../packages/bundle/web-app) | `bundle` | [`invariants`](../packages/runtime-diagnostics/invariants), [`shell-env`](../packages/shell/shell-env), [`system-prompt`](../packages/core/system-prompt) |
 | [`compaction-tool-result-pruner`](../packages/compaction/compaction-tool-result-pruner) | `compaction` | [`compaction`](../packages/compaction/compaction), [`invariants`](../packages/runtime-diagnostics/invariants), [`llm`](../packages/llm/llm), [`session`](../packages/core/session), [`token-meter`](../packages/llm/token-meter) |
-| [`team`](../packages/experimental/team) | `experimental` | [`agent`](../packages/core/agent), [`brand`](../packages/util/brand), [`invariants`](../packages/runtime-diagnostics/invariants), [`llm`](../packages/llm/llm), [`session`](../packages/core/session), [`session-persistence`](../packages/session/session-persistence), [`subagent`](../packages/subagent/subagent) |
+| [`experimental-agent-team`](../packages/experimental/agent-team) | `experimental` | [`agent`](../packages/core/agent), [`brand`](../packages/util/brand), [`invariants`](../packages/runtime-diagnostics/invariants), [`llm`](../packages/llm/llm), [`session`](../packages/core/session), [`session-persistence`](../packages/session/session-persistence), [`subagent`](../packages/subagent/subagent) |
 | [`tool-cordis`](../packages/extensions/tool-cordis) | `extensions` | [`agent`](../packages/core/agent), [`cordis-host-runner`](../packages/extensions/cordis-host-runner), [`invariants`](../packages/runtime-diagnostics/invariants), [`llm`](../packages/llm/llm), [`scope`](../packages/core/scope), [`session`](../packages/core/session), [`system-prompt`](../packages/core/system-prompt), [`tools`](../packages/core/tools) |
 | [`host-apiproxy`](../packages/host/apiproxy) | `host` | [`agent-presets`](../packages/preset/agent-presets), [`cordis-host-runner`](../packages/extensions/cordis-host-runner), [`invariants`](../packages/runtime-diagnostics/invariants) |
 | [`sdk-protocol`](../packages/sdk/protocol) | `sdk` | [`invariants`](../packages/runtime-diagnostics/invariants), [`llm`](../packages/llm/llm), [`session`](../packages/core/session), [`subagent`](../packages/subagent/subagent) |
@@ -1636,7 +1636,7 @@ flowchart TD
 | [`client-connection`](../packages/client/connection) | `client` | [`attachment`](../packages/attachment/attachment), [`commands`](../packages/interaction/commands), [`host-apiproxy`](../packages/host/apiproxy), [`host-webserver`](../packages/host/webserver), [`invariants`](../packages/runtime-diagnostics/invariants), [`llm`](../packages/llm/llm), [`session`](../packages/core/session), [`tools`](../packages/core/tools) |
 | [`compaction-basic`](../packages/compaction/compaction-basic) | `compaction` | [`agent`](../packages/core/agent), [`commands`](../packages/interaction/commands), [`compaction`](../packages/compaction/compaction), [`compaction-tool-result-pruner`](../packages/compaction/compaction-tool-result-pruner), [`invariants`](../packages/runtime-diagnostics/invariants), [`llm`](../packages/llm/llm), [`session`](../packages/core/session), [`token-meter`](../packages/llm/token-meter) |
 | [`agent-spine-demo`](../packages/examples/agent-spine-demo) | `examples` | [`agent`](../packages/core/agent), [`agent-instructions`](../packages/context/agent-instructions), [`agent-loop`](../packages/core/agent-loop), [`goal`](../packages/goal/goal), [`goal-round-driver`](../packages/goal/goal-round-driver), [`home-paths`](../packages/util/home-paths), [`invariants`](../packages/runtime-diagnostics/invariants), [`jobs-local`](../packages/jobs/jobs-local), [`llm`](../packages/llm/llm), [`llm-retry`](../packages/llm/llm-retry), [`scope`](../packages/core/scope), [`session`](../packages/core/session), [`session-title`](../packages/session/session-title), [`shell-env`](../packages/shell/shell-env), [`skill`](../packages/skill/skill), [`skill-filesystem`](../packages/skill/skill-filesystem), [`system-prompt`](../packages/core/system-prompt), [`tool-bash`](../packages/shell/tool-bash), [`tool-goal`](../packages/goal/tool-goal), [`tool-jobs`](../packages/jobs/tool-jobs), [`tool-skill`](../packages/skill/tool-skill), [`tools`](../packages/core/tools) |
-| [`tool-team`](../packages/experimental/tool-team) | `experimental` | [`agent`](../packages/core/agent), [`invariants`](../packages/runtime-diagnostics/invariants), [`session`](../packages/core/session), [`system-prompt`](../packages/core/system-prompt), [`team`](../packages/experimental/team), [`tools`](../packages/core/tools) |
+| [`experimental-tool-agent-team`](../packages/experimental/tool-agent-team) | `experimental` | [`agent`](../packages/core/agent), [`experimental-agent-team`](../packages/experimental/agent-team), [`invariants`](../packages/runtime-diagnostics/invariants), [`session`](../packages/core/session), [`system-prompt`](../packages/core/system-prompt), [`tools`](../packages/core/tools) |
 | [`sdk-client`](../packages/sdk/client) | `sdk` | [`invariants`](../packages/runtime-diagnostics/invariants), [`llm`](../packages/llm/llm), [`sdk-protocol`](../packages/sdk/protocol), [`session`](../packages/core/session) |
 | [`sdk-jsonrpc-server`](../packages/sdk/server) | `sdk` | [`agent`](../packages/core/agent), [`invariants`](../packages/runtime-diagnostics/invariants), [`llm`](../packages/llm/llm), [`llm-deepseek`](../packages/llm/llm-deepseek), [`scope`](../packages/core/scope), [`sdk-protocol`](../packages/sdk/protocol), [`session`](../packages/core/session), [`subagent`](../packages/subagent/subagent) |
 | [`subagent-dsh-sdk`](../packages/subagent/subagent-dsh-sdk) | `subagent` | [`agent`](../packages/core/agent), [`invariants`](../packages/runtime-diagnostics/invariants), [`llm`](../packages/llm/llm), [`sdk-client`](../packages/sdk/client), [`session`](../packages/core/session), [`subagent`](../packages/subagent/subagent), [`subprocess`](../packages/subprocess/subprocess) |

+ 2 - 2
docs/persistence-catalog.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 docs/persistence-catalog.md
-persistence-catalog.md: cbe9cec195ad899ba27dd08743d64090ae7277f2
-persistence-catalog.zh.md: 8057a0910e505b95872c341283d1acdbf033faaf
+persistence-catalog.md: 5bf9f2db778e320c7405e35643f6000384fc0c09
+persistence-catalog.zh.md: e977be51a7900a0b1817ad01150fcecfc56391b3

+ 8 - 8
docs/persistence-catalog.md

@@ -721,9 +721,9 @@ Source: [`packages/subagent/subagent/src/descriptor.ts:37`](../packages/subagent
 'team/member': { version: 1; teamId: TeamId; member: TeamMemberSnapshot }
 ```
 
-Types: [TeamId](subsystems/team.md) · [TeamMemberSnapshot](subsystems/team.md)
+Types: [TeamId](subsystems/agent-team.md) · [TeamMemberSnapshot](subsystems/agent-team.md)
 
-Source: [`packages/experimental/team/src/types.ts:206`](../packages/experimental/team/src/types.ts)
+Source: [`packages/experimental/agent-team/src/types.ts:206`](../packages/experimental/agent-team/src/types.ts)
 
 <a id="teammessagedelivered--log-only"></a>
 
@@ -739,9 +739,9 @@ Source: [`packages/experimental/team/src/types.ts:206`](../packages/experimental
 }
 ```
 
-Types: [TeamId](subsystems/team.md) · [TeamMessageId](subsystems/team.md)
+Types: [TeamId](subsystems/agent-team.md) · [TeamMessageId](subsystems/agent-team.md)
 
-Source: [`packages/experimental/team/src/types.ts:212`](../packages/experimental/team/src/types.ts)
+Source: [`packages/experimental/agent-team/src/types.ts:212`](../packages/experimental/agent-team/src/types.ts)
 
 <a id="teammessagequeued--log-only"></a>
 
@@ -752,9 +752,9 @@ Source: [`packages/experimental/team/src/types.ts:212`](../packages/experimental
 'team/message/queued': { version: 1; teamId: TeamId; message: TeamMessageSnapshot }
 ```
 
-Types: [TeamId](subsystems/team.md) · [TeamMessageSnapshot](subsystems/team.md)
+Types: [TeamId](subsystems/agent-team.md) · [TeamMessageSnapshot](subsystems/agent-team.md)
 
-Source: [`packages/experimental/team/src/types.ts:210`](../packages/experimental/team/src/types.ts)
+Source: [`packages/experimental/agent-team/src/types.ts:210`](../packages/experimental/agent-team/src/types.ts)
 
 <a id="teamtask--log-only"></a>
 
@@ -765,9 +765,9 @@ Source: [`packages/experimental/team/src/types.ts:210`](../packages/experimental
 'team/task': { version: 1; teamId: TeamId; task: TeamTaskSnapshot }
 ```
 
-Types: [TeamId](subsystems/team.md) · [TeamTaskSnapshot](subsystems/team.md)
+Types: [TeamId](subsystems/agent-team.md) · [TeamTaskSnapshot](subsystems/agent-team.md)
 
-Source: [`packages/experimental/team/src/types.ts:208`](../packages/experimental/team/src/types.ts)
+Source: [`packages/experimental/agent-team/src/types.ts:208`](../packages/experimental/agent-team/src/types.ts)
 
 ### `todo/*`
 

+ 8 - 8
docs/persistence-catalog.zh.md

@@ -723,9 +723,9 @@ export type SessionEvent<T extends SessionEventType = SessionEventType> = {
 'team/member': { version: 1; teamId: TeamId; member: TeamMemberSnapshot }
 ```
 
-类型:[TeamId](subsystems/team.md) · [TeamMemberSnapshot](subsystems/team.md)
+类型:[TeamId](subsystems/agent-team.md) · [TeamMemberSnapshot](subsystems/agent-team.md)
 
-来源:[`packages/experimental/team/src/types.ts:206`](../packages/experimental/team/src/types.ts)
+来源:[`packages/experimental/agent-team/src/types.ts:206`](../packages/experimental/agent-team/src/types.ts)
 
 <a id="teammessagedelivered--log-only"></a>
 
@@ -741,9 +741,9 @@ export type SessionEvent<T extends SessionEventType = SessionEventType> = {
 }
 ```
 
-类型:[TeamId](subsystems/team.md) · [TeamMessageId](subsystems/team.md)
+类型:[TeamId](subsystems/agent-team.md) · [TeamMessageId](subsystems/agent-team.md)
 
-来源:[`packages/experimental/team/src/types.ts:212`](../packages/experimental/team/src/types.ts)
+来源:[`packages/experimental/agent-team/src/types.ts:212`](../packages/experimental/agent-team/src/types.ts)
 
 <a id="teammessagequeued--log-only"></a>
 
@@ -754,9 +754,9 @@ export type SessionEvent<T extends SessionEventType = SessionEventType> = {
 'team/message/queued': { version: 1; teamId: TeamId; message: TeamMessageSnapshot }
 ```
 
-类型:[TeamId](subsystems/team.md) · [TeamMessageSnapshot](subsystems/team.md)
+类型:[TeamId](subsystems/agent-team.md) · [TeamMessageSnapshot](subsystems/agent-team.md)
 
-来源:[`packages/experimental/team/src/types.ts:210`](../packages/experimental/team/src/types.ts)
+来源:[`packages/experimental/agent-team/src/types.ts:210`](../packages/experimental/agent-team/src/types.ts)
 
 <a id="teamtask--log-only"></a>
 
@@ -767,9 +767,9 @@ export type SessionEvent<T extends SessionEventType = SessionEventType> = {
 'team/task': { version: 1; teamId: TeamId; task: TeamTaskSnapshot }
 ```
 
-类型:[TeamId](subsystems/team.md) · [TeamTaskSnapshot](subsystems/team.md)
+类型:[TeamId](subsystems/agent-team.md) · [TeamTaskSnapshot](subsystems/agent-team.md)
 
-来源:[`packages/experimental/team/src/types.ts:208`](../packages/experimental/team/src/types.ts)
+来源:[`packages/experimental/agent-team/src/types.ts:208`](../packages/experimental/agent-team/src/types.ts)
 
 ### `todo/*`
 

+ 2 - 2
docs/subsystems/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 docs/subsystems/README.md
-README.md: b3832e44d4fc2150efc4e81aab00d1006cb816b6
-README.zh.md: 5f5a44e9f21956921472c23a141eabac236704e9
+README.md: d926abac718ba14b0d50f27d7c00b421c8460352
+README.zh.md: f1b70aabe9ebbbe20274f5e9522ddead00a1f75f

+ 1 - 1
docs/subsystems/README.md

@@ -38,7 +38,7 @@ One page per subsystem of the DeepSeek Harness: what it is, the data structures
 | [skills.md](skills.md) | the skill service: discovery priority, `SkillSummary`/`SkillDefinition`, session-prefix catalog, model-facing `skill` loading |
 | [compaction.md](compaction.md) | the compaction seam: the `compaction/*` session events, `CompactionResult`, the `CompactionEngine` interface |
 | [subagent.md](subagent.md) | the subagent seam: the named-provider registry, `SubagentStartRequest`/`Result`/`Run`, the start-time-vs-runtime capability split |
-| [team.md](team.md) | Agent Teams: implicit Lead identity, named continuable teammates, durable peer mailbox, and shared task DAG |
+| [agent-team.md](agent-team.md) | Agent Teams: implicit Lead identity, named continuable teammates, durable peer mailbox, and shared task DAG |
 | [web.md](web.md) | the web access seam: `WebSearchRequest`/`Result`, `WebFetchRequest`/`Result`, `WebFetchBody`, provider availability, `WebError` |
 | [spill.md](spill.md) | the spill storage seam: `SaveTextSpill`, `SpillOwner`/`SpillSource`, `SpillRef`, the branded `SpillLocator` |
 | [workflow.md](workflow.md) | the workflow seam: `WorkflowStartRequest`, `WorkflowMeta`, `WorkflowRun`/`Result`, the `workflow/*` event payloads, `WorkflowError` fatality |

+ 1 - 1
docs/subsystems/README.zh.md

@@ -38,7 +38,7 @@
 | [skills.md](skills.md) | skill(技能)服务:发现优先级、`SkillSummary`/`SkillDefinition`、会话前缀目录、面向模型的 `skill` 加载 |
 | [compaction.md](compaction.md) | 压缩(compaction)seam:`compaction/*` 会话事件、`CompactionResult`、`CompactionEngine` 接口 |
 | [subagent.md](subagent.md) | subagent seam:命名提供方注册表、`SubagentStartRequest`/`Result`/`Run`、启动时与运行时能力拆分 |
-| [team.md](team.md) | Agent Teams:隐式 Lead 身份、具名 continuable teammate、持久 peer mailbox 与共享任务 DAG |
+| [agent-team.md](agent-team.md) | Agent Teams:隐式 Lead 身份、具名 continuable teammate、持久 peer mailbox 与共享任务 DAG |
 | [web.md](web.md) | Web 访问 seam:`WebSearchRequest`/`Result`、`WebFetchRequest`/`Result`、`WebFetchBody`、提供方可用性、`WebError` |
 | [spill.md](spill.md) | spill 存储 seam:`SaveTextSpill`、`SpillOwner`/`SpillSource`、`SpillRef`、品牌类型 `SpillLocator` |
 | [workflow.md](workflow.md) | 工作流 seam:`WorkflowStartRequest`、`WorkflowMeta`、`WorkflowRun`/`Result`、`workflow/*` 事件载荷、`WorkflowError` 致命性 |

+ 3 - 3
docs/subsystems/team.i18n.yaml → docs/subsystems/agent-team.i18n.yaml

@@ -1,6 +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 docs/subsystems/team.md
-team.md: 926434bb85d8cb3739e66fdf559c1c51d807613d
-team.zh.md: 7eeb4ef5aeeeee119ea931912390d4ff3d42bc85
+#   pnpm run verify-translation-pairing --write docs/subsystems/agent-team.md
+agent-team.md: 1e1c787cc6c4e1489ab3b6fc0599d0519b7a52f4
+agent-team.zh.md: 36f6685d55059c0d24b9ca3a5427c01e73ea9ab0

+ 6 - 6
docs/subsystems/team.md → docs/subsystems/agent-team.md

@@ -1,8 +1,8 @@
 # Agent Teams
 
-English | [中文](team.zh.md)
+English | [中文](agent-team.zh.md)
 
-Types shared by the experimental implicit-root Team domain, model tools, and host adapters. The [Agent Teams Agent Note](../../.agents/notes/implemented/feature/2026-08-05-agent-teams.md) owns identity, mailbox, task, and shared-checkout decisions; this page records the literal durable forms from [`packages/experimental/team/src/types.ts`](../../packages/experimental/team/src/types.ts).
+Types shared by the experimental implicit-root Team domain, model tools, and host adapters. The [Agent Teams Agent Note](../../.agents/notes/implemented/feature/2026-08-05-agent-teams.md) owns identity, mailbox, task, and shared-checkout decisions; this page records the literal durable forms from [`packages/experimental/agent-team/src/types.ts`](../../packages/experimental/agent-team/src/types.ts).
 
 ## Identity and roster
 
@@ -74,7 +74,7 @@ interface TeamTaskSnapshot {
 
 ## Replay
 
-`foldTeam()` replays one root Session into the roster, task board, and queued-minus-delivered mailbox that every Team operation reads. It selects records by `TeamId`, so events inherited by an ordinary fork retain the ancestor id and never enter the new root's state. Session event `seq` and `time` remain the ordering and timing record; Team snapshots do not duplicate them. Roster and task reads reach callers as views that add owner name, readiness, and write-scope warnings, while pending mail stays internal to delivery and recovery. The package [README](../../packages/experimental/team/README.md) owns operation, authorization, recovery, and limit behavior.
+`foldTeam()` replays one root Session into the roster, task board, and queued-minus-delivered mailbox that every Team operation reads. It selects records by `TeamId`, so events inherited by an ordinary fork retain the ancestor id and never enter the new root's state. Session event `seq` and `time` remain the ordering and timing record; Team snapshots do not duplicate them. Roster and task reads reach callers as views that add owner name, readiness, and write-scope warnings, while pending mail stays internal to delivery and recovery. The package [README](../../packages/experimental/agent-team/README.md) owns operation, authorization, recovery, and limit behavior.
 
 <!-- BEGIN GENERATED cordis-surface (gen-cordis-catalog.ts) — do not edit between markers -->
 
@@ -84,9 +84,9 @@ interface TeamTaskSnapshot {
 
 Generated from source by `scripts/gen-cordis-catalog.ts` (verified fresh by `pnpm run verify-cordis-catalog` in doc-sync; regenerate with `pnpm run gen-cordis-catalog`) — this section is byte-identical in both language sides of the page. Signature blocks use a `ts cordis-catalog` fence and keep the original source JSDoc; dispatch modes are defined in the [primer](../cordis-primer.md#dispatch-modes), and the framework-inherited `ctx` API lives in [cordis-api/inherited.md](../cordis-api/inherited.md).
 
-<a id="ctxteams--teamservice"></a>
+<a id="ctxagentteams--teamservice"></a>
 
-### `ctx.teams` — `TeamService`
+### `ctx.agentTeams` — `TeamService`
 
 Agent Teams service backed by the exact live Lead Session log.
 
@@ -179,5 +179,5 @@ tryMembership(agent: Agent): TeamMembership | undefined
 
 Types: [Agent](core.md)
 
-Source: [`packages/experimental/team/src/index.ts:56`](../../packages/experimental/team/src/index.ts)
+Source: [`packages/experimental/agent-team/src/index.ts:56`](../../packages/experimental/agent-team/src/index.ts)
 <!-- END GENERATED cordis-surface -->

+ 6 - 6
docs/subsystems/team.zh.md → docs/subsystems/agent-team.zh.md

@@ -1,8 +1,8 @@
 # Agent Teams
 
-[English](team.md) | 中文
+[English](agent-team.md) | 中文
 
-实验性隐式 Root Team 领域、模型工具与宿主适配器共享的类型。[Agent Teams Agent Note](../../.agents/notes/implemented/feature/2026-08-05-agent-teams.md)负责身份、mailbox、task 与共享 checkout 决策;本页记录 [`packages/experimental/team/src/types.ts`](../../packages/experimental/team/src/types.ts) 中的字面持久形式。
+实验性隐式 Root Team 领域、模型工具与宿主适配器共享的类型。[Agent Teams Agent Note](../../.agents/notes/implemented/feature/2026-08-05-agent-teams.md)负责身份、mailbox、task 与共享 checkout 决策;本页记录 [`packages/experimental/agent-team/src/types.ts`](../../packages/experimental/agent-team/src/types.ts) 中的字面持久形式。
 
 ## 身份与 roster
 
@@ -74,7 +74,7 @@ interface TeamTaskSnapshot {
 
 ## 回放
 
-`foldTeam()` 把一个 Root Session 回放成每个 Team 操作所读取的 roster、任务板与 queued-minus-delivered mailbox。它按 `TeamId` 选取记录,因此普通 fork 继承的 event 保留 ancestor id,绝不会进入新 Root 的状态。Session event 的 `seq` 与 `time` 继续负责顺序和时间记录,Team snapshot 不再重复保存它们。roster 与 task 读取以 view 形式到达调用方,附带 owner name、readiness 与 write-scope 警告,而 pending 邮件仅供投递与恢复内部使用。包 [README](../../packages/experimental/team/README.md)负责 operation、authorization、recovery 和限制行为。
+`foldTeam()` 把一个 Root Session 回放成每个 Team 操作所读取的 roster、任务板与 queued-minus-delivered mailbox。它按 `TeamId` 选取记录,因此普通 fork 继承的 event 保留 ancestor id,绝不会进入新 Root 的状态。Session event 的 `seq` 与 `time` 继续负责顺序和时间记录,Team snapshot 不再重复保存它们。roster 与 task 读取以 view 形式到达调用方,附带 owner name、readiness 与 write-scope 警告,而 pending 邮件仅供投递与恢复内部使用。包 [README](../../packages/experimental/agent-team/README.md)负责 operation、authorization、recovery 和限制行为。
 
 <!-- BEGIN GENERATED cordis-surface (gen-cordis-catalog.ts) — do not edit between markers -->
 
@@ -84,9 +84,9 @@ interface TeamTaskSnapshot {
 
 Generated from source by `scripts/gen-cordis-catalog.ts` (verified fresh by `pnpm run verify-cordis-catalog` in doc-sync; regenerate with `pnpm run gen-cordis-catalog`) — this section is byte-identical in both language sides of the page. Signature blocks use a `ts cordis-catalog` fence and keep the original source JSDoc; dispatch modes are defined in the [primer](../cordis-primer.md#dispatch-modes), and the framework-inherited `ctx` API lives in [cordis-api/inherited.md](../cordis-api/inherited.md).
 
-<a id="ctxteams--teamservice"></a>
+<a id="ctxagentteams--teamservice"></a>
 
-### `ctx.teams` — `TeamService`
+### `ctx.agentTeams` — `TeamService`
 
 Agent Teams service backed by the exact live Lead Session log.
 
@@ -179,5 +179,5 @@ tryMembership(agent: Agent): TeamMembership | undefined
 
 Types: [Agent](core.md)
 
-Source: [`packages/experimental/team/src/index.ts:56`](../../packages/experimental/team/src/index.ts)
+Source: [`packages/experimental/agent-team/src/index.ts:56`](../../packages/experimental/agent-team/src/index.ts)
 <!-- END GENERATED cordis-surface -->

+ 2 - 2
docs/tool-catalog.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 docs/tool-catalog.md
-tool-catalog.md: 13c56ed6d21c5aaac9909ed839ff111a867805df
-tool-catalog.zh.md: e1b9581f25103cf5857af6de09bfbe03b3e52993
+tool-catalog.md: 92b6d8b92050d2dc822f016c18d31a81b43ef447
+tool-catalog.zh.md: 97a202b86744a4cf63819a12586a061a5daaaed4

+ 13 - 13
docs/tool-catalog.md

@@ -37,7 +37,7 @@ This table connects model-visible tool names to the plugin package and service s
 | `@deepseek-ai/dsh-tool-subagent-control` | `interrupt_agent`, `list_agents`, `send_message` | `ctx.tools`, `ctx.subagents`, `ctx.agents and ctx.sessionProjections (list_agents only)` | `tool/call`, `tool/result`, `child session events through ctx.subagents` | - | The globally named control tools over continuable background subagents: provider-bound `tool-subagent` instances register distinct delegation tools, while this package registers `send_message` and `interrupt_agent` once, plus `list_agents` from its separately loaded `/list-agents` plugin (whose catalog rows use the sessionProjections and live Agent registries). |
 | `@deepseek-ai/dsh-tool-subagent-report` | `report` | `ctx.subagents`, `ctx.systemPrompt`, `a live continuable in-process child Agent` | `tool/call`, `tool/result`, `a user-role message in the direct parent session` | - | Registered per continuable in-process child rather than globally, so this schema is visible only inside such a child and survives its global `toolFilter`. The same contribution installs the child-scoped `tool:report` prompt section, which this catalog does not render. The parent-facing `send_message` tool is installed independently. |
 | `@deepseek-ai/dsh-tool-jobs` | `job_kill`, `job_list`, `job_output` | `ctx.tools`, `ctx.jobs`, `ctx.systemPrompt` | `tool/call`, `tool/result`, `user/message via agent.inject() for background completion notices` | - | The kind-agnostic background-job controller: background bash commands, PTY sends, and subagents are read, listed, and killed through the same three tools. Loading the plugin attaches the controller that arms producers' `ctx.jobs.start()`. |
-| `@deepseek-ai/dsh-tool-team` | `followup_task`, `interrupt_agent`, `list_agents`, `send_message`, `spawn_teammate`, `team_task_create`, `team_task_get`, `team_task_list`, `team_task_update`, `wait_agent` | `ctx.tools`, `ctx.systemPrompt`, `ctx.teams`, `an exact live Team member Agent` | `tool/call`, `team/member`, `team/message/queued`, `team/message/delivered`, `team/task`, `tool/result` | - | All ten tools are scoped to implicit Team Leads and durable teammates. The shipped dsh-base bundle keeps the package disabled; the documented Agent Teams profile patch enables it while disabling the legacy continuable-child control names. |
+| `@deepseek-ai/dsh-experimental-tool-agent-team` | `followup_task`, `interrupt_agent`, `list_agents`, `send_message`, `spawn_teammate`, `team_task_create`, `team_task_get`, `team_task_list`, `team_task_update`, `wait_agent` | `ctx.tools`, `ctx.systemPrompt`, `ctx.agentTeams`, `an exact live Team member Agent` | `tool/call`, `team/member`, `team/message/queued`, `team/message/delivered`, `team/task`, `tool/result` | - | All ten tools are scoped to implicit Team Leads and durable teammates. The shipped dsh-base bundle keeps the package disabled; the documented Agent Teams profile patch enables it while disabling the legacy continuable-child control names. |
 | `@deepseek-ai/dsh-tool-todo` | `todo_write` | `ctx.tools`, `owning Agent session` | `tool/call`, `todo/write`, `tool/result` | - | todo_write is session-owned state; UIs render the latest todo/write event as a checklist. `allowParallelInProgress` is required with no default, so the catalog states its choice: `true`, whose description invites several `in_progress` items. A deployment choosing `false` receives the same tool with a description asking for exactly one active task. |
 | `@deepseek-ai/dsh-tool-workflow` | `workflow` | `ctx.tools`, `ctx.workflowEngine`, `ctx.systemPrompt`, `a calling Agent (exec.agent parents the script children)` | `tool/call`, `tool/result` | - | - |
 | `@deepseek-ai/dsh-tool-web` | `web_fetch`, `web_search` | `ctx.tools`, `ctx.web`, `ctx.systemPrompt` | `tool/call`, `tool/result` | - | web_search and web_fetch keep provider selection behind ctx.web so model-visible schemas stay stable across backend swaps. |
@@ -1708,9 +1708,9 @@ Source: [`packages/jobs/tool-jobs/src/index.ts`](../packages/jobs/tool-jobs/src/
 
 The kind-agnostic background-job controller: background bash commands, PTY sends, and subagents are read, listed, and killed through the same three tools. Loading the plugin attaches the controller that arms producers' `ctx.jobs.start()`.
 
-<a id="deepseek-aidsh-tool-team"></a>
+<a id="deepseek-aidsh-experimental-tool-agent-team"></a>
 
-## `@deepseek-ai/dsh-tool-team`
+## `@deepseek-ai/dsh-experimental-tool-agent-team`
 
 ### `followup_task`
 
@@ -1736,7 +1736,7 @@ Send a durable follow-up task to another Team member and start a turn when neede
 }
 ```
 
-Source: [`packages/experimental/tool-team/src/index.ts`](../packages/experimental/tool-team/src/index.ts)
+Source: [`packages/experimental/tool-agent-team/src/index.ts`](../packages/experimental/tool-agent-team/src/index.ts)
 
 ### `interrupt_agent`
 
@@ -1757,7 +1757,7 @@ Interrupt one teammate's current turn while preserving its pending inbox. Team L
 }
 ```
 
-Source: [`packages/experimental/tool-team/src/index.ts`](../packages/experimental/tool-team/src/index.ts)
+Source: [`packages/experimental/tool-agent-team/src/index.ts`](../packages/experimental/tool-agent-team/src/index.ts)
 
 ### `list_agents`
 
@@ -1770,7 +1770,7 @@ List the Lead and every durable teammate with current runtime status.
 }
 ```
 
-Source: [`packages/experimental/tool-team/src/index.ts`](../packages/experimental/tool-team/src/index.ts)
+Source: [`packages/experimental/tool-agent-team/src/index.ts`](../packages/experimental/tool-agent-team/src/index.ts)
 
 ### `send_message`
 
@@ -1796,7 +1796,7 @@ Send durable information to another Team member without starting an idle member.
 }
 ```
 
-Source: [`packages/experimental/tool-team/src/index.ts`](../packages/experimental/tool-team/src/index.ts)
+Source: [`packages/experimental/tool-agent-team/src/index.ts`](../packages/experimental/tool-agent-team/src/index.ts)
 
 ### `spawn_teammate`
 
@@ -1835,7 +1835,7 @@ Create one named, durable teammate. Only the Team Lead may call this tool.
 }
 ```
 
-Source: [`packages/experimental/tool-team/src/index.ts`](../packages/experimental/tool-team/src/index.ts)
+Source: [`packages/experimental/tool-agent-team/src/index.ts`](../packages/experimental/tool-agent-team/src/index.ts)
 
 ### `team_task_create`
 
@@ -1875,7 +1875,7 @@ Create one unowned pending task on the shared Team task board.
 }
 ```
 
-Source: [`packages/experimental/tool-team/src/index.ts`](../packages/experimental/tool-team/src/index.ts)
+Source: [`packages/experimental/tool-agent-team/src/index.ts`](../packages/experimental/tool-agent-team/src/index.ts)
 
 ### `team_task_get`
 
@@ -1896,7 +1896,7 @@ Read the complete latest value of one shared task before changing or executing i
 }
 ```
 
-Source: [`packages/experimental/tool-team/src/index.ts`](../packages/experimental/tool-team/src/index.ts)
+Source: [`packages/experimental/tool-agent-team/src/index.ts`](../packages/experimental/tool-agent-team/src/index.ts)
 
 ### `team_task_list`
 
@@ -1935,7 +1935,7 @@ List shared tasks, including readiness, owner, revision, blockers, and write-sco
 }
 ```
 
-Source: [`packages/experimental/tool-team/src/index.ts`](../packages/experimental/tool-team/src/index.ts)
+Source: [`packages/experimental/tool-agent-team/src/index.ts`](../packages/experimental/tool-agent-team/src/index.ts)
 
 ### `team_task_update`
 
@@ -2002,7 +2002,7 @@ Compare-and-set a shared task action using the latest revision from team_task_ge
 }
 ```
 
-Source: [`packages/experimental/tool-team/src/index.ts`](../packages/experimental/tool-team/src/index.ts)
+Source: [`packages/experimental/tool-agent-team/src/index.ts`](../packages/experimental/tool-agent-team/src/index.ts)
 
 ### `wait_agent`
 
@@ -2020,7 +2020,7 @@ Wait for the next teammate status, mailbox, or shared-task change after this cal
 }
 ```
 
-Source: [`packages/experimental/tool-team/src/index.ts`](../packages/experimental/tool-team/src/index.ts)
+Source: [`packages/experimental/tool-agent-team/src/index.ts`](../packages/experimental/tool-agent-team/src/index.ts)
 
 All ten tools are scoped to implicit Team Leads and durable teammates. The shipped dsh-base bundle keeps the package disabled; the documented Agent Teams profile patch enables it while disabling the legacy continuable-child control names.
 

+ 12 - 12
docs/tool-catalog.zh.md

@@ -39,7 +39,7 @@
 | `@deepseek-ai/dsh-tool-subagent-control` | `interrupt_agent`、`list_agents`、`send_message` | `ctx.tools`、`ctx.subagents`、`ctx.agents and ctx.sessionProjections (list_agents only)` | `tool/call`、`tool/result`、`child session events through ctx.subagents` | - | 这些是控制可继续后台 subagent 的全局命名工具:绑定提供方的 `tool-subagent` 实例注册不同的委派工具;本包注册一次 `send_message` 和 `interrupt_agent`,另由 `list_agents` 通过单独加载的 `/list-agents` 插件提供,其目录行使用 sessionProjections 和实时 Agent 注册表。 |
 | `@deepseek-ai/dsh-tool-subagent-report` | `report` | `ctx.subagents`、`ctx.systemPrompt`、`a live continuable in-process child Agent` | `tool/call`、`tool/result`、`a user-role message in the direct parent session` | - | 按可继续的进程内子级注册,而非全局注册,因此该 schema 仅在这种子级内部可见,并且不受其全局 `toolFilter` 影响。同一份贡献还会安装子级作用域的 `tool:report` 系统提示词 section,本目录不渲染该 section。面向父级的 `send_message` 工具单独安装。 |
 | `@deepseek-ai/dsh-tool-jobs` | `job_kill`、`job_list`、`job_output` | `ctx.tools`、`ctx.jobs`、`ctx.systemPrompt` | `tool/call`、`tool/result`、`user/message via agent.inject() for background completion notices` | - | 与任务种类无关的后台任务控制器:后台 bash 命令、PTY 发送和 subagent 都通过相同的 3 个工具读取、列出和终止。加载该插件会挂接控制器,从而启用生产方的 `ctx.jobs.start()`。 |
-| `@deepseek-ai/dsh-tool-team` | `followup_task`、`interrupt_agent`、`list_agents`、`send_message`、`spawn_teammate`、`team_task_create`、`team_task_get`、`team_task_list`、`team_task_update`、`wait_agent` | `ctx.tools`、`ctx.systemPrompt`、`ctx.teams`、`an exact live Team member Agent` | `tool/call`、`team/member`、`team/message/queued`、`team/message/delivered`、`team/task`、`tool/result` | - | 这 10 个工具限定于隐式 Team Lead 与持久 teammate 作用域。随产品发布的 dsh-base bundle 默认禁用该包;文档中的 Agent Teams profile patch 会启用它,并禁用旧 continuable child 的同名控制工具。 |
+| `@deepseek-ai/dsh-experimental-tool-agent-team` | `followup_task`、`interrupt_agent`、`list_agents`、`send_message`、`spawn_teammate`、`team_task_create`、`team_task_get`、`team_task_list`、`team_task_update`、`wait_agent` | `ctx.tools`、`ctx.systemPrompt`、`ctx.agentTeams`、`an exact live Team member Agent` | `tool/call`、`team/member`、`team/message/queued`、`team/message/delivered`、`team/task`、`tool/result` | - | 这 10 个工具限定于隐式 Team Lead 与持久 teammate 作用域。随产品发布的 dsh-base bundle 默认禁用该包;文档中的 Agent Teams profile patch 会启用它,并禁用旧 continuable child 的同名控制工具。 |
 | `@deepseek-ai/dsh-tool-todo` | `todo_write` | `ctx.tools`、`owning Agent session` | `tool/call`、`todo/write`、`tool/result` | - | todo_write 是会话所有的状态;UI 将最新的 todo/write 事件渲染为检查清单。`allowParallelInProgress` 是没有默认值的必填项,因此本目录明确选择 `true`,对应描述允许同时存在多个 `in_progress` 项。选择 `false` 的部署会获得同一工具,但描述会要求只能有 1 个活动任务。 |
 | `@deepseek-ai/dsh-tool-workflow` | `workflow` | `ctx.tools`、`ctx.workflowEngine`、`ctx.systemPrompt`、`a calling Agent (exec.agent parents the script children)` | `tool/call`、`tool/result` | - | - |
 | `@deepseek-ai/dsh-tool-web` | `web_fetch`、`web_search` | `ctx.tools`、`ctx.web`、`ctx.systemPrompt` | `tool/call`、`tool/result` | - | web_search 和 web_fetch 将提供方选择置于 ctx.web 之后,使模型可见 schema 在更换后端时保持稳定。 |
@@ -1714,7 +1714,7 @@ lsp 工具将提供方选择和语言服务器子进程置于 ctx.lsp 之后,
 
 <a id="deepseek-aidsh-tool-todo"></a>
 
-## `@deepseek-ai/dsh-tool-team`
+## `@deepseek-ai/dsh-experimental-tool-agent-team`
 
 ### `followup_task`
 
@@ -1740,7 +1740,7 @@ lsp 工具将提供方选择和语言服务器子进程置于 ctx.lsp 之后,
 }
 ```
 
-来源:[`packages/experimental/tool-team/src/index.ts`](../packages/experimental/tool-team/src/index.ts)
+来源:[`packages/experimental/tool-agent-team/src/index.ts`](../packages/experimental/tool-agent-team/src/index.ts)
 
 ### `interrupt_agent`
 
@@ -1761,7 +1761,7 @@ lsp 工具将提供方选择和语言服务器子进程置于 ctx.lsp 之后,
 }
 ```
 
-来源:[`packages/experimental/tool-team/src/index.ts`](../packages/experimental/tool-team/src/index.ts)
+来源:[`packages/experimental/tool-agent-team/src/index.ts`](../packages/experimental/tool-agent-team/src/index.ts)
 
 ### `list_agents`
 
@@ -1774,7 +1774,7 @@ lsp 工具将提供方选择和语言服务器子进程置于 ctx.lsp 之后,
 }
 ```
 
-来源:[`packages/experimental/tool-team/src/index.ts`](../packages/experimental/tool-team/src/index.ts)
+来源:[`packages/experimental/tool-agent-team/src/index.ts`](../packages/experimental/tool-agent-team/src/index.ts)
 
 ### `send_message`
 
@@ -1800,7 +1800,7 @@ lsp 工具将提供方选择和语言服务器子进程置于 ctx.lsp 之后,
 }
 ```
 
-来源:[`packages/experimental/tool-team/src/index.ts`](../packages/experimental/tool-team/src/index.ts)
+来源:[`packages/experimental/tool-agent-team/src/index.ts`](../packages/experimental/tool-agent-team/src/index.ts)
 
 ### `spawn_teammate`
 
@@ -1839,7 +1839,7 @@ lsp 工具将提供方选择和语言服务器子进程置于 ctx.lsp 之后,
 }
 ```
 
-来源:[`packages/experimental/tool-team/src/index.ts`](../packages/experimental/tool-team/src/index.ts)
+来源:[`packages/experimental/tool-agent-team/src/index.ts`](../packages/experimental/tool-agent-team/src/index.ts)
 
 ### `team_task_create`
 
@@ -1879,7 +1879,7 @@ lsp 工具将提供方选择和语言服务器子进程置于 ctx.lsp 之后,
 }
 ```
 
-来源:[`packages/experimental/tool-team/src/index.ts`](../packages/experimental/tool-team/src/index.ts)
+来源:[`packages/experimental/tool-agent-team/src/index.ts`](../packages/experimental/tool-agent-team/src/index.ts)
 
 ### `team_task_get`
 
@@ -1900,7 +1900,7 @@ lsp 工具将提供方选择和语言服务器子进程置于 ctx.lsp 之后,
 }
 ```
 
-来源:[`packages/experimental/tool-team/src/index.ts`](../packages/experimental/tool-team/src/index.ts)
+来源:[`packages/experimental/tool-agent-team/src/index.ts`](../packages/experimental/tool-agent-team/src/index.ts)
 
 ### `team_task_list`
 
@@ -1939,7 +1939,7 @@ lsp 工具将提供方选择和语言服务器子进程置于 ctx.lsp 之后,
 }
 ```
 
-来源:[`packages/experimental/tool-team/src/index.ts`](../packages/experimental/tool-team/src/index.ts)
+来源:[`packages/experimental/tool-agent-team/src/index.ts`](../packages/experimental/tool-agent-team/src/index.ts)
 
 ### `team_task_update`
 
@@ -2006,7 +2006,7 @@ lsp 工具将提供方选择和语言服务器子进程置于 ctx.lsp 之后,
 }
 ```
 
-来源:[`packages/experimental/tool-team/src/index.ts`](../packages/experimental/tool-team/src/index.ts)
+来源:[`packages/experimental/tool-agent-team/src/index.ts`](../packages/experimental/tool-agent-team/src/index.ts)
 
 ### `wait_agent`
 
@@ -2024,7 +2024,7 @@ lsp 工具将提供方选择和语言服务器子进程置于 ctx.lsp 之后,
 }
 ```
 
-来源:[`packages/experimental/tool-team/src/index.ts`](../packages/experimental/tool-team/src/index.ts)
+来源:[`packages/experimental/tool-agent-team/src/index.ts`](../packages/experimental/tool-agent-team/src/index.ts)
 
 这 10 个工具限定于隐式 Team Lead 与持久 teammate 作用域。随产品发布的 dsh-base bundle 默认禁用该包;文档中的 Agent Teams profile patch 会启用它,并禁用旧 continuable child 的同名控制工具。
 

+ 4 - 4
examples/headless-agent/team.cordis.snapshot.yml

@@ -28,9 +28,9 @@
           backgroundMode: one-shot
           maxDepth: 1
       - insert:
-          - id: team
-            name: '@deepseek-ai/dsh-team'
-          - id: tool-team
-            name: '@deepseek-ai/dsh-tool-team'
+          - id: agent-team
+            name: '@deepseek-ai/dsh-experimental-agent-team'
+          - id: tool-agent-team
+            name: '@deepseek-ai/dsh-experimental-tool-agent-team'
           - id: team-fixture-llm
             name: './tests/fixtures/team-llm.mjs'

+ 2 - 2
examples/package.json

@@ -82,7 +82,7 @@
     "@deepseek-ai/dsh-subprocess-local": "workspace:*",
     "@deepseek-ai/dsh-system-prompt": "workspace:*",
     "@deepseek-ai/dsh-jobs-local": "workspace:*",
-    "@deepseek-ai/dsh-team": "workspace:*",
+    "@deepseek-ai/dsh-experimental-agent-team": "workspace:*",
     "@deepseek-ai/dsh-time-context": "workspace:*",
     "@deepseek-ai/dsh-tool-call-timeout-policy": "workspace:*",
     "@deepseek-ai/dsh-token-meter": "workspace:*",
@@ -105,7 +105,7 @@
     "@deepseek-ai/dsh-tool-subagent-control": "workspace:*",
     "@deepseek-ai/dsh-tool-subagent-report": "workspace:*",
     "@deepseek-ai/dsh-tool-jobs": "workspace:*",
-    "@deepseek-ai/dsh-tool-team": "workspace:*",
+    "@deepseek-ai/dsh-experimental-tool-agent-team": "workspace:*",
     "@deepseek-ai/dsh-tool-todo": "workspace:*",
     "@deepseek-ai/dsh-tool-web": "workspace:*",
     "@deepseek-ai/dsh-tool-workflow": "workspace:*",

+ 2 - 2
packages/experimental/AGENTS.md

@@ -3,7 +3,7 @@
 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.
 
 - 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 sets `private: true` and omits `publishConfig`; the dsh release family excludes this directory.
+- Every package here uses the `@deepseek-ai/dsh-experimental-*` npm prefix, sets `private: true`, and omits `publishConfig`; the workspace constraints gate enforces these declarations and the dsh release family excludes this directory.
 - Release packages and apps must not name packages here 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.
-- Promotion moves a package to its product-role group without renaming its `@deepseek-ai/dsh-*` package. Review its public contract, limitations, test evidence, release payload, runtime dependents, and named stable owner before promotion.
+- 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: 1c3fd8c76f3331a6606455563b2ea56ff4832dc9
-README.zh.md: d7d40b21ad21764b9f64a71afec8a08446fbdc2e
+README.md: 0e92ebd2bd959ac807830400dd57807b87b1cbe2
+README.zh.md: a1751c39f53bf8f6c0a9c623aba57355f35c2681

+ 2 - 2
packages/experimental/README.md

@@ -6,7 +6,7 @@ This group contains prototypes and internal-only Cordis plugins that use the rep
 
 | Package | Role | ctx key |
 |---|---|---|
-| `team/` | Implicit-root Agent Teams roster, durable peer mailbox, shared task DAG, and runtime coordination | `ctx.teams` |
-| `tool-team/` | Scoped model-facing Agent Teams tools and collaboration guidance | — |
+| `agent-team/` | Implicit-root Agent Teams roster, durable peer mailbox, shared task DAG, and runtime coordination | `ctx.agentTeams` |
+| `tool-agent-team/` | Scoped model-facing Agent Teams tools and collaboration guidance | — |
 
 The [subtree rules](AGENTS.md) define dependency isolation, release exclusion, and promotion.

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

@@ -6,7 +6,7 @@
 
 | 包 | 职责 | ctx key |
 |---|---|---|
-| `team/` | 隐式 root Agent Teams roster、持久 peer mailbox、共享任务 DAG 与运行时协调 | `ctx.teams` |
-| `tool-team/` | 按 Agent 作用域提供的 Agent Teams 模型工具与协作指引 | — |
+| `agent-team/` | 隐式 root Agent Teams roster、持久 peer mailbox、共享任务 DAG 与运行时协调 | `ctx.agentTeams` |
+| `tool-agent-team/` | 按 Agent 作用域提供的 Agent Teams 模型工具与协作指引 | — |
 
 [子树规则](AGENTS.md)规定依赖隔离、发布排除与 promotion。

+ 3 - 3
packages/experimental/tool-team/README.i18n.yaml → packages/experimental/agent-team/README.i18n.yaml

@@ -1,6 +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 packages/experimental/tool-team/README.md
-README.md: 1c0b2b4393be25f00af2f6b179ab4f925f9a1763
-README.zh.md: 8ddfebd17eb8f1a7a5cebeebab5ad4a47e091a41
+#   pnpm run verify-translation-pairing --write packages/experimental/agent-team/README.md
+README.md: 185f64446c3e8db9218695a4911a0f082ff32cc5
+README.zh.md: 64bfb3ef662399a34107ff290c30e00d81c2bae2

+ 5 - 5
packages/experimental/team/README.md → packages/experimental/agent-team/README.md

@@ -1,14 +1,14 @@
-# @deepseek-ai/dsh-team
+# @deepseek-ai/dsh-experimental-agent-team
 
 English | [中文](README.zh.md)
 
-Implicit-root Agent Teams domain. `ctx.teams` owns a flat Lead/teammate roster, a durable peer mailbox, and a shared task DAG in the Lead Session log. The [Agent Teams Agent Note](../../../.agents/notes/implemented/feature/2026-08-05-agent-teams.md) owns the coordination and isolation decisions; the [Team subsystem catalog](../../../docs/subsystems/team.md) records the literal durable shapes and service API.
+Implicit-root Agent Teams domain. `ctx.agentTeams` owns a flat Lead/teammate roster, a durable peer mailbox, and a shared task DAG in the Lead Session log. The [Agent Teams Agent Note](../../../.agents/notes/implemented/feature/2026-08-05-agent-teams.md) owns the coordination and isolation decisions; the [Team subsystem catalog](../../../docs/subsystems/agent-team.md) records the literal durable shapes and service API.
 
 ## Config
 
 ```yaml
-- id: team
-  name: '@deepseek-ai/dsh-team'
+- id: agent-team
+  name: '@deepseek-ai/dsh-experimental-agent-team'
   config:
     maxMembers: 8
     maxTasks: 256
@@ -61,7 +61,7 @@ Each delivered peer message is a user-role message. A short first text block nam
 
 #### Token effect
 
-Each peer delivery adds the sender prefix plus message content to the target history. Task and roster mutations add no model tokens; their model-facing representation belongs to `@deepseek-ai/dsh-tool-team` results.
+Each peer delivery adds the sender prefix plus message content to the target history. Task and roster mutations add no model tokens; their model-facing representation belongs to `@deepseek-ai/dsh-experimental-tool-agent-team` results.
 
 #### KV Cache effect
 

+ 5 - 5
packages/experimental/team/README.zh.md → packages/experimental/agent-team/README.zh.md

@@ -1,14 +1,14 @@
-# @deepseek-ai/dsh-team
+# @deepseek-ai/dsh-experimental-agent-team
 
 [English](README.md) | 中文
 
-隐式 Root Agent Teams 领域。`ctx.teams` 在 Lead Session 日志中维护扁平的 Lead/teammate roster、持久 peer mailbox 与共享任务 DAG。[Agent Teams Agent Note](../../../.agents/notes/implemented/feature/2026-08-05-agent-teams.md)负责协作和隔离决策;[Team 子系统目录](../../../docs/subsystems/team.md)记录持久数据的字面形态与服务 API。
+隐式 Root Agent Teams 领域。`ctx.agentTeams` 在 Lead Session 日志中维护扁平的 Lead/teammate roster、持久 peer mailbox 与共享任务 DAG。[Agent Teams Agent Note](../../../.agents/notes/implemented/feature/2026-08-05-agent-teams.md)负责协作和隔离决策;[Team 子系统目录](../../../docs/subsystems/agent-team.md)记录持久数据的字面形态与服务 API。
 
 ## 配置
 
 ```yaml
-- id: team
-  name: '@deepseek-ai/dsh-team'
+- id: agent-team
+  name: '@deepseek-ai/dsh-experimental-agent-team'
   config:
     maxMembers: 8
     maxTasks: 256
@@ -61,7 +61,7 @@ roster 同时报告持久 provisioning/failed phase 与实时 `running`/`idl
 
 #### Token 影响
 
-每次 peer 投递都会把发送者前缀与消息内容加入 target 历史。任务和 roster 变更不增加模型 token;其面向模型的呈现属于 `@deepseek-ai/dsh-tool-team` 结果。
+每次 peer 投递都会把发送者前缀与消息内容加入 target 历史。任务和 roster 变更不增加模型 token;其面向模型的呈现属于 `@deepseek-ai/dsh-experimental-tool-agent-team` 结果。
 
 #### KV Cache 影响
 

+ 2 - 2
packages/experimental/team/package.json → packages/experimental/agent-team/package.json

@@ -1,12 +1,12 @@
 {
-  "name": "@deepseek-ai/dsh-team",
+  "name": "@deepseek-ai/dsh-experimental-agent-team",
   "description": "Implicit-root Agent Teams roster, durable peer mailbox, and shared task DAG",
   "version": "0.1.0-rc.7",
   "private": true,
   "repository": {
     "type": "git",
     "url": "git+https://github.com/deepseek-ai/deepseek-harness.git",
-    "directory": "packages/experimental/team"
+    "directory": "packages/experimental/agent-team"
   },
   "type": "module",
   "main": "lib/index.js",

+ 0 - 0
packages/experimental/team/src/activity.ts → packages/experimental/agent-team/src/activity.ts


+ 0 - 0
packages/experimental/team/src/error.ts → packages/experimental/agent-team/src/error.ts


+ 0 - 0
packages/experimental/team/src/fold.ts → packages/experimental/agent-team/src/fold.ts


+ 3 - 3
packages/experimental/team/src/index.ts → packages/experimental/agent-team/src/index.ts

@@ -34,7 +34,7 @@ export { foldTeam } from './fold.ts'
 
 declare module '@deepseek-ai/cordis' {
   interface Context {
-    teams: TeamService
+    agentTeams: TeamService
   }
 }
 
@@ -75,7 +75,7 @@ export class TeamService extends Service {
   private readonly tasks: TeamTaskBoard
 
   constructor(ctx: Context, config: Config = {}) {
-    super(ctx, 'teams')
+    super(ctx, 'agentTeams')
     this.config = {
       maxMembers: positiveLimit('maxMembers', config.maxMembers ?? DEFAULT_MAX_MEMBERS),
       maxTasks: positiveLimit('maxTasks', config.maxTasks ?? DEFAULT_MAX_TASKS),
@@ -110,7 +110,7 @@ export class TeamService extends Service {
       const membership = this.roster.tryMembership(agent)
       if (membership !== undefined) this.activity.notify(membership.id)
     })
-    ctx.effect(() => () => this.disposeRuntime(), 'teams.runtimeLifecycle()')
+    ctx.effect(() => () => this.disposeRuntime(), 'agentTeams.runtimeLifecycle()')
     for (const agent of ctx.agents.list()) this.scheduleRecovery(agent)
   }
 

+ 1 - 1
packages/experimental/team/src/invariant.ts → packages/experimental/agent-team/src/invariant.ts

@@ -5,7 +5,7 @@ import type { InvariantFailure, InvariantInstaller } from '@deepseek-ai/dsh-inva
 import type { Session, SessionEvent } from '@deepseek-ai/dsh-session'
 import { applyTeamEvent, foldTeam, isTeamEvent } from './fold.ts'
 
-const PACKAGE_NAME = '@deepseek-ai/dsh-team'
+const PACKAGE_NAME = '@deepseek-ai/dsh-experimental-agent-team'
 
 /** Cordis companion plugin name. */
 export const name = 'team-invariant'

+ 0 - 0
packages/experimental/team/src/journal.ts → packages/experimental/agent-team/src/journal.ts


+ 0 - 0
packages/experimental/team/src/lifecycle.ts → packages/experimental/agent-team/src/lifecycle.ts


+ 0 - 0
packages/experimental/team/src/mailbox.ts → packages/experimental/agent-team/src/mailbox.ts


+ 0 - 0
packages/experimental/team/src/roster.ts → packages/experimental/agent-team/src/roster.ts


+ 0 - 0
packages/experimental/team/src/session-message.ts → packages/experimental/agent-team/src/session-message.ts


+ 0 - 0
packages/experimental/team/src/task-board.ts → packages/experimental/agent-team/src/task-board.ts


+ 0 - 0
packages/experimental/team/src/task-graph.ts → packages/experimental/agent-team/src/task-graph.ts


+ 0 - 0
packages/experimental/team/src/types.ts → packages/experimental/agent-team/src/types.ts


+ 0 - 0
packages/experimental/team/src/validation.ts → packages/experimental/agent-team/src/validation.ts


+ 0 - 0
packages/experimental/team/tests/fold.spec.ts → packages/experimental/agent-team/tests/fold.spec.ts


+ 2 - 2
packages/experimental/team/tests/invariant.spec.ts → packages/experimental/agent-team/tests/invariant.spec.ts

@@ -38,7 +38,7 @@ describe('Agent Teams stream invariant', () => {
       })
     }).toThrow(expect.objectContaining<Partial<InvariantError>>({
       code: 'INVARIANT',
-      packageName: '@deepseek-ai/dsh-team',
+      packageName: '@deepseek-ai/dsh-experimental-agent-team',
     }))
     expect(invalid.events).toEqual([])
   })
@@ -63,7 +63,7 @@ describe('Agent Teams stream invariant', () => {
       })
     }).toThrow(expect.objectContaining<Partial<InvariantError>>({
       code: 'INVARIANT',
-      packageName: '@deepseek-ai/dsh-team',
+      packageName: '@deepseek-ai/dsh-experimental-agent-team',
     }))
     expect(session.events).toEqual([])
   })

+ 5 - 5
packages/experimental/team/tests/persistence.spec.ts → packages/experimental/agent-team/tests/persistence.spec.ts

@@ -206,7 +206,7 @@ for (const backend of backends) {
         expect(failedMember?.error).toContain('child Session recovery failed')
       }, { timeout: 5_000 })
 
-      const receipt = await second.ctx.teams.sendMessage(activeHandle.agent, {
+      const receipt = await second.ctx.agentTeams.sendMessage(activeHandle.agent, {
         target: 'recoverable',
         content: [{ type: 'text', text: 'resume after reconciliation' }],
         delivery: 'wakeup',
@@ -274,7 +274,7 @@ for (const backend of backends) {
 
       const first = await stack(backend, storageRoot, [textResponse('initial teammate answer')])
       const firstLead = first.ctx.agentLoop.create(rootId, { provider: 'mock', model: 'mock' })
-      const started = await first.ctx.teams.spawnTeammate(firstLead, {
+      const started = await first.ctx.agentTeams.spawnTeammate(firstLead, {
         name: 'mail-worker',
         description: 'mail recovery worker',
         prompt: [{ type: 'text', text: 'finish before restart' }],
@@ -283,7 +283,7 @@ for (const backend of backends) {
         signal: SIGNAL,
       })
       await vi.waitFor(() => { expect(first.ctx.agents.get(started.member.id)).toBeUndefined() }, { timeout: 5_000 })
-      const quiet = await first.ctx.teams.sendMessage(firstLead, {
+      const quiet = await first.ctx.agentTeams.sendMessage(firstLead, {
         target: 'mail-worker',
         content: [{ type: 'text', text: 'durable quiet context' }],
         delivery: 'quiet',
@@ -304,7 +304,7 @@ for (const backend of backends) {
       })
       expect(second.ctx.agents.get(started.member.id)).toBeUndefined()
 
-      const waking = await second.ctx.teams.sendMessage(rootHandle.agent, {
+      const waking = await second.ctx.agentTeams.sendMessage(rootHandle.agent, {
         target: 'mail-worker',
         content: [{ type: 'text', text: 'resume after restart' }],
         delivery: 'wakeup',
@@ -335,7 +335,7 @@ for (const backend of backends) {
 
       const first = await stack(backend, storageRoot, [textResponse('initial teammate answer')])
       const firstLead = first.ctx.agentLoop.create(rootId, { provider: 'mock', model: 'mock' })
-      const started = await first.ctx.teams.spawnTeammate(firstLead, {
+      const started = await first.ctx.agentTeams.spawnTeammate(firstLead, {
         name: 'dedup-worker',
         description: 'mail deduplication worker',
         prompt: [{ type: 'text', text: 'finish before the crash window' }],

+ 128 - 128
packages/experimental/team/tests/team.spec.ts → packages/experimental/agent-team/tests/team.spec.ts

@@ -85,7 +85,7 @@ interface TeamServiceInternals {
 
 /** White-box access follows the runtime owners so coverage does not widen the service API. */
 function teamInternals(ctx: Context): TeamServiceInternals {
-  return ctx.teams as unknown as TeamServiceInternals
+  return ctx.agentTeams as unknown as TeamServiceInternals
 }
 
 function spawn(
@@ -95,7 +95,7 @@ function spawn(
   options: { context?: 'fresh' | 'fork'; provider?: string } = {},
 ) {
   const context = options.context ?? 'fresh'
-  return ctx.teams.spawnTeammate(lead, {
+  return ctx.agentTeams.spawnTeammate(lead, {
     name,
     description: `${name} responsibility`,
     prompt: content(`${name} initial`),
@@ -187,7 +187,7 @@ describe('Team identity and provisioning', () => {
 
     expect((await ctx.sessionPersistence.inspect(forked.member.id)).meta.seedLength).toBeGreaterThan(0)
     expect((await ctx.sessionPersistence.inspect(fresh.member.id)).meta.seedLength ?? 0).toBe(0)
-    expect(ctx.teams.listMembers(lead).map(row => [row.name, row.context, row.status])).toEqual([
+    expect(ctx.agentTeams.listMembers(lead).map(row => [row.name, row.context, row.status])).toEqual([
       ['lead', undefined, 'idle'],
       ['fork-worker', 'fork', 'inactive'],
       ['fresh-worker', 'fresh', 'inactive'],
@@ -288,7 +288,7 @@ describe('Team identity and provisioning', () => {
     const { ctx, lead } = await setup([], { maxMembers: 1 })
     await expect(spawn(ctx, lead, 'failed-worker', { provider: 'missing' })).rejects.toThrow()
 
-    expect(ctx.teams.listMembers(lead)[1]).toMatchObject({
+    expect(ctx.agentTeams.listMembers(lead)[1]).toMatchObject({
       name: 'failed-worker',
       status: 'failed',
       provider: 'missing',
@@ -301,11 +301,11 @@ describe('Team identity and provisioning', () => {
     const first = await setup([])
     vi.spyOn(first.ctx.subagents, 'startContinuable').mockRejectedValueOnce('string provider failure')
     await expect(spawn(first.ctx, first.lead, 'string-failure')).rejects.toBe('string provider failure')
-    expect(first.ctx.teams.listMembers(first.lead)[1]).toMatchObject({
+    expect(first.ctx.agentTeams.listMembers(first.lead)[1]).toMatchObject({
       status: 'failed',
       diagnostics: ['string provider failure'],
     })
-    await expect(first.ctx.teams.sendMessage(first.lead, {
+    await expect(first.ctx.agentTeams.sendMessage(first.lead, {
       target: 'string-failure', content: content('cannot deliver'), delivery: 'quiet', signal: SIGNAL,
     })).rejects.toMatchObject({ code: 'TEAM_MEMBER_NOT_FOUND' })
 
@@ -389,16 +389,16 @@ describe('Team identity and provisioning', () => {
     const started = await spawn(ctx, lead, 'worker')
     const worker = await waitRunning(ctx, started.member.id)
     await expect(spawn(ctx, worker, 'nested')).rejects.toMatchObject({ code: 'TEAM_LEAD_REQUIRED' })
-    expect(() => ctx.teams.interrupt(worker, 'worker')).toThrow(expect.objectContaining({ code: 'TEAM_LEAD_REQUIRED' }))
-    expect(ctx.teams.interrupt(lead, 'worker')).toEqual({ previousStatus: 'running' })
+    expect(() => ctx.agentTeams.interrupt(worker, 'worker')).toThrow(expect.objectContaining({ code: 'TEAM_LEAD_REQUIRED' }))
+    expect(ctx.agentTeams.interrupt(lead, 'worker')).toEqual({ previousStatus: 'running' })
     await waitNoAgent(ctx, worker.id)
-    expect(ctx.teams.interrupt(lead, 'worker')).toEqual({ previousStatus: 'inactive' })
-    expect(() => ctx.teams.interrupt(lead, 'lead')).toThrow(expect.objectContaining({ code: 'TEAM_INVALID_TARGET' }))
+    expect(ctx.agentTeams.interrupt(lead, 'worker')).toEqual({ previousStatus: 'inactive' })
+    expect(() => ctx.agentTeams.interrupt(lead, 'lead')).toThrow(expect.objectContaining({ code: 'TEAM_INVALID_TARGET' }))
   })
 
   it('validates teammate text fields and pre-provisioning cancellation', async () => {
     const { ctx, lead } = await setup([])
-    await expect(ctx.teams.spawnTeammate(lead, {
+    await expect(ctx.agentTeams.spawnTeammate(lead, {
       name: 'empty-description',
       description: ' ',
       prompt: content('unused'),
@@ -406,7 +406,7 @@ describe('Team identity and provisioning', () => {
       provider: 'spawn',
       signal: SIGNAL,
     })).rejects.toMatchObject({ code: 'TEAM_INVALID_ARGUMENT' })
-    await expect(ctx.teams.spawnTeammate(lead, {
+    await expect(ctx.agentTeams.spawnTeammate(lead, {
       name: 'empty-provider',
       description: 'valid description',
       prompt: content('unused'),
@@ -416,7 +416,7 @@ describe('Team identity and provisioning', () => {
     })).rejects.toMatchObject({ code: 'TEAM_INVALID_ARGUMENT' })
     const controller = new AbortController()
     controller.abort(new TeamError('cancelled before provisioning', 'TEST_CANCELLED'))
-    await expect(ctx.teams.spawnTeammate(lead, {
+    await expect(ctx.agentTeams.spawnTeammate(lead, {
       name: 'cancelled-worker',
       description: 'never provisioned',
       prompt: content('unused'),
@@ -429,7 +429,7 @@ describe('Team identity and provisioning', () => {
 
   it('treats an ordinary fork as a new Root Team and filters inherited Team state', async () => {
     const { ctx, lead } = await setup([])
-    await ctx.teams.createTask(lead, { subject: 'parent task', description: 'belongs to parent' })
+    await ctx.agentTeams.createTask(lead, { subject: 'parent task', description: 'belongs to parent' })
     const handle = await ctx.agents.create({
       sessionId: SessionId('ordinary-fork'),
       seed: lead.session.events,
@@ -437,7 +437,7 @@ describe('Team identity and provisioning', () => {
       agentOptions: { provider: 'mock', model: 'mock' },
     })
 
-    expect(ctx.teams.membership(handle.agent)).toMatchObject({
+    expect(ctx.agentTeams.membership(handle.agent)).toMatchObject({
       id: TeamId(handle.agent.id),
       role: 'lead',
       name: 'lead',
@@ -455,20 +455,20 @@ describe('Team identity and provisioning', () => {
       signal: SIGNAL,
     })
     const live = ctx.agents.get(started.childId)
-    if (live !== undefined) expect(ctx.teams.tryMembership(live)).toBeUndefined()
+    if (live !== undefined) expect(ctx.agentTeams.tryMembership(live)).toBeUndefined()
     await waitNoAgent(ctx, started.childId)
-    expect(() => ctx.teams.membership(lead)).not.toThrow()
+    expect(() => ctx.agentTeams.membership(lead)).not.toThrow()
 
     const impostor = { ...lead } as Agent
-    expect(ctx.teams.tryMembership(impostor)).toBeUndefined()
-    expect(() => ctx.teams.membership(impostor)).toThrow(expect.objectContaining({ code: 'TEAM_NOT_MEMBER' }))
+    expect(ctx.agentTeams.tryMembership(impostor)).toBeUndefined()
+    expect(() => ctx.agentTeams.membership(impostor)).toThrow(expect.objectContaining({ code: 'TEAM_NOT_MEMBER' }))
 
     const orphanRoot = await ctx.agents.create({
       sessionId: SessionId('orphan-ordinary-root'),
       meta: { parentSession: SessionId('absent-parent') },
       agentOptions: { provider: 'mock', model: 'mock' },
     })
-    expect(ctx.teams.membership(orphanRoot.agent)).toMatchObject({ role: 'lead', name: 'lead' })
+    expect(ctx.agentTeams.membership(orphanRoot.agent)).toMatchObject({ role: 'lead', name: 'lead' })
     await orphanRoot.dispose()
   })
 
@@ -490,7 +490,7 @@ describe('Team identity and provisioning', () => {
       resumeSessionId: started.childId,
       agentOptions: { provider: 'mock', model: 'mock' },
     })
-    expect(first.ctx.teams.tryMembership(orphan.agent)).toBeUndefined()
+    expect(first.ctx.agentTeams.tryMembership(orphan.agent)).toBeUndefined()
     expect(teamInternals(first.ctx).roster.liveChildrenByRoot()).toEqual(new Map())
     await orphan.dispose()
 
@@ -503,7 +503,7 @@ describe('Team identity and provisioning', () => {
     const journal = teamInternals(second.ctx).journal
     const state = journal.state.bind(journal)
     journal.state = () => { throw new Error('malformed Team stream') }
-    expect(second.ctx.teams.tryMembership(child.agent)).toBeUndefined()
+    expect(second.ctx.agentTeams.tryMembership(child.agent)).toBeUndefined()
     journal.state = state
     await child.dispose()
   })
@@ -528,7 +528,7 @@ describe('Team shared task DAG', () => {
     })
     await ctx.sessions.flush(lead.session)
 
-    await expect(ctx.teams.createTask(lead, {
+    await expect(ctx.agentTeams.createTask(lead, {
       subject: 'cannot allocate',
       description: 'no safe numeric task id remains',
     })).rejects.toMatchObject({ code: 'TEAM_TASK_LIMIT' })
@@ -536,20 +536,20 @@ describe('Team shared task DAG', () => {
 
   it('bounds non-deleted tasks while retaining deleted task ids as tombstones', async () => {
     const { ctx, lead } = await setup([], { maxTasks: 1 })
-    const first = await ctx.teams.createTask(lead, { subject: 'first', description: 'first task' })
-    await expect(ctx.teams.createTask(lead, { subject: 'overflow', description: 'overflow task' }))
+    const first = await ctx.agentTeams.createTask(lead, { subject: 'first', description: 'first task' })
+    await expect(ctx.agentTeams.createTask(lead, { subject: 'overflow', description: 'overflow task' }))
       .rejects.toMatchObject({ code: 'TEAM_TASK_LIMIT' })
 
-    const deleted = await ctx.teams.updateTask(lead, {
+    const deleted = await ctx.agentTeams.updateTask(lead, {
       taskId: first.id,
       expectedRevision: first.revision,
       action: 'delete',
     })
-    const second = await ctx.teams.createTask(lead, { subject: 'second', description: 'second task' })
+    const second = await ctx.agentTeams.createTask(lead, { subject: 'second', description: 'second task' })
     expect(deleted.status).toBe('deleted')
     expect(second.id).toBe(TeamTaskId('task-2'))
-    expect(ctx.teams.getTask(lead, first.id).status).toBe('deleted')
-    expect(ctx.teams.listTasks(lead).map(task => task.id)).toEqual([second.id])
+    expect(ctx.agentTeams.getTask(lead, first.id).status).toBe('deleted')
+    expect(ctx.agentTeams.listTasks(lead).map(task => task.id)).toEqual([second.id])
   })
 
   it('enforces CAS, ownership, dependencies, transitions, and write-scope warnings', async () => {
@@ -559,63 +559,63 @@ describe('Team shared task DAG', () => {
     const secondMember = await spawn(ctx, lead, 'beta')
     const beta = await waitRunning(ctx, secondMember.member.id)
 
-    const first = await ctx.teams.createTask(alpha, {
+    const first = await ctx.agentTeams.createTask(alpha, {
       subject: 'first',
       description: 'first task',
       writeScopes: ['src', './src/', 'src'],
     })
-    const second = await ctx.teams.createTask(beta, {
+    const second = await ctx.agentTeams.createTask(beta, {
       subject: 'second',
       description: 'second task',
       blockedBy: [first.id],
       writeScopes: ['src/feature'],
     })
     expect(first.writeScopes).toEqual(['src'])
-    await expect(ctx.teams.updateTask(beta, {
+    await expect(ctx.agentTeams.updateTask(beta, {
       taskId: second.id,
       expectedRevision: second.revision,
       action: 'claim',
     })).rejects.toMatchObject({ code: 'TEAM_TASK_BLOCKED' })
 
-    const claimed = await ctx.teams.updateTask(alpha, {
+    const claimed = await ctx.agentTeams.updateTask(alpha, {
       taskId: first.id,
       expectedRevision: first.revision,
       action: 'claim',
     })
-    await expect(ctx.teams.updateTask(beta, {
+    await expect(ctx.agentTeams.updateTask(beta, {
       taskId: first.id,
       expectedRevision: claimed.revision,
       action: 'claim',
     })).rejects.toMatchObject({ code: 'TEAM_TASK_ALREADY_CLAIMED' })
-    expect(ctx.teams.getTask(beta, second.id)).toMatchObject({
+    expect(ctx.agentTeams.getTask(beta, second.id)).toMatchObject({
       ready: false,
       writeScopeWarnings: [`write scopes overlap with ${first.id}`],
     })
-    await expect(ctx.teams.updateTask(beta, {
+    await expect(ctx.agentTeams.updateTask(beta, {
       taskId: first.id,
       expectedRevision: claimed.revision,
       action: 'edit',
       subject: 'stolen',
     })).rejects.toMatchObject({ code: 'TEAM_TASK_UNAUTHORIZED' })
-    await expect(ctx.teams.updateTask(alpha, {
+    await expect(ctx.agentTeams.updateTask(alpha, {
       taskId: first.id,
       expectedRevision: first.revision,
       action: 'complete',
     })).rejects.toMatchObject({ code: 'TEAM_TASK_STALE_REVISION' })
 
-    const completed = await ctx.teams.updateTask(alpha, {
+    const completed = await ctx.agentTeams.updateTask(alpha, {
       taskId: first.id,
       expectedRevision: claimed.revision,
       action: 'complete',
     })
     expect(completed.status).toBe('completed')
-    expect(ctx.teams.getTask(beta, second.id).ready).toBe(true)
-    const secondClaim = await ctx.teams.updateTask(beta, {
+    expect(ctx.agentTeams.getTask(beta, second.id).ready).toBe(true)
+    const secondClaim = await ctx.agentTeams.updateTask(beta, {
       taskId: second.id,
       expectedRevision: second.revision,
       action: 'claim',
     })
-    const released = await ctx.teams.updateTask(beta, {
+    const released = await ctx.agentTeams.updateTask(beta, {
       taskId: second.id,
       expectedRevision: secondClaim.revision,
       action: 'release',
@@ -623,40 +623,40 @@ describe('Team shared task DAG', () => {
     expect(released).toMatchObject({ status: 'pending', ready: true })
     expect('ownerId' in released).toBe(false)
 
-    ctx.teams.interrupt(lead, 'alpha')
-    ctx.teams.interrupt(lead, 'beta')
+    ctx.agentTeams.interrupt(lead, 'alpha')
+    ctx.agentTeams.interrupt(lead, 'beta')
     await Promise.all([waitNoAgent(ctx, alpha.id), waitNoAgent(ctx, beta.id)])
   })
 
   it('rejects malformed scopes and every invalid dependency relation', async () => {
     const { ctx, lead } = await setup([])
-    const first = await ctx.teams.createTask(lead, { subject: 'one', description: 'one' })
-    const second = await ctx.teams.createTask(lead, {
+    const first = await ctx.agentTeams.createTask(lead, { subject: 'one', description: 'one' })
+    const second = await ctx.agentTeams.createTask(lead, {
       subject: 'two', description: 'two', blockedBy: [first.id],
     })
-    await expect(ctx.teams.createTask(lead, {
+    await expect(ctx.agentTeams.createTask(lead, {
       subject: 'bad', description: 'bad', blockedBy: [TeamTaskId('missing')],
     })).rejects.toMatchObject({ code: 'TEAM_TASK_NOT_FOUND' })
-    await expect(ctx.teams.updateTask(lead, {
+    await expect(ctx.agentTeams.updateTask(lead, {
       taskId: first.id,
       expectedRevision: first.revision,
       action: 'set_dependencies',
       blockedBy: [second.id],
     })).rejects.toMatchObject({ code: 'TEAM_TASK_DEPENDENCY_CYCLE' })
-    await expect(ctx.teams.updateTask(lead, {
+    await expect(ctx.agentTeams.updateTask(lead, {
       taskId: first.id,
       expectedRevision: first.revision,
       action: 'set_dependencies',
       blockedBy: [first.id],
     })).rejects.toMatchObject({ code: 'TEAM_TASK_DEPENDENCY_CYCLE' })
-    await expect(ctx.teams.updateTask(lead, {
+    await expect(ctx.agentTeams.updateTask(lead, {
       taskId: first.id,
       expectedRevision: first.revision,
       action: 'set_dependencies',
       blockedBy: [second.id, second.id],
     })).rejects.toMatchObject({ code: 'TEAM_INVALID_ARGUMENT' })
     for (const scope of ['', '.', '..', '/root', 'C:\\root', 'C:root', 'a//b', 'a/../b']) {
-      await expect(ctx.teams.createTask(lead, {
+      await expect(ctx.agentTeams.createTask(lead, {
         subject: 'scope', description: 'scope', writeScopes: [scope],
       })).rejects.toMatchObject({ code: 'TEAM_INVALID_WRITE_SCOPE' })
     }
@@ -664,36 +664,36 @@ describe('Team shared task DAG', () => {
 
   it('rejects incomplete mutations, invalid transitions, and deletion of a live blocker', async () => {
     const { ctx, lead } = await setup([])
-    await expect(ctx.teams.createTask(lead, { subject: ' ', description: 'invalid' }))
+    await expect(ctx.agentTeams.createTask(lead, { subject: ' ', description: 'invalid' }))
       .rejects.toMatchObject({ code: 'TEAM_INVALID_ARGUMENT' })
-    await expect(ctx.teams.createTask(lead, { subject: 'invalid', description: '' }))
+    await expect(ctx.agentTeams.createTask(lead, { subject: 'invalid', description: '' }))
       .rejects.toMatchObject({ code: 'TEAM_INVALID_ARGUMENT' })
-    await expect(ctx.teams.createTask(lead, { subject: 'x'.repeat(201), description: 'too long' }))
+    await expect(ctx.agentTeams.createTask(lead, { subject: 'x'.repeat(201), description: 'too long' }))
       .rejects.toMatchObject({ code: 'TEAM_INVALID_ARGUMENT' })
-    const blocker = await ctx.teams.createTask(lead, { subject: 'blocker', description: 'blocker' })
-    await ctx.teams.createTask(lead, {
+    const blocker = await ctx.agentTeams.createTask(lead, { subject: 'blocker', description: 'blocker' })
+    await ctx.agentTeams.createTask(lead, {
       subject: 'dependent', description: 'dependent', blockedBy: [blocker.id],
     })
-    expect(() => ctx.teams.getTask(lead, TeamTaskId('missing')))
+    expect(() => ctx.agentTeams.getTask(lead, TeamTaskId('missing')))
       .toThrow(expect.objectContaining({ code: 'TEAM_TASK_NOT_FOUND' }))
     for (const action of ['release', 'complete', 'reopen'] as const) {
-      await expect(ctx.teams.updateTask(lead, {
+      await expect(ctx.agentTeams.updateTask(lead, {
         taskId: blocker.id,
         expectedRevision: blocker.revision,
         action,
       })).rejects.toMatchObject({ code: 'TEAM_TASK_INVALID_TRANSITION' })
     }
-    await expect(ctx.teams.updateTask(lead, {
+    await expect(ctx.agentTeams.updateTask(lead, {
       taskId: blocker.id,
       expectedRevision: blocker.revision,
       action: 'edit',
     })).rejects.toMatchObject({ code: 'TEAM_INVALID_ARGUMENT' })
-    await expect(ctx.teams.updateTask(lead, {
+    await expect(ctx.agentTeams.updateTask(lead, {
       taskId: blocker.id,
       expectedRevision: blocker.revision,
       action: 'set_dependencies',
     })).rejects.toMatchObject({ code: 'TEAM_INVALID_ARGUMENT' })
-    await expect(ctx.teams.updateTask(lead, {
+    await expect(ctx.agentTeams.updateTask(lead, {
       taskId: blocker.id,
       expectedRevision: blocker.revision,
       action: 'delete',
@@ -704,54 +704,54 @@ describe('Team shared task DAG', () => {
     const { ctx, lead } = await setup(['hang'])
     const started = await spawn(ctx, lead, 'owner')
     const owner = await waitRunning(ctx, started.member.id)
-    const task = await ctx.teams.createTask(owner, { subject: 'lifecycle', description: 'lifecycle' })
-    const assigned = await ctx.teams.updateTask(lead, {
+    const task = await ctx.agentTeams.createTask(owner, { subject: 'lifecycle', description: 'lifecycle' })
+    const assigned = await ctx.agentTeams.updateTask(lead, {
       taskId: task.id,
       expectedRevision: task.revision,
       action: 'reassign',
       owner: 'owner',
     })
-    await expect(ctx.teams.updateTask(owner, {
+    await expect(ctx.agentTeams.updateTask(owner, {
       taskId: task.id,
       expectedRevision: assigned.revision,
       action: 'reassign',
       owner: 'lead',
     })).rejects.toMatchObject({ code: 'TEAM_LEAD_REQUIRED' })
-    const complete = await ctx.teams.updateTask(owner, {
+    const complete = await ctx.agentTeams.updateTask(owner, {
       taskId: task.id,
       expectedRevision: assigned.revision,
       action: 'complete',
     })
-    await expect(ctx.teams.updateTask(lead, {
+    await expect(ctx.agentTeams.updateTask(lead, {
       taskId: task.id,
       expectedRevision: complete.revision,
       action: 'reassign',
       owner: 'lead',
     })).rejects.toMatchObject({ code: 'TEAM_TASK_INVALID_TRANSITION' })
-    const reopened = await ctx.teams.updateTask(owner, {
+    const reopened = await ctx.agentTeams.updateTask(owner, {
       taskId: task.id,
       expectedRevision: complete.revision,
       action: 'reopen',
     })
-    const claimed = await ctx.teams.updateTask(owner, {
+    const claimed = await ctx.agentTeams.updateTask(owner, {
       taskId: task.id,
       expectedRevision: reopened.revision,
       action: 'claim',
     })
-    const deleted = await ctx.teams.updateTask(owner, {
+    const deleted = await ctx.agentTeams.updateTask(owner, {
       taskId: task.id,
       expectedRevision: claimed.revision,
       action: 'delete',
     })
     expect(deleted.status).toBe('deleted')
-    expect(ctx.teams.listTasks(lead)).toEqual([])
-    await expect(ctx.teams.updateTask(owner, {
+    expect(ctx.agentTeams.listTasks(lead)).toEqual([])
+    await expect(ctx.agentTeams.updateTask(owner, {
       taskId: task.id,
       expectedRevision: deleted.revision,
       action: 'edit',
       subject: 'late',
     })).rejects.toMatchObject({ code: 'TEAM_TASK_DELETED' })
-    ctx.teams.interrupt(lead, 'owner')
+    ctx.agentTeams.interrupt(lead, 'owner')
     await waitNoAgent(ctx, owner.id)
   })
 
@@ -759,40 +759,40 @@ describe('Team shared task DAG', () => {
     const { ctx, lead } = await setup(['hang'])
     const started = await spawn(ctx, lead, 'editor')
     const editor = await waitRunning(ctx, started.member.id)
-    const blocker = await ctx.teams.createTask(lead, { subject: 'blocker', description: 'blocker' })
-    const task = await ctx.teams.createTask(lead, {
+    const blocker = await ctx.agentTeams.createTask(lead, { subject: 'blocker', description: 'blocker' })
+    const task = await ctx.agentTeams.createTask(lead, {
       subject: 'draft',
       description: 'draft description',
       blockedBy: [blocker.id],
     })
-    await expect(ctx.teams.updateTask(lead, {
+    await expect(ctx.agentTeams.updateTask(lead, {
       taskId: TeamTaskId('missing-update'), expectedRevision: 1, action: 'delete',
     })).rejects.toMatchObject({ code: 'TEAM_TASK_NOT_FOUND' })
-    await expect(ctx.teams.updateTask(lead, {
+    await expect(ctx.agentTeams.updateTask(lead, {
       taskId: task.id, expectedRevision: task.revision, action: 'reassign', owner: 'editor',
     })).rejects.toMatchObject({ code: 'TEAM_TASK_BLOCKED' })
 
-    const leadClaim = await ctx.teams.updateTask(lead, {
+    const leadClaim = await ctx.agentTeams.updateTask(lead, {
       taskId: blocker.id, expectedRevision: blocker.revision, action: 'claim',
     })
     expect(leadClaim.ownerName).toBe('lead')
-    const completedBlocker = await ctx.teams.updateTask(lead, {
+    const completedBlocker = await ctx.agentTeams.updateTask(lead, {
       taskId: blocker.id, expectedRevision: leadClaim.revision, action: 'complete',
     })
     expect(completedBlocker.status).toBe('completed')
-    const assigned = await ctx.teams.updateTask(lead, {
+    const assigned = await ctx.agentTeams.updateTask(lead, {
       taskId: task.id, expectedRevision: task.revision, action: 'reassign', owner: 'editor',
     })
-    const subject = await ctx.teams.updateTask(editor, {
+    const subject = await ctx.agentTeams.updateTask(editor, {
       taskId: task.id, expectedRevision: assigned.revision, action: 'edit', subject: 'edited subject',
     })
-    const description = await ctx.teams.updateTask(editor, {
+    const description = await ctx.agentTeams.updateTask(editor, {
       taskId: task.id,
       expectedRevision: subject.revision,
       action: 'edit',
       description: 'edited description',
     })
-    const scopes = await ctx.teams.updateTask(editor, {
+    const scopes = await ctx.agentTeams.updateTask(editor, {
       taskId: task.id,
       expectedRevision: description.revision,
       action: 'edit',
@@ -803,34 +803,34 @@ describe('Team shared task DAG', () => {
       description: 'edited description',
       writeScopes: ['src/nested'],
     })
-    const unassigned = await ctx.teams.updateTask(lead, {
+    const unassigned = await ctx.agentTeams.updateTask(lead, {
       taskId: task.id, expectedRevision: scopes.revision, action: 'reassign', owner: ' ',
     })
     expect(unassigned).toMatchObject({ status: 'pending' })
     expect('ownerId' in unassigned).toBe(false)
 
-    const broad = await ctx.teams.createTask(lead, {
+    const broad = await ctx.agentTeams.createTask(lead, {
       subject: 'broad scope', description: 'broad scope', writeScopes: ['src'],
     })
-    const narrow = await ctx.teams.createTask(lead, {
+    const narrow = await ctx.agentTeams.createTask(lead, {
       subject: 'narrow scope', description: 'narrow scope', writeScopes: ['src/nested'],
     })
-    const disjoint = await ctx.teams.createTask(lead, {
+    const disjoint = await ctx.agentTeams.createTask(lead, {
       subject: 'disjoint scope', description: 'disjoint scope', writeScopes: ['docs'],
     })
-    await ctx.teams.updateTask(lead, {
+    await ctx.agentTeams.updateTask(lead, {
       taskId: broad.id, expectedRevision: broad.revision, action: 'claim',
     })
-    await ctx.teams.updateTask(lead, {
+    await ctx.agentTeams.updateTask(lead, {
       taskId: narrow.id, expectedRevision: narrow.revision, action: 'claim',
     })
-    await ctx.teams.updateTask(lead, {
+    await ctx.agentTeams.updateTask(lead, {
       taskId: disjoint.id, expectedRevision: disjoint.revision, action: 'claim',
     })
-    expect(ctx.teams.getTask(lead, broad.id).writeScopeWarnings)
+    expect(ctx.agentTeams.getTask(lead, broad.id).writeScopeWarnings)
       .toEqual([`write scopes overlap with ${narrow.id}`])
 
-    ctx.teams.interrupt(lead, 'editor')
+    ctx.agentTeams.interrupt(lead, 'editor')
     await waitNoAgent(ctx, editor.id)
   })
 })
@@ -843,10 +843,10 @@ describe('Team mailbox and waiting', () => {
     lead.followup(createUserMessage({ content: content('keep the Lead busy'), source: { kind: 'user' } }))
     await waitRunning(ctx, lead.id)
 
-    const first = await ctx.teams.sendMessage(reporter, {
+    const first = await ctx.agentTeams.sendMessage(reporter, {
       target: 'lead', content: content('first wakeup report'), delivery: 'wakeup', signal: SIGNAL,
     })
-    const second = await ctx.teams.sendMessage(reporter, {
+    const second = await ctx.agentTeams.sendMessage(reporter, {
       target: 'lead', content: content('second wakeup report'), delivery: 'wakeup', signal: SIGNAL,
     })
     expect([first.status, second.status]).toEqual(['accepted', 'accepted'])
@@ -890,7 +890,7 @@ describe('Team mailbox and waiting', () => {
     const { ctx, lead } = await setup(['hang'])
     const started = await spawn(ctx, lead, 'pending-target')
     const target = await waitRunning(ctx, started.member.id)
-    const immediate = await ctx.teams.sendMessage(lead, {
+    const immediate = await ctx.agentTeams.sendMessage(lead, {
       target: 'pending-target',
       content: content('live quiet receipt'),
       delivery: 'quiet',
@@ -969,7 +969,7 @@ describe('Team mailbox and waiting', () => {
     await expect(teamInternals(ctx).mailbox.tryDispatch(lead, disappearing, SIGNAL)).resolves.toBe(false)
     expect(durable(lead).pendingMessages.map(pending => pending.id)).toEqual([disappearing.id])
 
-    ctx.teams.interrupt(lead, 'pending-target')
+    ctx.agentTeams.interrupt(lead, 'pending-target')
     target.cancel({ kind: 'parent' })
     await waitNoAgent(ctx, target.id)
   })
@@ -985,7 +985,7 @@ describe('Team mailbox and waiting', () => {
       return flush(session)
     })
 
-    const first = await ctx.teams.sendMessage(lead, {
+    const first = await ctx.agentTeams.sendMessage(lead, {
       target: 'busy-target', content: content('first waking message'), delivery: 'wakeup', signal: SIGNAL,
     })
 
@@ -996,7 +996,7 @@ describe('Team mailbox and waiting', () => {
       && message.source.messageId === first.messageId)).toBe(true)
 
     flushed.length = 0
-    const second = await ctx.teams.sendMessage(lead, {
+    const second = await ctx.agentTeams.sendMessage(lead, {
       target: 'busy-target', content: content('second waking message'), delivery: 'wakeup', signal: SIGNAL,
     })
 
@@ -1007,7 +1007,7 @@ describe('Team mailbox and waiting', () => {
       && (message.source.messageId === first.messageId || message.source.messageId === second.messageId)))
       .toHaveLength(2)
 
-    ctx.teams.interrupt(lead, 'busy-target')
+    ctx.agentTeams.interrupt(lead, 'busy-target')
     target.cancel({ kind: 'parent' })
     await waitNoAgent(ctx, target.id)
   })
@@ -1030,12 +1030,12 @@ describe('Team mailbox and waiting', () => {
       return createUserMessage({ content: blocks, source: { kind: 'user' } }).id
     })
 
-    const first = ctx.teams.sendMessage(lead, {
+    const first = ctx.agentTeams.sendMessage(lead, {
       target: 'ordered-target', content: content('first waking'), delivery: 'wakeup', signal: SIGNAL,
     })
     await entered.promise
     let secondSettled = false
-    const second = ctx.teams.sendMessage(lead, {
+    const second = ctx.agentTeams.sendMessage(lead, {
       target: 'ordered-target', content: content('second waking'), delivery: 'wakeup', signal: SIGNAL,
     }).finally(() => { secondSettled = true })
     await new Promise<void>((resolve) => { setTimeout(resolve, 0) })
@@ -1135,21 +1135,21 @@ describe('Team mailbox and waiting', () => {
     const inactiveStarted = await spawn(ctx, lead, 'inactive-target')
     await waitNoAgent(ctx, inactiveStarted.member.id)
     const inspect = vi.spyOn(ctx.sessionPersistence, 'inspect').mockRejectedValueOnce(new Error('inspect unavailable'))
-    const uncertain = await ctx.teams.sendMessage(lead, {
+    const uncertain = await ctx.agentTeams.sendMessage(lead, {
       target: 'inactive-target', content: content('inspection failure'), delivery: 'wakeup', signal: SIGNAL,
     })
     expect(uncertain.status).toBe('queued')
     inspect.mockRestore()
 
     vi.spyOn(ctx.subagents, 'followup').mockRejectedValueOnce(new Error('delivery unavailable'))
-    const failed = await ctx.teams.sendMessage(lead, {
+    const failed = await ctx.agentTeams.sendMessage(lead, {
       target: 'inactive-target', content: content('delivery failure'), delivery: 'wakeup', signal: SIGNAL,
     })
     expect(failed.status).toBe('queued')
     expect(warnings.some(warning => warning.includes('inspect unavailable'))).toBe(true)
     expect(warnings.some(warning => warning.includes('delivery unavailable'))).toBe(true)
 
-    ctx.teams.interrupt(lead, 'live-target')
+    ctx.agentTeams.interrupt(lead, 'live-target')
     await waitNoAgent(ctx, live.id)
   })
 
@@ -1160,12 +1160,12 @@ describe('Team mailbox and waiting', () => {
     const betaStarted = await spawn(ctx, lead, 'beta')
     await waitNoAgent(ctx, betaStarted.member.id)
 
-    const quiet = await ctx.teams.sendMessage(alpha, {
+    const quiet = await ctx.agentTeams.sendMessage(alpha, {
       target: 'beta', content: content('quiet info'), delivery: 'quiet', signal: SIGNAL,
     })
     expect(quiet.status).toBe('queued')
     expect(ctx.agents.get(betaStarted.member.id)).toBeUndefined()
-    const waking = await ctx.teams.sendMessage(alpha, {
+    const waking = await ctx.agentTeams.sendMessage(alpha, {
       target: 'beta', content: content('do another turn'), delivery: 'wakeup', signal: SIGNAL,
     })
     expect(waking.status).toBe('accepted')
@@ -1193,7 +1193,7 @@ describe('Team mailbox and waiting', () => {
       [waking.messageId, 'alpha'],
     ])
 
-    ctx.teams.interrupt(lead, 'alpha')
+    ctx.agentTeams.interrupt(lead, 'alpha')
     await waitNoAgent(ctx, alpha.id)
   })
 
@@ -1204,25 +1204,25 @@ describe('Team mailbox and waiting', () => {
     })
     const target = await spawn(ctx, lead, 'target')
     await waitNoAgent(ctx, target.member.id)
-    await expect(ctx.teams.sendMessage(lead, {
+    await expect(ctx.agentTeams.sendMessage(lead, {
       target: 'target', content: content('x'.repeat(300)), delivery: 'quiet', signal: SIGNAL,
     })).rejects.toMatchObject({ code: 'TEAM_MESSAGE_TOO_LARGE' })
-    const queued = await ctx.teams.sendMessage(lead, {
+    const queued = await ctx.agentTeams.sendMessage(lead, {
       target: 'target', content: content('one'), delivery: 'quiet', signal: SIGNAL,
     })
     expect(queued.status).toBe('queued')
-    await expect(ctx.teams.sendMessage(lead, {
+    await expect(ctx.agentTeams.sendMessage(lead, {
       target: 'target', content: content('two'), delivery: 'quiet', signal: SIGNAL,
     })).rejects.toMatchObject({ code: 'TEAM_MAILBOX_FULL' })
-    await expect(ctx.teams.sendMessage(lead, {
+    await expect(ctx.agentTeams.sendMessage(lead, {
       target: 'lead', content: content('self'), delivery: 'quiet', signal: SIGNAL,
     })).rejects.toMatchObject({ code: 'TEAM_SELF_MESSAGE' })
-    await expect(ctx.teams.sendMessage(lead, {
+    await expect(ctx.agentTeams.sendMessage(lead, {
       target: 'missing', content: content('unknown target'), delivery: 'quiet', signal: SIGNAL,
     })).rejects.toMatchObject({ code: 'TEAM_MEMBER_NOT_FOUND' })
     const controller = new AbortController()
     controller.abort(new TeamError('cancelled before queue', 'TEST_CANCELLED'))
-    await expect(ctx.teams.sendMessage(lead, {
+    await expect(ctx.agentTeams.sendMessage(lead, {
       target: 'target', content: content('cancelled'), delivery: 'quiet', signal: controller.signal,
     })).rejects.toMatchObject({ code: 'TEST_CANCELLED' })
   })
@@ -1231,11 +1231,11 @@ describe('Team mailbox and waiting', () => {
     const { ctx, lead } = await setup(['hang', textResponse('after interrupt')])
     const started = await spawn(ctx, lead, 'worker')
     const worker = await waitRunning(ctx, started.member.id)
-    const followup = await ctx.teams.sendMessage(lead, {
+    const followup = await ctx.agentTeams.sendMessage(lead, {
       target: 'worker', content: content('retained follow-up'), delivery: 'wakeup', signal: SIGNAL,
     })
     expect(followup.status).toBe('accepted')
-    expect(ctx.teams.interrupt(lead, 'worker')).toEqual({ previousStatus: 'running' })
+    expect(ctx.agentTeams.interrupt(lead, 'worker')).toEqual({ previousStatus: 'running' })
     await vi.waitFor(() => { expect(worker.status).toBe('idle') })
     expect(worker.inbox.nextTurn.some(message => message.source.kind === 'team-message'
       && message.source.messageId === followup.messageId)).toBe(true)
@@ -1252,7 +1252,7 @@ describe('Team mailbox and waiting', () => {
     await ctx.plugin(AgentLoop, { agents: [] })
     await ctx.plugin(SubagentService)
     const fiber = await ctx.plugin(TeamService)
-    const service = ctx.teams
+    const service = ctx.agentTeams
     const lead = ctx.agentLoop.create(SessionId('wait-lead'), {})
 
     await expect(service.waitForChange(lead, 9_999, SIGNAL))
@@ -1314,25 +1314,25 @@ describe('Team mailbox and waiting', () => {
     const disposed = service.waitForChange(lead, 10_000, SIGNAL)
     await fiber.dispose()
     await expect(disposed).resolves.toEqual({ timedOut: false })
-    expect(ctx.get('teams')).toBeUndefined()
+    expect(ctx.get('agentTeams')).toBeUndefined()
   })
 
   it('disposes live teammate Activations and their waits when the Team service unloads', async () => {
     const { ctx, lead, teamFiber } = await setup(['hang'])
     const started = await spawn(ctx, lead, 'dispose-worker')
     await waitRunning(ctx, started.member.id)
-    const waiting = ctx.teams.waitForChange(lead, 10_000, SIGNAL)
+    const waiting = ctx.agentTeams.waitForChange(lead, 10_000, SIGNAL)
 
     await teamFiber.dispose()
 
     await expect(waiting).resolves.toEqual({ timedOut: false })
     expect(ctx.agents.get(started.member.id)).toBeUndefined()
-    expect(ctx.get('teams')).toBeUndefined()
+    expect(ctx.get('agentTeams')).toBeUndefined()
   })
 
   it('closes creation admission and drains an in-flight spawn before unload completes', async () => {
     const { ctx, lead, teamFiber } = await setup(['hang'])
-    const service = ctx.teams
+    const service = ctx.agentTeams
     const start = ctx.subagents.startContinuable.bind(ctx.subagents)
     const entered = Promise.withResolvers<undefined>()
     const release = Promise.withResolvers<undefined>()
@@ -1363,7 +1363,7 @@ describe('Team mailbox and waiting', () => {
     await rejected
     await disposal
     if (childId !== undefined) expect(ctx.agents.get(childId)).toBeUndefined()
-    expect(ctx.get('teams')).toBeUndefined()
+    expect(ctx.get('agentTeams')).toBeUndefined()
   })
 
   it('retains an in-flight creation cleanup failure during disposal', async () => {
@@ -1433,9 +1433,9 @@ describe('Team mailbox and waiting', () => {
       },
     })
     await ctx.sessions.flush(lead.session)
-    expect(ctx.teams.listMembers(lead)[1]?.status).toBe('failed')
+    expect(ctx.agentTeams.listMembers(lead)[1]?.status).toBe('failed')
 
-    const internal = ctx.teams as unknown as { disposeRuntime(): Promise<void> }
+    const internal = ctx.agentTeams as unknown as { disposeRuntime(): Promise<void> }
     await internal.disposeRuntime()
     expect(ctx.agents.get(childId)).toBeUndefined()
   })
@@ -1460,14 +1460,14 @@ describe('Team mailbox and waiting', () => {
       })
     })
 
-    const sending = ctx.teams.sendMessage(lead, {
+    const sending = ctx.agentTeams.sendMessage(lead, {
       target: 'mailbox-worker',
       content: content('resume during disposal'),
       delivery: 'wakeup',
       signal: SIGNAL,
     })
     await entered.promise
-    const internal = ctx.teams as unknown as { disposeRuntime(): Promise<void> }
+    const internal = ctx.agentTeams as unknown as { disposeRuntime(): Promise<void> }
     let disposed = false
     const disposal = internal.disposeRuntime().then(() => { disposed = true })
     await aborted.promise
@@ -1521,7 +1521,7 @@ describe('Team mailbox and waiting', () => {
       },
     }), { surfaceOp: 'append' })
 
-    const internal = ctx.teams as unknown as { disposeRuntime(): Promise<void> }
+    const internal = ctx.agentTeams as unknown as { disposeRuntime(): Promise<void> }
     let disposed = false
     const disposal = internal.disposeRuntime().then(() => { disposed = true })
     await entered.promise
@@ -1549,7 +1549,7 @@ describe('Team mailbox and waiting', () => {
     ])
     expect(outcome).toBe('disposed')
     expect(drain).toHaveBeenCalledWith(lead, [started.member.id])
-    expect(ctx.get('teams')).toBeUndefined()
+    expect(ctx.get('agentTeams')).toBeUndefined()
   })
 
   it('bounds disposal while an admitted creation ignores cancellation', async () => {
@@ -1558,7 +1558,7 @@ describe('Team mailbox and waiting', () => {
     internal.roster.inFlightCreations.add(new Promise(() => {}))
 
     await expect(internal.disposeRuntime()).rejects.toBeInstanceOf(AggregateError)
-    await expect(ctx.teams.spawnTeammate(lead, {
+    await expect(ctx.agentTeams.spawnTeammate(lead, {
       name: 'after-timeout',
       description: 'admission remains closed',
       prompt: content('must reject'),
@@ -1566,7 +1566,7 @@ describe('Team mailbox and waiting', () => {
       provider: 'spawn',
       signal: SIGNAL,
     })).rejects.toMatchObject({ code: 'TEAM_DISPOSED' })
-    await expect(ctx.teams.sendMessage(lead, {
+    await expect(ctx.agentTeams.sendMessage(lead, {
       target: 'nobody', content: content('must reject'), delivery: 'quiet', signal: SIGNAL,
     })).rejects.toMatchObject({ code: 'TEAM_DISPOSED' })
     await expect(internal.mailbox.tryDispatch(lead, {
@@ -1626,7 +1626,7 @@ describe('Team mailbox and waiting', () => {
     vi.spyOn(ctx.subagents, 'drainContinuableDescendants').mockRejectedValueOnce(new Error('drain failure'))
 
     await teamFiber.dispose()
-    expect(ctx.get('teams')).toBeUndefined()
+    expect(ctx.get('agentTeams')).toBeUndefined()
   })
 
   it('reconciles mismatched persisted children and ignores a concurrently settled member', async () => {

+ 0 - 0
packages/experimental/team/tsconfig.json → packages/experimental/agent-team/tsconfig.json


+ 0 - 0
packages/experimental/team/tsdown.config.ts → packages/experimental/agent-team/tsdown.config.ts


+ 3 - 3
packages/experimental/team/README.i18n.yaml → packages/experimental/tool-agent-team/README.i18n.yaml

@@ -1,6 +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 packages/experimental/team/README.md
-README.md: f676f5b2245fd15559c9e5cd5f969ceece6625c8
-README.zh.md: e85dc59dcd349f69d23408038b4ecead01fbeca6
+#   pnpm run verify-translation-pairing --write packages/experimental/tool-agent-team/README.md
+README.md: a0ff967199e8a22b60483aa59442a1cbefb261a8
+README.zh.md: 3dc4d9ea1631cc23e171d0689271f60ff84f92c4

+ 6 - 6
packages/experimental/tool-team/README.md → packages/experimental/tool-agent-team/README.md

@@ -1,14 +1,14 @@
-# @deepseek-ai/dsh-tool-team
+# @deepseek-ai/dsh-experimental-tool-agent-team
 
 English | [中文](README.zh.md)
 
-Scoped model-facing adapter for [`ctx.teams`](../team/README.md). It installs the Agent Teams policy and collaboration tools in each implicit Lead and durable teammate scope. Scoped Team definitions shadow same-named legacy global continuable-subagent controls, so a composition that mounts both must disable the legacy definitions.
+Scoped model-facing adapter for [`ctx.agentTeams`](../agent-team/README.md). It installs the Agent Teams policy and collaboration tools in each implicit Lead and durable teammate scope. Scoped Team definitions shadow same-named legacy global continuable-subagent controls, so a composition that mounts both must disable the legacy definitions.
 
 ## Config
 
 ```yaml
-- id: tool-team
-  name: '@deepseek-ai/dsh-tool-team'
+- id: tool-agent-team
+  name: '@deepseek-ai/dsh-experimental-tool-agent-team'
   config:
     freshProvider: spawn
     forkProvider: fork
@@ -18,9 +18,9 @@ Scoped model-facing adapter for [`ctx.teams`](../team/README.md). It installs th
 
 ## Tools and authority
 
-The generated [tool catalog](../../../docs/tool-catalog.md#deepseek-aidsh-tool-team) owns exact schemas. The adapter supplies teammate creation; quiet and waking peer delivery; roster listing, waiting, and Lead-only interruption; and task create/list/get/compare-and-set update operations.
+The generated [tool catalog](../../../docs/tool-catalog.md#deepseek-aidsh-experimental-tool-agent-team) owns exact schemas. The adapter supplies teammate creation; quiet and waking peer delivery; roster listing, waiting, and Lead-only interruption; and task create/list/get/compare-and-set update operations.
 
-Every tool requires the exact calling `Agent`. `spawn_teammate` and `interrupt_agent` enforce Lead authority inside `ctx.teams`, not only in their descriptions. All members can communicate with any peer and use the task board. Task mutations retain the domain's owner/Lead and revision checks.
+Every tool requires the exact calling `Agent`. `spawn_teammate` and `interrupt_agent` enforce Lead authority inside `ctx.agentTeams`, not only in their descriptions. All members can communicate with any peer and use the task board. Task mutations retain the domain's owner/Lead and revision checks.
 
 `send_message` succeeds once mail is durable and never wakes an inactive target. `followup_task` also makes the message the target's next turn and can cold-resume it. A `queued` result is accepted durable work and must not be retried. Task readiness does not start an owner. Before arming its 10,000-through-3,600,000-millisecond edge wait, `wait_agent` checks for another member that is running or provisioning; without one it returns `noProgress` immediately with instructions to re-list and use `followup_task`. Otherwise it waits for one post-call Team edge, defaulting to 30,000 milliseconds, and callers re-list after wakeup or timeout because earlier changes are not replayed.
 

+ 6 - 6
packages/experimental/tool-team/README.zh.md → packages/experimental/tool-agent-team/README.zh.md

@@ -1,14 +1,14 @@
-# @deepseek-ai/dsh-tool-team
+# @deepseek-ai/dsh-experimental-tool-agent-team
 
 [English](README.md) | 中文
 
-[`ctx.teams`](../team/README.md) 的 scoped 模型适配器。它会在每个隐式 Lead 与持久 teammate scope 中安装 Agent Teams 策略和协作工具。scoped Team 定义会覆盖同名的旧全局 continuable-subagent control,因此同时挂载两者的组合必须禁用旧定义。
+[`ctx.agentTeams`](../agent-team/README.md) 的 scoped 模型适配器。它会在每个隐式 Lead 与持久 teammate scope 中安装 Agent Teams 策略和协作工具。scoped Team 定义会覆盖同名的旧全局 continuable-subagent control,因此同时挂载两者的组合必须禁用旧定义。
 
 ## 配置
 
 ```yaml
-- id: tool-team
-  name: '@deepseek-ai/dsh-tool-team'
+- id: tool-agent-team
+  name: '@deepseek-ai/dsh-experimental-tool-agent-team'
   config:
     freshProvider: spawn
     forkProvider: fork
@@ -18,9 +18,9 @@
 
 ## 工具与权限
 
-生成的[工具目录](../../../docs/tool-catalog.md#deepseek-aidsh-tool-team)负责精确 schema。该适配器提供 teammate 创建;quiet 与 waking peer 投递;roster 列表、等待和仅限 Lead 的 interrupt;以及任务 create/list/get/CAS update 操作。
+生成的[工具目录](../../../docs/tool-catalog.md#deepseek-aidsh-experimental-tool-agent-team)负责精确 schema。该适配器提供 teammate 创建;quiet 与 waking peer 投递;roster 列表、等待和仅限 Lead 的 interrupt;以及任务 create/list/get/CAS update 操作。
 
-每个工具都要求完全相同的调用 `Agent`。`spawn_teammate` 与 `interrupt_agent` 在 `ctx.teams` 内部强制执行 Lead 权限,而不只依赖描述。所有成员都可以与任意 peer 通讯并使用任务板。任务变更保留领域层的 Owner/Lead 与 revision 校验。
+每个工具都要求完全相同的调用 `Agent`。`spawn_teammate` 与 `interrupt_agent` 在 `ctx.agentTeams` 内部强制执行 Lead 权限,而不只依赖描述。所有成员都可以与任意 peer 通讯并使用任务板。任务变更保留领域层的 Owner/Lead 与 revision 校验。
 
 `send_message` 在 mail 持久化后即成功,并且绝不会唤醒 inactive target。`followup_task` 还会让该消息成为 target 的下一个 turn,并可冷恢复 target。`queued` 结果表示持久工作已经接受,不能重试。任务 ready 不会启动 owner。`wait_agent` 在注册 10,000 到 3,600,000 毫秒的边等待前,会检查是否有另一个 running 或 provisioning member;如果没有,它会立即返回 `noProgress`,提示重新 list 并使用 `followup_task`。否则它会等待调用后发生的一条 Team 边,默认 30,000 毫秒;由于不会回放更早的变化,调用方需要在唤醒或超时后重新 list。
 

+ 5 - 5
packages/experimental/tool-team/package.json → packages/experimental/tool-agent-team/package.json

@@ -1,12 +1,12 @@
 {
-  "name": "@deepseek-ai/dsh-tool-team",
-  "description": "Scoped model-facing Agent Teams tools over ctx.teams",
+  "name": "@deepseek-ai/dsh-experimental-tool-agent-team",
+  "description": "Scoped model-facing Agent Teams tools over ctx.agentTeams",
   "version": "0.1.0-rc.7",
   "private": true,
   "repository": {
     "type": "git",
     "url": "git+https://github.com/deepseek-ai/deepseek-harness.git",
-    "directory": "packages/experimental/tool-team"
+    "directory": "packages/experimental/tool-agent-team"
   },
   "type": "module",
   "main": "lib/index.js",
@@ -37,7 +37,7 @@
     "@deepseek-ai/dsh-invariants": "workspace:^",
     "@deepseek-ai/dsh-session": "workspace:^",
     "@deepseek-ai/dsh-system-prompt": "workspace:^",
-    "@deepseek-ai/dsh-team": "workspace:^",
+    "@deepseek-ai/dsh-experimental-agent-team": "workspace:^",
     "@deepseek-ai/dsh-tools": "workspace:^",
     "@deepseek-ai/cordis": "workspace:^"
   },
@@ -54,7 +54,7 @@
     "@deepseek-ai/dsh-subagent-spawn-in-process": "workspace:^",
     "@deepseek-ai/dsh-tool-subagent-control": "workspace:^",
     "@deepseek-ai/dsh-system-prompt": "workspace:^",
-    "@deepseek-ai/dsh-team": "workspace:^",
+    "@deepseek-ai/dsh-experimental-agent-team": "workspace:^",
     "@deepseek-ai/dsh-tools": "workspace:^",
     "@deepseek-ai/cordis": "workspace:^"
   }

+ 17 - 17
packages/experimental/tool-team/src/index.ts → packages/experimental/tool-agent-team/src/index.ts

@@ -3,15 +3,15 @@
 import type { Context } from '@deepseek-ai/cordis'
 import z from '@deepseek-ai/schemastery'
 import type { Agent } from '@deepseek-ai/dsh-agent'
-import { TeamTaskId } from '@deepseek-ai/dsh-team'
-import type { TeamMemberView } from '@deepseek-ai/dsh-team'
+import { TeamTaskId } from '@deepseek-ai/dsh-experimental-agent-team'
+import type { TeamMemberView } from '@deepseek-ai/dsh-experimental-agent-team'
 import { defineTool } from '@deepseek-ai/dsh-tools'
 import type { InferValue, ValueSchemaSpec } from '@deepseek-ai/dsh-tools'
 
 /** Cordis plugin name. */
-export const name = 'tool-team'
+export const name = 'tool-agent-team'
 /** Services required by the Team tool plugin. */
-export const inject = ['agents', 'teams', 'tools', 'systemPrompt']
+export const inject = ['agents', 'agentTeams', 'tools', 'systemPrompt']
 
 /** Tool routing configuration. */
 export interface Config {
@@ -165,7 +165,7 @@ function install(agent: Agent, ctx: Context, config: Required<Config>): () => vo
       name: 'team:policy',
       order: 60,
       text: () => {
-        const membership = ctx.teams.membership(agent)
+        const membership = ctx.agentTeams.membership(agent)
         return `${POLICY}\n\nYour Team role is ${membership.role}; your Team name is ${membership.name}; Team id is ${membership.id}.`
       },
     }))
@@ -187,7 +187,7 @@ function install(agent: Agent, ctx: Context, config: Required<Config>): () => vo
       async execute(args, exec) {
         const agent = callingAgent(exec.agent, 'spawn_teammate')
         const context = args.context ?? 'fresh'
-        return await ctx.teams.spawnTeammate(agent, {
+        return await ctx.agentTeams.spawnTeammate(agent, {
           name: args.name,
           description: args.description,
           prompt: [{ type: 'text', text: args.prompt }],
@@ -210,7 +210,7 @@ function install(agent: Agent, ctx: Context, config: Required<Config>): () => vo
         },
         output: jsonOutput(SEND_VALUE_SCHEMA),
         execute(args, exec) {
-          return ctx.teams.sendMessage(callingAgent(exec.agent, toolName), {
+          return ctx.agentTeams.sendMessage(callingAgent(exec.agent, toolName), {
             target: args.target,
             content: [{ type: 'text', text: args.message }],
             delivery,
@@ -228,7 +228,7 @@ function install(agent: Agent, ctx: Context, config: Required<Config>): () => vo
       parameters: {},
       output: jsonOutput(MEMBER_LIST_VALUE_SCHEMA),
       async execute(_args, exec) {
-        return Promise.resolve(ctx.teams.listMembers(callingAgent(exec.agent, 'list_agents')))
+        return Promise.resolve(ctx.agentTeams.listMembers(callingAgent(exec.agent, 'list_agents')))
       },
     })))
 
@@ -248,11 +248,11 @@ function install(agent: Agent, ctx: Context, config: Required<Config>): () => vo
         // Preserve TeamService's authoritative timeout validation before the
         // model-only no-progress shortcut.
         if (!Number.isSafeInteger(timeoutMs) || timeoutMs < 10_000 || timeoutMs > 3_600_000) {
-          return await ctx.teams.waitForChange(caller, timeoutMs, exec.signal)
+          return await ctx.agentTeams.waitForChange(caller, timeoutMs, exec.signal)
         }
         // The active-peer read and waiter registration must remain one synchronous
         // span; awaiting between them can lose the only peer-status edge.
-        const hasActivePeer = ctx.teams.listMembers(caller).some(member =>
+        const hasActivePeer = ctx.agentTeams.listMembers(caller).some(member =>
           member.id !== caller.id && ACTIVE_WAIT_STATUSES.has(member.status))
         if (!hasActivePeer) {
           return {
@@ -263,7 +263,7 @@ function install(agent: Agent, ctx: Context, config: Required<Config>): () => vo
             },
           }
         }
-        return await ctx.teams.waitForChange(caller, timeoutMs, exec.signal)
+        return await ctx.agentTeams.waitForChange(caller, timeoutMs, exec.signal)
       },
     })))
 
@@ -275,7 +275,7 @@ function install(agent: Agent, ctx: Context, config: Required<Config>): () => vo
       },
       output: jsonOutput(INTERRUPT_VALUE_SCHEMA),
       async execute(args, exec) {
-        return Promise.resolve(ctx.teams.interrupt(
+        return Promise.resolve(ctx.agentTeams.interrupt(
           callingAgent(exec.agent, 'interrupt_agent'),
           args.target,
         ))
@@ -297,7 +297,7 @@ function install(agent: Agent, ctx: Context, config: Required<Config>): () => vo
       },
       output: jsonOutput(TASK_VIEW_SCHEMA),
       async execute(args, exec) {
-        return await ctx.teams.createTask(callingAgent(exec.agent, 'team_task_create'), {
+        return await ctx.agentTeams.createTask(callingAgent(exec.agent, 'team_task_create'), {
           subject: args.subject,
           description: args.description,
           ...args.blocked_by === undefined ? {} : { blockedBy: args.blocked_by.map(TeamTaskId) },
@@ -323,7 +323,7 @@ function install(agent: Agent, ctx: Context, config: Required<Config>): () => vo
       output: jsonOutput(TASK_LIST_VALUE_SCHEMA),
       execute(args, exec) {
         const status = args.status
-        const filtered = ctx.teams.listTasks(callingAgent(exec.agent, 'team_task_list')).filter(task =>
+        const filtered = ctx.agentTeams.listTasks(callingAgent(exec.agent, 'team_task_list')).filter(task =>
           (status === undefined || task.status === status)
           && (args.owner === undefined || (args.owner === 'unowned' ? task.ownerName === undefined : task.ownerName === args.owner))
           && (args.ready === undefined || task.ready === args.ready))
@@ -346,7 +346,7 @@ function install(agent: Agent, ctx: Context, config: Required<Config>): () => vo
       },
       output: jsonOutput(TASK_VIEW_SCHEMA),
       async execute(args, exec) {
-        return Promise.resolve(ctx.teams.getTask(
+        return Promise.resolve(ctx.agentTeams.getTask(
           callingAgent(exec.agent, 'team_task_get'),
           TeamTaskId(args.task_id),
         ))
@@ -373,7 +373,7 @@ function install(agent: Agent, ctx: Context, config: Required<Config>): () => vo
       },
       output: jsonOutput(TASK_VIEW_SCHEMA),
       async execute(args, exec) {
-        return await ctx.teams.updateTask(callingAgent(exec.agent, 'team_task_update'), {
+        return await ctx.agentTeams.updateTask(callingAgent(exec.agent, 'team_task_update'), {
           taskId: TeamTaskId(args.task_id),
           expectedRevision: args.expected_revision,
           action: args.action,
@@ -402,7 +402,7 @@ export function apply(ctx: Context, config: Config = {}): void {
   }
   const installed = new Map<Agent, () => void>()
   const maybeInstall = (agent: Agent): void => {
-    if (installed.has(agent) || ctx.teams.tryMembership(agent) === undefined) return
+    if (installed.has(agent) || ctx.agentTeams.tryMembership(agent) === undefined) return
     installed.set(agent, install(agent, ctx, resolved))
   }
   for (const agent of ctx.agents.list()) maybeInstall(agent)

+ 1 - 1
packages/experimental/tool-team/src/invariant.ts → packages/experimental/tool-agent-team/src/invariant.ts

@@ -3,7 +3,7 @@
 import type { Context } from '@deepseek-ai/cordis'
 import type { InvariantInstaller } from '@deepseek-ai/dsh-invariants'
 
-const PACKAGE_NAME = '@deepseek-ai/dsh-tool-team'
+const PACKAGE_NAME = '@deepseek-ai/dsh-experimental-tool-agent-team'
 
 /** Cordis companion plugin name. */
 export const name = 'tool-team-invariant'

+ 5 - 5
packages/experimental/tool-team/tests/tool-team.spec.ts → packages/experimental/tool-agent-team/tests/tool-team.spec.ts

@@ -17,7 +17,7 @@ import { renderPrompt } from '@deepseek-ai/dsh-system-prompt'
 import * as ToolSubagentControl from '@deepseek-ai/dsh-tool-subagent-control'
 import { defineContentToolFixture } from '@deepseek-ai/dsh-tools'
 import { MockAdapter, textResponse } from '../../../core/agent-loop/tests/mock-adapter.ts'
-import TeamService from '../../team/src/index.ts'
+import TeamService from '../../agent-team/src/index.ts'
 import * as toolTeam from '../src/index.ts'
 
 const SIGNAL = new AbortController().signal
@@ -402,7 +402,7 @@ describe('dsh-tool-team', () => {
     const childId = spawnedChildId(spawned)
     await vi.waitFor(() => { expect(ctx.agents.get(childId)).toBeUndefined() }, { timeout: 5_000 })
 
-    await ctx.teams.sendMessage(lead, {
+    await ctx.agentTeams.sendMessage(lead, {
       target: 'cold-worker',
       content: [{ type: 'text', text: 'resume with Team scope' }],
       delivery: 'wakeup',
@@ -422,8 +422,8 @@ describe('dsh-tool-team', () => {
     expect(result.isError).toBe(true)
     expect(text(result)).toContain('unknown tool "list_agents"')
     expect('default' in toolTeam).toBe(false)
-    expect(toolTeam.name).toBe('tool-team')
-    expect(toolTeam.inject).toEqual(['agents', 'teams', 'tools', 'systemPrompt'])
+    expect(toolTeam.name).toBe('tool-agent-team')
+    expect(toolTeam.inject).toEqual(['agents', 'agentTeams', 'tools', 'systemPrompt'])
   })
 
   it('uses configured fresh and fork provider names', async () => {
@@ -437,6 +437,6 @@ describe('dsh-tool-team', () => {
     expect(result.isError).toBe(false)
     const childId = spawnedChildId(result)
     await vi.waitFor(() => { expect(ctx.agents.get(childId)).toBeUndefined() }, { timeout: 5_000 })
-    expect(ctx.teams.listMembers(lead)[1]).toMatchObject({ provider: 'team-fresh' })
+    expect(ctx.agentTeams.listMembers(lead)[1]).toMatchObject({ provider: 'team-fresh' })
   })
 })

+ 1 - 1
packages/experimental/tool-team/tsconfig.json → packages/experimental/tool-agent-team/tsconfig.json

@@ -14,7 +14,7 @@
     { "path": "../../core/session" },
     { "path": "../../core/system-prompt" },
     { "path": "../../core/tools" },
-    { "path": "../team" },
+    { "path": "../agent-team" },
     { "path": "../../runtime-diagnostics/invariants" }
   ]
 }

+ 2 - 2
packages/extensions/cordis-client-runner/src/client/api-catalog.ts

@@ -128,7 +128,7 @@ export const SERVICE_API: readonly ServiceApiEntry[] = [
       },
       {
         signature: 'setLocale(id: string): void',
-        description: 'Switch the active locale — the only user preference write entry.',
+        description: 'Switch the active locale — the only user preference write entry.\n\nThe durable write happens even when the id already matches the active locale, because the active value may be a provisional browser-derived or fallback resolution that nothing has stored yet. Picking the language already on screen is still an explicit choice, and it must survive a different browser sharing the same DSH home. Only the render notification is conditional: republishing an unchanged locale would churn every subscriber for nothing.',
         parameters: [{ name: 'id', description: 'a registered locale id; unknown ids throw.' }],
       },
       {
@@ -571,7 +571,7 @@ export const TYPE_API: readonly TypeApiEntry[] = [
   },
   {
     name: 'ISession',
-    declaration: 'export interface ISession {\n    readonly sessionId: SessionId;\n    readonly projections: ProjectionsFace;\n    prompt(content: PromptContentPart[], mode: \'queue\' | \'steer\'): Promise<RpcResult<{\n        accepted: true;\n    }>>;\n    readAttachment(attachmentId: AttachmentIdType): Promise<RpcResult<{\n        attachment: ImageAttachmentRef;\n        data: Uint8Array;\n    }>>;\n    updateQueue(itemId: MessageId, action: QueueAction): Promise<RpcResult<{\n        accepted: true;\n    }>>;\n    cancel(): Promise<RpcResult<{\n        accepted: true;\n    }>>;\n    rename(title: string): Promise<RpcResult<{\n        title: string;\n        seq: number;\n    }>>;\n    loadOlder(): Promise<void>;\n    command(line: string): Promise<RemoteResult<{\n        matched: boolean;\n    }>>;\n}',
+    declaration: 'export interface ISession {\n    readonly sessionId: SessionId;\n    readonly projections: ProjectionsFace;\n    prompt(content: PromptContentPart[], mode: \'queue\' | \'steer\', signal?: AbortSignal): Promise<RpcResult<{\n        accepted: true;\n    }>>;\n    readAttachment(attachmentId: AttachmentIdType): Promise<RpcResult<{\n        attachment: ImageAttachmentRef;\n        data: Uint8Array;\n    }>>;\n    updateQueue(itemId: MessageId, action: QueueAction): Promise<RpcResult<{\n        accepted: true;\n    }>>;\n    cancel(): Promise<RpcResult<{\n        accepted: true;\n    }>>;\n    rename(title: string): Promise<RpcResult<{\n        title: string;\n        seq: number;\n    }>>;\n    loadOlder(): Promise<void>;\n    command(line: string): Promise<RemoteResult<{\n        matched: boolean;\n    }>>;\n}',
   },
   {
     name: 'KeyPropsOf',

+ 73 - 73
packages/extensions/tool-cordis/src/api-catalog.ts

@@ -304,6 +304,79 @@ export const SERVICE_API: readonly ServiceApiEntry[] = [
       },
     ],
   },
+  {
+    key: 'agentTeams',
+    summary: 'Agent Teams service backed by the exact live Lead Session log.',
+    description: 'Agent Teams service backed by the exact live Lead Session log.',
+    methods: [
+      {
+        signature: 'membership(agent: Agent): TeamMembership',
+        description: 'Resolve one exact live Agent\'s Team role.',
+        parameters: [{ name: 'agent', description: 'exact live Agent used as the authority credential.' }],
+        returns: 'its root, Team identity, role, and model-facing name.',
+      },
+      {
+        signature: 'listMembers(agent: Agent): TeamMemberView[]',
+        description: 'List the runtime-enriched roster visible to one Team member.',
+        parameters: [{ name: 'agent', description: 'exact live Team member.' }],
+        returns: 'Lead and teammate rows in creation order.',
+      },
+      {
+        signature: 'async spawnTeammate(caller: Agent, request: SpawnTeammateRequest): Promise<SpawnTeammateResult>',
+        description: 'Create one named, continuable direct child of the Team Lead.',
+        parameters: [{ name: 'caller', description: 'exact live Lead Agent.' }, { name: 'request', description: 'immutable name, description, prompt, context mode, provider, and cancellation.' }],
+        returns: 'the active roster row.',
+      },
+      {
+        signature: 'async sendMessage(caller: Agent, request: SendTeamMessageRequest): Promise<SendTeamMessageResult>',
+        description: 'Queue one durable peer message, then attempt immediate delivery.',
+        parameters: [{ name: 'caller', description: 'exact live sending Team member.' }, { name: 'request', description: 'target name, content, scheduling mode, and pre-queue cancellation.' }],
+        returns: 'durable message identity and immediate-delivery observation.',
+      },
+      {
+        signature: 'async createTask(caller: Agent, request: CreateTeamTaskRequest): Promise<TeamTaskView>',
+        description: 'Create one unowned pending task in the Team Lead log.',
+        parameters: [{ name: 'caller', description: 'exact live Team member creating the task.' }, { name: 'request', description: 'task text, blockers, and advisory write scopes.' }],
+        returns: 'the revision-one task view.',
+      },
+      {
+        signature: 'getTask(caller: Agent, id: TeamTaskId): TeamTaskView',
+        description: 'Return one task, including a deleted tombstone.',
+        parameters: [{ name: 'caller', description: 'exact live Team member reading the task.' }, { name: 'id', description: 'Team-local task identity.' }],
+        returns: 'the latest task value and derived readiness diagnostics.',
+      },
+      {
+        signature: 'listTasks(caller: Agent): TeamTaskView[]',
+        description: 'List current non-deleted tasks in numeric creation order.',
+        parameters: [{ name: 'caller', description: 'exact live Team member reading the board.' }],
+        returns: 'detached current task views.',
+      },
+      {
+        signature: 'async updateTask(caller: Agent, request: UpdateTeamTaskRequest): Promise<TeamTaskView>',
+        description: 'Compare-and-set one authorized task transition.',
+        parameters: [{ name: 'caller', description: 'exact live Team member authorizing the mutation.' }, { name: 'request', description: 'task identity, expected revision, action, and action fields.' }],
+        returns: 'the committed next task revision.',
+      },
+      {
+        signature: 'async waitForChange(caller: Agent, timeoutMs: number, signal: AbortSignal): Promise<TeamWaitResult>',
+        description: 'Wait for the next Team-domain or member-status change.',
+        parameters: [{ name: 'caller', description: 'exact live Team member waiting for activity.' }, { name: 'timeoutMs', description: 'bounded wait duration from ten seconds through one hour.' }, { name: 'signal', description: 'caller cancellation for the wait only.' }],
+        returns: 'one observed change or a timeout result.',
+      },
+      {
+        signature: 'interrupt(caller: Agent, targetName: string): { previousStatus: \'running\' | \'idle\' | \'inactive\' }',
+        description: 'Interrupt one live teammate turn without clearing its pending inbox.',
+        parameters: [{ name: 'caller', description: 'exact live Lead Agent.' }, { name: 'targetName', description: 'durable teammate name.' }],
+        returns: 'the target status sampled before cancellation.',
+      },
+      {
+        signature: 'tryMembership(agent: Agent): TeamMembership | undefined',
+        description: 'Resolve a caller without throwing, used by scoped-tool installation and observers.',
+        parameters: [{ name: 'agent', description: 'candidate exact live Agent.' }],
+        returns: 'Team membership, or undefined for non-Team subagents and stale identities.',
+      },
+    ],
+  },
   {
     key: 'apiProxy',
     summary: 'Root interface of the unified API.',
@@ -1774,79 +1847,6 @@ export const SERVICE_API: readonly ServiceApiEntry[] = [
       },
     ],
   },
-  {
-    key: 'teams',
-    summary: 'Agent Teams service backed by the exact live Lead Session log.',
-    description: 'Agent Teams service backed by the exact live Lead Session log.',
-    methods: [
-      {
-        signature: 'membership(agent: Agent): TeamMembership',
-        description: 'Resolve one exact live Agent\'s Team role.',
-        parameters: [{ name: 'agent', description: 'exact live Agent used as the authority credential.' }],
-        returns: 'its root, Team identity, role, and model-facing name.',
-      },
-      {
-        signature: 'listMembers(agent: Agent): TeamMemberView[]',
-        description: 'List the runtime-enriched roster visible to one Team member.',
-        parameters: [{ name: 'agent', description: 'exact live Team member.' }],
-        returns: 'Lead and teammate rows in creation order.',
-      },
-      {
-        signature: 'async spawnTeammate(caller: Agent, request: SpawnTeammateRequest): Promise<SpawnTeammateResult>',
-        description: 'Create one named, continuable direct child of the Team Lead.',
-        parameters: [{ name: 'caller', description: 'exact live Lead Agent.' }, { name: 'request', description: 'immutable name, description, prompt, context mode, provider, and cancellation.' }],
-        returns: 'the active roster row.',
-      },
-      {
-        signature: 'async sendMessage(caller: Agent, request: SendTeamMessageRequest): Promise<SendTeamMessageResult>',
-        description: 'Queue one durable peer message, then attempt immediate delivery.',
-        parameters: [{ name: 'caller', description: 'exact live sending Team member.' }, { name: 'request', description: 'target name, content, scheduling mode, and pre-queue cancellation.' }],
-        returns: 'durable message identity and immediate-delivery observation.',
-      },
-      {
-        signature: 'async createTask(caller: Agent, request: CreateTeamTaskRequest): Promise<TeamTaskView>',
-        description: 'Create one unowned pending task in the Team Lead log.',
-        parameters: [{ name: 'caller', description: 'exact live Team member creating the task.' }, { name: 'request', description: 'task text, blockers, and advisory write scopes.' }],
-        returns: 'the revision-one task view.',
-      },
-      {
-        signature: 'getTask(caller: Agent, id: TeamTaskId): TeamTaskView',
-        description: 'Return one task, including a deleted tombstone.',
-        parameters: [{ name: 'caller', description: 'exact live Team member reading the task.' }, { name: 'id', description: 'Team-local task identity.' }],
-        returns: 'the latest task value and derived readiness diagnostics.',
-      },
-      {
-        signature: 'listTasks(caller: Agent): TeamTaskView[]',
-        description: 'List current non-deleted tasks in numeric creation order.',
-        parameters: [{ name: 'caller', description: 'exact live Team member reading the board.' }],
-        returns: 'detached current task views.',
-      },
-      {
-        signature: 'async updateTask(caller: Agent, request: UpdateTeamTaskRequest): Promise<TeamTaskView>',
-        description: 'Compare-and-set one authorized task transition.',
-        parameters: [{ name: 'caller', description: 'exact live Team member authorizing the mutation.' }, { name: 'request', description: 'task identity, expected revision, action, and action fields.' }],
-        returns: 'the committed next task revision.',
-      },
-      {
-        signature: 'async waitForChange(caller: Agent, timeoutMs: number, signal: AbortSignal): Promise<TeamWaitResult>',
-        description: 'Wait for the next Team-domain or member-status change.',
-        parameters: [{ name: 'caller', description: 'exact live Team member waiting for activity.' }, { name: 'timeoutMs', description: 'bounded wait duration from ten seconds through one hour.' }, { name: 'signal', description: 'caller cancellation for the wait only.' }],
-        returns: 'one observed change or a timeout result.',
-      },
-      {
-        signature: 'interrupt(caller: Agent, targetName: string): { previousStatus: \'running\' | \'idle\' | \'inactive\' }',
-        description: 'Interrupt one live teammate turn without clearing its pending inbox.',
-        parameters: [{ name: 'caller', description: 'exact live Lead Agent.' }, { name: 'targetName', description: 'durable teammate name.' }],
-        returns: 'the target status sampled before cancellation.',
-      },
-      {
-        signature: 'tryMembership(agent: Agent): TeamMembership | undefined',
-        description: 'Resolve a caller without throwing, used by scoped-tool installation and observers.',
-        parameters: [{ name: 'agent', description: 'candidate exact live Agent.' }],
-        returns: 'Team membership, or undefined for non-Team subagents and stale identities.',
-      },
-    ],
-  },
   {
     key: 'terminals',
     summary: 'In-process registry for replaceable PTY backends and exact-Agent sessions.',

+ 11 - 11
pnpm-lock.yaml

@@ -484,6 +484,12 @@ importers:
       '@deepseek-ai/dsh-e2b':
         specifier: workspace:*
         version: link:../packages/e2b/e2b
+      '@deepseek-ai/dsh-experimental-agent-team':
+        specifier: workspace:*
+        version: link:../packages/experimental/agent-team
+      '@deepseek-ai/dsh-experimental-tool-agent-team':
+        specifier: workspace:*
+        version: link:../packages/experimental/tool-agent-team
       '@deepseek-ai/dsh-fs-e2b':
         specifier: workspace:*
         version: link:../packages/e2b/fs-e2b
@@ -643,9 +649,6 @@ importers:
       '@deepseek-ai/dsh-system-prompt':
         specifier: workspace:*
         version: link:../packages/core/system-prompt
-      '@deepseek-ai/dsh-team':
-        specifier: workspace:*
-        version: link:../packages/experimental/team
       '@deepseek-ai/dsh-terminal':
         specifier: workspace:*
         version: link:../packages/terminal/terminal
@@ -715,9 +718,6 @@ importers:
       '@deepseek-ai/dsh-tool-subagent-report':
         specifier: workspace:*
         version: link:../packages/subagent/tool-subagent-report
-      '@deepseek-ai/dsh-tool-team':
-        specifier: workspace:*
-        version: link:../packages/experimental/tool-team
       '@deepseek-ai/dsh-tool-terminal':
         specifier: workspace:*
         version: link:../packages/terminal/tool-terminal
@@ -4081,7 +4081,7 @@ importers:
         specifier: workspace:^
         version: link:../../runtime-diagnostics/invariants
 
-  packages/experimental/team:
+  packages/experimental/agent-team:
     dependencies:
       '@deepseek-ai/schemastery':
         specifier: link:../../../vendor/schemastery
@@ -4133,7 +4133,7 @@ importers:
         specifier: workspace:^
         version: link:../../subagent/subagent-spawn-in-process
 
-  packages/experimental/tool-team:
+  packages/experimental/tool-agent-team:
     dependencies:
       '@deepseek-ai/schemastery':
         specifier: link:../../../vendor/schemastery
@@ -4151,6 +4151,9 @@ importers:
       '@deepseek-ai/dsh-agent-loop-testkit':
         specifier: workspace:^
         version: link:../../test-support/agent-loop-testkit
+      '@deepseek-ai/dsh-experimental-agent-team':
+        specifier: workspace:^
+        version: link:../agent-team
       '@deepseek-ai/dsh-invariants':
         specifier: workspace:^
         version: link:../../runtime-diagnostics/invariants
@@ -4175,9 +4178,6 @@ importers:
       '@deepseek-ai/dsh-system-prompt':
         specifier: workspace:^
         version: link:../../core/system-prompt
-      '@deepseek-ai/dsh-team':
-        specifier: workspace:^
-        version: link:../team
       '@deepseek-ai/dsh-tool-subagent-control':
         specifier: workspace:^
         version: link:../../subagent/tool-subagent-control

+ 18 - 9
scripts/check-workspace-constraints.spec.ts

@@ -9,18 +9,27 @@ import {
 
 const experimental: WorkspaceManifest = {
   dir: 'packages/experimental/prototype',
-  manifest: { name: '@deepseek-ai/dsh-prototype', private: true },
+  manifest: { name: '@deepseek-ai/dsh-experimental-prototype', private: true },
 }
 
 describe('experimental workspace constraints', () => {
+  it('requires the experimental package-name prefix', () => {
+    expect(checkExperimentalManifest({
+      ...experimental,
+      manifest: { ...experimental.manifest, name: '@deepseek-ai/dsh-prototype' },
+    })).toEqual([
+      '@deepseek-ai/dsh-prototype: experimental package name must start with "@deepseek-ai/dsh-experimental-"',
+    ])
+  })
+
   it('requires private manifests without publication metadata', () => {
     expect(checkExperimentalManifest(experimental)).toEqual([])
     expect(checkExperimentalManifest({
       ...experimental,
       manifest: { ...experimental.manifest, private: false, publishConfig: { access: 'public' } },
     })).toEqual([
-      '@deepseek-ai/dsh-prototype: experimental package must set "private": true',
-      '@deepseek-ai/dsh-prototype: experimental package must omit publishConfig',
+      '@deepseek-ai/dsh-experimental-prototype: experimental package must set "private": true',
+      '@deepseek-ai/dsh-experimental-prototype: experimental package must omit publishConfig',
     ])
   })
 
@@ -31,10 +40,10 @@ describe('experimental workspace constraints', () => {
         dir: 'packages/core/consumer',
         manifest: {
           name: '@deepseek-ai/dsh-consumer',
-          [section]: { '@deepseek-ai/dsh-prototype': 'workspace:^' },
+          [section]: { '@deepseek-ai/dsh-experimental-prototype': 'workspace:^' },
         },
       }])).toEqual([
-        `@deepseek-ai/dsh-consumer: ${section}.@deepseek-ai/dsh-prototype must not reference an experimental package`,
+        `@deepseek-ai/dsh-consumer: ${section}.@deepseek-ai/dsh-experimental-prototype must not reference an experimental package`,
       ])
     },
   )
@@ -44,24 +53,24 @@ describe('experimental workspace constraints', () => {
       dir: 'packages/core/test-only',
       manifest: {
         name: '@deepseek-ai/dsh-test-only',
-        devDependencies: { '@deepseek-ai/dsh-prototype': 'workspace:^' },
+        devDependencies: { '@deepseek-ai/dsh-experimental-prototype': 'workspace:^' },
       },
     }, {
       dir: 'packages/experimental/consumer',
       manifest: {
         name: '@deepseek-ai/dsh-experimental-consumer',
-        dependencies: { '@deepseek-ai/dsh-prototype': 'workspace:^' },
+        dependencies: { '@deepseek-ai/dsh-experimental-prototype': 'workspace:^' },
       },
     }, {
       dir: 'python/sdk-runtime',
       manifest: {
         name: '@deepseek-ai/dsh-python-runtime',
-        dependencies: { '@deepseek-ai/dsh-prototype': 'workspace:^' },
+        dependencies: { '@deepseek-ai/dsh-experimental-prototype': 'workspace:^' },
       },
     }]
 
     expect(checkExperimentalDependencyIsolation(manifests)).toEqual([
-      '@deepseek-ai/dsh-python-runtime: dependencies.@deepseek-ai/dsh-prototype must not reference an experimental package',
+      '@deepseek-ai/dsh-python-runtime: dependencies.@deepseek-ai/dsh-experimental-prototype must not reference an experimental package',
     ])
   })
 })

+ 5 - 0
scripts/check-workspace-constraints.ts

@@ -50,6 +50,8 @@ const repositoryUrl = 'git+https://github.com/deepseek-harness/deepseek-harness.
 const publishedRepositoryUrl = 'git+https://github.com/deepseek-ai/deepseek-harness.git'
 /** Private packages that participate in workspace checks but not releases. */
 const experimentalPackageDirectory = /^packages\/experimental\/[^/]+$/
+/** npm namespace reserved for private experimental packages. */
+const experimentalPackageNamePrefix = '@deepseek-ai/dsh-experimental-'
 /** Directories whose packages this repository publishes: one release member each. */
 const releaseMemberDirectory = /^(?:packages\/(?!experimental\/)[^/]+\/[^/]+|apps\/[^/]+|vendor\/[^/]+)$/
 
@@ -244,6 +246,9 @@ export function checkExperimentalManifest({ dir, manifest }: WorkspaceManifest):
   if (!experimentalPackageDirectory.test(dir)) return []
   const label = manifest.name ?? dir
   const errors: string[] = []
+  if (manifest.name?.startsWith(experimentalPackageNamePrefix) !== true) {
+    errors.push(`${label}: experimental package name must start with ${JSON.stringify(experimentalPackageNamePrefix)}`)
+  }
   if (manifest.private !== true) errors.push(`${label}: experimental package must set "private": true`)
   if (manifest.publishConfig !== undefined) errors.push(`${label}: experimental package must omit publishConfig`)
   return errors

+ 13 - 13
scripts/gen-cordis-catalog.ts

@@ -98,7 +98,7 @@ export const SERVICE_PAGE: Record<string, string> = {
   systemPrompt: 'system-prompt.md',
   jobs: 'jobs.md',
   sessionTelemetry: 'session-telemetry.md',
-  teams: 'team.md',
+  agentTeams: 'agent-team.md',
   tokenMeter: 'token-meter.md',
   toolResultPruner: 'compaction.md',
   tools: 'tools.md',
@@ -428,18 +428,18 @@ export const LINK_MAP: Readonly<Record<string, string>> = {
   JobSnapshot: 'jobs.md',
   JobStart: 'jobs.md',
   JobsChangedListener: 'jobs.md',
-  CreateTeamTaskRequest: 'team.md',
-  SendTeamMessageRequest: 'team.md',
-  SendTeamMessageResult: 'team.md',
-  SpawnTeammateRequest: 'team.md',
-  SpawnTeammateResult: 'team.md',
-  TeamId: 'team.md',
-  TeamMemberView: 'team.md',
-  TeamMembership: 'team.md',
-  TeamTaskId: 'team.md',
-  TeamTaskView: 'team.md',
-  TeamWaitResult: 'team.md',
-  UpdateTeamTaskRequest: 'team.md',
+  CreateTeamTaskRequest: 'agent-team.md',
+  SendTeamMessageRequest: 'agent-team.md',
+  SendTeamMessageResult: 'agent-team.md',
+  SpawnTeammateRequest: 'agent-team.md',
+  SpawnTeammateResult: 'agent-team.md',
+  TeamId: 'agent-team.md',
+  TeamMemberView: 'agent-team.md',
+  TeamMembership: 'agent-team.md',
+  TeamTaskId: 'agent-team.md',
+  TeamTaskView: 'agent-team.md',
+  TeamWaitResult: 'agent-team.md',
+  UpdateTeamTaskRequest: 'agent-team.md',
   TokenMeasurement: 'token-meter.md',
   CodeDispatchLog: 'tools.md',
   PostToolDecision: 'tools.md',

+ 4 - 4
scripts/gen-doc-graphs.ts

@@ -479,12 +479,12 @@ const SERVICE_ROLES: ServiceRole[] = [
     note: 'Providers implement transports; the service also owns optional Activation-based continuation orchestration, tool-subagent selects one-shot or continuable delegation, tool-subagent-control delivers follow-ups, and tool-ralph requires one fresh structured-output route.',
   },
   {
-    key: 'teams',
-    pkg: 'team',
+    key: 'agentTeams',
+    pkg: 'agent-team',
     title: 'Agent Teams coordination domain',
     mode: 'core',
-    consumers: ['tool-team'],
-    note: 'Owns the implicit-root roster, durable peer mailbox, shared task DAG, and continuable-child lifecycle; tool-team contributes the scoped model policy and controls.',
+    consumers: ['tool-agent-team'],
+    note: 'Owns the implicit-root roster, durable peer mailbox, shared task DAG, and continuable-child lifecycle; tool-agent-team contributes the scoped model policy and controls.',
   },
   {
     key: 'jobs',

+ 5 - 5
scripts/gen-persistence-catalog.ts

@@ -52,11 +52,11 @@ const LINK_MAP: Record<string, string> = {
   SessionTitleModelProvenance: 'session-title.md',
   SessionTitleProviderId: 'session-title.md',
   SessionTitleSource: 'session-title.md',
-  TeamId: 'team.md',
-  TeamMemberSnapshot: 'team.md',
-  TeamMessageId: 'team.md',
-  TeamMessageSnapshot: 'team.md',
-  TeamTaskSnapshot: 'team.md',
+  TeamId: 'agent-team.md',
+  TeamMemberSnapshot: 'agent-team.md',
+  TeamMessageId: 'agent-team.md',
+  TeamMessageSnapshot: 'agent-team.md',
+  TeamTaskSnapshot: 'agent-team.md',
 }
 
 /** One log event, extracted from a `SessionEventMap` declaration. */

+ 8 - 8
scripts/gen-tool-catalog.ts

@@ -58,8 +58,8 @@ import * as ToolLsp from '@deepseek-ai/dsh-tool-lsp'
 import * as ToolSkill from '@deepseek-ai/dsh-tool-skill'
 import * as ToolSessionQuery from '@deepseek-ai/dsh-tool-session-query'
 import * as ToolTasks from '@deepseek-ai/dsh-tool-jobs'
-import type TeamService from '@deepseek-ai/dsh-team'
-import * as ToolTeam from '@deepseek-ai/dsh-tool-team'
+import type TeamService from '@deepseek-ai/dsh-experimental-agent-team'
+import * as ToolTeam from '@deepseek-ai/dsh-experimental-tool-agent-team'
 import * as ToolTodo from '@deepseek-ai/dsh-tool-todo'
 import * as ToolSubagent from '@deepseek-ai/dsh-tool-subagent'
 import * as ToolWeb from '@deepseek-ai/dsh-tool-web'
@@ -524,10 +524,10 @@ const TOOL_PACKAGES: ToolPackage[] = [
       'The kind-agnostic background-job controller: background bash commands, PTY sends, and subagents are read, listed, and killed through the same three tools. Loading the plugin attaches the controller that arms producers\' `ctx.jobs.start()`.',
   },
   {
-    pkg: '@deepseek-ai/dsh-tool-team',
-    dir: 'tool-team',
-    source: 'packages/experimental/tool-team/src/index.ts',
-    requires: ['ctx.tools', 'ctx.systemPrompt', 'ctx.teams', 'an exact live Team member Agent'],
+    pkg: '@deepseek-ai/dsh-experimental-tool-agent-team',
+    dir: 'tool-agent-team',
+    source: 'packages/experimental/tool-agent-team/src/index.ts',
+    requires: ['ctx.tools', 'ctx.systemPrompt', 'ctx.agentTeams', 'an exact live Team member Agent'],
     writes: ['tool/call', 'team/member', 'team/message/queued', 'team/message/delivered', 'team/task', 'tool/result'],
     async mount(ctx) {
       await ctx.plugin(AgentRegistry)
@@ -540,7 +540,7 @@ const TOOL_PACKAGES: ToolPackage[] = [
         role: 'lead' as const,
         name: 'lead',
       }
-      ctx.provide('teams', {
+      ctx.provide('agentTeams', {
         tryMembership: (candidate: Agent) => candidate === agent ? membership : undefined,
         membership: () => membership,
       } as unknown as TeamService)
@@ -553,7 +553,7 @@ const TOOL_PACKAGES: ToolPackage[] = [
         } as unknown as Agent
         Object.assign(agent, { ctx: createScope(inner, agent).ctx })
         inner.agents.register(agent)
-      }, { inject: ['tools', 'systemPrompt', 'agents', 'teams'] }))
+      }, { inject: ['tools', 'systemPrompt', 'agents', 'agentTeams'] }))
       await ctx.plugin(ToolTeam)
       catalogChildScopes.set(ctx, agent)
     },

+ 58 - 7
scripts/release/bump.ts

@@ -3,7 +3,8 @@
  * readable from the repository rather than derived inside CI
  * ([rationale](../../.agents/notes/implemented/process/2026-08-10-npm-release-sequences.md)).
  *
- * The dsh family shares one version across its members and the workspace root:
+ * The dsh family shares one version across its publishable members, private
+ * package manifests, and the workspace root:
  * `major`, `minor`, `patch`, or an explicit `x.y.z` (including a prerelease such
  * as `0.0.1-rc.1`). The vendored family has one version line per package, but
  * every release advances and publishes the complete family so the next release
@@ -14,7 +15,7 @@
  * the tag after the commit merges. CI never writes to the repository.
  */
 
-import { readFileSync, writeFileSync } from 'node:fs'
+import { globSync, readFileSync, writeFileSync } from 'node:fs'
 import { join, matchesGlob } from 'node:path'
 import { parseArgs } from 'node:util'
 import { releaseFamily, type ReleaseFamily, type ReleaseMember } from './families.ts'
@@ -47,10 +48,20 @@ interface PlannedVersion {
   readonly from: string
   /** The version to write. */
   readonly to: string
-  /** The tag this version publishes from, or undefined for the workspace root. */
+  /** The tag this version publishes from, or undefined for a non-published manifest. */
   readonly tag: string | undefined
 }
 
+/** One private dsh package whose version follows the publishable family. */
+interface PrivateDshVersion {
+  /** Repository-relative manifest path. */
+  readonly manifestPath: string
+  /** Package directory used in bump output. */
+  readonly label: string
+  /** Current manifest version. */
+  readonly version: string
+}
+
 /**
  * Split a version into its release numbers, discarding any prerelease segment.
  * @param version - the current version.
@@ -236,14 +247,43 @@ function rootVersion(root: string): string {
 }
 
 /**
- * Plan the dsh family's rewrite: one version for every member and the root.
+ * Discover private package manifests that share the dsh version without joining
+ * its publish set.
+ * @param root - repository root.
+ * @returns Private package manifests sorted by path.
+ */
+function privateDshVersions(root: string): PrivateDshVersion[] {
+  return globSync('packages/*/*/package.json', { cwd: root })
+    .map(path => path.replaceAll('\\', '/'))
+    .sort()
+    .flatMap((manifestPath) => {
+      const parsed: unknown = JSON.parse(readFileSync(join(root, manifestPath), 'utf8'))
+      if (parsed === null || typeof parsed !== 'object' || Array.isArray(parsed)) {
+        throw new Error(`${manifestPath} is not a JSON object`)
+      }
+      const manifest = parsed as Record<string, unknown>
+      if (manifest.private !== true) return []
+      if (typeof manifest.version !== 'string') {
+        throw new Error(`${manifestPath} must declare a string version`)
+      }
+      return [{
+        manifestPath,
+        label: manifestPath.slice(0, -'/package.json'.length),
+        version: manifest.version,
+      }]
+    })
+}
+
+/**
+ * Plan the dsh family's rewrite: one version for every publishable member,
+ * private package, and the root.
  * @param family - the dsh family.
  * @param root - repository root.
  * @param members - the family's members.
  * @param request - `major`, `minor`, `patch`, or an explicit version.
  * @returns The manifests to rewrite and the shared target version.
  */
-function planShared(
+export function planShared(
   family: ReleaseFamily,
   root: string,
   members: readonly ReleaseMember[],
@@ -259,13 +299,24 @@ function planShared(
   ]
   for (const member of members) {
     planned.push({
-      manifestPath: join(member.directory, 'package.json'),
+      manifestPath: `${member.directory}/package.json`,
       label: member.directory,
       from: member.version,
       to: version,
       tag: family.tagFor({ ...member, version }),
     })
   }
+  const publishableManifests = new Set(members.map(member => `${member.directory}/package.json`))
+  for (const entry of privateDshVersions(root)) {
+    if (publishableManifests.has(entry.manifestPath)) continue
+    planned.push({
+      manifestPath: entry.manifestPath,
+      label: entry.label,
+      from: entry.version,
+      to: version,
+      tag: undefined,
+    })
+  }
   return { planned, version }
 }
 
@@ -287,7 +338,7 @@ function planPerPackage(
     const tagged = lastTaggedVersion(family, member)
     const to = nextVendorVersion(member.version, tagged, prerelease)
     planned.push({
-      manifestPath: join(member.directory, 'package.json'),
+      manifestPath: `${member.directory}/package.json`,
       label: member.directory,
       from: member.version,
       to,

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

@@ -6,7 +6,7 @@ import { dirname, join, resolve } from 'node:path'
 import { afterEach, describe, expect, it, vi } from 'vitest'
 import { officialClientBuildEnvironment, writeClientBuildRecord } from '../client-build-environment.ts'
 import { releaseFamily, type ReleaseMember } from './families.ts'
-import { compareVersions, nextVendorVersion, reachesPayload } from './bump.ts'
+import { compareVersions, nextVendorVersion, planShared, reachesPayload } from './bump.ts'
 
 /**
  * A release member standing in for a manifest on disk.
@@ -45,7 +45,25 @@ describe('release families', () => {
     const members = releaseFamily('dsh').members(resolve(import.meta.dirname, '../..'))
 
     expect(members.some(member => member.directory.startsWith('packages/experimental/'))).toBe(false)
-    expect(members.map(member => member.name)).not.toContain('@deepseek-ai/dsh-team')
+    expect(members.map(member => member.name)).not.toContain('@deepseek-ai/dsh-experimental-agent-team')
+  })
+
+  it('bumps private dsh packages without adding release tags', () => {
+    const root = mkdtempSync(join(tmpdir(), 'dsh-release-version-'))
+    roots.push(root)
+    write(join(root, 'package.json'), '{"version":"0.0.1"}\n')
+    write(join(root, 'packages/experimental/prototype/package.json'), '{"version":"0.0.1","private":true}\n')
+    write(join(root, 'packages/core/unselected/package.json'), '{"version":"0.0.1"}\n')
+
+    const dsh = releaseFamily('dsh')
+    const published = member('packages/core/published', '@deepseek-ai/dsh-published')
+    const { planned } = planShared(dsh, root, [published], '0.0.2')
+
+    expect(planned.map(entry => ({ path: entry.manifestPath, tag: entry.tag }))).toEqual([
+      { path: 'package.json', tag: undefined },
+      { path: 'packages/core/published/package.json', tag: 'dsh-v0.0.2' },
+      { path: 'packages/experimental/prototype/package.json', tag: undefined },
+    ])
   })
 
   it('names one tag for the whole dsh family and one per vendored package', () => {

+ 8 - 8
scripts/type-equiv.manifest.json

@@ -302,24 +302,24 @@
       "source": "packages/schedule/schedule/src/types.ts"
     },
     {
-      "doc": "docs/subsystems/team.md",
+      "doc": "docs/subsystems/agent-team.md",
       "symbol": "TeamMemberSnapshot",
-      "source": "packages/experimental/team/src/types.ts"
+      "source": "packages/experimental/agent-team/src/types.ts"
     },
     {
-      "doc": "docs/subsystems/team.md",
+      "doc": "docs/subsystems/agent-team.md",
       "symbol": "TeamMessageSnapshot",
-      "source": "packages/experimental/team/src/types.ts"
+      "source": "packages/experimental/agent-team/src/types.ts"
     },
     {
-      "doc": "docs/subsystems/team.md",
+      "doc": "docs/subsystems/agent-team.md",
       "symbol": "TeamMessageSource",
-      "source": "packages/experimental/team/src/types.ts"
+      "source": "packages/experimental/agent-team/src/types.ts"
     },
     {
-      "doc": "docs/subsystems/team.md",
+      "doc": "docs/subsystems/agent-team.md",
       "symbol": "TeamTaskSnapshot",
-      "source": "packages/experimental/team/src/types.ts"
+      "source": "packages/experimental/agent-team/src/types.ts"
     },
     {
       "doc": "docs/subsystems/commands.md",

+ 4 - 0
tsconfig.base.json

@@ -101,6 +101,8 @@
       "@deepseek-ai/dsh-agent/invariant": ["./packages/core/agent/src/invariant.ts"],
       "@deepseek-ai/dsh-scope/invariant": ["./packages/core/scope/src/invariant.ts"],
       "@deepseek-ai/dsh-agent-loop/invariant": ["./packages/core/agent-loop/src/invariant.ts"],
+      "@deepseek-ai/dsh-experimental-agent-team/invariant": ["./packages/experimental/agent-team/src/invariant.ts"],
+      "@deepseek-ai/dsh-experimental-tool-agent-team/invariant": ["./packages/experimental/tool-agent-team/src/invariant.ts"],
       "@deepseek-ai/dsh-*/invariant": [
         "./packages/core/*/src/invariant.ts",
         "./packages/prompt/*/src/invariant.ts",
@@ -232,6 +234,8 @@
       "@deepseek-ai/dsh-sdk-client": ["./packages/sdk/client/src"],
       "@deepseek-ai/dsh-sdk-protocol": ["./packages/sdk/protocol/src"],
       "@deepseek-ai/dsh-sdk-jsonrpc-server": ["./packages/sdk/server/src"],
+      "@deepseek-ai/dsh-experimental-agent-team": ["./packages/experimental/agent-team/src"],
+      "@deepseek-ai/dsh-experimental-tool-agent-team": ["./packages/experimental/tool-agent-team/src"],
       "@deepseek-ai/dsh-*": [
         "./packages/core/*/src",
         "./packages/prompt/*/src",

+ 2 - 2
tsconfig.host.json

@@ -275,8 +275,8 @@
     { "path": "./packages/jobs/jobs" },
     { "path": "./packages/jobs/jobs-local" },
     { "path": "./packages/jobs/tool-jobs" },
-    { "path": "./packages/experimental/team" },
-    { "path": "./packages/experimental/tool-team" },
+    { "path": "./packages/experimental/agent-team" },
+    { "path": "./packages/experimental/tool-agent-team" },
     { "path": "./packages/workflow/workflow" },
     { "path": "./packages/workflow/workflow-worker-thread" },
     { "path": "./packages/workflow/tool-workflow" },