feat(desktop): community-scoped env vars keyed by relay URL - #4101
Open
andydoucet wants to merge 1 commit into
Open
feat(desktop): community-scoped env vars keyed by relay URL#4101andydoucet wants to merge 1 commit into
andydoucet wants to merge 1 commit into
Conversation
Under agents-everywhere (block#2122) any managed-agent record may spawn into any community, so no existing env tier can carry a community-scoped secret: per-record/persona env_vars are identity-scoped and follow the agent into whichever community it spawns on, and global env_vars are one value for every community. Running two communities with separate memory-service accounts on one desktop, a restart cycle handed one community's API key to agents connected to the other community's relay. Add a location-scoped tier: GlobalAgentConfig.community_env_vars, a map of relay URL -> env map, injected at the single descriptor resolver keyed by the effective spawn relay. Layering: baked floor < runtime metadata < definition < global < community < persona < per-agent. Same reserved / derived / malformed key rules as every other tier; validation errors name the offending community. spawn_config_hash resolves the same relay as the spawn path so community edits mark affected running agents needs_restart, and set_global_agent_config diffs old vs new env under each live pair's relay so the existing auto-restart flow picks them up. Relay-agnostic model probes resolve without the community layer. The TS GlobalAgentConfig mirrors the field so UI round-trips don't drop it; no editor UI yet - the config file is the interface. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Signed-off-by: Andrew Doucet <65342358+illumin8ca@users.noreply.github.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
Adds a community-scoped env tier to the global agent config:
community_env_vars, a map of relay URL → env map, injected only into agents spawned for that community's effective relay.Layering (low → high):
baked floor < runtime metadata < definition < global < community < persona < per-agent— a community entry is a more specific global default; identity-scoped layers still win on collision.Why
Under agents-everywhere (#2122) any record may spawn into any community, so no existing env tier can carry a community-scoped secret:
env_varsare identity-scoped — they follow the agent into whichever community it spawns on (and [Bug] Desktop: agent settings edits always target one community's instance - per-community agent config (env vars) unreachable from the UI #2717 makes per-instance targeting from the UI unreliable anyway);env_varsare one value for every community.Running two communities with separate memory-service accounts on one desktop, a restart cycle handed one community's API key to agents connected to the other community's relay — a silent cross-tenant credential leak. The only always-truthful community signal is the effective spawn relay, so that's what this tier keys on. Closes #4099 and covers #2717's motivating use case (
CLAUDE_CONFIG_DIRper community) without needing per-instance UI targeting.How
GlobalAgentConfiggains#[serde(default)] community_env_vars: BTreeMap<String, BTreeMap<String, String>>plus save-time validation (same POSIX/reserved/derived-key rules as the global map, errors prefixed with the offending relay), empty-value stripping, and acommunity_env_for()lookup with trailing-slash/whitespace normalization — exact match only, no host heuristics.resolve_effective_harness_descriptor/resolve_effective_agent_envtake a newrelay_url: Option<&str>and inject the community layer between global and persona. Threaded through:spawn_agent_child— the pair's effective relay (the layer lands in real spawns);spawn_config_hash— same relay resolution as spawn, so editing a community's vars marks that community's running agentsneeds_restartand the existingset_global_agent_configauto-restart flow picks them up;None(community layer intentionally absent).set_global_agent_configrestart candidates diff old vs new env under the live pair's relay, so community edits restart exactly the affected agents.GlobalAgentConfigmirrors the field (and the empty-config constants include it) so UI round-trips don't drop it. No editor UI yet — the config file is the interface, same as several other advanced fields; a Settings editor can follow.Tests
global_config/tests.rs: validation (accepts valid maps; rejects reserved keys, derived provider/model keys, blank relay keys — errors name the community), strip-on-save (empty values and all-empty communities dropped), lookup normalization (trailing slash both directions, no cross-community match, blank relay never matches), full layering precedence (community overrides global, loses to per-agent; other relay andNoneget no community layer), and resolve-time reserved-key stripping for hand-edited config files.Full desktop lib suite passes locally (macOS): 2096 passed, 0 failed.
cargo fmt --checkclean.Related
No open PRs touch community/relay-scoped env handling ("none found" per CONTRIBUTING).
🤖 Generated with Claude Code