Skip to content

fix(approval): align PR77 review feedback on transport ownership - #102

Merged
zts212653 merged 8 commits into
mainfrom
fix/pr77-comment-alignment
Feb 27, 2026
Merged

fix(approval): align PR77 review feedback on transport ownership#102
zts212653 merged 8 commits into
mainfrom
fix/pr77-comment-alignment

Conversation

@zts212653

Copy link
Copy Markdown
Collaborator

What

This PR is a targeted follow-up for file-level review comments on PR #77.

Changes aligned to review feedback

  1. Do not rely on instance transport state outside transport-loop paths
  • Removed mutable DareAgent._active_transport state.
  • Threaded transport explicitly through execute/session/milestone/execute/tool/approval paths.
  • _send_transport_payload now requires explicit transport argument.
  1. Approval denial should surface as tool execution outcome
  • Added explicit tool-loop status category: not_allow for approval-denied paths.
  • Tool messages written back to STM now carry status so downstream consumers can distinguish deny vs generic failure.
  1. Drop redundant approval resolved transport emission
  • Removed approval.resolved transport event emission from agent approval flow.
  • Keep approval.pending as the async wait signal.

Why

  • Prevent transport cross-talk and hidden shared-state risks when the same agent instance is reused.
  • Make denied approvals explicit and machine-readable in tool outcomes.
  • Reduce transport event noise in the approval lifecycle.

Review-comment mapping (PR #77)

  • #discussion_r2796634176 -> addressed by explicit transport threading + removal of _active_transport.
  • #discussion_r2796936639 -> addressed by removing approval.resolved emission and introducing status=not_allow.
  • #discussion_r2796667747 / #discussion_r2796940677 -> partially addressed in this PR (agent-side approval output semantics and transport ownership). The larger architecture refactor (tool-owned approval pipeline/risk-policy redesign) is intentionally scoped out of this patch set.

Test Evidence

/Users/lysander/projects/dare-framework/.venv/bin/python -m pytest \
  tests/unit/test_five_layer_agent.py \
  tests/unit/test_dare_agent_hook_transport_boundary.py \
  tests/unit/test_examples_cli.py \
  tests/unit/test_examples_cli_mcp.py \
  tests/unit/test_tool_approval_action_handler.py \
  tests/unit/test_tool_approval_manager.py
# 55 passed

Open Questions


Supersedes: #100

@zts212653

Copy link
Copy Markdown
Collaborator Author

@codex review

Please review against PR #77 file-level feedback, especially transport ownership and approval deny semantics ().

@zts212653

Copy link
Copy Markdown
Collaborator Author

补充:重点核查 approval deny 路径的 tool result 分类为 not_allow,以及 agent 侧不再通过实例状态持有 transport。

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 41f0d6e048

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread dare_framework/tool/_internal/control/approval_manager.py Outdated
Comment thread examples/05-dare-coding-agent-enhanced/cli.py Outdated
苏策 added 3 commits February 26, 2026 01:12
Implement ADR v2 end-to-end for transport event typing and approval control-plane consistency.

Key changes:
- Introduce and propagate canonical  handling via  +  and expose normalizer from transport facade.
- Keep  minimal and add  for channels that support unsolicited event polling.
- Remove legacy transport payload dead fields () from runtime payload builders and hook emission.
- Route CLI approval flows through channel/action dispatch paths and require explicit  in approval responses.
- Add  filtering in approval pending polling and align pending-state notifications with condition-based synchronization.
- Expand and tighten tests for protocol normalization, adapter behavior, action handler responses, and example CLIs.

Rationale:
- Preserve transport boundary abstraction and avoid direct internal manager coupling.
- Make event routing explicit and auditable without relying on payload-shape heuristics.
- Reduce concurrency ambiguity in approval pending wakeups and prevent cross-session polling bleed.
- Match strict review feedback by removing protocol dead fields and consistency gaps before PR.
…semantics

Address the actionable file-review comments on PR #77 with focused behavioral fixes.

Key changes:
- Remove mutable instance-level  state from .
- Thread  explicitly through execution/session/milestone/tool loops and approval emission paths.
- Update  to require explicit transport input, avoiding hidden channel selection.
- Stop emitting  transport events after resolution.
- Represent denied approval outcomes as  in tool-loop results and tool messages.
- Preserve serialization stability for tool messages via .

Tests:
- Add regression test that transport payload send requires explicit transport argument.
- Add regression test that denied approvals produce  and do not emit .
- Run approval/agent regression suite (55 tests) covering five-layer flow, CLI approval paths, and approval manager/action handler behavior.

Rationale:
- Prevent transport cross-talk/concurrency risk from shared mutable state.
- Keep approval denial semantics explicit for downstream consumers and model-facing tool messages.
- Align transport behavior with reviewer guidance that non-transport-loop paths should rely on explicit transport parameters.
Cloud Codex reported two regressions on PR #102: session-filtered polling missed deduplicated pending approvals, and the CLI hard-capped approval action transport waits at 30s.\n\nThis commit fixes both issues and adds regression coverage:\n- Track all sessions waiting on a deduplicated pending approval request and include them in session-filtered poll matching.\n- Keep approval poll transport timeout aligned with user-provided timeout_seconds/timeout_ms, with a small client-side cushion so ask() does not expire first.\n- Apply the timeout fix in both example CLIs (05 enhanced and 06 mcp) to keep behavior consistent.\n- Add manager/action-handler tests for deduplicated cross-session polling and CLI tests that assert poll timeout values are propagated to transport waits.\n\nValidation:\n- Targeted regressions: 4 passed\n- Affected unit suites: 33 passed\n- Full suite currently has unrelated pre-existing failures in builder_manager_resolution and example_10 compatibility tests.
@zts212653
zts212653 force-pushed the fix/pr77-comment-alignment branch from 41f0d6e to b4603f9 Compare February 26, 2026 09:17
@mindfn

mindfn commented Feb 26, 2026

Copy link
Copy Markdown
Collaborator

@codex 严格一点的review下。必须充分考虑功能职责和代码实现

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: b4603f96fd

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread dare_framework/transport/interaction/payloads.py
Comment thread dare_framework/agent/dare_agent.py Outdated
Comment thread dare_framework/transport/interaction/payloads.py
Move approval evaluation/pending transport emission out of DareAgent and into a dedicated GovernedToolGateway wrapper so agent orchestration only performs tool-loop control and consumes tool outcomes.\n\nKey changes:\n- add dare_framework/tool/_internal/governed_tool_gateway.py to centralize approval evaluate/wait/send at tool invoke boundary\n- switch DareAgent tool invocation to governed gateway and treat denied calls as normal tool result status=not_allow\n- remove legacy agent-level approval helpers (_resolve_tool_approval/_emit_approval_pending_message/_send_transport_payload)\n- extend EnvelopeKind with SELECT and emit approval.pending envelopes as kind=select with explicit allow/deny options\n- update example 10 response parsing to prefer envelope.event_type with payload.type fallback so removing payload type aliases does not misclassify errors\n- refresh unit tests to assert event_type/select semantics and updated boundary behavior\n\nRationale:\n- addresses PR feedback about clear responsibility boundaries (agent vs tool gateway)\n- keeps interaction protocol explicit at envelope layer\n- preserves shipped consumer correctness under event_type-first transport routing

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: d3fedb2b02

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread dare_framework/tool/_internal/governed_tool_gateway.py Outdated
Comment thread dare_framework/tool/_internal/control/approval_manager.py
Address two blocking P1 regressions reported on PR #102.\n\nKey fixes:\n- restore approval lifecycle event emission in GovernedToolGateway while waiting for human resolution\n  - emit exec.waiting_human before wait_for_resolution\n  - emit exec.resume and tool.approval after decision\n  - preserve tool.approval events for rule-based allow/deny paths\n- wire DareAgent tool loop to pass its event logger into governed gateway so event-log-driven approval flows keep functioning\n- fix deduplicated pending request wakeups in ToolApprovalManager.evaluate\n  - when a dedup hit adds a new session subscriber, notify condition waiters immediately\n  - update _track_pending_session_locked to return whether subscriber set changed\n\nRegression coverage (Red->Green):\n- test_poll_pending_session_waiter_wakes_when_dedup_adds_matching_session\n- test_no_planner_emits_approval_lifecycle_events_for_event_log_auto_resolution\n\nVerification run:\n- targeted approval/event-flow suite: 82 passed\n- full pytest baseline remains unchanged except known pre-existing builder-manager failures (7 failed / 330 passed / 11 skipped).

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: acfb1463b7

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread dare_framework/agent/dare_agent.py
Address Codex P2 on PR #102: governed gateway invocation previously passed governance metadata as explicit keyword arguments (, , ) and then expanded . If a tool legitimately used one of those keys, Python raised  before approval evaluation or tool execution.\n\nImplementation:\n- introduce  in governed gateway to carry approval metadata out-of-band from tool params\n- change  to accept the approval context as a positional argument and derive governance fields internally\n- update  tool loop to construct/pass  and keep  untouched for downstream tool invocation\n\nRegression coverage:\n- add  to verify tool-level  arguments execute successfully through the approval path\n\nVerification:\n- targeted approval/event suites pass (83 passed)\n- full project baseline unchanged except known pre-existing builder-manager failures (7 failed / 331 passed / 11 skipped).

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 212daff3f8

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread dare_framework/agent/dare_agent.py Outdated
Comment thread dare_framework/tool/_internal/governed_tool_gateway.py Outdated
…failures

Address the two new Codex P2 comments on PR #102.

Changes:
- prevent governed invoke collisions when tool args include `context`
  - add `runtime_context` to `ApprovalInvokeContext`
  - stop passing `context=` explicitly from DareAgent into governed invoke
  - in `GovernedToolGateway`, route runtime context out-of-band using internal key `__dare_runtime_context__` when tool params already contain `context`
  - in `ToolGateway.invoke`, consume that internal key, restore colliding tool arg `context`, and build `RunContext` from runtime context override
- differentiate approval denial from approval infrastructure/configuration failures
  - add `ApprovalResolution` with verdicts: allow/deny/error
  - map deny => output.status `not_allow`
  - map infrastructure/configuration errors => output.status `fail`

Red-Green regression coverage:
- test_no_planner_tool_params_context_does_not_collide_with_runtime_context
- test_no_planner_missing_approval_manager_reports_fail_status

Verification:
- targeted approval/transport/gateway suites: 94 passed
- full baseline unchanged except known pre-existing builder-manager failures:
  7 failed / 333 passed / 11 skipped

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: d35a7a7f8b

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread dare_framework/tool/tool_gateway.py Outdated
Comment thread dare_framework/tool/_internal/governed_tool_gateway.py Outdated
Address PR #102 review feedback (P1 + P2) in one pass.

Key changes:
- Added RuntimeContextOverride internal wrapper and shared reserved key constant.
- Updated ToolGateway to ignore caller-supplied __dare_runtime_context__ values unless they carry the trusted internal wrapper type.
- Kept tool-argument/context collision recovery while preventing user-controlled runtime context replacement.
- Updated GovernedToolGateway to pass effective execution params (including reinjected context arg) into approval evaluation.
- Updated governed runtime-context forwarding to use the internal wrapper type.

Tests:
- Added regression test ensuring untrusted __dare_runtime_context__ does not override run_context deps.
- Added unit test ensuring approval evaluation uses effective params when context collides with invoke signature.
- Verified relevant gateway/five-layer tests pass after changes.
@mindfn

mindfn commented Feb 27, 2026

Copy link
Copy Markdown
Collaborator

这条评论只讨论“如何一次性把授权/权限链路做对”(当前项目仍在开发阶段,不需要兼容历史协议)。

我先给结论:

  • 这次改动方向是对的(把审批从 Agent loop 下沉到 Gateway 边界),但目前实现仍存在边界泄漏 + 语义不一致 + 一个确定性 correctness bug
  • 如果目标是“这轮直接把架构打稳”,建议不要再做零碎修补,而是按下述 3 个维度一次性收敛。

1) 架构层(职责边界)

问题 A:审批结果语义仍通过 ToolResult.output["status"] 字符串跨层传递,导致 Agent 与 Gateway 重新耦合

证据:

  • Gateway 在审批失败时返回:ToolResult(success=False, output={"status": ...}, error=...)
    • dare_framework/tool/_internal/governed_tool_gateway.py:115-121
  • Agent 再去解析 output.status 推断 approved
    • dare_framework/agent/dare_agent.py:1014-1023

这意味着:

  • 授权域语义被塞进了“业务输出 payload”;
  • Agent 必须了解 Gateway 的 status 字符串协议(not_allow/fail);
  • 任意 Tool 的真实 output 字段与治理状态字段存在语义冲突风险。

建议(一次性改):

  • ToolResult 增加显式类型化结果类别(例如 result_kind: success | denied | policy_error | execution_error)。
  • Agent 只看 ToolResult 的结构化字段,不再解析 output["status"]
  • output 只承载工具业务输出,不再承载治理控制面信号。

2) 设计层(审批模型一致性)

问题 B(P1):跨 session 去重与 scope=session 规则语义冲突,规则会落到错误 session

证据链:

  • pending 按 capability_id + params_hash 去重,跨 session 会复用同一个 request
    • dare_framework/tool/_internal/control/approval_manager.py:315-337
  • 生成 session scope 规则时,绑定的是 request.session_id(首个请求者)
    • dare_framework/tool/_internal/control/approval_manager.py:488

我本地最小复现(直接运行 approval manager):

same request? True
rules ... 'scope': 'session', 'session_id': 'A'

即:session B 对 dedup 后请求执行 grant,最终规则仍绑定到 session A

这不是风格问题,而是确定性逻辑错误。

建议(一次性改):

  • 明确“审批动作主体 session”概念(actor_session_id);
  • grant/denyscope=session 时必须使用 actor_session_id 绑定规则;
  • 如果拿不到 actor_session_id,就不要允许 scope=session(fail fast),避免 silently 错绑。

3) 协议/实现层(transport contract)

问题 C:协议声明、代码分支、运行行为三者不一致

证据:

  • 文档仍宣称会发 approval.resolved
    • docs/guides/Tool_Approval_Memory.md:138-140
  • 运行链路只发 pending,不发 resolved(Gateway resolve 后无 transport emission)
    • dare_framework/tool/_internal/governed_tool_gateway.py:207-250
  • 代码里仍保留 build_approval_resolved_payload,但全仓库无调用
    • dare_framework/transport/interaction/payloads.py:53-80

这会导致:客户端对审批生命周期无法建立稳定、可验证的协议预期。

建议(一次性改,二选一但要全链路一致):

  1. 保留完整生命周期:统一发 approval.pending + approval.resolved
  2. 只保留 pending:删除 resolved 的类型、文档、payload helper、adapter 分支,彻底去除死语义。

不要继续处于“文档说有,代码留着,但运行不发”的中间态。


4) 当前实现中的直接语义错误(补充)

AFTER_TOOL.approved 当前推导逻辑把审批系统错误(status=fail)标记成 approved=True

  • dare_framework/agent/dare_agent.py:1016-1023

这会污染审计/hook 语义(看起来像“已批准后执行失败”,实际是“审批系统失败或配置错误”)。

建议:

  • approved 不应由 output.status 推导;
  • 应由明确的授权决策字段推导(allow/deny/error),或改成更精确字段(例如 approval_decision, approval_checked)。

5) 建议的落地方式(一次性收敛,不打补丁)

建议按 3 个提交完成,避免继续在现有字符串协议上叠逻辑:

  1. Result 模型收敛
  • 扩展 ToolResult 为类型化结果(治理/执行语义出 output);
  • Agent/Hook/Event 全部改为消费类型化字段;
  • 删除 output["status"] 约定。
  1. 审批模型收敛
  • 在 approval manager 中引入 actor_session_id;
  • 修复 dedup + session scope 规则归属;
  • 为该场景补单测(grant from session B must bind to B)。
  1. 协议收敛
  • 明确并固定 transport lifecycle(pending-only 或 pending+resolved);
  • 同步更新 docs / adapters / payload helpers / tests;
  • 删除所有死代码与死分支。

6) 最低验收标准(建议作为 merge gate)

  • scope=session 在 dedup 场景下规则绑定正确 session(必须有回归测试)。
  • Agent 不再解析 ToolResult.output 中的治理状态字符串。
  • transport 协议文档与运行行为完全一致(不允许“文档有、代码无”)。
  • AFTER_TOOL 的 approval 相关字段语义单义且可审计。

如果愿意,我可以基于上述方案直接给出一个“最小且完整”的重构 PR 草案(按 3 commits 拆分)。

@mindfn

mindfn commented Feb 27, 2026

Copy link
Copy Markdown
Collaborator

补充一条更“可执行”的 review(按初级同学可落地的方式写),目标是把这个特性从“勉强可用”做到“易用 + 好用 + 可维护 + 可验证”。

先说原则:

  • 问题多不可怕,可怕的是问题被混在一起、没有被类型化。
  • 先把“语义契约”定清楚,再改代码;否则只会在字符串/分支上打补丁。

A. 当前问题分层清单(按严重级别)

P0 Correctness

  1. scope=session 在 dedup 场景会绑错 session(确定性 bug)
  • 去重逻辑:approval_manager.py:315-337
  • 建规则绑定:approval_manager.py:488
  • 复现场景:A、B 两个 session 同参数并发触发同一 pending,B 做 grant(session),规则最终写到 A。

这会直接破坏“session 级授权”的可信性。

P1 语义一致性

  1. AFTER_TOOL.approved 的语义被误判
  • 逻辑位置:dare_agent.py:1014-1023
  • 现在 approved=False 仅在 status=="not_allow",审批系统错误(status=="fail")会被记为 approved=True

结果:审计和 hook 看到的是“已批准后执行失败”,但真实是“审批系统失败/未配置”。

  1. 协议声明与运行行为不一致
  • 文档写有 approval.resolveddocs/guides/Tool_Approval_Memory.md:138-140
  • 运行链路不发 resolved:governed_tool_gateway.py:207-250
  • 代码仍保留 resolved helper:payloads.py:53-80
  • adapter 仍有 resolved 分支:transport/_internal/adapters.py:64

这是典型 contract drift。

P1 易用性

  1. 05/06 CLI 虽接入 approval channel,但执行任务时没把 transport 传给 agent
  • examples/05.../cli.py:336-339
  • examples/06.../cli.py:372-376

这意味着审批 pending 事件无法实时推送到 CLI(只能靠用户手动 /approvals poll),体验上是“可操作但不顺手”。

P2 健壮性/维护性

  1. action 响应事件类型校验过宽
  • examples/05.../cli.py:466-470
  • examples/06.../cli.py:555-559

当前只拦截 error,未强校验 result,未知 event_type 会被当成功路径继续解析。

  1. 05/06 审批命令实现几乎完全重复
  • 两个 CLI 的 approvals handling 基本复制粘贴,后续继续演进时极易出现“一个修了另一个漏修”。

B. 该怎么分析(先分析再改)

建议先写一页“授权链路 invariants”,至少包含以下 8 条:

  1. 同一工具调用最终只能归类为一种结果:allowed / denied / policy_error / execution_error
  2. approved 只能表达“有无 allow 决策”,不能混入系统错误。
  3. scope=session 规则必须绑定“执行 grant/deny 的 actor session”。
  4. dedup 只影响“pending request 复用”,不能改变规则归属语义。
  5. transport lifecycle 必须单一来源定义(pending-only 或 pending+resolved)。
  6. 文档、代码、测试三者必须对齐同一生命周期。
  7. 工具业务输出与治理状态不得混放同一字段。
  8. CLI 在 pending 时应提供实时反馈,不应要求用户猜测何时 poll。

然后把现状映射到 invariants,看每条谁违背了。


C. 该怎么设计(目标架构)

1) 结果模型类型化

当前把治理状态塞进 ToolResult.output["status"]。这会导致跨层字符串协议。

建议:

  • ToolResult 增加结构化结果类别(枚举)。
  • output 只放工具业务数据。
  • Agent/Hooks/EventLog 只消费结构化字段,不解析 output

2) 授权模型分离两个角色

  • request_owner_session_id:首次创建 pending 的 session。
  • actor_session_id:执行 grant/deny 的 session。

规则绑定(scope=session)必须用 actor_session_id

3) 协议生命周期定版

明确选择:

  • 方案 A:approval.pending + approval.resolved
  • 方案 B:仅 approval.pending

选一个后删除另一套的文档、分支、helper、枚举,避免半迁移状态。

4) CLI 产品化目标

  • pending 出现时能即时感知(自动提示 request_id/快捷操作)。
  • /approvals poll 作为 fallback,而不是主交互手段。
  • 错误提示区分:用户 deny vs 系统故障。

D. 该怎么开发(建议提交顺序)

  1. Commit 1: 类型契约
  • 引入结构化 approval/tool outcome 类型。
  • 移除 Agent 对 output["status"] 的解析。
  1. Commit 2: approval manager 语义修复
  • grant/deny 接受 actor_session_id。
  • scope=session 规则绑定 actor。
  • 补 dedup + session scope 回归测试。
  1. Commit 3: transport lifecycle 收敛
  • 选定 pending-only 或 pending+resolved。
  • 同步删改 payloads/types/adapters/docs/tests
  1. Commit 4: CLI 易用性
  • 运行任务时传 transport,支持实时 pending 提示。
  • 严格校验 action 响应 event_type。
  • 抽 05/06 公共 approvals helper,消除复制。
  1. Commit 5: 文档与示例统一
  • 更新 guide + interfaces + example README。
  • 给出一条“从 pending 到 grant/deny 到恢复执行”的完整时序图。

E. 测试应覆盖到什么程度(最小但完整)

单测

  1. dedup 场景下,B session grant(session) 规则必须绑定 B。
  2. AFTER_TOOL.approved 在 deny/infra_error 下的区分。
  3. lifecycle 合同测试:是否发 resolved(根据你最终协议决定)。
  4. action 响应未知 event_type 必须 fail-fast。

集成测试

  1. 两个并发 session 触发同 fingerprint pending,分别 grant/deny,行为一致且可解释。
  2. 事件日志与 transport 事件的一致性(至少保证不会互相矛盾)。

示例回归

  1. 05/06 CLI:无需手工 poll 也能感知 pending(如果设计为实时)。
  2. 07 示例:文档描述与实际输出逐条一致。

F. 文档应达到什么标准

  • 不是“告诉别人你改了什么”,而是“定义别人必须遵守什么”。
  • 必须明确:
  1. 术语定义(allow/deny/error/pending/resolved)
  2. 状态机与时序
  3. 各字段语义(谁写、谁读、何时出现)
  4. 兼容策略(本项目当前可明确写“不保证向后兼容”)

如果按上面收敛,你这个特性会从“可以跑”变成“可预测、可解释、可维护”。这才是授权系统真正可长期演进的状态。

@mindfn

mindfn commented Feb 27, 2026

Copy link
Copy Markdown
Collaborator

为了推动这条 PR 实际落地,我再给一个“合并前收敛清单”(请作者在本线程逐项回复 will-fixwon’t-fix + reason,不要跳项)。

Merge Gate(建议按此执行)

  1. 修复 session scope 归属 bug(必须)
  • 目标:dedup 场景下,执行 grant/deny 的 session 才是 scope=session 规则的绑定对象。
  • 交付:
    • 代码修复(actor_session_id 语义)
    • 回归测试:并发 A/B 同 fingerprint,B 授权后规则绑定 B。
  1. 修复 approval 语义误报(必须)
  • 目标:AFTER_TOOL.approved 不能把审批系统错误标记为 True
  • 交付:
    • 字段语义定义(approved / decision / error 各自含义)
    • 测试覆盖 deny 与 infra_error 两条路径。
  1. 统一 transport 合同(必须)
  • 在两者中二选一并全链路一致:
    • pending + resolved,或
    • pending-only
  • 交付:代码、文档、测试、示例全量同步,删除死分支/死 helper。
  1. 提升 CLI 可用性(强烈建议)
  • 目标:审批交互不依赖用户“猜测何时 poll”。
  • 最低要求:执行任务路径可接收实时 pending 事件(或明确说明为何不做)。
  • 同时对 action 响应做严格 event_type 校验(未知类型 fail-fast)。
  1. 去除重复实现(强烈建议)
  • 05/06 CLI 的 approvals handling 抽公共 helper,避免双份逻辑继续漂移。

交付格式(请按这个模板回复)

  • Item 1: will-fix / won’t-fix(原因)
  • Item 2: will-fix / won’t-fix(原因)
  • Item 3: 选择 A/B(并说明为什么)
  • Item 4: will-fix / won’t-fix(原因)
  • Item 5: will-fix / won’t-fix(原因)

并在最终更新时附上:

  • 变更点到文件的映射
  • 新增/修改测试清单
  • 实际测试命令与结果

这样这条 PR 就能从“讨论层面”进入“可验收层面”。

@zts212653

Copy link
Copy Markdown
Collaborator Author

已按 PR 上的收敛方向直接落盘:\n- 互动分发按 (message/action/control)收口,去耦消息/动作/控制路径;\n- Builder 侧注入 完整链路;\n- DefaultAgentChannel 的分发与超时/错误回包行为已统一;\n- stdio 入口按 命令映射 -> 并区分本地生命周期命令。\n如果需要,我再补一轮本地验证(本消息为同步状态同步/收敛确认)。

@zts212653

Copy link
Copy Markdown
Collaborator Author

已按 PR 收敛方向落盘同步:

  • 互动分发按 message/action/control 分流,按现有 TransportEnvelope 做了主线收口,去耦三类路径。
  • Builder 注入 DefaultAgentChannel 与 ActionHandlerDispatcher/AgentControlHandler 的链路已闭合。
  • DefaultAgentChannel 分发、超时、成功/失败回包与 reply_to 关联逻辑已统一。
  • stdio 入口按斜杠命令完成动作映射,本地命令如 /quit /exit 独立处理。

以上是本次收敛结果;如要,我再补一轮本地验证(我先前这条消息作为阶段同步/合入确认)。

@mindfn

mindfn commented Feb 27, 2026

Copy link
Copy Markdown
Collaborator

二次完整 review(基于当前 head 1da820a2d88eebe37c54494809819ad8d40edbf3,复核时间 2026-02-27)结论:目前仍有 3 个阻塞项 + 2 个建议项。这条评论只列仍然成立的问题,不重复已修复项。

Blocking Findings

1) [P0] scope=session 在 dedup 场景下规则绑定对象仍然错误

证据链:

  • pending dedup 仍按 fingerprint 复用同一 request:dare_framework/tool/_internal/control/approval_manager.py:315-337
  • grant/deny 入口没有 actor session 参数:approval_manager.py:373-403
  • 建 rule 时 SESSION 仍绑定 request.session_id(首个创建 pending 的 session):approval_manager.py:488

为何是阻塞:

  • 在 A/B 两个 session 复用同一个 pending 的场景,B 执行 grant(scope=session),最终 rule 仍会落到 A,直接破坏 session 级授权语义。

修复要求:

  • grant/deny/_resolve_request/_build_rule 链路引入 actor_session_id
  • scope=session 时只允许绑定 actor_session_id;拿不到 actor 时 fail fast,不要 silent fallback。

必须补的回归测试:

  • 并发 A/B 同 fingerprint,B 授权后 rule 必须绑定 B。

2) [P1] AFTER_TOOL.approved 语义仍被污染(审批系统错误被当作 approved)

证据链:

  • Gateway 已明确区分 deny 与 infra error:deny->status=not_allow,error->status=faildare_framework/tool/_internal/governed_tool_gateway.py:115-121
  • Agent hook 里 approved = (status != "not_allow")dare_framework/agent/dare_agent.py:1014-1023

为何是阻塞:

  • 审批系统错误(fail)被上报成 approved=True,审计与 hook 语义错误,排障会被误导。

修复要求:

  • 不要再由 output.status 反推 approved
  • 至少把 approval 决策语义显式化(allow/deny/error),approved 仅在 allow 为 true。

必须补的回归测试:

  • deny 路径 approved=False
  • approval infra error 路径 approved=False 且 decision/error 可区分

3) [P1] transport 合同仍处于漂移状态(文档/类型/运行行为不一致)

证据链:

  • 文档仍声明会发 approval.resolveddocs/guides/Tool_Approval_Memory.md:138-140
  • 当前测试反向断言“不会发 resolved”:tests/unit/test_five_layer_agent.py:609-611
  • 代码仍保留 resolved 类型与分支:
    • dare_framework/transport/types.py:27
    • dare_framework/transport/interaction/payloads.py:53-80
    • dare_framework/transport/_internal/adapters.py:64-71

为何是阻塞:

  • 协议对客户端不可预测:文档说有、运行不发、代码还留分支。

修复要求(二选一,但必须全链路一致):

  • 方案 A:恢复并稳定发送 approval.resolved
  • 方案 B:明确 pending-only,删除 resolved 的 docs/types/payload helper/adapter 分支与遗留映射。

Non-blocking but Recommended

4) [P2] 05/06 CLI 的执行路径未传 transport,approval.pending 无法实时推送

证据:

  • run_taskagent(Task(...)) 未传 transport:
    • examples/05-dare-coding-agent-enhanced/cli.py:336-339
    • examples/06-dare-coding-agent-mcp/cli.py:372-376
  • BaseAgent.__call__ 在未传 transport 时使用 _NO_OP_AGENT_CHANNELdare_framework/agent/base_agent.py:70-71

建议:

  • 要么显式传入 transport,要么在文档里明确“CLI 主要靠 /approvals poll,非实时 push”。

5) [P2] approvals action 响应对 event_type 校验仍过宽

证据:

  • 仅拦截 error,未强校验 result
    • examples/05.../cli.py:466-470
    • examples/06.../cli.py:555-559

建议:

  • action 返回应严格要求 event_type == "result",其他类型直接 fail-fast,防止协议漂移被吞掉。

建议作为 merge gate 的最小闭环

  1. 修复 session scope 绑定对象(含回归测试)。
  2. 修复 AFTER_TOOL.approved 语义(含 deny/error 区分测试)。
  3. 统一 transport 合同并清理死语义(docs + code + tests 对齐)。

如果上述 3 项不收敛,这条 PR 仍不建议合并。

@zts212653
zts212653 merged commit cf6c66a into main Feb 27, 2026
6 checks passed
@zts212653
zts212653 deleted the fix/pr77-comment-alignment branch February 27, 2026 07:30
@zts212653

Copy link
Copy Markdown
Collaborator Author

已按你说的把 #102 收束完毕并已合入。

本次我同步落盘了当前遗留修复(runtime context 派发参数去重污染)并补了回归测试,另起一个追踪:

本次 follow-up PR 先做一项 unblock(审批去重/持久化中剥离 dare_runtime_context),其余 3 个阻塞项与 2 个建议项我已在 issue 111 按清单跟进。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants