hermes-agent/tests
Teknium 243a01d5d7 fix(curator): make the autonomous write policy consistent (#67140)
The background write guard decided ownership from `isinstance(usage_rec, dict)`,
so a local skill with NO usage record passed. That successful write called
bump_patch(), which created a `created_by: null` record — and the identical
write was refused from then on. "Allowed exactly once, then never" is a race
with our own bookkeeping, not a policy. Reproduced on main: patch #1 succeeds,
patch #2 with the same arguments is refused.

Option B from the issue. Option A (split `session_review` from
`scheduled_curator` and let the session fork patch user-owned skills it
consulted) would widen autonomous write permission onto skills the user owns
with no user present to consent — wrong direction for a no-user-present actor.

- skill_manager_tool: missing and explicit-null records now resolve
  IDENTICALLY, both fail closed. The refusal names the reason and points at
  `hermes curator adopt <name>`.
- background_review: both review prompts told the reviewer to patch any skill
  consulted in the session and claimed pinned skills could be improved, while
  enforcement refused both. Prompts now list pinned, external, and user-owned
  skills as protected, and tell the reviewer to RECOMMEND adoption instead of
  attempting a write that will be refused.
- skill_usage: document that `created_by` is a curator-management policy flag,
  not a provenance claim, and add `is_curator_managed()` so call sites read as
  the question they ask. Field name retained — it is on disk in every
  `.usage.json` and renaming would strand those records.
- curator CLI: `hermes curator list-unmanaged` itemizes unmanaged skills with
  the reason each is unmanaged (completes the #67139 spec).

Foreground writes are untouched: a user-directed edit to a user-owned skill
still works, including on pinned skills.

Sibling tests: 9 failures in test_skill_manager_tool.py were fixtures that
created record-less skills to exercise OTHER guards (consolidation-delete,
read-before-write) and relied on ownership falling through. Fixed at the
fixture, since the real curator only ever operates on managed sediment. One
test asserted the old "manually authored" wording; rewritten to assert the
behavior contract instead of the string.

Validation: 274 targeted tests + all 7 background-review files (60 tests) pass.
E2E on a temp HERMES_HOME (30 checks) covers the flip, foreground writes,
adoption unblocking, pin semantics, prompt/enforcement parity, and the new verb.
Each new test sabotage-verified: revert the fix, confirm it goes red.

Fixes #67140
2026-07-25 19:27:17 -07:00
..
acp fix(acp): pin the session cwd for slash-command handlers too 2026-07-25 18:06:32 -07:00
acp_adapter
agent feat(aux): force streaming for providers that reject non-stream requests 2026-07-25 14:58:04 -07:00
ci fix(ci): report E2E evidence upload failures (#69901) 2026-07-23 05:45:17 +00:00
cli perf(cli): cut hermes -w startup from ~14s to ~1.8s by parallelizing + caching the worktree prune 2026-07-25 16:41:52 -07:00
computer_use Merge remote-tracking branch 'origin/main' into bb/computer-use-perf 2026-07-23 01:39:21 -05:00
cron fix: update heartbeat test stubs to accept workdir kwarg 2026-07-24 15:55:39 -07:00
dashboard
docker
e2e fix(slack): handle leading-space text commands 2026-07-22 20:55:51 -07:00
fakes
fixtures/plugins/example-dashboard/dashboard
gateway feat(relay): Phase 4 thread lifecycle — handoff threads, semantic renames, reply_to context, hello command manifest (#71624) 2026-07-26 10:26:20 +10:00
hermes_cli fix(curator): make the autonomous write policy consistent (#67140) 2026-07-25 19:27:17 -07:00
hermes_state
honcho_plugin fix(honcho): default device-code poll interval to 5s when AS omits it 2026-07-24 07:53:12 -07:00
integration
manual
openviking_plugin fix(openviking): cool down failed refreshes and publish conn identity atomically 2026-07-24 13:00:53 +05:30
plugins fix(image-gen): stop reporting the Codex tool_choice 400 as an account limit 2026-07-25 16:41:57 -07:00
providers
run_agent fix(conversation): anchor the cwd staleness read to the host-info block 2026-07-25 19:25:34 -07:00
scripts fix(scripts): accept legacy consecutive-hyphen GitHub logins in add_contributor 2026-07-24 22:40:15 -07:00
secret_sources
skills fix(skills): read OOXML parts as bytes and form JSON as UTF-8 in office skill scripts 2026-07-24 17:10:39 -07:00
state fix(compression): recover rotated session lineage 2026-07-24 16:00:34 -07:00
stress
tools fix(curator): make the autonomous write policy consistent (#67140) 2026-07-25 19:27:17 -07:00
tui_gateway test(project-tree): cover deleted-worktree fold into parent trunk 2026-07-25 20:31:17 -05:00
website
__init__.py
conftest.py fix(tests): gate WAL-dependent tests on the linked SQLite's real capability 2026-07-25 07:17:52 -07:00
run_interrupt_test.py
test_account_usage.py
test_atomic_replace_symlinks.py
test_background_review_list_shapes.py
test_background_review_session_isolation.py
test_base_url_hostname.py
test_batch_runner_checkpoint.py
test_bitwarden_secrets.py
test_cli_file_drop.py
test_cli_manual_compress.py test(cli): prove /compress type-ahead queue-drain; map contributor email 2026-07-23 07:24:46 -07:00
test_cli_skin_integration.py
test_code_skew.py
test_command_secret_source.py
test_conftest_wal_gate.py fix(tests): gate WAL-dependent tests on the linked SQLite's real capability 2026-07-25 07:17:52 -07:00
test_copilot_initiator.py
test_credential_file_permissions.py harden(slack): CDN-allowlist inbound file URLs, DNS-pin token downloads, widen token-file perms warning 2026-07-23 11:44:43 -07:00
test_ctx_halving_fix.py
test_delegate_cascade_49148.py
test_dispatch_session_id.py
test_empty_model_fallback.py
test_empty_session_hygiene.py
test_env_loader_applied_homes.py
test_env_loader_op_bootstrap.py
test_env_loader_secret_sources.py
test_evidence_store.py
test_fast_safe_load.py
test_fts_cjk_bigram.py
test_gateway_streaming_nested_config.py
test_get_tool_definitions_cache_isolation.py
test_hermes_bootstrap.py test(install): add UTF-8 regression guard for skills_sync child path 2026-07-24 17:10:39 -07:00
test_hermes_constants.py
test_hermes_home_profile_warning.py
test_hermes_logging.py
test_hermes_state.py fix(sessions): measure reclaimed space with SQLite page accounting 2026-07-24 22:41:30 -07:00
test_hermes_state_compression_locks.py fix(compression): prefer psutil.pid_exists for lease liveness probe; add same-pid self-reclaim guard 2026-07-23 16:21:19 -07:00
test_hermes_state_wal_fallback.py test(state): cover SQLite WAL-reset version gate and doctor probe 2026-07-23 17:32:38 +05:30
test_honcho_client_concurrency.py
test_honcho_client_config.py
test_honcho_session_context.py
test_honcho_startup_fail_open.py
test_install_autostash_conflict_recovery.py
test_install_diverged_update.py
test_install_lockfile_churn.py
test_install_no_initial_commit.py
test_install_ps1_ascii_only.py
test_install_ps1_native_stderr_eap.py
test_install_ps1_node_path_for_npm.py
test_install_ps1_python_fallback_venv.py
test_install_ps1_uv_powershell_host.py
test_install_ps1_web_server_syntax_probe.py
test_install_sh_browser_install.py
test_install_sh_install_method_stamp.py
test_install_sh_node_global_prefix.py
test_install_sh_pythonpath_sanitization.py
test_install_sh_root_fhs_uv_python_path.py
test_install_sh_setup_wizard_tty_probe.py
test_install_sh_symlink_stomp.py
test_install_sh_termux_network_prereqs.py
test_install_unmerged_index.py
test_ipv4_preference.py
test_iron_proxy.py Reapply "Merge pull request #30179 from NousResearch/feat/iron-proxy" 2026-07-24 09:49:00 -07:00
test_iron_proxy_cli.py Reapply "Merge pull request #30179 from NousResearch/feat/iron-proxy" 2026-07-24 09:49:00 -07:00
test_iron_proxy_e2e.py Reapply "Merge pull request #30179 from NousResearch/feat/iron-proxy" 2026-07-24 09:49:00 -07:00
test_lazy_session_regressions.py fix(desktop): persist @image: refs instead of the vision-enrichment text 2026-07-24 21:20:52 -05:00
test_lint_config.py
test_live_system_guard_self_test.py
test_mcp_serve.py
test_mini_swe_runner.py
test_minimax_model_validation.py
test_minimax_oauth.py
test_minisweagent_path.py
test_model_forces_max_completion_tokens.py
test_model_picker_scroll.py
test_model_tools.py
test_model_tools_async_bridge.py
test_ollama_num_ctx.py
test_onepassword_secrets.py
test_output_cap_parsing.py
test_packaging_build_guard.py rip out brew + pip/PyPI wheel support (#68217) 2026-07-22 16:51:01 -04:00
test_packaging_metadata.py rip out brew + pip/PyPI wheel support (#68217) 2026-07-22 16:51:01 -04:00
test_plugin_skills.py
test_plugin_utils.py
test_process_loop_event_loop_warning.py
test_profile_isolation_runtime.py
test_project_metadata.py rip out brew + pip/PyPI wheel support (#68217) 2026-07-22 16:51:01 -04:00
test_pty_keepalive_ws.py
test_pty_session.py
test_retry_utils.py
test_run_tests_parallel.py fix(tests): a run that collects nothing can no longer look green 2026-07-25 07:09:22 -07:00
test_sanitize_tool_error.py
test_search_slow_query_log.py
test_session_workspace_binding.py
test_slack_thread_require_mention.py Add Slack thread mention gating 2026-07-22 21:14:44 -07:00
test_slash_worker_watchdog.py
test_sql_injection.py
test_sqlite_wal_reset_gate.py test(runtime): cover managed SQLite cutover (E-949) 2026-07-24 16:00:03 -07:00
test_stale_utils_module_import.py
test_state_db_malformed_repair.py
test_subprocess_home_isolation.py
test_telegram_polling_progress_ptb.py
test_termux_all_extra_compat.py
test_timezone.py
test_tini_shim.py
test_toolset_distributions.py
test_toolsets.py docs(xai): clarify x_search vs xurl routing without schema cross-refs 2026-07-23 21:06:47 -07:00
test_trajectory_compressor.py fix(compaction): skip compression when it can't reduce tokens 2026-07-23 16:21:03 -07:00
test_trajectory_compressor_async.py
test_transform_llm_output_hook.py
test_transform_tool_result_hook.py
test_tui_entry_mcp_owner.py
test_tui_gateway_loop_noise.py
test_tui_gateway_queue_on_busy.py fix(desktop): preserve active correction on warm resume (#69725) 2026-07-22 21:53:56 -04:00
test_tui_gateway_server.py test: accept #71184's terminal error frame in the build-failure surfacing test 2026-07-24 22:21:06 -07:00
test_tui_gateway_ws.py fix(tui_gateway): preserve websocket batch order (#69684) 2026-07-23 05:02:45 +00:00
test_tui_mcp_late_refresh.py
test_utils_truthy_values.py
test_wal_checkpoint_strategy.py
test_web_server.py
test_web_server_sessiondb_eventloop.py
test_windows_subprocess_no_window_flags.py fix(cron): respect the platform-conditional decode design in _run_job_script + taskkill kwarg snapshot 2026-07-24 11:45:57 -07:00
test_yaml_indent_consistency_31999.py
test_yuanbao_integration.py
test_yuanbao_markdown.py
test_yuanbao_pipeline.py
test_yuanbao_proto.py
test_yuanbao_reconnect_set_active.py
test_yuanbao_shutdown.py
test_zeroed_state_db.py fix(state): quarantine lock fails closed when unacquireable (#68805) 2026-07-24 23:06:05 -07:00