Describe the bug
The packaged Codex Stop-hook launcher prefers the host-level compatibility copy at ~/.codex/hooks/nowledge-mem-stop-save.py whenever that file exists. Plugin updates can therefore run an older synchronous capture runtime instead of the updated packaged runtime. Because the packaged Stop hook has a 15-second timeout, the stale runtime can be terminated before it finishes.
To Reproduce
- Install an older Nowledge Mem Codex plugin and run
scripts/install_hooks.py so the host-level compatibility hook is copied into ~/.codex/hooks/.
- Update the plugin to a version with a newer Stop-hook runtime without rerunning the installer.
- Complete a Codex turn while both plugin hooks and host hooks are enabled.
- Observe that the packaged launcher selects the old host-level runtime; a slow synchronous capture may end with
Stop hook timed out after 15s.
Expected behavior
The plugin-bundled launcher should execute the runtime shipped in the same plugin version. The host-level copy should remain a compatibility fallback only when the packaged runtime is unavailable. Duplicate suppression should continue to prevent double capture when both hook registrations fire.
Screenshots
Not applicable.
Additional context
The current launcher test and plugin validator explicitly enforce host-level preference, so both contracts need to change. Add regression coverage for a stale host hook coexisting with a current packaged runtime.
A targeted audit found no equivalent packaged-to-stale-host preference in the Copilot CLI, Kimi Code, Cursor, Claude Code, CodeBuddy, Gemini CLI, Droid, or WorkBuddy integrations. Proma uses a single host-installed script model rather than this dual-path launcher pattern.
Acceptance criteria:
- Prefer the packaged Codex Stop-hook runtime when it exists.
- Fall back to the host-level compatibility runtime only when the packaged runtime is absent.
- Preserve the existing duplicate-capture guard and host fallback registration.
- Add a regression test for stale host runtime coexistence.
- Update validation and changelog contracts to describe packaged-first behavior.
Describe the bug
The packaged Codex Stop-hook launcher prefers the host-level compatibility copy at
~/.codex/hooks/nowledge-mem-stop-save.pywhenever that file exists. Plugin updates can therefore run an older synchronous capture runtime instead of the updated packaged runtime. Because the packaged Stop hook has a 15-second timeout, the stale runtime can be terminated before it finishes.To Reproduce
scripts/install_hooks.pyso the host-level compatibility hook is copied into~/.codex/hooks/.Stop hook timed out after 15s.Expected behavior
The plugin-bundled launcher should execute the runtime shipped in the same plugin version. The host-level copy should remain a compatibility fallback only when the packaged runtime is unavailable. Duplicate suppression should continue to prevent double capture when both hook registrations fire.
Screenshots
Not applicable.
Additional context
The current launcher test and plugin validator explicitly enforce host-level preference, so both contracts need to change. Add regression coverage for a stale host hook coexisting with a current packaged runtime.
A targeted audit found no equivalent packaged-to-stale-host preference in the Copilot CLI, Kimi Code, Cursor, Claude Code, CodeBuddy, Gemini CLI, Droid, or WorkBuddy integrations. Proma uses a single host-installed script model rather than this dual-path launcher pattern.
Acceptance criteria: