refactor(cron): reuse _install_fire_secret_scope for the external-worker env build

_launch_external_cron_worker hand-rolled the same hydrate -> set_secret_scope ->
set_multiplex_context(routed) sequence, and the same context-then-scope reset, that
_install_fire_secret_scope/_reset_fire_secret_scope already encode for the in-process
fire. Two copies of the ordering is how the two paths drift apart; the helper is the
one place that owns it. The only observable difference (re-setting an already-active
multiplex context for the span) is a no-op the token reset undoes.

Rename _scope_token in _run_one_job_body to _fire_scope_tokens: it has held the helper's
(scope, context) tuple since the routed-fire change, not a single token.
This commit is contained in:
kshitijk4poor
2026-09-15 00:57:53 +05:30
committed by kshitij
parent dcdbcb8a2b
commit 840c00c124
+9 -19
View File
@@ -2904,7 +2904,7 @@ def _run_one_job_body(
delivery_attempted = False
delivery_error = None
_scope_token = None
_fire_scope_tokens = None
_terminal_scope_token = None
try:
# Commit a finite one-shot's dispatch BEFORE its side effect so a tick dying mid-run cannot
@@ -2930,7 +2930,7 @@ def _run_one_job_body(
# get_secret() fails closed outside a scope; the ticker thread has none. Delivery adapters
# resolve credentials, so the scope must span delivery too (reset in the outer finally).
_scope_token = _install_fire_secret_scope()
_fire_scope_tokens = _install_fire_secret_scope()
# Same for terminal policy (gateway/run.py _profile_runtime_scope): else the ticker reads
# process-global TERMINAL_* env a concurrent profile pinned. Resolution failure installs a
# refusal scope — terminal execution raises instead of using the launch process's policy.
@@ -3069,8 +3069,8 @@ def _run_one_job_body(
finally:
# Function-level on purpose: must scope delivery, deferred teardown, claim-loss handling and
# bookkeeping — not just run_job. Do not move into the run block's finally.
if _scope_token is not None:
_reset_fire_secret_scope(_scope_token)
if _fire_scope_tokens is not None:
_reset_fire_secret_scope(_fire_scope_tokens)
if _terminal_scope_token is not None:
from tools.terminal_scope import reset_terminal_scope
@@ -3177,16 +3177,8 @@ def _launch_external_cron_worker(job: dict) -> bool:
str(ack_path),
]
from agent.secret_scope import (
build_profile_secret_scope,
is_multiplex_active,
reset_multiplex_context,
reset_secret_scope,
set_multiplex_context,
set_secret_scope,
)
from agent.secret_scope import is_multiplex_active
from cron.scheduler_provider import routed_profile_fire
from hermes_cli.env_loader import hydrate_profile_secret_sources
from tools.environments.local import build_subprocess_env, strip_launch_profile_env
from tools.process_registry import (
restart_safe_gateway_child_argv,
@@ -3240,9 +3232,9 @@ def _launch_external_cron_worker(job: dict) -> bool:
raise
profile_home = _get_hermes_home().resolve()
hydrate_profile_secret_sources(profile_home)
secret_token = set_secret_scope(build_profile_secret_scope(profile_home))
context_token = set_multiplex_context(True) if multiplex_active and not is_multiplex_active() else None
# Same hydrate -> scope -> (routed) multiplex-context install the in-process fire uses, for exactly
# the env build; the helper's reset order keeps the context from outliving its scope.
fire_scope_tokens = _install_fire_secret_scope()
try:
# No restore_managed_env here: the worker re-runs load_hermes_dotenv -> _apply_managed_env at
# import, and strip_launch_profile_env leaves managed keys in place.
@@ -3252,9 +3244,7 @@ def _launch_external_cron_worker(job: dict) -> bool:
extra={"HERMES_HOME": str(profile_home)},
))
finally:
if context_token is not None:
reset_multiplex_context(context_token)
reset_secret_scope(secret_token)
_reset_fire_secret_scope(fire_scope_tokens)
worker_env = systemd_user_bus_env(worker_env)
try:
process = subprocess.Popen(