Enzyme
Use Enzyme for local semantic retrieval over an initialized markdown workspace. Run all enzyme commands from the vault/workspace root. For Hermes, this is the directory where Hermes is launched.
Vault path: -p flag > ENZYME_VAULT_ROOT env var > current directory.
For Hermes, this skill is for operational use inside a user's workspace, not for developing Hermes itself. Run Enzyme from the directory where Hermes is launched so the same AGENTS.md/.hermes.md context and markdown corpus are visible to both.
Prerequisite: check the installed binary first with enzyme --version. If the binary is missing, install Enzyme before setup. If Enzyme is installed but old, tell the user you are upgrading Enzyme to the latest release before setup, then run the normal installer path. If the pre-upgrade version is older than 0.5.8, warn that older Enzyme releases used a different auth/provider contract; after upgrading, ask before clearing stale authentication. Never delete ~/.enzyme/auth.json or run enzyme logout without explicit confirmation. If this skill is loaded, runtime instructions are already available; do not call enzyme install <runtime> as part of normal vault setup.
Auth and provider safety: let Enzyme decide when auth is needed. Do not preflight ~/.enzyme/auth.json or start login before a command asks for it. If an Enzyme command reports that login is required, start device login in the background, read JSONL events from /tmp/enzyme-login.log, show the verification URI/code when present, wait for success/error/expiry, then retry the original command. Never ask the user to paste API keys or auth tokens.
Never print API key values. Only when the user explicitly requests their own provider, inspect which LLM environment variable names exist before enzyme init:
env | cut -d= -f1 | grep -E '^(ENZYME_JEV_MODEL|OPENAI_API_KEY|OPENAI_BASE_URL|OPENAI_MODEL|ENZYME_LOCAL_MODEL)$'
Enzyme ignores inherited LLM env keys by default. Do not unset env vars as a workaround, and do not silently spend the user's personal OpenAI/OpenRouter key just because it exists in the shell. If OPENAI_API_KEY is present, warn that using env credentials intentionally should normally include the complete OpenAI-compatible triple: OPENAI_API_KEY, OPENAI_BASE_URL, and OPENAI_MODEL. A bare OPENAI_API_KEY falls back to OpenAI defaults, which can produce unauthorized/provider-mismatch errors when the key actually belongs to OpenRouter, a local proxy, or another compatible provider. If only model/base-url vars are present without a matching key, treat it as partial env config and do not use it.
Before init or generation, run enzyme model status and honor its configured and effective modes. With no user preference, preserve auto: it uses the selected local model when installed and hosted generation otherwise. Explain whether the effective path needs network access before setup proceeds. Do not download a model, run model use, or run model disable without explicit consent. If the user intentionally wants to use their own OpenAI/OpenRouter/OpenAI-compatible provider, verify only the presence of the needed env var names without printing values and pass --use-env-llm:
enzyme init --quiet --use-env-llm
enzyme refresh --quiet --use-env-llm
The dedicated setup skill owns the full provider disclosure and consent flow. An app-level approval decision never substitutes for it.
Enzyme does not replace the user's memory system. It indexes the markdown structure the user already has: folders, tags, wikilinks, dates, inboxes, daily notes, people pages, and frontmatter. Preserve that structure and use it as retrieval signal. Be exact about frontmatter: literal wikilinks work in every field, while plain string/list values become generic link entities only when the active vault/workspace config names that field in frontmatter_link_fields; the field name does not create a typed person/project model.
User-facing mental model: Enzyme does the slow interpretive pass once, then leaves behind fast search handles. During init, it reads the shape of the vault and creates a small set of source-grounded questions for the ideas that keep showing up. Those questions are not summaries; they are questions the user's notes are good at answering. Later, when an agent needs context, it can use those precomputed questions to find relevant notes immediately instead of rereading the vault or guessing keywords. Refresh folds new markdown into that compiled map so future sessions can use it.
Do not expose embedding implementation details unless asked. Prefer simple language such as: "Enzyme turns your notes into questions an agent can search with," "the slow interpretive pass happens during init," and "runtime retrieval uses precomputed handles, so it is fast."
Do not build a separate context tree. Learn from the user's folders, but prefer lightweight markdown signals: tags for recurring ideas and wikilinks for people, projects, companies, decisions, and concepts. Create new folders or people pages only when the vault already uses that convention or the user asks for it.
First-Time Setup
If .enzyme/enzyme.db is missing, or the user asks to set up, re-set up,
diagnose, or repair the workspace, stop the routine retrieval flow and load the
dedicated enzyme-workspace-setup skill. Follow it end to end; it is the sole
source of truth for scan interpretation, configuration, consent, repair, backup,
revert, and proof. Do not improvise a setup procedure from this runtime skill.
enzyme install codex, enzyme install claude, enzyme install hermes, and
enzyme install openclaw install that setup skill beside this one. If it is
missing, rerun the matching install command once, then read its SKILL.md and
bundled references/knowledge-practice-review.md before issuing setup commands.
Session Lifecycle
Explain setup/refresh simply when useful: init is the slow compile step that turns the vault into source-grounded questions; refresh is how new notes join that compiled map; normal retrieval is fast because the agent uses those precomputed handles instead of starting from scratch.
enzyme refresh --quiet JSON includes an update object with a two-state contract. Check update.status: ok means nothing to do (a note may explain a slower call such as vault regeneration); action_required means perform or relay the action string to the user — never interpret any other keys. Use enzyme status when you need full binary-update diagnostics.
Claude/Codex plugin installation does not install Petri or refresh hooks by default. Do not create .claude/hooks/enzyme-petri.sh, mutate .claude/settings.json, or rely on automatic prompt injection during normal setup. Use enzyme petri and enzyme catalyze explicitly when context is needed.
What's automatic depends on your runtime:
Hermes (hooks handle it):
- First setup — the plugin can bootstrap the binary; load the installed
enzyme-workspace-setupskill for the complete workflow - Session start — binary bootstrap +
enzyme refreshrun automatically - Each turn —
enzyme petri --queryinjects vault context before the model sees your message - Session end — after any useful markdown notes are written,
enzyme refreshindexes them
OpenClaw (skill instructions + config):
- Session start — run
enzyme refresh --quiet(add to AGENTS.md or heartbeat) - First turn / context-dependent turns — run
enzyme petri --query "user's message"before responding - Session end — write useful markdown notes if the session produced durable memory, then run
enzyme refresh --quiet - Between sessions — heartbeat or cron can keep the index fresh for external syncs (see README for config)
In both cases: use petri and catalyze as tools. The difference is whether context injection is automatic in the host runtime (Hermes) or agent-driven from these instructions.
First Value Demo
After first-time setup, broad orientation, or a first retrieval session, do not end with setup status or a list of topics. Verification is internal. The user should immediately see Enzyme turn their own notes into a source-grounded connection that would have been hard to find with grep or ordinary file browsing.
Use this framing:
- Open with:
A connection worth opening: <plain-language phrase>. - Show 2-4 short excerpts or tight paraphrases from specific files, especially the user's own annotations or decision notes rather than only imported source text.
- Put the excerpts beside each other with minimal interpretation:
In <file>, you wrote...Elsewhere, this shows up as...Put together, the question becomes...
- Offer one concrete next move:
We could follow this into <tag/file/source> next.Or compare it against <related file/tag/source>.
Prefer words from the user's own notes. Avoid performative meta-language such as "live thread," "you are circling," "tension," "resonance," or "emerging pattern" unless those are the user's words. Do not claim intimacy with the user; create recognition by staying close to the artifacts.
Choose the first demo connection by vault type:
- Annotated reference/import vault (for example Readwise, web clips, papers, book notes, transcript highlights): start from one user annotation, marginal note, or explicit reaction when present, quote it as source text, then place it beside the saved passage and one adjacent source until a question appears. If the user names a title or distinctive phrase, use exact search to find that obvious note before using petri/catalyze for adjacent connections.
- Project/work vault: place a decision, blocker, meeting note, or artifact beside a later note that changes its meaning or next step.
- Journal/daily vault: place two entries from different dates beside each other to show how the wording, stakes, or desired action changed.
- People/CRM vault: place context notes beside a recent interaction or commitment to reveal one concrete next step.
- Research vault: place sources that sharpen an assumption, disagreement, missing evidence, or possible synthesis.
The demo succeeds only if it gives the user one specific, sourced connection they can recognize as theirs and one obvious next question to pursue. If the result feels generic, run another retrieval with sharper catalyst vocabulary and do not call setup complete yet.
Existing Structure
Do not impose a new memory schema.
- Follow existing Obsidian or markdown conventions before suggesting changes.
- Treat inboxes, daily notes, project folders, CRM folders, tags, wikilinks, and frontmatter as signal.
- If a
people/,contacts/,clients/, orcompanies/folder exists, treat it as canonical for person/company references. - If no people/company folder exists, prefer wikilinks and existing tags over creating a new per-person knowledge tree.
- Preserve existing date field names such as
date:,created:, orcreated_at:when they are consistent. - Preserve existing entity fields such as
people:,organizations:,companies:,clients:,projects:, orrelationships:when the vault uses them. Checkfrontmatter_link_fieldsbefore claiming their plain values are indexed; otherwise use exact wikilinks in those values or treat them as metadata only. - Propose frontmatter dates, people-page creation, or folder changes only when the user is explicitly doing setup or asks for structure improvement.
Optional backfills must be reviewed before running. Good candidates are date frontmatter inferred from filenames/paths, note-level entity fields already covered by frontmatter_link_fields or matched to existing wikilinks, and repeated person/company names that the user confirms should become CRM pages.
Readable workspace policy
Readable configuration lives in ~/.enzyme/configs/*.enzyme. When present, run
enzyme spec inspect "$PWD" --instructions from the active vault before routine
retrieval or memory capture. Follow the compiled workspace retrieval and capture
guidance alongside this skill and the user's current instructions. A remember
declaration supplies conditions and a destination; it does not install a hook or
authorize unrelated writes. If the vault has no readable policy, use this skill's
defaults. Report malformed configuration rather than silently ignoring it.
Working Memory
enzyme petri returns current entities and catalysts, which are thematic phrases from the vault.
- For a specific user prompt, run
enzyme petri --query "user's question". - For a broad prompt or first orientation, run
enzyme petri. - Treat nested children under a tag or folder as evidence inside that parent cluster by default.
Use catalyst phrases as vocabulary for enzyme catalyze searches. They connect to precomputed content that the user's raw words may not find.
Search
enzyme catalyze "query"searches by concept/theme. Compose queries from petri catalyst vocabulary.enzyme refresh --quietre-indexes changed content.- Use exact search for names, source titles, distinctive phrases,
#tags,[[wikilinks]], and literal text. - For annotated reference/import vaults, if the user names a title or phrase, find that obvious note first with exact search, then use petri/catalyze to connect it to adjacent material.
enzyme catalyze "query" --target ./target-dirprepares external content using vault catalysts, then searches it.- Tags can appear as
- tagin frontmatter or#taginline; search without#when you need both.
External References
Use enzyme catalyze "query" --target ./target-dir when the user wants to draw from external material without merging it into the vault: Readwise exports, articles/books, transcripts, research dumps, client docs, code repos, converted PDFs, Discord/Slack exports, or downloaded archives. Enzyme prepares the target automatically on first use.
enzyme catalyze "query" --target ./target-dir
Target search projects the source vault's catalysts onto the target corpus:
source vault catalysts → external target chunks
The vault is the lens. Search both sides when comparison matters:
enzyme catalyze "query"
enzyme catalyze "query" --target ./target-dir
Present it as: "I searched your own notes for the internal thread, then searched the external material through the same conceptual frame." Mention that target search may miss themes that exist only in the target and not in the user's vault.
Writing Notes
Write runtime memory as ordinary markdown observations, not as a separate memory store. The point is to leave sparse, source-linked notes that Enzyme can refresh and retrieve through Petri and Catalyze when a durable conclusion, commitment, reframe, or open loop is worth carrying forward.
The best time to write is near the end of a session or after a meaningful decision, when the durable outcome is clear. Do not interrupt the user's flow to capture routine Q&A.
Write a note when a session produces a decision, a reframe, an open thread worth returning to, a durable preference, a project state change, or useful people/company context.
Do not write a note for raw tool output, one-time commands, transient status, generic summaries, or facts already captured without material change. Never store secrets, credentials, tokens, or raw config values; if relevant, record only that a credential was configured.
Follow the vault's existing folder and frontmatter conventions. If no convention exists, ask before introducing a capture folder, date field, people folder, or context-tree-like structure.
Before writing, use enzyme petri, enzyme catalyze, or exact search to find related notes. Link to existing notes when possible. If a previous decision is superseded, write a new dated note referencing the old one rather than editing history in place.
Use existing tags and wikilinks. Check petri entities before inventing new tags. Use wikilinks for people and ideas when they help future retrieval; do not create standalone person pages unless the vault already has that pattern or the user confirms it. Preserve the user's exact wording for preferences, opinions, and stated rules when that wording matters.
For entities that apply to the whole note, prefer existing frontmatter fields over repeating the same names throughout the body. Examples include people:, organizations:, companies:, clients:, projects:, and relationships:. Only add fields already used by the vault or explicitly approved by the user. If the field is listed in frontmatter_link_fields, plain scalar/list strings become generic link entities; if it is not, use exact wikilinks when the value should be indexed and do not imply that an inert plain value is retrieval signal. Keep entity lists selective: include the people, organizations, clients, companies, tags, and relationships that are central to the note, not every incidental mention from retrieved context.
If the vault has no stronger template, write compact notes in this shape:
---
tags:
- existing-tag
created: "[[YYYY-MM-DD]]"
---
## descriptive title
The decision, reframe, or open thread in 2-3 sentences. Why it matters.
Related: [[existing note]]
Omit empty optional fields unless the vault commonly keeps them.
After writing memory notes at the end of the session, run:
enzyme refresh --quiet
Refresh is the Enzyme equivalent of making the new memory available to retrieval. It re-indexes changed markdown and updates catalyst retrieval; no background dreaming or consolidation pass is required.
Presentation
Use Enzyme command names internally; do not expose petri, catalyze, catalyst IDs, scores, or tool names to the user unless asked.
Before making observations, ground them with enzyme catalyze excerpts. Lead with the user's words and file attribution, then add a small observation.
For broad exploration, use petri plus 1-2 catalyze searches, then open one specific connection among the user's notes. Do not present a topic list. If exact search finds an obvious named note but catalyze misses it, say so plainly and use Enzyme for adjacent connections rather than pretending semantic retrieval found the note unaided.
For search results, do not lead with metadata. Notice repeated words, time gaps, changed wording, adjacent ideas, practical consequences, or source disagreements across results. End with one concrete next direction, not a generic invitation.
Choose the presentation posture from the user's task, not from the catalyze response:
- Exploration: wonder, probe, notice patterns, and open one specific connection.
- Continuity: restore what the user knew, show trajectory and stopping points, and enable forward motion.
- Reference/imports: surface what drew attention and connect imports to the user's own thinking without treating them as authoritative.