hermes-agent/gateway
Teknium c6806a8e97
feat(approval): make invisible Unicode, control bytes, and padding visible in approval prompts
Inspired by Claude Code v2.1.223: 'Fixed permission prompts so commands
padded with tabs or invisible Unicode can no longer hide part of the
command from the approval dialog.'

A dangerous command rendered into an approval prompt could previously
lie to the human approver three ways:
- invisible/format Unicode (zero-width, bidi overrides/isolates,
  variation selectors, U+E0000 tag block) rendered as nothing
- raw control bytes (ANSI/OSC escapes, bare CR) could erase or
  overwrite the just-printed prompt line in the terminal
- long whitespace padding runs pushed the dangerous tail out of view
  or past platform preview truncation (~200 chars on gateway)

New agent.redact.sanitize_command_for_display() replaces hidden chars
with visible escape markers (\u202e, \x1b) and collapses padding runs
to explicit markers, preserving literal IOCs instead of deleting them.
Wired at every approval display-mint site: CLI prompt, gateway
dangerous-command + execute_code + tool-approval payloads, pending
fallbacks, and gateway _redact_approval_command. Display-only — the
executed command and pattern-key persistence are untouched.

25 new tests; redact (97), approval (103), gateway approval-format
suites green; E2E with real imports across CLI + gateway paths.
2026-08-07 17:13:54 -07:00
..
assets
builtin_hooks
platforms fix(cron): surface initial scheduler registration failures 2026-08-07 17:45:06 +05:30
relay fix(gateway): bound go_dormant ws.close with teardown timeout 2026-08-04 11:17:11 +05:30
__init__.py
agent_cache_pressure.py fix: follow-ups for salvaged PR #80795 2026-08-07 21:02:33 +05:30
authz_mixin.py fix(secrets): route authz gate and pairing allowlist reads through the profile secret scope 2026-08-02 10:02:33 -07:00
cgroup_cleanup.py
channel_directory.py perf(slack): parallelize conversations.info lookups with asyncio.gather 2026-08-07 18:40:33 +05:30
code_skew.py
config.py fix: address self-review findings on the check_fn/ensure_deps_fn split 2026-08-07 13:28:43 +05:30
cwd_placeholder.py
dead_targets.py
delivery.py
delivery_ledger.py
display_config.py
drain_control.py
hooks.py
kanban_watchers.py feat(kanban,mcp): orphaned-card reconciliation + per-server MCP identity header 2026-08-07 08:58:20 -07:00
lifecycle_ledger.py
memory_monitor.py
message_timestamps.py
mirror.py
pairing.py fix(secrets): route authz gate and pairing allowlist reads through the profile secret scope 2026-08-02 10:02:33 -07:00
platform_registry.py fix(gateway): split check_fn (passive probe) from ensure_deps_fn (active installer) 2026-08-07 13:28:43 +05:30
profile_routing.py
readiness.py
response_filters.py
restart.py fix(gateway): defer in-band restart until active turns finish (#77184) 2026-08-03 09:57:58 +05:30
restart_loop_guard.py
rich_sent_store.py
run.py feat(approval): make invisible Unicode, control bytes, and padding visible in approval prompts 2026-08-07 17:13:54 -07:00
runtime_footer.py feat(gateway): add opt-in 'latency' runtime footer field 2026-08-03 17:16:57 +05:30
scale_to_zero.py
session.py fix: defer O(n) fallback_data construction to failure path in _save_entry 2026-08-08 01:12:16 +05:30
session_context.py fix(cron): scope cron approval context per session 2026-08-03 00:25:20 +05:30
session_stall.py feat(gateway): session activity watchdog, stall notify, compress timeout (#72424) 2026-08-02 16:16:36 -07:00
session_state.py refactor(gateway): extract the hygiene recovery gate and forward the failure reason 2026-08-06 15:04:53 +05:30
shutdown_flush.py
shutdown_forensics.py
shutdown_watchdog.py
slash_access.py
slash_commands.py fix(agent): finish the #80622 bug class — sibling predicates, refund ordering, prompt carve-out, honest skip response 2026-08-07 19:44:35 +05:30
status.py fix(windows): native Windows correctness for CLI, gateway status, banner, and WSL browser paths 2026-07-29 23:16:18 -07:00
status_phrases.py
sticker_cache.py
stream_consumer.py fix(gateway): don't claim deleted head chunks as delivered in the empty-fallback recovery 2026-08-06 03:13:32 +05:30
stream_dispatch.py
stream_events.py
streaming_tts_consumer.py
systemd_notify.py
turn_context.py fix(gateway): reap only the background processes an abandoned turn created 2026-08-02 14:23:55 +05:30
turn_lease.py refactor(gateway): drop dead degraded token field; de-churn salvage diff 2026-08-07 18:23:57 +05:30
wake.py
whatsapp_identity.py