[PR #1088] [MERGED] fix(mcp): retain complete application results across response limits #2636

Closed
opened 2026-10-17 21:08:28 +00:00 by bsakaguchi · 0 comments
Owner

📋 Pull Request Information

Original PR: https://github.com/morluto/rea/pull/1088
Author: @N0zoM1z0
Created: 10/8/2026
Status: ✅ Merged
Merged: 10/8/2026
Merged by: @N0zoM1z0

Base: main ← Head: fix/mcp-large-result-delivery


📝 Commits (6)

  • 0169b9f fix(mcp): retain large application results across response limits
  • 6360514 fix(evidence): enforce JSON validation for owned snapshots
  • 8fadc4b test(evidence): check mutable depth rejection before sealing
  • 2059bde chore: merge main and preserve streaming evidence diagnostics
  • 4ee7a1c fix(mcp): verify complete screenshot recovery across frame budgets
  • 927a768 Merge remote-tracking branch 'origin/main' into fix/mcp-large-result-delivery

📊 Changes

43 files changed (+1314 additions, -186 deletions)

View changed files

📝 docs/javascript-artifact-reconstruction.md (+12 -7)
📝 docs/mcp-contracts.md (+20 -0)
📝 scripts/lib/browser-screenshot-e2e.mjs (+86 -2)
📝 scripts/lib/large-result-mcp.mjs (+4 -1)
📝 skill-src/reverse-engineer-anything/SKILL.md (+7 -0)
📝 skill-src/reverse-engineer-anything/references/javascript-applications.md (+8 -1)
📝 src/application/EvidenceBundleFiles.ts (+12 -5)
📝 src/application/JsonFiles.ts (+38 -20)
📝 src/application/binary/BinarySessionRecords.ts (+10 -0)
📝 src/application/investigation/EvidenceLedger.test.ts (+30 -0)
📝 src/application/investigation/EvidenceLedger.ts (+31 -6)
📝 src/application/investigation/InvestigationRecordPort.ts (+4 -0)
📝 src/application/investigation/InvestigationRecords.ts (+10 -0)
📝 src/application/javascript/JavaScriptApplicationEvidence.ts (+12 -0)
➕ src/application/javascript/JavaScriptApplicationEvidenceGraph.test.ts (+47 -0)
📝 src/application/javascript/JavaScriptApplicationEvidenceGraph.ts (+43 -4)
📝 src/application/javascript/JavaScriptApplicationService.ts (+2 -2)
📝 src/cli/jsonOutput.ts (+5 -107)
📝 src/config/environment.ts (+2 -0)
➕ src/config/mcpResponseBudget.ts (+31 -0)

...and 23 more files

📄 Description

Summary

Complete JavaScript application analysis can succeed while its repeated MCP response exceeds the client's frame budget or Node's single-string limit. The connection then fails and the retained analysis is difficult to use. This change returns a typed delivery constraint, keeps the complete authenticated Evidence in the session, and makes subsequent graph queries and full bundle export practical for real large applications.

Addresses T1 of #1065 and the delivery failure tracked in #1053. The broader roadmap remains open.

Problem and expected behavior

The published 6.0.0 default SDK workflow disconnects on a 28 KB JavaScript source; complete ASAR results can also fail with Invalid string length even with an enlarged client buffer. Supported analysis should preserve its full result and offer a usable continuation when the wire representation cannot fit.

The complete real Notion 7.6.1 and Obsidian 1.12.7 application bundles now support analysis, retained module tracing, complete export, subsequent pings, and session cleanup through an isolated installed package. A real Chrome capture also verifies complete screenshot recovery under the default budget and complete inline delivery when both endpoints explicitly select a larger budget.

Change and scope

  • Account incrementally for the actual structured and escaped-text representations before assembling an oversized string. Default accounting follows the pinned SDK's 10 MiB stdio receive budget, with protocol-envelope reserve and a separate Node string-limit guard.
  • Advertise a retained-Evidence reference only after recording succeeds, including the browser capture adapter. Preserve ordinary complete success envelopes and full CLI output. REA_MCP_MAX_RESPONSE_BYTES supports clients explicitly configured for larger frames.
  • Reuse authenticated, deeply immutable producer and ledger snapshots for read-only analysis and serialization. Detached public reads and foreign records still undergo validation. Owned results retain the same maximum JSON depth and prototype-member semantics as other inputs.
  • Stream canonical bundle JSON to an atomic destination instead of cloning and joining the entire document. Failed writes preserve the original file and clean the staging directory.
  • Use traversal-local strong sets and root-only weak authentication entries. A real native Notion probe exposed and corrected an intermediate deep-freeze regression: approximately 124 seconds to 4.24 seconds, with unchanged digest. This comparison is between intermediate implementations, not a published-version speedup claim.

Contract and boundary impact

  • Semantic owner and earliest changed stage: domain JSON/Evidence ownership and encoding; application ledger access/export; MCP delivery projection.
  • CLI and MCP/tool-catalog contract: 139 canonical tools and existing complete success shapes remain intact. Oversized successful representations produce resource_constraint with resource: transport; full Evidence is recoverable when retained.
  • Provider, bridge, target-format, or platform compatibility: no provider protocol changes. Real full ASAR acceptance covers Linux Node 24.18.0 and native Windows Node 22.19.0, using SDK 2.3.1.
  • Evidence, artifact, provenance, or reconstruction contract: canonical content, identities, locations, limitations, unknowns, and caller-selected paths remain preserved. Internal borrowing requires authenticated immutable ownership.
  • Process execution, authorization, cleanup, or containment impact: no new execution authority. Applications are analyzed as inert artifacts. Export uses the caller-selected destination; closing the session clears retained records and rejects stale references.
  • Generated metadata, package, or installation impact: authored skill instructions live in skill-src/; catalogs, skill copies, and conformance projections follow main's generated-build pipeline. No installer or dependency changes in this PR; isolated tarball installations were verified against the compiled source.

Evidence and regression coverage

  • Added regressions for UTF-8/escaping and repeated-envelope byte accounting, early encoding stop, complete canonical JSON parity, deep immutability, tampering, detached versus borrowed reads, JSON depth and prototype-named members, and atomic stream failures/exclusive publication.
  • 325 focused source, conformance, compiled boundary, acceptance, and module-boundary tests passed before the final main integration; 49 affected tests passed again after resolving the integration, including generated-skill installation and file-error diagnostics. Converted schema dialect, root-union compatibility, and the #919 input constraints remain valid.
  • Independent streaming validation walked every field of both complete CLI outputs and both Windows exports at approximately 20 MiB peak RSS. Complete normalized results match across platforms after replacing only input_path in the comparison. Actual records retain their selected paths.
  • Final Notion CLI output is byte-identical to the published 6.0.0 baseline: 336,236,132 bytes, SHA-256 2459bef328f7492bfc82b264e4169d702707afa24b96551815816eee8ca06692.

Illustrative structured error excerpt; callers use the ID returned by their session:

{
  "error": {
    "code": "resource_constraint",
    "category": "resource_constraint",
    "details": {
      "resource": "transport",
      "reported_limits": {
        "boundary": "mcp-response",
        "constraint": "receive-buffer",
        "evidence_reference": {
          "kind": "retained-evidence",
          "evidence_id": "ev_aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
        }
      }
    }
  }
}

Native Windows real-package measurements, two CPUs, below-normal priority, 1.5 GiB server heap, default SDK receive buffer, extended 600-second caller deadlines:

Full target Analysis Complete workflow Peak family working set Complete bundle export
Notion 7.6.1 97.03 s 147.52 s 1.52 GiB 336,253,911 bytes
Obsidian 1.12.7 153.32 s 217.26 s 1.67 GiB 429,198,332 bytes

Both workflows delivered a 2,517-byte constraint, then answered meaningful module traces of 69,898 / 131,902 bytes, exported the full two-record bundle, safely handled broad bundle queries, emptied the ledger on close, rejected stale references, and passed subsequent pings. No memory, disk, or deadline reserve guard intervened.

A separate native production-converter probe on the complete Obsidian export with a 1 GiB response budget verified the Node string-limit branch and a safely serializable 2,507-byte error at 1.04 GiB peak working set. This is an encoding-boundary probe, paired with the full default-buffer SDK workflows above.

Validation performed

  • npm run test:local -- <11 exact source/conformance files> — 110 tests passed across the two focused runs.
  • npm run test:focused -- <13 exact boundary/acceptance/evaluation files> — 215 tests passed across the two focused runs.
  • npm run check -- --concurrency=1 — passed; static checks also passed sequentially under resource guards.
  • npm run docs:check — passed; generated outputs follow the current build pipeline.
  • npm run jscpd and npm run scan:todos — passed.
  • npm run verify:package — passed again after integrating main in an isolated prefix; peak family RSS approximately 1.40 GiB.
  • npm run verify:browser — passed against actual Chrome 150. A 9,331,405-byte PNG was recovered byte-for-byte from full exported Evidence under the default SDK frame budget, then delivered completely inline with matching 64 MiB endpoint budgets. The complete browser lane finished in 116.10 seconds at approximately 2.66 GiB peak process-family RSS under two CPUs, with no reserve guard intervention.
  • Browser followup: 14 focused MCP/projection tests, sequential static checks, and generated-document checks passed. After integrating the separately merged #1091 CI correction, all four downloaded-build generators and 27 catalog/skill/owned-process tests passed again.
  • npm pack and npm pack --dry-run — passed. After integrating main, the compiled analysis, ownership, JSON validation, and MCP encoding modules remained byte-identical to the real-tested installation; 49 affected tests and generated-doc checks passed again.
  • Actual installed-package SDK workflows, complete CLI runs, independent full-document JSON proofs, and cross-platform content comparisons for both real applications — passed.

Compatibility, safety, and release

  • Breaking changes or migration steps: existing encodable success envelopes and CLI bytes are preserved. Clients opting into larger frames configure both their receive buffer and REA_MCP_MAX_RESPONSE_BYTES; Node's string limit still applies.
  • Real Hopper/Ghidra, browser, or OS coverage: native Windows and Linux real ASAR workflows verified. Real Chrome CLI/MCP capture and default-budget Evidence recovery verified; no Hopper/Ghidra verification was performed. Provider wire protocols are unchanged.
  • Package or release metadata impact: no version/dependency/installer changes in this PR; authored skill guidance updated.
  • Security, privacy, process, or containment review: immutable ownership cannot be forged by a shallow freeze; detached/imported data retains integrity validation; atomic export and owned temporary cleanup tested. Public examples and measurements omit private host paths and credentials.
  • Remaining work: responsive cancellation, default client waiting behavior, catalog/context costs, response views, oversized error projections, and very large foreign bundle imports remain separate workloads in the roadmap.

Review checklist

  • The PR has one focused outcome and the title follows type(scope): outcome.
  • Related issues are linked.
  • Tests cover changed observable behavior and meaningful failure paths.
  • Owning docs, contracts, and generated metadata are updated where needed.
  • User-visible CLI/MCP changes include representative output.
  • Final diff checked for secrets, unrelated cleanup, and unsupported claims.
  • Observed, derived, and inferred claims remain distinguishable.
  • Artifact identity, source provenance, and failed attempts remain preserved.
  • Incomplete and uncertain outcomes remain visible.

🔄 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/1088 **Author:** [@N0zoM1z0](https://github.com/N0zoM1z0) **Created:** 10/8/2026 **Status:** ✅ Merged **Merged:** 10/8/2026 **Merged by:** [@N0zoM1z0](https://github.com/N0zoM1z0) **Base:** `main` ← **Head:** `fix/mcp-large-result-delivery` --- ### 📝 Commits (6) - [`0169b9f`](https://github.com/morluto/rea/commit/0169b9f9b558e1a0fbd563dfb18a91eb89584189) fix(mcp): retain large application results across response limits - [`6360514`](https://github.com/morluto/rea/commit/63605142a956a66ae48f16137c621e671d8edd79) fix(evidence): enforce JSON validation for owned snapshots - [`8fadc4b`](https://github.com/morluto/rea/commit/8fadc4b229483bd222749f7dacaecc9950f789b0) test(evidence): check mutable depth rejection before sealing - [`2059bde`](https://github.com/morluto/rea/commit/2059bde24550e8ceede9d893b182a243835f8fcf) chore: merge main and preserve streaming evidence diagnostics - [`4ee7a1c`](https://github.com/morluto/rea/commit/4ee7a1c2ebdef8f90edeb3c426115ce0070ccb94) fix(mcp): verify complete screenshot recovery across frame budgets - [`927a768`](https://github.com/morluto/rea/commit/927a768eefc193e8975af1cb17239bf5b6534da9) Merge remote-tracking branch 'origin/main' into fix/mcp-large-result-delivery ### 📊 Changes **43 files changed** (+1314 additions, -186 deletions) <details> <summary>View changed files</summary> 📝 `docs/javascript-artifact-reconstruction.md` (+12 -7) 📝 `docs/mcp-contracts.md` (+20 -0) 📝 `scripts/lib/browser-screenshot-e2e.mjs` (+86 -2) 📝 `scripts/lib/large-result-mcp.mjs` (+4 -1) 📝 `skill-src/reverse-engineer-anything/SKILL.md` (+7 -0) 📝 `skill-src/reverse-engineer-anything/references/javascript-applications.md` (+8 -1) 📝 `src/application/EvidenceBundleFiles.ts` (+12 -5) 📝 `src/application/JsonFiles.ts` (+38 -20) 📝 `src/application/binary/BinarySessionRecords.ts` (+10 -0) 📝 `src/application/investigation/EvidenceLedger.test.ts` (+30 -0) 📝 `src/application/investigation/EvidenceLedger.ts` (+31 -6) 📝 `src/application/investigation/InvestigationRecordPort.ts` (+4 -0) 📝 `src/application/investigation/InvestigationRecords.ts` (+10 -0) 📝 `src/application/javascript/JavaScriptApplicationEvidence.ts` (+12 -0) ➕ `src/application/javascript/JavaScriptApplicationEvidenceGraph.test.ts` (+47 -0) 📝 `src/application/javascript/JavaScriptApplicationEvidenceGraph.ts` (+43 -4) 📝 `src/application/javascript/JavaScriptApplicationService.ts` (+2 -2) 📝 `src/cli/jsonOutput.ts` (+5 -107) 📝 `src/config/environment.ts` (+2 -0) ➕ `src/config/mcpResponseBudget.ts` (+31 -0) _...and 23 more files_ </details> ### 📄 Description ## Summary Complete JavaScript application analysis can succeed while its repeated MCP response exceeds the client's frame budget or Node's single-string limit. The connection then fails and the retained analysis is difficult to use. This change returns a typed delivery constraint, keeps the complete authenticated Evidence in the session, and makes subsequent graph queries and full bundle export practical for real large applications. Addresses T1 of #1065 and the delivery failure tracked in #1053. The broader roadmap remains open. ## Problem and expected behavior The published 6.0.0 default SDK workflow disconnects on a 28 KB JavaScript source; complete ASAR results can also fail with `Invalid string length` even with an enlarged client buffer. Supported analysis should preserve its full result and offer a usable continuation when the wire representation cannot fit. The complete real Notion 7.6.1 and Obsidian 1.12.7 application bundles now support analysis, retained module tracing, complete export, subsequent pings, and session cleanup through an isolated installed package. A real Chrome capture also verifies complete screenshot recovery under the default budget and complete inline delivery when both endpoints explicitly select a larger budget. ## Change and scope - Account incrementally for the actual structured and escaped-text representations before assembling an oversized string. Default accounting follows the pinned SDK's 10 MiB stdio receive budget, with protocol-envelope reserve and a separate Node string-limit guard. - Advertise a retained-Evidence reference only after recording succeeds, including the browser capture adapter. Preserve ordinary complete success envelopes and full CLI output. `REA_MCP_MAX_RESPONSE_BYTES` supports clients explicitly configured for larger frames. - Reuse authenticated, deeply immutable producer and ledger snapshots for read-only analysis and serialization. Detached public reads and foreign records still undergo validation. Owned results retain the same maximum JSON depth and prototype-member semantics as other inputs. - Stream canonical bundle JSON to an atomic destination instead of cloning and joining the entire document. Failed writes preserve the original file and clean the staging directory. - Use traversal-local strong sets and root-only weak authentication entries. A real native Notion probe exposed and corrected an intermediate deep-freeze regression: approximately 124 seconds to 4.24 seconds, with unchanged digest. This comparison is between intermediate implementations, not a published-version speedup claim. ## Contract and boundary impact - Semantic owner and earliest changed stage: domain JSON/Evidence ownership and encoding; application ledger access/export; MCP delivery projection. - CLI and MCP/tool-catalog contract: 139 canonical tools and existing complete success shapes remain intact. Oversized successful representations produce `resource_constraint` with `resource: transport`; full Evidence is recoverable when retained. - Provider, bridge, target-format, or platform compatibility: no provider protocol changes. Real full ASAR acceptance covers Linux Node 24.18.0 and native Windows Node 22.19.0, using SDK 2.3.1. - Evidence, artifact, provenance, or reconstruction contract: canonical content, identities, locations, limitations, unknowns, and caller-selected paths remain preserved. Internal borrowing requires authenticated immutable ownership. - Process execution, authorization, cleanup, or containment impact: no new execution authority. Applications are analyzed as inert artifacts. Export uses the caller-selected destination; closing the session clears retained records and rejects stale references. - Generated metadata, package, or installation impact: authored skill instructions live in `skill-src/`; catalogs, skill copies, and conformance projections follow main's generated-build pipeline. No installer or dependency changes in this PR; isolated tarball installations were verified against the compiled source. ## Evidence and regression coverage - Added regressions for UTF-8/escaping and repeated-envelope byte accounting, early encoding stop, complete canonical JSON parity, deep immutability, tampering, detached versus borrowed reads, JSON depth and prototype-named members, and atomic stream failures/exclusive publication. - 325 focused source, conformance, compiled boundary, acceptance, and module-boundary tests passed before the final main integration; 49 affected tests passed again after resolving the integration, including generated-skill installation and file-error diagnostics. Converted schema dialect, root-union compatibility, and the #919 input constraints remain valid. - Independent streaming validation walked every field of both complete CLI outputs and both Windows exports at approximately 20 MiB peak RSS. Complete normalized results match across platforms after replacing only `input_path` in the comparison. Actual records retain their selected paths. - Final Notion CLI output is byte-identical to the published 6.0.0 baseline: 336,236,132 bytes, SHA-256 `2459bef328f7492bfc82b264e4169d702707afa24b96551815816eee8ca06692`. Illustrative structured error excerpt; callers use the ID returned by their session: ```json { "error": { "code": "resource_constraint", "category": "resource_constraint", "details": { "resource": "transport", "reported_limits": { "boundary": "mcp-response", "constraint": "receive-buffer", "evidence_reference": { "kind": "retained-evidence", "evidence_id": "ev_aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" } } } } } ``` Native Windows real-package measurements, two CPUs, below-normal priority, 1.5 GiB server heap, default SDK receive buffer, extended 600-second caller deadlines: | Full target | Analysis | Complete workflow | Peak family working set | Complete bundle export | | --- | ---: | ---: | ---: | ---: | | Notion 7.6.1 | 97.03 s | 147.52 s | 1.52 GiB | 336,253,911 bytes | | Obsidian 1.12.7 | 153.32 s | 217.26 s | 1.67 GiB | 429,198,332 bytes | Both workflows delivered a 2,517-byte constraint, then answered meaningful module traces of 69,898 / 131,902 bytes, exported the full two-record bundle, safely handled broad bundle queries, emptied the ledger on close, rejected stale references, and passed subsequent pings. No memory, disk, or deadline reserve guard intervened. A separate native production-converter probe on the complete Obsidian export with a 1 GiB response budget verified the Node string-limit branch and a safely serializable 2,507-byte error at 1.04 GiB peak working set. This is an encoding-boundary probe, paired with the full default-buffer SDK workflows above. ## Validation performed - `npm run test:local -- <11 exact source/conformance files>` — 110 tests passed across the two focused runs. - `npm run test:focused -- <13 exact boundary/acceptance/evaluation files>` — 215 tests passed across the two focused runs. - `npm run check -- --concurrency=1` — passed; static checks also passed sequentially under resource guards. - `npm run docs:check` — passed; generated outputs follow the current build pipeline. - `npm run jscpd` and `npm run scan:todos` — passed. - `npm run verify:package` — passed again after integrating main in an isolated prefix; peak family RSS approximately 1.40 GiB. - `npm run verify:browser` — passed against actual Chrome 150. A 9,331,405-byte PNG was recovered byte-for-byte from full exported Evidence under the default SDK frame budget, then delivered completely inline with matching 64 MiB endpoint budgets. The complete browser lane finished in 116.10 seconds at approximately 2.66 GiB peak process-family RSS under two CPUs, with no reserve guard intervention. - Browser followup: 14 focused MCP/projection tests, sequential static checks, and generated-document checks passed. After integrating the separately merged #1091 CI correction, all four downloaded-build generators and 27 catalog/skill/owned-process tests passed again. - `npm pack` and `npm pack --dry-run` — passed. After integrating main, the compiled analysis, ownership, JSON validation, and MCP encoding modules remained byte-identical to the real-tested installation; 49 affected tests and generated-doc checks passed again. - Actual installed-package SDK workflows, complete CLI runs, independent full-document JSON proofs, and cross-platform content comparisons for both real applications — passed. ## Compatibility, safety, and release - Breaking changes or migration steps: existing encodable success envelopes and CLI bytes are preserved. Clients opting into larger frames configure both their receive buffer and `REA_MCP_MAX_RESPONSE_BYTES`; Node's string limit still applies. - Real Hopper/Ghidra, browser, or OS coverage: native Windows and Linux real ASAR workflows verified. Real Chrome CLI/MCP capture and default-budget Evidence recovery verified; no Hopper/Ghidra verification was performed. Provider wire protocols are unchanged. - Package or release metadata impact: no version/dependency/installer changes in this PR; authored skill guidance updated. - Security, privacy, process, or containment review: immutable ownership cannot be forged by a shallow freeze; detached/imported data retains integrity validation; atomic export and owned temporary cleanup tested. Public examples and measurements omit private host paths and credentials. - Remaining work: responsive cancellation, default client waiting behavior, catalog/context costs, response views, oversized error projections, and very large foreign bundle imports remain separate workloads in the roadmap. ## Review checklist - [x] The PR has one focused outcome and the title follows `type(scope): outcome`. - [x] Related issues are linked. - [x] Tests cover changed observable behavior and meaningful failure paths. - [x] Owning docs, contracts, and generated metadata are updated where needed. - [x] User-visible CLI/MCP changes include representative output. - [x] Final diff checked for secrets, unrelated cleanup, and unsupported claims. - [x] Observed, derived, and inferred claims remain distinguishable. - [x] Artifact identity, source provenance, and failed attempts remain preserved. - [x] Incomplete and uncertain outcomes remain visible. --- <sub>🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.</sub>
bsakaguchi 2026-10-17 21:08:28 +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#2636
No description provided.