hermes-agent/tools
ethernet 8a3ae1a98f fix(skills): sweep writable mode on the origin-hash fast path
Rebase fixup for the writable-copy fix. #72622 landed an early-exit on
`origin_hash == bundled_hash` after this branch was written, which returns
before either migration sweep and left the pre-existing-install case
unrepaired — the branch's own
test_preexisting_hash_identical_readonly_copy_is_repaired failed on
current main.

That fast path deliberately skips hashing the user's copy, so it is
exactly the branch a pre-fix install lands on every sync. Sweep there too,
gated on the skill root's own mode via `_is_owner_writable` so the
steady-state path stays O(1): copytree propagates source modes to
directories, so an unrepaired copy always has a read-only root and a
repaired one never re-walks. #72622 removed recursive I/O from this branch
on purpose and sync_skills runs at CLI startup — measured on a real
67-skill install, an ungated sweep cost ~11ms per startup to repair
nothing; gated it is ~3.6ms and only walks a tree that needs it.

Also drops two stray asserts left in test_clone_config_copies_files by the
rebase conflict resolution (they referenced a `model.provider` config
shape this test never sets up).

Verified against the real /nix/store bundled skills tree:
  fresh sync   -r--r--r-- -> -rw-r--r--, 0 non-writable, patch OK
  migration    -r--r--r-- -> -rw-r--r-- with copied=0 updated=0, patch OK
2026-08-03 15:27:41 -04:00
..
computer_use
…
environments
…
neutts_samples
…
wakewords
…
__init__.py
…
ansi_strip.py
…
approval.py
…
async_delegation.py
…
audio_container.py
…
binary_extensions.py
…
blueprints.py
…
browser_camofox.py
…
browser_camofox_state.py
…
browser_cdp_tool.py
…
browser_dialog_tool.py
…
browser_supervisor.py
…
browser_tool.py
…
budget_config.py
…
checkpoint_manager.py
…
clarify_gateway.py
…
clarify_tool.py
…
close_terminal_tool.py
…
code_execution_tool.py
…
computer_use_tool.py
…
credential_files.py
…
cronjob_tools.py
…
daemon_pool.py
…
debug_helpers.py
…
delegate_tool.py
…
delegation_live_log.py
…
desktop_ui.py
…
discord_tool.py
…
env_passthrough.py
…
env_probe.py
…
fal_common.py
…
feishu_doc_tool.py
…
feishu_drive_tool.py
…
file_operations.py
…
file_state.py
…
file_tools.py
…
flux3_video_tool.py
…
focus_pane_tool.py
…
fuzzy_match.py
…
homeassistant_tool.py
…
hook_output_spill.py
…
image_generation_tool.py
…
image_source.py
…
interrupt.py
…
kanban_tools.py
…
lazy_deps.py
…
managed_tool_gateway.py
…
mcp_dashboard_oauth.py
…
mcp_oauth.py
…
mcp_oauth_manager.py
…
mcp_schema_cache.py
…
mcp_stdio_watchdog.py
…
mcp_tool.py
…
memory_tool.py
…
microsoft_graph_auth.py
…
microsoft_graph_client.py
…
neutts_synth.py
…
open_preview_tool.py
…
openrouter_client.py
…
osv_check.py
…
patch_parser.py
…
path_security.py
…
process_registry.py
…
project_tools.py
…
react_to_message_tool.py
…
read_extract.py
…
read_terminal_tool.py
…
registry.py
…
schema_sanitizer.py
…
send_message_tool.py
…
session_search_tool.py
…
skill_manager_tool.py
…
skill_provenance.py
…
skill_usage.py
…
skills_ast_audit.py
…
skills_guard.py
…
skills_hub.py
…
skills_sync.py
…
skills_sync_client.py
…
skills_tool.py
…
slash_confirm.py
…
terminal_hints.py
…
terminal_tool.py
…
thread_context.py
…
threat_patterns.py
…
tirith_security.py
…
todo_tool.py
…
tool_backend_helpers.py
…
tool_output_limits.py
…
tool_result_storage.py
…
tool_search.py
…
transcription_tools.py
…
tts_streaming.py
…
tts_text_normalize.py
…
tts_tool.py
…
url_safety.py
…
video_generation_tool.py
…
vision_tools.py
…
voice_mode.py
…
wake_word.py
…
web_tools.py
…
website_policy.py
…
working_diff.py
…
write_approval.py
…
x_search_tool.py
…
xai_http.py
…
xai_video_tools.py
…
yuanbao_tools.py
…