Approach C persists imageTag in Instance.imageTag and renders the full
.env for CCP-provisioned tenants. For install.sh-registered tenants
(isRegistered=true, no encryptedSecrets), the .env was filtered out of
the rendered file set — so the new imageTag never reached the tenant's
compose, leaving install.sh tenants unable to bump image versions via
Approach C.
Closes the gap with an in-place .env key patch:
- agent/services/file.service.ts: patchEnv(basePath, vars) — reads .env,
finds existing keys and replaces values, appends unknown keys at end
under a "# Added by CCP env-patch" comment. Preserves comments and
unrelated keys. Validates ENV_KEY_RE + rejects newlines in values.
- agent/routes/files.routes.ts: POST /instance/:slug/env/patch.
- api/services/execution-driver.ts: patchEnv added to interface.
- api/services/local-driver.ts + remote-driver.ts: patchEnv methods.
- api/services/upgrade.service.ts:runReleaseUpgrade — for isRegistered
tenants with newImageTag, calls driver.patchEnv({ IMAGE_TAG }) after
writeFiles and before composePull. Non-fatal on failure (logs warn).
This makes Approach C functional for the existing install.sh fleet
(marcelle, linda, pia + future). CCP-provisioned tenants still get
the full .env render — unchanged behavior.
All three projects type-check cleanly.
Bunker Admin