- Shell variables in write targets expand from the environment plus `p=...` / `export p=...`
assignments earlier in the command.
- Inline interpreter code that writes is refused when its working directory is inside a
locked skill (relative paths), not only when it names the skill.
- A recursive delete/move of a directory holding the lock record is refused even when the only
locked skill lives in skills.external_dirs.
- Reads are no longer refused: inline code counts as writing only for write-mode open(),
write/delete/rename/copy calls and shell write forms; `find -exec` is refused only when the
executed command itself writes.
- locked_skill_dirs resolves every lock in one walk of the skills dirs instead of one
_find_skill search per locked name.
- Newlines separate commands (shlex read them as whitespace, so a second-line `sed -i` hid
behind an `echo`).
- Wrapper options that take a value (`sudo -u root`, `xargs -n 1`) are skipped, reusing
self_repo_guard's wrapper table.
- `( ... )` subshells restore the working directory when they close.
- `cp/mv/install/ln -t DIR` and `--target-directory=DIR` are the write destination.
- Recursive copies (`cp -r`, rsync) and archive extraction into a directory above a locked skill,
inside a skills root, are refused: they can merge into it.
- Globs expand against the filesystem like the shell does, so `sed -i ... ops/*/SKILL.md` is
judged by what it matches.
- The curator's auto-archive check resolves rows (frontmatter names) to the directory-keyed lock
via tools/skill_lock.is_locked_skill.
Builds on the per-skill lock record (`hermes curator lock`): the lock now holds against the
agent everywhere, not only the background passes.
- skill_manage refuses every mutating action on a locked skill for every origin (normal turns,
cron, subagents, review fork, curator); a corrupt sidecar still fails closed only for the
autonomous passes so one broken file can't freeze every skill edit.
- write_file / patch hard-refuse any path inside a locked skill's directory and the lock
record (skills/.usage.json) while any skill is locked (tools/skill_lock.path_refusal, wired
into _check_sensitive_path).
- terminal refuses, before approvals and under --yolo, commands that write into a locked skill:
redirections/tee, cp/mv/rm/touch/mkdir/chmod, sed/perl -i, git changes in its tree, archive
extraction into it, inline python/bash code naming it, including after a cd into it; and the
agent running `hermes curator unlock`. Reads and running the skill's own scripts still work.
- The curator never auto-archives a locked skill.
- Docs: "Locking a skill" rewritten for the new contract.