[GH-ISSUE #5468] [Bug] Managed/native verification rejects inspection Evidence with an empty P/Invoke import name #3325

Closed
opened 2026-10-31 00:39:11 +00:00 by bsakaguchi · 2 comments
Owner

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

Before submitting

  • I searched the open and closed issues for a related report.
  • I removed credentials, tokens, private paths, and sensitive target data.

Area

Evidence, artifacts, or reconstruction

Observed behavior

inspect-managed-native-boundaries succeeds and returns complete Evidence for a synthetic PE/CLI declaration with import_name: "" and import_scope_name: "nativehelper.dll". Passing that unchanged Evidence to verify-managed-native-boundaries fails with invalid_request / invalid_input: the verifier rejects its own nested managed.import_name result field as invalid caller input. The canonical request schema accepts the request. The real stdio MCP tool verify_managed_native_boundaries fails equivalently.

Reproduction

Independently reproduced on the already built source checkout below. Run this from its root in Bash with Node.js, jq, base64, and gzip available. The payloads contain a synthetic 4,096-byte PE/CLI fixture and the shipped synthetic native-observation example; no managed code, native library, or live provider executes. The assembly SHA-256 is 21abedb0cd58debbcbae0b187f27a4fdd66cb491d48601d219e0392f4451d7b8.

Executable reproduction
REPRO="$(mktemp -d)"
mkdir -p "$REPRO"/{home,config,data,cache,state}
rea_repro() {
  env HOME="$REPRO/home" XDG_CONFIG_HOME="$REPRO/config" \
    XDG_DATA_HOME="$REPRO/data" XDG_CACHE_HOME="$REPRO/cache" \
    XDG_STATE_HOME="$REPRO/state" node scripts/rea.mjs "$@"
}
printf '%s' 'H4sIAAAAAAACE/ONYiAbNDBQDgJcGRh8GBlRxB4wMDFyM2JRrABjODAwCAApJixqDHCIIwEBhgEAQLd7IHH1SlIrSmCOAfmLD9PdQOEEWjvLA2wtKwODIgODCNB+ULADMRuDGgODIMPwB07BXk6MDJDExgPEZSZ6BnrGBsaGliARFnAEHANi5ToGBg2gsqUgdnBJUWZeejFIxQVGSBQqu4d6uoDSLpBvAuI75eQnQe0ABWu4CIMIJ1KaZiQRg0iYdlkGMyBbgCGMIQ4Yc4xgmMbABXQgSFZMIY+BF0hzMgQAY1CPgZtBjAHkVGawGSwNIJIJyGOBmgZSy8GA7LJpcDYoQbZAmG6ZFSWlRal6KTk5cLZvYl5iemoKQ0hiUXpqiVtRYm5qeX5RtmMJMHySSktSGYIri0tSc/WCSvNKMnNT9cJSi4oz8/OAYcegl1ySX8QQUJSfDtQFM5AhOR+oMrWIwTcxM48hL7Eksyw1IzWnILUIxdqi1OL80qLk1GI080HONFYSZAh1KU/rmLlq95m77/4zcGyvigmTNHnQycTGAQwCRhYFRkY+WUYGCT0/1xDn/KJUx4ICHajDbMss9AwYRsEoGDEAlPth+Uk3JbEkcTRIRhQwYqoGVissoKqNS2s0OEbBKBgFo2DEAABdzv3TABAAAA==' | base64 -d | gzip -d > "$REPRO/empty-import.dll"
printf '%s' 'H4sIAAAAAAACE7VVwW7bMAz9FUPnpLXT1Gly22HHocB6LAqDluiYqywZkpwmK/rvI+PURbEeBhjLzdLj4+OjyDy+KjyQQaexIqN2/FXpeoPFXb5ZG7Mqal3nxaap65tSF1vT5LfbMl/dGN3kd5pP12Dy2xK2W32zhc2mXOmVWqg41L9QJ7V7VQ46ZF4HiQ7You0xXBlrGWRoj/GMiS2sbktGbWb+1NtCWa/BVj2klgmv8QhdbzFefyGg8aEDFqA60O3S8wkE3VJi5UMQ0ce7sirXQtoHLzYFUXv2aaRbcqSPHHip8uf3b9l4k/HN/UM2xS3UAUMk7xhVCCM4sKdIsWJIQ5aj3WCtZEJDGhJW6dQLZ0C4egczjWf9nOFMRC72LLYS/SK/h8A6EidinZwjwEsVMA42vbM7KdnSbzTTxesXPkS0zMugz4ZM3bwYs1DauwTkMFRSQ+WbJuIlGedHZwhEqKWUuMSFevHBVJHzq1255g5I0KVOc7JUS1cs7Fn/49NCDYN4PSpHl8Kp9+RSPDchYXdBJZ/Aql3OmGMLQxT71S6FAfkxUEfpbNcZ/Pa5xfOY6oGsqdhvMJBgFpX1YCrtuw6cmSfKYM+u8zzTzOqo632Y6TUe/+KYnhC/Y1eNsyKDZwy3gwEqPxZ5nstTQXhWuwZsZO6AI9d0EP0Q9HmxdOrtQ1jxb8Ii7juc+5JkttGBExkS/RmhHi4zlP2QqbrPoiWN2TQw2TgrGcVscM/Ov7iMXJZa/o4nl1pMpLPL9rpSko9Dm3FVi311xHBAI94NqfWB0omPY0t9j2YJIVEDvIFlcA4UvJN632fpvyqVZtmRnMXwq+bFB/tpv8l6nlxcfPz7WHLPo7NPfwAPOBvilQYAAA==' | base64 -d | gzip -d > "$REPRO/native.json"
rea_repro inspect-managed-native-boundaries "$REPRO/empty-import.dll" --json > "$REPRO/inspection.json"
jq -n --slurpfile managed "$REPRO/inspection.json" --slurpfile native "$REPRO/native.json" \
  '{managed_boundaries: $managed[0], native_observations: $native[0]}' > "$REPRO/request.json"
rea_repro verify-managed-native-boundaries "$REPRO/request.json" --json

Inspection exits 0; verification exits 1. The exact decoded payloads and command sequence were independently replayed, with only the disposable directory location changed. The verifier also exercised the same request through a real stdio MCP client. An open_native / nativehelper.dll control succeeded through both adapters with one verified declaration. An additional empty-import/empty-module fixture failed through CLI, showing that an empty module name is unnecessary. These are observed cases, not a measured failure rate in real assemblies.

Expected behavior

Verification should accept authenticated inspection Evidence under the producer's schema, preserve the declaration, and return an explicit unresolved or partial result when its entry identity cannot be matched. It should not blame caller arguments for an invalid nested value created in its own output.

At the tested revision, src/domain/managed/managedArtifact.ts:257-267 permits an empty import string; src/domain/managed/managedNativeVerification.ts:33-46 authenticates the inspection operation and parses that producer schema. src/contracts/managed/managedWorkflowToolContracts.ts:116-123 promises preservation of declaration and unresolved states. This is a static Evidence contract, not a claim that the CLR accepts the assembly or resolves an empty entry point.

Impact and scope

P2: a bounded metadata shape prevents the static inspection-to-verification workflow from returning a result and produces unusable caller-remediation advice. Ordinary import verification succeeds. Both CLI and MCP reproduce the rejection. No direct verification workaround was found: modifying inspection Evidence without recomputing its identity is rejected for an Evidence semantic identifier mismatch; inspection alone does not provide native verification.

Only one declaration per fixture was executed. Real-world frequency, CLR loadability, other platforms, and multi-declaration behavior were not tested. No security boundary crossing was established.

REA version

rea-agents 6.7.0; source commit 074768901f3cdc8205b61773fb1faf6f6c7b3ca8.

Runtime and platform

Node.js v26.12.0; macOS. NOT_ENOUGH_INFO: the independent verification notes did not record the macOS version or architecture. No Hopper, Ghidra, IDA, or other native provider executed.

Target and artifact context

Synthetic PE/CLI fixture with one P/Invoke declaration, an empty import name, and nonempty module nativehelper.dll. Native observations are the shipped synthetic example from src/contracts/managed/managedWorkflowExamples.ts:315, describing an open_native export. No production artifact or CLR loader was exercised.

Interface

CLI

Earliest failure stage

Transport or result projection

Relevant output or evidence

Observed CLI verification error:

{"code":"invalid_request","category":"invalid_input","message":"Analysis input is invalid. Check the arguments and try again.","retryable":true,"remediation":{"action":"Correct the listed arguments and retry."},"details":{"operation":"verify_managed_native_boundaries","issues":[{"path":[],"reason":"invalid_value","message":"A nested value failed validation at managed.import_name: Too small: expected string to have >=1 characters"}]}}

The inspection reported complete metadata and coverage, no coverage issues, and verification: "managed-declaration-only". The canonical managedNativeVerificationInputSchema.safeParse succeeded for the empty-import request. MCP returned isError: true, with the equivalent error under error in its text content. The ordinary control returned verified: 1, inferred: 0, unresolved: 0, contradicted: 0 through both adapters.

Typed outcome or recovery expected

Retain the inspected declaration and its empty source value, report unresolved/partial semantics explicitly, and return no invalid caller-input error caused by constructing the result. Preserve ordinary control verification and rejection of genuinely tampered Evidence. These restoration checks are proposed acceptance criteria; no fix was tested.

Analysis or suspected cause

Source-derived reasoning: src/dotnet/ManagedNativeBoundaryHelpers.ts:194-199,225 preserves the empty import; src/domain/managed/managedNativeVerificationMatch.ts:307-322 copies it into the result and validates it. The output schema at src/domain/managed/managedNativeVerificationSchemas.ts:31 requires a nonempty managed.import_name. src/application/managed/ManagedNativeVerificationService.ts:30-36 converts that output-construction validation failure into an invalid caller-input outcome.

Additional context

Prepared with AI assistance and independently reproduced through the built CLI and real stdio MCP. Upstream was fetched before submission: none of the cited producer, verifier, output-schema, or service files changed between the tested baseline and origin/main at 052956af3416fa01d93837e54fdec3ad2739f6d1. No reproduction on that later revision is claimed. No last-known-good version is established.

Related reports checked: #3201 concerns missing module identity becoming a false contradiction, #4055 concerns runtime-provided methods being counted as unresolved native bodies, #2621 concerns duplicate-ID input diagnostics, and #4639 concerns authentic unsupported native Evidence failing only over MCP. None describes this empty-import output-schema failure.

Originally created by @coygeek on GitHub (Oct 20, 2026). Original GitHub issue: https://github.com/morluto/rea/issues/5468 ### Before submitting - [x] I searched the open and closed issues for a related report. - [x] I removed credentials, tokens, private paths, and sensitive target data. ### Area Evidence, artifacts, or reconstruction ### Observed behavior `inspect-managed-native-boundaries` succeeds and returns complete Evidence for a synthetic PE/CLI declaration with `import_name: ""` and `import_scope_name: "nativehelper.dll"`. Passing that unchanged Evidence to `verify-managed-native-boundaries` fails with `invalid_request` / `invalid_input`: the verifier rejects its own nested `managed.import_name` result field as invalid caller input. The canonical request schema accepts the request. The real stdio MCP tool `verify_managed_native_boundaries` fails equivalently. ### Reproduction Independently reproduced on the already built source checkout below. Run this from its root in Bash with Node.js, jq, base64, and gzip available. The payloads contain a synthetic 4,096-byte PE/CLI fixture and the shipped synthetic native-observation example; no managed code, native library, or live provider executes. The assembly SHA-256 is `21abedb0cd58debbcbae0b187f27a4fdd66cb491d48601d219e0392f4451d7b8`. <details> <summary>Executable reproduction</summary> ```bash REPRO="$(mktemp -d)" mkdir -p "$REPRO"/{home,config,data,cache,state} rea_repro() { env HOME="$REPRO/home" XDG_CONFIG_HOME="$REPRO/config" \ XDG_DATA_HOME="$REPRO/data" XDG_CACHE_HOME="$REPRO/cache" \ XDG_STATE_HOME="$REPRO/state" node scripts/rea.mjs "$@" } printf '%s' 'H4sIAAAAAAACE/ONYiAbNDBQDgJcGRh8GBlRxB4wMDFyM2JRrABjODAwCAApJixqDHCIIwEBhgEAQLd7IHH1SlIrSmCOAfmLD9PdQOEEWjvLA2wtKwODIgODCNB+ULADMRuDGgODIMPwB07BXk6MDJDExgPEZSZ6BnrGBsaGliARFnAEHANi5ToGBg2gsqUgdnBJUWZeejFIxQVGSBQqu4d6uoDSLpBvAuI75eQnQe0ABWu4CIMIJ1KaZiQRg0iYdlkGMyBbgCGMIQ4Yc4xgmMbABXQgSFZMIY+BF0hzMgQAY1CPgZtBjAHkVGawGSwNIJIJyGOBmgZSy8GA7LJpcDYoQbZAmG6ZFSWlRal6KTk5cLZvYl5iemoKQ0hiUXpqiVtRYm5qeX5RtmMJMHySSktSGYIri0tSc/WCSvNKMnNT9cJSi4oz8/OAYcegl1ySX8QQUJSfDtQFM5AhOR+oMrWIwTcxM48hL7Eksyw1IzWnILUIxdqi1OL80qLk1GI080HONFYSZAh1KU/rmLlq95m77/4zcGyvigmTNHnQycTGAQwCRhYFRkY+WUYGCT0/1xDn/KJUx4ICHajDbMss9AwYRsEoGDEAlPth+Uk3JbEkcTRIRhQwYqoGVissoKqNS2s0OEbBKBgFo2DEAABdzv3TABAAAA==' | base64 -d | gzip -d > "$REPRO/empty-import.dll" printf '%s' 'H4sIAAAAAAACE7VVwW7bMAz9FUPnpLXT1Gly22HHocB6LAqDluiYqywZkpwmK/rvI+PURbEeBhjLzdLj4+OjyDy+KjyQQaexIqN2/FXpeoPFXb5ZG7Mqal3nxaap65tSF1vT5LfbMl/dGN3kd5pP12Dy2xK2W32zhc2mXOmVWqg41L9QJ7V7VQ46ZF4HiQ7You0xXBlrGWRoj/GMiS2sbktGbWb+1NtCWa/BVj2klgmv8QhdbzFefyGg8aEDFqA60O3S8wkE3VJi5UMQ0ce7sirXQtoHLzYFUXv2aaRbcqSPHHip8uf3b9l4k/HN/UM2xS3UAUMk7xhVCCM4sKdIsWJIQ5aj3WCtZEJDGhJW6dQLZ0C4egczjWf9nOFMRC72LLYS/SK/h8A6EidinZwjwEsVMA42vbM7KdnSbzTTxesXPkS0zMugz4ZM3bwYs1DauwTkMFRSQ+WbJuIlGedHZwhEqKWUuMSFevHBVJHzq1255g5I0KVOc7JUS1cs7Fn/49NCDYN4PSpHl8Kp9+RSPDchYXdBJZ/Aql3OmGMLQxT71S6FAfkxUEfpbNcZ/Pa5xfOY6oGsqdhvMJBgFpX1YCrtuw6cmSfKYM+u8zzTzOqo632Y6TUe/+KYnhC/Y1eNsyKDZwy3gwEqPxZ5nstTQXhWuwZsZO6AI9d0EP0Q9HmxdOrtQ1jxb8Ii7juc+5JkttGBExkS/RmhHi4zlP2QqbrPoiWN2TQw2TgrGcVscM/Ov7iMXJZa/o4nl1pMpLPL9rpSko9Dm3FVi311xHBAI94NqfWB0omPY0t9j2YJIVEDvIFlcA4UvJN632fpvyqVZtmRnMXwq+bFB/tpv8l6nlxcfPz7WHLPo7NPfwAPOBvilQYAAA==' | base64 -d | gzip -d > "$REPRO/native.json" rea_repro inspect-managed-native-boundaries "$REPRO/empty-import.dll" --json > "$REPRO/inspection.json" jq -n --slurpfile managed "$REPRO/inspection.json" --slurpfile native "$REPRO/native.json" \ '{managed_boundaries: $managed[0], native_observations: $native[0]}' > "$REPRO/request.json" rea_repro verify-managed-native-boundaries "$REPRO/request.json" --json ``` </details> Inspection exits 0; verification exits 1. The exact decoded payloads and command sequence were independently replayed, with only the disposable directory location changed. The verifier also exercised the same request through a real stdio MCP client. An `open_native` / `nativehelper.dll` control succeeded through both adapters with one verified declaration. An additional empty-import/empty-module fixture failed through CLI, showing that an empty module name is unnecessary. These are observed cases, not a measured failure rate in real assemblies. ### Expected behavior Verification should accept authenticated inspection Evidence under the producer's schema, preserve the declaration, and return an explicit unresolved or partial result when its entry identity cannot be matched. It should not blame caller arguments for an invalid nested value created in its own output. At the tested revision, `src/domain/managed/managedArtifact.ts:257-267` permits an empty import string; `src/domain/managed/managedNativeVerification.ts:33-46` authenticates the inspection operation and parses that producer schema. `src/contracts/managed/managedWorkflowToolContracts.ts:116-123` promises preservation of declaration and unresolved states. This is a static Evidence contract, not a claim that the CLR accepts the assembly or resolves an empty entry point. ### Impact and scope P2: a bounded metadata shape prevents the static inspection-to-verification workflow from returning a result and produces unusable caller-remediation advice. Ordinary import verification succeeds. Both CLI and MCP reproduce the rejection. No direct verification workaround was found: modifying inspection Evidence without recomputing its identity is rejected for an Evidence semantic identifier mismatch; inspection alone does not provide native verification. Only one declaration per fixture was executed. Real-world frequency, CLR loadability, other platforms, and multi-declaration behavior were not tested. No security boundary crossing was established. ### REA version `rea-agents` 6.7.0; source commit `074768901f3cdc8205b61773fb1faf6f6c7b3ca8`. ### Runtime and platform Node.js v26.12.0; macOS. NOT_ENOUGH_INFO: the independent verification notes did not record the macOS version or architecture. No Hopper, Ghidra, IDA, or other native provider executed. ### Target and artifact context Synthetic PE/CLI fixture with one P/Invoke declaration, an empty import name, and nonempty module `nativehelper.dll`. Native observations are the shipped synthetic example from `src/contracts/managed/managedWorkflowExamples.ts:315`, describing an `open_native` export. No production artifact or CLR loader was exercised. ### Interface CLI ### Earliest failure stage Transport or result projection ### Relevant output or evidence Observed CLI verification error: ```json {"code":"invalid_request","category":"invalid_input","message":"Analysis input is invalid. Check the arguments and try again.","retryable":true,"remediation":{"action":"Correct the listed arguments and retry."},"details":{"operation":"verify_managed_native_boundaries","issues":[{"path":[],"reason":"invalid_value","message":"A nested value failed validation at managed.import_name: Too small: expected string to have >=1 characters"}]}} ``` The inspection reported complete metadata and coverage, no coverage issues, and `verification: "managed-declaration-only"`. The canonical `managedNativeVerificationInputSchema.safeParse` succeeded for the empty-import request. MCP returned `isError: true`, with the equivalent error under `error` in its text content. The ordinary control returned `verified: 1`, `inferred: 0`, `unresolved: 0`, `contradicted: 0` through both adapters. ### Typed outcome or recovery expected Retain the inspected declaration and its empty source value, report unresolved/partial semantics explicitly, and return no invalid caller-input error caused by constructing the result. Preserve ordinary control verification and rejection of genuinely tampered Evidence. These restoration checks are proposed acceptance criteria; no fix was tested. ### Analysis or suspected cause Source-derived reasoning: `src/dotnet/ManagedNativeBoundaryHelpers.ts:194-199,225` preserves the empty import; `src/domain/managed/managedNativeVerificationMatch.ts:307-322` copies it into the result and validates it. The output schema at `src/domain/managed/managedNativeVerificationSchemas.ts:31` requires a nonempty `managed.import_name`. `src/application/managed/ManagedNativeVerificationService.ts:30-36` converts that output-construction validation failure into an invalid caller-input outcome. ### Additional context Prepared with AI assistance and independently reproduced through the built CLI and real stdio MCP. Upstream was fetched before submission: none of the cited producer, verifier, output-schema, or service files changed between the tested baseline and `origin/main` at `052956af3416fa01d93837e54fdec3ad2739f6d1`. No reproduction on that later revision is claimed. No last-known-good version is established. Related reports checked: #3201 concerns missing module identity becoming a false contradiction, #4055 concerns runtime-provided methods being counted as unresolved native bodies, #2621 concerns duplicate-ID input diagnostics, and #4639 concerns authentic unsupported native Evidence failing only over MCP. None describes this empty-import output-schema failure.
Author
Owner

@matbrgz commented on GitHub (Oct 20, 2026):

Cross-referencing with sibling reports in Cluster AK: #3351 and #5467 ([Bug] Managed/native verification treats an empty normalized module identity as known). Both address P/Invoke import resolution and empty string handling during managed/native verification.

Consolidated under Cluster AK (Managed/Native P/Invoke Boundary Verification Anomalies) in tracker #4330.

<!-- gh-comment-id:6291446068 --> @matbrgz commented on GitHub (Oct 20, 2026): Cross-referencing with sibling reports in **Cluster AK**: #3351 and #5467 (`[Bug] Managed/native verification treats an empty normalized module identity as known`). Both address P/Invoke import resolution and empty string handling during managed/native verification. Consolidated under **Cluster AK (Managed/Native P/Invoke Boundary Verification Anomalies)** in tracker #4330.
Author
Owner

@coygeek commented on GitHub (Oct 24, 2026):

Checked the reported fix on main at d87e73f2db.

The verifier output now derives managed declaration fields directly from managedNativeImportSchema, preserving its empty import-name allowance. Matching explicitly returns no symbol-name candidates for an empty import name, avoiding suffix-generated matches. The conformance test parameter table includes importName="" with an A export and expects unresolved plus unchanged managed.import_name and no candidates.

Implementation: managedNativeVerificationSchemas.ts, managedNativeVerificationMatch.ts.

The relevant regression checks in managedNativeVerification.test.ts passed in the focused test run on this revision. This closure is based on the current source and those checks; provider fixtures do not establish a real-engine run. Closing as completed on main.

<!-- gh-comment-id:6380754094 --> @coygeek commented on GitHub (Oct 24, 2026): Checked the reported fix on `main` at d87e73f2db50be72d33a4b3c7199af35518b441c. The verifier output now derives managed declaration fields directly from managedNativeImportSchema, preserving its empty import-name allowance. Matching explicitly returns no symbol-name candidates for an empty import name, avoiding suffix-generated matches. The conformance test parameter table includes importName="" with an A export and expects unresolved plus unchanged managed.import_name and no candidates. Implementation: [managedNativeVerificationSchemas.ts](https://github.com/morluto/rea/blob/d87e73f2db50be72d33a4b3c7199af35518b441c/src/domain/managed/managedNativeVerificationSchemas.ts#L27), [managedNativeVerificationMatch.ts](https://github.com/morluto/rea/blob/d87e73f2db50be72d33a4b3c7199af35518b441c/src/domain/managed/managedNativeVerificationMatch.ts#L257). The relevant regression checks in [managedNativeVerification.test.ts](https://github.com/morluto/rea/blob/d87e73f2db50be72d33a4b3c7199af35518b441c/tests/conformance/providers/managed/managedNativeVerification.test.ts) passed in the focused test run on this revision. This closure is based on the current source and those checks; provider fixtures do not establish a real-engine run. Closing as completed on main.
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#3325
No description provided.