#114175·hermes-agent

[Bug]: Desktop approval card hides the flag reason it already receives (shown only in the "Always allow" dialog)

Author: mofahqcCreated Sep 17, 2026Updated Sep 17, 2026
Labelstype/bugduplicateP2comp/desktop

What happens

On the desktop surface, the approval card renders only the text being approved — the raw command, or the whole Python script for an execute_code gate. The deterministic flag reason (description) is delivered to the client and is already mapped into the desktop ApprovalRequest, but the card never renders it; the only place it appears is inside the "Always allow" confirmation dialog. So the card does not answer "why is this being flagged", even though every other surface does.

Evidence (checked on current main, 2026-09-17)

  • apps/desktop/src/components/assistant-ui/tool/approval.tsx — the ApprovalCard renders request.command only; request.description appears solely in the Always-allow DialogDescription.
  • apps/desktop/src/store/prompts.tsdescription is already mapped from the pending payload into ApprovalRequest (with a 'dangerous command' fallback), so rendering it needs no backend or payload change.
  • tools/approval.py — the gateway/TUI notify dict already carries "description": display_description (alongside pattern_keys, allow_permanent, smart_denied).
  • CLI parity: the CLI panel prints the reason (⚠️ DANGEROUS COMMAND: recursive delete); gateway adapters render the same (Command was flagged (script execution via -e/-c flag), see the example in #113330). Desktop is the one surface that drops it.
  • The file is byte-identical on current main to the installed v0.21.3 copy (verified by downloading approval.tsx from main), so this is present-day main behavior, not a stale install.

Steps to reproduce

  1. Desktop session, any approval mode.
  2. Trigger an approval — e.g. python -c "print(1)" (flagged as script execution via -e/-c flag), or an execute_code call.
  3. The card shows the code only — no reason line.
  4. Open ⋮ → "Always allow": the confirm dialog renders the description the card never showed.

Why it matters

For an execute_code gate the approver stares at a wall of Python with no statement of the class of risk — while the payload literally contains the advisory ("the script can spawn subprocesses or mutate files without passing through terminal command approval; approval is one-shot for this run"). For shell commands, the "why paused" (recursive delete / Tirith finding) is invisible on desktop only.

This is the deterministic half of the #34625 / #113330 cluster: no agent-intent field is needed to fix it. Note that #6959 was closed citing that deterministic detector/Tirith reasons "are already shown across CLI and gateway surfaces" — that premise does not hold on desktop.

Suggested fix

Render request.description on the card (small secondary text under the command preview, clamped); optionally mark smart-denied prompts (smartDenied). Desktop-only, no payload change; keep the raw command as the authoritative artifact.

Environment

  • Hermes desktop app, Windows 11
  • v0.21.3 (2026.9.14), upstream 98f758ae, install method: git

Source: NousResearch/hermes-agent