Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
12 changes: 7 additions & 5 deletions client/DESIGN.md
Original file line number Diff line number Diff line change
Expand Up @@ -313,10 +313,11 @@ v1 设计选择:优先支持 `--control-stdin`,即 stdin 一行一个 JSON
3. `skills:list`
4. `status:get`

当前仍未纳入 Slice C 基线
Slice D 设计基线

1. `actions:list`
2. capability discovery / startup handshake
1. v1 capability discovery 优先走显式 `actions:list`,继续复用 `client-control-stdin.v1`
2. unsolicited startup handshake 不纳入当前宿主协议基线,避免在 stdout 多路复用流上引入额外隐式帧
3. 能力发现返回当前 session 可用的 canonical action ids,不要求首版附带额外元数据矩阵

#### 8.3.5 错误处理与安全边界(Slice C landed baseline)

Expand Down Expand Up @@ -352,7 +353,7 @@ v1 设计选择:优先支持 `--control-stdin`,即 stdin 一行一个 JSON
4. `script` 模式(注释/空行/失败中断)。
5. headless 协议稳定性(事件 envelope、schema version、error path)。
6. `control-stdin` 往返控制(approvals / MCP / skills / status)。
7. capability discovery(`actions:list` / 启动握手)与宿主降级策略。
7. capability discovery(显式 `actions:list`)与宿主降级策略。

## 11. 分阶段落地计划

Expand Down Expand Up @@ -381,7 +382,8 @@ v1 设计选择:优先支持 `--control-stdin`,即 stdin 一行一个 JSON
1. `--headless` 明确模式边界
2. versioned event envelope v1
3. `--control-stdin` 最小外部控制面
4. capability discovery / handshake
4. 显式 capability discovery(`actions:list`)
5. 启动握手若要引入,需作为后续独立 slice 明确多路复用与兼容策略

## 12. 风险与缓解

Expand Down
5 changes: 3 additions & 2 deletions client/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -347,19 +347,20 @@ Issue #135 对应的宿主编排能力目前分成“已落地”和“未落地

仍未落地:

- `actions:list` / 启动握手式能力发现
- `actions:list` 显式能力发现

当前推荐边界是:

1. 自动化脚本仍使用 `run/script --output json`。
2. 宿主事件流接入使用 `run/script --headless`。
3. 运行中控制当前优先使用 `--control-stdin` 做 `status:get`、approvals、MCP 与 `skills:list`;`actions:list` / 启动握手仍在后续 Slice
3. 运行中控制当前优先使用 `--control-stdin` 做 `status:get`、approvals、MCP 与 `skills:list`;`actions:list` 作为下一 Slice 的显式能力发现入口继续推进
4. 不要把当前 `log/event/result` 三类 JSON 行当作长期稳定的宿主协议。

补充说明:

- `script --headless` 与 `run --headless` 一样支持审批超时控制。
- `script` 可显式传入 `--approval-timeout-seconds <seconds>`;未显式传入时,headless 脚本默认使用 `120s` 超时,避免无头会话无限等待审批。
- 启动即发送的 capability handshake 当前不属于 v1 计划;宿主应通过显式 discovery action 获取支持矩阵。

退出码约定:

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ topics: ["client-cli", "host-orchestration", "control-plane", "issue-135"]
todo_ids: ["CCLI-005", "CCLI-006"]
created: 2026-03-02
updated: 2026-03-02
status: active
status: archived
mode: openspec
---

Expand Down Expand Up @@ -46,6 +46,7 @@ mode: openspec
- `../../.venv/bin/python -m pytest tests/integration/test_client_cli_flow.py -q`
- `openspec list`
- `openspec validate client-external-control-plane-v1 --type change --strict --json --no-interactive`
- `openspec archive client-external-control-plane-v1 -y`
- `./scripts/ci/check_governance_evidence_truth.sh`

### Results
Expand All @@ -60,10 +61,11 @@ mode: openspec
- `../../.venv/bin/python -m pytest tests/integration/test_client_cli_flow.py -q -k 'status_get_reports_pending_approvals'`: failed before the review fix because `run --headless --control-stdin` only updated the approval timeout watch, leaving `status:get` snapshots blind to pending runtime approvals; passed after wiring run-mode approval pending/resolved events into `CLISessionState.pending_runtime_approvals`.
- `../../.venv/bin/python -m pytest tests/integration/test_client_cli_flow.py -q -k 'surfaces_action_handler_failure or rejects_unsupported_action or bridges_approvals_list or control_stdin_status_get_emits_structured_result or script_headless_control_stdin_status_get_reports_active_task'`: passed (`5` tests), covering happy path plus unsupported-action and handler-failure branches.
- `../../.venv/bin/python -m pytest tests/unit/test_client_cli.py -q -k 'cancellation_does_not_block_default_executor_shutdown'`: failed before the review fix because cancelling the control task still left a blocking `stdin.readline()` worker pinned in the default executor; passed after moving `control-stdin` reads onto a daemon thread + asyncio queue bridge.
- `../../.venv/bin/python -m pytest tests/unit/test_client_cli.py -q`: passed (`44` tests, `0` failures).
- `../../.venv/bin/python -m pytest tests/integration/test_client_cli_flow.py -q`: passed (`20` tests, `0` failures).
- `../../.venv/bin/python -m pytest tests/unit/test_client_cli.py -q`: passed (`45` tests, `0` failures) after the final `pending_approvals` status snapshot regression fix.
- `../../.venv/bin/python -m pytest tests/integration/test_client_cli_flow.py -q`: passed (`21` tests, `0` failures) after the final `status:get` pending-approval coverage landed.
- `openspec list`: confirms Slice A / Slice B have been archived out of the active change list, and the active Slice C change now shows `✓ Complete`.
- `openspec validate client-external-control-plane-v1 --type change --strict --json --no-interactive`: passed (`1/1` change valid, `0` issues).
- `openspec archive client-external-control-plane-v1 -y`: archived the completed change to `openspec/changes/archive/2026-03-02-client-external-control-plane-v1/` and synced the landed control-plane deltas back into `openspec/specs/client-host-orchestration/spec.md`.
- `./scripts/ci/check_governance_evidence_truth.sh`: passed after the Slice C feature evidence block and prior-slice archive moves were synchronized.

### Behavior Verification
Expand All @@ -83,7 +85,8 @@ mode: openspec
- Slice A intent gate (merged): `https://github.com/zts212653/Deterministic-Agent-Runtime-Engine/pull/141`
- Slice B implementation gate (merged): `https://github.com/zts212653/Deterministic-Agent-Runtime-Engine/pull/145`
- Slice C docs-only intent PR (merged): `https://github.com/zts212653/Deterministic-Agent-Runtime-Engine/pull/148`
- Slice C implementation PR (open): `https://github.com/zts212653/Deterministic-Agent-Runtime-Engine/pull/151`
- Slice C implementation PR (merged): `https://github.com/zts212653/Deterministic-Agent-Runtime-Engine/pull/151`
- Slice C spec-fold review thread: `https://github.com/zts212653/Deterministic-Agent-Runtime-Engine/pull/148#discussion_r2872038646`
- Slice C implementation review thread: `https://github.com/zts212653/Deterministic-Agent-Runtime-Engine/pull/151#discussion_r2872629793`
- Slice C implementation review thread: `https://github.com/zts212653/Deterministic-Agent-Runtime-Engine/pull/151#discussion_r2872876273`
- Archive target: `openspec/changes/archive/2026-03-02-client-external-control-plane-v1/`
71 changes: 71 additions & 0 deletions docs/features/client-capability-discovery-and-host-tests.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
---
change_ids: ["client-capability-discovery-and-host-tests"]
doc_kind: feature
topics: ["client-cli", "host-orchestration", "capability-discovery", "issue-135"]
todo_ids: ["CCLI-007", "CCLI-008"]
created: 2026-03-02
updated: 2026-03-02
status: active
mode: openspec
---

# Feature: client-capability-discovery-and-host-tests

## Scope

落实 Issue #135 的 Slice D:为 `client/` 的宿主协议面补上显式 capability discovery(`actions:list`),并建立覆盖 headless event envelope、control plane 与 discovery 的宿主级回归测试。

## OpenSpec Artifacts

- Proposal: `openspec/changes/client-capability-discovery-and-host-tests/proposal.md`
- Design: `openspec/changes/client-capability-discovery-and-host-tests/design.md`
- Specs:
- `openspec/changes/client-capability-discovery-and-host-tests/specs/client-host-orchestration/spec.md`
- Tasks: `openspec/changes/client-capability-discovery-and-host-tests/tasks.md`

## TODO Coverage

- `CCLI-007`
- `CCLI-008`

## Evidence

### Commands

- `git fetch origin`
- `git worktree add .worktrees/client-capability-discovery-and-host-tests -b codex/client-capability-discovery-and-host-tests origin/main`
- `openspec archive client-external-control-plane-v1 -y`
- `../../.venv/bin/python -m pytest tests/unit/test_client_cli.py -q`
- `../../.venv/bin/python -m pytest tests/integration/test_client_cli_flow.py -q`
- `openspec list`
- `openspec show client-capability-discovery-and-host-tests --type change --json --no-interactive`
- `openspec validate client-capability-discovery-and-host-tests --type change --strict --json --no-interactive`
- `./scripts/ci/check_governance_evidence_truth.sh`

### Results

- `git fetch origin`: confirmed `origin/main` has merged Slice C via PR `#151`.
- `git worktree add .worktrees/client-capability-discovery-and-host-tests -b codex/client-capability-discovery-and-host-tests origin/main`: created an isolated Slice D workspace from merged `main` at commit `cce6e4d`.
- `openspec archive client-external-control-plane-v1 -y`: archived the completed Slice C change to `openspec/changes/archive/2026-03-02-client-external-control-plane-v1/` and synced the landed control-plane deltas back into the main `client-host-orchestration` spec.
- `../../.venv/bin/python -m pytest tests/unit/test_client_cli.py -q`: passed (`45` tests, `0` failures) as the Slice D kickoff baseline in the new worktree.
- `../../.venv/bin/python -m pytest tests/integration/test_client_cli_flow.py -q`: passed (`21` tests, `0` failures) as the Slice D kickoff baseline in the new worktree.
- `openspec list`: shows the new change as `client-capability-discovery-and-host-tests 0/7 tasks`.
- `openspec show client-capability-discovery-and-host-tests --type change --json --no-interactive`: confirms the change exposes `1` `MODIFIED` delta under `client-host-orchestration`.
- `openspec validate client-capability-discovery-and-host-tests --type change --strict --json --no-interactive`: passed (`1/1` change valid, `0` issues).
- `./scripts/ci/check_governance_evidence_truth.sh`: passed after the Slice C archive moves and Slice D kickoff evidence were synchronized.

### Behavior Verification

- Happy path: Slice C is now archived on top of merged `main`, and Slice D design chooses explicit `actions:list` discovery on `--control-stdin` rather than adding startup chatter to the host protocol.
- Error branch: unsolicited startup capability handshake remains out of scope for v1, preventing hosts from depending on implicit frames before explicit discovery semantics are finalized.

### Risks and Rollback

- Risk: until Slice D implementation lands, hosts still need a hardcoded discovery matrix even though the design baseline now prefers explicit `actions:list`.
- Rollback: drop the Slice D kickoff change and keep the repository at the archived Slice C baseline where control is available but capability discovery remains planned-only.

### Review and Merge Gate Links

- Slice C implementation gate (merged): `https://github.com/zts212653/Deterministic-Agent-Runtime-Engine/pull/151`
- Slice C archive target: `openspec/changes/archive/2026-03-02-client-external-control-plane-v1/`
- Slice D intent PR: pending
Original file line number Diff line number Diff line change
Expand Up @@ -16,14 +16,15 @@ mode: openspec

## 认领声明(Claim Ledger)

> 当前状态:Slice A / Slice B 已于 2026-03-02 完成并合入 `main`;Slice C 的 docs-only intent PR `#148` 已合入,当前实现已覆盖 approvals / MCP / skills / status 的 `control-stdin` 基线,待进入实现 PR / review gate
> Slice C 负责外部 control plane v1;Slice D 继续承担 capability discovery 与宿主级回归测试
> 当前状态:Slice A / Slice B / Slice C 已于 2026-03-02 完成并合入 `main`;Slice C 已归档到 `openspec/changes/archive/2026-03-02-client-external-control-plane-v1/`
> Slice D 当前进入 docs-first kickoff:先建立 capability discovery 与宿主协议回归测试的设计基线、OpenSpec change 和 intent PR payload,再进入实现

| Claim ID | TODO Scope | Owner | Status | Declared At | Expires At | OpenSpec Change | Notes |
|---|---|---|---|---|---|---|---|
| CLM-20260302-CCLI-A | CCLI-001~CCLI-002 | bouillipx | done | 2026-03-02 | 2026-03-09 | `client-host-orchestration-doc-baseline` | Slice A: docs baseline 已随 PR `#141` 合入 `main`,待归档到 `openspec/changes/archive/2026-03-02-client-host-orchestration-doc-baseline/`。 |
| CLM-20260302-CCLI-B | CCLI-003~CCLI-004 | bouillipx | done | 2026-03-02 | 2026-03-09 | `client-headless-event-envelope-v1` | Slice B: headless event envelope v1 已随 PR `#145` 合入 `main`,待归档到 `openspec/changes/archive/2026-03-02-client-headless-event-envelope-v1/`。 |
| CLM-20260302-CCLI-C | CCLI-005~CCLI-006 | bouillipx | active | 2026-03-02 | 2026-03-09 | `client-external-control-plane-v1` | Slice C: docs-only intent PR `#148` 已合入;当前已落地 `--control-stdin` 最小基线,以及 `status:get`、approvals、`mcp:list/reload/show-tool`、`skills:list` host bridge;`actions:list` 仍留给 Slice D。 |
| CLM-20260302-CCLI-A | CCLI-001~CCLI-002 | bouillipx | done | 2026-03-02 | 2026-03-09 | `client-host-orchestration-doc-baseline` | Slice A: docs baseline 已随 PR `#141` 合入 `main`,并已归档到 `openspec/changes/archive/2026-03-02-client-host-orchestration-doc-baseline/`。 |
| CLM-20260302-CCLI-B | CCLI-003~CCLI-004 | bouillipx | done | 2026-03-02 | 2026-03-09 | `client-headless-event-envelope-v1` | Slice B: headless event envelope v1 已随 PR `#145` 合入 `main`,并已归档到 `openspec/changes/archive/2026-03-02-client-headless-event-envelope-v1/`。 |
| CLM-20260302-CCLI-C | CCLI-005~CCLI-006 | bouillipx | done | 2026-03-02 | 2026-03-09 | `client-external-control-plane-v1` | Slice C: docs-only intent PR `#148` 与实现 PR `#151` 已合入;change 已归档到 `openspec/changes/archive/2026-03-02-client-external-control-plane-v1/`,feature evidence 已迁移到 `docs/features/archive/client-external-control-plane-v1.md`。 |
| CLM-20260302-CCLI-D | CCLI-007~CCLI-008 | bouillipx | active | 2026-03-02 | 2026-03-09 | `client-capability-discovery-and-host-tests` | Slice D: 建立显式 `actions:list` 能力发现与宿主协议回归测试的 docs baseline、OpenSpec artifacts 与 intent PR payload。 |

## 切片规划

Expand All @@ -42,10 +43,10 @@ mode: openspec
| 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/archive/client-host-orchestration-doc-baseline.md` | 2026-03-02 |
| CCLI-003 | P1 | done | CCLI-GAP-001 | `client-headless-event-envelope-v1` | 为 `client` 设计并实现显式 headless 模式,定义禁止 prompt / 禁止内联审批 / 只输出协议帧的行为边界。 | bouillipx | `client/main.py`;`client/session.py`;`tests/integration/test_client_cli_flow.py`;`docs/features/archive/client-headless-event-envelope-v1.md` | 2026-03-02 |
| CCLI-004 | P1 | done | CCLI-GAP-002 | `client-headless-event-envelope-v1` | 设计并实现 versioned event envelope(至少含 `schema_version`、`run_id`、`seq`、`event`、`data`),并定义与现有 JSON 输出的兼容策略。 | bouillipx | `client/render/headless.py`;`tests/unit/test_client_cli.py`;`tests/integration/test_client_cli_flow.py`;`docs/features/archive/client-headless-event-envelope-v1.md` | 2026-03-02 |
| CCLI-005 | P1 | doing | CCLI-GAP-003 | `client-external-control-plane-v1` | 设计外部控制协议入口(如 `control-stdin` 或 loopback RPC),覆盖 approvals / MCP / skills / status 的结构化控制。 | bouillipx | `client/main.py`;`client/render/control.py`;`tests/unit/test_client_cli.py`;`tests/integration/test_client_cli_flow.py`;相关 OpenSpec design/specs/tasks | 2026-03-02 |
| CCLI-006 | P2 | doing | CCLI-GAP-005 | `client-external-control-plane-v1` | 将当前 canonical MCP actions(首批为 `mcp:list/reload/show-tool`)接入外部 control plane,并明确运行中生效与错误处理语义。CLI 层 `unload` 待后续补 canonical action 后再纳入宿主协议面。 | bouillipx | `client/main.py`;`tests/integration/test_client_cli_flow.py`;`docs/features/client-external-control-plane-v1.md` | 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 |
| CCLI-005 | P1 | done | CCLI-GAP-003 | `client-external-control-plane-v1` | 设计外部控制协议入口(如 `control-stdin` 或 loopback RPC),覆盖 approvals / MCP / skills / status 的结构化控制。 | bouillipx | `client/main.py`;`client/render/control.py`;`tests/unit/test_client_cli.py`;`tests/integration/test_client_cli_flow.py`;`docs/features/archive/client-external-control-plane-v1.md`;`openspec/changes/archive/2026-03-02-client-external-control-plane-v1/` | 2026-03-02 |
| CCLI-006 | P2 | done | CCLI-GAP-005 | `client-external-control-plane-v1` | 将当前 canonical MCP actions(首批为 `mcp:list/reload/show-tool`)接入外部 control plane,并明确运行中生效与错误处理语义。CLI 层 `unload` 待后续补 canonical action 后再纳入宿主协议面。 | bouillipx | `client/main.py`;`tests/integration/test_client_cli_flow.py`;`docs/features/archive/client-external-control-plane-v1.md`;`openspec/changes/archive/2026-03-02-client-external-control-plane-v1/` | 2026-03-02 |
| CCLI-007 | P2 | doing | CCLI-GAP-004 | `client-capability-discovery-and-host-tests` | 将 `actions:list` 提升到 CLI 宿主协议面,并收敛为显式 discovery action;启动握手不纳入当前 v1 scope。 | bouillipx | `client/DESIGN.md`;`client/README.md`;`docs/features/client-capability-discovery-and-host-tests.md`;相关 OpenSpec design/specs/tasks | 2026-03-02 |
| CCLI-008 | P1 | doing | CCLI-GAP-006 | `client-capability-discovery-and-host-tests` | 新增 headless 协议稳定性、外部控制、能力发现三组集成测试,并回写 README / 设计文档中的验证锚点。 | bouillipx | `tests/integration/test_client_cli_flow.py`;`docs/features/client-capability-discovery-and-host-tests.md`;相关 OpenSpec design/specs/tasks | 2026-03-02 |

---

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
schema: spec-driven
created: 2026-03-02
Loading