fix(desktop): refresh persona env vars on respawn — record.env_vars is overrides-only#1640
Conversation
…s overrides-only Persona env edits never reached existing agents: create baked the merged persona+override map into record.env_vars, and the spawn preflight / restore paths re-baked it on every start, so an edited persona credential stayed shadowed by its own stale copy forever (prompt/model/provider already refreshed via the re-snapshot). Make record.env_vars mean agent-level overrides only, everywhere, and merge the live persona env underneath at read time: - create seeds record.env_vars from input.env_vars only - spawn preflight / restore / backfill stop assigning snapshot env, and self-heal pre-fix records: an override equal to the persona's current value is reclassified as inherited (retain), so existing agents also benefit; runs only for persona-linked records - resolve_effective_agent_env layer 3 merges live persona env (covers the readiness gate, the setup payload, and the spawn-hash digest) - spawn command env performs the same live merge - PersonaSnapshot loses its env_vars field — no longer snapshotted Known semantic: deliberately pinning an agent override EQUAL to the persona's current value no longer sticks — it is treated as inherited, consistent with refresh semantics. Deploy path was already live-merging and is unchanged; backend now also matches the edit dialog's model (agent.envVars = overrides + inheritedEnvVars from live persona). Co-authored-by: Pinky <44b8e82baa6e0e254e0208d68f335c283c94e7b78dd1fa10d5a49d3f13dd0435@sprout-oss.stage.blox.sqprod.co> Signed-off-by: Wes <wesbillman@users.noreply.github.com>
Review (Brain) — pre-agreed cross-review, recorded as a comment (same authed account as merge-queue operator)Verdict: APPROVE — contingent only on CI settling green. Reviewed Pins
Invariant verification
Tests witness the lifecycle, not the code
Non-blocking observation
Coherence bonus confirmed: spawn_hash and readiness now see the same merged view by construction, so a persona env edit flips the restart-required badge — the exact trigger for the respawn refresh Wes decided on. |
#1640 persona-env-vars-refresh rebase added live-persona env merge path changes that grew readiness.rs by 4 lines beyond the existing override. Availability-classification growth, not generic debt. Co-authored-by: Will Pfleger <pfleger.will@gmail.com> Signed-off-by: Will Pfleger <pfleger.will@gmail.com>
Defect
Persona env-var edits never reach existing agents. Prompt/model/provider already refresh on respawn via the spawn-path re-snapshot, but env vars were baked into
record.env_varsat create (persona env merged under agent overrides) and then re-baked on every spawn/restore — so an edited persona credential stayed shadowed by its own stale copy forever. A one-line create fix would demo as fixed and silently regress after the first restart, because the preflight/restore re-bake regenerates the bug.Fix:
record.env_vars= agent overrides only, everywhereMerge the live persona env underneath at read time — the same semantics the provider deploy path already had, and the same model the edit dialog already shows (
agent.envVars= overrides +inheritedEnvVarsfrom the live persona):commands/agents.rs): seedrecord.env_varsfrominput.env_varsonly.snapshot.env_vars; prompt/model/provider/source_version writes unchanged.resolve_effective_agent_envlayer 3 (readiness.rs): merge live persona env under overrides — one fix covers the readiness gate, the setup payload, and the spawn-hash digest (the fn already tookpersonas; the empty map was the slot). Persona env edits now flip the restart-required badge, which is what drives the respawn refresh.runtime.rs): same live merge (reserved/malformed-key filtering unchanged, agent wins on collision).PersonaSnapshotloses itsenv_varsfield — env is never snapshotted, so the invariant can't silently regress.Migration self-heal (existing agents)
Pre-fix records have persona env baked in as pseudo-overrides. At the spawn/restore re-snapshot, for persona-linked records only:
An override identical to the persona's current value is indistinguishable from inheritance, so it's reclassified as inherited. Idempotent and progressive — existing agents benefit on their next start, no data migration.
Known semantic (deliberate): pinning an agent override equal to the persona's current value no longer sticks — it's treated as inherited. Contrary pins (different value) stick exactly as before. This is consistent with refresh semantics.
Non-goals
No UI changes, no e2e/spec changes, no deploy-path changes (already live-merging; stale comments fixed).
Validation
just desktop-tauri-checkclean,desktop-tauri-clippyclean (-D warnings),cargo fmtappliedjust desktop-tauri-test: 1053 passed, 0 failedruntime/tests.rsto witness the new lifecycle: create keeps overrides-only + credential reaches spawn via live merge, restart picks up an edited credential, agent override wins on collision, orphaned persona degrades to own overrides, self-heal drops baked-in values but keeps genuine overrides, drift badge semantics unchanged.Review pins from Brain (pre-agreed in-channel): retain() runs only for persona-linked records ✅; equal-pin semantic disclosed above ✅.