[GH-ISSUE #4276] [Design] Define recovery for raw partial observations after MCP cancellation #1690

Open
opened 2026-10-16 21:09:07 +00:00 by bsakaguchi · 1 comment
Owner

Originally created by @morluto on GitHub (Oct 15, 2026).
Original GitHub issue: https://github.com/morluto/rea/issues/4276

Decision needed

Define whether typed raw provider partial observations should remain inline-only or support recovery after an MCP client cancels. The existing Evidence bundle records partial Evidence with an ID; it does not retain every raw error observation. Clarify this boundary now and choose any broader retention contract before implementing it.

Context and evidence

Observed on audit head 5c6005b88a4d20dfd4042476f4e056344afe29bb, with the real MCP SDK client/server and linked in-memory transports. A controlled ADB port waited for cancellation, then returned AnalysisCancelledError("pull_adb_file") with a typed raw acquired-file observation (fixture serial/path and digest_status: "unknown"). No device, file transfer, GUI, or personal data was used.

The client request rejected on abort; the server received the signal and completed with an error. A later ping succeeded. get_evidence_bundle with detail: "summary" and the operation filter reported total_retained_records: 0 and matching_records: 0. The raw partial was not recoverable through Evidence tools after the SDK suppressed the reply.

Source explanation: deliverEvidenceResult records an error partial only when it carries evidence_id. AdbAcquiredFilePartialObservation is a provider-owned raw provider_id/operation/result shape. The error retains it in process, but there is no durable record referenced by the bundle. Existing documentation promises recovery for partial Evidence, including JavaScript reconstruction; it does not promise it for all raw provider errors. This is a confirmed runtime consequence and a contract/design question, not an established violation of the current documented contract.

This differs from #4261: that fix retains successful provider results through late abort and records typed partial Evidence. This probe starts from a provider error carrying raw partial data.

Expected interaction with targets

Documentation clarification has no target interaction. The executed probe used a controlled provider and real in-process MCP protocol. Any future retention implementation would read/retain existing returned data; target execution and cleanup authority must remain unchanged.

Boundary details

Preserve the distinction between observations, validated Evidence, primary failure, cleanup state, and unknown provenance. An empty Evidence bundle cannot establish that no native work or partial side effect occurred. Do not invent an Evidence identity or observed confidence for arbitrary raw errors in the generic transport adapter.

Options and tradeoffs

  • Keep raw partials inline-only and document the cancellation/recovery limit explicitly. The clarification is included in #4274.
  • Have individual producing providers build partial Evidence where identity and provenance are established; retain unknown or incomplete fields truthfully.
  • Design bounded raw-error retention separately, with explicit lifetime, size, export, and lookup semantics. This is broader than wrapping every error in Evidence.

Verification available so far

Observed SDK cancellation/reply suppression, server completion, same-connection ping, and absence from the Evidence bundle. The probe is disposable under .cache/codebase-audit/adb-raw-partial-cancel-probe.mts; it is not committed or a real ADB reproduction. Exact invocation/toolchain will be added with the result record.

Success criteria and open questions

Document the current boundary; decide which facts, if any, should be recoverable; establish the owning producer and provenance rules; then cover SDK cancellation, error reply delivery, lookup/export, capacity/lifetime, and successful controls for the chosen contract. Until that decision, do not infer a product bug for every raw partial error or silently expand retention.

References

Originally created by @morluto on GitHub (Oct 15, 2026). Original GitHub issue: https://github.com/morluto/rea/issues/4276 ### Decision needed Define whether typed raw provider partial observations should remain inline-only or support recovery after an MCP client cancels. The existing Evidence bundle records partial Evidence with an ID; it does not retain every raw error observation. Clarify this boundary now and choose any broader retention contract before implementing it. ### Context and evidence Observed on audit head `5c6005b88a4d20dfd4042476f4e056344afe29bb`, with the real MCP SDK client/server and linked in-memory transports. A controlled ADB port waited for cancellation, then returned `AnalysisCancelledError("pull_adb_file")` with a typed raw acquired-file observation (fixture serial/path and `digest_status: "unknown"`). No device, file transfer, GUI, or personal data was used. The client request rejected on abort; the server received the signal and completed with an error. A later ping succeeded. `get_evidence_bundle` with `detail: "summary"` and the operation filter reported `total_retained_records: 0` and `matching_records: 0`. The raw partial was not recoverable through Evidence tools after the SDK suppressed the reply. Source explanation: `deliverEvidenceResult` records an error partial only when it carries `evidence_id`. `AdbAcquiredFilePartialObservation` is a provider-owned raw `provider_id/operation/result` shape. The error retains it in process, but there is no durable record referenced by the bundle. Existing documentation promises recovery for partial Evidence, including JavaScript reconstruction; it does not promise it for all raw provider errors. This is a confirmed runtime consequence and a contract/design question, **not an established violation of the current documented contract**. This differs from #4261: that fix retains successful provider results through late abort and records typed partial Evidence. This probe starts from a provider error carrying raw partial data. ### Expected interaction with targets Documentation clarification has no target interaction. The executed probe used a controlled provider and real in-process MCP protocol. Any future retention implementation would read/retain existing returned data; target execution and cleanup authority must remain unchanged. ### Boundary details Preserve the distinction between observations, validated Evidence, primary failure, cleanup state, and unknown provenance. An empty Evidence bundle cannot establish that no native work or partial side effect occurred. Do not invent an Evidence identity or observed confidence for arbitrary raw errors in the generic transport adapter. ### Options and tradeoffs - Keep raw partials inline-only and document the cancellation/recovery limit explicitly. The clarification is included in #4274. - Have individual producing providers build partial Evidence where identity and provenance are established; retain unknown or incomplete fields truthfully. - Design bounded raw-error retention separately, with explicit lifetime, size, export, and lookup semantics. This is broader than wrapping every error in Evidence. ### Verification available so far Observed SDK cancellation/reply suppression, server completion, same-connection ping, and absence from the Evidence bundle. The probe is disposable under `.cache/codebase-audit/adb-raw-partial-cancel-probe.mts`; it is not committed or a real ADB reproduction. Exact invocation/toolchain will be added with the result record. ### Success criteria and open questions Document the current boundary; decide which facts, if any, should be recoverable; establish the owning producer and provenance rules; then cover SDK cancellation, error reply delivery, lookup/export, capacity/lifetime, and successful controls for the chosen contract. Until that decision, do not infer a product bug for every raw partial error or silently expand retention. ### References - Lifecycle audit #4227 and implementation #4274. - [Evidence delivery owner](https://github.com/morluto/rea/blob/5c6005b88a4d20dfd4042476f4e056344afe29bb/src/server/contractToolHandler.ts#L28). - [ADB partial observation types](https://github.com/morluto/rea/blob/5c6005b88a4d20dfd4042476f4e056344afe29bb/src/domain/adb/adbDeviceAnalysis.ts). - [Progress and cancellation contract](https://github.com/morluto/rea/blob/5c6005b88a4d20dfd4042476f4e056344afe29bb/docs/mcp-contracts.md#progress-and-cancellation).
Author
Owner

@morluto commented on GitHub (Oct 15, 2026):

Probe invocation from the audit checkout: env PATH=/opt/homebrew/opt/node@24/bin:$PATH npx tsx .cache/codebase-audit/adb-raw-partial-cancel-probe.mts. The disposable probe is ignored, not a shipped regression fixture. It connects the real MCP client and server using InMemoryTransport, substitutes a controlled ADB application port that returns AnalysisCancelledError with a typed raw partial after abort, waits for the server completion log, then pings and queries the operation-filtered Evidence bundle. No device or file transfer occurs.

Repeated at 90846dc7d with Node 24.18.0, tsx 4.23.15, MCP client/server 2.3.1: client rejected, server signal aborted, server operation completed with status error, ping succeeded, bundle reported zero retained/matching records. An earlier run on Node 26.5.0 produced the same result.

Commit 90846dc7d in #4274 documents the current limit. This issue remains a design decision: choose recoverable facts, producer/provenance ownership, and retention lifetime before implementing storage. The observed behavior does not establish a violation of the existing Evidence-only recovery contract.

<!-- gh-comment-id:6203690663 --> @morluto commented on GitHub (Oct 15, 2026): Probe invocation from the audit checkout: `env PATH=/opt/homebrew/opt/node@24/bin:$PATH npx tsx .cache/codebase-audit/adb-raw-partial-cancel-probe.mts`. The disposable probe is ignored, not a shipped regression fixture. It connects the real MCP client and server using `InMemoryTransport`, substitutes a controlled ADB application port that returns `AnalysisCancelledError` with a typed raw partial after abort, waits for the server completion log, then pings and queries the operation-filtered Evidence bundle. No device or file transfer occurs. Repeated at `90846dc7d` with Node 24.18.0, tsx 4.23.15, MCP client/server 2.3.1: client rejected, server signal aborted, server operation completed with status `error`, ping succeeded, bundle reported zero retained/matching records. An earlier run on Node 26.5.0 produced the same result. Commit `90846dc7d` in #4274 documents the current limit. This issue remains a design decision: choose recoverable facts, producer/provenance ownership, and retention lifetime before implementing storage. The observed behavior does not establish a violation of the existing Evidence-only recovery contract.
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#1690
No description provided.