Skip to content

Default Artifacts

Murmur publishes the artifacts below from murmur-nexus/default-artifacts, in the murmur scope: each is named murmur/<name>, and a capsule's model calls a tool by <name> alone — see Artifact names. Declare one in artifacts: and install it with mur install — none of them has to be built locally. mur search reads the same index from the terminal.

This page also documents the environment the runtime hands hook and driver components.


Inference drivers

An inference driver turns the runtime's provider-agnostic request into one provider's wire format. Declare one with runtime: driver and a gateway: block naming the provider, and name it in inference.driver.artifact.

Artifact Provider
murmur/driver-anthropic Anthropic Messages API
murmur/driver-openai OpenAI Chat Completions, and the Responses API for gpt-5 and later models
murmur/driver-deepseek DeepSeek

Every driver reads the same inference environment and passes inference.max_tokens through unchanged as the provider's output cap.

Process drivers

A process driver drives a harness CLI instead of a provider API. Declare one with runtime: driver, no gateway: block, and name it in inference.driver.artifact under transport: process.

Artifact Harness
murmur/driver-claude-code The Claude CLI (claude)

See Run a capsule on your subscription for what that transport costs before you choose it.


Hooks

A hook's binding, execution mode and commit policy are fixed by the artifact, not by the entry that declares it — see Hook artifacts. A hook with no capabilities: block on its manifest entry gets no directory and no network at all; the ones that write a file need a filesystem grant.

Artifact Fires on What it does
murmur/hook-compact on-compaction Summarizes conversation history when the session token threshold is reached, and replaces the context with the summary
murmur/hook-debug Every event except on-stage Appends one JSON object per lifecycle event to hook-debug.jsonl
murmur/hook-diff-summary Every event Snapshots files before each tool-write and tool-edit call and emits a unified-diff summary at the end of the turn
murmur/hook-eval Every event Scores the session against the configured scorers and writes eval.jsonl
murmur/hook-grafana Every event Emits OpenTelemetry spans for each lifecycle event to a Grafana Tempo OTLP/HTTP endpoint
murmur/hook-memory on-task-start Seeds a task with the relevant, budget-bounded slice of the conversation record read so far
murmur/hook-regression-verifier Every event Watches a task's test runs and reopens the task when a change broke previously-passing tests
murmur/hook-shell-desc on-stage Returns enriched tool manifests for common shell binaries at staging time

murmur/hook-debug

The quickest way to see what the runtime dispatched during a session. It is the only shipped hook that runs execution_mode: async, so the agent loop never waits on it.

artifacts:
  - name: murmur/hook-debug
    version: "0.10.0"
    runtime: hook
    capabilities:
      filesystem:
        scope: .

scope: . mounts the accessible workdir as the hook's current directory, which is where hook-debug.jsonl lands.

murmur/hook-grafana

artifacts:
  - name: murmur/hook-grafana
    version: "0.11.0"
    runtime: hook

observability:
  otel_endpoint: "http://localhost:4318"

Without observability.otel_endpoint the hook logs a warning to logs/hook-hook-grafana.log in its current directory and exports nothing for that session. The session runs as normal.

murmur/hook-eval

artifacts:
  - name: murmur/hook-eval
    version: "0.11.0"
    runtime: hook
    capabilities:
      filesystem:
        records: true

observability:
  eval:
    dataset_id: my-dataset
    scorers:
      - type: exit_ok
        name: success_check
      - type: max_turns
        name: turn_limit
        max: 5

records: true mounts the session records directory's hooks/ as the hook's current directory, so eval.jsonl lands beside the session's trace.jsonl, where the capsule's commands cannot change it and where mur eval reads it.

Without an observability.eval block the hook logs a warning to logs/hook-hook-eval.log in its current directory — the records directory's hooks/ when its entry declares capabilities.filesystem.records: true — and scores nothing. The session runs as normal.

See Scorer types for what each scorer measures and the shape of the file it writes, observability.eval for the fields each scorer takes, and mur eval for reading and comparing eval files.


Tools

Artifact What it does
murmur/tool-code-coverage Spectrum-based fault localization (Ochiai / Tarantula) over per-test LCOV reports the agent has already captured. Reads a repository indexed by murmur/tool-code-graph
murmur/tool-code-graph Indexes a Rust or Python repository into a symbol/edge graph and answers structured queries over it. Symbols are addressed by a stable identity rather than by file:line
murmur/tool-corpus Append-only, schema-validated record store for a capsule's own notes, behind the capsule's capabilities.state grant
murmur/tool-create Scaffolds a new tool artifact directory: murmur.yaml, a stub implementation and a README
murmur/tool-edit Replaces exact text in a file, several edits at once, all or nothing
murmur/tool-find Searches file contents for a regex, optionally narrowed by a glob
murmur/tool-git Structured git operations returning typed JSON, in place of git in capabilities.shell.allow
murmur/tool-read Reads a file, or a range of its lines
murmur/tool-registry-search Searches the artifact index by keyword
murmur/tool-request-input Pauses the agent loop and requests external input over A2A; the answer comes back as the tool result
murmur/tool-test-report Parses a test-runner output file the agent has already captured into a structured list of failures
murmur/tool-write Creates or replaces a file, and any missing directories

murmur/tool-corpus

An append-only JSON-lines store for records a capsule wants to keep across turns — state/corpus.jsonl, reachable only where the manifest entry grants capabilities.state; every operation returns state_unavailable without it.

Operation Does
append Writes one record of a declared type. external_id makes a retried call idempotent, returning the first call's id with deduped: true; withdraws: <id> retires an earlier record instead of deleting it
get Reads one record by id, withdrawn or not
read_recent Newest non-withdrawn records of one type
search Term-matched hits, each {id, type, created_at, score, excerpt} — the excerpt is one matching line, not the record body
verify Reports every unreadable line by number, parse error and preview. Needs the state grant but not the configuration

Record types, their JSON Schema, and the caps on read_recent's n and search's k come from this tool's own config: block — see Choosing a config block. An entry with none gets config_missing on every operation but verify. A line that fails to parse is skipped rather than failing the call: the response carries skipped_lines and skipped_line_count so the damage reaches the trace on the next call.

Searches an artifact index by keyword, so a capsule can discover artifacts mid-session. It is a native tool with payloads for linux-x86_64 and darwin-aarch64. It takes three inputs:

Input Required Notes
query yes Matched case-insensitively against the full name <scope>/<name>, the bare name, the description and the tags
index no An http:// or https:// URL, or a path to an artifacts-index.json inside the capsule's workdir, relative to it or absolute. Omit for the index on the latest default-artifacts release. local is refused: the capsule cannot see the global artifact store
limit no Maximum results to return. Default: 10

It returns:

Field Value
index The URL or path it read
scope The index's scope
count The number of results
results One entry per matching artifact: name (<scope>/<name>), runtime, description, tags, and versions
results[].versions Every version the index lists, newest first, each with version, release, built_at_level and platforms (any for a platform-independent payload)

mur decides whether a version fits when it installs it; the tool lists every published version.

As a native tool it runs under the capsule-wide grants, so the capsule lists https://github.com and https://release-assets.githubusercontent.com in its top-level capabilities.network.allow, plus the host of any other index URL. mur new declares this tool in the generator capsule it cold-boots, and fails with E-RUN-008 if it is not installed first.

What each native tool needs

Five of the tools above ship native implementations. Each runs in the capsule's own sandbox, with the capsule-wide grants — see Native tools — so what it needs is declared in the capsule's top-level capabilities: block. Its own artifact entry carries only config: and capabilities.state, which reach that tool alone — see A native tool's own config and store:

Tool Capsule grants it needs scoped sealed
murmur/tool-git git in capabilities.shell.allow; the repository inside the workdir. fetch, pull, push and clone also need the remote's host in capabilities.network.allow and an interpreter_runtime grant for git naming the directory its remote helpers live in (/usr/lib/git-core on Debian and Ubuntu); without it git cannot start git-remote-https Works Works
murmur/tool-code-graph repo_path inside the workdir. It writes <repo_path>/.murmur/code-graph.db Works Works
murmur/tool-code-coverage repo_path and coverage_dir inside the workdir, and the index murmur/tool-code-graph built there Works Works
murmur/tool-test-report input_path (and repo_path, when given) inside the workdir Works Works
murmur/tool-registry-search https://github.com and https://release-assets.githubusercontent.com in capabilities.network.allow, plus the host of any other index URL; a path index inside the workdir Works Works

Without git in capabilities.shell.allow, every murmur/tool-git operation fails with failed to execute git: Permission denied (os error 13).


Skills

Artifact What it does
murmur/skill-create-manifest How to write a valid murmur.yaml. mur new loads it into its generator capsule
murmur/skill-investigation-checkpoint The checkpoints/decisions.json convention for recording and reusing investigative verdicts across a session

Hook environment

The runtime injects these into every hook component. They are the whole environment a hook sees — nothing from the host is inherited.

Env var Injected when Value
MURMUR_OTEL_ENDPOINT observability.otel_endpoint is set The configured OTLP endpoint URL
MURMUR_EVAL_CONFIG observability.eval is set The eval block as JSON: dataset_id and the parsed scorers list
MURMUR_ARTIFACT_CONFIG This hook's entry in the operator's manifest declares config: That entry's config: block as compact JSON
MURMUR_GATEWAY_ENDPOINT This hook's entry in the operator's manifest declares gateway: http://127.0.0.1:9 followed by the path of gateway.endpoint
MURMUR_DATASET_ID mur eval run is driving a dataset and observability.eval.dataset_id is set observability.eval.dataset_id
MURMUR_CASE_ID mur eval run is driving a dataset The case_id of the case being run
MURMUR_FORMATION_ID The session belongs to a formation The session's formation id
MURMUR_FORMATION_PEERS The session is a formation member that may call at least one member Each member it may call at its virtual address, name=http://<name>.formation.invalid, in roster order

Driver and tool environment

When the manifest configures inference:, the runtime injects these into the driver component and into every tool artifact.

Env var Value Under transport: process
MURMUR_INFERENCE_TRANSPORT inference.transport process
MURMUR_INFERENCE_MODEL inference.model The configured model, empty when inference.model is omitted
MURMUR_INFERENCE_ENDPOINT http://127.0.0.1:9 followed by the path of the driver entry's gateway.endpoint — https://api.moonshot.ai/v1 gives http://127.0.0.1:9/v1. Nothing listens there: the runtime sends the driver's requests to this address on to gateway.endpoint with the key attached Empty
MURMUR_INFERENCE_DRIVER inference.driver.artifact Empty
MURMUR_INFERENCE_DRIVER_CONFIG inference.driver.config as JSON. Not set when the field is absent Not set
MURMUR_CAPSULE_NAME name from the manifest Same
MURMUR_CAPSULE_VERSION version from the manifest Same
MURMUR_SESSION_ID The session ID Same
MURMUR_CAPSULE_URL localhost:<port>, the address the capsule's HTTP server bound Same

A formation member that may call at least one member also hands every tool, and a transport: http driver, MURMUR_FORMATION_PEERS, whether or not inference: is configured. Shell commands, native tools and a transport: process harness are not handed it.

Three further variables are injected per artifact rather than per session:

Env var Injected when Value
MURMUR_ARTIFACT_CONFIG This artifact's entry in the operator's manifest declares config: That entry's config: block as compact JSON
MURMUR_STATE_DIR This artifact is a native tool, and its entry declares capabilities.state. Native tools only: a WASM artifact reaches its store as the state directory The store's absolute path, ~/.murmur/state/<store>/
MURMUR_GATEWAY_ENDPOINT This artifact's entry declares gateway:, and the call uses its gateway http://127.0.0.1:9 followed by the path of gateway.endpoint. Requests sent there reach gateway.endpoint with the key attached as the artifact's upstream_auth: block declares

Each reaches the declaring artifact and no other, and the runtime sets it whether or not inference: is configured. The configured driver receives MURMUR_GATEWAY_ENDPOINT on its agent turns and a hook's run-inference; a driver called by name as a tool receives neither the variable nor its gateway. A native tool receives MURMUR_ARTIFACT_CONFIG and MURMUR_STATE_DIR on every containment tier, and none of the per-session variables above; a gateway: block on a native tool is refused with E-CAP-017. The runtime sets these names, and no capabilities.env.allow or capabilities.shell.baseline_env entry takes them from the host.

Under transport: process the driver named by inference.driver is a process driver: a runtime: driver artifact granted nothing at all — no environment, no files, no network — which plans the harness subprocess rather than calling a provider itself. None of the variables above reach it. Tool artifacts still receive the whole table.