[PR #4761] [MERGED] fix(mcp): accept authentic native Evidence for managed boundary verification #6395

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

📋 Pull Request Information

Original PR: https://github.com/morluto/rea/pull/4761
Author: @kaoru0822-kitauji
Created: 10/17/2026
Status: ✅ Merged
Merged: 10/17/2026
Merged by: @kaoru0822-kitauji

Base: main ← Head: fix/mcp-native-evidence-integrity


📝 Commits (1)

  • 8572c46 fix(mcp): accept authentic native Evidence for managed boundary verification

📊 Changes

2 files changed (+136 additions, -12 deletions)

View changed files

📝 src/server/registerManagedWorkflowTools/evidence.ts (+20 -12)
➕ tests/boundary/mcp/managedNativeVerificationAdapters.test.ts (+116 -0)

📄 Description

Summary

Fixes #4639.

Before this change, MCP verify_managed_native_boundaries rejected authentic native Evidence whose operation is not inspect_macho or analyze_function (for example inspect_signature). It returned evidence_integrity_mismatch and told the caller to recreate or re-import the records. The CLI accepts the same input and returns partial verification Evidence. Now MCP returns the same result as the CLI: one unsupported native observation, the P/Invoke left unresolved with basis unsupported-native-evidence, partial coverage, both input Evidence links kept, and the unsupported-operation limitation.

Problem and expected behavior

Smallest trigger: managed-boundary Evidence from inspect_managed_native_boundaries, plus one authentic native record from an operation that the workflow does not read symbols from.

Root cause: before calling the shared verifyManagedNativeBoundariesEvidence service, the MCP handler ran native observations through resolveNativeEvidence. That function checked an inspect_macho/analyze_function operation allowlist and a rea.analysis predicate, and reported any other authentic record as an integrity failure. The domain already decides which native operations it can use: collectNativeSymbols counts the others as unsupported. The CLI calls the shared service directly, so only MCP applied this second, conflicting check. The broken invariant: a shared workflow must give the same Evidence semantics through both adapters, and an unsupported operation is not damaged Evidence.

Change and scope

resolveNativeEvidence now only authenticates native observations with parseEvidence. Authentication failures still return EvidenceIntegrityError. The operation and predicate checks are gone, so operation support is decided once, in the domain. The other managed resolvers keep their single-operation checks, which match what their domain parsers require.

Not included:

  • The managed-boundary resolver for this tool is unchanged. Swapped or wrong-role managed-boundary records and tampered records still return evidence_integrity_mismatch over MCP, while the CLI reports them as invalid input. That difference already existed and is not part of this issue.
  • The revision_conflict from automatic unknowns, which happens when a session runs a second, different unresolved verification, is tracked in #3333 and open PR #3503.

Contribution scope: a correctness fix inside an existing MCP adapter. A maintainer scope decision is not applicable.

Contract and boundary impact

  • Semantic owner and earliest changed stage: the domain (collectNativeSymbols in src/domain/managed/managedNativeVerificationMatch.ts) owns native operation support. The MCP resolver in src/server/registerManagedWorkflowTools/evidence.ts no longer repeats that decision.
  • Contribution scope fit and linked maintainer decision: in scope; not applicable.
  • CLI and MCP/tool-catalog contract: no schema or catalog change. MCP now succeeds, as the CLI already did, for authentic native records whose operation the workflow does not support.
  • Provider, bridge, target-format, or platform compatibility: none.
  • Evidence, artifact, provenance, or reconstruction contract: MCP now returns the shared workflow's partial-verification Evidence instead of an integrity error. The unsupported record is still authenticated and recorded as a source.
  • Target selection, authority, upstream behavior, and cleanup details (if applicable): not applicable.
  • Generated metadata (docs/public/product-catalog.json), package, or installation impact: none.

Expected effects (check known effects; use documentation-only on its own).
Unchecked items do not establish absence; leave uncertainties visible.

  • Read existing files or captured data.
  • Launch or attach to a process.
  • Inject instrumentation or run scripts/code.
  • Change process memory, registers, files, or configuration.
  • Contact network services.
  • Recover protected code or work around protections.
  • Documentation or usability only; no target interaction.
  • Not sure yet; investigation or maintainer guidance needed.

Evidence and regression coverage

  • Tests added or updated: tests/boundary/mcp/managedNativeVerificationAdapters.test.ts. It gets real managed-boundary Evidence from a generated P/Invoke PE over stdio MCP, then sends the same input with an authentic inspect_signature record to both MCP and the compiled CLI. It asserts that:
    • the two normalized results are equal;
    • the result has { total: 1, accepted: 0, unsupported: 1, symbols: 0 }, one unresolved P/Invoke with basis unsupported-native-evidence, partial coverage, both Evidence links, and the unsupported-operation limitation;
    • a tampered native record is still rejected over MCP with evidence_integrity_mismatch.
  • Base reproduction or other evidence (executed):
    • The issue's executable reproduction on origin/main (5120eb441, macOS, built with npm run build:cached) printed evidence_integrity_mismatch / Expected inspect_macho or analyze_function Evidence, received inspect_signature for both MCP attempts. The CLI returned unsupported: 1, unresolved: 1, partial coverage, and the inspect_macho control passed.
    • The new test fails on main's source with that same error. I re-checked this after rebasing onto ae029fe2f by temporarily restoring main's evidence.ts: 1 failed, 49 passed.
  • User-visible CLI/MCP output: MCP now returns Evidence whose normalized_result.native_observations is {"total":1,"accepted":0,"unsupported":1,"symbols":0}, the same as the CLI. I ran an adapted copy of the issue script against the fixed build, using real inspect_signature Evidence for /usr/bin/true. Both attempts succeeded, and the MCP and CLI normalized results were equal.
  • Remaining proof gaps:
    • Only inspect_signature was tested as an unsupported operation.
    • The regression test uses an authentic inspect_signature record built with createEvidence, so it does not depend on the platform. Real macOS inspect_signature Evidence was only used in the adapted issue script.
    • In that script, the inspect_macho control step then failed with revision_conflict (already-exists). That is the automatic-unknown collision tracked in #3333 / #3503, not this change.
    • Other platforms were not run.

For evidence-bearing changes:

  • Observed, derived, and inferred claims remain distinguishable.
  • Artifact identity, source provenance, and failed attempts remain preserved.
  • Unsupported, incomplete, unavailable, or uncertain outcomes remain visible.

Validation performed

Node v26.5.0 was used locally because the pinned 24.18.0 was not installed.

  • npm ci then npm run build:cached — succeeded.
  • Issue reproduction script on main — reproduced (both MCP attempts returned evidence_integrity_mismatch; CLI returned partial results).
  • npm run test:focused -- tests/boundary/mcp/managedNativeVerificationAdapters.test.ts tests/boundary/mcp/managedMcp.test.ts tests/boundary/mcp/outputSchemaSemanticConstraints.test.ts tests/boundary/cli/jsonInputStatus.test.ts tests/conformance/providers/managed/managedNativeVerification.test.ts:
    • main source: 1 failed, 49 passed;
    • this branch after rebase: 50 passed.
  • npx tsc --noEmit -p . — exit 0.
  • npx oxlint and npx oxfmt --check on the changed files — exit 0.

Compatibility, safety, and release

  • Breaking changes or migration steps: none. MCP callers that got evidence_integrity_mismatch for authentic native records of other operations now get the partial-verification Evidence.
  • Real Hopper/Ghidra, browser, or OS coverage: none needed. macOS static inspection (/usr/bin/true) was used only in the adapted issue script.
  • Package or release metadata impact: none.
  • Security, privacy, process, or containment review: Evidence authentication is still enforced before the workflow runs. The managed assembly is never executed.

Author readiness

Human owner:

  • I reviewed the final diff and relevant existing code, understand the change and its edge cases, and take responsibility for the complete PR, including AI-assisted work.
  • I checked the evidence above, confirmed it supports the current change, and recorded meaningful validation gaps.
  • I declare this PR ready for initial maintainer review.

Before merge

  • This PR addresses a concrete problem or an agreed enhancement.
  • Material scope and authority questions are resolved, and any required maintainer scope decision covers the final diff.
  • The PR has one focused outcome and the title follows type(scope): outcome.
  • Related issue is linked, or the reason for not linking one is stated above.
  • 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.
  • I checked the final diff for secrets, unrelated cleanup, and unsupported claims.

🤖 Generated with Claude Code


🔄 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/4761 **Author:** [@kaoru0822-kitauji](https://github.com/kaoru0822-kitauji) **Created:** 10/17/2026 **Status:** ✅ Merged **Merged:** 10/17/2026 **Merged by:** [@kaoru0822-kitauji](https://github.com/kaoru0822-kitauji) **Base:** `main` ← **Head:** `fix/mcp-native-evidence-integrity` --- ### 📝 Commits (1) - [`8572c46`](https://github.com/morluto/rea/commit/8572c468f382e9bc4ebc0f7d2388822ffe7f871e) fix(mcp): accept authentic native Evidence for managed boundary verification ### 📊 Changes **2 files changed** (+136 additions, -12 deletions) <details> <summary>View changed files</summary> 📝 `src/server/registerManagedWorkflowTools/evidence.ts` (+20 -12) ➕ `tests/boundary/mcp/managedNativeVerificationAdapters.test.ts` (+116 -0) </details> ### 📄 Description ## Summary Fixes #4639. Before this change, MCP `verify_managed_native_boundaries` rejected authentic native Evidence whose operation is not `inspect_macho` or `analyze_function` (for example `inspect_signature`). It returned `evidence_integrity_mismatch` and told the caller to recreate or re-import the records. The CLI accepts the same input and returns partial verification Evidence. Now MCP returns the same result as the CLI: one unsupported native observation, the P/Invoke left unresolved with basis `unsupported-native-evidence`, partial coverage, both input Evidence links kept, and the unsupported-operation limitation. ## Problem and expected behavior Smallest trigger: managed-boundary Evidence from `inspect_managed_native_boundaries`, plus one authentic native record from an operation that the workflow does not read symbols from. Root cause: before calling the shared `verifyManagedNativeBoundariesEvidence` service, the MCP handler ran native observations through `resolveNativeEvidence`. That function checked an `inspect_macho`/`analyze_function` operation allowlist and a `rea.analysis` predicate, and reported any other authentic record as an integrity failure. The domain already decides which native operations it can use: `collectNativeSymbols` counts the others as `unsupported`. The CLI calls the shared service directly, so only MCP applied this second, conflicting check. The broken invariant: a shared workflow must give the same Evidence semantics through both adapters, and an unsupported operation is not damaged Evidence. ## Change and scope `resolveNativeEvidence` now only authenticates native observations with `parseEvidence`. Authentication failures still return `EvidenceIntegrityError`. The operation and predicate checks are gone, so operation support is decided once, in the domain. The other managed resolvers keep their single-operation checks, which match what their domain parsers require. Not included: - The managed-boundary resolver for this tool is unchanged. Swapped or wrong-role managed-boundary records and tampered records still return `evidence_integrity_mismatch` over MCP, while the CLI reports them as invalid input. That difference already existed and is not part of this issue. - The `revision_conflict` from automatic unknowns, which happens when a session runs a second, different unresolved verification, is tracked in #3333 and open PR #3503. Contribution scope: a correctness fix inside an existing MCP adapter. A maintainer scope decision is not applicable. ## Contract and boundary impact - Semantic owner and earliest changed stage: the domain (`collectNativeSymbols` in `src/domain/managed/managedNativeVerificationMatch.ts`) owns native operation support. The MCP resolver in `src/server/registerManagedWorkflowTools/evidence.ts` no longer repeats that decision. - Contribution scope fit and linked maintainer decision: in scope; not applicable. - CLI and MCP/tool-catalog contract: no schema or catalog change. MCP now succeeds, as the CLI already did, for authentic native records whose operation the workflow does not support. - Provider, bridge, target-format, or platform compatibility: none. - Evidence, artifact, provenance, or reconstruction contract: MCP now returns the shared workflow's partial-verification Evidence instead of an integrity error. The unsupported record is still authenticated and recorded as a source. - Target selection, authority, upstream behavior, and cleanup details (if applicable): not applicable. - Generated metadata (`docs/public/product-catalog.json`), package, or installation impact: none. Expected effects (check known effects; use documentation-only on its own). Unchecked items do not establish absence; leave uncertainties visible. - [x] Read existing files or captured data. - [ ] Launch or attach to a process. - [ ] Inject instrumentation or run scripts/code. - [ ] Change process memory, registers, files, or configuration. - [ ] Contact network services. - [ ] Recover protected code or work around protections. - [ ] Documentation or usability only; no target interaction. - [ ] Not sure yet; investigation or maintainer guidance needed. ## Evidence and regression coverage - Tests added or updated: `tests/boundary/mcp/managedNativeVerificationAdapters.test.ts`. It gets real managed-boundary Evidence from a generated P/Invoke PE over stdio MCP, then sends the same input with an authentic `inspect_signature` record to both MCP and the compiled CLI. It asserts that: - the two normalized results are equal; - the result has `{ total: 1, accepted: 0, unsupported: 1, symbols: 0 }`, one unresolved P/Invoke with basis `unsupported-native-evidence`, partial coverage, both Evidence links, and the unsupported-operation limitation; - a tampered native record is still rejected over MCP with `evidence_integrity_mismatch`. - Base reproduction or other evidence (executed): - The issue's executable reproduction on `origin/main` (5120eb441, macOS, built with `npm run build:cached`) printed `evidence_integrity_mismatch` / `Expected inspect_macho or analyze_function Evidence, received inspect_signature` for both MCP attempts. The CLI returned `unsupported: 1`, `unresolved: 1`, partial coverage, and the `inspect_macho` control passed. - The new test fails on main's source with that same error. I re-checked this after rebasing onto ae029fe2f by temporarily restoring main's `evidence.ts`: 1 failed, 49 passed. - User-visible CLI/MCP output: MCP now returns Evidence whose `normalized_result.native_observations` is `{"total":1,"accepted":0,"unsupported":1,"symbols":0}`, the same as the CLI. I ran an adapted copy of the issue script against the fixed build, using real `inspect_signature` Evidence for `/usr/bin/true`. Both attempts succeeded, and the MCP and CLI normalized results were equal. - Remaining proof gaps: - Only `inspect_signature` was tested as an unsupported operation. - The regression test uses an authentic `inspect_signature` record built with `createEvidence`, so it does not depend on the platform. Real macOS `inspect_signature` Evidence was only used in the adapted issue script. - In that script, the `inspect_macho` control step then failed with `revision_conflict` (`already-exists`). That is the automatic-unknown collision tracked in #3333 / #3503, not this change. - Other platforms were not run. For evidence-bearing changes: - [ ] Observed, derived, and inferred claims remain distinguishable. - [ ] Artifact identity, source provenance, and failed attempts remain preserved. - [ ] Unsupported, incomplete, unavailable, or uncertain outcomes remain visible. ## Validation performed Node v26.5.0 was used locally because the pinned 24.18.0 was not installed. - `npm ci` then `npm run build:cached` — succeeded. - Issue reproduction script on main — reproduced (both MCP attempts returned `evidence_integrity_mismatch`; CLI returned partial results). - `npm run test:focused -- tests/boundary/mcp/managedNativeVerificationAdapters.test.ts tests/boundary/mcp/managedMcp.test.ts tests/boundary/mcp/outputSchemaSemanticConstraints.test.ts tests/boundary/cli/jsonInputStatus.test.ts tests/conformance/providers/managed/managedNativeVerification.test.ts`: - main source: 1 failed, 49 passed; - this branch after rebase: 50 passed. - `npx tsc --noEmit -p .` — exit 0. - `npx oxlint` and `npx oxfmt --check` on the changed files — exit 0. ## Compatibility, safety, and release - Breaking changes or migration steps: none. MCP callers that got `evidence_integrity_mismatch` for authentic native records of other operations now get the partial-verification Evidence. - Real Hopper/Ghidra, browser, or OS coverage: none needed. macOS static inspection (`/usr/bin/true`) was used only in the adapted issue script. - Package or release metadata impact: none. - Security, privacy, process, or containment review: Evidence authentication is still enforced before the workflow runs. The managed assembly is never executed. ## Author readiness Human owner: - [ ] I reviewed the final diff and relevant existing code, understand the change and its edge cases, and take responsibility for the complete PR, including AI-assisted work. - [ ] I checked the evidence above, confirmed it supports the current change, and recorded meaningful validation gaps. - [ ] I declare this PR ready for initial maintainer review. ## Before merge - [ ] This PR addresses a concrete problem or an agreed enhancement. - [ ] Material scope and authority questions are resolved, and any required maintainer scope decision covers the final diff. - [ ] The PR has one focused outcome and the title follows `type(scope): outcome`. - [ ] Related issue is linked, or the reason for not linking one is stated above. - [ ] 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. - [ ] I checked the final diff for secrets, unrelated cleanup, and unsupported claims. 🤖 Generated with [Claude Code](https://claude.com/claude-code) --- <sub>🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.</sub>
bsakaguchi 2026-10-31 01:14:08 +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#6395
No description provided.