You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Clearing DAEMON_CLAUDE_SETTINGS / DAEMON_CLAUDE_EFFORT on a plain spawn (PR #35, commit d27fbcc, and its review/land companion #37) stops the dispatcher
from recording the gateway — it does not stop the spawned worker from using
it. When a dispatcher runs inside a gateway-routed daemon, the clodex settings
file has already placed the gateway's transport variables into that session's
environment, and every Bash subprocess inherits them, including the claude --bg that daemon-spawn launches for a "plain" worker.
Verified on this machine: ~/.claude/clodex-settings.json is a settings file
whose only top-level key is env, carrying
Consequence: a plain-route worker spawned from inside a gateway session routes
its first turn through localhost:8317 while no gateway metadata is
persisted in the registry meta — so when the sweep later resumes it, daemon-resume.sh restores nothing and the same daemon silently changes model
provider mid-life. That is strictly more confusing than the #35/#37 leak, which
at least stayed on the gateway consistently.
Found by the review engine on PR #35 (round 2, P1) and confirmed by the reviewer
against the real settings file. Not fixed in #35: the fix is a design decision,
not a mechanical edit (see below), and #35's ticket was scoped to a one-line
default flip.
Constraints
The gateway's variable set is not repo-owned. It lives in a user-local
settings file ($CLODEX_SETTINGS, default ~/.claude/clodex-settings.json)
whose env keys can change without any repo change. A hardcoded unset-list in
the dispatchers would be wrong the moment that file gains a key — so
"just add env -u ANTHROPIC_BASE_URL …" is not an acceptable fix on its own.
Whatever lands must keep the gateway route working unchanged, and must not
require a dispatcher to parse secrets out of the settings file into its own
argv or logs (ANTHROPIC_AUTH_TOKEN is in there).
Affects all three dispatchers (implement, review, land) and any future daemon-spawn.sh caller, so a per-dispatcher fix repeats the bug by
construction. Prefer one place.
Success criteria
A plain-route worker spawned from inside a gateway-routed session talks to the
normal Anthropic endpoint, not the gateway — demonstrated, not argued.
A gateway-route worker still reaches the gateway, and still survives a resume
on it (the existing persistence contract in daemon-spawn.sh / daemon-resume.sh keeps working).
No daemon can silently change model provider between its first turn and a
later resumed turn.
A test pins the plain case against an ambient gateway environment.
Open questions
Where does "route" become explicit? Recommended direction, carried over
from the PR feat(implement): default model route flips clodex → claude (C6) #35 fixer's own out-of-scope note: give daemon-spawn.sh an
explicit route input (a --no-gateway flag, or a required route argument)
instead of inferring "plain" from the absence of env. Then the substrate — the
one place that knows it is launching a claude process — owns clearing the
gateway's environment, and every caller becomes correct by construction. The
substrate can derive the key list from the settings file it was handed
(unset exactly the env keys that file declares) rather than from a hardcoded
list, which also satisfies the constraint above.
Alternative worth pricing: never inherit at all — have daemon-spawn.sh build
the child environment allowlist-style rather than by mutation. Cleaner
invariant, larger blast radius; needs its own gate.
Does the same inheritance affect the review ENGINE call
(review-engine.sh → nested codex exec)? It already isolates CODEX_HOME
and sets SSL_CERT_FILE, but it does not clear ANTHROPIC_*. Probably
irrelevant (codex does not read ANTHROPIC_*) — confirm rather than assume.
Problem & intent
Clearing
DAEMON_CLAUDE_SETTINGS/DAEMON_CLAUDE_EFFORTon a plain spawn (PR#35, commit
d27fbcc, and its review/land companion #37) stops the dispatcherfrom recording the gateway — it does not stop the spawned worker from using
it. When a dispatcher runs inside a gateway-routed daemon, the clodex settings
file has already placed the gateway's transport variables into that session's
environment, and every Bash subprocess inherits them, including the
claude --bgthat daemon-spawn launches for a "plain" worker.Verified on this machine:
~/.claude/clodex-settings.jsonis a settings filewhose only top-level key is
env, carryingConsequence: a plain-route worker spawned from inside a gateway session routes
its first turn through
localhost:8317while no gateway metadata ispersisted in the registry meta — so when the sweep later resumes it,
daemon-resume.shrestores nothing and the same daemon silently changes modelprovider mid-life. That is strictly more confusing than the #35/#37 leak, which
at least stayed on the gateway consistently.
Found by the review engine on PR #35 (round 2, P1) and confirmed by the reviewer
against the real settings file. Not fixed in #35: the fix is a design decision,
not a mechanical edit (see below), and #35's ticket was scoped to a one-line
default flip.
Constraints
settings file (
$CLODEX_SETTINGS, default~/.claude/clodex-settings.json)whose
envkeys can change without any repo change. A hardcoded unset-list inthe dispatchers would be wrong the moment that file gains a key — so
"just add
env -u ANTHROPIC_BASE_URL …" is not an acceptable fix on its own.require a dispatcher to parse secrets out of the settings file into its own
argv or logs (
ANTHROPIC_AUTH_TOKENis in there).daemon-spawn.shcaller, so a per-dispatcher fix repeats the bug byconstruction. Prefer one place.
Success criteria
normal Anthropic endpoint, not the gateway — demonstrated, not argued.
on it (the existing persistence contract in
daemon-spawn.sh/daemon-resume.shkeeps working).later resumed turn.
Open questions
from the PR feat(implement): default model route flips clodex → claude (C6) #35 fixer's own out-of-scope note: give
daemon-spawn.shanexplicit route input (a
--no-gatewayflag, or a required route argument)instead of inferring "plain" from the absence of env. Then the substrate — the
one place that knows it is launching a
claudeprocess — owns clearing thegateway's environment, and every caller becomes correct by construction. The
substrate can derive the key list from the settings file it was handed
(unset exactly the
envkeys that file declares) rather than from a hardcodedlist, which also satisfies the constraint above.
daemon-spawn.shbuildthe child environment allowlist-style rather than by mutation. Cleaner
invariant, larger blast radius; needs its own gate.
(
review-engine.sh→ nestedcodex exec)? It already isolatesCODEX_HOMEand sets
SSL_CERT_FILE, but it does not clearANTHROPIC_*. Probablyirrelevant (codex does not read
ANTHROPIC_*) — confirm rather than assume.Decision log
PR: the reviewer judged it a design fork (the correct fix changes the substrate
spawn contract and touches every caller), which the review protocol routes to a
new ticket instead of a fix wave.
DAEMON_CLAUDE_*hygiene fixfor review/land) because review/land dispatchers leak an ambient gateway env onto the plain claude route #37 is small, safe, and unblocks C5: review-loop worker default route clodex → claude + plumbing removal #32 now, whereas this
one needs a design decision first. review/land dispatchers leak an ambient gateway env onto the plain claude route #37 is not a prerequisite of this ticket and
neither blocks the other; if this lands first in the substrate, review/land dispatchers leak an ambient gateway env onto the plain claude route #37 becomes
redundant rather than wrong.