Fixed
-
The sandbox now grants
LEMONSQUEEZY_TEST_API_KEY.src/secret.tsreads it, but the--allow-envlist omitted it, so underLEMONSQUEEZY_MCP_SANDBOX=1the variable was absent fromprocess.envrather than denied -- oam withholds a non-granted variable instead of throwing. The test-mode branch simply took its false path: with both keys set the server silently used the production key, and with only the test key setloadApiKey()threwLEMONSQUEEZY_API_KEY or LEMONSQUEEZY_API_KEY_COMMAND environment variable is requiredwhile the key was in fact configured. That silent-misconfiguration shape is the exact hazard the launcher header cites as the reason the sandbox is opt-in rather than default.Scope was judged against the built bundle, not
src/:LEMONSQUEEZY_TEST_API_KEYappears twice indist/index.js, so it ships.LEMONSQUEEZY_TEST_STORE_IDappears zero times -- it is read only byintegration.test.ts-- so it stays ungranted rather than widening the sandbox for a variable the server never reads.
Added
src/sandbox-env.test.tsfails the build if the allow-list drifts from what the bundle reads. The gap above existed because nothing compared the two. The test parses the launcher's--allow-envarray and everyprocess.env.LEMONSQUEEZY_*indist/index.js, and asserts the first covers the second; both sides also assert non-empty, so a regex that stops matching after a refactor fails loudly instead of passing vacuously. Asserting against the built artifact rather than sources is deliberate -- that is what runs under the sandbox, and it naturally excludes test-only reads. The inverse direction (granted but never read) is reported as a note rather than asserted, since a grant may legitimately land ahead of the code that uses it.