diff --git a/client/DESIGN.md b/client/DESIGN.md index e54a5ea0..04016acb 100644 --- a/client/DESIGN.md +++ b/client/DESIGN.md @@ -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 关键决策 @@ -41,6 +54,11 @@ 4. **默认安全策略**: - 高风险工具审批默认开启(复用 `ToolApprovalManager` 默认行为)。 - 不提供默认绕过审批的开关。 +5. **宿主协议与现有 JSON 输出分层**: + - 当前 `--output json` 继续作为脚本/调试输出层。 + - 规划中的宿主编排协议使用独立 headless contract,避免与现有 JSON 行格式耦合。 +6. **v1 外部控制面优先使用本地 stdin 命令帧**: + - 相比本地 HTTP/JSON-RPC,`control-stdin` 不新增端口、鉴权面与进程发现复杂度,更适合作为最小宿主协议基线。 ### 3.2 架构图 @@ -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` + +#### 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. 审批规则存储继续复用: @@ -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. 分阶段落地计划 @@ -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 逻辑重复迁移导致回归** diff --git a/client/README.md b/client/README.md index 6d6b15b0..85c5aa7b 100644 --- a/client/README.md +++ b/client/README.md @@ -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`:成功 diff --git a/docs/design/TODO_INDEX.md b/docs/design/TODO_INDEX.md index 70c70735..d6e2ff3a 100644 --- a/docs/design/TODO_INDEX.md +++ b/docs/design/TODO_INDEX.md @@ -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`) diff --git a/docs/design/modules/event/README.md b/docs/design/modules/event/README.md index 98311459..db91a6df 100644 --- a/docs/design/modules/event/README.md +++ b/docs/design/modules/event/README.md @@ -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) diff --git a/docs/features/client-host-orchestration-doc-baseline.md b/docs/features/client-host-orchestration-doc-baseline.md new file mode 100644 index 00000000..b6cd0915 --- /dev/null +++ b/docs/features/client-host-orchestration-doc-baseline.md @@ -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` diff --git a/docs/todos/2026-03-02_client_cli_host_orchestration_gap_analysis.md b/docs/todos/2026-03-02_client_cli_host_orchestration_gap_analysis.md new file mode 100644 index 00000000..3250d316 --- /dev/null +++ b/docs/todos/2026-03-02_client_cli_host_orchestration_gap_analysis.md @@ -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。 diff --git a/docs/todos/2026-03-02_client_cli_host_orchestration_master_todo.md b/docs/todos/2026-03-02_client_cli_host_orchestration_master_todo.md new file mode 100644 index 00000000..8f52ce50 --- /dev/null +++ b/docs/todos/2026-03-02_client_cli_host_orchestration_master_todo.md @@ -0,0 +1,77 @@ +--- +change_ids: [] +doc_kind: todo +topics: ["client-cli", "host-orchestration", "issue-135", "headless-protocol"] +created: 2026-03-02 +updated: 2026-03-02 +status: active +mode: openspec +--- + +# 2026-03-02 Client CLI 宿主编排 Master TODO(Issue #135) + +> 来源:`docs/todos/2026-03-02_client_cli_host_orchestration_gap_analysis.md` +> 执行模型:docs baseline -> OpenSpec slice -> docs-only intent PR -> implementation -> evidence -> archive +> 范围:仅覆盖 `client/` 作为外部宿主可编排 CLI 的协议与治理闭环 + +## 认领声明(Claim Ledger) + +> 当前状态:Slice A 已进入 docs baseline 准备阶段;尚未进入实现代码阶段。 +> 进入实现前,必须先完成 docs-only intent PR 合入,再推进后续 Slice B/C/D。 + +| Claim ID | TODO Scope | Owner | Status | Declared At | Expires At | OpenSpec Change | Notes | +|---|---|---|---|---|---|---|---| +| CLM-20260302-CCLI-A | CCLI-001~CCLI-002 | bouillipx | active | 2026-03-02 | 2026-03-09 | `client-host-orchestration-doc-baseline` | Slice A: 建立宿主编排 docs baseline、OpenSpec artifacts 与 intent PR payload。 | + +## 切片规划 + +| Slice | 目标 | 建议 OpenSpec Change | 主要覆盖 TODO | +|---|---|---|---| +| Slice A | 更新 canonical 设计与 README,明确宿主编排 contract | `client-host-orchestration-doc-baseline` | CCLI-001, CCLI-002 | +| Slice B | 定义并实现 headless 模式与事件 envelope v1 | `client-headless-event-envelope-v1` | CCLI-003, CCLI-004 | +| Slice C | 定义并实现外部 control plane v1 | `client-external-control-plane-v1` | CCLI-005, CCLI-006 | +| Slice D | 暴露 capability discovery,并补齐宿主协议回归测试 | `client-capability-discovery-and-host-tests` | CCLI-007, CCLI-008 | + +## TODO 清单 + +| ID | Priority | Status | Gap ID | Planned OpenSpec Change | Task | Owner | Evidence | Last Updated | +|---|---|---|---|---|---|---|---|---| +| CCLI-001 | P0 | done | CCLI-GAP-006 | `client-host-orchestration-doc-baseline` | 更新 `client/DESIGN.md`,新增“宿主编排 / headless / control plane / capability discovery / 错误语义”章节,作为后续实现唯一设计输入。 | bouillipx | `client/DESIGN.md`;`openspec/changes/client-host-orchestration-doc-baseline/design.md` | 2026-03-02 | +| CCLI-002 | P0 | done | CCLI-GAP-006 | `client-host-orchestration-doc-baseline` | 更新 `client/README.md`,明确当前 `--output json` 是 legacy automation schema,补充后续宿主协议模式的兼容说明。 | bouillipx | `client/README.md`;`docs/features/client-host-orchestration-doc-baseline.md` | 2026-03-02 | +| CCLI-003 | P1 | todo | CCLI-GAP-001 | `client-headless-event-envelope-v1` | 为 `client` 设计并实现显式 headless 模式,定义禁止 prompt / 禁止内联审批 / 只输出协议帧的行为边界。 | TBD | `client/main.py`;相关 OpenSpec design/specs/tasks | 2026-03-02 | +| CCLI-004 | P1 | todo | CCLI-GAP-002 | `client-headless-event-envelope-v1` | 设计并实现 versioned event envelope(至少含 `schema_version`、`run_id`、`seq`、`event`、`data`),并定义与现有 JSON 输出的兼容策略。 | TBD | `client/main.py`;`client/render/json.py`;相关测试 | 2026-03-02 | +| CCLI-005 | P1 | todo | CCLI-GAP-003 | `client-external-control-plane-v1` | 设计外部控制协议入口(如 `control-stdin` 或 loopback RPC),覆盖 approvals / MCP / skills / status 的结构化控制。 | TBD | `client/main.py`;`client/runtime/action_client.py`;相关 OpenSpec design/specs/tasks | 2026-03-02 | +| CCLI-006 | P2 | todo | CCLI-GAP-005 | `client-external-control-plane-v1` | 将当前 canonical MCP actions(首批为 `mcp:list/reload/show-tool`)接入外部 control plane,并明确运行中生效与错误处理语义。CLI 层 `unload` 待后续补 canonical action 后再纳入宿主协议面。 | TBD | `client/commands/mcp.py`;相关集成测试 | 2026-03-02 | +| CCLI-007 | P2 | todo | CCLI-GAP-004 | `client-capability-discovery-and-host-tests` | 将 `actions:list` 提升到 CLI 宿主协议面,并定义启动握手或显式查询命令。 | TBD | `dare_framework/transport/interaction/resource_action.py`;`client/main.py`;相关文档 | 2026-03-02 | +| CCLI-008 | P1 | todo | CCLI-GAP-006 | `client-capability-discovery-and-host-tests` | 新增 headless 协议稳定性、外部控制、能力发现三组集成测试,并回写 README / 设计文档中的验证锚点。 | TBD | `tests/integration/test_client_cli_flow.py`;新增协议测试文件 | 2026-03-02 | + +--- + +## 执行规则 + +1. 不允许直接从 CCLI-003 开始写代码;必须先完成 CCLI-001 / CCLI-002 并提交 docs-only intent PR。 +2. 每个 OpenSpec change 只消费上表中的一个 slice,不混切多个高风险协议面。 +3. 任何会改变现有 `--output json` 行格式的方案,都必须先写清兼容策略与迁移说明。 +4. `Claim Ledger`、OpenSpec `tasks.md`、后续 `docs/features/.md` 必须对齐同一组 TODO IDs。 + +## 建议验收边界 + +### Slice A + +- `client/DESIGN.md` 已能独立描述宿主编排 contract。 +- `client/README.md` 已说明 legacy JSON 与未来宿主协议面的边界。 + +### Slice B + +- headless 模式下不存在 `dare>` prompt 或内联审批提示。 +- 宿主可稳定解析事件 envelope,且 error path 也有一致 schema。 + +### Slice C + +- 宿主可对活跃 run 下发至少一类审批指令与一类 MCP 指令。 +- control plane 错误语义可结构化返回,而非仅 stdout 文案。 + +### Slice D + +- 宿主可查询能力清单,而非硬编码支持矩阵。 +- 回归测试可覆盖 happy path 与 changed error path。 diff --git a/docs/todos/README.md b/docs/todos/README.md index da1c966c..e4434e2a 100644 --- a/docs/todos/README.md +++ b/docs/todos/README.md @@ -11,6 +11,8 @@ - `2026-02-27_full_design_review_gap_todo.md`:全量设计文档评审对应 TODO 清单(持续治理中)。 - `2026-02-27_design_reconstructability_gap_analysis.md`:可重建性差异分析(P0/P1 已闭环,后续与 full-review 联动)。 - `2026-02-27_design_reconstructability_gap_todo.md`:可重建性治理 TODO 清单(已回写 done,待按周期归档)。 +- `2026-03-02_client_cli_host_orchestration_gap_analysis.md`:Issue #135 的 `/client` 宿主编排协议差距分析(活跃)。 +- `2026-03-02_client_cli_host_orchestration_master_todo.md`:Issue #135 对应 master TODO 与切片规划(活跃)。 - `archive/2026-02-27_design_code_gap_analysis.md`:当前设计与实现差异分析基线(文档先行治理,已归档)。 - `archive/2026-02-27_design_code_gap_todo.md`:由 gap 分析推导出的执行 TODO 清单(已归档)。 - `templates/change_execution_todo_template.md`:活跃 change 执行协作板模板。 diff --git a/openspec/changes/client-host-orchestration-doc-baseline/.openspec.yaml b/openspec/changes/client-host-orchestration-doc-baseline/.openspec.yaml new file mode 100644 index 00000000..fd79bfc5 --- /dev/null +++ b/openspec/changes/client-host-orchestration-doc-baseline/.openspec.yaml @@ -0,0 +1,2 @@ +schema: spec-driven +created: 2026-03-02 diff --git a/openspec/changes/client-host-orchestration-doc-baseline/design.md b/openspec/changes/client-host-orchestration-doc-baseline/design.md new file mode 100644 index 00000000..abcc917c --- /dev/null +++ b/openspec/changes/client-host-orchestration-doc-baseline/design.md @@ -0,0 +1,87 @@ +## Context + +当前 `client/` 已经具备: + +- `run/script` 非交互执行入口; +- `--output json` 的自动化行输出; +- `skills list` 与 `mcp list/inspect/reload/unload`; +- framework 内部已有 `actions:list`、`approvals:*`、`mcp:*`、`skills:list` 等 deterministic action 基础。 + +但这些能力仍未被整理成“宿主托管协议”。本 change 不实现协议,只把后续实现需要遵守的设计边界、兼容策略和 TODO slice 固化下来。 + +## Goals / Non-Goals + +**Goals:** + +- 为 `client` 建立宿主编排的 canonical 设计基线。 +- 明确当前 automation-json 与未来 headless contract 的边界。 +- 为后续 Slice B/C/D 提供稳定的 capability 约束与 TODO 映射。 +- 保持仓库 docs-first 工作流完整:Claim Ledger、OpenSpec、feature evidence、intent PR payload 一致。 + +**Non-Goals:** + +- 本次不修改 `client` 运行时行为。 +- 本次不实现 `--headless`、`--control-stdin` 或新的事件 schema。 +- 本次不为外部宿主定义远程网络控制协议。 + +## Decisions + +### Decision 1: 现有 `--output json` 保留为 legacy automation schema + +- 当前 `log/event/result` 行结构继续保留,避免破坏现有脚本与测试。 +- 新的宿主协议不得直接复用这三类行结构,而应显式使用 versioned envelope。 +- 文档层必须明确两者边界,避免调用方误判。 + +### Decision 2: headless host orchestration 作为独立模式,而不是 `chat/run/script` 的隐式变体 + +- interactive 允许 `dare>` prompt 与内联审批; +- automation-json 允许脚本消费 JSON 行; +- headless 只允许结构化事件流与结构化控制面。 + +理由:只有显式模式切换,宿主才能依赖“禁止人类交互副作用”的强语义。 + +### Decision 3: v1 外部控制面优先选 `control-stdin` + +- `control-stdin` 避免新增本地端口、发现机制与额外鉴权面。 +- 行级 JSON 帧足以覆盖 approvals / MCP / skills / actions / status 基线控制。 +- loopback RPC 可作为未来增强,但不进入当前设计承诺。 + +### Decision 4: capability discovery 是宿主协议的基线能力,不是附属优化 + +- `actions:list` 或等价启动握手必须进入宿主协议设计。 +- 宿主不能依赖硬编码支持矩阵来判断某个 `client` 版本是否支持某 action。 + +### Decision 5: docs baseline 必须落在多层文档,而不是只改一个局部 README + +- `client/DESIGN.md` 负责详细设计; +- `client/README.md` 负责用户可见边界; +- `docs/design/modules/event/README.md` 与 `docs/design/TODO_INDEX.md` 负责 canonical backlog 与跨模块追踪; +- `docs/features/.md` 负责 Slice A 的状态与证据。 + +## Risks / Trade-offs + +- [Risk] 先写未来协议设计,短期会形成“文档先于实现”的差距。 + → Mitigation: 明确标注 `planned`,并把 Slice B/C/D 绑定到同一 master TODO。 + +- [Risk] 继续保留 legacy automation schema 会增加双轨维护成本。 + → Mitigation: 明确 legacy 与 headless 的分层语义,避免后续再混为一谈。 + +- [Risk] `control-stdin` 可能不足以覆盖未来复杂宿主场景。 + → Mitigation: 将 loopback RPC 保留为后续可扩展方向,但不影响 v1 最小能力落地。 + +## Migration Plan + +1. Slice A:建立 docs baseline、OpenSpec capability、feature evidence、intent PR payload。 +2. Slice B:实现 `--headless` 与 versioned event envelope v1。 +3. Slice C:实现 `--control-stdin` 与 approvals / MCP / skills 的外部控制。 +4. Slice D:实现 capability discovery 与宿主协议回归测试。 + +Rollback: + +- 若团队否决该设计方向,可回退本 change 的设计文档与 capability 定义,恢复到“仅支持 automation-json”的当前表述。 + +## Open Questions + +- `status:get` 是否需要作为独立 action,还是由 `actions:list` + 事件流已足够? +- `session.started` 是否承担完整握手,还是需要单独的 capability handshake 事件? +- 宿主协议 envelope 是否应直接复用 transport `seq/stream_id` 命名,还是在 CLI 层做字段投影? diff --git a/openspec/changes/client-host-orchestration-doc-baseline/proposal.md b/openspec/changes/client-host-orchestration-doc-baseline/proposal.md new file mode 100644 index 00000000..1fd9f988 --- /dev/null +++ b/openspec/changes/client-host-orchestration-doc-baseline/proposal.md @@ -0,0 +1,44 @@ +## Why + +Issue #135 暴露的核心问题不是 `client/` 缺少基础 CLI 能力,而是仓库缺少一份关于“宿主如何稳定托管 `client/`”的 canonical 设计基线。 +当前代码已经具备 `run/script`、`--output json`、`skills list`、`mcp reload/unload` 等能力,但它们仍停留在“可脚本化 / 可调试”的层级,尚未被定义为显式的 host orchestration contract。 + +如果直接进入实现 Slice B/C/D,会产生三个风险: + +1. 把现有 `--output json` 误当作长期宿主协议,造成兼容风险。 +2. 在没有 headless/control plane 明确边界时,把 prompt / inline approval / transport action 混杂到同一层。 +3. 后续实现缺少可追踪的 docs baseline,无法满足仓库 docs-first SOP。 + +因此需要先做一个 docs-only Slice A,建立后续实现的唯一设计输入。 + +## What Changes + +- 更新 `client/DESIGN.md`,明确 interactive / automation-json / headless 三层模式边界。 +- 更新 `client/README.md`,澄清当前 `--output json` 的 legacy automation 属性与兼容边界。 +- 同步 `docs/design/modules/event/README.md` 与 `docs/design/TODO_INDEX.md`,把 host-orchestrated client envelope 纳入 canonical design backlog。 +- 新增 OpenSpec capability `client-host-orchestration`,记录后续 headless event envelope、structured control plane、capability discovery 的目标约束。 +- 创建 feature aggregation 文档,作为当前 Slice A 的状态与证据源。 + +## Capabilities + +### New Capabilities + +- `client-host-orchestration`: 定义 `client/` 作为外部宿主可编排 CLI 时的模式边界、事件协议、控制面与能力发现约束。 + +### Modified Capabilities + +- `interaction-dispatch`: 补充宿主能力发现与结构化 control plane 的规划约束。 +- `transport-channel`: 补充宿主事件 envelope 的版本化与关联字段要求。 + +## Impact + +- 影响文件: + - `client/DESIGN.md` + - `client/README.md` + - `docs/design/modules/event/README.md` + - `docs/design/TODO_INDEX.md` + - `docs/todos/2026-03-02_client_cli_host_orchestration_master_todo.md` + - `docs/features/client-host-orchestration-doc-baseline.md` + - `openspec/changes/client-host-orchestration-doc-baseline/**` +- 代码影响:无,本 change 仅建立 docs baseline 与后续实现约束。 +- 流程影响:后续 Slice B/C/D 必须消费本 change 的 TODO 子集与 capability 要求,不允许绕过 docs-only intent PR 直接实现。 diff --git a/openspec/changes/client-host-orchestration-doc-baseline/specs/client-host-orchestration/spec.md b/openspec/changes/client-host-orchestration-doc-baseline/specs/client-host-orchestration/spec.md new file mode 100644 index 00000000..0cc701e2 --- /dev/null +++ b/openspec/changes/client-host-orchestration-doc-baseline/specs/client-host-orchestration/spec.md @@ -0,0 +1,52 @@ +## ADDED Requirements + +### Requirement: Client host orchestration modes are explicitly separated +The system SHALL distinguish between interactive CLI behavior, legacy automation JSON output, and a future host-orchestrated headless contract. + +- Interactive mode MAY use prompts and inline human approval UX. +- Legacy automation JSON MAY keep the current `log/event/result` line schema for backward compatibility. +- Headless host orchestration MUST be an explicit mode boundary and MUST NOT rely on prompt text or inline human approval interactions. + +#### Scenario: Headless mode does not depend on prompt UX +- **GIVEN** the client is started in host-orchestrated headless mode +- **WHEN** a task execution requires runtime observation or control +- **THEN** the client does not emit `dare>` style prompts +- **AND** it does not require inline approval input from stdout/stdin prompt UX + +### Requirement: Host event stream is versioned and correlated +The system SHALL provide a versioned host event envelope for headless orchestration that is distinct from the legacy automation JSON line schema. + +- The envelope MUST include a schema version field. +- The envelope MUST include correlation metadata sufficient for session/run/event ordering. +- The envelope MUST provide stable event identifiers or sequence semantics for host replay and parsing. + +#### Scenario: Host receives correlated event frames +- **GIVEN** a host launches the client in headless mode +- **WHEN** the client emits lifecycle, tool, or approval events +- **THEN** each frame contains versioned envelope metadata +- **AND** the host can correlate frames within the same run without parsing human-readable log text + +### Requirement: Host control is provided through a structured local control plane +The system SHALL provide a structured local control plane for host-orchestrated sessions. + +- The control plane MUST accept deterministic actions for approvals, MCP management, skills discovery, and capability discovery. +- Control responses MUST use structured success/error payloads. +- The control plane MUST preserve existing approval and action semantics rather than bypassing them. + +#### Scenario: Host grants approval through structured control +- **GIVEN** a running headless session emits an approval-pending event +- **WHEN** the host submits a structured approval grant command +- **THEN** the client resolves the approval through the deterministic approval action path +- **AND** the result is returned as a structured control response + +### Requirement: Host capabilities are discoverable without hardcoded matrices +The system SHALL provide a deterministic capability discovery surface for host orchestration. + +- Hosts MUST be able to discover supported actions for the active client/runtime. +- Capability discovery MAY be exposed via an explicit action such as `actions:list` or an equivalent startup handshake. + +#### Scenario: Host queries supported actions +- **GIVEN** a host needs to determine whether the client supports dynamic MCP reload +- **WHEN** it requests capability discovery +- **THEN** the client returns a structured list of supported actions +- **AND** the host does not need to infer support by parsing help text or natural-language output diff --git a/openspec/changes/client-host-orchestration-doc-baseline/tasks.md b/openspec/changes/client-host-orchestration-doc-baseline/tasks.md new file mode 100644 index 00000000..37f87900 --- /dev/null +++ b/openspec/changes/client-host-orchestration-doc-baseline/tasks.md @@ -0,0 +1,16 @@ +## 1. Establish Docs Baseline + +- [x] 1.1 更新 `client/DESIGN.md`,定义 interactive / automation-json / headless 的模式分层与 planned host orchestration contract。 +- [x] 1.2 更新 `client/README.md`,澄清当前 `--output json` 的 legacy automation 边界。 +- [x] 1.3 更新 `docs/design/modules/event/README.md` 与 `docs/design/TODO_INDEX.md`,把 host-orchestrated client envelope 纳入 canonical backlog。 + +## 2. Create Change Tracking Assets + +- [x] 2.1 创建 `client-host-orchestration-doc-baseline` 的 proposal / design / tasks / spec delta。 +- [x] 2.2 创建 `docs/features/client-host-orchestration-doc-baseline.md`,并初始化 Evidence 区块。 +- [x] 2.3 将 master TODO 的 Slice A `Claim Ledger` 与 TODO IDs 绑定到该 change。 + +## 3. Prepare Intent Payload + +- [x] 3.1 准备 docs-only intent PR payload(Claim Ledger + docs baseline + OpenSpec artifacts + feature doc)。 +- [x] 3.2 运行 OpenSpec change 校验,确认当前 artifacts 结构可被工具识别。