RUL-042 — Delegated work runs on Hermes, DeepSeek provider, deepseek-v4-pro

Ruling

Mohamed, 2026-10-24, verbatim, twice:

"no sonnet, just use deepseek provider and deepseek 4 pro" (to kimi, 05:29 EDT)

"remember our flow hermes and deepseek p[rovider and deepseek version 4, for god's sake document the workflow, you are the reason kimmy was confused and messing up because of yyour lack of rigor" (to the host Claude, 12:08 EDT)

Every delegated task, meaning code, tests, scripts, units, data or diagnosis that a coordinator hands to a worker, runs on one route:

Field Value
Harness Hermes, deployed at /opt/hermes, through hermes-task (CLI), the hermes_run MCP tool, or the hermes agent type
Provider deepseek, the DeepSeek API direct (key DEEPSEEK_API_KEY). Not OpenRouter. The default. Or minimax (amendment below)
Model deepseek-v4-pro. --executor deepseek-pro selects the same pair. On minimax: MiniMax-M3.1-Flash (provider default) or MiniMax-M3

Amendment 2026-10-30: MiniMax allowed

Mohamed, 2026-10-30, verbatim: "yes allowed all the time, deepseek can remain default".

Nothing else is used for delegated work unless Mohamed names it for that task:

Why

On 2026-10-24 kimi coordinated a full day of components work. It was told "no sonnet, just use deepseek provider and deepseek 4 pro" at 05:29 and still dispatched a Sonnet run, because the written workflow offered three delegation paths. The wiki workflow page listed Sonnet builders, Hermes on Qwen or DeepSeek, and pi-task. RUL-026 said Sonnet is the default. dispatch/templates/routing.md said qwen, deepseek-flash or sonnet. The host Claude then read the same documents and made the same mistake the same day: it read kimi's 05:29 instruction and still dispatched kimi-capture-1 and kimi-capture-1b on Sonnet and kimi-capture-units2 on deepseek-flash. A ruling that lives only in one conversation is lost at the next session, and contradicting documents win by default.

The flow, step by step

The coordinator (host Claude or kimi, flagship model, RUL-041: writes no code) does steps 1, 2, 4 and 5. Hermes does step 3.

  1. Worktree. Create a provisioned wt-<NAME> off origin/master, from a master worktree: cd ~/workspace/wt-INTEGRATION && env -u PYTHONPATH -u VIRTUAL_ENV -u ORCHESTRATA_ROOT .venv/bin/python scripts/worktrees.py create <name> --base origin/master. Run direnv allow ~/workspace/wt-<NAME> once; its .envrc is the committed one.

  2. Brief. A committed plans/briefs/<name>.md in that worktree. It contains:

    • goal, ruling/context, inputs, binding design, work, rules;
    • a ```files block, the write allowlist (Hermes's guard refuses writes outside it, and the after-run diff fails the run on any OUTSIDE BRIEF path);
    • a ```checks block of EXPECT :: CMD lines. The harness runs them after the run and writes verdict.json; the model's claims never set the verdict;
    • a ```env block, compulsory (ADR-0148): venv:, files:, set:, secrets: (names only), import:. The agent and every check run in exactly that environment, the preflight proves it before the model starts, and <run>/env.json records it. An orchestrata worktree declares venv: .venv, files: env/test.env env/toolchain.env env/ast-roots.env, set: UV_NO_EDITABLE=1, secrets: none, import: orchestrata_ultimate. A check with env -u, env -i, unset or direnv exec is refused.

    Claude Code's hooks do not run inside Hermes, so a brief that changes .py carries ruff, black, trace-lint and the module's tests (with the live-observer plugin) in its checks. Context comes from a generated context pack (exact source via code_map.py / serialize_codebase_ast.py source), never from "go explore". Session content (kimi or Claude transcripts) never goes into a brief; agents read conversation history from the KG.

  3. Dispatch:

    hermes-task run --cwd ~/workspace/wt-<NAME> --provider deepseek --model deepseek-v4-pro \
      --brief ~/workspace/wt-<NAME>/plans/briefs/<name>.md --name <run> --detach
    

    Add --budget USD (wrap-up at 80%, stop at 100%), --min-credit USD and --timeout S (Hermes wraps up at 80%) as the task warrants. These are the flags hermes-task run --help lists, checked 2026-10-24. Watch with hermes-task status and hermes-task peek <run> (exit 3 means something is OUTSIDE BRIEF) at least every 10 minutes. Never wait blind.

  4. Verify. Read /opt/hermes/runs/<run-id>/verdict.json and result.json. Check answered_by: the provider must be deepseek and the model deepseek-v4-pro, or (since 2026-10-30) minimax and the MiniMax model the run asked for; fell_back: true means the OpenRouter fallback answered, and that is reported. Re-run the checks yourself only when a check is red, or when the worktree changed after the verdict (git status differs from the run's git-status-end.txt); a green harness verdict on an unchanged tree stands, because the harness ran the checks and the model's claims never set it (amended 2026-10-28, Mohamed: "Re-run only on red (Recommended)", cycle-cost plan P15 C7 in codetools plans/gates-delivery-plan-2026-10-28.md). Always read the diff and review the code for the properties tests miss (cost, I/O, idle behaviour). A defect goes back as a new fix brief on the same route, never as a hand edit.

  5. Land. git commit --only -- <files from the files block>, with no AI attribution. Then git fetch && git rebase origin/master, deploy/ship.sh --dry-run, deploy/ship.sh in the background, post-deploy verification, and worktree removal (worktrees.py gc --target origin/master --apply for merge-commit landings, by hand for fast-forward).

Supersedes

Enforcement

Mechanism (RUL-014)

Judgment-only at recording time. Owed: a user-level PreToolUse guard that refuses, in orchestrata checkouts:

The guard is code, so it is built on this route from a brief.

Verification

jq -r '.answered_by[] | "\(.provider) \(.model)"' /opt/hermes/runs/*/result.json | sort | uniq -c

After 2026-10-24 12:10 EDT, every orchestrata delegated run shows deepseek deepseek-v4-pro. After 2026-10-30, minimax MiniMax-M3.1-Flash or minimax MiniMax-M3 is also correct.