# NousResearch/hermes-agent · delegate_task not honoring delegation configuration settings

## Open now

- Nothing open on GitHub.

The members concern delegate_task apparently not respecting delegation config: one issue reports it as hardcoded to xiaomi, and two pull requests propose making the active config authoritative for limits and merging persistent and runtime config sources. Details beyond the titles are not shown, so the exact relationship between them is unconfirmed.

## TL;DR

- 3 member(s): 0 open issue(s), 1 closed issue(s), 0 open PR(s), 1 merged PR(s), 1 PR(s) closed without merging.
- A fix was merged to main in PR #60577. Verify it addresses your case.
- **Recommended:** read PR #60577 (and any competing PRs below) before filing. Confirm the merged change covers your symptom.

## Maintainer resolution verdict

- Internal-tracker verdict over this cluster's issue members: `unresolved`. This is distinct from the fix status above. Weigh it yourself.

## How this cluster was grouped

- Link evidence (`STRUCTURAL_SPANNING`): every member is connected by structural evidence: shared changed files, or a closing/superseded reference.
- Pairwise link density `0.67`: the share of member pairs that carry a link, counting a structural link in full and a relevance-only link at 0.36. `1.00` means every pair is linked.

## Closed / duplicate issues

- #55380: Bug: delegate_task ignores delegation config — hardcoded to xiaomi

## Prior & competing PRs

- **#60577: fix(delegation): make active config authoritative for delegation limits**. merged to main · fix tier `verified`
  - maintainer direction: category `merged`
  - files: `tests/tools/test_delegate.py`, `tools/delegate_tool.py`
  - fix hunks:
  - `tests/tools/test_delegate.py`

    ```diff
    @@ -13,6 +13,7 @@
     import os
     import threading
     import time
    +import types
     import unittest
     from unittest.mock import MagicMock, patch
     
    ```

    ```diff
    @@ -21,6 +22,7 @@
         DELEGATE_TASK_SCHEMA,
         DelegateEvent,
         _get_max_concurrent_children,
    +    _load_config,
         _LEGACY_EVENT_MAP,
         MAX_DEPTH,
         check_delegate_requirements,
    ```

    ```diff
    @@ -2390,6 +2392,71 @@ def test_progress_callback_task_progress_not_misrendered(self):
     class TestConcurrencyDefaults(unittest.TestCase):
         """Tests for the concurrency default and no hard ceiling."""
     
    +    def test_load_config_prefers_active_persistent_config_over_cli_defaults(self):
    +        stale_cli = types.ModuleType("cli")
    +        stale_cli.CLI_CONFIG = {
    +            "delegation": {
    +                "max_iterations": 45,
    +                "model": "",
    +                "provider": "",
    +                "base_url": "",
    +                "api_key": "",
    +            }
    +        }
    +        active_config = {
    +            "delegation": {
    +                "max_iterations": 50,
    +                "max_concurrent_children": 50,
    +                "max_spawn_depth": 10,
    +            }
    +        }
    +
    +        with patch.dict("sys.modules", {"cli": stale_cli}):
    +            with patch(
    +                "hermes_cli.config.load_config_readonly", return_value=active_config
    +            ):
    +                self.assertEqual(_load_config()["max_concurrent_children"], 50)
    +                self.assertEqual(_get_max_concurrent_children(), 50)
    +
    +    def test_load_config_falls_back_to_cli_config_when_persistent_load_fails(self):
    +        fallback_cli = types.ModuleType("cli")
    +        fallback_cli.CLI_CONFIG = {
    +            "delegation": {
    +                "max_iterations": 45,
    +                "max_concurrent_children": 8,
    +            }
    +        }
    +
    +        with patch.dict("sys.modules", {"cli": fallback_cli}):
    +            with patch(
    +                "hermes_cli.config.load_config_readonly",
    +                side_effect=RuntimeError("boom"),
    +            ):
    +                self.assertEqual(_load_config()["max_concurrent_children"], 8)
    +
    +    def test_load_config_prefers_cli_config_when_user_config_ignored(self):
    +        # `hermes chat --ignore-user-config` sets HERMES_IGNORE_USER_CONFIG=1,
    +        # which only load_cli_config() honors. The delegation loader must keep
    +        # CLI_CONFIG authoritative under the flag so user config.yaml
    +        # delegation keys stay suppressed.
    +        ignoring_cli = types.ModuleType("cli")
    +        ignoring_cli.CLI_CONFIG = {
    +            "delegation": {
    +                "max_iterations": 45,
    +                "max_concurrent_children": 4,
    +            }
    +        }
    +        user_config = {"delegation": {"max_concurrent_children": 50}}
    +
    +        with patch.dict("sys.modules", {"cli": ignoring_cli}):
    +            with patch.dict(os.environ, {"HERMES_IGNORE_USER_CONFIG": "1"}):
    +                with patch(
    +                    "hermes_cli.config.load_config_readonly",
    +                    return_value=user_config,
    +                ) as mock_loader:
    +                    self.assertEqual(_load_config()["max_concurrent_children"], 4)
    +                    mock_loader.assert_not_called()
    +
         @patch("tools.delegate_tool._load_config", return_value={})
         def test_default_is_three(self, mock_cfg):
             # Clear env var if set
    ```
  - `tools/delegate_tool.py`

    ```diff
    @@ -3098,26 +3098,40 @@ def _resolve_delegation_credentials(cfg: dict, parent_agent) -> dict:
     
     
     def _load_config() -> dict:
    -    """Load delegation config from CLI_CONFIG or persistent config.
    -
    -    Checks the runtime config (cli.py CLI_CONFIG) first, then falls back
    -    to the persistent config (hermes_cli/config.py load_config()) so that
    -    ``delegation.model`` / ``delegation.provider`` are picked up regardless
    -    of the entry point (CLI, gateway, cron).
    +    """Load delegation config from the active Hermes config.
    +
    +    Prefer the shared persistent loader because it follows the active
    +    HERMES_HOME/profile. ``cli.CLI_CONFIG`` is a legacy fallback for entry
    +    points that cannot import the shared loader; importing it first can return
    +    an old default ``delegation`` block and hide user-set keys such as
    +    ``max_concurrent_children``.
    +
    +    Uses ``load_config_readonly()``: every consumer of this dict is read-only
    +    (``.get()`` lookups), and this runs on each ``get_definitions()`` schema
    +    rebuild via ``_get_max_concurrent_children``, so skipping the defensive
    +    deepcopy matters. Do NOT mutate the returned dict.
    +
    +    ``HERMES_IGNORE_USER_CONFIG=1`` (``hermes chat --ignore-user-config``) is
    +    only honored by the legacy ``cli`` loader, not the shared one, so when the
    +    flag is set we keep ``cli.CLI_CONFIG`` authoritative to preserve the
    +    flag's contract of suppressing user config.yaml settings.
         """
    +    prefer_legacy = os.environ.get("HERMES_IGNORE_USER_CONFIG") == "1"
    +    if not prefer_legacy:
    +        try:
    +            from hermes_cli.config import load_config_readonly
    +
    +            full = load_config_readonly()
    +            cfg = full.get("delegation") or {}
    +            if isinstance(cfg, dict):
    +                return cfg
    +        except Exception:
    +            pass
         try:
             from cli import CLI_CONFIG
     
             cfg = CLI_CONFIG.get("delegation") or {}
    -        if cfg:
    -            return cfg
    -    except Exception:
    -        pass
    -    try:
    -        from hermes_cli.config import load_config
    -
    -        full = load_config()
    -        return full.get("delegation") or {}
    +        return cfg if isinstance(cfg, dict) else {}
         except Exception:
             return {}
     
    ```
- **#55478: fix(delegate): merge persistent + runtime delegation config sources**. closed without merge
  - maintainer direction: category `implemented_elsewhere`; implication `superseded`; refs `#60577`, `#59982`

## Fix status

- Merged to main in PR #60577 (cited above). No release data is tracked. Verify downstream.
- Fix last verified (merged) `2026-07-08`.
- Subsystem: `agent`
