Found by the pre-publication claim audit of this round's response comment, which refuted the sentence "none of the unscrubbed env reads names a write destination" on the grounds that naming a path is not the same property as influencing where writes land. GSD_ALLOW_SYMLINKED_DEST is boolean and names no path, so every rung of the derivation is structurally incapable of reaching it: not a registry configHome, not descriptor-shaped, not one of GSD's own location vars. It is still a #2665 leak vector. install-engine.cts reads it env-first (:214) and threads it as allowOptInFollow into the symlink-escape guard at four call sites, each gating a write (:361/:367, :416/:424, :785/:790, :927/:932). That guard is what stops a write leaving the install root, so an ambient =1 disarms it for the whole suite — the #2665 hazard arriving through a permission rather than a path. Added as its own named family (WRITE_ESCAPE_PERMISSION_ENV_KEYS) rather than folded into a location rung, for the same reason GSD_HOME got its own family in round 3: the list should not misdescribe what its members are. Blanking is fail-safe in the only direction that matters — '' is neither '1' nor 'true', so a blanked value makes the guard stricter, never looser. That asymmetry is what licenses scrubbing it wholesale rather than reasoning about each call site. The guard test names the variable literally rather than iterating the family constant: a test that asserts over the constant shrinks its own expectation when the family is emptied, which is the enumeration-relative failure that let the kimi-code descriptor go unwatched earlier in this same round. #2393's opt-in suite is unaffected (99/100, 0 fail): it sets process.env directly in-process and never routes through scrubConfigLocationEnv, and an explicit env argument still wins over TEST_ENV_BASE in childEnv.
14 KiB
14 KiB