ReviewOS

pantry-pm/pantry

fix(native): validate the actual Pantry toolchain before runtime provisioning

#275
Open chris opened this 1 hour ago ·
1 hour ago

ts-pantry/native's public provisionNativeRuntime() invokes bare pantry install ziglang.org@... --no-save --ignore-scripts without checking that executable against the supported SDK toolchain. Buddy setup validation is a separate caller and cannot enforce this for standalone SDK consumers.

Related: https://github.com/stacksjs/stacks/issues/3107. The Stacks correction must validate the executable each Stacks caller actually runs; it must not claim that an unrelated PANTRY_BIN validation covers the SDK's bare PATH command.

A bounded public subprocess reproduction against normally installed SDK 0.11.159 uses a real clean local authored Git fixture, the public nativeRuntimeCacheKey() and provisionNativeRuntime() exports, and no injected NativeCommand. A bare executable reporting Pantry 0.11.156 reaches install ziglang.org@0.17.0 --no-save --ignore-scripts while PANTRY_BIN names a different 0.11.159 executable. The install attempt is guarded with exit93, before compiler acquisition or native build. No runtime/backend source substitution, network acquisition, native build, profile changes or actual installation is claimed. Evidence: /tmp/stacks-3107-public-n745efwm/native-api/result.json, source/probe identities in /tmp/stacks-3107-reproduction-proposal.json SHA256 ee33dbceb20b44afebd6a75b71f4f4e6281244e348f292038cc39287f33ac8d4.

Acceptance:

  • Define and enforce the SDK's supported CLI declaration through its owning public native contract, using existing Pantry version/semver facilities rather than a downstream wrapper or private import.
  • Validate the same executable, cwd and effective environment that the actual native install executes. A good unrelated PANTRY_BIN must not permit an incompatible bare PATH command.
  • Refuse known broken, malformed and incompatible executables before install or cache mutation, with actionable diagnostics and no silent global upgrade.
  • Preserve paths that require no installation, including a qualified cached native runtime and valid explicit CRAFT_BIN. Do not require an unused Pantry just to accept those paths.
  • Maintain public subprocess regressions proving refusal before a guarded install marker and compatible execution reaching that marker. Keep missing-command behavior explicit. No mocked successful install, SDK-private imports, generated runtime rewrites or widened native acceptance claims.

This is an owning-source gap, not proof that a specific native game scenario or provider is supported. It remains separate from the root pre-Bun shell acquisition issue.

Approved implementation policy (2026-11-02):

  • The supported native CLI range is derived from the owning SDK package version in the paired SDK/CLI release metadata. The Node/Bun native contract validates versions and uses the owning Node-compatible version utility; it does not add a Bun-global requirement or a parallel hardcoded range.
  • Preserve bare pantry selection. PANTRY_BIN is not an advertised selector for this native API. options.env, when supplied, remains the complete child environment, and final validation uses the exact installation cwd and environment.
  • Valid CRAFT_BIN, no-runtime and qualified cached-runtime paths do not require unused Pantry. Existing source and binary provenance checks remain.
  • Existing checkouts that need installation are checked before clone/dependency/profile writes. Cold checkouts first pre-screen Pantry in the existing project root before acquisition, then validate again in the actual checkout cwd before profile invalidation or install. The first probe is explicitly a pre-screen, not identical-cwd evidence.
  • An existing cache/profile is never discarded by a toolchain refusal. After a successful cold pre-screen, newly acquired immutable source may remain if a later cwd-dependent check refuses; that is unqualified source only, not a successful native cache. This policy does not promise that no source acquisition can ever precede a later refusal.
  • Version probing uses an optional bounded owning NativeCommand timeout contract. Unrelated commands retain their existing defaults. The default executor must terminate and await its owned child, settle pipes/timers, and avoid race-and-abandon handling; this does not claim arbitrary process-group ownership.
1 hour ago

The owning fix is now normally delivered to main in 98fd9675c, with the separate OpenJDK fixture organization commit and current TestFlight work preserved. Both independent review axes passed.

The integrated SDK passed 961 tests, with 8 existing skips and 0 failures, plus types, lint, build and a fresh normally packed Node/Bun consumer. All 1,869 candidate package files matched the original candidate archive. The CLI range is derived from paired SDK metadata; actual bare command, cwd and complete environment are validated before provisioning, preserving the documented cold-source boundary and no-install paths.

The unchanged canonical bun run release:patch exited0 and delivered candidate v0.11.162, exact main source 9d9a0c2a0c7338d996acd951c198f3a375ef1a99, authored and committed as Chris without coauthors. Exact main push CI and Releaser are still pending qualification. This issue remains open until the required hosted gates and actual public SDK/native artifacts and consumer checks are verified. No framework/app adoption or native game qualification is inferred.

Release receipt: /tmp/pantry-162-canonical-release-receipt.json, SHA256 293693ef31a7c5d9928357bf38c9348ff98f6f224dc0af312e8de2c8efca015b.

Sign in to comment on this issue.