Hermes Agent Weekly #25: Smart Approval Defaults, Kanban Artifact Handoff, Desktop QA Overhaul & CI Hardening
- Commits summarized
- 1,038
- Period
- Jul 13 - Jul 19, 2026
- Published
- Jul 20, 2026
Hermes Agent Weekly Development Update
Repository: NousResearch/hermes-agent
Period: 2026-07-13 → 2026-07-19
Cadence: Weekly
This post highlights a selection of 200 commit summaries from a total of 1,038 commits in the period.
🎯 Who Should Care
This was a heavily front-loaded week across the approval system, Kanban boards, Windows/desktop reliability, and test infrastructure. If you run Hermes in "smart" approval mode, use Kanban for durable artifact workflows, develop on macOS/Windows, or maintain CI pipelines — several of the fixes below directly affect you.
⚡ Approval System Overhaul
Smart Approvals Are Now the Default
The approvals.mode default changed from "manual" to "smart" (62a76bd3). This affected several downstream tests that had to be pinned to manual mode to avoid LLM call cascades in test environments.
Dashboard Approval Config Fix
The dashboard's approval mode selector showed ['ask', 'yolo', 'deny'] — values that never matched the actual config. Corrected to ['manual', 'smart', 'off'] with a regression test to prevent future drift.
da6d6164— fix(dashboard): correct approvals.mode select options (Closes #31925)7c19eb80— docs(dashboard): align approval mode guidance
Smart Verdict Observer Hooks
Smart-approval decisions now properly emit observer hooks, enabling external monitoring or audit logging of automated verdicts.
b03c94db— fix(approval): emit observer hooks for smart verdicts
Scoped Smart Deny Overrides
Smart deny owner overrides were leaking across operations. They are now scoped to a single operation, preventing unintended cascading denials.
d48bf743— fix(approval): scope smart deny owner overrides to one operation
Canonical Gateway Timeout Honored
The approval system now respects the canonical gateway timeout configuration instead of using a hardcoded value.
c5e841ab— fix(approval): honor canonical gateway timeout
🗂️ Kanban Improvements
Project Directory Collection
Boards now automatically collect project directory context when being created.
aaf56912— feat(kanban): collect project directory when creating boards (#63249)
Durable Artifact Handoff
The Kanban artifact handoff is now hardened to survive process restarts, and scratch completion artifacts are preserved after task completion.
8030b01a— fix(kanban): harden durable artifact handoffe6c42b5d— fix(kanban): preserve scratch completion artifacts
Done-Card Results & Final Summaries
Done cards now surface actionable results and show a run summary when task.result is empty.
98b45629— fix(kanban): make Done-card results actionabledeae8e3b— feat(kanban): surface final_result for Done cards
Goal-Mode Worker Fix
Goal-mode workers spawned by the dispatcher weren't actually running the goal loop — they got one turn, printed text, and exited. Adding -Q to the spawn invocation fixes the circuit breaker violation.
80b58ec7— fix(kanban): spawn goal_mode workers with-Q
🖥️ Desktop & Windows Reliability
Native Binary Classification Fix (macOS)
classifyNativeBinary only checked big-endian Mach-O magic bytes. Real Darwin .node files from node-pty prebuilds are little-endian (cffaedfe), so every macOS contributor saw npm run check fail with platform mismatch warnings. All six Mach-O/Fat byte orderings are now recognized.
5d691374— fix(desktop): recognize little-endian Mach-O magic in native binary classifier
Cross-Platform Native Binary Staging
stageNodePty now validates that the staged binary's platform matches the target. Cross-targets with no matching prebuild fail closed.
7a44a8fd— fix(desktop): prevent staging wrong-platform node-pty binary for cross targetsc008f41b— fix(desktop): stage-native-deps falls back to electron-rebuild when no native binary exists
Windows Bash Path Fixes
Three cumulative fixes for Windows subsystem paths:
1. MSYS arg-conversion was mangling C:/... paths in snapshot files [#63621]
2. Broken Git Bash login shells (bash -l) now fall back to non-login mode [#63948]
3. Mixed /c/Users\... path normalization in file operations
f2fcf89c— fix(windows): bash-safe snapshot paths after #63113c4622a1d— fix(windows): survive broken Git Bash login shells
Stream Pin & View Sync Fix
Live deltas from one session were leaking into another after "New Session" when events arrived without session_id. Now pinned to the session that received message.start, and stale background flushes are cleared on session switch.
da52ffea— fix(desktop): pin unscoped streams + clear view sync on switch
Base-Branch Picker for Worktrees
The "New worktree" sidebar button now offers a filterable branch picker instead of branching off whatever HEAD you were on.
6f7ee72b— feat(desktop): base-branch picker for new worktree dialogf6d1fd51— feat(desktop): auto-fetch remote base branch before worktree add
Profile-Aware Approval Mode
Desktop approval mode control is now profile-aware, allowing per-profile approval configuration.
3510b188— feat(desktop): add profile-aware approval mode control
Draft Fallback Rows
Draft fallback rows were being wiped by the resync effect after autosave. Now ignores value updates that match the last emitted chain.
3615545b— fix(desktop): keep draft fallback rows across autosave echo
🔌 Gateway & API Drains
Multiple fixes ensure the gateway properly reserves and drains in-flight work during shutdown — preventing SIGKILL mid-tool on desktop/API sessions.
021ee345— fix(gateway): drain in-flight api_server runs on shutdown (Closes #63529)104ffeae— fix(gateway): complete API-server shutdown drainffc10cc6— fix(gateway): quiesce API and cron work during drains915f1bf1— fix(api): reserve cron fire work during drain
🧪 Test Infrastructure Overhaul
Desktop Tests: act() Warnings Eliminated
44 act() warnings reduced to zero across 8 test files by wrapping render()/fireEvent() calls in act() blocks and adding vitest.setup.ts.
ef614369— test(desktop): fix React act() warnings across all desktop test filesa6857faf— test(desktop): fix remaining act() warnings in gateway-connecting-overlay
Source-Regex Tests Replaced
Several tests that regexed TypeScript source text have been replaced with real unit tests using extracted pure functions:
- Zoom window config — Extracted
zoomWiringForWindowKind()into pure testable config - Profile delete routing — Extracted
decideProfileDeleteAction()into testable routing module - Windows Hermes resolution — Three Windows resolution bugs now tested via injected deps
- Windows child process options — Extracted
hiddenWindowsChildOptions()andstopBackendChild() - Cursor layout for TUI — Extracted
resolveCursorLayout(),fastBackspaceEffect(),fastAppendEffect()
Migrated to Vitest
Desktop test runner migrated to Vitest for Node tests as well, alongside lint/fmt cleanup.
955c5b73— test(desktop): move node tests to vitest as well7c98c651— cleanup(desktop): lint&fmt all47d56b80— test(desktop): run scripts/ tests in vitest
CI Hardening
The workspace matrix discovery now fails closed if it produces an empty list (instead of silently running zero check jobs). Python test speedups landed, and a pass/failed jobs summary was added for debugging neutral-status jobs.
75778342— fix(ci): fail closed when workspace matrix discovery produces empty list7fe1cb38— feat(ci): python test speedups79061f44— feat(ci): show passed/failed jobs in summary
🔐 Auth & Credential Management
Anthropic sk-ant-oat Normalization
Manually-added Anthropic setup tokens defaulted to api_key and were sent via x-api-key, which Anthropic rejects with a 429. Fixed to infer OAuth from the sk-ant-oat prefix.
77763f00— fix(auth): normalize Anthropic sk-ant-oat pool creds to OAuth (Fixes #63737)0512f06a— fix(auth): centralize pool auth normalization
Empty Credential Pool Leases Rejected
The credential pool now rejects empty leases, preventing silent failures downstream.
5d524d04— fix: reject empty credential pool leases (#63620)
⚙️ Agent & Provider Fixes
Multi-Model Custom Provider Matching
Custom providers with multi-model catalogs (providers.<name>.models mapping) silently dropped extra_body when the default model differed from the session model. This meant an OpenAI custom provider pinning service_tier=flex via extra_body ran every request at STANDARD tier (~2.3x billing). Usage reports now carry service_tier for audit.
8a5f8379— fix(agent): honor custom-provider extra_body for multi-model catalogs
Compression Lock Safety
Compression lock acquisition now distinguishes "missing" (version skew, safe to skip) from "broken" (unexpected error, fail closed to prevent concurrent compressors from forking the session).
2627933f— fix(agent): distinguish missing from broken compression locks8f29c9f4— fix(agent): fail closed on unexpected compression-lock acquisition errors
Patch: Inert Context-Only Hunks Ignored
Patches with only context lines and no actual changes are now ignored instead of causing patch application failures.
dfeedf61— fix(patch): ignore inert context-only hunks (#63678)
Config String Preservation
String-typed config values were being type-coerced in some paths; now preserved as-is.
e4ea0a0e— fix(config): preserve string-typed config values
📱 Channel & Session Management
Dashboard Session Import
A full session import flow has been added to the dashboard, with payload validation that rejects corrupt metadata and detaches cyclic lineage links.
b51d365e— feat(dashboard): add session import flowac705b52— fix(sessions): validate imported session payloads
WhatsApp Interactive Taps
Interactive message taps on WhatsApp Cloud are now gated on a DM allowlist.
f96b2e6e— fix(whatsapp_cloud): gate interactive taps on DM allowlist
Mobile Channel Setup Modal
The mobile channel setup modal UI received a targeted fix.
2bffeece— Fix mobile channel setup modal
📦 Delegation & Completion Delivery
67f4e1b4— feat(delegation): persist background completionsd0e9a42c— fix(delegation): harden durable completion delivery94a7705b— fix(gateway): deduplicate completion delivery
🧰 Nemo Relay
297dbf95— chore(nemo-relay): refresh uv lock for relay 0.52d2bed58— Merge origin/main into bbednarski/nemo-relay-upgrade
🧹 Chores & Release
acb3bde0— chore(release): map @jakelongvu-bot in AUTHOR_MAP0709714a— chore(release): map @yinkev in AUTHOR_MAPf813c7dd— chore(release): map @Tortugasaur desktop commitsd921005e— chore(release): map @kavioavio in AUTHOR_MAPd2b2be0f— chore(release): map delegation contributoraf250d84— docs(delegation): clarify background lifetime
This update covers highlights from 200 commit summaries out of 1,038 total commits in the period. For the full changelog, visit the repository.