feat(memory,skills): approve/deny gate for memory + skill writes (#38199)
Adds memory.write_mode and skills.write_mode (on|off|approve), applied to both foreground turns and the background self-improvement review fork — the source of the unprompted 'wrong assumption' saves users reported. - on (default): write freely, unchanged behaviour - off: never write; the tool returns a clean disabled result - approve: don't commit. Memory foreground writes prompt inline (small, reviewable in a chat bubble); background memory writes and ALL skill writes stage to a pending store instead (a SKILL.md is too large to review inline, and a daemon thread can't block on a prompt) Review staged writes from CLI or any messaging platform: /memory pending|approve|reject|mode /skills pending|approve|reject|diff|mode Skill review respects the size asymmetry: inline you see a one-line gist; the full unified diff stays out-of-band (/skills diff, dashboard, or the staged JSON file). New: tools/write_approval.py (gate + pending store), hermes_cli/ write_approval_commands.py (shared CLI+gateway handlers). Gates wired at the single entry points memory_tool() and skill_manage(), using the existing write-origin ContextVar to distinguish foreground from background_review.
This commit is contained in:
@@ -209,8 +209,62 @@ memory:
|
||||
user_profile_enabled: true
|
||||
memory_char_limit: 2200 # ~800 tokens
|
||||
user_char_limit: 1375 # ~500 tokens
|
||||
write_mode: on # on | off | approve
|
||||
```
|
||||
|
||||
## Controlling memory writes (`write_mode`)
|
||||
|
||||
By default the agent saves memory freely — including from the background
|
||||
self-improvement review that runs after a turn. If you'd rather not have
|
||||
memory written behind your back, `memory.write_mode` gives you three options
|
||||
(applied to **both** foreground turns and the background review):
|
||||
|
||||
| Mode | Behaviour |
|
||||
|------|-----------|
|
||||
| `on` | Write freely (default — current behaviour). |
|
||||
| `off` | Never write. The memory tool returns a clean "disabled" result; nothing is saved. |
|
||||
| `approve` | Don't commit writes — review them first. Foreground writes prompt you inline (entries are small enough to read in a chat bubble). Background-review writes are **staged** instead of committed (a background thread can't block on a prompt). |
|
||||
|
||||
Review staged writes from the CLI or any messaging platform:
|
||||
|
||||
```
|
||||
/memory pending # list staged memory writes (auto ones tagged [auto])
|
||||
/memory approve <id> # apply one (or 'all')
|
||||
/memory reject <id> # drop one (or 'all')
|
||||
/memory mode approve # change write_mode and persist it
|
||||
```
|
||||
|
||||
This is the answer to "the agent saved a wrong assumption about me": set
|
||||
`write_mode: approve`, and every save — especially the unprompted background
|
||||
ones — waits for your yes/no before it ever enters your profile.
|
||||
|
||||
## Controlling skill writes (`skills.write_mode`)
|
||||
|
||||
Skills use the same three-state gate, but the review UX differs because a
|
||||
`SKILL.md` is far too large to read in a chat bubble:
|
||||
|
||||
```yaml
|
||||
skills:
|
||||
write_mode: on # on | off | approve
|
||||
```
|
||||
|
||||
In `approve` mode, skill writes (create / edit / patch / write_file / delete)
|
||||
always **stage** regardless of origin. You review the one-line gist inline, but
|
||||
the full diff stays out-of-band:
|
||||
|
||||
```
|
||||
/skills pending # list staged skill writes + a one-line gist each
|
||||
/skills diff <id> # full unified diff (best viewed in CLI or dashboard)
|
||||
/skills approve <id> # apply it (or 'all')
|
||||
/skills reject <id> # drop it (or 'all')
|
||||
/skills mode approve # change write_mode and persist it
|
||||
```
|
||||
|
||||
On a messaging platform, approve a skill from its gist + metadata, or open
|
||||
`/skills diff` on the CLI / dashboard / the staged file under
|
||||
`~/.hermes/pending/skills/<id>.json` when you want to read the whole change.
|
||||
|
||||
|
||||
## External Memory Providers
|
||||
|
||||
For deeper, persistent memory that goes beyond MEMORY.md and USER.md, Hermes ships with 8 external memory provider plugins — including Honcho, OpenViking, Mem0, Hindsight, Holographic, RetainDB, ByteRover, and Supermemory.
|
||||
|
||||
Reference in New Issue
Block a user