Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
128 changes: 128 additions & 0 deletions client/DESIGN.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,19 @@
2. 远程多节点编排与分布式队列。
3. 新增框架核心能力(仅复用现有 `dare_framework`)。

### 2.3 宿主编排协议基线(planned)

Issue #135 之后,`client/` 还需要补一层“宿主可稳定托管”的协议面,但该能力当前仍处于规划态。

本轮设计基线约束:

1. **不回退当前 CLI 可用性**:`chat/run/script` 与现有 `--output json` 行为保持兼容。
2. **显式区分三类模式**:
- interactive(当前主路径,已落地)
- automation-json(当前脚本集成路径,已落地但仅是 legacy automation schema)
- headless host orchestration(规划中)
3. **后续变更必须以显式协议切面落地**,不能继续把宿主编排能力混在 `dare>` prompt、内联审批和展示型 JSON 输出中。

## 3. 总体方案

### 3.1 关键决策
Expand All @@ -41,6 +54,11 @@
4. **默认安全策略**:
- 高风险工具审批默认开启(复用 `ToolApprovalManager` 默认行为)。
- 不提供默认绕过审批的开关。
5. **宿主协议与现有 JSON 输出分层**:
- 当前 `--output json` 继续作为脚本/调试输出层。
- 规划中的宿主编排协议使用独立 headless contract,避免与现有 JSON 行格式耦合。
6. **v1 外部控制面优先使用本地 stdin 命令帧**:
- 相比本地 HTTP/JSON-RPC,`control-stdin` 不新增端口、鉴权面与进程发现复杂度,更适合作为最小宿主协议基线。

### 3.2 架构图

Expand Down Expand Up @@ -197,6 +215,106 @@ CLI 层不自行定义“平行配置模型”,只对 `Config` 做覆盖合并
4. `3`:`doctor` 检查失败(环境或配置探测失败)
5. `130`:用户中断(Ctrl+C)

### 8.3 宿主编排协议基线(planned)

> 本节是 Slice A 的目标设计输入,**尚未实现**。
> 当前仓库事实仍以 `8.1`/`8.2` 描述的 landed 行为为准。

#### 8.3.1 模式分层

| 模式 | 状态 | 入口 | 主要语义 |
|---|---|---|---|
| interactive | landed | `dare chat` | 允许 `dare>` prompt、内联审批提示、人类可读输出。 |
| automation-json | landed / legacy | `run/script --output json` | 允许脚本消费 `log/event/result` 行输出,但不承诺宿主级稳定 envelope。 |
| headless | planned | 规划中的 `run/script --headless` | 禁止 prompt、禁止内联审批提示,仅允许结构化事件流与结构化控制通道。 |

#### 8.3.2 核心流程

```text
Host Process
|
| start CLI in headless mode
v
DARE client
|
| emits versioned event envelope
v
Host Event Parser
|
| sends structured command frames via control-stdin
v
DARE control handler
|
| returns structured result/error frame
v
Host Orchestrator
```

headless 目标流程要求:

1. 启动后先输出 `session.started` 或等价握手事件。
2. 执行期间所有可观察状态都走结构化事件帧,而不是 `[INFO]` / prompt 文案。
3. 审批、MCP、skills、能力发现等控制请求通过独立 control plane 完成,而不是依赖交互文本命令。

#### 8.3.3 事件 envelope v1(planned)

规划中的宿主事件帧至少包含以下顶层字段:

1. `schema_version`
2. `ts`
3. `session_id`
4. `run_id`
5. `seq`
6. `event`
7. `data`

首批事件类别基线:

1. lifecycle:`session.started`、`task.started`、`task.completed`、`task.failed`
2. tool/model:`model.response`、`tool.invoke`、`tool.result`、`tool.error`
3. approvals:`approval.pending`、`approval.resolved`
4. dynamic capability:`mcp.reloaded`、`mcp.unloaded`、`skills.listed`

兼容原则:

1. 当前 `--output json` 行结构视为 legacy automation schema。
2. headless envelope 使用独立 schema version,不直接复用现有 `type=log|event|result` 结构。
3. 迁移阶段必须允许宿主显式区分 legacy automation 与 host protocol。

#### 8.3.4 control-stdin v1(planned)

v1 设计选择:优先支持 `--control-stdin`,即 stdin 一行一个 JSON 命令帧。

命令 envelope 最小字段:

1. `schema_version`
2. `id`
3. `action`
4. `params`

结果 envelope 最小字段:

1. `schema_version`
2. `id`
3. `ok`
4. `result`
5. `error`

首批 action 基线:

1. `actions:list`
2. `approvals:list/poll/grant/deny/revoke`
3. `mcp:list/reload/show-tool`
4. `skills:list`
5. `status:get`

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Drop unsupported status:get from v1 control baseline

The new control-plane baseline lists status:get as a first-batch action, but the deterministic action registry in dare_framework/transport/interaction/resource_action.py has no status:get, and ResourceAction.value_of(...) returns None for unknown IDs. If a host follows this design and sends status:get over the structured control plane, it will be rejected as an unknown action, so the documented contract is internally inconsistent unless this action is added canonically (or explicitly mapped) first.

Useful? React with 👍 / 👎.


#### 8.3.5 错误处理与安全边界(planned)

1. headless 模式下禁止回落到 `input("dare> ")` 或内联 `approve>` 提示。
2. control plane 的失败必须返回结构化错误对象,而不是只写 stdout 文案。
3. 宿主协议层不得绕过已有 `approvals:*` / `mcp:*` / `skills:*` action 语义,只能在 CLI 外层做协议桥接。
4. 若未来补 `--control-port`,必须额外定义 loopback 约束、调用方身份与审计关联;该能力不属于当前 Slice A 的设计承诺。

## 9. 安全与边界

1. 审批规则存储继续复用:
Expand All @@ -222,6 +340,9 @@ CLI 层不自行定义“平行配置模型”,只对 `Config` 做覆盖合并
2. `chat` + 后台执行 + approvals 命令并发。
3. `mcp reload/unload` 行为(mock MCP manager 或本地 fake server)。
4. `script` 模式(注释/空行/失败中断)。
5. headless 协议稳定性(事件 envelope、schema version、error path)。
6. `control-stdin` 往返控制(approvals / MCP / skills / status)。
7. capability discovery(`actions:list` / 启动握手)与宿主降级策略。

## 11. 分阶段落地计划

Expand All @@ -245,6 +366,13 @@ CLI 层不自行定义“平行配置模型”,只对 `Config` 做覆盖合并
2. 完整命令文档与示例脚本
3. 回归测试矩阵接入 CI

### Phase 4(宿主编排协议,planned)

1. `--headless` 明确模式边界
2. versioned event envelope v1
3. `--control-stdin` 最小外部控制面
4. capability discovery / handshake

## 12. 风险与缓解

1. **风险:示例 CLI 逻辑重复迁移导致回归**
Expand Down
22 changes: 22 additions & 0 deletions client/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -320,6 +320,28 @@ JSON 行结构(简化):
- 事件:`{"type":"event","event":"header|mode|plan_preview|transport","data":{...}}`
- 结果:`{"type":"result","data":{...}}`

重要说明:

- 当前 `--output json` 是 **现有 automation schema**,适合脚本、调试和外部 UI 做轻量集成。
- 它**不是**未来宿主编排协议的稳定承诺;当前输出仍缺少版本化 envelope、`run_id/seq` 等宿主级关联字段。
- 如果目标是“像主流 agent CLI 一样被外部宿主长期稳定托管”,后续会补显式 `headless` 协议面与独立控制通道;在该能力落地前,请将 `--output json` 视为当前版本的脚本接口,而非长期协议。

## 宿主编排说明(规划中)

Issue #135 对应的设计基线已经建立,但当前尚未实现以下能力:

- 显式 `headless` 模式
- versioned event envelope
- `--control-stdin` 结构化控制面
- `actions:list` / 启动握手式能力发现

现阶段的推荐边界是:

1. 自动化执行使用 `run` / `script`。
2. 输出消费使用 `--output json`。
3. 审批、MCP、skills 等运行时控制仍以显式 CLI 命令或当前 transport/action 能力为主。
4. 不要把当前 `log/event/result` 三类 JSON 行当作长期稳定的宿主协议。

退出码约定:

- `0`:成功
Expand Down
4 changes: 2 additions & 2 deletions docs/design/TODO_INDEX.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,13 +43,13 @@

## security
- [ ] 提供 production-grade Policy/Sandbox 实现。(`docs/design/modules/security/README.md`)
- [ ] 与 HITL (`IExecutionControl`) 形成审批闭环。(`docs/design/modules/security/README.md`)
- [ ] 与 HITL (`IExecutionControl`) 形成审批闭环(含宿主控制面桥接)。(`docs/design/modules/security/README.md`)
- [ ] 统一 security 事件 taxonomy(deny/approve_required/allow)。(`docs/design/modules/security/README.md`)

## event
- [ ] 评估大规模场景下的存储后端升级路径(WORM/远端签名/分片归档)。(`docs/design/modules/event/README.md`)
- [ ] 统一 legacy events 与 event domain 的迁移策略。(`docs/design/modules/event/README.md`)
- [ ] 定义稳定事件 taxonomy 与 payload schema。(`docs/design/modules/event/README.md`)
- [ ] 定义稳定事件 taxonomy 与 payload schema(含 host-orchestrated client envelope 映射)。(`docs/design/modules/event/README.md`)

## hook
- [ ] 在 DareAgent 生命周期注入 hook 调用点。(`docs/design/modules/hook/README.md`)
Expand Down
2 changes: 2 additions & 0 deletions docs/design/modules/event/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -56,12 +56,14 @@ flowchart TD

- 当前默认实现为单机 SQLite 基线实现(非分布式多写场景)。
- 事件 taxonomy 与 payload schema 仍需统一规范。
- 面向外部宿主的 CLI/headless 事件 envelope 尚未与 canonical runtime taxonomy 明确映射;当前 `client --output json` 仅是 automation 输出层,不等同于 event domain 合约。

## 8. TODO / 未决问题

- TODO: 评估大规模场景下的存储后端升级路径(WORM/远端签名/分片归档)。
- TODO: 定义 legacy events -> event domain 的迁移策略。
- TODO: 固化跨模块事件命名与字段协议。
- TODO: 明确 host-orchestrated client event envelope 与 runtime/event taxonomy 的映射边界。

## 能力状态(landed / partial / planned)

Expand Down
62 changes: 62 additions & 0 deletions docs/features/client-host-orchestration-doc-baseline.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
---
change_ids: ["client-host-orchestration-doc-baseline"]
doc_kind: feature
topics: ["client-cli", "host-orchestration", "headless-protocol", "issue-135"]
todo_ids: ["CCLI-001", "CCLI-002"]
created: 2026-03-02
updated: 2026-03-02
status: active
mode: openspec
---

# Feature: client-host-orchestration-doc-baseline

## Scope

为 Issue #135 建立 docs-only Slice A 基线:纠正 `client/` 作为真实入口的事实,明确宿主编排协议的 planned 边界,并为后续 headless / control plane / capability discovery 实现切片提供统一设计输入。

## OpenSpec Artifacts

- Proposal: `openspec/changes/client-host-orchestration-doc-baseline/proposal.md`
- Design: `openspec/changes/client-host-orchestration-doc-baseline/design.md`
- Specs:
- `openspec/changes/client-host-orchestration-doc-baseline/specs/client-host-orchestration/spec.md`
- Tasks: `openspec/changes/client-host-orchestration-doc-baseline/tasks.md`

## TODO Coverage

- `CCLI-001`
- `CCLI-002`

## Evidence

### Commands

- `openspec list`
- `openspec --help`
- `openspec change --help`
- `openspec show client-host-orchestration-doc-baseline --type change --json --no-interactive`
- `openspec validate client-host-orchestration-doc-baseline --type change --strict`
- `./scripts/ci/check_governance_evidence_truth.sh`

### Results

- `openspec list`: confirmed the change must be created manually in the current CLI workflow.
- `openspec --help` and `openspec change --help`: confirmed the local CLI supports `show` / `validate`, but not `new` / `status`.
- `openspec show client-host-orchestration-doc-baseline --type change --json --no-interactive`: confirmed the change exposes 4 `ADDED` deltas under `client-host-orchestration`.
- `openspec validate client-host-orchestration-doc-baseline --type change --strict`: passed (`1/1` change valid, `0` issues).
- `./scripts/ci/check_governance_evidence_truth.sh`: passed after the PR link was added to this feature doc.

### Behavior Verification

- Happy path: Slice A now records the host orchestration baseline in `client/DESIGN.md`, clarifies the current `--output json` boundary in `client/README.md`, and binds the same scope to TODO + OpenSpec + feature evidence.
- Error branch: the docs now explicitly record that current automation JSON is not the future host protocol, preventing later slices from treating the existing `log/event/result` schema as a stable host contract.

### Risks and Rollback

- Risk: the design baseline may drift from future implementation slices if Slice B/C/D do not consume the same capability spec.
- Rollback: revert this docs-only slice and keep `client` documented only as the current automation CLI without host-orchestration commitments.

### Review and Merge Gate Links

- Intent PR: `https://github.com/zts212653/Deterministic-Agent-Runtime-Engine/pull/141`
113 changes: 113 additions & 0 deletions docs/todos/2026-03-02_client_cli_host_orchestration_gap_analysis.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
---
change_ids: []
doc_kind: analysis
topics: ["client-cli", "host-orchestration", "issue-135", "headless-protocol"]
created: 2026-03-02
updated: 2026-03-02
status: active
mode: openspec
---

# 2026-03-02 DARE Client CLI 宿主编排 Gap Analysis(Issue #135)

> 类型:专题 gap 分析
> 范围:`/client` 作为“可被外部宿主稳定编排的 CLI agent”时的协议与控制面差距
> 关联 issue:GitHub `#135`
> 评审基线:当前仓库 `client/` 实现、`client/DESIGN.md`、`client/README.md`、相关测试与 transport action/event 契约

---

## 1. 先纠偏(避免错误范围)

本议题的真实入口是 `client/`,不是 `examples/06-dare-coding-agent-mcp/cli.py`。

当前 `client/` 已具备的能力:

1. 非交互执行路径已经存在:
- `client/main.py` 提供 `run` / `script` 子命令。
2. 结构化输出已经存在:
- `client/main.py` 提供 `--output human|json`。
- `client/README.md` 已定义 `log/event/result` 三类 JSON 行。
3. Skills 与动态 MCP 能力已经暴露:
- `client/main.py` 提供 `skills list`、`mcp list/inspect/reload/unload`。
- `client/commands/mcp.py` 已接运行时 `reload_mcp/unload_mcp`。
4. framework 内部已有可复用的 transport envelope 元数据:
- `dare_framework/transport/types.py` 已定义 `event_type`、`stream_id`、`seq`。

因此,本议题不是“补齐从无到有的 CLI 基础能力”,而是把现有 `client/` 从“可脚本化调用”提升到“可被宿主稳定托管”的协议级能力。

---

## 2. 当前结论

- `client/` 已经是 **L1 可接入候选**。
- 真实 gap 集中在 **协议硬边界、外部控制通道、事件 envelope 稳定性、能力发现、宿主级测试**。
- 根据文档先行治理要求,这一轮应先补 **设计事实源 + master TODO**,再按切片进入 OpenSpec 与实现。

---

## 3. Gap 明细

| Gap ID | 设计声明(Design Claim) | 代码现状(Code Evidence) | 影响评估(Impact) | 建议动作(Action) | 优先级 |
|---|---|---|---|---|---|
| CCLI-GAP-001 | `client/` 需要有显式、可依赖的 headless 合约,保证宿主可强约束其只走结构化 I/O。 | `client/main.py` 仍以 `chat` + `input("dare> ")` 作为交互主循环;parser 只有 `--output human|json`,没有 `--headless` 或等价语义开关。`client/DESIGN.md` 只定义交互与 JSON 输出模式。 | 宿主虽然可以调用 `run/script`,但无法依赖一套“禁止 prompt / 禁止内联审批 / 禁止人类文案漂移”的强语义模式。 | 在设计文档中定义 `interactive` 与 `headless` 的模式边界、禁止行为、退出码与审批语义;后续实现显式开关。 | P1 |
| CCLI-GAP-002 | 机器可读输出需要宿主稳定字段与版本化 envelope,而不只是展示型 JSON。 | `client/main.py` 当前 JSON 输出为 `{"type":"log|event|result", ...}`;`client/README.md` 也只声明这三类结构;`tests/unit/test_client_cli.py` 直接锁定该简化 schema。 | 缺少 `schema_version`、`run_id`、`seq`、关联字段时,宿主难以做跨版本兼容、幂等重放、事件关联和细粒度生命周期解析。 | 先在设计层定义 `headless event envelope v1`,明确与现有 `--output json` 的兼容策略,再切实现。 | P1 |
| CCLI-GAP-003 | 宿主应能在活跃执行期间持续下发结构化控制,而不是仅限同进程 transport 调用。 | `client/runtime/action_client.py` 的 action/control 仅封装 `DirectClientChannel.ask(...)`;CLI 参数层没有 `--control-stdin`、`--control-port` 等宿主可接入控制面。 | 外部平台难以对运行中的任务执行审批、MCP 热重载、skills 查询、状态轮询等持续控制。 | 先定义外部 control plane(例如 `stdin` JSON 帧或 loopback RPC)的协议、动作集合、鉴权和错误语义。 | P1 |
| CCLI-GAP-004 | CLI 应向宿主暴露“能力发现”协议面,避免外部系统硬编码支持矩阵。 | framework 内部已有 `actions:list` 枚举,但 CLI 对外仅提供 `tools/skills/config/model/mcp/approvals/control` 等命令,没有 `actions list` 或等价启动握手。 | 宿主在对接时只能预设 CLI 能力,无法做启动协商或按能力降级。 | 将 `actions:list` 提升到 CLI 宿主协议面,并在设计中定义启动能力声明或显式查询命令。 | P2 |
| CCLI-GAP-005 | 动态 MCP 需要补齐“宿主实时注入”闭环,而不只是会话内命令能力。 | `client/commands/mcp.py` 已支持 `reload/unload`,但仍依附当前进程 runtime;缺少外部控制协议将其绑定到活跃 run。 | 现有能力更像“人工 / 单脚本可用”,不是“外部平台实时编排可用”。 | 先将当前 canonical MCP actions(`mcp:list/reload/show-tool`)纳入外部 control plane,并明确运行中可见性与一致性语义;CLI 层 `unload` 保持为独立命令能力,待后续补 canonical action 后再扩展。 | P2 |
| CCLI-GAP-006 | 宿主编排能力需要设计级与测试级双重基线,确保后续演进不回退。 | `client/DESIGN.md` 尚未定义宿主编排协议;现有测试覆盖 `--output json`、审批超时、CLI 基础路径,但没有 headless 协议稳定性、外部控制、能力发现集成测试。 | 即使后续补实现,也容易因为缺少设计锚点与回归测试而再次漂移。 | 先更新 canonical 设计文档,再增加协议级集成测试清单作为 slice 验收入口。 | P0 |

---

## 4. 影响范围

### 4.1 设计与文档

- `client/DESIGN.md`
- `client/README.md`
- `docs/design/TODO_INDEX.md`
- 视切片范围补充到 `docs/design/modules/event/README.md` 或相关 transport / interaction 设计文档

### 4.2 实现

- `client/main.py`
- `client/runtime/action_client.py`
- `client/runtime/event_stream.py`
- `client/render/json.py`
- 可能涉及 `dare_framework/transport/**` 与 interaction dispatcher 适配层

### 4.3 测试

- `tests/unit/test_client_cli.py`
- `tests/integration/test_client_cli_flow.py`
- 新增宿主协议集成测试(headless / control / capability discovery)

---

## 5. 建议切片(供 master TODO / OpenSpec 使用)

1. Slice A: 设计基线更新
- 目标:把 `client` 宿主编排协议写成 canonical docs。
2. Slice B: headless 模式与事件 envelope v1
- 目标:定义并实现稳定宿主事件流。
3. Slice C: 外部 control plane v1
- 目标:让宿主可在运行中持续控制审批 / MCP / skills。
4. Slice D: capability discovery + 协议级测试
- 目标:完成能力握手与回归基线。

---

## 6. 风险提示

1. 直接修改现有 `--output json` 语义会打破现有 README 与测试契约,必须先定义兼容策略。
2. 若先做代码、后补设计,后续 OpenSpec 切片边界会混乱,不符合仓库 SOP。
3. 若只补事件输出而不补外部控制面,CLI 仍然只能算“可观察”,不能算“可托管”。

---

## 7. 本轮结论

- Issue #135 应继续推进,但目标应重写为:
- “补齐 `client/` 的宿主编排协议能力”
- 而不是“回到 examples CLI 重做一套”
- 下一步应创建对应 master TODO,并将以上 6 个 gap 映射到可独立执行的 slice。
Loading
Loading