[PR #3097] [CLOSED] fix(session): 修复会话恢复后残留的工具不可用状态 #5613

Closed
opened 2026-10-31 01:07:59 +00:00 by bsakaguchi · 0 comments
Owner

📋 Pull Request Information

Original PR: https://github.com/morluto/rea/pull/3097
Author: @wxggzz
Created: 10/14/2026
Status: ❌ Closed

Base: main ← Head: codex/fix-session-recovery-availability


📝 Commits (2)

  • ef0b496 fix(session): 修复会话恢复后残留的工具不可用状态
  • 82e08c8 Merge remote-tracking branch 'origin/main' into HEAD

📊 Changes

1 file changed (+192 additions, -0 deletions)

View changed files

📝 tests/composition/analysis-sessions/binarySession.test.ts (+192 -0)

📄 Description

摘要

Fixes #2657

修复目标切换取消后恢复原目标时,新的客户端运行仍继承旧客户端 provider_unavailable 状态的问题。统一正常打开与恢复路径的 binding 激活入口,让失败观察随客户端运行更新,同时保留调查证据和 Unknown 历史。

问题与预期行为

最小触发过程:

  1. 打开目标 A,执行查询并触发 ProviderAdapterError,同 provider 的操作被标记不可用。
  2. 切换到目标 B,在旧客户端关闭期间取消。
  3. 会话恢复目标 A,并分配新的 analysis_run.run_id。
  4. 修复前,binary_session.tool_availability 仍沿用旧客户端的失败;Agent 即使尚未尝试新客户端,也会收到不可用提示。

在新 binding 安装完成后,工具清单不应继续继承已退役客户端的失败。这里的“可用”是恢复既有能力声明,并不代表提前验证了尚未启动的 provider;新客户端实际调用失败时仍会正常记录不可用状态。

代表性 MCP 输出(通过 expandToolAvailability 展开,仅摘录变化字段):

// 修复前:已经是新 run,仍残留旧客户端错误
{"name":"address_name","available":false,"reason":"provider_unavailable","remediation":"ProviderAdapterError: Provider fixture adapter failed during address_name"}
// 修复后:再次查询之前即更新发现结果
{"name":"address_name","available":true,"reason":"available","remediation":null}

修改与范围

  • 在 BinarySession 引入 #activate(binding),由正常打开与成功恢复共同调用。
  • 先安装新 binding,再清空旧运行的 availability 观察并通知订阅者,使通知读取到新的 run。
  • 同目标的存活客户端复用和提前取消不经过新 binding 激活,保留该运行的真实错误。
  • 不改变 provider 路由、健康检查、懒创建、关闭重试或快照逻辑;不新增自动重试。

契约与边界影响

  • 语义归属与最早修改阶段:应用层 BinarySession 安装新客户端 binding 时。
  • 贡献范围与维护者决策:现有会话恢复逻辑的普通缺陷修复,无新增 provider 或执行能力,不需要提前范围审批。
  • CLI、MCP 与工具清单:输入及输出 schema 不变;修正既有可用性字段与通知的取值。新增 MCP 测试实际经过 SDK、内存传输与服务端处理链。
  • Provider、bridge、目标格式与平台:接口不变,无 provider 专属适配修改。
  • Evidence、artifact、provenance:历史证据与 Unknown 保留,测试对恢复前后内容作精确比较。
  • 目标、权限、副作用与清理:不扩大目标选择或授权;保留现有客户端关闭/恢复语义。新增测试仅使用临时 fixture 和受控 provider,不执行第三方目标程序。
  • 元数据、安装与发行:无变更,未提交构建输出。
  • 预期效果:只改变进程内会话的可用性状态归属;没有新增目标执行、注入、联网、持久化写入或保护绕过能力。

证据与回归覆盖

新增 3 个回归用例:

  1. Composition:取消切换后恢复新 run,在重试前更新查询/写操作的可用性与通知,保留 Evidence/Unknown;新客户端后续失败仍重新标记不可用。
  2. Composition:存活客户端复用、提前取消不清除原运行故障,也不创建新客户端或发送虚假恢复通知。
  3. MCP 边界:通过协议取消目标切换,验证 binary_session 在新查询前更新工具清单,并验证随后查询成功。

基线复现:在 b3c5672ce 的生产代码上加入测试后执行,composition 恢复用例与 MCP 用例均因预期 available: true、实际 available: false 而失败;复用/提前取消对照用例通过。应用修复后全部通过。

已验证历史证据、显式 Unknown 和后续真实失败不会被恢复逻辑隐藏。

实际执行的验证

环境:macOS,Node.js 24.18.0,npm 11.16.0。

npm run test:focused -- \
  tests/boundary/mcp/sessionAvailabilityRecovery.test.ts \
  tests/boundary/mcp/sessionMcp.test.ts \
  tests/boundary/mcp/sessionEvidenceRecovery.test.ts \
  tests/composition/analysis-sessions/binarySession.test.ts \
  tests/composition/analysis-sessions/binarySessionCleanupRetry.test.ts \
  tests/composition/analysis-sessions/providerBinding.test.ts \
  src/application/binary/BinarySessionLiveness.test.ts
  • 上述测试:7 个文件、76 个测试通过,其中 3 个为本次新增用例。
  • npm run check:通过类型、lint、格式、knip、元数据、模块边界及架构约束检查;lint 为 0 错误,仓库仍有警告。
  • npm run verify:test-discovery:通过,1243 个测试文件均被且仅被发现一次。
  • git diff --check:通过。

兼容性、安全与验证限制

  • 无破坏性 schema 变更或迁移要求。
  • 未运行真实 Hopper/Ghidra、浏览器或其他操作系统的 provider 验证;本次 MCP 覆盖使用受控 provider,不能等同于真实逆向引擎验证。
  • 未执行全仓库测试及覆盖率套件;完整 CI 结果以该 PR 当前提交的远端检查为准。
  • 无新权限、凭据、私人目标样本或安装依赖;不涉及保护绕过与攻击自动化。
  • 本 PR 的源码分析、补丁和测试使用 Codex 辅助完成。

合并前检查

  • 对应可复现的具体问题,已关联 issue。
  • 范围聚焦于现有行为修复,无待批准的权限扩展。
  • 标题遵循 type(scope): outcome。
  • 回归覆盖可观察行为与重要失败路径。
  • 未改变文档契约、schema 或生成元数据,不需要同步这些内容。
  • 提供代表性 MCP 输出与真实验证结果。
  • 已检查补丁中的凭据、无关改动与未经验证的声明。

🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.

## 📋 Pull Request Information **Original PR:** https://github.com/morluto/rea/pull/3097 **Author:** [@wxggzz](https://github.com/wxggzz) **Created:** 10/14/2026 **Status:** ❌ Closed **Base:** `main` ← **Head:** `codex/fix-session-recovery-availability` --- ### 📝 Commits (2) - [`ef0b496`](https://github.com/morluto/rea/commit/ef0b4962b61f61fdbf0d9ca77be14074985b0f4a) fix(session): 修复会话恢复后残留的工具不可用状态 - [`82e08c8`](https://github.com/morluto/rea/commit/82e08c8446ea95e4307477701cf541e93276052f) Merge remote-tracking branch 'origin/main' into HEAD ### 📊 Changes **1 file changed** (+192 additions, -0 deletions) <details> <summary>View changed files</summary> 📝 `tests/composition/analysis-sessions/binarySession.test.ts` (+192 -0) </details> ### 📄 Description ## 摘要 Fixes #2657 修复目标切换取消后恢复原目标时,新的客户端运行仍继承旧客户端 `provider_unavailable` 状态的问题。统一正常打开与恢复路径的 binding 激活入口,让失败观察随客户端运行更新,同时保留调查证据和 Unknown 历史。 ## 问题与预期行为 最小触发过程: 1. 打开目标 A,执行查询并触发 `ProviderAdapterError`,同 provider 的操作被标记不可用。 2. 切换到目标 B,在旧客户端关闭期间取消。 3. 会话恢复目标 A,并分配新的 `analysis_run.run_id`。 4. 修复前,`binary_session.tool_availability` 仍沿用旧客户端的失败;Agent 即使尚未尝试新客户端,也会收到不可用提示。 在新 binding 安装完成后,工具清单不应继续继承已退役客户端的失败。这里的“可用”是恢复既有能力声明,并不代表提前验证了尚未启动的 provider;新客户端实际调用失败时仍会正常记录不可用状态。 代表性 MCP 输出(通过 `expandToolAvailability` 展开,仅摘录变化字段): ```jsonc // 修复前:已经是新 run,仍残留旧客户端错误 {"name":"address_name","available":false,"reason":"provider_unavailable","remediation":"ProviderAdapterError: Provider fixture adapter failed during address_name"} // 修复后:再次查询之前即更新发现结果 {"name":"address_name","available":true,"reason":"available","remediation":null} ``` ## 修改与范围 - 在 `BinarySession` 引入 `#activate(binding)`,由正常打开与成功恢复共同调用。 - 先安装新 binding,再清空旧运行的 availability 观察并通知订阅者,使通知读取到新的 run。 - 同目标的存活客户端复用和提前取消不经过新 binding 激活,保留该运行的真实错误。 - 不改变 provider 路由、健康检查、懒创建、关闭重试或快照逻辑;不新增自动重试。 ## 契约与边界影响 - 语义归属与最早修改阶段:应用层 `BinarySession` 安装新客户端 binding 时。 - 贡献范围与维护者决策:现有会话恢复逻辑的普通缺陷修复,无新增 provider 或执行能力,不需要提前范围审批。 - CLI、MCP 与工具清单:输入及输出 schema 不变;修正既有可用性字段与通知的取值。新增 MCP 测试实际经过 SDK、内存传输与服务端处理链。 - Provider、bridge、目标格式与平台:接口不变,无 provider 专属适配修改。 - Evidence、artifact、provenance:历史证据与 Unknown 保留,测试对恢复前后内容作精确比较。 - 目标、权限、副作用与清理:不扩大目标选择或授权;保留现有客户端关闭/恢复语义。新增测试仅使用临时 fixture 和受控 provider,不执行第三方目标程序。 - 元数据、安装与发行:无变更,未提交构建输出。 - 预期效果:只改变进程内会话的可用性状态归属;没有新增目标执行、注入、联网、持久化写入或保护绕过能力。 ## 证据与回归覆盖 新增 3 个回归用例: 1. Composition:取消切换后恢复新 run,在重试前更新查询/写操作的可用性与通知,保留 Evidence/Unknown;新客户端后续失败仍重新标记不可用。 2. Composition:存活客户端复用、提前取消不清除原运行故障,也不创建新客户端或发送虚假恢复通知。 3. MCP 边界:通过协议取消目标切换,验证 `binary_session` 在新查询前更新工具清单,并验证随后查询成功。 基线复现:在 `b3c5672ce` 的生产代码上加入测试后执行,composition 恢复用例与 MCP 用例均因预期 `available: true`、实际 `available: false` 而失败;复用/提前取消对照用例通过。应用修复后全部通过。 已验证历史证据、显式 Unknown 和后续真实失败不会被恢复逻辑隐藏。 ## 实际执行的验证 环境:macOS,Node.js 24.18.0,npm 11.16.0。 ```bash npm run test:focused -- \ tests/boundary/mcp/sessionAvailabilityRecovery.test.ts \ tests/boundary/mcp/sessionMcp.test.ts \ tests/boundary/mcp/sessionEvidenceRecovery.test.ts \ tests/composition/analysis-sessions/binarySession.test.ts \ tests/composition/analysis-sessions/binarySessionCleanupRetry.test.ts \ tests/composition/analysis-sessions/providerBinding.test.ts \ src/application/binary/BinarySessionLiveness.test.ts ``` - 上述测试:7 个文件、76 个测试通过,其中 3 个为本次新增用例。 - `npm run check`:通过类型、lint、格式、knip、元数据、模块边界及架构约束检查;lint 为 0 错误,仓库仍有警告。 - `npm run verify:test-discovery`:通过,1243 个测试文件均被且仅被发现一次。 - `git diff --check`:通过。 ## 兼容性、安全与验证限制 - 无破坏性 schema 变更或迁移要求。 - 未运行真实 Hopper/Ghidra、浏览器或其他操作系统的 provider 验证;本次 MCP 覆盖使用受控 provider,不能等同于真实逆向引擎验证。 - 未执行全仓库测试及覆盖率套件;完整 CI 结果以该 PR 当前提交的远端检查为准。 - 无新权限、凭据、私人目标样本或安装依赖;不涉及保护绕过与攻击自动化。 - 本 PR 的源码分析、补丁和测试使用 Codex 辅助完成。 ## 合并前检查 - [x] 对应可复现的具体问题,已关联 issue。 - [x] 范围聚焦于现有行为修复,无待批准的权限扩展。 - [x] 标题遵循 `type(scope): outcome`。 - [x] 回归覆盖可观察行为与重要失败路径。 - [x] 未改变文档契约、schema 或生成元数据,不需要同步这些内容。 - [x] 提供代表性 MCP 输出与真实验证结果。 - [x] 已检查补丁中的凭据、无关改动与未经验证的声明。 --- <sub>🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.</sub>
bsakaguchi 2026-10-31 01:07:59 +00:00
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
morluto/rea#5613
No description provided.