--- title: "Harnesses" description: "AI platform integrations and harness configuration." order: 15 section: "Reference" --- # Harnesses Harnesses are the AI platforms and tools that Signet integrates with through connectors, plugins, and lifecycle hooks. For the end-to-end process of connecting a harness on one machine to a Signet daemon on another machine, see [[remote-connectors|Remote Harness Connectors]]. > **Path note:** `$SIGNET_WORKSPACE` means your active Signet workspace path. > Default is `~/.agents`, configurable via `signet workspace set `. --- ## How Harness Sync Works When you change `$SIGNET_WORKSPACE/AGENTS.md`: 1. The [[daemon]] file watcher detects the change (within 2 seconds) 2. The daemon reads the new content 3. It prepends an auto-generated header identifying the source 4. It writes the result to each configured harness location The header looks like this: ``` # CLAUDE.md # ============================================================================ # AUTO-GENERATED from $SIGNET_WORKSPACE/AGENTS.md by Signet # Generated: 2025-02-17T18:00:00.000Z # # DO NOT EDIT THIS FILE - changes will be overwritten # Edit the source file instead: $SIGNET_WORKSPACE/AGENTS.md # # Related documents: # - $SIGNET_WORKSPACE/SOUL.md (Personality & tone) # - $SIGNET_WORKSPACE/MEMORY.md (Working memory context) # - $SIGNET_WORKSPACE/agent.yaml (Configuration & settings) # # Memory commands: /remember | /recall # ============================================================================ ``` You can also trigger a manual re-sync: ```bash curl -X POST http://localhost:3850/api/harnesses/regenerate ``` --- ## Lossless Working Memory Fidelity (Closure Wave) This matrix is the source of truth for closure-wave fidelity and degraded mode expectations across harness paths. | Harness path | Prompt retrieval order | Thread-head continuity | Compaction artifact persistence | Forced post-event MEMORY refresh | |---|---|---|---|---| | TS daemon (primary) | entity current-view injection; transcripts via explicit `session_search` | yes | yes | yes (session-summary + compaction-complete) | | daemon-rs shadow | entity current-view injection | yes (agent-scoped retrieval path) | partial (hook route persistence only) | degraded (full event-driven refresh parity follows rust cutover wave) | Degraded mode rules: - When a harness/runtime path cannot emit every lifecycle event, Signet must document the missing surface explicitly instead of implying full parity. - Compaction/session-summary forced-refresh guarantees are currently full in TS daemon and degraded in daemon-rs shadow path. - Watcher-driven harness identity sync (batched `AGENTS.md` / `USER.md` / `MEMORY.md` propagation, queued reruns during active sync, and generated `SIGNET-ARCHITECTURE.md` refresh) is currently full in the TS daemon and degraded in the daemon-rs shadow path, which does not yet own that watcher pipeline. - Prompt-time anti-bleed scoping remains mandatory across all paths. --- ## Claude Code Claude Code is Anthropic's official CLI for Claude. It reads configuration from `~/.claude/`. ### Files managed by Signet | File | Description | |------|-------------| | `~/.claude/CLAUDE.md` | Auto-synced from `$SIGNET_WORKSPACE/AGENTS.md` | | `~/.claude/settings.json` | Hook configuration (written once during setup) | ### Memory hooks Signet writes [[hooks]] to `~/.claude/settings.json` that fire at session lifecycle events. The hooks call the Signet [[cli|CLI]], which routes requests through the daemon HTTP API: ```json { "hooks": { "SessionStart": [{ "hooks": [{ "type": "command", "command": "signet hook session-start -H claude-code --project \"$(pwd)\"", "timeout": 3000 }] }], "UserPromptSubmit": [{ "hooks": [{ "type": "command", "command": "signet hook user-prompt-submit -H claude-code --project \"$(pwd)\"", "timeout": 7000 }] }], "SessionEnd": [{ "hooks": [{ "type": "command", "command": "signet hook session-end -H claude-code", "timeout": 15000 }] }] } } ``` Prompt-submit timeout note: `SIGNET_PROMPT_SUBMIT_TIMEOUT` defaults to `5000` (daemon wait budget). Claude Code hook config adds a `+2000ms` grace buffer when written to `settings.json`, so the installed `UserPromptSubmit` timeout default is `7000`. Upgrade note: Claude Code hook timeouts are written to `~/.claude/settings.json` at install/update time. Existing installs keep their previous timeout values until you rerun `signet connect claude-code` (or `signet setup`) to rewrite hook config. **SessionStart** — loads memories and context, outputs them as text that Claude Code injects into the system prompt. **UserPromptSubmit** — optionally loads per-prompt context (lighter weight than session start). **SessionEnd** — automatically saves a session summary to memory. ### Native memory bridge Signet indexes Claude Code-owned memdir artifacts without rewriting them or turning them into Signet-authored rows. The daemon watches Claude Code entrypoint indexes and memory files under `~/.claude/projects/*/memory/`, session memory under `~/.claude/session-memory/`, and agent-scoped memory under `~/.claude/agent-memory/` and `~/.claude/agent-memory-local/`. Matching content is exposed through Signet recall as `native_memory` results with Claude Code provenance. Removed native files are soft-deleted from active recall while preserving their artifact rows for lineage. This replaces the older daemon-local Claude watcher that only read `~/.claude/projects/*/memory/MEMORY.md` and pushed chunks back through `/api/memory/remember`. Claude Code remains the owner of those native files; Signet indexes them as artifacts. ### Using /remember and /recall In Claude Code sessions, use these commands directly: ``` /remember nicholai prefers bun over npm /recall coding preferences ``` These work via the built-in skills in `$SIGNET_WORKSPACE/skills/`. The skill instructions tell Claude how to call the Signet daemon API. ### MCP Tools Claude Code also gets native MCP tool access to Signet memory via the `signet-mcp` stdio server, registered in `~/.claude/settings.json`: ```json { "mcpServers": { "signet": { "type": "stdio", "command": "signet-mcp", "args": [] } } } ``` This gives Claude Code direct access to `memory_search`, `session_search`, `memory_store`, `memory_get`, `memory_list`, `memory_modify`, and `memory_forget` tools. ### Prerequisites - Claude Code installed and in `PATH` - `~/.claude/` directory exists --- ## Codex Codex is OpenAI's terminal coding agent (`codex-rs`). Signet integrates with Codex through a generated Codex plugin bundle when the installed Codex CLI supports plugin marketplaces. The plugin declares Signet metadata, skills, and MCP configuration. Until Codex exposes plugin lifecycle hooks, Signet also installs compatibility `hooks.json` entries for session start, prompt submit, and session end. Older Codex versions fall back to direct hook and MCP config patching. ### Files managed by Signet | File | Description | |------|-------------| | `~/.codex/.tmp/signet-plugin-marketplace` | Generated local marketplace containing the Signet plugin bundle | | `~/.codex/config.toml` | Plugin marketplace/config registration, or compatibility `[mcp_servers.signet]` on older Codex installs | | `~/.codex/hooks.json` | Compatibility lifecycle hooks — SessionStart, UserPromptSubmit, Stop | | `~/.codex/skills` | Compatibility symlink to `$SIGNET_WORKSPACE/skills` when plugin support is unavailable | ### Native memory bridge Signet indexes Codex-owned memory artifacts without rewriting them or turning them into Signet-authored memory rows. The daemon polls Codex memory files with content hashes under `~/.codex/memories/`, including `memory_summary.md`, `MEMORY.md`, rollout summaries, skill memories, ad-hoc extension notes, and automation-local `~/.codex/automations/*/memory.md` files. Matching content is indexed as `codex_native_memory` source artifacts with path, hash, line range, and rollout-id metadata when present. Removed native files are soft-deleted from active recall while preserving their artifact rows for lineage. When Codex native memories are enabled, Signet's Codex prompt hook reduces automatic injection of Codex-owned memory rows. Prompt-time context stays focused on high-value Signet material: cross-harness history, source-backed documents, ontology, explicit recalls, and accepted decisions. Explicit recall still uses daemon-side dedupe keyed by `session_key`, `agent_id`, and `context_epoch`. ### How it works 1. `signet setup --harness codex` feature-detects `codex plugin` support. 2. On supported Codex installs, Signet writes a local plugin marketplace bundle and registers `signet@signet-local` in `~/.codex/config.toml`. 3. While plugin lifecycle hooks are not available, Codex also reads compatibility hooks from `~/.codex/hooks.json`. 4. On session start, Codex fires `SessionStart` → calls `signet hook session-start -H codex --codex-json` → Signet returns identity + memories as `hookSpecificOutput.additionalContext` with `suppressOutput: true`, injected into the model's context window without printing the hook payload to the user transcript. 5. On every user prompt, Codex fires `UserPromptSubmit` → calls `signet hook user-prompt-submit -H codex --codex-json` → Signet returns bounded entity current-view context only when the prompt mentions a known entity or active alias. Empty matches return no additional context. This is blocking — Codex waits for the hook before sending to the model. 6. On session end, Codex fires `Stop` → calls `signet hook session-end -H codex` → Signet extracts memories from the transcript. 7. The MCP server exposes `signet_recall`, `signet_source_search`, `signet_session_search`, `signet_save_note`, and compatibility `memory_*` tools that Codex can invoke directly during sessions. Codex `SessionStart` hook timeout defaults to 20 seconds: the Signet CLI waits up to `SIGNET_SESSION_START_TIMEOUT` (`15000` ms by default) for the daemon, and the generated Codex hook config adds 5 seconds of harness grace. Codex `UserPromptSubmit` defaults to 7 seconds: `SIGNET_PROMPT_SUBMIT_TIMEOUT` (`5000` ms by default) plus 2 seconds of harness grace. Rerun `signet setup` or `signet connect codex` after upgrading to rewrite an existing `~/.codex/hooks.json`. For a remote Signet daemon, pass `--url` and `--api-key` when installing the Codex connector: ```bash signet api-key create --name "work laptop codex" --connector codex --agent-id signet connect codex --url http://192.168.0.60:3850 --api-key sig_sk_... ``` Use `--agent-id` when creating the API key to bind the remote Codex install to one Signet agent. The key scope becomes the default agent for Codex hook/MCP requests, and requests for another agent are rejected by daemon auth scope. Codex also has a native-plugin-oriented npm installer name for machines where you do not want to install the full Signet CLI first: ```bash npx -y @signetai/codex-plugin install --url http://192.168.0.60:3850 --api-key sig_sk_... ``` When `SIGNET_DAEMON_URL` or `--url` is set, the Codex connector writes the plugin MCP URL, or compatibility `[mcp_servers.signet] url = "/mcp"` when plugin support is unavailable, and bakes the same daemon URL into generated lifecycle hook commands. This keeps on-demand MCP tools and automatic lifecycle memory pointed at the same Signet instance. When an API key is provided, Codex MCP and lifecycle hook calls send it as bearer auth. The URL value must be the daemon origin only, for example `http://192.168.0.60:3850` or `https://signet.internal:3850`, with no path, query string, fragment, or embedded credentials. Codex matches the session-start, prompt-submit, and session-end path, but it does **not** currently expose the same compaction lifecycle fidelity as Claude Code or OpenCode. ### Supported hooks | Hook | Supported | |------|-----------| | session-start | yes — identity + memories via `hookSpecificOutput.additionalContext` | | user-prompt-submit | yes — entity current-view context via `hookSpecificOutput.additionalContext` when matched | | session-end | yes — transcript extraction via `Stop` hook | ### MCP tools When the Signet MCP server is registered, Codex gains access to these tools (namespaced as `mcp__signet__*`): - `signet_recall` — explicit Signet recall for cross-harness history and accepted decisions - `signet_source_search` — search source-backed Signet artifacts and docs - `signet_session_search` — search active or completed session transcripts - `signet_save_note` — write a small explicit note into Codex native memory extensions - `memory_search`, `memory_store`, `session_search`, and other legacy `memory_*` tools — compatibility aliases MCP tools do not replace hooks. MCP gives Codex on-demand tools during a session; hooks provide automatic identity injection, prompt-time recall, and session-end extraction. ### Extraction provider Codex can be selected as the extraction provider in `agent.yaml`. When set, the pipeline uses the Codex CLI (similar to the `claude-code` provider) to run extraction and decision passes against Codex's configured model rather than a local Ollama instance. ### Prerequisites - Codex (`codex-rs`) installed and in `PATH` - Signet daemon running (`signet daemon start`) --- ## OpenCode OpenCode is an open-source AI coding tool. Signet integrates via a bundled plugin and AGENTS.md sync. ### Files managed by Signet | File | Description | |------|-------------| | `~/.config/opencode/AGENTS.md` | Auto-synced from `$SIGNET_WORKSPACE/AGENTS.md` | | `~/.config/opencode/plugins/signet.mjs` | Bundled plugin providing memory tools | ### Plugin Bundle During `signet install`, the connector writes a self-contained `signet.mjs` file to `~/.config/opencode/plugins/` and registers `./plugins/signet.mjs` in the OpenCode config so the runtime loads it consistently at startup. The plugin is built from `@signet/opencode-plugin` source and bundled into a single ESM file at build time (stored as a string constant in `plugin-bundle.ts`). This means the plugin has no external dependencies at runtime. The previous approach (`memory.mjs` in the OpenCode root directory) is considered legacy. The connector automatically migrates away from it during install by deleting the old file and scrubbing any `memory.mjs` references from the config's `plugin` or `plugins` arrays. ### Config File Detection The connector searches for an OpenCode config file in this order: 1. `~/.config/opencode/opencode.json` 2. `~/.config/opencode/opencode.jsonc` 3. `~/.config/opencode/config.json` The first one found is used. If none exist, `opencode.json` is created as the default. JSONC files (with `//` comments and trailing commas) are parsed correctly — the connector strips comments and trailing commas before parsing. ### MCP Tools OpenCode also gets MCP tool access via a local server entry registered in the config file during install: ```json { "mcp": { "signet": { "type": "local", "command": ["signet-mcp"], "enabled": true } } } ``` The plugin handles lifecycle hooks; MCP provides on-demand memory tools. ### Supported hooks | Hook | Supported | |------|-----------| | session-start | yes | | user-prompt-submit | yes | | pre-compaction | yes | | compaction-complete | yes | | session-end | yes | ### Prerequisites - OpenCode installed - `~/.config/opencode/` directory exists --- ## Oh My Pi (`oh-my-pi`) Oh My Pi uses a managed Signet runtime extension installed by `@signetai/connector-oh-my-pi`. The extension forwards lifecycle events to the daemon and injects hidden Signet context into the session when needed. ### Files managed by Signet | File | Description | |------|-------------| | `PI_CODING_AGENT_DIR/extensions/signet-oh-my-pi.js` | Managed extension bundle when `PI_CODING_AGENT_DIR` is set | | `~/.omp/agent/extensions/signet-oh-my-pi.js` | Managed extension bundle in the default Oh My Pi agent directory | ### Managed extension During setup or connect, the connector writes a bundled `signet-oh-my-pi.js` file into the Oh My Pi extensions directory. If `PI_CODING_AGENT_DIR` is set, Signet uses that agent directory. Otherwise it writes to `~/.omp/agent/extensions/`. The install path is idempotent and only manages `signet-oh-my-pi.js`. Older Signet-managed `.mjs` installs are removed automatically on the next setup or sync run. ### Runtime behavior - Existing unrelated Oh My Pi extensions are left untouched. - Signet refuses to overwrite a colliding unmanaged `signet-oh-my-pi.js`. - Daemon or network failures are fail-open, so prompt handling, compaction, session switches, and shutdown continue even if Signet is unavailable. - The extension persists hidden session-context and recall injections through `before_agent_start`, marks them with `attribution: "agent"`, and keeps them out of transcript reconstruction so memory-backed answers remain attributable without consuming user-attributed Copilot requests. - It does not currently add `/remember` or `/recall` tools, and it does not sync `AGENTS.md` into Oh My Pi. ### Supported hooks | Hook | Supported | |------|-----------| | session-start | yes | | user-prompt-submit | yes | | pre-compaction | yes | | compaction-complete | yes | | session-end | yes | --- ## pi (`pi`) pi uses a managed Signet runtime extension installed by `@signetai/connector-pi`. The extension forwards lifecycle events to the daemon and injects hidden Signet context into the session when needed. ### Files managed by Signet | File | Description | |------|-------------| | `PI_CODING_AGENT_DIR/extensions/signet-pi.js` | Managed extension bundle when `PI_CODING_AGENT_DIR` is set | | `~/.pi/agent/extensions/signet-pi.js` | Managed extension bundle in the default pi agent directory | ### Managed extension During setup or connect, the connector writes a bundled `signet-pi.js` file into the pi extensions directory. If `PI_CODING_AGENT_DIR` is set, Signet uses that agent directory. Otherwise it writes to `~/.pi/agent/extensions/`. ### Runtime behavior - Existing unrelated pi extensions are left untouched. - Signet refuses to overwrite a colliding unmanaged `signet-pi.js`. - Daemon or network failures are fail-open, so prompt handling, compaction, session switches, and shutdown continue even if Signet is unavailable. - **Automatic recall**: On every user prompt, the extension automatically fetches relevant memories from the daemon and injects them as hidden messages (`display: false`) into the agent's context. These injections are kept out of transcript reconstruction. - **Manual commands**: `/recall ` and `/remember ` let users explicitly search and store memories. The `/recall` command **displays results in the UI only** — it does not inject them into the conversation context. `/signet-status` shows connection and memory stats. - `/remember ` — save a memory - `/remember critical: ` — save as pinned (never decays) - `/remember [tag1, tag2]: ` — save with tags - `/remember critical: [tag1, tag2]: ` — pinned with tags (critical prefix must come first) - **Agent tools**: `signet_recall`, `signet_source_search`, `signet_session_search`, and `signet_remember` are registered as LLM-callable tools. When the agent calls `signet_recall`, the results (including memory IDs) **are** returned into the conversation context via the tool response. `signet_source_search` searches provenance-backed artifacts separately from ordinary memory recall; `signet_session_search` searches active or completed session transcripts. - Hidden inject messages use `display: false` and `role: "custom"`. Pi converts custom messages to `role: "user"` for the LLM, so the `X-Initiator` header (which determines Copilot billing attribution) is set based on the last message's role — extensions cannot override it via an `attribution` field as Oh My Pi can. - Does not sync `AGENTS.md` into pi. ### Configuration Configuration is optional and loaded from `~/.pi/agent/extensions/signet.json` (or `$PI_CODING_AGENT_DIR/extensions/signet.json` if set). The `SIGNET_ENABLED` environment variable overrides the file setting. **Optional `~/.pi/agent/extensions/signet.json`:** ```json { "enabled": false } ``` | Option | Description | Default | |-----------|------------------------------------------------|---------| | `enabled` | Whether Signet is enabled by default | `true` | **Environment Variable** (overrides file config): | Variable | Description | |------------------|--------------------------------| | `SIGNET_ENABLED` | Set to `false` to disable | Examples: ```bash # Use config file defaults pi # Disable Signet for a single session SIGNET_ENABLED=false pi # Create a config file to disable by default echo '{"enabled": false}' > ~/.pi/agent/extensions/signet.json ``` ### Supported hooks | Hook | Supported | |--------------------|-----------| | session-start | yes | | user-prompt-submit | yes | | pre-compaction | yes | | compaction-complete| yes | | session-end | yes | --- ## OpenClaw OpenClaw is the flagship harness for the lossless working-memory model. The plugin path gives the closest match to the full LCM runtime, while the legacy hook path remains compatibility-only. `signet sync` auto-migrates legacy-only Signet installs to the plugin path, and `signet doctor` warns when a config is still stuck on legacy-only mode. ### Files managed by Signet | Location | Description | |----------|-------------| | `$SIGNET_WORKSPACE/AGENTS.md` | Source of truth (OpenClaw reads workspace directly) | | `$SIGNET_WORKSPACE/hooks/agent-memory/` | Hook handler directory | | `~/.openclaw/openclaw.json` | Workspace configuration | ### Workspace configuration Signet sets OpenClaw-family configs to your active Signet workspace. Change it with: ```bash signet workspace set ~/.openclaw/workspace ``` Common compatible workspace targets include: - `~/.openclaw/workspace` - `~/.clawdbot/workspace` - `~/clawd` - `~/.moltbot/workspace` OpenClaw config value: ```json { "agents": { "defaults": { "workspace": "$SIGNET_WORKSPACE" } } } ``` OpenClaw checks these config locations (in order): - `~/.openclaw/openclaw.json` - `~/.clawdbot/clawdbot.json` - `~/.moltbot/moltbot.json` ### @signetai/adapter-openclaw The adapter package provides a full lifecycle integration: ```javascript import createPlugin from '@signetai/adapter-openclaw'; const signet = createPlugin({ enabled: true, daemonUrl: 'http://localhost:3850' // default }); ``` **Session start** — inject memories into system prompt: ```javascript const result = await signet.onSessionStart({ harness: 'openclaw', sessionKey: session.id }); // result.inject → prepend to system prompt ``` **Pre-compaction** — get summary guidelines: ```javascript const guide = await signet.onPreCompaction({ harness: 'openclaw', messageCount: messages.length }); // guide.summaryPrompt → use as compaction instruction ``` **Compaction complete** — save the generated summary: ```javascript await signet.onCompactionComplete({ harness: 'openclaw', summary: generatedSummary, sessionKey: session.id }); ``` When OpenClaw only exposes compaction metadata to the plugin hook, the runtime may read the latest compaction summary back from `sessionFile` before calling the daemon so the temporal DAG still receives the real artifact. **Manual memory operations:** ```javascript await signet.remember('nicholai prefers bun', { who: 'openclaw' }); const results = await signet.recall('coding preferences'); ``` ### MEMORY.md synthesis The daemon synthesis worker is the primary runtime path for keeping `MEMORY.md` current. OpenClaw may still drive synthesis on a schedule by: 1. Calls `GET /api/hooks/synthesis/config` to check if synthesis should run 2. Calls `POST /api/hooks/synthesis` to get the synthesis prompt 3. Runs the prompt through the configured model 4. Posts the result to `POST /api/hooks/synthesis/complete` Both paths write through the same merge-safe head record, so the rendered `MEMORY.md` stays shared across harnesses instead of becoming OpenClaw-specific. ### Hooks directory During setup, Signet creates `$SIGNET_WORKSPACE/hooks/agent-memory/` with: - `HOOK.md` — hook documentation - `handler.js` — event handler (for older hook-based integration) - `package.json` — package metadata ### Package Distinction: adapter vs connector Signet provides two separate packages for OpenClaw integration: #### @signetai/connector-openclaw **Purpose:** Setup and installation This is a setup-time package that: - Patches OpenClaw config files (openclaw.json, clawdbot.json, moltbot.json) - Sets `agents.defaults.workspace` to your active Signet workspace - Enables the `signet-memory` internal hook entry - Installs hook handler files under `$SIGNET_WORKSPACE/hooks/agent-memory/` Installed during `signet setup` when OpenClaw is selected. #### @signetai/adapter-openclaw **Purpose:** Runtime plugin This is a runtime plugin that OpenClaw loads to: - Call the Signet daemon API for /remember, /recall operations - Handle lifecycle hooks (session start, compaction, etc.) - Inject memories into the system prompt Has a peer dependency on `openclaw` — only usable within the OpenClaw process. ## Hermes Agent Hermes Agent is an open-source terminal AI agent by Nous Research. Signet integrates as a pluggable memory provider via Hermes's `MemoryProvider` ABC, deploying a Python plugin that bridges all Signet daemon hooks into the Hermes lifecycle. ### Files managed by Signet | Location | Description | |----------|-------------| | `~/.hermes/plugins/signet/__init__.py` | User-level Signet `MemoryProvider` implementation | | `~/.hermes/plugins/signet/client.py` | User-level HTTP client for the Signet daemon API | | `~/.hermes/plugins/signet/plugin.yaml` | User-level plugin metadata | | `~/.hermes/plugins/signet/signet.install.json` | Install marker with connector version and plugin source hash | | `/plugins/memory/signet/__init__.py` | Signet `MemoryProvider` implementation | | `/plugins/memory/signet/client.py` | HTTP client for the Signet daemon API | | `/plugins/memory/signet/plugin.yaml` | Plugin metadata | | `/plugins/memory/signet/signet.install.json` | Install marker with connector version and plugin source hash | | `~/.hermes/config.yaml` | `memory.provider: signet` activation | | `~/.hermes/.env` | Daemon connection environment variables | ### How it works 1. `signet setup` (with `hermes-agent` selected) copies the Python plugin into both `~/.hermes/plugins/signet/` and, when discovered, `/plugins/memory/signet/`. 2. The connector writes install markers, daemon connection env vars to `~/.hermes/.env`, and activates the provider by setting `memory.provider: signet` in Hermes config. 3. At session start, Hermes calls `initialize()` on the plugin, which fires `POST /api/hooks/session-start` to load identity, memories, and system prompt injection from the daemon. 4. On each user turn, `queue_prefetch()` fires `POST /api/hooks/user-prompt-submit` for entity current-view context when the prompt mentions a known entity or active alias. 5. At session end, `on_session_end()` sends the accumulated transcript via `POST /api/hooks/session-end` for async pipeline extraction. ### Tools exposed to the agent | Tool | Description | |------|-------------| | `memory_search` | Hybrid memory search (keyword + semantic + knowledge graph) | | `session_search` | Search active or completed session transcripts | | `memory_store` | Store a fact/preference/decision with auto entity extraction | | `memory_get` | Retrieve a memory by ID | | `memory_list` | List memories with optional filters | | `memory_modify` | Edit an existing memory | | `memory_forget` | Soft-delete a memory | | `recall` / `remember` | Compatibility aliases for search/store | ### Supported hooks | Hook | Supported | |------|-----------| | session-start | yes — identity + memories via `system_prompt_block()` | | user-prompt-submit | yes — entity current-view context via `queue_prefetch()` / `prefetch()` | | pre-compaction | yes — daemon-generated summary guidelines via `on_pre_compress()` | | compaction-complete | yes — saves summary as session memory via `on_compaction_complete()` | | checkpoint-extract | yes — periodic mid-session delta extraction every 30 turns | | session-end | yes — transcript extraction via `on_session_end()` | ### Delegation support When Hermes delegates to subagents, the parent's `on_delegation()` hook stores the task+result pair as a Signet memory tagged `["delegation", "subagent"]`. ### Prerequisites - Hermes Agent installed (repo with `plugins/memory/` directory) - Signet daemon running (`signet start`) - `signet setup --harness hermes-agent` - `signet doctor hermes` reports daemon health, plugin freshness, config activation, and Hermes tool routing --- ## Adding a New Harness To integrate Signet with a harness not listed here: 1. **Identity sync** — simply watch for `$SIGNET_WORKSPACE/AGENTS.md` changes and copy the content to wherever your harness reads agent instructions. 2. **Memory access** — call the daemon's HTTP API: - `POST /api/memory/remember` to save memories - `POST /api/memory/recall` to search memories 3. **Lifecycle hooks** — call the hooks API at session events: - `POST /api/hooks/session-start` at session start - `POST /api/hooks/pre-compaction` before compaction - `POST /api/hooks/compaction-complete` after compaction 4. **Check daemon health** — always verify `GET /health` returns 200 before making other calls. See [API.md](./API.md) for full endpoint documentation and [HOOKS.md](./HOOKS.md) for hook integration details. --- ## Working-Memory Fidelity Matrix All harnesses target the same model: - one agent - many sessions / branches - one shared root `MEMORY.md` head, with optional agent-local `MEMORY.md` overrides for named agents - structured retrieval first - transcripts as fallback / deep history - compaction artifacts feeding the same temporal DAG Where they differ is lifecycle fidelity: | Harness | session-start | prompt-submit | pre-compaction | post-compaction | session-end | Notes | |---------|---------------|---------------|----------------|-----------------|-------------|-------| | OpenCode plugin | yes | yes | yes | yes | yes | Reference full-fidelity path | | OpenClaw plugin | yes | yes | yes | yes | yes | Flagship path; post-compaction may read summary back from `sessionFile` when the hook only exposes metadata | | Oh My Pi extension (v1) | yes | yes | yes | yes | yes | Lifecycle events only; no Signet memory tools or AGENTS.md sync yet | | Hermes Agent plugin | yes | yes | yes | yes | yes | Full fidelity via `MemoryProvider` ABC; includes checkpoint-extract and delegation hooks | | pi extension | yes | yes | yes | yes | yes | Full lifecycle and Signet tools (`/recall`, `/remember`, `signet_recall`, `signet_source_search`, `signet_session_search`, `signet_remember`); no AGENTS.md sync yet | | Claude Code | yes | yes | yes | no | yes | Good continuity, degraded after-compaction fidelity | | Codex | yes | yes | no | no | yes | Solid baseline, degraded compaction fidelity | | OpenClaw legacy hooks | manual `/context` | no | no | no | no | Compatibility-only, not full parity | The docs should be read literally. If a hook surface is absent here, that mode is degraded rather than silently assumed. --- ## Harness Status Check which harnesses are configured: ```bash signet status ``` Or via API: ```bash curl http://localhost:3850/api/harnesses ``` Or in the dashboard under the **Harnesses** section.