Skip to content

refactor: retire legacy src/ hooks; migrate all live behavior to the daemon path#34

Merged
nickroci merged 1 commit into
mainfrom
feat/retire-legacy-src-hooks
Jun 12, 2026
Merged

refactor: retire legacy src/ hooks; migrate all live behavior to the daemon path#34
nickroci merged 1 commit into
mainfrom
feat/retire-legacy-src-hooks

Conversation

@nickroci

Copy link
Copy Markdown
Owner

What & why

Two hook systems ran in parallel: the legacy src/ hooks (package "agent-mem") and the current plugin/daemon path (ultan/ + hooks/hooks.json). The switch to the plugin silently dropped several behaviors that were live before it. This removes src/ entirely and ports every behavior that was live before the switch (the 7-hook ~/.claude/settings.json.ultan-bak set) into the daemon path.

Migrated (were live, lost at the switch)

  • Assistant-prose capture — the daemon now reads the Claude Code transcript on a sealing Stop/SessionEnd and folds the assistant's natural-language turns into the buffer the Librarian sees. Before, only user prompts + tool I/O were captured, so design reasoning never reached memory. daemon/agent_mem_daemon/transcript.py + scheduler injection; ultan/_hooks.py forwards transcript_path.
  • PreToolUse tool-blocking — re-added the dropped 7th hook + ultan/_blockers.py (block_triggers, severity deny|advise). Was live until 2026-06-09 (18k PreToolUse events).
  • Nudge consume/budget/injectultan/_nudges.py completes a half-migrated pipeline: the Scholar still wrote pending-nudges.md but nothing consumed it.
  • SessionStart boot-context injectionultan/_session_context.py (the old handler returned 0 without emitting the additionalContext envelope).
  • project_slug priming parity.

Removed

  • The entire src/ tree + its workspace member, set-version.sh / check-version-coherence.sh entries, CI matrix entry, a dead agent-mem dep.
  • /ultan-install (install.py + README + global command file) — the plugin owns hook installation now.

Preserved / rebuilt

  • agent-mem doctor's structural lint reimplemented in-process (tools/search/_lint.py); it had shelled out to the deleted src/scripts/lint.py. Resolution mirrors the daemon's wikilink_resolves, so it's accurate (0 false broken-links / orphans on the real 542-entry library).

Reviewer notes (judgment calls)

  • Thin-install safety: ultan/ imports no aliases (retrieval-only) — bucket helpers are mirrored locally, matching _priming.py / _session_context.py, so the base install + the no-extra CI job pass. (A regression here was caught and fixed mid-work.)
  • Dropped the lint missing_backlink check: it produced 555 noise suggestions (this library links content one-directionally by design). Trivial to restore if you want strict parity.
  • Assistant-prose is best-effort: a per-session marker dedups; failures degrade to no-prose and never break ingestion.

Verification

  • 79 ultan · 683 daemon (90.6% cov) · 171 tools/search · pyright 0 · ruff + format clean · version coherence OK.
  • agent-mem doctor runs clean against the real store.

🤖 Generated with Claude Code

…daemon path

The project ran two hook systems in parallel: the legacy `src/` hooks (package
"agent-mem") and the current plugin/daemon path (`ultan/` + `hooks/hooks.json`).
The plugin switch silently dropped several behaviors that were live before it.
This removes `src/` entirely and ports every behavior that was live before the
switch (the 7-hook `settings.json` set) into the daemon path.

Migrated (were live, lost at the switch):
- Assistant-prose capture: the daemon reads the Claude Code transcript on a
  sealing Stop/SessionEnd and folds assistant turns into the buffer the
  Librarian sees (daemon/agent_mem_daemon/transcript.py + scheduler injection;
  ultan/_hooks.py forwards transcript_path).
- PreToolUse tool-blocking: re-added the PreToolUse hook + ultan/_blockers.py
  (block_triggers, severity deny|advise).
- Nudge consume/budget/inject: ultan/_nudges.py completes the half-migrated
  pipeline (the Scholar wrote pending-nudges.md but nothing consumed it).
- SessionStart boot-context injection: ultan/_session_context.py.
- project_slug priming parity.

Removed:
- The entire src/ tree + its workspace member, set-version.sh /
  check-version-coherence.sh entries, CI matrix entry, and a dead agent-mem dep.
- The /ultan-install command (install.py + README + global command file) — the
  plugin now owns hook installation.

Preserved/rebuilt:
- `agent-mem doctor`'s structural lint reimplemented in-process
  (tools/search/_lint.py) since it shelled out to the deleted src/scripts/lint.py;
  resolution mirrors the daemon's wikilink_resolves so it's accurate at scale.

Thin-install safety: ultan/ imports no `aliases` (retrieval-only); the bucket
helpers are mirrored locally so the base install + no-extra CI job pass.

Suites green: 79 ultan, 683 daemon, 171 tools/search; pyright 0; ruff clean.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@nickroci nickroci merged commit 4195768 into main Jun 12, 2026
6 checks passed
@nickroci nickroci deleted the feat/retire-legacy-src-hooks branch June 12, 2026 13:54
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant