Skip to content

feat(hooks): add Empryo session capture - #341

Merged
edheltzel merged 5 commits into
mainfrom
feat/empryo-adapter
Oct 20, 2026
Merged

edheltzel merged 5 commits into
mainfrom
feat/empryo-adapter

Conversation

@Atlas-Key

Copy link
Copy Markdown
Collaborator

What Changed

  • Add Empryo session-log capture through existing Claude Stop hooks, plus bounded history capture for manually configured SessionEnd hooks.
  • Share capture helpers and prevent Empryo sessions from entering Claude transcript extraction or pre-compaction fallback paths.
  • Add adapter regression coverage, uninstall cleanup, and integration documentation covering MCP setup, skill discovery, custom databases, and capture limits.

Risk Assessment

✅ Low: The adapter is bounded, reuses the existing capture boundary, and introduces no substantiated material defects in the reviewed paths.

Testing

Focused adapter tests, the production build, native Empryo capture/resume, database forwarding, adversarial hook checks, MCP retrieval, and lifecycle cleanup passed after resolving harness setup issues. CLI and persisted-state evidence is retained; disposable processes and data were removed. No rendered UI was changed or exercised.

  • Live validation: ✅ go - 11 of 11 scenarios driven live against the product
Scenario Result Live Evidence
Complete and resume an Empryo session; both turns become searchable in the forwarded custom database. ✅ pass live Native Empryo commands and hook completion; Product transcript
Forward legacy MEM_DB_PATH; the completed Empryo turn reaches that database. ✅ pass live Native Empryo commands and hook completion
Forward both database variables; RECALL_DB_PATH wins and the legacy database remains empty. ✅ pass live Native Empryo commands and hook completion; native-precedence-persisted.json
Omit custom-database forwarding; Empryo filters the variable and capture reaches the sandbox default database. ✅ pass live Product transcript
Fire concurrent and repeated Stop hooks; each recent tab's latest visible turn is stored once, excluding stale, hidden, tool, and incomplete content. ✅ pass live Hook commands and searches; Product transcript
Fire and repeat SessionEnd; all completed visible turns persist without duplicate replay. ✅ pass live SessionEnd persisted memory; Hook commands and searches
Supply unknown-version, unversioned, and missing Empryo logs beside a Claude transcript; no unrelated memory is captured. ✅ pass live Hook commands and searches
Run PreCompact and enabled in-session extraction on Empryo logs; extraction is skipped while explicit correction capture remains searchable. ✅ pass live Hook commands and searches; Product transcript
End an oversized session; the newest completed turn fitting the serialized input cap remains searchable. ✅ pass live Oversized capture persisted memory; Hook commands and searches
Connect Recall MCP and search for a native Empryo turn; the captured prompt and answer are returned. ✅ pass live MCP search response
Run installer hook-copy and registration steps, capture through installed links, then uninstall; managed adapter links disappear while foreign helpers and searchable memory survive. ✅ pass live Installation and uninstall transcript
Evidence: Product transcript
# Empryo live product evidence

Runtime: official Empryo 3.10.1-beta, Bun 1.4.2, built Recall CLI and MCP server. The model API was a disposable local endpoint. Recall, Empryo, hooks, CLI search, MCP, and SQLite storage were real. All homes and data paths were inside the assigned worktree.

## Complete Empryo turns, Stop receipts, and CLI search

`` `text
Empryo: Recorded nativeproof901 in the disposable Empryo session.
exit status: 0
`` `

`` `text
$ recall search nativeproof901 -t messages
Found 1 result(s):

[messages#1] [project] 2026-10-20
  user: Remember nativeproof901 for the Recall integration.  assistant: Recorded nativeproof901 in the...
exit status: 0
`` `

`` `text
Empryo: Recorded nativeproof902 in the disposable Empryo session.
exit status: 0
`` `

`` `text
$ recall search nativeproof902 -t messages
Found 1 result(s):

[messages#2] [project] 2026-10-20
  user: Remember nativeproof902 for the Recall integration.  assistant: Recorded nativeproof902 in the...
exit status: 0
`` `

`` `text
Empryo: Recorded nativeproof903 in the disposable Empryo session.
exit status: 0
`` `

`` `text
$ recall search nativeproof903 -t messages
Found 1 result(s):

[messages#1] [project] 2026-10-20
  user: Remember nativeproof903 for the Recall integration.  assistant: Recorded nativeproof903 in the...
exit status: 0
`` `

`` `text
Empryo: Recorded nativeproof904 in the disposable Empryo session.
exit status: 0
`` `

`` `text
Empryo: Recorded nativeproof905 in the disposable Empryo session.
exit status: 0
`` `

`` `text
$ recall search nativeproof905 -t messages
No results found.
exit status: 0
`` `

`` `text
$ recall search nativeproof905 -t messages
Found 1 result(s):

[messages#1] [project] 2026-10-20
  user: Remember nativeproof905 for the Recall integration.  assistant: Recorded nativeproof905 in the...
exit status: 0
`` `

## Persisted native capture

`` `json
{
  "messages": [
    {
      "id": 1,
      "session_id": "nativeprimary901",
      "content": "user: Remember nativeproof901 for the Recall integration.\n\nassistant: Recorded nativeproof901 in the disposable Empryo session."
    },
    {
      "id": 2,
      "session_id": "nativeprimary901",
      "content": "user: Remember nativeproof902 for the Recall integration.\n\nassistant: Recorded nativeproof902 in the disposable Empryo session."
    }
  ],
  "loa": [
    {
      "session_id": "nativeprimary901",
      "tags": "automatic-capture,empryo",
      "importance": 6
    }
  ]
}
`` `

## Unforwarded-variable control

The real hook receipt contains no database override; the custom database stays empty and the sandbox default retains the turn.

`` `json
{"input":{"session_id":"nativeunforwarded905","transcript_path":"~/.no-mistakes/worktrees/fd32172f1538/01M5BB78BDJEKXV3P5K2S4HTTH/.local-test-empryo/native-final-complete/unforwarded/project/.empryo/sessions/nativeunforwarded905/session.jsonl","cwd":"~/.no-mistakes/worktrees/fd32172f1538/01M5BB78BDJEKXV3P5K2S4HTTH/.local-test-empryo/native-final-complete/unforwarded/project","hook_event_name":"Stop","stop_hook_active":true},"env":{"HOME":"~/.no-mistakes/worktrees/fd32172f1538/01M5BB78BDJEKXV3P5K2S4HTTH/.local-test-empryo/native-final-complete/unforwarded/home"},"code":0,"out":"","err":""}
{
  "custom": {
    "messages": [],
    "loa": []
  },
  "fallback": {
    "messages": [
      {
        "id": 1,
        "session_id": "nativeunforwarded905",
        "content": "user: Remember nativeproof905 for the Recall integration.\n\nassistant: Recorded nativeproof905 in the disposable Empryo session."
      }
    ],
    "loa": [
      {
        "session_id": "nativeunforwarded905",
        "tags": "automatic-capture,empryo",
        "importance": 6
      }
    ]
  }
}
`` `

## MCP readback

`` `text
Found 2 results for "nativeproof901":

[messages#1] project | 2026-10-20T00:41:49.352Z | provenance: verbatim
user: Remember nativeproof901 for the Recall integration.

assistant: Recorded nativeproof901 in the disposable Empryo session.

---

[loa#1] project | 2026-10-20 00:41:49 | provenance: extracted
Empryo session nativeprimary901: ## ONE SENTENCE SUMMARY

Session with 2 messages.

## MAIN IDEAS

- User started with: user: Remember nativeproof901 for the Recall integration.

assistant: Recorded n...
`` `

## Stop selection and exclusions

`` `json
{
  "messages": [
    {
      "id": 1,
      "session_id": "tabs701",
      "role": "user",
      "content": "user: sideproof701\n\nassistant: Side reply.",
      "chars": 42
    },
    {
      "id": 3,
      "session_id": "tabs701",
      "role": "user",
      "content": "user: latestproof701\n\nassistant: Latest reply.",
      "chars": 46
    }
  ],
  "loa": [
    {
      "session_id": "tabs701",
      "tags": "automatic-capture,empryo",
      "importance": 6
    }
  ]
}
`` `

`` `text
$ recall search hiddenproof701 -t messages
No results found.
exit status: 0
`` `

`` `text
$ recall search incompleteproof701 -t messages
No results found.
exit status: 0
`` `

`` `text
$ recall search toolsecretproof701 -t messages
No results found.
exit status: 0
`` `

`` `text
$ recall search tooloutputproof701 -t messages
No results found.
exit status: 0
`` `

`` `text
$ recall search unrelatedclaude701 -t messages
No results found.
exit status: 0
`` `

`` `text
$ recall search correctionproof701 -t learnings
Found 1 result(s):

[learnings#1] [project] 2026-10-20 00:39:53
  That's wrong, use correctionproof701 instead.
exit status: 0
`` `

`` `text
$ recall search newestbig701 -t messages
Found 1 result(s):

[messages#1] [project] 2026-10-20
  user: newestbig701 """""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""...
exit status: 0
`` `

## Installation and uninstall

The installer hook-copy and hook-registration steps created canonical files and managed symlinks. The installed Stop hook captured a turn. The real uninstall script removed the adapter link and its empty directory, retained the foreign helper, and preserved searchable memory.

`` `text
$ recall search lifecycleproof701 -t messages
Found 1 result(s):

[messages#1] [project] 2026-10-20
  user: lifecycleproof701  assistant: Installed adapter works.
exit status: 0
`` `

`` `text
$ recall search lifecycleproof701 -t messages
Found 1 result(s):

[messages#1] [project] 2026-10-20
  user: lifecycleproof701  assistant: Installed adapter works.
exit status: 0
`` `

## Scope of verification

The existing Empryo test file and production build completed successfully. Native Stop checks waited for receipts containing the capture child exit status. Direct hook scenarios covered concurrent repeat hooks, SessionEnd, unsupported/missing/unversioned logs, PreCompact, enabled in-session extraction with corrections, and the serialized input-size limit. No GUI was changed or exercised; the product surfaces here are headless CLI, hooks, MCP, and persisted memory.

Early harness attempts searched before background Stop completion, used the old resume flag, and hit a read-only SQLite observer error during native shutdown. Those setup issues were corrected; the retained final scenario files describe the completed rerun. The installed 3.10.0-beta was left unchanged; the verified official 3.10.1-beta bundle ran only inside the disposable worktree.
Evidence: Native Empryo commands and hook completion
{"command":["~/.bun/bin/bun","~/.no-mistakes/worktrees/fd32172f1538/01M5BB78BDJEKXV3P5K2S4HTTH/dist/index.js","init"],"code":0,"out":"✓ Created database at ~/.no-mistakes/worktrees/fd32172f1538/01M5BB78BDJEKXV3P5K2S4HTTH/.local-test-empryo/native-final-complete/primary/custom.db\n","err":""}
{"command":["~/.no-mistakes/worktrees/fd32172f1538/01M5BB78BDJEKXV3P5K2S4HTTH/.local-test-empryo/empryo-3.10.1-beta-darwin-arm64/empryo","--headless","--events","--model","recall-fixture/recall-fixture","--mode","default","--no-genome","--no-profile","--session-id","nativeprimary901","--save-session","--max-steps","3","--timeout","15000","--cwd","~/.no-mistakes/worktrees/fd32172f1538/01M5BB78BDJEKXV3P5K2S4HTTH/.local-test-empryo/native-final-complete/primary/project","Remember nativeproof901 for the Recall integration."],"code":0,"out":"{\"type\":\"start\",\"model\":\"recall-fixture/recall-fixture\",\"mode\":\"default\",\"session\":\"nativeprimary901\",\"checkout\":{\"root\":\"~/.no-mistakes/worktrees/fd32172f1538/01M5BB78BDJEKXV3P5K2S4HTTH\",\"kind\":\"linked\",\"branch\":null,\"name\":\"01M5BB78BDJEKXV3P5K2S4HTTH\"},\"genome\":null,\"workers\":{\"intelligence\":\"starting\",\"io\":\"ready\"}}\n{\"type\":\"bg-error\",\"errorId\":\"mvfykam9_1\",\"source\":\"mcp\",\"message\":\"MCP server \\\"recall-memory\\\" resources/list: Server does not support resources\",\"ts\":1792456908993}\n{\"type\":\"mcp-state\",\"servers\":{\"recall-memory\":{\"name\":\"recall-memory\",\"status\":\"ready\",\"toolCount\":9,\"error\":null,\"transport\":\"stdio\",\"tools\":[{\"name\":\"memory_search\",\"description\":\"Search memory using FTS5 full-text search. Use this BEFORE asking the user to repeat anything. Searches across messages, LoA entries, decisions, learnings, and breadcrumbs.\"},{\"name\":\"memory_hybrid_search\",\"description\":\"Hybrid search, or the configured query harness when that key is present. A local win stays on the configured mode. Falls back to keyword-only if embeddings are unavailable and the mode is hybrid.\"},{\"name\":\"memory_recall\",\"description\":\"Recall recent memory entries. Use at session start or when context is needed. Returns recent LoA entries, decisions, and breadcrumbs.\"},{\"name\":\"loa_show\",\"description\":\"Show a full Library of Alexandria entry. The body is fabric_extract (column name, not the writer).\"},{\"name\":\"memory_add\",\"description\":\"Add a structured memory record (decision, learning, or breadcrumb). Use to capture important context during sessions.\"},{\"name\":\"decision_update\",\"description\":\"Update a decision's lifecycle status. Use 'supersede' when a newer decision replaces an older one. Use 'revert' when a decision was wrong and rolled back. Only active decisions can be transitioned.\"},{\"name\":\"memory_dump\",\"description\":\"Dump a conversation session into SQLite for immediate searchability. Pass messages for host-portable capture. If messages are omitted, Recall attempts legacy native-session discovery for Claude Code, OpenCode, or Pi; MCP does not provide lifecycle auto-capture by itself.\"},{\"name\":\"memory_stats\",\"description\":\"Get RECALL database statistics.\"},{\"name\":\"context_for_agent\",\"description\":\"Prepare context before spawning an agent. Uses the configured query harness when that key is present. A local win stays on that mode.\"}]}}}\n{\"type\":\"session-load-progress\",\"sessionId\":\"nativeprimary901\",\"percent\":5,\"stage\":\"Reading session log\"}\n{\"type\":\"session-load-progress\",\"sessionId\":\"nativeprimary901\",\"percent\":20,\"stage\":\"Rebuilding conversation\"}\n{\"type\":\"session-load-progress\",\"sessionId\":\"nativeprimary901\",\"percent\":20,\"stage\":\"Preparing tabs\"}\n{\"type\":\"session-load-progress\",\"sessionId\":\"nativeprimary901\",\"percent\":20,\"stage\":\"Waking agent — TAB-1\"}\n{\"type\":\"session-load-progress\",\"sessionId\":\"nativeprimary901\",\"percent\":55,\"stage\":\"Restoring transcript & costs: TAB-1\"}\n{\"type\":\"session-load-progress\",\"sessionId\":\"nativeprimary901\",\"percent\":95,\"stage\":\"Attaching session log\"}\n{\"type\":\"artifacts-reset\",\"sessionId\":\"nativeprimary901\"}\n{\"type\":\"session-load-progress\",\"sessionId\":\"nativeprimary901\",\"percent\":100,\"stage\":\"Done\"}\n{\"type\":\"workbench-changed\",\"registry\":\"link\"}\n{\"type\":\"workbench-changed\",\"registry\":\"routines\"}\n{\"type\":\"turn-start\",\"tabId\":\"8b4e74a6-d830-4561-9e57-628b76232554\",\"id\":\"turn-1474c15e-f2b6-4e22-9a8d-aa51244667d9-6\",\"prompt\":\"Remember nativeproof901 for the Recall integration.\",\"absorbs\":[]}\n{\"type\":\"model-wait\",\"tabId\":\"8b4e74a6-d830-4561-9e57-628b76232554\",\"id\":\"turn-1474c15e-f2b6-4e22-9a8d-aa51244667d9-6\",\"modelId\":\"recall-fixture/recall-fixture\",\"phase\":\"sent\",\"at\":1792456909244}\n{\"type\":\"model-wait\",\"tabId\":\"8b4e74a6-d830-4561-9e57-628b76232554\",\"id\":\"turn-1474c15e-f2b6-4e22-9a8d-aa51244667d9-6\",\"modelId\":\"recall-fixture/recall-fixture\",\"phase\":\"generating\",\"at\":1792456909250}\n{\"type\":\"text-start\",\"tabId\":\"8b4e74a6-d830-4561-9e57-628b76232554\",\"id\":\"turn-1474c15e-f2b6-4e22-9a8d-aa51244667d9-6\",\"blockId\":\"txt-0\"}\n{\"type\":\"text\",\"content\":\"Recorded nativeproof901 in the disposable Empryo session.\"}\n{\"type\":\"text-end\",\"tabId\":\"8b4e74a6-d830-4561-9e57-628b76232554\",\"id\":\"turn-1474c15e-f2b6-4e22-9a8d-aa51244667d9-6\",\"blockId\":\"txt-0\"}\n{\"type\":\"model-call\",\"modelId\":\"recall-fixture/recall-fixture\",\"source\":\"main\",\"lane\":\"main\",\"tabId\":\"8b4e74a6-d830-4561-9e57-628b76232554\",\"startedAt\":1792456909244,\"durationMs\":7,\"state\":\"ok\",\"input\":0,\"output\":0,\"cacheRead\":0,\"cacheWrite\":0}\n{\"type\":\"step\",\"step\":1,\"tokens\":{\"input\":0,\"output\":0,\"cacheRead\":0,\"cacheWrite\":0,\"lastStepRequest\":{\"requestChars\":71324,\"systemChars\":16928,\"overheadChars\":53725}},\"cost\":0}\n{\"type\":\"context-status\",\"tabId\":\"8b4e74a6-d830-4561-9e57-628b76232554\",\"tokens\":17713,\"chars\":70850,\"contextWindow\":256000,\"usableTokens\":236000,\"usableChars\":0,\"requestCharCap\":0,\"pct\":0.06919140625,\"tokenPct\":0.06919140625,\"charPct\":0,\"triggerPct\":0.95,\"limitedBy\":\"tokens\",\"estimated\":true,\"strategy\":\"auto\",\"slots\":2,\"compacting\":false}\n{\"type\":\"model-call\",\"modelId\":\"recall-fixture/recall-fixture\",\"source\":\"other\",\"lane\":\"namer\",\"tabId\":\"8b4e74a6-d830-4561-9e57-628b76232554\",\"startedAt\":1792456909255,\"durationMs\":3,\"state\":\"ok\",\"input\":0,\"output\":0,\"cacheRead\":0,\"cacheWrite\":0}\n{\"type\":\"tab-label\",\"tabId\":\"8b4e74a6-d830-4561-9e57-628b76232554\",\"label\":\"Recall proof\"}\n{\"type\":\"tab-idle\",\"tabId\":\"8b4e74a6-d830-4561-9e57-628b76232554\"}\n{\"type\":\"session-saved\",\"sessionId\":\"nativeprimary901\"}\n{\"type\":\"done\",\"output\":\"Recorded nativeproof901 in the disposable Empryo session.\",\"steps\":1,\"tokens\":{\"input\":0,\"output\":0,\"cacheRead\":0,\"cacheWrite\":0},\"cost\":0,\"toolCalls\":[],\"filesEdited\":[],\"duration\":51}\n","err":"mcp: MCP server \"recall-memory\" resources/list: Server does not support resources\n"}
{"command":["~/.bun/bin/bun","~/.no-mistakes/worktrees/fd32172f1538/01M5BB78BDJEKXV3P5K2S4HTTH/dist/index.js","search","nativeproof901","-t","messages"],"code":0,"out":"Found 1 result(s):\n\n[messages#1] [project] 2026-10-20\n  user: Remember nativeproof901 for the Recall integration.  assistant: Recorded nativeproof901 in the...\n\n","err":""}
{"command":["~/.no-mistakes/worktrees/fd32172f1538/01M5BB78BDJEKXV3P5K2S4HTTH/.local-test-empryo/empryo-3.10.1-beta-darwin-arm64/empryo","--headless","--events","--model","recall-fixture/recall-fixture","--mode","default","--no-genome","--no-profile","--resume","nativeprimary901","--save-session","--max-steps","3","--timeout","15000","--cwd","~/.no-mistakes/worktrees/fd32172f1538/01M5BB78BDJEKXV3P5K2S4HTTH/.local-test-empryo/native-final-complete/primary/project","Remember nativeproof902 for the Recall integration."],"code":0,"out":"{\"type\":\"sta

... [21607 bytes truncated] ...

Users/ed/.no-mistakes/worktrees/fd32172f1538/01M5BB78BDJEKXV3P5K2S4HTTH/dist/index.js","init"],"code":0,"out":"✓ Created database at ~/.no-mistakes/worktrees/fd32172f1538/01M5BB78BDJEKXV3P5K2S4HTTH/.local-test-empryo/native-final-complete/unforwarded/custom.db\n","err":""}
{"command":["~/.bun/bin/bun","~/.no-mistakes/worktrees/fd32172f1538/01M5BB78BDJEKXV3P5K2S4HTTH/dist/index.js","init"],"code":0,"out":"✓ Created database at ~/.no-mistakes/worktrees/fd32172f1538/01M5BB78BDJEKXV3P5K2S4HTTH/.local-test-empryo/native-final-complete/unforwarded/home/.agents/Recall/recall.db\n","err":""}
{"command":["~/.no-mistakes/worktrees/fd32172f1538/01M5BB78BDJEKXV3P5K2S4HTTH/.local-test-empryo/empryo-3.10.1-beta-darwin-arm64/empryo","--headless","--events","--model","recall-fixture/recall-fixture","--mode","default","--no-genome","--no-profile","--session-id","nativeunforwarded905","--save-session","--max-steps","3","--timeout","15000","--cwd","~/.no-mistakes/worktrees/fd32172f1538/01M5BB78BDJEKXV3P5K2S4HTTH/.local-test-empryo/native-final-complete/unforwarded/project","Remember nativeproof905 for the Recall integration."],"code":0,"out":"{\"type\":\"start\",\"model\":\"recall-fixture/recall-fixture\",\"mode\":\"default\",\"session\":\"nativeunforwarded905\",\"checkout\":{\"root\":\"~/.no-mistakes/worktrees/fd32172f1538/01M5BB78BDJEKXV3P5K2S4HTTH\",\"kind\":\"linked\",\"branch\":null,\"name\":\"01M5BB78BDJEKXV3P5K2S4HTTH\"},\"genome\":null,\"workers\":{\"intelligence\":\"starting\",\"io\":\"ready\"}}\n{\"type\":\"bg-error\",\"errorId\":\"mvfykd8w_1\",\"source\":\"mcp\",\"message\":\"MCP server \\\"recall-memory\\\" resources/list: Server does not support resources\",\"ts\":1792456912400}\n{\"type\":\"mcp-state\",\"servers\":{\"recall-memory\":{\"name\":\"recall-memory\",\"status\":\"ready\",\"toolCount\":9,\"error\":null,\"transport\":\"stdio\",\"tools\":[{\"name\":\"memory_search\",\"description\":\"Search memory using FTS5 full-text search. Use this BEFORE asking the user to repeat anything. Searches across messages, LoA entries, decisions, learnings, and breadcrumbs.\"},{\"name\":\"memory_hybrid_search\",\"description\":\"Hybrid search, or the configured query harness when that key is present. A local win stays on the configured mode. Falls back to keyword-only if embeddings are unavailable and the mode is hybrid.\"},{\"name\":\"memory_recall\",\"description\":\"Recall recent memory entries. Use at session start or when context is needed. Returns recent LoA entries, decisions, and breadcrumbs.\"},{\"name\":\"loa_show\",\"description\":\"Show a full Library of Alexandria entry. The body is fabric_extract (column name, not the writer).\"},{\"name\":\"memory_add\",\"description\":\"Add a structured memory record (decision, learning, or breadcrumb). Use to capture important context during sessions.\"},{\"name\":\"decision_update\",\"description\":\"Update a decision's lifecycle status. Use 'supersede' when a newer decision replaces an older one. Use 'revert' when a decision was wrong and rolled back. Only active decisions can be transitioned.\"},{\"name\":\"memory_dump\",\"description\":\"Dump a conversation session into SQLite for immediate searchability. Pass messages for host-portable capture. If messages are omitted, Recall attempts legacy native-session discovery for Claude Code, OpenCode, or Pi; MCP does not provide lifecycle auto-capture by itself.\"},{\"name\":\"memory_stats\",\"description\":\"Get RECALL database statistics.\"},{\"name\":\"context_for_agent\",\"description\":\"Prepare context before spawning an agent. Uses the configured query harness when that key is present. A local win stays on that mode.\"}]}}}\n{\"type\":\"session-load-progress\",\"sessionId\":\"nativeunforwarded905\",\"percent\":5,\"stage\":\"Reading session log\"}\n{\"type\":\"session-load-progress\",\"sessionId\":\"nativeunforwarded905\",\"percent\":20,\"stage\":\"Rebuilding conversation\"}\n{\"type\":\"session-load-progress\",\"sessionId\":\"nativeunforwarded905\",\"percent\":20,\"stage\":\"Preparing tabs\"}\n{\"type\":\"session-load-progress\",\"sessionId\":\"nativeunforwarded905\",\"percent\":20,\"stage\":\"Waking agent — TAB-1\"}\n{\"type\":\"session-load-progress\",\"sessionId\":\"nativeunforwarded905\",\"percent\":55,\"stage\":\"Restoring transcript & costs: TAB-1\"}\n{\"type\":\"session-load-progress\",\"sessionId\":\"nativeunforwarded905\",\"percent\":95,\"stage\":\"Attaching session log\"}\n{\"type\":\"artifacts-reset\",\"sessionId\":\"nativeunforwarded905\"}\n{\"type\":\"session-load-progress\",\"sessionId\":\"nativeunforwarded905\",\"percent\":100,\"stage\":\"Done\"}\n{\"type\":\"workbench-changed\",\"registry\":\"link\"}\n{\"type\":\"workbench-changed\",\"registry\":\"routines\"}\n{\"type\":\"turn-start\",\"tabId\":\"3fc467a8-cb06-4ca1-abcb-5361db2d127c\",\"id\":\"turn-1991a6b4-908a-44d1-aa5b-07757475b830-6\",\"prompt\":\"Remember nativeproof905 for the Recall integration.\",\"absorbs\":[]}\n{\"type\":\"model-wait\",\"tabId\":\"3fc467a8-cb06-4ca1-abcb-5361db2d127c\",\"id\":\"turn-1991a6b4-908a-44d1-aa5b-07757475b830-6\",\"modelId\":\"recall-fixture/recall-fixture\",\"phase\":\"sent\",\"at\":1792456912647}\n{\"type\":\"model-wait\",\"tabId\":\"3fc467a8-cb06-4ca1-abcb-5361db2d127c\",\"id\":\"turn-1991a6b4-908a-44d1-aa5b-07757475b830-6\",\"modelId\":\"recall-fixture/recall-fixture\",\"phase\":\"generating\",\"at\":1792456912653}\n{\"type\":\"text-start\",\"tabId\":\"3fc467a8-cb06-4ca1-abcb-5361db2d127c\",\"id\":\"turn-1991a6b4-908a-44d1-aa5b-07757475b830-6\",\"blockId\":\"txt-0\"}\n{\"type\":\"text\",\"content\":\"Recorded nativeproof905 in the disposable Empryo session.\"}\n{\"type\":\"text-end\",\"tabId\":\"3fc467a8-cb06-4ca1-abcb-5361db2d127c\",\"id\":\"turn-1991a6b4-908a-44d1-aa5b-07757475b830-6\",\"blockId\":\"txt-0\"}\n{\"type\":\"model-call\",\"modelId\":\"recall-fixture/recall-fixture\",\"source\":\"main\",\"lane\":\"main\",\"tabId\":\"3fc467a8-cb06-4ca1-abcb-5361db2d127c\",\"startedAt\":1792456912647,\"durationMs\":6,\"state\":\"ok\",\"input\":0,\"output\":0,\"cacheRead\":0,\"cacheWrite\":0}\n{\"type\":\"step\",\"step\":1,\"tokens\":{\"input\":0,\"output\":0,\"cacheRead\":0,\"cacheWrite\":0,\"lastStepRequest\":{\"requestChars\":71328,\"systemChars\":16932,\"overheadChars\":53725}},\"cost\":0}\n{\"type\":\"context-status\",\"tabId\":\"3fc467a8-cb06-4ca1-abcb-5361db2d127c\",\"tokens\":17714,\"chars\":70854,\"contextWindow\":256000,\"usableTokens\":236000,\"usableChars\":0,\"requestCharCap\":0,\"pct\":0.0691953125,\"tokenPct\":0.0691953125,\"charPct\":0,\"triggerPct\":0.95,\"limitedBy\":\"tokens\",\"estimated\":true,\"strategy\":\"auto\",\"slots\":2,\"compacting\":false}\n{\"type\":\"model-call\",\"modelId\":\"recall-fixture/recall-fixture\",\"source\":\"other\",\"lane\":\"namer\",\"tabId\":\"3fc467a8-cb06-4ca1-abcb-5361db2d127c\",\"startedAt\":1792456912658,\"durationMs\":3,\"state\":\"ok\",\"input\":0,\"output\":0,\"cacheRead\":0,\"cacheWrite\":0}\n{\"type\":\"tab-label\",\"tabId\":\"3fc467a8-cb06-4ca1-abcb-5361db2d127c\",\"label\":\"Recall proof\"}\n{\"type\":\"tab-idle\",\"tabId\":\"3fc467a8-cb06-4ca1-abcb-5361db2d127c\"}\n{\"type\":\"session-saved\",\"sessionId\":\"nativeunforwarded905\"}\n{\"type\":\"done\",\"output\":\"Recorded nativeproof905 in the disposable Empryo session.\",\"steps\":1,\"tokens\":{\"input\":0,\"output\":0,\"cacheRead\":0,\"cacheWrite\":0},\"cost\":0,\"toolCalls\":[],\"filesEdited\":[],\"duration\":51}\n","err":"mcp: MCP server \"recall-memory\" resources/list: Server does not support resources\n"}
{"command":["~/.bun/bin/bun","~/.no-mistakes/worktrees/fd32172f1538/01M5BB78BDJEKXV3P5K2S4HTTH/dist/index.js","search","nativeproof905","-t","messages"],"code":0,"out":"No results found.\n","err":""}
{"command":["~/.bun/bin/bun","~/.no-mistakes/worktrees/fd32172f1538/01M5BB78BDJEKXV3P5K2S4HTTH/dist/index.js","search","nativeproof905","-t","messages"],"code":0,"out":"Found 1 result(s):\n\n[messages#1] [project] 2026-10-20\n  user: Remember nativeproof905 for the Recall integration.  assistant: Recorded nativeproof905 in the...\n\n","err":""}
  • Evidence: Hook commands and searches (local file: ~/.no-mistakes/evidence/01M5BB78BDJEKXV3P5K2S4HTTH/hook-commands.jsonl)
Evidence: SessionEnd persisted memory
{
  "messages": [
    {
      "id": 1,
      "session_id": "end701",
      "role": "user",
      "content": "user: staleproof701\n\nassistant: Stale reply.\n\nuser: earlierproof701\n\nassistant: Earlier reply.\n\nuser: sideproof701\n\nassistant: Side reply.\n\nuser: latestproof701\n\nassistant: Latest reply.",
      "chars": 186
    }
  ],
  "loa": [
    {
      "session_id": "end701",
      "tags": "automatic-capture,empryo",
      "importance": 6
    }
  ]
}
Evidence: Oversized capture persisted memory
{
  "messages": [
    {
      "id": 1,
      "session_id": "big701",
      "role": "user",
      "content": "user: newestbig701 \"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\" ... [large content omitted]",
      "chars": 9437218
    }
  ],
  "loa": [
    {
      "session_id": "big701",
      "tags": "automatic-capture,empryo",
      "importance": 6
    }
  ]
}
Evidence: MCP search response
{
  "tools": [
    "memory_search",
    "memory_hybrid_search",
    "memory_recall",
    "loa_show",
    "memory_add",
    "decision_update",
    "memory_dump",
    "memory_stats",
    "context_for_agent"
  ],
  "result": {
    "content": [
      {
        "type": "text",
        "text": "Found 2 results for \"nativeproof901\":\n\n[messages#1] project | 2026-10-20T00:41:49.352Z | provenance: verbatim\nuser: Remember nativeproof901 for the Recall integration.\n\nassistant: Recorded nativeproof901 in the disposable Empryo session.\n\n---\n\n[loa#1] project | 2026-10-20 00:41:49 | provenance: extracted\nEmpryo session nativeprimary901: ## ONE SENTENCE SUMMARY\n\nSession with 2 messages.\n\n## MAIN IDEAS\n\n- User started with: user: Remember nativeproof901 for the Recall integration.\n\nassistant: Recorded n..."
      }
    ]
  }
}
Evidence: Installation and uninstall transcript
{"command":["bash","-c","source lib/install-lib.sh && _recall_copy_hook_files && recall_register_all_hooks"],"code":0,"out":"✓ Installed hook: RecallExtract.ts\n✓ Installed hook: RecallBatchExtract.ts\n✓ Installed hook: RecallTelosSync.ts\n✓ Installed hook: RecallStart.ts\n✓ Installed hook: RecallPreCompact.ts\n✓ Installed hook: RecallInSession.ts\n✓ Installed hook: RecallClearExtract.ts\n✓ Installed hooks/lib/ (34 files)\n✓ Installed extraction prompt template\n✓ Registered RecallExtract hook (Stop) in settings.json\n✓ Registered RecallTelosSync hook (SessionStart) in settings.json\n✓ Registered RecallStart hook (SessionStart) in settings.json\n✓ Registered RecallPreCompact hook (PreCompact) in settings.json\n✓ Registered RecallInSession hook (PostToolUse) in settings.json\n✓ Registered RecallInSession hook (UserPromptSubmit) in settings.json\n✓ Registered RecallClearExtract hook (SessionStart) in settings.json\n","err":""}
{"command":["~/.bun/bin/bun","~/.no-mistakes/worktrees/fd32172f1538/01M5BB78BDJEKXV3P5K2S4HTTH/dist/index.js","init"],"code":0,"out":"✓ Created database at ~/.no-mistakes/worktrees/fd32172f1538/01M5BB78BDJEKXV3P5K2S4HTTH/.local-test-empryo/lifecycle/recall.db\n","err":""}
{"command":["~/.bun/bin/bun","~/.no-mistakes/worktrees/fd32172f1538/01M5BB78BDJEKXV3P5K2S4HTTH/.local-test-empryo/lifecycle/home/.claude/hooks/RecallExtract.ts"],"input":{"hook_event_name":"Stop","session_id":"lifecycle701","transcript_path":"~/.no-mistakes/worktrees/fd32172f1538/01M5BB78BDJEKXV3P5K2S4HTTH/.local-test-empryo/lifecycle/project/.empryo/sessions/lifecycle701/session.jsonl","cwd":"~/.no-mistakes/worktrees/fd32172f1538/01M5BB78BDJEKXV3P5K2S4HTTH/.local-test-empryo/lifecycle/project"},"code":0,"out":"","err":""}
{"command":["~/.bun/bin/bun","~/.no-mistakes/worktrees/fd32172f1538/01M5BB78BDJEKXV3P5K2S4HTTH/dist/index.js","search","lifecycleproof701","-t","messages"],"code":0,"out":"Found 1 result(s):\n\n[messages#1] [project] 2026-10-20\n  user: lifecycleproof701  assistant: Installed adapter works.\n\n","err":""}
{"command":["bash","packaging/uninstall.sh","--no-confirm","--skip-opencode","--skip-pi","--skip-omp","--skip-grok"],"code":0,"out":"\n╔══════════════════════════════════════════════════════════╗\n║                     Recall Uninstall                     ║\n╚══════════════════════════════════════════════════════════╝\n\nMode: LIVE\nSkipping: OpenCode\nSkipping: Pi\nSkipping: Grok\nSkipping: omp\n\nWill REMOVE (Recall integration files; skill/command cleanup unlinks managed symlinks only and removes directories only when empty):\n  • Legacy ~/.claude/commands/Recall/ and lowercase ~/.claude/commands/recall/\n  • Recall-owned skills in Claude, Pi, and omp skills directories\n  • ~/.claude/Recall_GUIDE.md\n  • Recall hook entries in ~/.claude/settings.json and ~/.claude.json\n  • Recall mcpServers entry in ~/.claude/settings.json and ~/.claude.json\n  • ~/.claude/hooks/*.ts (Recall-managed symlinks only)\n  • ~/.claude/hooks/lib/*.ts (Recall-managed symlinks only)\n  • Recall-generated ## MEMORY section in ~/.claude/CLAUDE.md (external sections stay)\n  • ~/.claude/MEMORY/extract_prompt.md (symlink → ~/.agents/Recall/shared/)\n  • bun unlink (removes recall/recall-mcp from PATH)\n\nWill PRESERVE:\n  • ~/.agents/Recall/ (DB, canonical files, backups, MEMORY artifacts)\n  • ~/.claude/memory.db (legacy DB if it exists)\n  • ~/.claude/MEMORY/ (non-Recall artifacts in this Claude-owned directory)\n  • This source directory (remove with: rm -rf ~/.no-mistakes/worktrees/fd32172f1538/01M5BB78BDJEKXV3P5K2S4HTTH)\n\n\n→ Removing quarterly age cron...\nSkipping quarterly age cron: HOME is not the account home (set RECALL_CRONTAB_BIN to schedule anyway)\n\n→ Removing slash commands...\n\n→ Removing agent skills...\n\n→ Removing guide...\n\n→ Removing Claude Code MCP registration...\n✓ Filtered Recall entries from ~/.no-mistakes/worktrees/fd32172f1538/01M5BB78BDJEKXV3P5K2S4HTTH/.local-test-empryo/lifecycle/home/.claude/settings.json\n\n→ Removing hook files...\n✓ Removed 41 Recall hook file(s)/symlink(s) (surgical — non-Recall hooks/lib untouched)\n✓ Removed extract_prompt.md symlink at ~/.no-mistakes/worktrees/fd32172f1538/01M5BB78BDJEKXV3P5K2S4HTTH/.local-test-empryo/lifecycle/home/.claude/MEMORY/extract_prompt.md\n\n→ Removing CLAUDE.md MEMORY section...\n\n→ Unlinking global binaries...\n→ Skipping bun unlink (RECALL_SKIP_BUN_UNLINK=true)\n\n╔══════════════════════════════════════════════════════════╗\n║                    Uninstall Complete                    ║\n╚══════════════════════════════════════════════════════════╝\n\n✓ Recall uninstalled successfully.\n\nPreserved (remove manually if desired):\n  • ~/.agents/Recall/ (DB, canonical files, backups)\n  • ~/.claude/memory.db (legacy DB if not migrated)\n  • ~/.claude/MEMORY/ (user-authored files and surviving managed MEMORY links)\n  • Source directory at ~/.no-mistakes/worktrees/fd32172f1538/01M5BB78BDJEKXV3P5K2S4HTTH (remove with: rm -rf ~/.no-mistakes/worktrees/fd32172f1538/01M5BB78BDJEKXV3P5K2S4HTTH)\n\n","err":""}
{"command":["~/.bun/bin/bun","~/.no-mistakes/worktrees/fd32172f1538/01M5BB78BDJEKXV3P5K2S4HTTH/dist/index.js","search","lifecycleproof701","-t","messages"],"code":0,"out":"Found 1 result(s):\n\n[messages#1] [project] 2026-10-20\n  user: lifecycleproof701  assistant: Installed adapter works.\n\n","err":""}

Pipeline

Updates from git push no-mistakes

⏭️ **Intent** - skipped

Step was skipped.

✅ **Rebase** - passed

✅ No issues found.

🔧 **Review** - 1 issue found → auto-fixed ✅
  • ⚠️ docs/EMPRYO_INTEGRATION.md:26 - Document hook environment forwarding for custom databases. With RECALL_DB_PATH=/data/recall.db set when launching Empryo and the same path configured for MCP, capture still falls back to ~/.agents/Recall/recall.db because Empryo filters custom hook environment variables unless explicitly forwarded. This either writes to another initialized database or loses capture when that database is absent. The affected path is hooks/RecallExtract.ts:1006 → hooks/lib/hosts/capture-door.ts:68; MCP independently receives the path configured here. Add setup and troubleshooting instructions for forwarding RECALL_DB_PATH (or legacy MEM_DB_PATH) through EMPRYO_HOOK_ENV. See Empryo’s hook environment contract.

🔧 Fix applied.
✅ Re-checked - no issues remain.

✅ **Test** - passed

✅ No issues found.

  • Live validation: ✅ go - 11 of 11 scenarios driven live against the product
Scenario Result Live Evidence
Complete and resume an Empryo session; both turns become searchable in the forwarded custom database. ✅ pass live Native Empryo commands and hook completion; Product transcript
Forward legacy MEM_DB_PATH; the completed Empryo turn reaches that database. ✅ pass live Native Empryo commands and hook completion
Forward both database variables; RECALL_DB_PATH wins and the legacy database remains empty. ✅ pass live Native Empryo commands and hook completion; native-precedence-persisted.json
Omit custom-database forwarding; Empryo filters the variable and capture reaches the sandbox default database. ✅ pass live Product transcript
Fire concurrent and repeated Stop hooks; each recent tab's latest visible turn is stored once, excluding stale, hidden, tool, and incomplete content. ✅ pass live Hook commands and searches; Product transcript
Fire and repeat SessionEnd; all completed visible turns persist without duplicate replay. ✅ pass live SessionEnd persisted memory; Hook commands and searches
Supply unknown-version, unversioned, and missing Empryo logs beside a Claude transcript; no unrelated memory is captured. ✅ pass live Hook commands and searches
Run PreCompact and enabled in-session extraction on Empryo logs; extraction is skipped while explicit correction capture remains searchable. ✅ pass live Hook commands and searches; Product transcript
End an oversized session; the newest completed turn fitting the serialized input cap remains searchable. ✅ pass live Oversized capture persisted memory; Hook commands and searches
Connect Recall MCP and search for a native Empryo turn; the captured prompt and answer are returned. ✅ pass live MCP search response
Run installer hook-copy and registration steps, capture through installed links, then uninstall; managed adapter links disappear while foreign helpers and searchable memory survive. ✅ pass live Installation and uninstall transcript
  • bun install --frozen-lockfile --ignore-scripts
  • Isolated bun test tests/hooks/empryo-capture.test.ts
  • Isolated bun run build
  • Verified the official Empryo 3.10.1-beta bundle signature and SHA-256 before running it locally.
  • bun .local-test-empryo/native-final.ts
  • bun .local-test-empryo/hook-e2e.ts
  • bun .local-test-empryo/mcp-readback.ts
  • bun .local-test-empryo/lifecycle-e2e.ts
  • Verified disposable children had exited and removed test homes, databases, downloaded runtime, temporary drivers, and build output.
✅ **Document** - passed

✅ No issues found.

✅ **Lint** - passed

✅ No issues found.

✅ **Push** - passed

✅ No issues found.

- Route Empryo session logs to a new empryo host adapter as harness empryo
- Stop sends the latest finished turn; SessionEnd sends every turn within the JSON cap
- Skip the Claude transcript fallback, PreCompact flush, and in-session extraction for Empryo logs
- Share payload building and the recall capture call in hooks/lib/hosts/capture-door.ts
- Document the Empryo integration and remove the new hook files on uninstall
- Mark the omp Curated LoA tasks done with PR #340
- Add Empryo MCP registration, injection check, and hyphenated search bug
- Stop sends each tab's latest turn finished within 10 minutes of the newest
- Stop no longer relies on SessionEnd, which the installer does not register
- Run the Claude and Empryo Stop tests from a hooks copy without src
- Drop source-grep assertions in favor of that run
- Narrow Empryo skill docs: plugin installs do not expose skills to Empryo
@Atlas-Key
Atlas-Key requested a review from edheltzel as a code owner October 20, 2026 00:48
@edheltzel
edheltzel merged commit 4319176 into main Oct 20, 2026
3 checks passed
@edheltzel
edheltzel deleted the feat/empryo-adapter branch October 20, 2026 01:02

@edheltzel edheltzel left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

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.

2 participants