Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
41 commits
Select commit Hold shift + click to select a range
c46c285
feat: setup 自动登记 Console 工作区
Dandre126 Aug 4, 2026
94b10a2
feat: 优化首页编码工具引导
Dandre126 Aug 4, 2026
b0bbc68
feat: 支持 Codex 与 Claude 桌面版
Dandre126 Aug 4, 2026
f5cd7f2
feat: 优化 Dyro 引导与控制台体验
Dandre126 Aug 4, 2026
d00d5ca
feat: 完善首次设置个人偏好引导
Dandre126 Aug 4, 2026
41a8276
feat: 建立 Agent Bridge 只读基础能力
Dandre126 Aug 6, 2026
f30edb9
feat: 实现 Agent Bridge 确定性计划
Dandre126 Aug 6, 2026
6a9e7ed
fix: 收紧 Agent Bridge Git 配置边界
Dandre126 Aug 6, 2026
2787921
feat: 实现 Agent Bridge 严格传输边界
Dandre126 Aug 6, 2026
e7e1225
feat: 完善 Agent Bridge 外部能力与安全门禁
Dandre126 Aug 7, 2026
7718932
docs: 补充 Dyro 功能介绍视觉资产
Dandre126 Aug 7, 2026
e284c1c
Revert "docs: 补充 Dyro 功能介绍视觉资产"
Dandre126 Aug 7, 2026
5a7f467
fix: 修复 Agent Bridge 零副作用审计运行时路径与 fixture 契约
Dandre126 Aug 11, 2026
0c4cc7a
merge: 合并 main 并解决 cli.py 格式冲突
Dandre126 Aug 11, 2026
eb6111c
fix: 修复 Bridge CI 归档目录与版本元数据漂移
Dandre126 Aug 11, 2026
abca42c
fix: 修复 Bridge CI bind mount 与黑盒强制操作断言
Dandre126 Aug 11, 2026
f9bb14f
docs: 归档 Agent Bridge Phase 0 CI 与 host 验收证据
Dandre126 Aug 11, 2026
cc29fd6
docs: 补充 Agent Bridge F04 上下文预算证据
Dandre126 Aug 11, 2026
de6b783
docs: 记录 Agent Bridge Phase 0 最终质量门 No-Go
Dandre126 Aug 11, 2026
c329ad1
refactor: 卸掉 Ubuntu 门控 Agent Bridge 与 MCP 发布面
Dandre126 Aug 11, 2026
3d8e75f
feat: Skill 改为镜像加分身,支持多宿主安装
Dandre126 Aug 11, 2026
a450938
feat: 自定义选仓支持序号输入
Dandre126 Aug 11, 2026
c0cc8f4
fix: harden Skill legacy bounds and prep 0.6.3 release metadata
Dandre126 Aug 11, 2026
7bb8c64
docs: align Skill install note across localized READMEs
Dandre126 Aug 11, 2026
7be05c0
feat: guide and auto-repair managed Skill across setup and updates
Dandre126 Aug 11, 2026
79d18b5
merge: sync main after Skill lifecycle PR #20
Dandre126 Aug 11, 2026
92e6448
merge: sync main after 0.6.4 release metadata
Dandre126 Aug 12, 2026
98476ab
chore: 移出本地审查与会话资料
Dandre126 Aug 12, 2026
07f4d42
feat: 扩展 Dyro 只读控制面与安全边界
Dandre126 Aug 12, 2026
6d4bbac
fix: 收紧控制面隐私并优化创建确认
Dandre126 Aug 13, 2026
9d749a0
merge: sync main after 0.6.5 release metadata
Dandre126 Aug 13, 2026
b34c470
feat: 启动面支持本机已装编码工具
Dandre126 Aug 13, 2026
5535428
fix: 修正 agent discover 测试对桌面宿主的依赖
Dandre126 Aug 13, 2026
0e02266
merge: sync main after 0.6.6 release metadata
Dandre126 Aug 13, 2026
94dafa7
fix: 让裸 dyro update 确认后安装
Dandre126 Aug 13, 2026
f40d559
feat: 将 DeepSeek Harness 与 Pi 纳入编码工具目录
Dandre126 Aug 14, 2026
83d8c4f
merge: sync main after 0.6.7 release metadata
Dandre126 Aug 14, 2026
c6e06a7
test: 按 HOSTS 隔离 Skill 宿主环境变量
Dandre126 Aug 14, 2026
0bb299f
feat: 落地九路 dispatch、Batch V1 与托管 dyro-dispatch Skill
Dandre126 Aug 14, 2026
bb2bb0d
chore(发布): 准备 0.6.8
Dandre126 Aug 14, 2026
00e87e4
fix: 让 dispatch 在干净 Home 下探测环境而不依赖本机模型配置
Dandre126 Aug 14, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ jobs:
"$smoke_root/wheel-venv/bin/python" -c "import experiments.local_agent_dispatch"
"$smoke_root/wheel-venv/bin/python" -I -c "import dyro.continuation"
"$smoke_root/wheel-venv/bin/python" -I -c "from dyro.console.assets import validate_assets; validate_assets()"
"$smoke_root/wheel-venv/bin/python" -I -c "from importlib.resources import files; root=files('dyro.integrations').joinpath('assets'); assert root.joinpath('dyro-control-plane','SKILL.md').is_file(); assert root.joinpath('dyro-control-plane','agents','openai.yaml').is_file(); assert not root.joinpath('dyro-readonly').is_dir()"
"$smoke_root/wheel-venv/bin/python" -I -c "from importlib.resources import files; root=files('dyro.integrations').joinpath('assets'); assert root.joinpath('dyro-control-plane','SKILL.md').is_file(); assert root.joinpath('dyro-control-plane','agents','openai.yaml').is_file(); assert root.joinpath('dyro-dispatch','SKILL.md').is_file(); assert root.joinpath('dyro-dispatch','agents','openai.yaml').is_file(); assert not root.joinpath('dyro-readonly').is_dir()"
test -x "$smoke_root/wheel-venv/bin/dyro"
test ! -e "$smoke_root/wheel-venv/bin/dyro-bridge"
test ! -e "$smoke_root/wheel-venv/bin/dyro-mcp"
Expand All @@ -94,7 +94,7 @@ jobs:
"$smoke_root/sdist-venv/bin/pip" install "${sdist_artifact}"
"$smoke_root/sdist-venv/bin/python" -I -c "import dyro.continuation"
"$smoke_root/sdist-venv/bin/python" -I -c "from dyro.console.assets import validate_assets; validate_assets()"
"$smoke_root/sdist-venv/bin/python" -I -c "from importlib.resources import files; root=files('dyro.integrations').joinpath('assets'); assert root.joinpath('dyro-control-plane','SKILL.md').is_file(); assert root.joinpath('dyro-control-plane','agents','openai.yaml').is_file(); assert not root.joinpath('dyro-readonly').is_dir()"
"$smoke_root/sdist-venv/bin/python" -I -c "from importlib.resources import files; root=files('dyro.integrations').joinpath('assets'); assert root.joinpath('dyro-control-plane','SKILL.md').is_file(); assert root.joinpath('dyro-control-plane','agents','openai.yaml').is_file(); assert root.joinpath('dyro-dispatch','SKILL.md').is_file(); assert root.joinpath('dyro-dispatch','agents','openai.yaml').is_file(); assert not root.joinpath('dyro-readonly').is_dir()"
test -x "$smoke_root/sdist-venv/bin/dyro"
test ! -e "$smoke_root/sdist-venv/bin/dyro-bridge"
test ! -e "$smoke_root/sdist-venv/bin/dyro-mcp"
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/pypi-publish.yml
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,7 @@ jobs:
"$smoke_root/wheel-venv/bin/pip" install "$GITHUB_WORKSPACE"/dist/dyro-*.whl
"$smoke_root/wheel-venv/bin/python" -c "import experiments.local_agent_dispatch"
"$smoke_root/wheel-venv/bin/python" -I -c "from dyro.console.assets import validate_assets; validate_assets()"
"$smoke_root/wheel-venv/bin/python" -I -c "from importlib.resources import files; root=files('dyro.integrations').joinpath('assets'); assert root.joinpath('dyro-control-plane','SKILL.md').is_file(); assert root.joinpath('dyro-control-plane','agents','openai.yaml').is_file()"
"$smoke_root/wheel-venv/bin/python" -I -c "from importlib.resources import files; root=files('dyro.integrations').joinpath('assets'); assert root.joinpath('dyro-control-plane','SKILL.md').is_file(); assert root.joinpath('dyro-control-plane','agents','openai.yaml').is_file(); assert root.joinpath('dyro-dispatch','SKILL.md').is_file(); assert root.joinpath('dyro-dispatch','agents','openai.yaml').is_file()"
"$smoke_root/wheel-venv/bin/python" -I -c "import importlib.util; assert importlib.util.find_spec('dyro.bridge') is None"
test -x "$smoke_root/wheel-venv/bin/dyro"
test ! -e "$smoke_root/wheel-venv/bin/dyro-bridge"
Expand All @@ -155,7 +155,7 @@ jobs:
"$smoke_root/sdist-venv/bin/pip" install "$GITHUB_WORKSPACE"/dist/dyro-*.tar.gz
"$smoke_root/sdist-venv/bin/python" -c "import experiments.local_agent_dispatch"
"$smoke_root/sdist-venv/bin/python" -I -c "from dyro.console.assets import validate_assets; validate_assets()"
"$smoke_root/sdist-venv/bin/python" -I -c "from importlib.resources import files; root=files('dyro.integrations').joinpath('assets'); assert root.joinpath('dyro-control-plane','SKILL.md').is_file(); assert root.joinpath('dyro-control-plane','agents','openai.yaml').is_file()"
"$smoke_root/sdist-venv/bin/python" -I -c "from importlib.resources import files; root=files('dyro.integrations').joinpath('assets'); assert root.joinpath('dyro-control-plane','SKILL.md').is_file(); assert root.joinpath('dyro-control-plane','agents','openai.yaml').is_file(); assert root.joinpath('dyro-dispatch','SKILL.md').is_file(); assert root.joinpath('dyro-dispatch','agents','openai.yaml').is_file()"
"$smoke_root/sdist-venv/bin/python" -I -c "import importlib.util; assert importlib.util.find_spec('dyro.bridge') is None"
test -x "$smoke_root/sdist-venv/bin/dyro"
test ! -e "$smoke_root/sdist-venv/bin/dyro-bridge"
Expand Down
39 changes: 39 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,45 @@

## Unreleased

## 0.6.8 - 2026-08-15

- Fix Console inspection falsely timing out healthy workspaces by budgeting for
isolated Python process startup. Unavailable or missing workspace counts now
render as unknown instead of zero, and partial pages no longer claim that all
projects are healthy.
- Add executable dispatch adapters for Cursor Agent, OpenCode, Grok, Hermes,
Kimi, DeepSeek Harness (`dsh`), and Pi alongside Codex and Claude. Every
adapter now has bounded process supervision, an explicit read/edit tool or
sandbox policy, a backend-specific authentication probe, and a structured
result decoder. Cursor dispatch intentionally requires `CURSOR_API_KEY` so
it can run with an isolated home instead of loading user MCP processes;
Cursor edit dispatch remains fail-closed until its sandbox process lifecycle
can be proven. Provider credentials are scoped to the selected model, and
successful-looking CLIs cannot leave closed-stdio descendants running.
Hermes receives only projected task context: user rules, identity, memory,
fallback providers, background review, and session persistence are disabled.
Pi requires Node.js 22.19.0 or newer.
- Preserve a multi-harness panel board when one member fails instead of losing
the other members' terminal results; deduplicate and cap explicit members,
and let every ready integrated Provider participate in selection. Default
panels remain a cost-bounded three-Provider sample; explicit `--members all`
runs every ready Provider with at most four concurrent members.
- Add the separately managed `dyro-dispatch` Skill for explicit parallel,
delegated, and independent-agent work. It installs through
`dyro integration install dispatch`, keeps outbound Provider effects separate
from the read-only control plane, and preserves all gate, signoff, merge, and
push boundaries. A single setup opt-in now installs both first-party Skills;
existing managed control-plane installs automatically gain Dispatch, and both
stay synchronized across interactive launches and package updates.
- Add persistent Batch V1 orchestration for two to four heterogeneous roles:
side-effect-free planning, digest-bound idempotent start, compact status,
bounded partial-result recovery, and cooperative cancellation. Plans bind
Provider choices, guarded context, timeouts, and edit HEAD; all members pass
preflight before any Provider starts, at most one may edit, and cleanup that
cannot be proven remains visible instead of being reported as cancelled.
Workers revalidate planned context immediately before Provider use, and edit
worktrees are pinned to the reviewed object ID.

## 0.6.7 - 2026-08-13

- Make bare `dyro update` check, confirm, and install (same path as
Expand Down
24 changes: 19 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -283,11 +283,25 @@ To upgrade later, run `pipx upgrade dyro`. If your team manages Python packages
python3 -m pip install --user --upgrade dyro
```

Interactive `dyro setup` can install the control-plane Skill during personal
preferences. After package updates, already-managed Skills sync automatically;
interactive launches also repair an outdated managed Skill. First-time install
remains opt-in via setup or `dyro integration install skill --yes` (alias:
`codex`).
Interactive `dyro setup` can install the first-party Skill bundle during personal
preferences. That one opt-in installs both `dyro-control-plane` and the separate
`dyro-dispatch` Skill. Existing managed control-plane installations automatically
gain the Dispatch companion on the next interactive launch or package refresh, and
both managed Skills then stay synchronized with Dyro updates. Machines that have
never opted into a Dyro Skill are not modified silently.

Multi-harness delegation remains separate from the read-only control plane so its
process/network effects are explicit. Manual installation is still available:
preview with `dyro integration install dispatch --dry-run`, then install with
`dyro integration install dispatch --yes`.

For two to four different roles, `dyro dispatch batch-plan` produces a
side-effect-free, context-bound plan. Review its digest before
`batch-start --expect-plan-sha256 …`, then recover through `batch-status`,
`batch-result`, or `batch-cancel`. Batch V1 is independent fan-out with at most
one edit writer; it is not a dependency DAG, retry queue, or automatic judge.
Use explicit synchronous `panel --members all` only for a full-ready-Provider
same-task comparison.

Interactive `dyro`, `dyro home`, and `dyro start` launches check the official
PyPI endpoint at most once per local day. A failed or slow check never blocks
Expand Down
17 changes: 14 additions & 3 deletions README.zh-CN.md
Original file line number Diff line number Diff line change
Expand Up @@ -281,9 +281,20 @@ dyro --version
python3 -m pip install --user --upgrade dyro
```

交互式 `dyro setup` 可在个人偏好步骤安装控制面 Skill。包升级后会自动同步**已托管**
的 Skill;交互启动时也会修复过期的托管安装。首次安装仍需 setup 勾选,或手动运行
`dyro integration install skill --yes`(别名 `codex`)。
交互式 `dyro setup` 可在个人偏好步骤一次启用第一方 Skill 套件,同时安装
`dyro-control-plane` 与独立的 `dyro-dispatch`。已经托管控制面 Skill 的用户会在下次
交互启动或包更新后自动补装 Dispatch,此后两项都会随 Dyro 自动同步;从未启用过
Dyro Skill 的机器不会被后台静默写入。

多 Harness 委派仍与只读控制面隔离,确保 Provider 进程与网络副作用需要明确请求。
也可手动运行 `dyro integration install dispatch --dry-run` 预览,再用
`dyro integration install dispatch --yes` 安装。

需要 2–4 个不同角色时,先用 `dyro dispatch batch-plan` 生成不创建状态、绑定
上下文的计划;审阅摘要后再执行 `batch-start --expect-plan-sha256 …`,随后可用
`batch-status`、`batch-result` 或 `batch-cancel` 恢复生命周期。Batch V1 是最多
一个编辑者的独立 fan-out,并非依赖 DAG、重试队列或自动终裁器。只有用户明确要求
全 Harness 同题比较时,才使用同步的 `panel --members all`。

交互运行 `dyro`、`dyro home` 或 `dyro start` 时,Dyro 每个本地自然日最多访问一次官方 PyPI;断网、超时或状态目录不可写都不会阻塞进入工作区。默认仍由用户确认更新:

Expand Down
8 changes: 5 additions & 3 deletions docs/designs/local-web-console.md
Original file line number Diff line number Diff line change
Expand Up @@ -226,8 +226,9 @@ C04 将真实工作区读取移出 HTTP 请求线程,并补齐概览的单工
- `create_console_http_server()` 默认装配 `IsolatedOverviewService` IPC client。它以固定 `python -m`
argv、最小环境和新 session 启动 inspection process;worker 不继承 bearer、bootstrap、编码工具
配置或其它宿主环境值,异常 stderr 不会进入 API;
- inspection outer worker 对单次请求施加 5 秒硬 deadline。它在内部最多运行 4 个 daemon 子进程,
每个 workspace 750ms;超时或崩溃只返回该 workspace 的 `unavailable`/`WORKSPACE_TIMEOUT` 卡片,
- inspection outer worker 对单次请求施加 8 秒硬 deadline。它在内部最多运行 4 个 daemon 子进程,
每个 workspace 3 秒、整页内部采集最多 6 秒;超时或崩溃只返回该 workspace 的
`unavailable`/`WORKSPACE_TIMEOUT` 卡片,
并在父 deadline 后终止整个 process group;
- 当前 process-tree 回收仅在 POSIX 平台启用;Windows 在具备经验证的 Job Object 回收实现前对
inspection fail closed,不会以“只终止 outer process”的方式留下读取子进程;
Expand Down Expand Up @@ -591,7 +592,8 @@ CLI Browser Server

- registry 结构损坏是一个全局 `registry_unavailable` 状态;Console 保持可打开并提供恢复说明,但绝不覆盖文件。
- Profile 或 Objective 损坏只影响对应 workspace card。
- summary 默认最多 4 个 workspace 并行读取,单 workspace 预算 750 ms,总预算 5 秒。
- summary 默认最多 4 个 workspace 并行读取,单 workspace 预算 3 秒,内部总预算 6 秒,外层
inspection process group 硬预算 8 秒。该预算包含隔离 Python 子进程的启动成本。
- detail 中每个 Git 子进程必须传显式 timeout;超时转换为 `GIT_PROBE_TIMEOUT`。
- HTTP 主进程把 registry 和 workspace inspection 交给 `exec` 启动的内部 worker process;父进程
使用单调时钟硬 deadline、有界队列和最多 4 个 worker。协作式 cancellation 只用于普通步骤,
Expand Down
49 changes: 44 additions & 5 deletions docs/designs/optional-local-agent-dispatch.md
Original file line number Diff line number Diff line change
Expand Up @@ -191,7 +191,7 @@ DetachedWorker
## 9. 异步生命周期与并发

```text
accepted → running → completed|failed|timeout
accepted → running → completed|failed|timeout|cancelled
lease heartbeat
```
Expand All @@ -204,7 +204,7 @@ accepted → running → completed|failed|timeout
| 租约 | `pid` + `process_started_at` + 随机 owner token;续租/释放必须匹配所有权 |
| init grace | 槽位新建后短窗口内禁止判死 |
| 僵死回收 | rename 抢占 + 删除;失败则下轮重试 |
| GC | 超龄 run、影子目录、不活跃 thread 可回收 |
| GC | 活跃/未过期 orchestration 保护成员;终态过期后与 run 一致回收,但保留 request tombstone 防重复计费 |

worker 记录会持久化 `pid + process_started_at + owner token`。短命的派发 CLI
退出后,新 Supervisor、`result --wait` 与 GC 都会重建监控:只有操作系统证明该
Expand All @@ -213,10 +213,48 @@ worker 记录会持久化 `pid + process_started_at + owner token`。短命的

相对「仅 TTL 锁」:增加 **进程启动时刻** 防 PID 复用;相对「无 grace」:避免 init 竞态误杀。

当前 `run` / `panel` / worker 的进程树监管限定 POSIX(Linux/macOS);Windows
当前 `run` / `panel` / worker 的专用进程组监管限定 POSIX(Linux/macOS)。它不是
OS 容器:主动 `setsid` 脱离该进程组的恶意后代不在终止证明内,因此真实 Provider
仍必须标记为 unconfined 并由调用方显式确认。Windows
允许导入与只读 discovery,但执行会 fail-closed,直到提供并验证 Windows 原生
process-tree 与 pipe 后端。

### 9.1 持久 Batch V1

不同角色或不同仓库切片使用独立的持久编排,而不是让宿主临时维护多个
`run_id`:

```text
batch-plan → batch-start → batch-status → batch-result
└──→ batch-cancel
```

- 请求包含 2–4 个 `strategy=independent` 成员、唯一 `role_id` 和完整
TaskContract;最多一个 edit writer。
- `batch-plan` 不创建状态,也不启动 Provider/鉴权 CLI;它只解析已安装候选。
JCS + SHA-256 摘要绑定规范化合同、canonical project root、确定的 Provider、
非秘密执行 profile(含适配器内层 Provider/model)、守卫后的 context digest、
timeout,以及 edit 成员的 Git HEAD。
- `batch-start` 必须携带已审阅摘要并重新计划;先主动验证全部登录态,再创建
状态。任何 context、HEAD 或 Provider execution profile 漂移都会拒绝启动。
全部成员预检并创建确定性 run 后才开始 Provider。
- 每个 run 继续持有 planned context digest;异步 worker 在调用 Provider 前重新
读取并核对,关闭 start 与真正执行之间的 TOCTOU。edit context 必须是已审阅
HEAD 中的 clean tracked files,detached worktree 直接固定到该 object ID。
- `request_id + plan_sha256` 确定 orchestration ID;orchestration ID + member
index 确定 run ID。相同请求和计划可幂等续建,不重复启动已运行/终态成员。
- GC 删除终态过期 manifest/run 后保留有界 request tombstone;旧
`request_id` 不得再次启动,显式的新执行必须使用新的 request ID。
- `batch-status` 只返回小型状态投影;`batch-result` 只在成员终态后聚合有界
summary/evidence/warnings/patch_ref,且不会因单个失败抹掉健康结果。
- `batch-cancel` 先持久化取消意图。accepted 成员可直接取消;running 成员由
精确 worker generation 协作终止,只有 backend cleanup 获得证明后才成为
cancelled。证明不足时保留 running/attention,不做跨进程猜测式 `killpg`。

Batch V1 不提供依赖 DAG、超过四成员的异步队列、自动 retry/resume、自动
judge 或多 edit writer。显式 `panel --members all` 仍是同步的全 ready Provider
同题比较,不能伪装成 Batch 队列。

## 10. Edit 模式:worktree + patch

1. 从当前 Git `HEAD` 创建 detached 隔离 worktree;源工作区未提交变更不会隐式复制
Expand All @@ -238,8 +276,8 @@ process-tree 与 pipe 后端。

安装/刷新时:

1. `dyro dispatch backends` 探测本机命令与登录态;当前受审计、可执行的集成为 `codex` 和 `claude`
2. `cursor-agent`、`opencode`、`grok`、`hermes`、`kimi` 会被展示为“已发现但未集成”,不得被自动或手动路由,直到各自拥有经过审计的非交互协议 adapter
1. `dyro dispatch --dry-run backends` 仅被动发现本机命令并标记 `authentication_probe=not_run`,不会启动第三方鉴权 CLI;授权执行前再用非 dry-run 的 `dyro dispatch backends` 主动核验登录态。当前受审计、可执行的集成为 `codex`、`claude`、`cursor-agent`、`opencode`、`grok`、`hermes`、`kimi`、`dsh` 和 `pi`。其中 Cursor 仅支持只读派发;其 edit 模式在沙箱进程生命周期获得证明前保持 fail-closed
2. 每个 Provider 只有在命令存在、精确鉴权通过且相应非交互 adapter 就绪时才可路由;未登录或运行时布局不受支持时继续展示,但不得进入自动选择。Hermes 额外关闭用户规则、身份、记忆、fallback、后台复核与会话持久化,仅接收 Dyro 投影上下文。Kimi 只绑定一个已选择的 Provider/model 路由;文件型 OAuth 仅复制该路由对应的 token 到单次运行目录,keyring 型 OAuth 因无法证明隔离而 fail-closed。DSH 通过受审查的 headless patch 固定为 `deepseek-official/deepseek-v4-flash`
3. 当只有一个已认证 Provider 时,`backend: auto` 可以选择它;当有多个时,用户必须使用 `dyro dispatch route add default <provider>` 选择默认路由;一个也没有时 fail-closed 并给出发现结果。
4. `echo` 仅用于显式 `--backend echo --allow-offline-simulation` 的确定性测试,输出的 `execution_kind=offline-simulation`、低置信度和非生产警告不得被上游当作真实模型结论。
5. 渲染 skill 正文只含已准备 Provider、发现但未集成的命令、路由表与上述限制,再分发到各宿主 skills 目录。
Expand All @@ -262,6 +300,7 @@ process-tree 与 pipe 后端。
| **L1** | `RunStore` + 双层槽位租约 + strict 影子接入 | 单测绿 |
| **L2** | `echo`/`codex`/`claude` 适配器 + CLI `run`/`result` | 单测(echo)+ 本机可选真 CLI |
| **L3** | `panel`、skill 渲染、routes、`gc` | 单测绿 |
| **L4** | 持久 Batch V1:plan/start/status/result/cancel | 单测 + 对抗生命周期绿 |

## 15. 测试矩阵(L0)

Expand Down
Loading