Skip to content

Restructure the repository around the marketplace and pin the Rizin runtime - #8

Merged
JerryLinLinLin merged 2 commits into
mainfrom
claude/sweet-wescoff-f4ebc5
Oct 14, 2026
Merged

JerryLinLinLin merged 2 commits into
mainfrom
claude/sweet-wescoff-f4ebc5

Conversation

@JerryLinLinLin

@JerryLinLinLin JerryLinLinLin commented Oct 14, 2026 •

Copy link
Copy Markdown
Owner

Why

A structure review found that every Claude Code install of this marketplace downloaded about 628 MB, almost all of it the six Rizin source submodules, for 1.3 MB of plugin content. The repository root was still laid out like the Rizin build repo it grew out of, the plugins followed different conventions for experiments, imported material, and runtime pinning, and the marketplace name was a template placeholder. This PR implements all of the review's findings.

What changed

Layout

  • The six sources/ submodules and .gitmodules are gone. runtimes/rizin/build_bundle.py fetches each component into ignored build/sources/ at the commit locked in bundle.lock.json (shallow, detached, patched once, retryable after an interrupted fetch or a lock change). --sources-only fetches without building. The checker rejects .gitmodules and gitlink entries.
  • Rizin build inputs moved from the root and scripts/ into runtimes/rizin/. scripts/ now holds only repository-wide checks, the Hyper-V builder, and the Windows CI test scripts.
  • The Capstone and Frida experiment harnesses moved out of the plugins into tests/capstone-binary-patching/ and tests/frida-use/.
  • Frida's byte-for-byte imported material (82% of that plugin by size, with name collisions and dead links) moved to docs/archive/frida-use/. The import manifest uses repository-relative paths, the files are stored with -text so their recorded CRLF digests hold on every checkout, and the checker verifies all 31 hashes.
  • The marketplace is renamed to jerry-plugin-marketplace. Tested with throwaway registrations in both clients: Claude Code keeps the registration name and updates in place (marketplace update, then plugin update moved rizin-re-toolkit 0.4.1 to 0.5.0); Codex keys installed plugins to the declared marketplace name and orphans them, so it needs remove, marketplace remove, add, and install. The README gives each client its own steps.

Rizin runtime pinning

  • New plugins/rizin-re-toolkit/runtime.json pins the release tag, archive, SHA-256, and URL, matching how Hyper-V Control already pins its executable.
  • install.ps1 downloads only that archive and verifies its hash. No GitHub API calls, so the 60 requests/hour limit no longer matters. It checks the destination before downloading, stages inside the destination root (no cross-volume moves on Windows PowerShell 5.1), and resolves relative destinations against the caller's directory.
  • scripts/test-rizin-installer.ps1 replaces test-installer.ps1: synthetic probe by default, -ReleaseDir build\release for a packaged archive before publishing.
  • The Hyper-V installer dropped the cross-field validation of its manifest that the repository checker already enforces.
  • The Rizin skill shrank from 395 to 227 lines; its command tables moved to references/commands.md.

Housekeeping

  • .gitignore drops the stray test/ rule; .gitattributes normalizes text to LF with explicit binary rules.
  • scripts/ci-plan.py selects the Windows job by path prefix and uses --no-renames so a moved input still triggers it.
  • scripts/check-marketplace.py now also checks every plugin Markdown file and tests/, rejects experiments or docs shipped inside plugins, and validates runtime pins with two rules (well-formed SHA-256, URL matching tag and asset).
  • Plugin versions bumped so cached installs refresh: rizin-re-toolkit 0.5.0, frida-use 1.1.0, capstone-binary-patching 0.1.1, hyper-v-control 0.1.3.
  • CONTRIBUTING, the release and Rizin build guides, the docs index, and the validation report links are updated.

CI reproducibility check (second commit)

  • The Windows job's exact-hash comparison of the rebuilt Hyper-V executable against the pin fails on this branch and, when run manually, on unchanged main. Diffing the bundles shows only 84 bytes differ, all compiler-recorded identifiers inside HyperVControl.dll (PE timestamp, module version id, PDB id and checksum) plus the derived bundle id; IL, metadata, host, and bundled runtime are identical.
  • Two inputs change those identifiers without changing code: the runtime patch the compiler runs on (recorded in the PDB; setup-dotnet moved from 10.0.12 to 10.0.13 this week, and a local rebuild on 10.0.13 reproduces today's CI hash exactly) and source checksums (the October 11 history rewrite removed one comment line from each file under src/HyperVControl/Extracted/, so the pin cannot be reproduced from current sources anywhere).
  • scripts/compare-hyperv-runtime.py now downloads the pinned asset, verifies its SHA-256 against runtime.json, and compares it with the rebuilt executable while masking only those identifier fields. Every other byte must match. An unpublished pin (404) is reported and skipped so a release PR can precede its assets.

Reviewer notes

  • The 31 archived Frida files show as modified as well as renamed because they are now stored with CRLF bytes (-text). Their content is unchanged apart from line endings, and their SHA-256 digests match the import manifest in a fresh clone on Windows and Linux.
  • src/HyperVControl/Extracted/ keeps its name. Renaming it could change the pinned executable hash and I could not rebuild with .NET 10 locally.
  • The Windows CI job runs for this PR (scripts and plugin inputs changed). It rebuilds Hyper-V, runs the pinned-release comparison, and runs the installer, isolation, and launcher tests.

Tested locally

  • python scripts/check-marketplace.py, python scripts/test-runtime-packaging.py, and claude plugin validate --strict for the catalog and all four plugins.
  • scripts/test-rizin-installer.ps1 under pwsh 7 and Windows PowerShell 5.1, including -ReleaseDir against the real published rizin-v0.3.1 archive; the real installer against GitHub (hash matched).
  • scripts/test-release-isolation.ps1 with the real pinned Hyper-V executable, and scripts/test-hyperv-launcher.ps1.
  • build_bundle.py --sources-only: all six components at their locked commits with patches applied; retry after an interrupted fetch and after a lock change.
  • Frida harness from its new location (25 integration and 4 CLI cases) and the Capstone harness (13 groups).
  • A fresh export of the index passes the checker with all archive hashes intact.
  • scripts/compare-hyperv-runtime.py against the pinned asset: passes for local rebuilds on runtime 10.0.12 and 10.0.13 and for the pinned file itself; fails for a flipped IL byte, a flipped byte in a bundled runtime assembly, a flipped host byte, and a truncated file.

🤖 Generated with Claude Code

…untime

Claude Code clones a marketplace with every submodule, so each install pulled
about 628 MB of Rizin sources for 1.3 MB of plugins. The repository root was
also laid out around the Rizin build, and the plugins followed different
conventions for experiments, imported material, and runtime pinning.

Layout
- Remove the six source submodules and .gitmodules. build_bundle.py now
  fetches each component into ignored build/sources at the commit locked in
  bundle.lock.json (shallow, detached, patched once, retryable) and has a
  --sources-only flag. The checker rejects .gitmodules and gitlink entries.
- Move the Rizin build inputs (lock file, patches, build/package/verify
  scripts, smoke fixture, UTF-8 manifest) to runtimes/rizin/.
- Move the Capstone and Frida experiment harnesses out of the plugins and
  scripts/ into tests/<plugin-id>/.
- Move Frida's byte-for-byte imported material to docs/archive/frida-use/.
  The import manifest now uses repository-relative paths; the files are
  stored with -text so their recorded CRLF digests hold on every checkout,
  and the checker verifies them.
- Rename the marketplace from my-plugin-marketplace to
  jerry-plugin-marketplace, with a migration note in the README.

Rizin runtime
- Add plugins/rizin-re-toolkit/runtime.json pinning the exact release tag,
  archive, SHA-256, and URL, matching Hyper-V Control.
- Rewrite install.ps1 to download only that archive and verify its hash. It
  no longer queries the GitHub API, checks the destination before any
  download, stages under the destination root, and handles Windows
  PowerShell 5.1 stderr and relative destinations.
- Replace test-installer.ps1 with test-rizin-installer.ps1 (synthetic probe,
  or -ReleaseDir for a packaged archive) and simplify the Hyper-V installer's
  redundant manifest cross-checks.
- Split the Rizin skill's command reference into references/commands.md.

Housekeeping
- .gitignore drops the stray test/ rule; .gitattributes normalizes text to
  LF with explicit binary rules.
- ci-plan.py selects the Windows job by path prefix with --no-renames.
- check-marketplace.py also checks every plugin Markdown file and tests/,
  plugin content boundaries, and runtime pin consistency.
- Bump plugin versions (rizin-re-toolkit 0.5.0, frida-use 1.1.0,
  capstone-binary-patching 0.1.1, hyper-v-control 0.1.3) so cached installs
  refresh, and update CONTRIBUTING, the guides, and validation report links.
…f its exact hash

The Windows CI job failed on this branch and, when run manually, on main:
the rebuilt executable no longer hashes to the pinned hyper-v-control-v0.1.0
asset. Diffing the single-file bundles shows only 84 bytes differ, all inside
HyperVControl.dll and all compiler-recorded identifiers (PE timestamp, module
version id, PDB id and checksum) plus the bundle id derived from them. The IL,
metadata, host, and bundled runtime are identical.

Two inputs feed those identifiers without changing any code:
- The runtime patch the C# compiler runs on is recorded in the PDB. GitHub's
  setup-dotnet installs the newest patch, which moved from 10.0.12 to 10.0.13
  this week; rebuilding locally with 10.0.13 reproduces today's CI hash exactly.
- Source checksums are recorded in the PDB. The history rewrite on 2026-10-11
  removed one comment line from each file under src/HyperVControl/Extracted/,
  so the pin built from the earlier sources cannot be reproduced anywhere.

An exact-hash check therefore fails on every monthly runtime patch and on
comment-only edits, and re-pinning would require publishing a new release.
scripts/compare-hyperv-runtime.py downloads the pinned asset, verifies its
SHA-256 against runtime.json, and compares it with the rebuilt executable
while masking only those identifier fields; every other byte must match.
The workflow step now runs that comparison; CONTRIBUTING and the release
guide describe it.
@JerryLinLinLin
JerryLinLinLin merged commit f738ed3 into main Oct 14, 2026
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant