8 Commits
Author SHA1 Message Date
Hermes Agent ffaff66505 deps: REA 6.8.0 (+ Node 24.22.1), and the admissions that moved with it
Upstream: https://github.com/morluto/rea/releases/tag/rea-agents-6.8.0
Check:    make check-updates  ->  0 actionable / 6 pending / 0 unknown
Harness:  scripts/verify-all-engines.sh  121/0/3 · 109/0/8 · 102/0/7 · 94/0/11

REA 6.8.0 changes two things this image has to follow:

- engines.node is now ^22.23.4 || ^24.22.1 || >=26.12.1, so the 24.22.0
  runtime that 6.7.0 accepted is *refused*. NODE_VERSION moves to 24.22.1
  in the same commit, in the Dockerfile and in the compose default.
- the bundled skill is v49 with 229 MCP tools (was v42 / 207), read from the
  shipped dist/mcp-catalog.json rather than the release notes.

No engine admission moved: GhidraReleasePolicy.ts is byte-identical
(12.1.4, Java 21) and Hopper is still the vendor feed's 6.6.0 demo, so the
engine pins are untouched and the harness re-proved both providers.

Two checks had to change shape, and both got stricter:

- binwalk/unblob left CapabilityInventory's remediation prose for structured
  defineToolRequirement() entries in
  src/contracts/firmware/firmwareToolRequirements.ts. scrape_rea now reads
  those first and falls back to the prose, so both rows keep showing the
  admitted value instead of printing `ok` with nothing verified.
- extract-artifact lost its second positional (REA picks the destination and
  reports output_root). The harness now asserts containment_verified,
  coverage complete, cleanup verified, non-empty created artifacts, and that
  the reported files exist under the reported root - one check more per
  image than the exit-status check it replaces.

Docs regenerated for this run: docs/verify-engines.txt,
docs/verify-summary.txt, the size table (make sizes), and the skill/tool
counts in README, HERMES-MCP, IMAGES, ARCHITECTURE and UPDATES.
2026-10-25 10:02:32 +00:00
Hermes Agent 9d78e670b4 deps: REA 6.7.0, and Hopper admission through the vendor's signed feed
morluto/rea rea-agents-6.7.0 is the current npm release (the pin was 6.5.0).
This is not only a version string: REA 6.6.0 replaced Hopper's fixed
launcher-digest allowlist (SUPPORTED_RELEASES / SUPPORTED_HOPPER_SHA256) with the
vendor's publisher-signed release feed, whose only Linux entry is the *current*
demo. The pinned Hopper 6.4.2 build is refused outright by 6.6.0+, so the admitted
build is now Hopper 6.6.0 (launcher b2271008...).

Dockerfile:
  * REA_VERSION 6.5.0 -> 6.7.0; frida 17.23.3 -> 17.24.1
  * the Hopper layer reads the vendor feed and fails when it no longer matches the
    pins (HOPPER_DEMO_VERSION / _SHA1 / _BYTES / _LAUNCHER_SHA256), verifies the
    downloaded package (byte length + SHA-1) and the installed launcher digest,
    and retains the signed evidence (feed row + vendor public key + package bytes)
    under REA's own cache path, so the launcher is admitted without network access
  * records the admitted digest at /usr/local/share/rea/hopper-launcher.sha256
    for the harness to assert against
checker (scripts/check-updates.py):
  * Ghidra admission source was renamed (GhidraInstallationPolicy.ts ->
    GhidraReleasePolicy.ts in the 6.6.x line) - repointed
  * Hopper admission is read from the vendor feed rather than REA's source, which
    no longer carries either table. Both engine rows had silently stopped
    verifying; they verify again rather than merely reporting ok
harness:
  * the Hopper launcher-digest check asserts the digest this build admits and
    skips with a reason for a vendor/licensed package, which REA admits by its own
    publisher evidence instead
compose / env / docs:
  * 6.7.0 tag suffix everywhere, Hopper moved to 6.6.0, refreshed size table
    (Hopper's delta grew ~92 MB -> ~128 MB: the retained signed evidence
    duplicates the installed .deb), UPDATES/VERIFICATION/BYO-LICENSES/TROUBLESHOOTING
    rewritten for the feed gate, Kuna recorded as an accepted gap (caller-supplied
    provider, like IDA), and a stale NODE_VERSION default in compose corrected

Checks run:
  * make check-updates -> 34 rows: 0 actionable, 0 unverifiable, exit 0
  * scripts/verify-all-engines.sh (all four images, full harness) -> 0 failures,
    exit 0 on every image: all 120/0/3, ghidra 108/0/8, hopper 101/0/7,
    ida 93/0/11. Report: docs/verify-engines.txt (runs 20261019T014730Z,
    ...T015922Z, ...T021101Z, ...T021249Z), summary: docs/verify-summary.txt
  * the four images were built locally as ghcr.io/alexmi256/rea-agent[-ghidra|
    -hopper|-ida]:6.7.0-linux-amd64 and the in-image harness confirms REA reports
    hopper launcher-sha256:b2271008... in every Hopper analysis profile

Upstream: https://github.com/morluto/rea/releases/tag/rea-agents-6.7.0
2026-10-19 02:16:12 +00:00
Hermes Agent 02f9c3adaa add a version-drift checker and the update procedure
scripts/check-updates.py answers 'is this repo behind?' in ~5s, and encodes the
distinction that actually matters here: REA validates engines and helper tools by
digest or version banner, so upstream 'latest' is frequently the WRONG target.
The checker compares every pin against two references - the newest thing upstream
ships, and what the pinned REA release ADMITS - and reads those admissions live
from morluto/rea@rea-agents-<REA_VERSION> (GhidraInstallationPolicy,
LinuxHopper SUPPORTED_RELEASES/HOPPER_SHA256, CapabilityInventory remediation
strings, runtimeVersion). Bumping REA therefore re-derives the expectations
instead of relying on documentation memory.

33 rows: rea + Node (checked against REA's engines range), engines, every
REA-located helper tool, our own unpinned tools, the base image and the action
majors. Statuses separate the two failure modes - behind-REA (a breakage: REA
refuses the banner) from outdated (optional: upstream newer, not admitted) - and
'docker compose pull'-style checks are not confused with engine validation.
Modes: table, --quiet, --json, --markdown; exit 1 when actionable; --only/--skip
by key or group. Every row carries the URL it came from, and a failed lookup is
reported as unknown-with-reason, never as up to date.

Findings on day one: 6 actionable (Node 24.21->24.22, unicorn, uv, frida,
supergateway patches; Wakaru MISSING - REA 6.5.0 admits ^1.13.0 for
recover_javascript_sources and we do not install it), plus apktool 3.x and
ilspycmd 11.x as explicitly optional (REA's apktool requirement is a floor of
2.7.0, and REA only needs a runnable ilspycmd).

Wiring: make check-updates / check-updates-json; a weekly 'updates' workflow
(Mondays 06:17 UTC + dispatch) that needs no Docker or package permissions, puts
the report in the run summary, uploads the JSON, and fails when something is
actionable; validate now compiles the script, proves --help works offline and
requires scripts/*.py to be executable.

docs/UPDATES.md is the procedure: which reference governs which component, the
general loop, per-engine procedures (Ghidra's exact build, Hopper's digest gate),
the helper-tool table with locator variables and install method, the release
string that must agree across five files, how to add a tool REA advertises but we
do not ship (worked example: Wakaru), accepted gaps, how to extend the checker,
and the traps worth remembering.
2026-10-15 20:30:28 +00:00
Hermes Agent e23e8bbcc8 build: bump rea-agents to 6.5.0
Upstream published rea-agents 6.5.0 (npm `latest` and the GitHub release
`rea-agents-6.5.0`, 2026-10-14), one minor ahead of the 6.4.0 this repo pinned.

Only REA changed. Every other pin was re-checked against what 6.5.0 itself
declares, and all already matched:

* Node 24.21.0 — 6.5.0 engines are ^22.19.0 || ^24.11.0 || >=26.0.0, and its
  SQLite inspector needs 24.x >= 24.15.
* frida 17.23.2 — 6.5.0 lists it as `optionalDependencies`, installed with
  `--allow-scripts=frida` and symlinked into the package, as before.
* Ghidra 12.1.4, Hopper 6.4.2 (the Linux build 6.5.0 still admits, digest-
  checked), WABT 1.0.42, sigrok-cli 0.7.2 + libsigrokdecode, TShark 4.x,
  mitmproxy 12.2.3, Apktool 2.12.x, jadx-headless-mcp 0.7.1, unblob 26.6.4.

The image's bundled workflow skill moves with the package: v37 -> v42, and the
MCP catalog 170 -> 207 tools (153 CLI commands). Docs that quoted those numbers
are updated, and the stale "this family is on repository main, not in the
release" notes are rewritten — 6.5.0 *is* the release that ships those families.

Harness: 6.5.0 exposes command families that 6.4.0 left on main (frida, sqlite,
wasm, go, pcap, signal), so `check_rea` now runs them for real instead of
skipping — the `all` image went from 14 skips to 3. That exposed one latent
harness defect: `sigrok decoder inventory` asserted `uart` appeared in the
decoder catalog's *default* page, but the catalog is sorted and paginated
(50 of 111), so `uart` sorts past it. The command was fine; the check now
searches with `inspect-signal-decoders --query uart`.

Also newly green on this bump: RISC-V64 and PowerPC ELF searches, which 6.4.0
refused with `unsupported ELF architecture`.

Verification (full harness, one run per image, twice — the second pass after the
sigrok fix confirmed the same counts and populated `image:` in the summaries):

  all     107 passed / 0 failed / 3 skipped   exit 0
  ghidra   95 passed / 0 failed / 8 skipped   exit 0
  hopper   88 passed / 0 failed / 7 skipped   exit 0
  ida      80 passed / 0 failed / 11 skipped  exit 0

Records regenerated in docs/verify-engines.txt and docs/verify-summary.txt
(platform line redacted as before).

scripts/verify.sh, scripts/build.sh and CI now pass REA_IMAGE_ID to the harness,
so the summary names the image it verified instead of reporting "unknown" (the
harness's own fallback, /etc/rea/image-id, is hidden by the ./config bind mount).
2026-10-14 21:27:20 +00:00
Hermes Agent e6a1d1d1b9 publish the four engine images to GHCR on push, and document pulling them
Registry:
- The build job now runs on push to main (and dispatch), not just dispatch, and
  publishes each engine image to ghcr.io/<owner>/rea-agent[-ghidra|-hopper|-ida]
  under both <REA_VERSION>-linux-amd64 and latest. PRs skip it (a fork token
  cannot push packages). Publishing happens after the harness and the foreign-uid
  check pass, so a broken image never reaches the registry.
- The published tag is derived from the Dockerfile's REA_VERSION (no drift), and
  the OCI label org.opencontainers.image.source is set from the repo URL - that
  label is what links the package to the repository and lets it inherit the
  repo's (public) visibility. It is baked last so adding labels never invalidates
  the cached engine layers.
- docker/login-action@v4 (v3 is node20 - same deprecation trap as the others).

One source of truth for image names:
- New scripts/image-name.sh resolves an engine to its image, honouring
  REA_IMAGE / REA_GHIDRA_IMAGE / REA_HOPPER_IMAGE / REA_IDA_IMAGE from .env and
  falling back to a plain local name. build.sh, verify.sh (new --engine flag),
  verify-all-engines.sh and the Makefile all use it, so what you build, verify
  and pull are never different names. Previously a local build tagged
  rea-agent-ghidra while compose asked for the GHCR name.
- compose and .env.example now default to the GHCR coordinates, so
   works with no build at all; rebuilding from source
  replaces the same name instead of creating a second one.
- Makefile: pull / pull-all / sizes work on pulled or built images alike.

Docs: README quick start split into pull vs build; docs/IMAGES.md gains the GHCR
table, air-gapped transfer, per-fork publishing steps and the permissions note;
TROUBLESHOOTING covers pull failures and resolver mismatches.

CI validate now fails if the published names, compose defaults, resolver output
and docs drift apart, or if the tag disagrees with the Dockerfile.
2026-10-13 23:02:51 +00:00
Hermes Agent 28ba580064 Fix engine-awareness gaps the per-engine harness exposed
- Healthcheck kept the old unconditional Ghidra/Hopper checks (left over from the
  first patch), so every single-engine image reported itself unhealthy. Removed
  them; the healthcheck now checks only the engine(s) it declares, and the
  harness asserts the healthcheck itself ('healthy:') for each image, shallow and
  deep.
- Engine paths moved from /etc/rea to /usr/local/share/rea: compose mounts the
  user's ./config over /etc/rea, which shadowed the baked marker and env file.
- The harness adopts engine.env for its own checks (and supplies inert defaults),
  so a single-engine image skips instead of aborting under set -u.
- .dockerignore no longer excludes vendor/*.deb and vendor/ida/*: git still never
  commits them, but the build context must contain them or the documented
  licensed-Hopper / baked-IDA paths silently do nothing. Verified with a probe
  build that the files now reach the context.
- verify-all-engines.sh: QUICK=0 made ${QUICK:+--quick} always expand, so the
  sweep silently ran the fast profile. Use an empty default.
- docs: sizes are measured now, MULTIARCH/vendor/compose docs follow the
  per-engine services.
2026-10-13 20:12:36 +00:00
Hermes Agent 596f7befb3 Per-engine images: one Dockerfile, four images (all/ghidra/hopper/ida)
- REA_ENGINE=(all|ghidra|hopper|ida) selects the native engine; the engine
  layers are built LAST so every earlier layer is shared cache across the four
  variants (docs/ARCHITECTURE.md layer map updated).
- Each image declares itself: /etc/rea/engine (marker), /etc/rea/engine.env
  (only the paths it needs, plus REA_ANALYSIS_PROVIDER for single-engine
  images), and a /usr/local/bin/rea wrapper that sources engine.env - so
  `docker exec -i <ctr> rea mcp` finds the engine with no compose environment,
  and an image without Ghidra never advertises GHIDRA_INSTALL_DIR.
- healthcheck, entrypoint and the verification harness are engine-aware: they
  read /etc/rea/engine and SKIP (with a reason) checks for engines the image
  does not ship. One harness verifies all four images.
- compose: one service per engine (rea-agent, rea-ghidra, rea-hopper, rea-ida)
  with per-engine env and home volumes; engine-agnostic HTTP bridge sidecar;
  IDA overlay applies to both rea-agent and rea-ida.
- scripts: build.sh --engine, build-all.sh, verify-all-engines.sh; Makefile
  gains per-engine build/up/verify/sizes targets; CI matrix (ghidra on push,
  all four on workflow_dispatch).
- fix: runtime user creation is now tolerant of Ubuntu's stock uid/gid 1000
  (groupadd failed with 'GID 1000 already exists' when REA_UID was unset), and
  build.sh passes REA_UID/REA_GID through from the environment/.env.
- docs: new IMAGES.md (per-engine guide) and ida-variants.md (IDA vs IDA Pro:
  one program, four licence plans; which edition can drive REA and how);
  README/HERMES-MCP/BYO-LICENSES/ARCHITECTURE/TROUBLESHOOTING updated.
2026-10-13 19:37:07 +00:00
Hermes Agent ba296cd09a rea-agent: Docker image + compose stack for Reverse Engineer Anything
Brings the REA MCP server and its full analysis toolchain into one
linux/amd64 image: Ghidra 12.1.4 (multi-architecture), Hopper 6.5.0 demo,
bring-your-own IDA/JEB, pwntools/pwndbg, binwalk+unblob, tshark, sigrok-cli,
mitmproxy, WABT, jadx/apktool/adb, .NET+ILSpy, Chrome/Playwright, Frida,
qemu-user/wine/cross toolchains, plus the stdio and Streamable HTTP MCP
surfaces and an in-image verification harness.
2026-10-13 16:19:18 +00:00