Skip to content
 
 

Repository files navigation

ReproSpec: Portable Evidence Bundles and Sandboxed Replay for Node.js Executions

ReproSpec is an experimental CLI and evidence-bundle format designed to make Node.js script execution logs and test results portable, integrity-checked using SHA-256 file hashes, and re-runnable inside local sandboxed containers.

The Maintainer Problem

Open-source maintainers face a dual crisis: a high volume of incomplete or platform-dependent bug reports ("works on my machine"), and a growing security risk when triaging pull requests that require running untrusted test suites locally.

ReproSpec aims to reduce this triage burden by packaging execution logs, environmental context, and dependency states into a portable evidence bundle. It attempts to replay the command in an offline local sandbox to verify if the result matches the reporter's claim, while using tools designed to leave the original checkout unchanged (with git status verification before and after replay).

Technical Mechanism & Security Boundaries

1. What ReproSpec Captures

During a capture command, ReproSpec logs:

  • Standard output (stdout) and standard error (stderr) streams.
  • Execution metadata (command parameters, exit code, and duration).
  • System environment context (Node version, OS architecture, platform type, CPU/Memory layout).
  • A redacted environment variable list (redacts supported secret patterns such as GitHub tokens and AWS keys).
  • Dependency metadata extracted from npm manifest files.

2. Integrity Verification

The verify command recalculates and validates SHA-256 integrity hashes for all declared files in the evidence bundle against a hashed manifest index (integrity.json).

⚠️ Important Security Boundary: Verification only proves that the declared files inside the bundle directory haven't been altered or tampered with since they were generated. It does not prove:

  • Who created the bundle (no asymmetric key pairs are used for author identity verification).
  • That the original capture was truthful (an author could mock the output during initial capture).
  • That all secrets were successfully redacted (only supported regex heuristic patterns are scrubbed).
  • That replay is deterministic across all systems.

3. How Sandboxed Replay Works

The replay command performs the following sequence:

  • Workspace Protection (Immutability):
    • Default: Required source and manifest files are copied into an isolated temporary workspace folder. The original repository is never exposed.
    • Optional Exception: The original repository may be mounted read-only only when allowWorkspaceMount is explicitly enabled by the user.
  • Dependency Isolation: Uses an isolated temporary dependency environment inside a Docker volume, executing npm ci inside a bridge container to fetch and cache Linux-compatible packages without polluting host node_modules.
  • Sandbox Bounds: Replay container runs with --network none (network disabled) and applies CPU, memory, and PID limits.
  • Trust Warning: Docker replay executes arbitrary project code. It should only be used with trusted local repositories during this alpha phase.

Supported and Unsupported Alpha Scope

Supported Scope

  • Runtime: Node.js 20+
  • Languages: Pure JavaScript or TypeScript repositories.
  • Package Manager: npm with standard package-lock.json.
  • Operating Systems: macOS and Linux hosts.

Unsupported Scope (Alpha)

  • Python, Go, Rust, or other non-Node environments.
  • Yarn, pnpm, and monorepo configurations.
  • Windows hosts.
  • Reuse of native host-compiled binaries inside replay.
  • Active network connections or remote endpoint access during replay.

90-Second Quickstart

To run the full capture, verify, and replay cycle on your machine:

# 1. Clone the repository and enter workspace
git clone https://github.com/HenryParker37-VIP/reprospec.git
cd reprospec

# 2. Install package-lock dependencies
npm ci

# 3. Capture command execution
node bin/reprospec.js capture --output my-bundle -- node -e "console.log('original run')"

Captured Output:

[reprospec] Capturing: node -e console.log('original run')
[reprospec] Working directory: <temporary-workspace>
[reprospec] Started at: 2026-07-31T15:46:09.188Z

[reprospec] Bundle written to: <temporary-workspace>/my-bundle
[reprospec] Exit code: 0
[reprospec] Status: PASS
[reprospec] Removed env vars: EXAMPLE_API_TOKEN, EXAMPLE_DATABASE_URL

✅ Bundle written to: <temporary-workspace>/my-bundle
# 4. Verify bundle integrity
node bin/reprospec.js verify my-bundle

Verification Output:

── ReproSpec Bundle Verification ──────────────────────
Bundle: <temporary-workspace>/my-bundle
Status: ✅ INTEGRITY_VERIFIED — The bundle manifest and SHA-256 file hashes were verified.

File Details:
  ✅ stdout.txt: OK
  ✅ stderr.txt: OK
  ✅ command.json: OK
  ✅ environment.json: OK
  ✅ integrity.json: OK
───────────────────────────────────────────────────────
# 5. Replay inside Docker sandbox
node bin/reprospec.js replay my-bundle

Replay Output:

── ReproSpec Replay Sandbox ───────────────────────────
Bundle: <temporary-workspace>/my-bundle
Docker: v29.5.3
────────────────────────────────────────────────────────

[reprospec] Running replay container: docker run --rm --name reprospec-replay-1785512773174 --network none --user 1000:1000 --memory 1g --cpus 1.0 --pids-limit 128 --security-opt no-new-privileges=true --read-only -v <temporary-workspace>:/workspace:ro --workdir /workspace --tmpfs /tmp:rw,noexec,nosuid,size=64m --stop-timeout 60 node:20-alpine node -e console.log('original run')

── Replay Result ───────────────────────────────────────
Status:           REPLAY_VERIFIED
Expected Exit:    0
Container Exit:   0
Oracle Match:     ✅ YES

Container Output:
original run

───────────────────────────────────────────────────────

About

Portable, integrity-checked evidence bundles and sandboxed replay for reproducible Node.js bug reports and pull requests.

Resources

Code of conduct

Contributing

Security policy

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages