Add voice.submit_mode=direct|draft without model-refine hooks or callbacks. Validate the config, preserve direct-submit compatibility, render editable drafts in the Ink composer, and document both locales.
Co-authored-by: BELIVIN MEDIA <212580280+KarateWilly@users.noreply.github.com>
Adds the comment-based hotspot convention (no new primitives) across three
guidance surfaces:
- KANBAN_GUIDANCE worker lifecycle: new step 7 — when a file keeps colliding
with siblings or appears in other cards' recent comments, leave a
'hotspot: <path> — <reason>' kanban_comment and repeat it in completion
metadata so the orchestrator can decompose the file first.
- kanban.md (en + zh-Hans): 'Collision hotspots in parallel campaigns'
subsection — the convention, the orchestrator response (2+ flags on one
path => dedicated decomposition card before queuing more work touching
it), and the cross-link to merge-reconciler for conflicts that already
happened.
- merge-reconciler SKILL.md Pitfalls: repeated conflicts on the same file
across rounds are a hotspot signal — flag for decomposition rather than
serially reconciling.
Live-verified: guidance renders once via real import (6152 chars); hotspot
comment round-trips through add_comment -> list_comments -> worker context
on an isolated HERMES_KANBAN_DB; kanban tools, review-surfaces, and
merge-reconciler skill tests green (45 passed).
Design decisions belong to the orchestrator: decide naming schemes,
schemas, file formats, and API shapes before fanning out; never let two
subtree cards decide the same question; stamp every decision into each
dependent card body since workers cannot see sibling context. Mirrored
in the kanban docs (en + zh-Hans) with an exporter/importer worked
example, and bounded KANBAN_GUIDANCE size with an invariant test.
Add a non-terminal "review" status so a worker that finished implementation
can hand off for human review without abusing kanban_block. The old
kanban_block(reason="review-required: ...") convention routed the handoff
through the unblock-loop breaker, so a normal review -> changes -> review
cycle was falsely escalated to triage.
- kanban_db: request_review (running/ready -> review, non-block, emits
review_requested), reopen_review_task (review -> ready/todo, review_reopened),
complete_task accepts review -> done, and a review_dispatch gate (default off,
shared by the dispatcher loop and the gateway health probe).
- kanban_request_review worker tool + `request-review` / `reopen-review` CLI
verbs; tool wired through toolsets, EXPOSED_TOOLS, _POLISHED_TOOLS.
- Gateway notifier wakes the origin subscriber on review_requested and
block_loop_detected; the subscription survives until done/archived, so every
review cycle re-notifies.
- Dashboard PATCH + bulk route the review transitions (request_review /
reopen_review_task) and render the review column.
- goals.py goal-loop and KANBAN_GUIDANCE recognize review as a terminator.
- Docs (reference tables, user guide, AGENTS.md, zh-Hans mirrors) + tests.
needs_input / failed are unchanged: they still route through kanban_block,
still count toward block_recurrences, and still escalate to triage.
The upstream ahujasid/blender-mcp and ahujasid/ableton-mcp GitHub repos
were hijacked on 2026-08-08: the maintainer (@sidahuj) publicly reported
his account was compromised and ownership stripped, and both repos now
redirect to an attacker-controlled org (MCPBlender, created the same
day, pushing new commits since).
Although our catalog pinned blender-mcp==1.6.4 from PyPI (pre-compromise,
sha256 verified unchanged), the server is only half the bridge: the
manifest's post-install instructions and the optional skill directed
users to download addon.py — arbitrary Python executed inside Blender —
from the now-compromised GitHub repo (the raw URL currently 404s, and
the addon ships in no PyPI artifact). There is no trustworthy source
for the addon half, so the entry cannot be installed safely end-to-end.
Removing the catalog entry and skill entirely until the maintainer
confirms account recovery; re-adding is a follow-up PR once upstream
is verified clean.
- optional-mcps/blender/: removed
- optional-skills/creative/blender-mcp/: removed
- docs: catalog rows, sidebar entry, skill pages (en + zh-Hans) removed
- cross-references in unreal-mcp and kanban-video-orchestrator cleaned
Adds skills/autonomous-ai-agents/merge-reconciler — a bundled skill teaching
a neutral third-party agent to resolve git merge conflicts between two
agents' branches: gather both diffs + intents, classify each hunk
(disjoint-intent / same-question-different-answer / superseded), resolve
under an impartiality contract, verify, and hand back a per-hunk summary.
Procedure was live-tested end-to-end against a real conflict fixture.
Includes contract tests (tests/skills/test_merge_reconciler_skill.py) and a
kanban docs cross-reference (en + zh-Hans): assign a third neutral profile a
reconciliation card with both conflicted cards as parents.
Surface the existing planner/worker cost-split capability as an explicit
strategy in the docs:
- delegation.md: new 'Cost strategy: frontier planner, inexpensive workers'
subsection under Model Override, with a config.yaml snippet using the
verified delegation.model / delegation.provider keys, the resolution order
(base_url > provider > inherit parent; model applies in all cases, empty =
inherit), and a note that delegate_task has no per-task model parameter —
quality-sensitive tasks should use kanban's per-task override instead.
- kanban.md: matching 'Cost strategy: frontier orchestrator, inexpensive
workers' subsection using the verified per-profile config mechanism
(dispatcher injects profile-scoped HERMES_HOME at worker spawn) and the
existing per-task model_override (--model/--provider, set-model, dashboard).
- zh-Hans mirrors for both pages.
- cli-config.yaml.example: cost tip comment under the delegation section.
Config resolution was live-verified against tools/delegate_tool.py
(_load_config + _resolve_delegation_credentials) with a temp HERMES_HOME:
delegation.model pins children to the sentinel model; with no delegation
keys, children inherit the parent model and credentials.
Adds 'Handing context to follow-up cards (the parent link)' to the kanban
feature page and a CI-remediation worked example to the tutorial, with
zh-Hans mirrors. Claims live-verified against kanban_db on an isolated
board: create_task creates children of done parents directly in ready,
recompute_ready leaves children of open parents in todo, and
build_worker_context surfaces the parent's completion summary and
metadata under '## Parent task results'.
Explain that schema.description is model-facing while register_tool(description=...) only populates ToolEntry metadata, and remove the duplicated hello-world description in English and zh-Hans docs.
Refs #60735
Co-authored-by: Shiki <132348332+songshikang0111@users.noreply.github.com>
New tests/skills/test_authoring_standards.py parametrizes every bundled +
optional SKILL.md (1148 checks) against the mechanically-verifiable subset
of the hardline standards:
- required frontmatter fields (name/description/version/author/license/
platforms) + tags
- frontmatter name == directory name
- description <= 60 chars, ends with period, no marketing words
- related_skills resolve in-repo
- no machine-local paths
- <= 100k chars
Grandfather dict for legacy debt ships EMPTY — all pre-existing violations
fixed in this PR:
- 13 frontmatter names canonicalized to their directory names (the install
identifier); all related_skills references updated (comfyui -> stable-
diffusion). Fixes the class behind PR #42788's report; also fixes
here.now's invalid dot-name.
- optional-skills/devops/cli -> inference-sh-cli (dir was the generic
'cli'; fm name was right) incl. docs pages (en + zh-Hans), catalog row,
sidebar entry.
- pytorch-fsdp: 157k generated 'Quick Reference' dump moved to
references/common-patterns.md; SKILL.md 159k -> 2.5k with a pointer.
- research-paper-writing: 31.7k Phase 5 drafting section moved to
references/phase5-paper-drafting.md; SKILL.md 103k -> 71k.
Docs regenerated with scope discipline.
Adds a per-server `trust: full|untrusted` config key
(mcp_servers.<name>.trust). On an untrusted server, every write-capable
tool call — any tool whose discovery-time annotations do not carry
readOnlyHint=True — routes through the existing approval surface
(tools.approval.request_elicitation_consent, same lazy-import +
surface-routing pattern the MCP elicitation handler uses) before the RPC
fires. Denied/cancelled/errored approvals fail closed: the RPC never
runs, including the lazy first-use server spawn.
Design points:
- Classification happens at CALL TIME from metadata captured at
DISCOVERY (_record_tool_trust_metadata in _register_server_tools and
the lazy cache-registration path). No toolset/schema mutation, so the
toolset stays byte-stable and prompt caching is preserved.
- readOnlyHint is a server-supplied HINT: on an untrusted server a lying
server can at most skip approval for tools it claims read-only — it
can never widen access. Trust tiering itself is operator config.
- Missing/malformed annotations => write-capable (fail closed).
- Unrecognized trust values => untrusted (fail closed); missing key =>
full (backward compatible, documented in mcp-config-reference).
- The schema cache now persists readOnlyHint so lazy-registered servers
gate identically on next startup without spawning.
Tests: tests/tools/test_mcp_trust_gating.py (11 tests, TDD red->green):
approval invoked + accept proceeds, deny/cancel blocks RPC, readOnlyHint
=true skips gate, trusted/unconfigured servers skip gate, explicit
readOnlyHint=false gated, approval exception fails closed, trust
normalization, discovery-time capture (SDK objects and cached dicts).
Ported from: cloudflare-os classifyTool() (Apache-2.0), corroborated by
Claude Cowork (idea-level).
Per the 'when in doubt, optional' rule — niche prediction-market data
skill that sees no regular use; belongs alongside stocks in the finance
optional category rather than the default bundle.
Install via: hermes skills install official/finance/polymarket
- website/docs/user-guide/configuration.md (en) and the zh-Hans
translation gain a 'Session Stall Watchdog' section: default 300,
0=disabled, notify-only semantics (never kills the turn — contrast
gateway_timeout), one notification per stall episode, and the exact
stall message text so it is greppable.
- cli-config.yaml.example: the two in-agent compression timeout keys
(compression.context_timeout_seconds /
compression.context_total_ceiling_seconds) are shown as commented
lines next to session_stall_timeout's example for discoverability.
The post-begin_commit() waiter previously called unbounded future.result(),
so the advertised compression.context_total_ceiling_seconds was silently
unenforced for commit-phase hangs. The commit still must complete (abandoning
an in-flight SessionDB mutation would diverge live messages from durable
state), but the wait is now bounded in increments against the remaining
ceiling: on ceiling breach the overrun is logged (WARNING escalating to
ERROR), surfaced once through the user-visible warning channel via the new
on_commit_overrun callback (wired to _emit_warning in run_agent.py), and the
host keeps waiting in bounded slices until the commit finishes.
Documented guarantee (config comment + docs, en/zh): summary phase bounded
by the ceiling; commit phase logged + surfaced if it exceeds it — never
silently hung, never abandoned mid-commit.
Test updated to assert the surfacing fires (previously accepted a silent
over-ceiling wait); adds coverage that a raising overrun callback cannot
break the commit wait.
Once begin_commit() wins, SessionDB mutation cannot be fence-cancelled;
document that context_total_ceiling_seconds covers the summary phase only
and pin the hang-wait contract in tests.
Three mechanisms to detect and notify when gateway sessions stall silently:
1. Mid-turn activity heartbeats stamped to SessionDB so hermes sessions list
and hermes status show progress during long turns without new message rows.
2. Stall watchdog: when a busy session has pending inbound and the shared
activity clock is idle past agent.session_stall_timeout (default 300),
log a WARNING and notify the user once to try /new. Notify-only; does
not kill the turn.
3. Compaction timeout: fenceless compress_context callers get a progress-aware
host budget (compression.context_timeout_seconds default 120 idle,
compression.context_total_ceiling_seconds default 600 ceiling). On timeout,
cancel via commit fence, skip compaction without dropping messages, and
continue the turn.
Closes#72016 (slices 1-3; slice 4 cumulative SSE stream-retry deadline
remains a follow-up).
Cherry-picked from PR #72424 by @fangliquanflq.
Every ORDER BY id query on the messages table sorted or scanned the
whole session: get_messages_around's window seek, latest_message_row_id
(LIMIT 1), and get_messages' full-load ordering all paid O(session
history) per call — hot mid-turn via session_search and reactions.
messages.id is an original column (INTEGER PRIMARY KEY AUTOINCREMENT),
so the index lives in SCHEMA_SQL next to idx_messages_session — no
legacy-column migration hazard (the kanban lesson from #28776 does not
apply).
Measured (real schema, one 20k-message session, median of 30):
get_messages_around 7.08 -> 0.22 ms (32x), latest_message_row_id
3.37 -> 0.011 ms (307x), get_messages full load 111.6 -> 98.6 ms
(1.13x — remaining cost is row deserialization, not the sort).
Window results byte-identical at probe points across the session.
Tests: VM-step pin (get_messages_around bounded work, calibrated
~12 vs ~855 handler calls, threshold 300 — fails without the index)
and window parity with/without the index. No EXPLAIN/plan text
(behavior contracts, AGENTS.md).
Google API and authentication packages permit vulnerable httplib2 and pyasn1
transitives, while the Workspace and Google Chat runtime installers previously
treated any importable version as sufficient. Existing environments could
therefore remain vulnerable after the project dependency pins were repaired.
Carry the fixed versions through the Google and Vertex extras, lazy feature
requirements, lockfile, and both runtime installers. Route the documented
Google Chat installation path through its maintained secure requirements
instead of an unconstrained direct pip command.
Detect stale distributions, install only unsatisfied requirements, and verify
the result before continuing. Behavioral tests cover those repair invariants
without freezing manifests, lockfiles, or complete package sets.
Related #72108
Extracted from #72840
Co-authored-by: Teknium <127238744+teknium1@users.noreply.github.com>
Follows PR #75592: the notifier is no longer gated on
kanban.dispatch_in_gateway. Every gateway delivers events for
subscriptions owned by the profiles whose adapters it hosts; legacy
unstamped subscriptions go only through the confirmed dispatcher
lock owner. Adds a 'Multi-profile setups' subsection to the kanban
Gateway notifications docs (en + zh-Hans).
The test runner moved to per-file subprocess isolation via
scripts/run_tests_parallel.py (hermetic `env -i`, worker count auto-scaled
from CPU count, FLAKY-retry policy) — no pytest-xdist, no SIGALRM per-test
timeout fixture. Docs still described the old runner in many places:
- AGENTS.md: "-n auto xdist workers, in-tree subprocess-isolation plugin"
clause replaced with the current per-file-subprocess description; the
`::test_x` single-test example now shows file + -k (runner is
file-granular).
- CONTRIBUTING.md: "hermetic env, 4 xdist workers" comment corrected;
`tests/conftest.py::_enforce_test_timeout` reference redirected to the
win32 timeout-method shim in `tests/conftest.py::pytest_configure`.
- skills/autonomous-ai-agents/hermes-agent/references/contributor-guide.md
and windows-quirks.md: same corrections (the bundled skill mirrors the
contributor docs); Windows workaround no longer installs pytest-xdist
or passes -n 0.
- website/docs + zh-Hans i18n mirrors: same fixes in adding-providers.md
and the bundled-skill doc pages.
- skills/software-development/python-debugpy/SKILL.md (+ zh-Hans mirror):
"-p no:xdist"/"-n 0" pdb advice rewritten for the captured per-file
subprocess runner.
- skills/creative/comfyui/tests/README.md: parent-repo "-n auto by
default" rationale updated to past tense.
Combined salvage of PR #38295 (konsisumer), PR #51354 (TutkuEroglu,
redirected to the current conftest truth and the relocated
references/contributor-guide.md), and PR #54956 (waroffchange).
Co-authored-by: TutkuEroglu <rrandqua@gmail.com>
Co-authored-by: waroffchange <116298975+waroffchange@users.noreply.github.com>
Local faster-whisper called model.transcribe with bare {'beam_size': 5}:
no VAD, cross-window conditioning on, no confidence filtering. Pure
silence produced hallucinated tokens (E2E: 5s anullsrc WAV -> 'You',
no_speech_prob=0.705) and noisy clips could produce runs of junk, often
in other languages.
Three-layer class fix, one shared owner for every local-whisper call
site (build_local_transcribe_kwargs):
1. Silero VAD filter (bundled with faster-whisper) on by default —
silence never reaches the model. stt.local.vad: false restores the
raw behavior for music/ambient transcription.
stt.local.vad_min_silence_ms tunes chunk splitting (default 500).
2. condition_on_previous_text=False — one hallucinated token can no
longer seed a self-reinforcing run; negligible cost for
voice-note-length audio.
3. Segment confidence gate (_join_confident_segments): drop a segment
only when no_speech_prob > 0.6 AND avg_logprob < -1.0 (openai-whisper's
own heuristic shape; both must hit so quiet-but-real speech survives).
Config: stt.local.no_speech_prob_threshold / logprob_threshold.
The WHISPER_HALLUCINATIONS blocklist in voice_mode.py stays as
last-resort defense but should now almost never fire.
E2E (real faster-whisper 'base', CPU int8):
silence.wav before 'You' -> after ''
noise.wav before '' -> after ''
speech.wav before/after 'Hello World, this is a test of the
transcription system.' (unchanged)
Docs (EN + zh-Hans), DEFAULT_CONFIG, cli-config.yaml.example updated;
19 unit tests (kwargs contract, off-switch, confidence gate incl.
quiet-speech survival, _transcribe_local wiring), sabotage-verified.
The Skills Hub 'Marketplace' tab showed a single useless entry: Anthropic
changed .claude-plugin/marketplace.json to bundle-shaped plugins whose
source is './', so all plugins collapsed to one identifier pointing at the
repo root, and the second marketplace repo (aiskillstore/marketplace) is
gone (404). Everything in anthropics/skills is already surfaced by the
GitHub tap as the Anthropic tab, making this source fully redundant.
Removes ClaudeMarketplaceSource and all wiring: source router, index
builder (crawl + floors + sort order + rate-limit messaging), extract
labels/install/URL mapping, hub UI tab, web server labels, CLI limits,
docs (en + zh), the legacy index-cache snapshot, and test fixtures.
Stale skills-index entries with source 'claude-marketplace' still install
fine: HermesIndexSource fetches via resolved GitHub paths generically.
One page consolidating all three Hermes×Buzz integration paths —
Desktop managed runtime, buzz-acp relay bridge, and the native gateway
platform — with a comparison table, per-path pointers into the detailed
docs, identity guidance, and contributor credits. Registered in
sidebars.ts under Integrations; Buzz added to the messaging platform
list and a new Collaboration Workspaces section on the integrations
index. en + zh-Hans.
Adds gpt-transcribe (OpenAI's new file-transcription model, $0.0045/min)
to the OpenAI STT provider:
- OPENAI_MODELS set: gpt-transcribe is recognized so provider
auto-correction keeps it on OpenAI and rejects it on Groq
- Language hint wiring: gpt-transcribe replaces the singular
'language' field with a 'languages' list; the API rejects the legacy
field, so the hint is sent via extra_body {languages: [..]}
- Config comment (DEFAULT_CONFIG), cli-config.yaml.example, desktop
settings enum, and docs (en + zh-Hans) updated
- Tests: model pass-through, languages-list hint shape, legacy singular
hint preserved for gpt-4o-transcribe, Groq auto-correction
gpt-live-transcribe (realtime WebSocket, $0.017/min) is NOT wired here:
the file-based STT pipeline has no realtime session path; it belongs in
a future realtime/voice-mode integration.
Follow-up on the salvaged #69915 commits:
- verified env vars against block/buzz crates/buzz-acp/src/config.rs
(BUZZ_RELAY_URL, BUZZ_PRIVATE_KEY, BUZZ_API_TOKEN, BUZZ_ACP_AGENT_COMMAND/
ARGS, BUZZ_ACP_RELAY_OBSERVER, BUZZ_ACP_AGENT_OWNER) and kind 24200
observer frames against docs/nips/NIP-AO.md
- dropped unverifiable claims: docs/hermes-agent-acp.md link (404 upstream),
relay-directory profile publication / External-agents card walkthrough,
'bot role' membership phrasing
- replaced key provisioning with the actual buzz-admin generate-key /
add-member flow from the buzz-acp README
- retitled the section 'Buzz channels (relay bridge)' and cross-linked it
with the Buzz Desktop managed-runtime section both ways; permission
paragraph now points at the owner-only warning instead of duplicating it
- zh-Hans translation of the new section + retitle to ACP 宿主集成
The quickstart voice-mode section used `uv pip install -e ".[voice]"`
which fails on a fresh curl-installed setup because no virtual environment
is active. Use `--python ./venv/bin/python` to target the installer-created
venv explicitly, matching the curl installer layout.
Fixes#44364
The Buzz Desktop section covered discovery only. The combination that
actually needs stating: the hermes-acp toolset carries terminal and
execute_code, and buzz-acp answers session/request_permission itself with
allow_once instead of surfacing it. A Hermes agent in Buzz runs shell
commands on the host unattended.
Buzz defaults every agent to owner-only and that default holds through to
the spawned process env, so nobody reaches the open state by accident.
But Anyone is one dropdown change away with no warning shown, and it
hands channel-wide shell access to the host.
Also record that the two obvious mitigations do not work: approvals.mode
manual raises the request but Buzz auto-approves it anyway, and
platform_toolsets.acp does not narrow the ACP toolset. Both verified by
running rm -rf through the ACP path under each setting.
Amend the Approvals section too — it promised prompts route back to the
editor, which is only true for hosts that choose to surface them.
en + zh-Hans.
Signed-off-by: SHL0MS <SHL0MS@users.noreply.github.com>
Existing installs predate the install.sh hermes-acp launcher, and hermes
update never re-runs setup_path, so ACP hosts (Zed, JetBrains, Buzz)
still resolve Hermes as unavailable until a reinstall. _ensure_acp_launcher()
writes the launcher next to an existing hermes command in ~/.local/bin or
/usr/local/bin during hermes update — delegating to the sibling launcher so
it is correct for every install layout. Never follows symlinks (#21454),
skips unwritable dirs, no-op on Windows (venv Scripts is already on PATH).
Docs: add a Buzz Desktop section to the ACP page (en + zh-Hans).
Three mechanisms to detect and notify when gateway sessions stall silently:
1. Mid-turn activity heartbeats stamped to SessionDB so hermes sessions list
and hermes status show progress during long turns without new message rows.
2. Stall watchdog: when a busy session has pending inbound and the shared
activity clock is idle past agent.session_stall_timeout (default 300),
log a WARNING and notify the user once to try /new. Notify-only; does
not kill the turn.
3. Compaction timeout: fenceless compress_context callers get a progress-aware
host budget (compression.context_timeout_seconds default 120 idle,
compression.context_total_ceiling_seconds default 600 ceiling). On timeout,
cancel via commit fence, skip compaction without dropping messages, and
continue the turn.
Closes#72016 (slices 1-3; slice 4 cumulative SSE stream-retry deadline
remains a follow-up).
Cherry-picked from PR #72424 by @fangliquanflq.