docs(logstream): concept page, tool/CLI references, coordination protocol (RFC 003 phase 4)

- website/concepts/agent-logstream.md: event/artifact model, delegation
  loop, coordination-vs-memory table; added to the sidebar.
- website/reference/mcp-tools.md: schemas for the seven logstream tools;
  tool count 35 -> 42 (README updated to match).
- website/reference/cli.md: mempalace logstream / mempalace artifact.
- website/guide/remote-server.md: hub doubles as agent coordination bus.
- integrations/shared/coordination-protocol.md: canonical shared-brain
  protocol (identity, delegation loop, hard rules) with a copy-paste
  system-prompt snippet; linked from recall-protocol.md and the
  mempalace-recall skill so recall and coordination never blur.

(cherry picked from commit 1ff312511aef39abbe4638bdc23301266f87dbe6)
This commit is contained in:
Igor Lins e Silva
2026-08-05 23:50:18 -03:00
parent 62df5fee0e
commit 77c8998174
9 changed files with 500 additions and 36 deletions
+52 -18
View File
@@ -108,30 +108,50 @@ CUDA-accelerated embeddings, build the GPU variant with
## Storage backends
ChromaDB is the default and needs no configuration. MemPalace also ships a
pluggable backend contract, exercised across deliberately different substrates
so the contract is never accidentally shaped around one vendor. Every
non-default backend is opt-in.
ChromaDB is the default. For the pluggable-backend preview, MemPalace also
ships `sqlite_exact` for local exact-vector correctness checks, and two opt-in
external service backends — `qdrant` (REST) and `pgvector` (Postgres). The two
external backends exercise the storage contract on different substrates (a
REST/dict store and a SQL/JSONB store), so it is not accidentally shaped around
one vendor.
| Backend | Mode | Install | Namespaces | Lexical | Configure with |
| ------- | ---- | ------- | :--------: | :-----: | -------------- |
| `chroma` _(default)_ | Local (embedded) | bundled | – | ✓ | – |
| `sqlite_exact` | Local (exact) | bundled | – | ✓ | – |
| `milvus` | Local (Lite) · Server opt-in | `mempalace[milvus]` | ✓ | ✓ | `MEMPALACE_MILVUS_URI` |
| `qdrant` | Server (REST) | bundled | ✓ | ✓ | `MEMPALACE_QDRANT_URL` |
| `pgvector` | Server (Postgres) | `mempalace[pgvector]` | ✓ | ✓ | `MEMPALACE_PGVECTOR_DSN` |
```bash
# local no-service backend
mempalace mine ~/projects/myapp --backend sqlite_exact
Select with `--backend <name>`, `MEMPALACE_BACKEND=<name>`, or
`"backend": "<name>"` in `config.json`. See
[Storage backends](/guide/configuration#storage-backends) for connection
variables, namespace behavior, and deployment notes.
# Qdrant backend, defaulting to http://localhost:6333
MEMPALACE_QDRANT_URL=http://localhost:6333 \
mempalace mine ~/projects/myapp --backend qdrant
# Postgres + pgvector backend, defaulting to postgresql://localhost:5432/mempalace
# needs the optional driver: pip install mempalace[pgvector]
# and the `vector` extension available on the server
MEMPALACE_PGVECTOR_DSN=postgresql://localhost:5432/mempalace \
mempalace mine ~/projects/myapp --backend pgvector
```
Qdrant can also be configured with `MEMPALACE_QDRANT_API_KEY`,
`MEMPALACE_QDRANT_NAMESPACE`, and `MEMPALACE_QDRANT_TIMEOUT`; pgvector with
`MEMPALACE_PGVECTOR_NAMESPACE`. Both external backends isolate tenants by
namespace (advertised via the `supports_namespace_isolation` capability) and
write a local marker (`qdrant_backend.json` / `pgvector_backend.json`) to guard
against silently opening a palace against the wrong server.
When `MEMPALACE_QDRANT_URL` or `MEMPALACE_PGVECTOR_DSN` points anywhere other
than your own local or trusted self-hosted service, MemPalace will send and
store verbatim drawer text and metadata there. That is an explicit opt-in
backend choice, never the default.
## Quickstart
```bash
# Optional: choose a shared local palace for multiple agents on one machine
mempalace config set palace-path ~/.mempalace/palaces/shared-agent-brain
# Mine content into the palace
mempalace mine ~/projects/myapp # project files
mempalace mine ~/.claude/projects/ --mode convos # Claude Code sessions (scope with --wing per project)
mempalace mine ~/.local/share/opencode --mode convos # OpenCode sessions
# Search
mempalace search "why did we switch to GraphQL"
@@ -209,11 +229,25 @@ Usage and tool reference:
## MCP server
36 MCP tools cover palace reads/writes, knowledge-graph operations,
cross-wing navigation, drawer management, and agent diaries. Installation
42 MCP tools cover palace reads/writes, knowledge-graph operations,
cross-wing navigation, drawer management, agent diaries, and agent
coordination (logstream events + artifact handoffs). Installation
and the full tool list:
[mempalaceofficial.com/reference/mcp-tools](https://mempalaceofficial.com/reference/mcp-tools.html).
For multiple agents writing to the same local palace, run one shared MCP
HTTP server and connect every client to that endpoint:
```bash
mempalace serve --host 127.0.0.1 --port 8765
```
Launching separate stdio `mempalace-mcp` servers against one palace is
safe for recall, but only the first writer can mutate; later servers run
mutating tools read-only to avoid ChromaDB stale-state corruption. The
`mempalace serve` command prints ready-to-paste client config for the
shared-server shape.
## Agents
Each specialist agent gets its own wing and diary in the palace.
@@ -269,7 +303,7 @@ PRs welcome. See [CONTRIBUTING.md](CONTRIBUTING.md).
MIT — see [LICENSE](LICENSE).
<!-- Link Definitions -->
[version-shield]: https://img.shields.io/badge/version-3.7.0-4dc9f6?style=flat-square&labelColor=0a0e14
[version-shield]: https://img.shields.io/badge/version-3.5.0-4dc9f6?style=flat-square&labelColor=0a0e14
[release-link]: https://github.com/MemPalace/mempalace/releases
[python-shield]: https://img.shields.io/badge/python-3.9+-7dd8f8?style=flat-square&labelColor=0a0e14&logo=python&logoColor=7dd8f8
[python-link]: https://www.python.org/
@@ -0,0 +1,125 @@
# MemPalace Shared-Brain Coordination Protocol
The canonical protocol for agents sharing one MemPalace hub — memory
discipline plus the logstream coordination layer (RFC 003). Like
`recall-protocol.md`, this file is the single source of truth: skills,
rules, and system prompts should link here or copy the System-Prompt
Snippet below verbatim, so the protocol never drifts per-agent.
## The two layers
A shared palace gives every agent two distinct channels. Do not mix them:
- **Memory (drawers, KG, diary)** — durable knowledge worth recalling
later. Searched semantically. Follow
[`recall-protocol.md`](recall-protocol.md).
- **Coordination (logstream events + artifacts)** — active work moving
between agents *right now*: delegations, replies, patches, acks.
Filtered structurally, never searched semantically.
Rule of thumb: if another agent should **act** on it, it is an event.
If a future session should **know** it, it is a drawer. A concluded
delegation usually produces both: the events carried the work; a drawer
records the outcome.
## Identity
Every agent uses one stable `from_agent` identity, formatted
`<machine>-<harness>` (e.g. `mac-claude`, `windows-codex`,
`aero-opencode`). Never impersonate another agent; never rotate names —
the event trail is only auditable if identities are stable.
## Delegating work (requester)
1. Generate a `correlation_id` for the task: `task_<short-description>`
plus enough entropy to be unique (e.g. `task_fix_ranking_7f3a`).
2. `mempalace_event_append` with `type=task.request`, `stream=project/<name>`,
`room=delegation`, `to_agent=<worker>`, `status=open`, and a body that
states the goal, the branch, the base commit, and the definition of done.
3. Wait for the reply: `mempalace_event_wait` with the `correlation_id`
and `to_agent=<you>`. Waits cap at 5 minutes — loop, passing
`since_event_id` of the last event you saw.
4. When a `patch.ready` arrives: `mempalace_artifact_get`, verify the
`sha256`, apply locally, run the stated verification.
5. Always close the loop with `mempalace_event_ack` — `status=applied`
on success, `status=failed` with verbatim evidence on failure.
## Receiving work (worker)
1. Poll or wait for `type=task.request`, `to_agent=<you>` (plus `*`
broadcasts are matched automatically).
2. Claim it: `mempalace_event_ack` with `status=claimed` so no other
agent duplicates the work.
3. Do the work on the stated branch/commit.
4. Deliver through the formal channel — `mempalace_patch_submit` with the
diff, `correlation_id`, `branch`, and `base_commit`. **Pushing a
branch is not a handoff**; the event is. If you also pushed, say so
in the body.
5. If blocked or unable to produce a patch, still reply:
`type=task.reply` with `status=blocked` or `failed` and verbatim
notes. Silence is the only unrecoverable failure.
## Hard rules
- **Never apply a patch silently.** Fetching an artifact is free;
applying it is an explicit local decision, stated to the user.
- **Verify hashes.** An artifact's `sha256` must match its content
before you act on it.
- **Append-only.** Never try to edit or delete events; supersede with a
new event (`status=superseded`) referencing the old one.
- **Exact payloads.** Bodies and artifacts are verbatim — no summaries
of diffs, no truncated logs. If it is too big, store it as an
artifact and reference it.
- **Close every loop.** Every `task.request` you claimed ends in an
`applied`, `failed`, or `blocked` — no dangling `open` tasks.
- **File the outcome.** When a delegation concludes, write one drawer
(`mempalace_add_drawer`) recording what was decided/learned, so the
result is searchable without replaying the event trail.
## System-Prompt Snippet
Copy this block into an agent's system prompt / custom instructions.
Replace `<AGENT_ID>` with the agent's stable identity.
```text
## MemPalace shared brain
You share a MemPalace hub with other agents. Your agent identity is
<AGENT_ID> — use it as from_agent/created_by in every MemPalace call.
Memory (recall + writing):
- Before answering about past work, decisions, people, or projects,
search the palace (mempalace_search; mempalace_kg_query for
relational/temporal facts). Quote results verbatim — never paraphrase
stored content. If the palace has nothing, say so; don't guess.
- File durable outcomes (decisions, conclusions, learned facts) with
mempalace_add_drawer. When a fact changes: mempalace_kg_invalidate the
old fact, then mempalace_kg_add the new one. Don't file secrets or
tokens.
Coordination (logstream):
- Check your inbox when starting work and before long tasks:
mempalace_event_list with to_agent=<AGENT_ID> (new since your last
seen event id).
- To delegate: mempalace_event_append (type=task.request, stream=
project/<name>, room=delegation, correlation_id=task_..., status=open,
body = goal + branch + base commit + definition of done), then
mempalace_event_wait on that correlation_id for the reply.
- When you accept a task: ack it with status=claimed. Deliver code as a
patch via mempalace_patch_submit (never just push a branch and go
silent). If blocked, reply with status=blocked and verbatim notes.
- When you receive a patch: mempalace_artifact_get, verify sha256,
apply only with explicit user-visible intent, run the stated tests,
then mempalace_event_ack with status=applied or failed.
- Events are append-only and verbatim. Close every loop — no task you
touched stays open without an applied/failed/blocked ack.
```
## See also
- [`recall-protocol.md`](recall-protocol.md) — the search-before-answer
memory protocol this composes with.
- [Agent Logstream concepts](../../website/concepts/agent-logstream.md) —
event/artifact model and the full tool reference.
- RFC 003 (`docs/rfcs/003-agent-logstream-coordination.md`) — design
rationale and storage model.
+5
View File
@@ -116,5 +116,10 @@ added through the MCP server and diary entries, which have no source file
- [`integrations/openclaw/SKILL.md`](../openclaw/SKILL.md) — the original
full-protocol skill this is distilled from.
- [`coordination-protocol.md`](coordination-protocol.md) — the shared-brain
companion protocol: when agents delegate work to each other over the
hub, they use the logstream (`mempalace_event_append` /
`mempalace_event_wait`), not drawers. Recall answers questions;
the logstream moves work.
- MemPalace design principles (verbatim, local-first, never summarize):
<https://github.com/MemPalace/mempalace>
+7
View File
@@ -82,6 +82,13 @@ rule and the other integrations — lives in
question — not a system prompt or pasted conversation) plus optional
`wing` / `room` filters and `limit` (default 5).
**Active coordination is not recall.** When delegating work to another
agent on the shared hub — or waiting for its reply or patch — use the
logstream tools (`mempalace_event_append`, `mempalace_event_wait`,
`mempalace_patch_submit`, `mempalace_artifact_get`), not drawers or
search. The canonical protocol lives in
[`integrations/shared/coordination-protocol.md`](../../integrations/shared/coordination-protocol.md).
## Unhappy paths
- **Empty results.** Say the palace has nothing on this; do not invent an
+1
View File
@@ -76,6 +76,7 @@ export default withMermaid(
{ text: 'AAAK Dialect', link: '/concepts/aaak-dialect' },
{ text: 'Knowledge Graph', link: '/concepts/knowledge-graph' },
{ text: 'Specialist Agents', link: '/concepts/agents' },
{ text: 'Agent Logstream', link: '/concepts/agent-logstream' },
{ text: 'Contradiction Detection', link: '/concepts/contradiction-detection' },
],
},
+137
View File
@@ -0,0 +1,137 @@
# Agent Logstream
MemPalace is a memory system first — but agents sharing one palace also need to
*coordinate*: delegate work to each other, wait for replies, and hand off
patches without a human relaying messages between machines. The **logstream**
is that coordination layer (RFC 003).
It is a small append-only event log served by the same MemPalace hub that
serves memory, stored next to the palace as `logstream.sqlite3`. It follows
the same promises as everything else in MemPalace:
- **Local-first** — lives inside your palace directory, reachable over
loopback, LAN, or tailnet exactly like the rest of the hub. No cloud queue,
no Redis, no SaaS.
- **Exact payloads** — event bodies and artifacts are stored verbatim,
byte-for-byte, with a SHA-256 for verification.
- **Append-only** — events are immutable. Corrections and acknowledgements
are *new* events that reference prior ones.
- **Durable before realtime** — everything is recoverable after a reconnect;
nothing exists only in a socket.
## Events
An event is a structured coordination message with routing metadata and an
optional verbatim body:
```json
{
"id": "evt_20260702T032443_02ce0c31acdb",
"type": "patch.ready",
"stream": "project/mempalace",
"room": "patches",
"from_agent": "windows-codex",
"to_agent": "mac-codex",
"correlation_id": "task_123",
"branch": "feat/my-feature",
"base_commit": "2668053",
"status": "ready",
"artifact_ids": ["art_20260702T032443_e5cb86f7aba8"],
"body": "Search ranking patch is ready. Tests passed on Windows.",
"created_at": "2026-07-02T03:24:43Z"
}
```
- **`stream`** is the broad channel — `project/<name>` for per-project work,
or a shared channel like `shared_agent_brain`.
- **`room`** is the sub-channel: `delegation`, `patches`, `reviews`, `status`.
- **`correlation_id`** ties a request to its replies and acks. Generate one
per task and carry it through the whole exchange.
- **`to_agent`** targets one agent, or `*` to broadcast. Filters on
`to_agent` also match broadcasts.
- **`status`** is one of `open`, `claimed`, `ready`, `applied`, `blocked`,
`failed`, `superseded`.
- **`seq`** (returned on every event) is the append-order cursor. Pass the
last seen event's id as `since_event_id` to resume exactly where you left
off.
## Artifacts
An artifact is exact content attached to an event: a unified diff, a
generated file, a test log, a JSON report. Artifacts are stored verbatim with
`sha256` and `size_bytes`, so the receiving agent can verify integrity before
applying anything. v1 artifacts are UTF-8 text, up to 4 MiB.
## The delegation loop
The canonical two-agent exchange:
**Requester (agent A):**
1. `mempalace_event_append` — `type=task.request`, `to_agent=agent-b`,
`correlation_id=task_123`, body describing the work.
2. `mempalace_event_wait` — `correlation_id=task_123`, `type=patch.ready`,
`timeout_ms=300000`.
3. `mempalace_artifact_get` — fetch the patch, verify the `sha256`.
4. Apply the patch locally, run tests. Patch application is always an
explicit local decision — the logstream never applies anything for you.
5. `mempalace_event_ack` — `status=applied` (or `failed` with notes).
**Worker (agent B):**
1. `mempalace_event_wait` — `to_agent=agent-b`, `type=task.request`.
2. Do the work.
3. `mempalace_patch_submit` — stores the artifact and appends the
`patch.ready` event in one call.
If an agent can't produce a patch, it still replies: `task.reply` or a
`blocked`/`failed` status with verbatim notes. Silence is the only failure
mode the logstream can't help with.
`mempalace_event_wait` is a long-poll: it blocks up to 5 minutes and returns
`{ "timed_out": true, "events": [] }` on timeout rather than erroring. Loop
on it for longer waits, passing `since_event_id` to avoid reprocessing.
## Tools and CLI
Seven MCP tools serve the logstream: `mempalace_event_append`,
`mempalace_event_list`, `mempalace_event_wait`, `mempalace_event_ack`,
`mempalace_artifact_put`, `mempalace_artifact_get`, and
`mempalace_patch_submit` — see the [MCP tools reference](/reference/mcp-tools)
for schemas.
The same operations are available from the shell:
```bash
mempalace logstream append --type task.request --stream project/myapp \
--room delegation --from-agent mac --to-agent windows \
--correlation-id task_123 --body "Please fix the flaky test."
mempalace logstream wait --correlation-id task_123 --type patch.ready \
--timeout-ms 300000 --json
mempalace artifact get art_... | git apply --3way
```
`--json` makes every command scriptable; `wait` exits `2` on timeout so
shell loops can retry.
## Coordination vs. memory
The logstream complements the palace; it does not replace it:
| | Palace (drawers) | Logstream (events) |
|---|---|---|
| Purpose | Long-term recall | Active coordination |
| Access | Semantic search | Structured filters + long-poll |
| Lifetime | Forever | Forever (append-only) |
| Content | Anything worth remembering | Work packets, replies, patches |
Durable outcomes still belong in the palace: when a delegated task concludes,
file the *decision and outcome* as a drawer so it is searchable later. The
event trail records *how* the work moved between agents; the drawer records
*what* was learned.
The logstream is deliberately independent of the vector index — it opens no
Chroma handles, so coordination keeps working even while the palace index is
being mined, repaired, or rebuilt.
+7
View File
@@ -177,6 +177,13 @@ Once connected, all of MemPalace's [MCP tools](/guide/mcp-integration) operate
against the shared palace — searches and saved memories are visible to the
whole team.
A shared hub also gives your agents a coordination channel: the
[agent logstream](/concepts/agent-logstream) lets one agent delegate work
(`mempalace_event_append`), another long-poll for it
(`mempalace_event_wait`), and patches move as verified artifacts
(`mempalace_patch_submit` / `mempalace_artifact_get`) — no human relaying
messages between machines.
## Operating notes
- **Mining** still happens via the CLI (`mempalace mine …`) on the server host
+42
View File
@@ -171,3 +171,45 @@ mempalace instructions mine
mempalace instructions help
mempalace instructions status
```
## `mempalace logstream`
Agent coordination events — delegate work, wait for replies, acknowledge
outcomes (RFC 003). Operates on `logstream.sqlite3` in the palace directory;
safe to run alongside a live hub. See [Agent Logstream](/concepts/agent-logstream).
```bash
mempalace logstream append --type task.request --stream project/myapp \
--room delegation --from-agent mac --to-agent windows \
--correlation-id task_123 --body "Please fix the flaky test."
mempalace logstream list --stream project/myapp --room delegation --json
mempalace logstream wait --correlation-id task_123 --type patch.ready \
--timeout-ms 300000 --json
mempalace logstream ack evt_... --from-agent mac --status applied
```
| Subcommand | Description |
|------------|-------------|
| `append` | Append an immutable event (`--type`, `--stream`, `--room`, `--from-agent` required; `--body`/`--body-file`, `--artifact-id` repeatable) |
| `list` | List events, oldest first (all routing fields as filters, `--since-event-id`, `--limit`) |
| `wait` | Long-poll until a match or timeout (`--timeout-ms`, max 300000; exits `2` on timeout) |
| `ack` | Append an `event.ack` for an event (`--from-agent` required, `--status`, `--body`) |
All subcommands accept `--json` for scriptable output.
## `mempalace artifact`
Exact artifact exchange for agent handoffs — unified diffs, files, logs.
Content is stored verbatim with a SHA-256.
```bash
git diff | mempalace artifact put --kind patch --created-by windows --json
mempalace artifact get art_... | git apply --3way
mempalace artifact get art_... --out /tmp/handoff.patch
```
| Subcommand | Description |
|------------|-------------|
| `put` | Store content (`--kind patch\|file\|log\|json\|note`, `--created-by` required; `--content`, `--file`, or stdin) |
| `get` | Print exact content to stdout, or `--out FILE`; `--json` for metadata |
+124 -18
View File
@@ -1,6 +1,6 @@
# MCP Tools Reference
Detailed parameter schemas for all 36 MCP tools.
Detailed parameter schemas for all 42 MCP tools.
## Palace — Read Tools
@@ -111,7 +111,6 @@ Save a whole session in one call. Semantic-dedups each item, files the non-dupli
| `items` | array | **Yes** | Verbatim items to file. Each is `{ wing, room, content }` |
| `diary` | object | No | Diary entry written after filing: `{ agent_name, entry, topic?, wing? }` (`entry` is AAAK-format) |
| `dedup_threshold` | number | No | Similarity threshold 0–1 for the per-item dedup check (default 0.9) |
| `added_by` | string | No | Who is filing these drawers. An explicit value takes precedence; otherwise the diary `agent_name`, else `checkpoint` |
**Returns:** `{ added: [...], duplicates: [...], errors: [...], diary? }`
@@ -264,22 +263,6 @@ Mark a fact as no longer true.
---
### `mempalace_kg_supersede`
Atomically replace a fact with its successor at a single shared boundary. Use when a single-valued fact changes (model, employer, address) instead of a separate `mempalace_kg_invalidate` + `mempalace_kg_add` — a point-in-time query at the boundary then returns only the new value.
| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `subject` | string | **Yes** | Entity whose fact is changing |
| `predicate` | string | **Yes** | Relationship (e.g. `uses_model`, `works_at`) |
| `old_object` | string | **Yes** | Value being replaced |
| `new_object` | string | **Yes** | New value |
| `at` | string | No | Boundary instant (YYYY-MM-DD or YYYY-MM-DDTHH:MM:SSZ; default: now UTC) |
**Returns:** `{ success, triple_id, fact, superseded }`
---
### `mempalace_kg_timeline`
Chronological timeline of facts.
@@ -480,3 +463,126 @@ Force a reconnect to the palace database. Use this after external scripts or CLI
**Parameters:** None
**Returns:** `{ success, message, drawers, vector_disabled[, vector_disabled_reason] }` (on no-palace: `{ success: false, message, drawers, vector_disabled }`; on exception: `{ success: false, error }`)
---
## Agent Coordination Tools (Logstream)
Append-only coordination events and exact artifacts for multi-agent work — see the [Agent Logstream](/concepts/agent-logstream) concept page. Backed by `logstream.sqlite3` in the palace directory, independent of the vector index. In `--read-only` mode the mutating tools (`event_append`, `event_ack`, `artifact_put`, `patch_submit`) are hidden and refused.
### `mempalace_event_append`
Append an immutable coordination event.
| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `type` | string | **Yes** | Event type, e.g. `task.request`, `task.reply`, `patch.ready` |
| `stream` | string | **Yes** | Logical stream, e.g. `project/myapp` or `shared_agent_brain` |
| `room` | string | **Yes** | Sub-channel: `delegation`, `patches`, `reviews`, `status` |
| `from_agent` | string | **Yes** | Writer agent identity |
| `to_agent` | string | No | Target agent, or `*` for broadcast |
| `correlation_id` | string | No | Task id tying request and reply events together |
| `branch` | string | No | Git branch, when relevant |
| `base_commit` | string | No | Git commit the work started from |
| `status` | string | No | `open`, `claimed`, `ready`, `applied`, `blocked`, `failed`, `superseded` |
| `body` | string | No | Verbatim content (max 256 KiB) |
| `metadata` | object | No | Extra structured fields, stored verbatim |
| `artifact_ids` | array | No | Ids of already-stored artifacts to reference |
**Returns:** `{ success, event }` — the stored event including server-generated `id`, `seq`, and `created_at`.
---
### `mempalace_event_list`
List events with structured filters, oldest first.
| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `stream` | string | No | Filter by stream |
| `room` | string | No | Filter by room |
| `type` | string | No | Filter by event type |
| `to_agent` | string | No | Filter by target; also matches `*` broadcasts |
| `from_agent` | string | No | Filter by writer |
| `correlation_id` | string | No | Filter by correlation id |
| `status` | string | No | Filter by status |
| `since_event_id` | string | No | Only events strictly after this id (precise cursor) |
| `since_created_at` | string | No | Only events at/after this time (inclusive) |
| `limit` | integer | No | Max events (default 50, cap 500) |
**Returns:** `{ events: [...], count }`
---
### `mempalace_event_wait`
Block until a matching event exists or the timeout expires (long-poll; max 5 minutes). Accepts the same filters as `event_list` plus:
| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `timeout_ms` | integer | No | Wait duration in ms (default 60000, clamped to 300000) |
**Returns:** `{ timed_out, events: [...], count }` — timeout is a normal result, not an error.
---
### `mempalace_event_ack`
Acknowledge an event: appends a new `event.ack` routed back to the original writer, with `correlation_id` copied from the target (falling back to the target's id). Never mutates the target event.
| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `event_id` | string | **Yes** | Event to acknowledge |
| `from_agent` | string | **Yes** | Acknowledging agent identity |
| `status` | string | No | e.g. `applied`, `failed` |
| `body` | string | No | Verbatim ack notes |
**Returns:** `{ success, event }` — the new ack event.
---
### `mempalace_artifact_put`
Store exact artifact content for handoffs. UTF-8 text only, max 4 MiB.
| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `kind` | string | **Yes** | `patch`, `file`, `log`, `json`, `note` |
| `content` | string | **Yes** | Exact content |
| `created_by` | string | **Yes** | Writer agent identity |
| `metadata` | object | No | Extra fields, e.g. branch/base_commit |
**Returns:** `{ success, artifact: { id, kind, sha256, size_bytes, created_by, created_at } }`
---
### `mempalace_artifact_get`
Fetch an artifact by id — exact content plus `sha256` for verification.
| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `artifact_id` | string | **Yes** | Artifact id |
**Returns:** `{ artifact: { id, kind, sha256, size_bytes, content, created_by, created_at, metadata } }` (or `{ error }` if not found)
---
### `mempalace_patch_submit`
Convenience: store a patch artifact and append its `patch.ready` event in one call.
| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `content` | string | **Yes** | Unified diff content |
| `from_agent` | string | **Yes** | Submitting agent identity |
| `stream` | string | **Yes** | Logical stream |
| `room` | string | No | Sub-channel (default `patches`) |
| `to_agent` | string | No | Target agent or `*` |
| `correlation_id` | string | No | Task id tying the patch to its request |
| `branch` | string | No | Git branch |
| `base_commit` | string | No | Git commit the patch applies to |
| `body` | string | No | Verbatim notes |
| `metadata` | object | No | Extra structured fields |
**Returns:** `{ success, artifact, event }`