fix(cli): preserve one-shot isolation flags - #51797
Conversation
f7ecd5c to
15cd7f5
Compare
ec1ffb3 to
95e674a
Compare
Top-level one-shot mode bypasses the chat command path, so safe-mode, ignore-user-config, and ignore-rules must be applied before plugin, MCP, shell-hook, and config startup side effects. Honor HERMES_IGNORE_USER_CONFIG in load_config() itself so one-shot and chat share the same configuration boundary, and keep ignore-rules threaded into AIAgent so context files and memory stay disabled. Constraint: Top-level -z intentionally bypasses cli.py for clean stdout output Constraint: --safe-mode and --ignore-user-config must affect startup discovery before load_config() consumers run Rejected: Handle user-config isolation only inside oneshot | load_config() is the shared boundary used by MCP, shell hooks, plugins, and startup config reads Rejected: Split ignore-user-config and ignore-rules env helpers | one startup helper better preserves ordering while keeping _apply_safe_mode(args) intact Confidence: high Scope-risk: moderate Directive: Keep top-level oneshot, Termux fast-path, and chat startup isolation env setup in sync Tested: scripts/run_tests.sh tests/hermes_cli/test_ignore_user_config_flags.py tests/hermes_cli/test_safe_mode.py tests/hermes_cli/test_tui_resume_flow.py tests/hermes_cli/test_config_env_expansion.py tests/hermes_cli/test_managed_scope_config.py tests/hermes_cli/test_managed_scope_regression.py tests/hermes_cli/test_mcp_startup.py Tested: venv/bin/python -m ruff check hermes_cli/main.py hermes_cli/config.py hermes_cli/oneshot.py tests/hermes_cli/test_ignore_user_config_flags.py tests/hermes_cli/test_safe_mode.py tests/hermes_cli/test_tui_resume_flow.py Tested: git diff --check Not-tested: Full scripts/run_tests.sh pass after the final load_config() adjustment
95e674a to
0cdd6c7
Compare
|
Thanks for the focused isolation fix. Static review confirms the premise remains present on current main: top-level one-shot dispatch does not forward isolation state ( The PR's changes target those exact gaps, including separate isolated config-cache state, without adding model-tool surface or altering conversation context mid-session. Automated hermes-sweeper review. |
GottZ
left a comment
There was a problem hiding this comment.
This was generated by AI during triage.
Summary
Two open PRs address the same one-shot isolation gap: user config and rules/memory isolation flags not reaching the embedded agent when invoked via top-level -z/--safe-mode. #51797 (+308/-22) fixes the gap at all three levels named in the root cause — top-level dispatch (main.py), config loader (config.py), and oneshot agent construction (oneshot.py). #73005 (+216/-5) only touches the config-loader and oneshot layers, leaving the top-level dispatch chokepoint untouched.
Related pull requests
- #51797
related— (+308/-22) — keep_open (contributor teknium1, 7327 commits): diff adds_apply_isolation_env()as a chokepoint called from bothcmd_chatand_prepare_agent_startup, so top-level-z/--safe-modesets isolation env vars before plugin/tool discovery; also adds a sentinel cache signature inload_config()forHERMES_IGNORE_USER_CONFIGand threads an explicitignore_rulesparameter throughrun_oneshot/_run_agentintoAIAgent(skip_context_files=, skip_memory=). Reviewer's static check against current main confirmed all three cited gaps (main.py:14737,oneshot.py:393,config.py:6953) are real and are exactly what this diff closes. - #73005
duplicate— (+216/-5) — no review verdict recorded: diff introduces a sharedshould_ignore_user_config()helper used bycli.py'sload_cli_config()and by_load_config_impl(settinguser_sig=Noneinstead of a sentinel signature), and hasoneshot._run_agentreadHERMES_IGNORE_RULESdirectly from the env rather than via a passed parameter. It does not modifymain.py, so it does not fix the top-level dispatch gap that #51797's reviewer confirmed is still present on current main — meaning-zinvocations that never set the env vars in the first place would still leak user config/rules under this PR alone.
Duplicates
#51797 and #73005 both fix the same root cause (isolation flags not reaching load_config()/AIAgent in the one-shot -z path) with overlapping changes to hermes_cli/config.py and hermes_cli/oneshot.py, but #73005 lacks the main.py top-level dispatch fix that #51797 includes.
Suggested consolidation
merge #51797 — the keep_open review from teknium1 (contributor, 7327 commits) verified against current main that its diff closes all three root-cause gaps, including the top-level dispatch chokepoint in main.py that #73005 does not touch. #73005 can be closed as superseded by #51797: it duplicates the config.py/oneshot.py portion of the fix but is incomplete without the main.py change, so merging it alone would not fully resolve the reported issue.
Complex graph
flowchart LR
classDef open fill:#dbeafe,stroke:#1d4ed8,color:#1e3a8a
classDef merged fill:#dcfce7,stroke:#15803d,color:#14532d
classDef closed fill:#e5e7eb,stroke:#6b7280,color:#1f2937
classDef unverified fill:#f3f4f6,stroke:#9ca3af,color:#374151
classDef best stroke-width:3px,stroke:#b45309
classDef target stroke-width:3px,stroke:#4338ca
subgraph Dup51797 ["PRs duplicating each other"]
P51797["PR #51797 (open)"]
P73005["PR #73005 (open)"]
end
class P51797 open
class P73005 open
class P51797 target
click P51797 "https://github.com/NousResearch/hermes-agent/pull/51797"
click P73005 "https://github.com/NousResearch/hermes-agent/pull/73005"
Graph: solid arrow = fixes / best fix, dashed arrow = partial or unverified (see edge label); boxed group = PRs duplicating each other; amber border = best fix; indigo border = target; gray node = closed or no verify verdict yet (state tag in the node label).
Cross-PR triage: Reviewed 2 pull requests and 0 issues in this complex. Each diff was read against this issue; Assessment working set: 30 kB of PR diffs, 4 kB of issue/PR text, <1 kB of discussion (1 comments), 1 verify verdict. verdicts reflect diff content, not PR titles. Part of an automated triage batch.
Resolve conflicts by preserving current one-shot cleanup/startup wrappers and reapplying ignore-rules/user-config propagation plus regression coverage.
Summary
_apply_safe_mode(args)as the safe-mode helper.hermes_cli.config.load_config()honorHERMES_IGNORE_USER_CONFIG=1, skipping the userconfig.yamlwhile preserving built-in defaults and managed-scope config.ignore_rulesinto the one-shot runner soAIAgentskips context files and persistent memory for--ignore-rules/--safe-mode.-z --usage-filesupport while adding the new isolation plumbing.--safe-mode -z, direct one-shotignore_rules, config-loader user-config isolation, and startup env ordering.Root Cause
Top-level
-zbypassed thecmd_chatpath where isolation environment variables were set. The one-shot runner also constructedAIAgentwithoutskip_context_files/skip_memory, soAGENTS.mdcould still be loaded even when the user requested--ignore-rulesor--safe-mode.After #45300, another related gap remained:
HERMES_IGNORE_USER_CONFIGwas honored bycli.load_cli_config(), the interactivecli.pyloader path, but not by the sharedhermes_cli.config.load_config()loader used by startup discovery, MCP, shell hooks, and other config consumers. This PR moves that boundary intoload_config()and uses a cache signature sentinel so normal and isolated loads do not reuse each other's cached config.Rebase Notes
origin/main(240afd0b70a016ba17568d597e0f2c32f94f4cfd) and resolved conflicts.requested_providerwiring._apply_safe_mode(args)intact._apply_isolation_env(args)so startup call sites have a single ordering-sensitive helper.usage_filein therun_oneshot()signature and dispatch calls.Test Plan
scripts/run_tests.sh tests/hermes_cli/test_tui_resume_flow.py tests/hermes_cli/test_safe_mode.py tests/hermes_cli/test_ignore_user_config_flags.py tests/hermes_cli/test_config_env_expansion.py tests/hermes_cli/test_managed_scope_config.py tests/hermes_cli/test_managed_scope_regression.py tests/hermes_cli/test_mcp_startup.py(37 passed)venv/bin/python -m ruff check hermes_cli/main.py hermes_cli/oneshot.py hermes_cli/config.py tests/hermes_cli/test_tui_resume_flow.py tests/hermes_cli/test_safe_mode.py tests/hermes_cli/test_ignore_user_config_flags.pygit diff --cached --check -- hermes_cli/main.py hermes_cli/oneshot.py hermes_cli/config.py tests/hermes_cli/test_tui_resume_flow.py tests/hermes_cli/test_safe_mode.py tests/hermes_cli/test_ignore_user_config_flags.py