Conversation
…a safe parser The DSH_MODEL_CONTEXT bare int() the ticket names was already converted to _env_int by XERK-372 (commit 0e7f5fd, in main). This finishes the ticket's "grep for any other bare int(os.environ...) at module scope and convert them" step: the per-runtime sibling modules still parsed their own knobs with bare casts at import time — agent/dsh_session.py: DSH_ACK_TIMEOUT_SEC, DSH_CONNECT_TIMEOUT_SEC, DSH_LINE_MAX_BYTES, DSH_PROJECTION_POLL_SEC agent/qwen_session.py: QWEN_PROJECTION_POLL_SEC so a mistyped value crashes the dsh/qwen spawn that imports the module (a ValueError, NOT the ImportError the launch paths degrade on), violating the XERK-372 invariant documented in .claude/rules/agent.md. These are stdlib-only siblings that can't reach hub-agent's private _env_num, so the safe parser goes in runtime_tail.py — the XERK-528 "identical part once" home both already import — as env_num/env_int/env_float, mirroring hub-agent's copy (fall back + warn to stderr, clamp on minimum/maximum). Each sibling's except-ImportError branch keeps a default-returning stub so the degraded standalone import still never raises. The function-scoped casts in hooks/ask.py and qwen/ask_mcp.py already carry their own try/except ValueError and are left as-is. Tests: a junk *_CONTEXT env no longer crashes the hub-agent import (test_hub_agent TestEnvNumHelpers.test_context_knobs_survive_a_junk_value); the sibling knobs fall back on junk via a subprocess re-import (ModuleEnvKnobsTest in test_dsh_session / test_qwen_session); the shared helper itself in the new test_runtime_tail.py.
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 & why
XERK-523 reports that a BARE
int(os.environ.get(...))at module scope crashes the whole agent at import on a junk value — one mistyped*_CONTEXT(or itsLOCAL_MODEL_CONTEXTfallback) raisesValueErrorduring import, beforemain(), and since the native agent runs the file as its managed foreground process, it crash-loops the host with the symptom pointing nowhere near the cause.The headline line the ticket names (
DSH_MODEL_CONTEXTinagent/hub-agent.py) was already converted to the safe_env_inthelper by XERK-372 (commit0e7f5fd, inmain). This PR completes the ticket's second instruction — "grep for any other bareint(os.environ...)at module scope and convert them too" — for the remaining offenders in the stdlib-only runtime siblings thathub-agent.pyimports on a dsh/qwen launch:agent/dsh_session.pyDSH_ACK_TIMEOUT_SEC,DSH_CONNECT_TIMEOUT_SEC,DSH_LINE_MAX_BYTES,DSH_PROJECTION_POLL_SECagent/qwen_session.pyQWEN_PROJECTION_POLL_SECA junk value in any of these raised
ValueError(not theImportErrorthose launch paths degrade on), crashing the spawn — violating the XERK-372 invariant documented in.claude/rules/agent.md("Every numeric env knob at module scope goes through_env_int/_env_float, NEVER a bareint(os.environ.get(...))").How
_env_num, so the safe parser lands inagent/runtime_tail.py— the XERK-528 "identical part once" module both siblings already import — asenv_num/env_int/env_float, mirroring hub-agent's copy (fall back to a typed default + warn to stderr on junk; clamp onminimum/maximum; reject non-finite floats).except ImportErrorbranch gains default-returning stubs so a degraded standalone import (runtime_tail absent) still never raises.agent/hooks/ask.pyandagent/qwen/ask_mcp.pyalready carry their owntry/except ValueErrorand are left as-is (they run at call time, can't crash the import).No behavior change for any valid config value; the only change is junk → warn+default instead of crash.
How verified
unittest):agent/tests/test_runtime_tail.py(new, the shared helper);ModuleEnvKnobsTestintest_dsh_session.py/test_qwen_session.py(subprocess re-import with junk env → rc 0 + fallback);TestEnvNumHelpers.test_context_knobs_survive_a_junk_valueintest_hub_agent.py(the ticket's exactDSH_MODEL_CONTEXT=lots/LOCAL_MODEL_CONTEXT=lotsrepro).qaagent): PASS, no defects. Drove the real import-time behavior via subprocess reimport of all three files with hostile env (""," ",10m,"20",lots,nan,inf,1_0 00, 26-digit): all exit 0 with the documented defaults; valid values still apply; the degradedexcept ImportErrorpath stays importable (verified with runtime_tail removed fromsys.path). Mutation-testedruntime_tail.py(neutered the non-finite guard and the min clamp) — each produced a distinct failure, so the tests have teeth. Suites:test_runtime_tail+test_dsh_session+test_qwen_session= 59 pass;TestEnvNumHelpers= 10 pass.Scope: low-risk, bounded, agent-only; no hub/UI/container runtime surface.