The config option alone was invisible: the host's plugin-configuration page
only renders cards a plugin ships itself, so a namespace field would never
show up. Give the market's own card a Build environment editor, persisted
through the market's state.json like channel/region — and deliberately NOT
through the settings namespace, which would become a second writer for a
value that already has an editor (the exact shape of the channel bug).
- src/hot.ts: MarketState.buildEnv with sanitizing reads/writes
(POSIX names only, PATH/CI dropped, blank values removed)
- src/routes.ts: mount applies a saved state buildEnv over the composition;
/status reports the effective map; POST /dsh-market/build-env validates,
persists and applies it live (next install builds under it, no restart)
- src/client/SettingsCard.tsx: KEY=value editor seeded from /status, posts
the parsed map, echoes the server-applied answer, empty list clears
- src/settings.ts: reverted to allowRestart only (single-writer contract)
- tests: card editor (render/save/clear/refusal), route round-trip +
remount survival, state persistence/sanitizing; README updated
Ordinary installs compile under whatever environment the dsh process
inherited — which a GUI, systemd/launchd or Windows Start-menu launch does
not inherit from a shell. Add a `buildEnv` map to the market config (and its
settings section, editable live where the settings service exists) that is
merged into every install/build spawn after process.env but before the
market-owned PATH and CI, so a pinned CC/CXX can replace an inherited
compiler without ever breaking the two values the market computes itself.
- src/dsh-cli.ts: spawnEnv merges a live build-env source; setBuildEnvSource
returns the previous source so mount can restore it on teardown
- src/routes.ts: MarketConfig.buildEnv; mount wires the live source
- src/settings.ts: buildEnv in the dsh-market settings namespace
- src/index.ts: thread config.buildEnv into both mount paths
- tests: schema defaults, live settings sync, spawn wiring incl. CI/PATH
protection; README documents the option in both languages