v1.85.1

EvoMap/evolverv1.85.1May 22, 2026by autogame-17

AI Summary

Fixes the Stop hook to prevent it from re-injecting evolution receipts as user prompts, which was causing extra reasoning turns. Also introduces per-workspace random secrets for better security.

Key Highlights

  • Stop hook no longer re-injects evolution receipts as user prompts.
  • Cursor compatibility improvements for the Stop hook.
  • Per-workspace random secret replaces plain-text `cwd` in `memory_graph.jsonl`.
  • Stop hook process now exits promptly after stdin closes.

New Features

  • Per-workspace random secret in memory_graph.jsonl

Full Release Notes

## Fixed

- **Stop hook no longer re-injects the evolution receipt as a user prompt.**
  The hook used to emit `followup_message`, which by Claude Code spec
  feeds its value back into the next inference round. Agents kept
  "responding" to their own evolution log line — visible to users as an
  unexplained extra reasoning turn after every task. The hook now emits
  only `systemMessage`, a UI-only notification.

- **Cursor compatibility for the Stop hook.** Cursor's Claude Code-compat
  runtime currently treats `systemMessage` as a user prompt as well.
  When Cursor is detected (via `TERM_PROGRAM=cursor`, `CURSOR_TRACE_ID`,
  `CURSOR_SESSION_ID`, or the manual override `EVOLVER_HOOK_HOST=cursor`),
  the hook omits `systemMessage` too. The receipt is always appended to
  `~/.evolver/logs/evolution.log` (override path with
  `EVOLVER_HOOK_LOG_DIR`) so it is never silently lost. Set
  `EVOLVER_HOOK_VERBOSE=1` to force the inline notification on under
  Cursor for debugging.

- **Stop hook process now exits promptly.** A 7 s `setTimeout` watchdog
  was held open for the full duration on every session end because
  it was never cleared after stdin closed. Now cleared explicitly.

- **`evolver --review` no longer raises `memory_missing` / `user_missing` /
  `session_logs_missing` on every cycle when running on Codex (#540).**
  Codex doesn't generate a workspace-root `MEMORY.md` / `USER.md` and
  doesn't expose readable session-transcript files. `collect.js` now
  falls back, in order: `MEMORY.md` / `USER.md` → the
  `<!-- evolver-evolution-memory -->` section that `setup-hooks` injects
  into the workspace's `AGENTS.md` / `CLAUDE.md` → the tail of
  `memory_graph.jsonl` (last 5 outcomes). README adds a "Codex caveats"
  subsection.

## Security

- **Per-workspace random secret replaces plain-text `cwd` self-tag in
  `memory_graph.jsonl` (#109).** v1.85.0 + PR #108 introduced a `cwd`
  field on every memory-graph entry to scope reads at the user-level
  fallback path. The Cursor Bugbot round-3 advisory pointed out that
  `cwd` is a self-report — any process under the same uid could write
  entries claiming a different workspace's `cwd` and poison its reads.
  This release adds `paths.getWorkspaceId()`, which lazily creates
  `<workspace>/.evolver/workspace-id` (mode 0600, 32-hex random) and
  stamps every new entry with `workspace_id`. The reader uses a
  three-tier policy: prefer `workspace_id` matching when the current
  workspace has a secret, fall back to legacy `cwd`-only matching when
  it doesn't (clean upgrade for pre-existing entries), drop entries
  that have neither. The secret file is created with
  `O_WRONLY | O_CREAT | O_EXCL | O_NOFOLLOW` after an `lstat` pre-check,
  so a pre-placed symlink can't redirect the write outside the
  workspace. `EVOLVER_WORKSPACE_ID` env var remains as an explicit
  override / escape hatch. Note: in the co-uid threat model, any process
  under the same uid can still *read* the FS secret — migrating to an
  OS keychain is tracked as a follow-up.

PRs: #109, #110, #540

---

🤖 Generated with [Claude Code](https://claude.com/claude-code)