fix(memory/byterover): brv child carries the served profile's cloud key, never the launch profile's

Under gateway.multiplex_profiles os.environ holds the default profile's .env, so `_run_brv`
building the child env from raw os.environ curated a secondary profile's turns into the DEFAULT
profile's ByteRover cloud account (and prefetched the default's memories into the secondary's
context). The local half was already profile-scoped (`_get_brv_cwd`).

The child env now comes from `build_subprocess_env` and, under multiplex, strips the launch
profile's residue and sets BRV_API_KEY only from the served profile's secret scope — a miss means
no cloud key. Single-profile installs pass the process env through unchanged.

Closes #108993 (report and fix direction by @jonpol01).
This commit is contained in:
teknium1
2026-09-13 13:22:01 -07:00
committed by Teknium
parent 9e6a8645ea
commit 732504c8d6
2 changed files with 103 additions and 1 deletions
+26 -1
View File
@@ -76,6 +76,31 @@ def _resolve_brv_path() -> Optional[str]:
return _cached_brv_path or None
def _brv_child_env(brv_path: str) -> Dict[str, str]:
"""Env for the ``brv`` child. Under gateway.multiplex_profiles ``os.environ`` holds the
LAUNCH profile's ``.env``; the served profile's ``BRV_*`` (cloud identity) live only in its
secret scope, so they are resolved through the scope — a miss means no cloud key, never
another profile's — and the launch profile's ``.env`` residue is stripped. Outside multiplex
the process env IS this profile's own and is passed through unchanged."""
from agent.secret_scope import UnscopedSecretError, get_secret, is_multiplex_active
from hermes_constants import get_hermes_home_override
from tools.environments.local import build_subprocess_env, strip_launch_profile_env
env = build_subprocess_env(scrub_secrets=False)
if is_multiplex_active():
env = strip_launch_profile_env(env, get_hermes_home_override())
for key in [k for k in env if k.startswith("BRV_")]:
env.pop(key, None)
try:
api_key = get_secret("BRV_API_KEY", "")
except UnscopedSecretError:
api_key = ""
if api_key:
env["BRV_API_KEY"] = api_key
env["PATH"] = str(Path(brv_path).parent) + os.pathsep + env.get("PATH", "")
return env
def _run_brv(args: List[str], timeout: int = _QUERY_TIMEOUT, cwd: str = None) -> dict:
"""Run a brv CLI command. Returns {success, output, error}."""
global _cached_brv_path
@@ -84,7 +109,7 @@ def _run_brv(args: List[str], timeout: int = _QUERY_TIMEOUT, cwd: str = None) ->
return {"success": False, "error": "brv CLI not found. Install: npm install -g byterover-cli"}
effective_cwd = cwd or str(_get_brv_cwd())
Path(effective_cwd).mkdir(parents=True, exist_ok=True)
env = {**os.environ, "PATH": str(Path(brv_path).parent) + os.pathsep + os.environ.get("PATH", "")}
env = _brv_child_env(brv_path)
try:
result = subprocess.run(
[brv_path] + args, capture_output=True, text=True, encoding='utf-8', errors='replace',