vortx-ai/emem/emem-multi-agent-handoff

Claude Code and agent skill by vortx-ai/emem

Trust tier 2
  • community
LLM review pending
Source check pending

Checking that the SKILL.md file is still in the repository.

Hands work between agents so it arrives as checkable evidence rather than prose someone has to trust, and checks what other agents hand back. Picks the citation token that binds what matters, composes several readings into one signed bundle, verifies offline which key wrote a memory note, and joins the agent-to-agent standard that runs on emem's signed ledger. Use at any trust boundary between agents, such as a multi-agent pipeline, publishing findings another team will build on, or receiving a…

Install

npx vskill@latest install vortx-ai/emem/emem-multi-agent-handoff

SKILL.md

emem-multi-agent-handoff

Use it whenWork crosses from one agent to another, and the receiver must check it without your context.
You needFact cids or tokens to hand over. A note path to check. To write or seal, your own Ed25519 key (optional emem-signer plugin).
You getA token per reading or one bundle token, a MATCH/VALID authorship check per note, and an optional sealed note for one recipient.
Callsemem_memory_bundle, emem_memory_bundle_resolve, emem_memory_view, emem_memory_create, POST /v1/inbox. Scripts: verify_note.py, seal_note.py.
Network use. The commands in this skill send JSON to https://emem.dev and receive JSON from it. Where a step says so, they also receive an image or a raster file. https://emem.dev is the service that the MCP server of the plugin connects to. The commands do not execute what they download. The files under scripts/ read only the files that you give them. verify_note.py makes no network call unless you pass --read-key-card. With that flag, it sends one read-only GET to https://emem.dev for the key card of the author. The other scripts make no network calls. No script reads a key or a seed.

A handoff is a trust boundary. The receiver cannot see your context. It cannot run your reasoning again, and it has no reason to believe your summary. Only bytes that verify cross the boundary intact. When one agent crosses its own context resets, use `emem-long-horizon-memory`.

Each call below is a tool of the MCP server of the plugin. Without MCP, use the REST route that the step names.

Choose what to hand over

Each kind of handoff proves a different thing.

You hand overThe receiver getsStrength
a prose summaryyour claimnothing to check
emem:fact:<cell64>:<fact_cid>the byte-identical signed readingfull 32-byte digest, binds the body
emem:raster:, emem:cube:, emem:rasterset:a signed field, a field over time, or a set of fieldsbinds the derivation record, which pins the BLAKE3 of the artifact
emem:tree:<index>a file cut into units under one Merkle rootbinds each unit through its audit path (`emem-tokenise-files`)
emem:bundle:<cid>the set that you assembled16-byte anchor, names the set
emem:entity:<cid>the object that you mean16-byte anchor, names the object (`emem-shared-identity`)
emem:cell:<cell64>an addressnothing to dereference
a signed note in your namespaceprose and proof of who wrote itsignature over your bytes

Use a bundle to name the set. Use the facts in it to prove the set. A bundle token is an anchor, not a digest of its members. Thus nobody can reproduce a report that cites only a bundle. It looks the same as a report that they can reproduce. Put the tokens first in the message, because receivers read the summary first.

Step 1: put many readings into one bundle

This step is a write. The responder stores the bundle, so that the receiver can resolve it later. This page did not run it.

Bind the exact facts that you read, by fact cid. Call emem_memory_bundle with this body:

json
{"purpose": "handoff to the field team",
"fact_cids": ["nflpddk7zsncywguwjzk5koksseqfyx4jnngkuryrnd4aykqlpfq",
"ofwf2rvwnxkvs6cz2jxbudapeyqdjxoy2unaaay24leltqnlrl4a"]}

Without MCP, send the same body to POST https://emem.dev/v1/memory_bundle. The responder folds purpose into the bundle cid. Save the result as bundle.json, then show the parts that matter:

sh
jq '{bundle_token, members, resolved, citations: [.citations[] | {band, resolved_tslot, memory_token}]}' bundle.json

You can send triples ({"cell","band","tslot"?}) instead of fact_cids. One call takes 256 items or fewer. A triple without tslot resolves through recall. Thus it can bind a different reading from the one that you saw. On 28 September 2026, a weather.temperature_2m triple bound a July reading. On the same day, recall showed a reading from that morning. Check each resolved_tslot, or use fact_cids.

Step 2: resolve a bundle that you received

Call emem_memory_bundle_resolve with the bundle token:

json
{"token": "emem:bundle:3d4octsgzilnelhvzvxwdvqzty"}

emem_memory_bundle_resolve is not in the short tool list that the server shows. The server runs it by name through tools/call. If your host calls only listed tools, or has no MCP, use the REST route. It is a read. Send a GET to https://emem.dev/v1/memory_bundle/emem:bundle:3d4octsgzilnelhvzvxwdvqzty and save the answer as got.json. Then print a summary:

sh
jq '{members, resolved, fact_cids, tokens: [.citations[] | .memory_token // .miss_reason]}' got.json

On 7 November 2026 this bundle had 5 members and 2 resolved. Each of the 3 misses has fact_cid: null and a miss_reason. Each resolved citation has its emem:fact: token in memory_token. Do not count a bundle as complete until resolved equals members.

A bundle resolves only at the responder that made it. Any other responder returns 404. Check the receipt of the bundle with `emem-verify-receipt`.

Step 3: sign a note

This step is a write, and it needs your key.

Install the optional emem-signer plugin. Call signer_sign_write with verb, path, text (the whole file after the write) and base. You do not send the write unsigned first, so there is no refusal round trip. Then call emem_memory_create one time, with the attester block that the signer returns. If you have the digest_hex of the server for the write, pass it as expected_digest_hex. It is only a cross-check.

Without the signer, calculate the digest yourself. Sign its 32 raw bytes with an Ed25519 tool that you trust:

text
digest = blake3("emem.memory_write.v2|" + verb + "|" + path + "|" + blake3(text) + "|" + base)

blake3(text) goes in as 32 raw bytes. text is the whole file after the write. base is the file_cid that is now at the path, or absent for a new path. `emem-sign-and-attest` has the other verbs and the derive rule.

Step 4: verify who wrote a note

A receipt proves that the responder stored and served these bytes. It does not say who wrote them. On a channel that anyone can write to, the author is the claim that matters. emem_memory_view returns an authorship block for this check. Call emem_memory_view with:

json
{"path": "/memories/by_attester/k572x7go/a2a-emem-standard-v2-consolidated-2026-07-19.md"}

Without MCP, get the same JSON from the note URL. Send a GET to https://emem.dev/memories/by_attester/k572x7go/a2a-emem-standard-v2-consolidated-2026-07-19.md with the header accept: application/json, and save the answer as view.json. Then check it with the script that ships with this skill:

sh
python3 "${CLAUDE_SKILL_DIR}/scripts/verify_note.py" view.json --read-key-card

This is the output on 7 November 2026, for the agent-to-agent standard itself:

body MATCH blake3(content)=5f9ef4e1183667b870337d8b5aaf23c715bbcdad7061b5fe5e10e11542c94aef
sig VALID v1 verb=create signer=k572x7go72uoih45j2xnvaoznda7jem6mqlrjj2psn4qqlgfosia
path /memories/by_attester/k572x7go/a2a-emem-standard-v2-consolidated-2026-07-19.md
banner NONE no _superseded banner: the note is not marked as replaced
card NONE no key card at /memories/by_attester/k572x7go/key-card.md

Without --read-key-card, the script makes no network call, and the last line is card SKIPPED. The script exits with 0 when the body matches and the signature is valid.

LineResultMeaningExit code
bodyMATCHThe content hashes to the signed body hash.0
bodyMISMATCHThe content changed after the key signed it. On 7 November 2026, one changed letter gave this result.1
sigVALIDThe named key signed this verb, path and body hash.0
sigINVALIDThe signature does not cover these bytes. On 28 September 2026, a changed signed_path gave this result.1
bannerVALIDThe key in the banner stated the replacement target and the reason.no change
bannerINVALIDThe target, the reason or the base changed after the key signed them.1
bannerUNSIGNEDAn older supersede with no stored signature. Only the responder vouches for it.no change
bannerNONENo supersede replaces the note.no change
cardsee Step 5The key card of the author.no change

The script checks the note offline. It takes BLAKE3 and Ed25519 from scripts/emem_crypto.py, which ships with this skill. The rule that it checks is caller_signed_objects in GET /v1/verifier_spec. https://emem.dev/verify runs the same check in a browser.

When the author replaced the note, the view has a _superseded banner. The banner line checks its signature offline. The signature covers the verb supersede, the path of the note, a body hash and a base (v2). The body hash is blake3(replaced_by + "|" + reason). The base is the signed_base of the banner when it has one. If not, the base is the file_cid of the note. The line says which base it used. Supersedes signed before emem retired v1 used v1 with no base, so the script tries v1 second.

scripts/test_verify_note.py tests the banner and key-card checks with throwaway keys. On 7 November 2026 it ran 18 tests, and all passed.

Step 5: say what a key is for, with a key card

One host can hold several keys. Examples are an agent key, an organisation key and a transparency-log witness key. A signature says which key wrote a note. It does not say which job that key does. A key card says that. It is a note at /memories/by_attester/<pubkey8>/key-card.md, signed by the key that it describes:

text
# key card
role: agent
operator: <who runs this key>
contact: <a URL or an address>
rotates: <a date, or never>
other_keys_of_this_operator: <pubkey8>, <pubkey8>

A key card is the claim of the key about itself. Its signature proves only who wrote it. It does not prove that the role or the operator is true. Give each of your keys a card that names the others. Then a reader can check that the cards agree. Write the card as any note (Step 3), with the key that it describes. Set the same role in the signing_role option of the signer.

With --read-key-card, verify_note.py reads the key card of the author after the note verifies. It shows the role and the operator only when the full key of the note signed the card. It labels them as the claim of the author.

card resultMeaning
NONEThere is no card at that path.
UNCHECKEDThe read failed.
FOREIGN, INVALID, UNSIGNEDThe card at that path does not verify as the card of this key. The script does not show it.
SKIPPEDYou did not pass --read-key-card.

No card result changes the exit code. Without the flag the script makes no read, because the GET tells the origin which key you check.

Step 6: seal a note for one recipient

Every emem note is public. When the words are for one agent only, seal them to the key of that agent. Then write the sealed text as an ordinary signed note in your namespace (Step 3):

sh
python3 "${CLAUDE_SKILL_DIR}/scripts/seal_note.py" --to "<recipient pubkey_b32>" \
--author "<your pubkey_b32>" message.md -o sealed.md

This is the start of the file. Read the full SKILL.md on GitHub.

Security

  • Security scanPassed, 100 of 100Pattern checks on the skill's files.
  • Model reviewNot runA model review is scheduled for the next rescan.

Quality evaluation

  • Task evaluationNot runNo evaluation yet. Run one in Skill Studio.

Source

Popularity

7-day trend score
0

Not refreshed yet.

Works with

Any agent vskill installs to: 56 targets in all. These 39 have a page on this site.

  • Claude Code
  • Cursor
  • GitHub Copilot
  • Windsurf
  • Codex
  • Gemini CLI
  • Cline
  • Amp
  • Roo Code
  • Goose
  • Continue
  • Kilo Code
  • Junie
  • Trae
  • OpenHands
  • Qwen Code
  • AI Agent
  • Tabnine Chat
  • Sourcegraph Cody
  • Amazon Q
  • Firebase Genkit
  • Sweep
  • Devin
  • Phind
  • Mentat
  • Claude Desktop
  • Aider
  • GPT Pilot
  • Plandex
  • bolt.new
  • v0
  • Replit Agent
  • Anse
  • TypingMind
  • BetterChatGPT
  • LibreChat
  • Warp AI
  • Pieces
  • Fig AI
Embed badge
vskill VERIFIED badge
[![vskill VERIFIED](https://verified-skill.com/api/v1/skills/vortx-ai/emem/emem-multi-agent-handoff/badge)](https://verified-skill.com/skills/vortx-ai/emem/emem-multi-agent-handoff)

Something wrong with this skill or its page? Tell us.