ReelGrove
Open studio

Your game. Your development environment.

Bring your local build
back to ReelGrove.

Download bundlepack to package an edited development bundle for Import new build. It runs locally and needs no ReelGrove credentials.

Linux amd64 & arm64Works in a Linux WSL2 environmentLocal execution
  1. 1ExportGet your development ZIP.
  2. 2BuildEdit and compile locally.
  3. 3PackageMake a verified TAR.
  4. 4ReturnUpload, validate, activate.

Choose the architecture of the Linux environment where you will run the command. Run uname -m there: x86_64 means amd64; aarch64 means arm64.

Enable JavaScript to check the available bundlepack release.

Before the first run

Check the download.

  1. Download the utility and its matching SHA-256 file into the same folder.
  2. Open Verify and run this download on your architecture’s card. Run its sha256sum -c command from that folder and check that the result says OK.
  3. Run the displayed chmod command, then -version. Its JSON reports version, os and arch; check these against the card.

If the checksum does not match, download both files again before running the utility. The checksum identifies the utility download; the pack command later reports a separate checksum for your game archive.

Make room for the build

Use a private Linux workspace.

In your project’s Export game dialog, choose Development bundle. Extract its ZIP into a private working folder, then follow source/development/README.md and the included source instructions to edit and rebuild both frontend targets.

Each export reserves 2 GiB of studio storage until it expires, and a studio holds up to 4 GiB of exports across all its projects. If a new export has no room, cancel exports you no longer need under Export game → Your exports on the project that made them, or wait for them to expire. The message says how much of the reservation is yours and how much belongs to exports or math previews requested by other studio members, which only they can cancel, and when the next of their exports expires.

Using Windows?

Run bundlepack inside WSL2’s Linux terminal. Keep the working bundle in your Linux home directory, such as ~/studio-work/, so Linux file permissions apply. Use that workspace instead of /mnt/c or a shared Windows folder.

The completed bundle folder must be private (mode 0700). Keep dependency installs, build caches, hidden files and credentials outside it. Use regular files and directories; symbolic links and hard links are rejected.

Keep the supplied layout, notices and game declarations. The bundle’s root contains:

Completed bundle
bundle.json
source/
frontend/
standalone/frontend/
math/
notices/

Keep the supplied runtime override arrays empty. Uploaded assets and saved Art, Sound, Motion and Animation Lab work stay in the original project and are preserved when you activate the rebuilt game in that same project. A build imported into another project does not transfer that saved Lab work. The Animation Lab export guide explains how to download editable rigs and standalone playback packages.

Saved game-animation bindings use the hooks implemented by that project’s original source. Retain their declarations when rebuilding. Standalone exports carry the exact bound rig versions and playback runtime; development downloads keep the empty binding manifests. Check real game placement, sound, skip, turbo and reduced motion after integrating a new hook.

After the build finishes

Make the import archive.

Stop build watchers and other processes writing to the finished bundle. From the folder containing your verified utility, run the example below. Replace the paths with your own; for ARM64 use bundlepack-linux-arm64.

Linux amd64 example · replace the paths before running
chmod 700 /absolute/path/to/completed-bundle
./bundlepack-linux-amd64 \
  -source /absolute/path/to/completed-bundle \
  -out /absolute/path/to/game.tar

The output folder must already exist outside the completed bundle. Choose a new filename: bundlepack never overwrites an existing archive. When it finishes, it prints the archive path, byte count and SHA-256.

The pack command packages completed files. Follow your game’s build instructions first; packaging does not compile source or generate math.

Pick up where your team left off

Upload, review, then activate.

  1. To update your existing project, open its Import new build action. For an independent Engine game, use Import existing game where enabled. Template-build imports keep their approved original.
  2. Select the .tar created by bundlepack, upload it, and submit it for validation.
  3. Review the result and choose Activate build when ready. Uploading alone does not change the project.
  4. Open the Lab and preview, inspect your saved artwork, sounds, motion and animations, and check the math and frontend reports. Confirm that the rebuilt game still declares the hooks used by your saved animation bindings.

Import and activation must be enabled for your installation and role. A passing validation report checks the supplied files; play and review the rebuilt game before submission.

Your project is waiting.

Continue from Overview when your archive is ready.

Open studio ↗

explicit project creation

Create a separate owned project with a durable receipt.

The CLI provides owned-project upload|status|validate|cancel|register. Use a key on an existing project with explicit projects:create and every required import scope. The server reserves a distinct destination; the anchor key gains no destination access. Issue a separate destination key for subsequent automation.

Explicit initial-project commands
studioctl -url ACCOUNT_MCP_URL -key-file /private/anchor.key \
  owned-project upload -archive game.tar -receipt creation.json -name 'My game'
studioctl -url ACCOUNT_MCP_URL -key-file /private/anchor.key \
  owned-project validate -receipt creation.json
studioctl -url ACCOUNT_MCP_URL -key-file /private/anchor.key \
  owned-project status -receipt creation.json
studioctl -url ACCOUNT_MCP_URL -key-file /private/anchor.key \
  owned-project register -receipt creation.json

Review the isolated validation result before registration. Keep the exact TAR and private receipt after an uncertain response; resuming reuses the reservation and committed offset. Upload allows 30 minutes by default, up to 1 hour with -timeout; a larger TAR gets 1.5 seconds per 1 MiB chunk plus 10 minutes, up to 4 seconds per chunk plus 10 minutes. Chunks are paced within the request budget. HTTP 429 stops with retry timing guidance; uncertain writes are never retried automatically. Read the authority and recovery contract.

Local preflight

Check preview space and tile assets before upload.

bundlepack math seekable converts large book files into standard seekable Zstandard with byte-exact verification. The matching preview worker reads bounded frames without expanding the books into runtime scratch. Ordinary compressed files retain their existing behavior. Hosted preview creation allows up to four minutes to verify and prepare large inputs; the isolated game still has a separate 30-second startup limit.

The current bundlepack prepare reports expanded book bytes, index space and 128 MiB reserved for database and filesystem overhead against the preview’s 1 GiB runtime. Add -require-preview-budget to fail CI when the estimate exceeds that budget. Prepared files and the JSON receipt remain available. This checks disk headroom; it does not prove that the game boots or renders.

The current tile check verifies matching filenames, decoded image formats, transparent foreground/logo pixels and the decimal 3 MB background-plus-foreground limit. It prints dimensions and hashes without modifying the artwork. Composition, rights and small-size legibility still need review. Use the matching current downloadable tool release.

Local tile check
bundlepack tiles -background GameTitle-BG.jpg \
  -foreground GameTitle-FG.png -logo ProviderName-Logo.png

Project-key file transfer

Save a full native rig without an account login.

The account and CLI support studioctl animation save|get|get-version for native files up to 24 MiB. They use the same project key, revision checks, Motion and embedded-media permissions, and immutable save receipts as Animation Lab. Inline MCP keeps its 4 MiB limit. The file service uses project-key authentication; an account browser session is unnecessary.

Keep an intent JSON with expectedActiveRevision, documentId, expectedSequence and a durable requestId. The CLI reads and hashes the input file; it never retries a write automatically. Recover uncertain results using get_animation_save_result before changing the intent. A rejected document reports the JSON path, reason code and any suggestion of its first fault and is not saved.

Full-document save using the existing project key
studioctl -url YOUR_PROJECT_MCP_URL -key-file /private/project.key \
  animation save -args-file intent.json -input rig.animation.json

For downloads, use animation get -args-file scope.json -output rig.animation.json with expectedActiveRevision and documentId in the scope file. get-version additionally requires versionId. Verified downloads create a private file and never replace an existing destination. Read the animation authority and recovery guide.

Your repository and build pipeline

Upload with a project-scoped CLI.

Studioctl connects to your existing independent project with a project key. Create a key with Import whole game bundles access and its required disciplines, then keep the key in a private file. Register a new project in the studio or use the initial-project commands with a key on an existing project and explicit creation access. Follow the existing-game workflow to prepare your first independent bundle.

Enable JavaScript to check the available studioctl release.

Use your project’s MCP URL and a private key file
chmod 600 /private/path/project.key
./studioctl-linux-amd64 -url YOUR_PROJECT_MCP_URL \
  -key-file /private/path/project.key \
  owned-build upload -archive game.tar -receipt build-request.json
./studioctl-linux-amd64 -url YOUR_PROJECT_MCP_URL \
  -key-file /private/path/project.key \
  owned-build validate -receipt build-request.json
./studioctl-linux-amd64 -url YOUR_PROJECT_MCP_URL \
  -key-file /private/path/project.key \
  owned-build status -receipt build-request.json

The current studioctl paces owned-build chunks below the shared admission rate. It allows 30 minutes by default, up to one hour with -timeout; a TAR larger than 800 MiB gets 1.5 seconds per 1 MiB chunk plus 10 minutes, up to 4 seconds per chunk plus 10 minutes and never beyond 23 hours. A 4 GB build with a million-book library uploads in roughly 40 to 60 minutes. If another client consumes the remaining rate allowance, wait one minute and resume the identical archive and receipt. Uncertain writes are never automatically retried.

Keep the receipt to resume the same upload or recover an uncertain response. It contains request identities and hashes, never the key or game files. Uploading and validation leave your active game unchanged. After reviewing a validated candidate, explicitly run owned-build activate -receipt build-request.json with the same URL and key options to preserve Lab work and switch builds.

The server checks current permissions, revision and editor capacity. Revoking or expiring the key stops unfinished work from acquiring new authority. Use an owner-only workspace for the archive, receipt and key; share review results separately from credentials.

studioctl export download saves a ready project archive with per-chunk and complete-file verification, without overwriting existing files. It handles temporary read-rate limits within the download timeout. See project exports through MCP and CI for capture, recovery, required permissions and the complete download command.

saved QA capacity

Read capacity and archive exact records.

The three scoped QA history tools are available through studioctl call. Keep the exact archive request JSON privately before sending it; choose a new UUID only for a new, explicit action. After a lost reply, recover the original receipt instead of creating another request.

Read current working and retained capacity
studioctl -url YOUR_PROJECT_MCP_URL -key-file /private/project.key \
  call get_qa_history_usage -args-file current-project-revision.json

The arguments file contains expectedActiveRevision from project_context. Read-only keys need every evidence read permission. Archival additionally requires review-comment permission and current editing capacity. It releases working capacity while retaining original evidence and storage; portable archive limits remain separate.

Keep your editable work

Recover a portable project offline.

Choose Portable project in Export game to capture your source, math, current Lab settings, every uploaded asset, editable animation versions, review lineage and saved QA scenarios. The same download verifies this archive and recovers its files without an account connection.

When archived QA exists, the portable capture retains the project’s saved scenarios, candidates, reviews and archive receipts across revisions. It verifies paged history and all referenced evidence before export and import. The complete archive remains limited to 2 GiB; capacity overflow fails the capture instead of omitting old evidence.

Retained hosted browser observations travel with the exact frontend, selected outcomes and settings that were tested. Completed observations include their raw results and screenshots, including failed checks. Retired files cannot be exported. Offline inspection labels these records as imported evidence; they do not approve a new project.

Profile matrices retain every definition and complete expansion, including original outcome books and requested profiles. Readiness policies and decisions retain their exact selected evidence across builds. Named regression suites retain every saved version, exact referenced scenarios and books, and release links for the captured revision. The export verifies complete membership and history within the shared capture limit; it does not silently omit cases. A new project keeps the original capsule as imported evidence, without converting it into native suite authority or approval.

Linux or WSL example · replace the paths before running
./bundlepack-linux-amd64 portable verify \
  -archive /absolute/path/to/studio-portable.zip
./bundlepack-linux-amd64 portable unpack \
  -archive /absolute/path/to/studio-portable.zip \
  -out /absolute/path/to/recovered-project

Choose a new recovery directory. Files are verified before publication and written privately; existing files and directories are never replaced. New exports include every retained animation version in the project, including earlier branches and documents with no current head. Older archives contain only the versions captured by their original exporter; verification cannot recover missing history.

Keep the original ZIP. To reproduce an unchanged extracted archive, use bundlepack portable pack -directory recovered-project -out archived-again.zip with the new ZIP outside that directory. Edited or extra files cause verification to fail. To rebuild the game, work from the recovered development.zip and follow its instructions.

Before planning a new project, run bundlepack portable plan -archive studio-portable.zip. It also checks the nested development source, editable Lab data, media and animation references, saved outcomes and release-review relationships. Its JSON report marks imported evidence as imported_unattested and requires fresh isolated source validation. Planning does not create a hosted project or transfer another studio’s approvals.

Offline recovery writes local files. To create a new editable project on an installation with restoration enabled, follow the steps below. Import new build preserves the destination project's existing Lab work; it does not import these Lab sidecars.

Create an independent project

Restore the captured source and Lab work.

Use a Portable project ZIP from an export you are authorized to use. Prepare it locally, then package the new directory as a normal import TAR. Choose new output paths outside the archive and recovery directories.

The prepared candidate must fit within 2 GiB, including the current source, retained original ZIP and preparation metadata. A successful export, portable verify or portable plan does not establish this fit. Run portable prepare below before uploading for hosted restoration.

Prepare the exact archive for fresh validation
./bundlepack-linux-amd64 portable prepare \
  -archive /absolute/path/to/studio-portable.zip \
  -out /absolute/path/to/prepared-restoration
./bundlepack-linux-amd64 -source /absolute/path/to/prepared-restoration \
  -out /absolute/path/to/restoration.tar
  1. 01

    Upload and validate.

    Choose Import existing game in the destination studio, select the prepared TAR and request validation. Keep the identical file for upload recovery.

  2. 02

    Review the portable project.

    Open the validated candidate. Its Restore editable project panel identifies the archive and saved request. Choose Restore project explicitly; the worker verifies the complete archive before copying saved work.

  3. 03

    Open and review the result.

    After completion, open the new project. Its captured Lab settings, media, animation heads and retained history are editable. Review the game and create fresh test scenarios and release decisions for the destination.

Restoration requires current project-creation and discipline permissions, editing capacity and an enabled worker. Source, math and saved Lab work receive new project ownership; original review decisions and browser records remain imported evidence. They do not grant access, approve the new project or become fresh hosted runs.

After a lost response or reload, use Check status or Retry same restoration. The saved request recovers the same project. Cancellation is available before final creation starts, including after editing expires. A stopped candidate keeps its history; another attempt needs a newly prepared and uploaded candidate. For a request requiring operator review, retain its ID and contact support.

Older archives restore only the history they actually contain. Source and non-animation Lab settings describe the captured revision; earlier complete project revisions are not recreated. On installations with cloning enabled, Clone project copies current saved work into another project in the same studio without a manual archive upload. It retains compact imported history; the current source, that history and preparation metadata must fit the same 2 GiB candidate limit. Imported history grants no destination approval. To reuse selected creative content, create a studio kit below.

Carry creative work into your next game

Build a reusable studio kit.

Select uploaded images, audio and exact animation versions from a Portable project export. The kit keeps their original bytes and embedded animation media. Start by listing the available paths, then copy the paths you want into a selection file.

List the captured content
./bundlepack-linux-amd64 kit list \
  -portable studio-portable.zip > available.json

Save selection.json with {"version":1,"paths":["EXACT_PATH_FROM_AVAILABLE_JSON"]}, replacing the placeholder with a listed path. Add more paths to select multiple files.

Create, verify and extract into a new directory
./bundlepack-linux-amd64 kit create -portable studio-portable.zip \
  -selection selection.json -out reusable-kit.zip
./bundlepack-linux-amd64 kit verify -archive reusable-kit.zip
./bundlepack-linux-amd64 kit unpack -archive reusable-kit.zip \
  -out reusable-kit

Use Open JSON in AnimationLab to load an extracted animations/*.animation.json file, then save it explicitly in a writable project. Upload files from assets/ through ImageLab or SoundLab. Configure game bindings in the destination project. Outputs are private and existing files are never replaced.

The local workflow works without a hosted installer. Where the project menu in your Lab offers Studio kits, you can upload the ZIP and review a separate installation plan. Kits carry content hashes; project approvals and private reviewer records are excluded. Verification checks byte integrity and animation structure, not rendered playback or Engine acceptance.

a separate saved copy

Copy a project through the CLI.

Use a key on the source project with explicit creation, import and export scopes. Save drafts first, inspect availability, then start the copy with a durable private receipt:

Capture a separate destination and retain the exact request
studioctl -url ACCOUNT_MCP_URL -key-file /private/source.key clone context
studioctl -url ACCOUNT_MCP_URL -key-file /private/source.key \
  clone start -name 'Alternate direction' -receipt clone.json
studioctl -url ACCOUNT_MCP_URL -key-file /private/source.key \
  clone wait -receipt clone.json

context and list only read. status checks a saved receipt once; wait polls every two seconds for up to 30 minutes by default. Stopping the CLI leaves server work running. Use cancel -receipt clone.json explicitly for permitted asynchronous cleanup.

Keep the receipt after a lost reply. Accepted retries recover the original captured source and destination even after the source project changes. New work needs the original credential and current editing capacity; a replacement read key can recover the same actor's accepted history. The copied project requires a separate key for further automation. See the scoped clone contract.

a reviewed portable plan

Restore through your project key.

After preparing the portable archive above, use owned-project upload and validate with a creation-enabled key on an existing project. Keep its private receipt, then inspect and explicitly start the restoration:

Review the plan, then restore its reserved destination
studioctl -url ACCOUNT_MCP_URL -key-file /private/anchor.key \
  restore inspect -creation-receipt creation.json -receipt restoration.json
studioctl -url ACCOUNT_MCP_URL -key-file /private/anchor.key \
  restore start -creation-receipt creation.json -receipt restoration.json \
  -reviewed-plan-sha256 EXACT_PLAN_SHA256
studioctl -url ACCOUNT_MCP_URL -key-file /private/anchor.key \
  restore wait -creation-receipt creation.json -receipt restoration.json

Review the exact plan produced by portable preparation before supplying its digest. Inspection reads the protected marker; the worker separately verifies the complete archive. status checks once; wait polls reads for up to 30 minutes by default. Stopping the CLI does not cancel server work. Use cancel explicitly when cleanup is permitted.

Keep both receipts after a lost reply. The same request recovers the same destination, including after the anchor changes. The original key owns new effects; a replacement read key can recover permitted history. The destination needs a separately issued key for further automation. See the scoped tool contract.

Review what enters this project

Install selected kit contents.

Open the destination project’s Lab, choose the project name at the top left and choose Studio kits from the project menu when your installation enables it. Uploading needs current editing access for each selected discipline, including image or audio permissions for media embedded in animations. Some workspaces allow inspected uploads but do not offer installation.

  1. 01

    Choose and upload.

    Select the kit ZIP, give it a name and choose its exact files. The local inventory only helps you choose; Upload selected kit hashes the archive and sends bounded chunks. Keep that identical ZIP to resume an interrupted upload.

  2. 02

    Inspect the complete archive.

    Choose Inspect uploaded archive. The server checks every payload, including unselected files, and reports the selected media and embedded animation contents. Inspection does not install anything.

  3. 03

    Review the destination.

    Choose Review installation. Check which images and sounds will be added or reused, the fresh identity for each animation and the additional Lab storage. Download the exact inspection and installation plan when you need to retain the review.

  4. 04

    Confirm, then review playback.

    Tick the review confirmation and choose Install reviewed contents. Existing Lab content is preserved. Refresh the relevant Lab library, open the imported work and check its playback. Configure game bindings explicitly.

After a lost response, reopen Studio kits from the project menu and use Recover saved request before starting another operation. The same browser tab retains the exact request and confirmation; reselect the identical ZIP when more bytes are needed. Closing the dialog pauses local work and keeps the request. Your kit history remains readable with the required permissions after editing expires.

scoped kit tools for MCP offer the same upload, inspection, separate plan review and explicit installation steps. Use either the scoped tools or the workspace controls above with current permissions.

Each upload and installation plan expires after 30 minutes; recovering the same request keeps its original deadline. Expired unfinished work is cleaned up only after the server verifies what it can remove. Selected-file lists, inspections and plans remain in history, and completed installations retain their original archive. Unfinished operations recovered from a backup stay available for operator review.

Use the offered cancellation action while an upload or installation is cancelable. Completed installations retain their history and original archive. A record requiring review needs operator support; copied recovery records do not authorize resuming an old installation. Origin hashes remain unverified source claims, and installation does not create a browser pass or an Engine approval.

Use the same download in CI

Retain an exact replay scenario.

The qa commands capture a published outcome and hash its source, frontend, math and optional creative files. They preserve the original event bytes. Stop input writers, then save a request outside the directories being checked.

qa-request.json · adapt the game, revision, directories and published outcome
{
  "projectId": "my-game", "gameId": "my-game", "revision": "git-commit",
  "roots": {"source": "./source", "frontend": "./dist", "math": "./my-game"},
  "selection": {"mode": "base", "variant": "", "bookId": "1", "costX100": "100"},
  "profile": {"name": "desktop", "width": 1280, "height": 720,
    "currency": "USDT", "language": "en", "reducedMotion": false,
    "actions": ["replay", "wait:complete"]}
}

Paths resolve relative to the request. The math directory needs its published index, books and lookup weights. The game ID and mode cost must match those files; 100 means a 1× mode. Add art, sound, motion and animation roots when you have creative overrides, including their binding and settings documents.

Capture and recover events · keep output files outside all input roots
./bundlepack-linux-amd64 qa capture -request qa-request.json > scenario.json
./bundlepack-linux-amd64 qa replay -request qa-request.json \
  -scenario scenario.json > replay-events.json
./bundlepack-linux-amd64 qa verify -request qa-request.json \
  -scenario scenario.json > report.json

Replay fails if the saved inputs or outcome changed. Verify reports browser execution as pending and exits nonzero when no separately collected browser observation is supplied. Saving a scenario does not run the game or establish that it passed a browser test. These local files are independent of the saved scenarios in your hosted workspace.

In the workspace, find a published outcome by zero payout, payout range, published maximum or exact recorded event type before explicitly saving a scenario. Results retain exact IDs and weights; zero-weight published records remain available for deliberate replay review.

Observe the built game

Replay an outcome in isolated Chromium.

Download the local browser runtime for Linux AMD64, then use the current bundlepack above. Docker and Python 3 are required. Integrate the opt-in adapter with your real game handlers to record replay completions, requested controls, errors and a screenshot.

Save the runtime archive, manifest, notices and loader in one new directory. Before executing the loader, verify these exact downloaded files:

Check the manifest and loader, then verify and load the image
printf '%s  %s\n' \
  'c68dd18a2494e1657a253aa902ab0592ccfe5e5499a4dacd90af61935675ec86' manifest.json \
  '910a413b7e09f0537cc59491bb1811c370e5b2e0c99f0c0f64131628fc9b5ead' browser-image.py | sha256sum --check
python3 browser-image.py verify .
python3 browser-image.py load . > browser-image-id.txt

Follow the integration guide to build your game with the observer adapter, capture a scenario and create browser.json. Use the verified local ID returned by the loader:

Run once into a new result directory, then check the retained receipt
./bundlepack-linux-amd64 browser run -request browser.json \
  -image "$(cat browser-image-id.txt)" -out browser-result
./bundlepack-linux-amd64 browser verify -directory browser-result

These receipts contain local observations. Where hosted workers are enabled, use Run browser checks in the workspace for separately retained server observations. Neither workflow grants automatic release approval. An observer-enabled starter release supplies its own integration; existing studios keep earlier template releases, so a newer default does not add the adapter to those projects. The runtime source revision is 2afb0e2; the host verifier requires bundlepack from 63cd53c or later. Different Docker image stores can report different local IDs; the loader verifies their configuration and layer mapping before returning one.

Keep the reason behind every math change

Run and compare local experiments.

The math commands run your reviewed generator or optimizer in a new local job, retain selected inputs and generated distributions, and compare the results. They use your installed tooling with your operating-system permissions. They do not install an SDK or provide a hosted execution sandbox.

Choose an explicit file list, include deterministic seed and dependency configuration where your tooling supports them, and pin the executable using bundlepack math hash-tool -path /absolute/path/to/python3. Save a reviewed spec outside your source directory. Adapt every path, file, game ID, mode and target below; replace the SHA placeholder with that command’s result.

experiment.json · example for a generator that writes sdk/generated
{
  "schemaVersion": 1, "name": "base-rtp", "gameId": "my-game",
  "inputsReviewed": true,
  "inputs": [{"name": "sdk", "root": "/absolute/path/to/my-game",
    "files": ["generate.py", "config.json"]}],
  "commands": [{"name": "generate", "argv": ["/usr/bin/python3", "generate.py"],
    "executableSha256": "REPLACE_WITH_TOOL_SHA256"}],
  "workingDirectory": "sdk", "outputDirectory": "sdk/generated",
  "targets": [{"mode": "base", "costX100": 100,
    "rtpPercent": {"min": "96", "max": "96.1"}}],
  "timeoutSeconds": 60, "maxOutputBytes": 104857600, "maxProcessBytes": 65536
}
Run, inspect and compare · use the job directories returned by run
./bundlepack-linux-amd64 math run -spec experiment.json -jobs /absolute/path/to/jobs
./bundlepack-linux-amd64 math verify -job /absolute/path/to/jobs/first
./bundlepack-linux-amd64 math compare \
  -before /absolute/path/to/jobs/first -after /absolute/path/to/jobs/second

Completed output must contain valid Engine books, lookup weights and an index matching every declared mode and cost. Comparisons use exact published weights. The math run exit codes are 0 for success, 3 for a valid result that misses its targets, 2 for invalid usage or a spec that cannot be read, and 1 for execution or integrity failure. math verify checks receipt integrity and can succeed for an intact job that missed its targets. Failed jobs retain their evidence; math recover -job … records an interrupted attempt without rerunning it.

Promote generated math deliberately through your game’s build and import workflow. A successful experiment does not update a hosted project, independently recompute your paytable, or establish Engine approval.

For a studio-owned project with hosted workers enabled, the workspace’s Math experiments panel offers reviewed execution profiles, retained comparisons and explicit preparation of a new build. Build validation and activation remain separate steps.

retained native evidence

Read and compare build receipts.

The MCP service provides two read-only tools for completed hosted math jobs. Use a current key with Project and Math read access; the key selects the project. Save the exact UUID returned by your experiment in receipt-read.json as {"jobId":"YOUR_JOB_UUID"}. For a pair, save {"beforeJobId":"FIRST_JOB_UUID","afterJobId":"SECOND_JOB_UUID"} in receipt-pair.json. Replace every placeholder with your retained UUID.

Read evidence and compare two retained native jobs
./studioctl-linux-amd64 -url https://reelgrove.net/mcp -key-file ./project.key \
  call get_math_build_receipt -args-file receipt-read.json
./studioctl-linux-amd64 -url https://reelgrove.net/mcp -key-file ./project.key \
  call compare_math_build_receipts -args-file receipt-pair.json

The read result contains base64 receiptJson and its exact receiptSha256. Keep the original bytes when saving evidence. The comparison binds both receipt hashes and reports its limitations. Only two distinct verified normalized runs may state two clean runs matched; matching runs do not guarantee future determinism. Legacy jobs remain ineligible. Downloaded or imported JSON cannot create a new native observation.

These reads do not execute source, promote math or activate a build. They remain subject to current key/membership access and retained output. MCP responses are bounded to 8 MiB. See the receipt tool contract for profile availability and authority limits, or the workspace controls for receipt downloads.