[PR #3602] feat(windows): admit arm64 hosts for the bundled native controls #5849

Open
opened 2026-10-31 01:09:54 +00:00 by bsakaguchi · 0 comments
Owner

📋 Pull Request Information

Original PR: https://github.com/morluto/rea/pull/3602
Author: @chanasia
Created: 10/14/2026
Status: 🔄 Open

Base: main ← Head: feat/windows-arm64-native-controls


📝 Commits (10+)

  • bef00b0 feat(windows): admit arm64 hosts for the bundled native controls
  • 0c4744b test(windows): pin each manifest target check independently
  • 65e3cc6 feat(android): admit Windows arm64 hosts for JADX subprocess ownership
  • b6c3cd2 Merge remote-tracking branch 'origin/main' into sweep/3602
  • a0a0c66 fix(windows): align doctor and remediation text with arm64 admission
  • 4205b52 feat(ghidra): admit Windows arm64 hosts with win_arm_64 native tools
  • 1171423 Merge remote-tracking branch 'origin/main' into feat/windows-arm64-native-controls
  • 6fc7034 Merge remote-tracking branch 'origin/main' into feat/windows-arm64-native-controls
  • eb38ddd Merge remote-tracking branch 'origin/main' into feat/windows-arm64-native-controls
  • 943a542 Merge remote-tracking branch 'origin/main' into feat/windows-arm64-native-controls

📊 Changes

19 files changed (+270 additions, -115 deletions)

View changed files

📝 docs/installation.md (+4 -3)
📝 native/windows/src/process.cc (+4 -0)
📝 src/android/JadxConfiguration.ts (+6 -3)
📝 src/android/JadxRelease.ts (+2 -2)
📝 src/application/Doctor.test.ts (+23 -29)
📝 src/application/DoctorDiagnostics.ts (+3 -2)
📝 src/domain/windowsNativeArtifact.ts (+38 -23)
📝 src/ghidra/GhidraDoctor.test.ts (+9 -2)
📝 src/ghidra/GhidraInstallation.test.ts (+41 -0)
📝 src/ghidra/GhidraInstallation.ts (+3 -3)
📝 src/ghidra/GhidraProvider.behavior.test.ts (+2 -2)
📝 src/ghidra/GhidraProviderCapabilities.ts (+3 -3)
📝 src/process/WindowsAuthority.ts (+5 -4)
📝 src/windows/WindowsNativeLoader.test.ts (+67 -7)
📝 src/windows/WindowsNativeLoader.ts (+48 -24)
📝 src/windows/WindowsOwnedProcess.ts (+2 -2)
📝 tests/boundary/android/jadxDoctor.test.ts (+1 -1)
📝 tests/fixtures/windowsNativeArtifact.ts (+8 -4)
📝 tests/process-global/windowsNativeControlCapability.test.ts (+1 -1)

📄 Description

Summary

On Windows on Arm with native arm64 Node.js, every operation that needs the
bundled Windows native controls fails at host admission. JavaScript/Electron
static analysis is one example:

$ npx -y rea-agents@6.5.0 analyze-javascript-application <Discord 1.0.9258>/resources/app.asar --json
code: capability_unavailable
reason: REA Windows native controls require a Windows x64 host.

This PR makes the loader admit an arm64 build of the same addon, with the same
identity checks as x64. On a real arm64 host, the existing native conformance
lane passes and the analysis above completes.

The PR also opens the JADX host gate on arm64. JADX uses these controls to
own its Java subprocess. On arm64 it failed at requireSupportedHost with
unsupported_host, even with a JDK and the JADX jar configured, because the
gate admitted only win32/x64. arm64 now goes through the same checks as
x64: the native authority must load and report owned protocol stdin, or the
gate fails closed as before. On the same arm64 host, Android package
inspection, class search and method decompilation through MCP complete.

The last commit (4205b52) extends the arm64 admission to Windows Ghidra P0.
Ghidra 12.1 already maps an arm64 JVM to Ghidra/Features/Decompiler/os/win_arm_64
and its Gradle native build targets that platform, but the release archive ships
no win_arm_64 natives, and REA's installation check knew only win32/x64, so
an arm64 host was rejected with unsupported_host before Ghidra started. REA now
maps win32/arm64 to win_arm_64. The existing executable-header admission
and the JDK os.arch cross-check still apply, so an x64 decompiler or an
emulated x64 JDK is still reported as incompatible. REA still does not build or
install native tools.

This PR does not yet build or package an arm64 artifact. See Open
questions
. No issue is linked; this PR carries the proposal and the
questions it needs answered.

Problem and expected behavior

  • Before: loadWindowsNativeAuthority admits only win32/x64. The
    manifest, inspection schema and PE check accept only x64. process.cc
    reports a hardcoded "x64".
  • After: the shared native artifact contract
    (src/domain/windowsNativeArtifact.ts, introduced on main in 3d565fa)
    owns one table mapping each admitted architecture (x64, arm64) to its
    artifact name (rea-windows-<arch>.node) and PE machine (0x8664,
    0xAA64). The loader passes the host architecture to it. The checks are:
    • the manifest's architecture and artifact must match the host before
      the artifact is read;
    • the existing SHA-256 and PE32+ checks use the host's machine;
    • the native self-inspection must report the host architecture.
  • x64: behavior is unchanged.

Change and scope

  • native/windows/src/process.cc: report architecture from
    _M_ARM64/__aarch64__. The existing "x64" stays in #else. This was
    the only architecture-specific line in the native sources.

  • src/domain/windowsNativeArtifact.ts (18e08f1, 195e814): WINDOWS_NATIVE_TARGETS
    maps x64/arm64 to the artifact name and PE machine.
    parseWindowsNativeManifest takes the host architecture as an optional
    third argument. Its default is WINDOWS_NATIVE_ARTIFACT.architecture
    (x64), so the build and verify scripts keep their x64 contract unchanged.
    validateWindowsNativeArtifact checks the PE machine of the manifest's
    architecture, inside main's declared optional-header checks (a486cfe).
    WINDOWS_NATIVE_ARTIFACT and createWindowsNativeManifest stay x64.

  • src/windows/WindowsNativeLoader.ts: host admission, passing the host
    architecture to the shared contract, the inspection schema and its
    architecture cross-check, and readArtifact/loadArtifact taking the
    selected artifact name.

  • src/android/JadxConfiguration.ts: requireSupportedHost admits
    win32/arm64 as well as win32/x64, through the same path:
    systemWindowsNativeAuthority() must load and its inspection must report
    protocolStdin: true. Anything else still throws. The two remediation
    messages in this file no longer say x64 only.

  • src/windows/WindowsNativeLoader.test.ts: new tests:

    • arm64 admission;
    • a manifest declaring another target rejected before the artifact is read
      or loaded, with separate cases for architecture only, artifact only, and
      both (the reason now comes from the shared contract: "has an invalid
      architecture" or "has an invalid artifact");
    • a cross-architecture inspection rejected.

    The previous arm64 → host rejection case now uses ia32.

  • tests/fixtures/windowsNativeArtifact.ts (abfa130): main's shared PE
    fixture takes an optional architecture (default x64), so the arm64 loader
    cases reuse it. Its other callers keep x64.

  • src/application/DoctorDiagnostics.ts (a0a0c66): the informational host
    check admits win32/arm64 as well as win32/x64 and still rejects
    other Windows architectures. Without this, rea doctor called the same
    host unsupported that the loader and the JADX gate admit.

  • Remediation (a0a0c66): WindowsAuthority.ts, WindowsOwnedProcess.ts and
    JadxRelease.ts name the package whose bundled native artifact matches the
    host architecture instead of "Windows x64". The artifact-stage message is
    the first one an arm64 user with today's x64-only package hits. The
    Ghidra-specific strings were left for the Ghidra commit below.

  • Ghidra (4205b52):

    • src/ghidra/GhidraInstallation.ts: NATIVE_PLATFORMS maps
      win32/arm64 to win_arm_64; the two host remediation strings name
      Windows arm64.
    • src/ghidra/GhidraProviderCapabilities.ts: the Windows P0 limitation says
      the matching native addon may be x64 or arm64.
    • docs/installation.md: Windows x64/arm64 P0, and win_arm_64 beside
      linux_arm_64 as a native directory that release archives may lack.

Intentionally not included. These stay x64-only, fail-closed, until each is
verified:

  • Bun
  • the release build lane, package files, verify-windows-native-artifact.mjs,
    verify-windows-package.mjs and CI (the build and verify scripts call the
    shared contract with its x64 default)

Open questions

  1. Build lane:
    • Option A: extend the Linux cross-build with llvm-mingw
      (aarch64-w64-mingw32-clang++, llvm-dlltool -m arm64). The GNU
      MinGW-w64 aarch64 target is not mature yet.
    • Option B: build with MSVC on a windows-11-arm runner. The prototype
      used this toolchain (details below).
  2. Packaging: ship both artifacts in rea-agents with per-architecture
    manifests, or use per-architecture optional packages. This PR keeps one
    manifest.json describing whichever artifact was built.
  3. CI: run verify:windows-native on windows-11-arm alongside the x64
    lane.
  4. Remediation text: resolved in a0a0c66 (see Change and scope),
    following review feedback.

Q1–Q3 do not affect whether this PR is safe to merge: x64 is unchanged, and
arm64 hosts with today's x64-only package fail at the artifact stage with a
clearer message. They block shipping arm64 to users. Q1 (build lane) comes
first; Q2 (packaging) and Q3 (CI) follow from it.

Contract and boundary impact

  • Semantic owner and earliest changed stage: WindowsNativeLoader host
    admission decides the host architecture once. The shared contract in
    src/domain/windowsNativeArtifact.ts binds the manifest and PE machine to
    it, and consumers use the loader's result.
  • Contribution scope fit and linked maintainer decision: existing native
    controls, extended to a new host architecture. No new provider or
    capability. Pending maintainer decision on the open questions.
  • CLI and MCP/tool-catalog contract: none changed.
  • Provider, bridge, target-format, or platform compatibility:
    • x64 hosts are unchanged.
    • On arm64 hosts running the current x64-only package, the failure moves
      from the host stage (unsupported_host) to the artifact stage
      (runtime_missing), with the reason "REA Windows native controls are
      unavailable: Windows native artifact manifest has an invalid
      architecture" (observed on this host after 18e08f1; see Validation
      performed
      ). The reason no longer names the required artifact; the
      artifact-stage remediation in WindowsAuthority.ts names
      rea-windows-arm64.node.
    • On arm64 hosts with the arm64 artifact, JADX operations no longer stop
      at unsupported_host.
    • rea doctor reports a win32 arm64 host as supported in its
      informational host check.
    • Windows Ghidra P0 on an arm64 host with a win_arm_64 decompiler and an
      aarch64 JDK is admitted instead of failing at unsupported_host. An
      arm64 host whose Ghidra has only win_x86_64 natives still fails, now at
      native_decompiler ("Matching native decompiler for win32/arm64 was not
      found"). This is source-derived; it was not run with x64-only natives.
  • Evidence, artifact, provenance, or reconstruction contract: none.
  • Target selection, authority, upstream behavior, and cleanup details:
    unchanged. The same Job Object, DACL and cleanup controls are admitted on
    arm64 only after the native inspection proves them.
  • Generated metadata, package, or installation impact: none in this diff.
    Packaging is open question 2.

Expected effects. These are the existing native controls, now admitted on
arm64 hosts; nothing new is introduced:

  • Read existing files or captured data.
  • Launch or attach to a process.
  • Change process memory, registers, files, or configuration. (Private
    runtime directories and owned helper processes only; target processes and
    memory are untouched.)
  • Inject instrumentation or run scripts/code.
  • 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:
    • src/windows/WindowsNativeLoader.test.ts (above);
    • src/application/Doctor.test.ts: the host check is now an it.each over
      x64 (supported), arm64 (supported) and ia32 (unsupported);
    • src/ghidra/GhidraDoctor.test.ts and
      tests/boundary/android/jadxDoctor.test.ts: remediation assertions
      follow the new wording.
    • tests/fixtures/windowsNativeArtifact.ts: the shared PE fixture takes
      the architecture (above);
    • src/ghidra/GhidraInstallation.test.ts: a Windows arm64 installation
      with a win_arm_64 decompiler and an aarch64 JDK is admitted;
      src/ghidra/GhidraProvider.behavior.test.ts follows the capability
      wording.
  • Base reproduction: the rea-agents@6.5.0 failure in Summary, on
    the host below.
  • User-visible CLI output: analyze-javascript-application on the same
    app.asar with this branch completes in about 51 s cold. Statistics:
    relevant_files 5, parsed_javascript_files 2, modules 972,
    visited_ast_nodes 503068, parse_failures 0; graph 1,132 nodes / 4,187
    edges.
  • JADX through MCP: on a third-party release APK (22,088 classes, 995
    resources), with Temurin JDK 21.0.12 and jadx-headless-mcp 0.7.1:
    • inspect_android_package returned the package summary;
    • search_android_classes found the main activity;
    • inspect_android_method decompiled its onCreate to Java
      (fell_back: false).
  • Remaining proof gaps:
    • no unit test covers the JADX gate change itself
    • the MinGW x64 lane after the process.cc change (no MinGW on this host;
      CI covers it)
    • an x64 child under emulation inside an arm64-owned Job Object
    • multi-processor-group hosts
    • a packed tarball and verify-windows-package.mjs
    • CLI/MCP from a packed install
    • Bun
    • Ghidra on an x64 Windows host after 4205b52 (the change only adds a map
      entry and strings; the x64 test still passes)
    • Ghidra with official win_arm_64 natives: the 12.1.4 release has none,
      so validation used natives built locally (details below)
    • the native lane, JADX and Ghidra end-to-end after 18e08f1 and the later
      main merges (only the loader path was re-run on the real artifact)

Evidence-bearing checks:

  • 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

Host: Windows 11 Pro 10.0.26200 arm64, Snapdragon X Elite X1E78100 (12
logical processors, one processor group), NTFS, Node.js 24.18.0 arm64. The
token was non-elevated, medium integrity (integrityLevel 8192). Base
b8510ee.

  • npx vitest run src/windows/WindowsNativeLoader.test.ts — 25 passed.
    Removing either manifest equality check (architecture or artifact) fails
    one test each, checked by temporarily editing the guard out.
  • npm run check:fast — passed (typecheck, lint).
  • npm run docs:check — passed.
  • npx vitest run src/windows src/process src/application/Doctor — 326
    passed, 2 failed, 21 skipped. Unmodified b8510ee on this host gives 323
    passed and the same 2 failures, so they are unrelated to this change:
    • ProcessScenarioRuntimeValidation "preserves the caller-selected
      executable symlink"
    • Doctor "checks the canonical user install after the system launcher"
  • npm run build:cached — passed.
  • systemWindowsNativeAuthority() with the arm64 artifact — available: true,
    architecture: "arm64". privateDacl, privateBridgeDescriptorAccess,
    atomicJobAssignment, killOnOwnerClose, protocolStdin and
    jobMemoryLimit are all true.
  • node scripts/verify-windows-native.mjs . <arm64 process-boundary.exe> —
    ok: true:
    • all 20 controls;
    • processes checks, including breakawayDenied,
      childOwnerNormalizedWithoutChangingCaller,
      windowsEnvironmentSemantics,
      callerAffinityBoundsOwnedProcessOrRefusesToWiden,
      ownerForcedExitKillsOwnedChild, protocol input and jobMemoryLimit
      (128 MiB limit; reached exit 1 with peak 140,668,928 bytes; control exit
      0).
  • node scripts/rea.mjs analyze-javascript-application <app.asar> --json —
    completed (above).
  • Pre-commit hooks (oxfmt, oxlint) — passed.

JADX commit (65e3cc6, on top of 0c4744b):

  • npm run compile — passed.
  • npx vitest run tests/boundary/android/JadxAnalysis.test.ts — 14 passed.
  • inspectJadxAvailability() from the rebuilt dist — status: "available", with the JDK compiler and the JADX jar found.
  • The MCP calls above, against a server restarted on the rebuilt dist.
  • Pre-commit hooks (oxfmt, oxlint) — passed.

After merging main (b6c3cd2) and the doctor/remediation commit (a0a0c66).
main changed process.cc and the boundary fixture, so both were rebuilt
for arm64 first:

  • npx vitest run src/application/Doctor.test.ts src/ghidra/GhidraDoctor.test.ts tests/boundary/android/jadxDoctor.test.ts tests/boundary/android/jadxConfiguration.test.ts src/windows src/process tests/conformance/providers/ghidra/windowsCapabilities.test.ts
    — 359 passed, 2 failed, 50 skipped. The 2 failures are the same two as
    above. They also fail on b6c3cd2 without a0a0c66 on this host.
  • npm run check:fast — passed. npm run docs:check — passed.
    npm run build:cached — passed.
  • node scripts/verify-windows-native.mjs . <arm64 process-boundary.exe> —
    ok: true, 66 leaf checks. The only false values are
    callerToken.elevated and callerToken.administrator (non-elevated
    token).
  • node scripts/rea.mjs doctor --json — host check ok: true,
    detail: "win32 arm64".
  • analyze-javascript-application on the same app.asar — modules 972,
    parse_failures 0, graph 1,132 nodes / 4,187 edges (unchanged).

Ghidra commit (4205b52, on top of a0a0c66), same host. Ghidra 12.1.4 (release
archive, SHA-256 checked), Microsoft Build of OpenJDK 21.0.12 aarch64, and
win_arm_64 natives built locally (details below):

  • npx vitest run src/ghidra — 544 passed, 14 failed, 7 skipped. The same 14
    fail on a0a0c66 without this commit on this host (GhidraAnalysisSeeds
    symlink commitment, GhidraLanguageOverride ×5, GhidraPowerPcProfile ×1,
    GhidraSnapshotCache relationship/replay ×7).
  • npm run check:fast — passed. npm run docs:check — passed.
    npm run build:cached — passed. Pre-commit hooks (oxfmt, oxlint) — passed.
  • node scripts/rea.mjs doctor --provider ghidra --json — every Ghidra check
    ok: true: platform win32, architecture arm64, java (21.0.12.1,
    64-bit JDK), native_decompiler (".../os/win_arm_64/decompile.exe reports
    pe arm64, which matches win32/arm64") and native_authority.
  • rea decompile <3 MB x64 PE> entry --provider ghidra — returned the C
    pseudo-code of entry (83 s cold, including analysis).
  • Stdio MCP (rea mcp, one session): open_binary on a 47.8 MB x64 PE,
    then xrefs, resolve_containing_procedure and procedure_pseudo_code
    on the functions found. The first analysis-backed call returned after
    15 min 42 s; later calls in the session returned in seconds.
  • With the default 330 s startup deadline, the same 47.8 MB import did not
    finish (provider_timeout, "Ghidra startup deadline elapsed");
    REA_GHIDRA_STARTUP_TIMEOUT_MS=3600000 was set for the runs above. The
    default is unchanged by this PR.

After merging main (9c9c64e) and moving the arm64 binding into the shared
contract (18e08f1). main now requires Node.js ^24.22.1, so these runs used
Node.js 24.22.1 arm64:

  • npm run typecheck — passed. Pre-push check:fast — passed.
  • npx vitest run src/domain/windowsNativeArtifact.test.ts src/windows src/process/WindowsAuthority src/ghidra src/application/Doctor.test.ts tests/conformance/formats/mzPeAdmission.test.ts tests/conformance/providers/ghidra tests/process-global/windowsNativeControlCapability.test.ts tests/boundary/android/jadxDoctor.test.ts
    — 1119 passed, 6 failed, 44 skipped. Five failures (GhidraDolProfile ×4,
    GhidraMipsProfile ×1) fail the same way on unmodified 9c9c64e on this
    host. The sixth is the GhidraAnalysisSeeds symlink commitment listed
    above (EPERM creating a symlink).
  • loadWindowsNativeAuthority from source with the arm64 artifact built for
    the earlier validation. Its manifest says 6.5.0, so the host's
    packageVersion was set to match. Result: available: true,
    architecture: "arm64", with privateDacl,
    privateBridgeDescriptorAccess, atomicJobAssignment, killOnOwnerClose,
    protocolStdin and jobMemoryLimit all true.
  • The same arm64 host with an x64 manifest — failureStage: "artifact",
    reason "Windows native artifact manifest has an invalid architecture".
  • Not repeated after this merge: an arm64 artifact rebuilt from the current
    sources, verify-windows-native.mjs, windowsNativeArtifactVerifier.test.ts
    (needs dist), docs:check, build:cached, and the JADX and Ghidra
    end-to-end runs.

After merging main (365fb03), whose a486cfe validates the declared PE
optional header, and keeping the arm64 machine check inside that validation
(195e814), same host and Node.js:

  • Pre-push check:fast — passed.
  • The focused vitest command above — 1160 passed, 6 failed, 47 skipped.
    The 6 failures are the same six as above.
  • The loader from source with the same arm64 artifact — available: true,
    architecture: "arm64", all controls true. The same host with an x64
    manifest — "Windows native artifact manifest has an invalid architecture".

After merging main (bcc6775), whose 740c0f5 moved the loader's PE bytes into
tests/fixtures/windowsNativeArtifact.ts, and binding that fixture to the
requested architecture (abfa130), same host and Node.js:

  • Pre-push check:fast — passed.
  • npx vitest run src/application/Doctor.test.ts tests/boundary/android/jadxDoctor.test.ts src/ghidra/GhidraDoctor.test.ts src/ghidra/GhidraInstallation.test.ts src/ghidra/GhidraProvider.behavior.test.ts src/android src/windows src/domain/windowsNativeArtifact.test.ts
    — 485 passed, 31 skipped.
  • npx vitest run src/windows src/domain/windowsNativeArtifact.test.ts src/process tests/process-global/windowsNativeControlCapability.test.ts
    — 880 passed, 9 failed, 67 skipped. The 9 (LinuxCgroupMemory ×2,
    OwnedWorkerRuntime ×7) fail the same way on unmodified bcc6775 on this
    host.
  • npx vitest run tests/conformance/readmeConsistency.test.ts tests/boundary/process/windowsNativeArtifactVerifier.test.ts
    — 11 passed.
  • node scripts/run-turbo.mjs run docs:check:built — passed. npm run docs:check itself stops in its run-exclusive.mjs wrapper with "REA
    Windows native controls are unavailable: Windows native artifact belongs
    to another REA version": the local arm64 artifact was built for 6.5.0 and
    the package is now 6.8.0.
  • The loader from source with the same arm64 artifact — same two results as
    above.
  • Not repeated: an arm64 artifact rebuilt from the current sources,
    verify-windows-native.mjs, build:cached, and the JADX and Ghidra
    end-to-end runs.
How the arm64 artifact was built for this validation (outside the repository lane)

MSVC 14.51 (Visual Studio 2026) Hostarm64/arm64, under
vcvarsall.bat arm64. Node 22.19.0 headers were checked against
SHASUMS256.txt. node-api.def was generated the same way as
build-windows-native.mjs.

lib /nologo /def:node-api.def /machine:arm64 /out:node-api.lib
cl /nologo /std:c++17 /O2 /EHsc /MT /W3 /DNAPI_VERSION=8 /D_WIN32_WINNT=0x0A00 ^
  /I<node-v22.19.0>\include\node ^
  native\windows\src\addon.cc native\windows\src\filesystem.cc native\windows\src\process.cc ^
  /LD /Fe:native\windows\build\rea-windows-arm64.node ^
  /link /Brepro /DELAYLOAD:node.exe node-api.lib delayimp.lib advapi32.lib bcrypt.lib ntdll.lib
cl /nologo /std:c++17 /O2 /EHsc /MT tests\fixtures\windows\processBoundary.cc ^
  /Fe:process-boundary.exe /link advapi32.lib

The existing addon.cc delay-load hook works unchanged with MSVC. The
manifest.json used architecture: "arm64" and
artifact: "rea-windows-arm64.node". MSVC reports C4267/C4244 size_t
narrowing warnings; they are not arm64-specific (x64 size_t is 64-bit too).

How the win_arm_64 Ghidra natives were built for this validation (outside the repository)

Ghidra 12.1.4 sources (tag Ghidra_12.1.4_build), MSVC 14.51 Hostarm64/arm64
under vcvarsall.bat arm64. Source lists, defines and flags follow the
VisualCpp branch of Ghidra/Features/Decompiler/buildNatives.gradle, whose
model already lists win_arm_64:

cl /c /MP /EHsc /W3 /O2 /Oy /GL /D_SECURE_SCL=0 /D_HAS_ITERATOR_DEBUGGING=0 ^
  /DWINDOWS /D_WINDOWS /DWIN32 /D_WIN32 <decompile .cc sources>
link /LTCG /OUT:decompile.exe *.obj
rem sleigh.exe: the sleigh .cc list with /DLOCAL_ZLIB, plus zlib *.c with /DNO_GZIP

Both outputs are PE32+ machine 0xAA64 and were placed in
Ghidra/Features/Decompiler/os/win_arm_64/. Gradle's win_arm_64 branch
does not define WIN64/_WIN64 (only win_x86_64 does); the sources do not
use WIN64, and MSVC predefines _WIN64 for ARM64.

Compatibility, safety, and release

  • Breaking changes or migration steps: none. WindowsNativeLoadHost
    readArtifact/loadArtifact now receive the selected artifact name. The
    interface is internal, and the only production host is
    systemWindowsNativeAuthority. parseWindowsNativeManifest gains an
    optional architecture argument; existing callers keep x64.
  • Real Hopper/Ghidra, browser, or OS coverage: real Windows 11 arm64 host for
    the native lane, JavaScript analysis and JADX, and (4205b52) Ghidra P0
    through the CLI and stdio MCP. Hopper was not exercised.
  • Package or release metadata impact: none in this diff (open question 2).
  • Security, privacy, process, or containment review: admission stays
    fail-closed. An arm64 host loads only an artifact whose manifest
    architecture, artifact name, SHA-256, PE machine, and self-inspected
    architecture all match. No environment override was added.

Author readiness

Human owner: @chanasia

  • 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.

🔄 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/3602 **Author:** [@chanasia](https://github.com/chanasia) **Created:** 10/14/2026 **Status:** 🔄 Open **Base:** `main` ← **Head:** `feat/windows-arm64-native-controls` --- ### 📝 Commits (10+) - [`bef00b0`](https://github.com/morluto/rea/commit/bef00b02726b4b9276d1f1d808e788ca3fe8ee72) feat(windows): admit arm64 hosts for the bundled native controls - [`0c4744b`](https://github.com/morluto/rea/commit/0c4744b24f57cdc1ddc600e06d3ee0f9ebca85c8) test(windows): pin each manifest target check independently - [`65e3cc6`](https://github.com/morluto/rea/commit/65e3cc688a1638ebe0d04f919d7f4aaedac742a1) feat(android): admit Windows arm64 hosts for JADX subprocess ownership - [`b6c3cd2`](https://github.com/morluto/rea/commit/b6c3cd269c51b3d51d4d9e4c8a20e7e3bee0e5b1) Merge remote-tracking branch 'origin/main' into sweep/3602 - [`a0a0c66`](https://github.com/morluto/rea/commit/a0a0c66e40902f9a46959e548c72123fb1111683) fix(windows): align doctor and remediation text with arm64 admission - [`4205b52`](https://github.com/morluto/rea/commit/4205b52b7774459f679459161fbfc4107a8eec00) feat(ghidra): admit Windows arm64 hosts with win_arm_64 native tools - [`1171423`](https://github.com/morluto/rea/commit/11714233c89be52da28770b62a57f0bba1ff274d) Merge remote-tracking branch 'origin/main' into feat/windows-arm64-native-controls - [`6fc7034`](https://github.com/morluto/rea/commit/6fc7034882fd41e2eaa0cf47b1b3d71037e44b7a) Merge remote-tracking branch 'origin/main' into feat/windows-arm64-native-controls - [`eb38ddd`](https://github.com/morluto/rea/commit/eb38ddd39bbd25d9e8cc2460b1f7c09ddf57c3aa) Merge remote-tracking branch 'origin/main' into feat/windows-arm64-native-controls - [`943a542`](https://github.com/morluto/rea/commit/943a542d2fd4509eca475962819312ac80c9907e) Merge remote-tracking branch 'origin/main' into feat/windows-arm64-native-controls ### 📊 Changes **19 files changed** (+270 additions, -115 deletions) <details> <summary>View changed files</summary> 📝 `docs/installation.md` (+4 -3) 📝 `native/windows/src/process.cc` (+4 -0) 📝 `src/android/JadxConfiguration.ts` (+6 -3) 📝 `src/android/JadxRelease.ts` (+2 -2) 📝 `src/application/Doctor.test.ts` (+23 -29) 📝 `src/application/DoctorDiagnostics.ts` (+3 -2) 📝 `src/domain/windowsNativeArtifact.ts` (+38 -23) 📝 `src/ghidra/GhidraDoctor.test.ts` (+9 -2) 📝 `src/ghidra/GhidraInstallation.test.ts` (+41 -0) 📝 `src/ghidra/GhidraInstallation.ts` (+3 -3) 📝 `src/ghidra/GhidraProvider.behavior.test.ts` (+2 -2) 📝 `src/ghidra/GhidraProviderCapabilities.ts` (+3 -3) 📝 `src/process/WindowsAuthority.ts` (+5 -4) 📝 `src/windows/WindowsNativeLoader.test.ts` (+67 -7) 📝 `src/windows/WindowsNativeLoader.ts` (+48 -24) 📝 `src/windows/WindowsOwnedProcess.ts` (+2 -2) 📝 `tests/boundary/android/jadxDoctor.test.ts` (+1 -1) 📝 `tests/fixtures/windowsNativeArtifact.ts` (+8 -4) 📝 `tests/process-global/windowsNativeControlCapability.test.ts` (+1 -1) </details> ### 📄 Description ## Summary On Windows on Arm with native arm64 Node.js, every operation that needs the bundled Windows native controls fails at host admission. JavaScript/Electron static analysis is one example: ``` $ npx -y rea-agents@6.5.0 analyze-javascript-application <Discord 1.0.9258>/resources/app.asar --json code: capability_unavailable reason: REA Windows native controls require a Windows x64 host. ``` This PR makes the loader admit an arm64 build of the same addon, with the same identity checks as x64. On a real arm64 host, the existing native conformance lane passes and the analysis above completes. The PR also opens the JADX host gate on arm64. JADX uses these controls to own its Java subprocess. On arm64 it failed at `requireSupportedHost` with `unsupported_host`, even with a JDK and the JADX jar configured, because the gate admitted only `win32`/`x64`. arm64 now goes through the same checks as x64: the native authority must load and report owned protocol stdin, or the gate fails closed as before. On the same arm64 host, Android package inspection, class search and method decompilation through MCP complete. The last commit (4205b52) extends the arm64 admission to Windows Ghidra P0. Ghidra 12.1 already maps an arm64 JVM to `Ghidra/Features/Decompiler/os/win_arm_64` and its Gradle native build targets that platform, but the release archive ships no `win_arm_64` natives, and REA's installation check knew only `win32`/`x64`, so an arm64 host was rejected with `unsupported_host` before Ghidra started. REA now maps `win32`/`arm64` to `win_arm_64`. The existing executable-header admission and the JDK `os.arch` cross-check still apply, so an x64 decompiler or an emulated x64 JDK is still reported as incompatible. REA still does not build or install native tools. This PR does not yet build or package an arm64 artifact. See **Open questions**. No issue is linked; this PR carries the proposal and the questions it needs answered. ## Problem and expected behavior - **Before:** `loadWindowsNativeAuthority` admits only `win32`/`x64`. The manifest, inspection schema and PE check accept only x64. `process.cc` reports a hardcoded `"x64"`. - **After:** the shared native artifact contract (`src/domain/windowsNativeArtifact.ts`, introduced on `main` in 3d565fa) owns one table mapping each admitted architecture (`x64`, `arm64`) to its artifact name (`rea-windows-<arch>.node`) and PE machine (`0x8664`, `0xAA64`). The loader passes the host architecture to it. The checks are: - the manifest's `architecture` and `artifact` must match the host before the artifact is read; - the existing SHA-256 and PE32+ checks use the host's machine; - the native self-inspection must report the host architecture. - **x64:** behavior is unchanged. ## Change and scope - `native/windows/src/process.cc`: report `architecture` from `_M_ARM64`/`__aarch64__`. The existing `"x64"` stays in `#else`. This was the only architecture-specific line in the native sources. - `src/domain/windowsNativeArtifact.ts` (18e08f1, 195e814): `WINDOWS_NATIVE_TARGETS` maps `x64`/`arm64` to the artifact name and PE machine. `parseWindowsNativeManifest` takes the host architecture as an optional third argument. Its default is `WINDOWS_NATIVE_ARTIFACT.architecture` (`x64`), so the build and verify scripts keep their x64 contract unchanged. `validateWindowsNativeArtifact` checks the PE machine of the manifest's architecture, inside `main`'s declared optional-header checks (a486cfe). `WINDOWS_NATIVE_ARTIFACT` and `createWindowsNativeManifest` stay x64. - `src/windows/WindowsNativeLoader.ts`: host admission, passing the host architecture to the shared contract, the inspection schema and its architecture cross-check, and `readArtifact`/`loadArtifact` taking the selected artifact name. - `src/android/JadxConfiguration.ts`: `requireSupportedHost` admits `win32`/`arm64` as well as `win32`/`x64`, through the same path: `systemWindowsNativeAuthority()` must load and its inspection must report `protocolStdin: true`. Anything else still throws. The two remediation messages in this file no longer say x64 only. - `src/windows/WindowsNativeLoader.test.ts`: new tests: - arm64 admission; - a manifest declaring another target rejected before the artifact is read or loaded, with separate cases for architecture only, artifact only, and both (the reason now comes from the shared contract: "has an invalid architecture" or "has an invalid artifact"); - a cross-architecture inspection rejected. The previous `arm64 → host` rejection case now uses `ia32`. - `tests/fixtures/windowsNativeArtifact.ts` (abfa130): `main`'s shared PE fixture takes an optional architecture (default `x64`), so the arm64 loader cases reuse it. Its other callers keep x64. - `src/application/DoctorDiagnostics.ts` (a0a0c66): the informational `host` check admits `win32`/`arm64` as well as `win32`/`x64` and still rejects other Windows architectures. Without this, `rea doctor` called the same host unsupported that the loader and the JADX gate admit. - Remediation (a0a0c66): `WindowsAuthority.ts`, `WindowsOwnedProcess.ts` and `JadxRelease.ts` name the package whose bundled native artifact matches the host architecture instead of "Windows x64". The artifact-stage message is the first one an arm64 user with today's x64-only package hits. The Ghidra-specific strings were left for the Ghidra commit below. - Ghidra (4205b52): - `src/ghidra/GhidraInstallation.ts`: `NATIVE_PLATFORMS` maps `win32`/`arm64` to `win_arm_64`; the two host remediation strings name Windows arm64. - `src/ghidra/GhidraProviderCapabilities.ts`: the Windows P0 limitation says the matching native addon may be x64 or arm64. - `docs/installation.md`: Windows x64/arm64 P0, and `win_arm_64` beside `linux_arm_64` as a native directory that release archives may lack. Intentionally not included. These stay x64-only, fail-closed, until each is verified: - Bun - the release build lane, package `files`, `verify-windows-native-artifact.mjs`, `verify-windows-package.mjs` and CI (the build and verify scripts call the shared contract with its x64 default) ### Open questions 1. **Build lane:** - **Option A:** extend the Linux cross-build with llvm-mingw (`aarch64-w64-mingw32-clang++`, `llvm-dlltool -m arm64`). The GNU MinGW-w64 aarch64 target is not mature yet. - **Option B:** build with MSVC on a `windows-11-arm` runner. The prototype used this toolchain (details below). 2. **Packaging:** ship both artifacts in `rea-agents` with per-architecture manifests, or use per-architecture optional packages. This PR keeps one `manifest.json` describing whichever artifact was built. 3. **CI:** run `verify:windows-native` on `windows-11-arm` alongside the x64 lane. 4. ~~**Remediation text**~~: resolved in a0a0c66 (see **Change and scope**), following review feedback. Q1–Q3 do not affect whether this PR is safe to merge: x64 is unchanged, and arm64 hosts with today's x64-only package fail at the artifact stage with a clearer message. They block shipping arm64 to users. Q1 (build lane) comes first; Q2 (packaging) and Q3 (CI) follow from it. ## Contract and boundary impact - Semantic owner and earliest changed stage: `WindowsNativeLoader` host admission decides the host architecture once. The shared contract in `src/domain/windowsNativeArtifact.ts` binds the manifest and PE machine to it, and consumers use the loader's result. - Contribution scope fit and linked maintainer decision: existing native controls, extended to a new host architecture. No new provider or capability. Pending maintainer decision on the open questions. - CLI and MCP/tool-catalog contract: none changed. - Provider, bridge, target-format, or platform compatibility: - x64 hosts are unchanged. - On arm64 hosts running the current x64-only package, the failure moves from the `host` stage (`unsupported_host`) to the `artifact` stage (`runtime_missing`), with the reason "REA Windows native controls are unavailable: Windows native artifact manifest has an invalid architecture" (observed on this host after 18e08f1; see **Validation performed**). The reason no longer names the required artifact; the `artifact`-stage remediation in `WindowsAuthority.ts` names `rea-windows-arm64.node`. - On arm64 hosts with the arm64 artifact, JADX operations no longer stop at `unsupported_host`. - `rea doctor` reports a `win32 arm64` host as supported in its informational `host` check. - Windows Ghidra P0 on an arm64 host with a `win_arm_64` decompiler and an aarch64 JDK is admitted instead of failing at `unsupported_host`. An arm64 host whose Ghidra has only `win_x86_64` natives still fails, now at `native_decompiler` ("Matching native decompiler for win32/arm64 was not found"). This is source-derived; it was not run with x64-only natives. - Evidence, artifact, provenance, or reconstruction contract: none. - Target selection, authority, upstream behavior, and cleanup details: unchanged. The same Job Object, DACL and cleanup controls are admitted on arm64 only after the native inspection proves them. - Generated metadata, package, or installation impact: none in this diff. Packaging is open question 2. Expected effects. These are the existing native controls, now admitted on arm64 hosts; nothing new is introduced: - [x] Read existing files or captured data. - [x] Launch or attach to a process. - [x] Change process memory, registers, files, or configuration. (Private runtime directories and owned helper processes only; target processes and memory are untouched.) - [ ] Inject instrumentation or run scripts/code. - [ ] 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:** - `src/windows/WindowsNativeLoader.test.ts` (above); - `src/application/Doctor.test.ts`: the host check is now an `it.each` over `x64` (supported), `arm64` (supported) and `ia32` (unsupported); - `src/ghidra/GhidraDoctor.test.ts` and `tests/boundary/android/jadxDoctor.test.ts`: remediation assertions follow the new wording. - `tests/fixtures/windowsNativeArtifact.ts`: the shared PE fixture takes the architecture (above); - `src/ghidra/GhidraInstallation.test.ts`: a Windows arm64 installation with a `win_arm_64` decompiler and an `aarch64` JDK is admitted; `src/ghidra/GhidraProvider.behavior.test.ts` follows the capability wording. - **Base reproduction:** the `rea-agents@6.5.0` failure in **Summary**, on the host below. - **User-visible CLI output:** `analyze-javascript-application` on the same `app.asar` with this branch completes in about 51 s cold. Statistics: `relevant_files 5`, `parsed_javascript_files 2`, `modules 972`, `visited_ast_nodes 503068`, `parse_failures 0`; graph 1,132 nodes / 4,187 edges. - **JADX through MCP:** on a third-party release APK (22,088 classes, 995 resources), with Temurin JDK 21.0.12 and `jadx-headless-mcp` 0.7.1: - `inspect_android_package` returned the package summary; - `search_android_classes` found the main activity; - `inspect_android_method` decompiled its `onCreate` to Java (`fell_back: false`). - **Remaining proof gaps:** - no unit test covers the JADX gate change itself - the MinGW x64 lane after the `process.cc` change (no MinGW on this host; CI covers it) - an x64 child under emulation inside an arm64-owned Job Object - multi-processor-group hosts - a packed tarball and `verify-windows-package.mjs` - CLI/MCP from a packed install - Bun - Ghidra on an x64 Windows host after 4205b52 (the change only adds a map entry and strings; the x64 test still passes) - Ghidra with official `win_arm_64` natives: the 12.1.4 release has none, so validation used natives built locally (details below) - the native lane, JADX and Ghidra end-to-end after 18e08f1 and the later `main` merges (only the loader path was re-run on the real artifact) Evidence-bearing checks: - [x] Observed, derived, and inferred claims remain distinguishable. - [x] Artifact identity, source provenance, and failed attempts remain preserved. - [x] Unsupported, incomplete, unavailable, or uncertain outcomes remain visible. ## Validation performed Host: Windows 11 Pro 10.0.26200 arm64, Snapdragon X Elite X1E78100 (12 logical processors, one processor group), NTFS, Node.js 24.18.0 arm64. The token was non-elevated, medium integrity (`integrityLevel 8192`). Base b8510ee. - `npx vitest run src/windows/WindowsNativeLoader.test.ts` — 25 passed. Removing either manifest equality check (architecture or artifact) fails one test each, checked by temporarily editing the guard out. - `npm run check:fast` — passed (typecheck, lint). - `npm run docs:check` — passed. - `npx vitest run src/windows src/process src/application/Doctor` — 326 passed, 2 failed, 21 skipped. Unmodified b8510ee on this host gives 323 passed and the same 2 failures, so they are unrelated to this change: - `ProcessScenarioRuntimeValidation` "preserves the caller-selected executable symlink" - `Doctor` "checks the canonical user install after the system launcher" - `npm run build:cached` — passed. - `systemWindowsNativeAuthority()` with the arm64 artifact — `available: true`, `architecture: "arm64"`. `privateDacl`, `privateBridgeDescriptorAccess`, `atomicJobAssignment`, `killOnOwnerClose`, `protocolStdin` and `jobMemoryLimit` are all `true`. - `node scripts/verify-windows-native.mjs . <arm64 process-boundary.exe>` — `ok: true`: - all 20 `controls`; - `processes` checks, including `breakawayDenied`, `childOwnerNormalizedWithoutChangingCaller`, `windowsEnvironmentSemantics`, `callerAffinityBoundsOwnedProcessOrRefusesToWiden`, `ownerForcedExitKillsOwnedChild`, protocol input and `jobMemoryLimit` (128 MiB limit; reached exit 1 with peak 140,668,928 bytes; control exit 0). - `node scripts/rea.mjs analyze-javascript-application <app.asar> --json` — completed (above). - Pre-commit hooks (oxfmt, oxlint) — passed. JADX commit (65e3cc6, on top of 0c4744b): - `npm run compile` — passed. - `npx vitest run tests/boundary/android/JadxAnalysis.test.ts` — 14 passed. - `inspectJadxAvailability()` from the rebuilt `dist` — `status: "available"`, with the JDK compiler and the JADX jar found. - The MCP calls above, against a server restarted on the rebuilt `dist`. - Pre-commit hooks (oxfmt, oxlint) — passed. After merging `main` (b6c3cd2) and the doctor/remediation commit (a0a0c66). `main` changed `process.cc` and the boundary fixture, so both were rebuilt for arm64 first: - `npx vitest run src/application/Doctor.test.ts src/ghidra/GhidraDoctor.test.ts tests/boundary/android/jadxDoctor.test.ts tests/boundary/android/jadxConfiguration.test.ts src/windows src/process tests/conformance/providers/ghidra/windowsCapabilities.test.ts` — 359 passed, 2 failed, 50 skipped. The 2 failures are the same two as above. They also fail on b6c3cd2 without a0a0c66 on this host. - `npm run check:fast` — passed. `npm run docs:check` — passed. `npm run build:cached` — passed. - `node scripts/verify-windows-native.mjs . <arm64 process-boundary.exe>` — `ok: true`, 66 leaf checks. The only `false` values are `callerToken.elevated` and `callerToken.administrator` (non-elevated token). - `node scripts/rea.mjs doctor --json` — `host` check `ok: true`, `detail: "win32 arm64"`. - `analyze-javascript-application` on the same `app.asar` — `modules 972`, `parse_failures 0`, graph 1,132 nodes / 4,187 edges (unchanged). Ghidra commit (4205b52, on top of a0a0c66), same host. Ghidra 12.1.4 (release archive, SHA-256 checked), Microsoft Build of OpenJDK 21.0.12 aarch64, and `win_arm_64` natives built locally (details below): - `npx vitest run src/ghidra` — 544 passed, 14 failed, 7 skipped. The same 14 fail on a0a0c66 without this commit on this host (`GhidraAnalysisSeeds` symlink commitment, `GhidraLanguageOverride` ×5, `GhidraPowerPcProfile` ×1, `GhidraSnapshotCache` relationship/replay ×7). - `npm run check:fast` — passed. `npm run docs:check` — passed. `npm run build:cached` — passed. Pre-commit hooks (oxfmt, oxlint) — passed. - `node scripts/rea.mjs doctor --provider ghidra --json` — every Ghidra check `ok: true`: `platform win32`, `architecture arm64`, `java` (21.0.12.1, 64-bit JDK), `native_decompiler` (".../os/win_arm_64/decompile.exe reports pe arm64, which matches win32/arm64") and `native_authority`. - `rea decompile <3 MB x64 PE> entry --provider ghidra` — returned the C pseudo-code of `entry` (83 s cold, including analysis). - Stdio MCP (`rea mcp`, one session): `open_binary` on a 47.8 MB x64 PE, then `xrefs`, `resolve_containing_procedure` and `procedure_pseudo_code` on the functions found. The first analysis-backed call returned after 15 min 42 s; later calls in the session returned in seconds. - With the default 330 s startup deadline, the same 47.8 MB import did not finish (`provider_timeout`, "Ghidra startup deadline elapsed"); `REA_GHIDRA_STARTUP_TIMEOUT_MS=3600000` was set for the runs above. The default is unchanged by this PR. After merging `main` (9c9c64e) and moving the arm64 binding into the shared contract (18e08f1). `main` now requires Node.js ^24.22.1, so these runs used Node.js 24.22.1 arm64: - `npm run typecheck` — passed. Pre-push `check:fast` — passed. - `npx vitest run src/domain/windowsNativeArtifact.test.ts src/windows src/process/WindowsAuthority src/ghidra src/application/Doctor.test.ts tests/conformance/formats/mzPeAdmission.test.ts tests/conformance/providers/ghidra tests/process-global/windowsNativeControlCapability.test.ts tests/boundary/android/jadxDoctor.test.ts` — 1119 passed, 6 failed, 44 skipped. Five failures (`GhidraDolProfile` ×4, `GhidraMipsProfile` ×1) fail the same way on unmodified 9c9c64e on this host. The sixth is the `GhidraAnalysisSeeds` symlink commitment listed above (`EPERM` creating a symlink). - `loadWindowsNativeAuthority` from source with the arm64 artifact built for the earlier validation. Its manifest says 6.5.0, so the host's `packageVersion` was set to match. Result: `available: true`, `architecture: "arm64"`, with `privateDacl`, `privateBridgeDescriptorAccess`, `atomicJobAssignment`, `killOnOwnerClose`, `protocolStdin` and `jobMemoryLimit` all `true`. - The same arm64 host with an x64 manifest — `failureStage: "artifact"`, reason "Windows native artifact manifest has an invalid architecture". - Not repeated after this merge: an arm64 artifact rebuilt from the current sources, `verify-windows-native.mjs`, `windowsNativeArtifactVerifier.test.ts` (needs `dist`), `docs:check`, `build:cached`, and the JADX and Ghidra end-to-end runs. After merging `main` (365fb03), whose a486cfe validates the declared PE optional header, and keeping the arm64 machine check inside that validation (195e814), same host and Node.js: - Pre-push `check:fast` — passed. - The focused `vitest` command above — 1160 passed, 6 failed, 47 skipped. The 6 failures are the same six as above. - The loader from source with the same arm64 artifact — `available: true`, `architecture: "arm64"`, all controls `true`. The same host with an x64 manifest — "Windows native artifact manifest has an invalid architecture". After merging `main` (bcc6775), whose 740c0f5 moved the loader's PE bytes into `tests/fixtures/windowsNativeArtifact.ts`, and binding that fixture to the requested architecture (abfa130), same host and Node.js: - Pre-push `check:fast` — passed. - `npx vitest run src/application/Doctor.test.ts tests/boundary/android/jadxDoctor.test.ts src/ghidra/GhidraDoctor.test.ts src/ghidra/GhidraInstallation.test.ts src/ghidra/GhidraProvider.behavior.test.ts src/android src/windows src/domain/windowsNativeArtifact.test.ts` — 485 passed, 31 skipped. - `npx vitest run src/windows src/domain/windowsNativeArtifact.test.ts src/process tests/process-global/windowsNativeControlCapability.test.ts` — 880 passed, 9 failed, 67 skipped. The 9 (`LinuxCgroupMemory` ×2, `OwnedWorkerRuntime` ×7) fail the same way on unmodified bcc6775 on this host. - `npx vitest run tests/conformance/readmeConsistency.test.ts tests/boundary/process/windowsNativeArtifactVerifier.test.ts` — 11 passed. - `node scripts/run-turbo.mjs run docs:check:built` — passed. `npm run docs:check` itself stops in its `run-exclusive.mjs` wrapper with "REA Windows native controls are unavailable: Windows native artifact belongs to another REA version": the local arm64 artifact was built for 6.5.0 and the package is now 6.8.0. - The loader from source with the same arm64 artifact — same two results as above. - Not repeated: an arm64 artifact rebuilt from the current sources, `verify-windows-native.mjs`, `build:cached`, and the JADX and Ghidra end-to-end runs. <details> <summary>How the arm64 artifact was built for this validation (outside the repository lane)</summary> MSVC 14.51 (Visual Studio 2026) `Hostarm64/arm64`, under `vcvarsall.bat arm64`. Node 22.19.0 headers were checked against `SHASUMS256.txt`. `node-api.def` was generated the same way as `build-windows-native.mjs`. ```bat lib /nologo /def:node-api.def /machine:arm64 /out:node-api.lib cl /nologo /std:c++17 /O2 /EHsc /MT /W3 /DNAPI_VERSION=8 /D_WIN32_WINNT=0x0A00 ^ /I<node-v22.19.0>\include\node ^ native\windows\src\addon.cc native\windows\src\filesystem.cc native\windows\src\process.cc ^ /LD /Fe:native\windows\build\rea-windows-arm64.node ^ /link /Brepro /DELAYLOAD:node.exe node-api.lib delayimp.lib advapi32.lib bcrypt.lib ntdll.lib cl /nologo /std:c++17 /O2 /EHsc /MT tests\fixtures\windows\processBoundary.cc ^ /Fe:process-boundary.exe /link advapi32.lib ``` The existing `addon.cc` delay-load hook works unchanged with MSVC. The `manifest.json` used `architecture: "arm64"` and `artifact: "rea-windows-arm64.node"`. MSVC reports C4267/C4244 `size_t` narrowing warnings; they are not arm64-specific (x64 `size_t` is 64-bit too). </details> <details> <summary>How the win_arm_64 Ghidra natives were built for this validation (outside the repository)</summary> Ghidra 12.1.4 sources (tag `Ghidra_12.1.4_build`), MSVC 14.51 `Hostarm64/arm64` under `vcvarsall.bat arm64`. Source lists, defines and flags follow the VisualCpp branch of `Ghidra/Features/Decompiler/buildNatives.gradle`, whose model already lists `win_arm_64`: ```bat cl /c /MP /EHsc /W3 /O2 /Oy /GL /D_SECURE_SCL=0 /D_HAS_ITERATOR_DEBUGGING=0 ^ /DWINDOWS /D_WINDOWS /DWIN32 /D_WIN32 <decompile .cc sources> link /LTCG /OUT:decompile.exe *.obj rem sleigh.exe: the sleigh .cc list with /DLOCAL_ZLIB, plus zlib *.c with /DNO_GZIP ``` Both outputs are PE32+ machine `0xAA64` and were placed in `Ghidra/Features/Decompiler/os/win_arm_64/`. Gradle's `win_arm_64` branch does not define `WIN64`/`_WIN64` (only `win_x86_64` does); the sources do not use `WIN64`, and MSVC predefines `_WIN64` for ARM64. </details> ## Compatibility, safety, and release - Breaking changes or migration steps: none. `WindowsNativeLoadHost` `readArtifact`/`loadArtifact` now receive the selected artifact name. The interface is internal, and the only production host is `systemWindowsNativeAuthority`. `parseWindowsNativeManifest` gains an optional architecture argument; existing callers keep x64. - Real Hopper/Ghidra, browser, or OS coverage: real Windows 11 arm64 host for the native lane, JavaScript analysis and JADX, and (4205b52) Ghidra P0 through the CLI and stdio MCP. Hopper was not exercised. - Package or release metadata impact: none in this diff (open question 2). - Security, privacy, process, or containment review: admission stays fail-closed. An arm64 host loads only an artifact whose manifest architecture, artifact name, SHA-256, PE machine, and self-inspected architecture all match. No environment override was added. ## Author readiness Human owner: @chanasia - [x] 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. - [x] I checked the evidence above, confirmed it supports the current change, and recorded meaningful validation gaps. - [x] 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. --- <sub>🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.</sub>
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#5849
No description provided.