vortx-ai/emem/emem-multi-agent-handoff
Claude Code and agent skill by vortx-ai/emem
- community
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-handoffSKILL.md
emem-multi-agent-handoff
| Use it when | Work crosses from one agent to another, and the receiver must check it without your context. | |
| You need | Fact cids or tokens to hand over. A note path to check. To write or seal, your own Ed25519 key (optional emem-signer plugin). | |
| You get | A token per reading or one bundle token, a MATCH/VALID authorship check per note, and an optional sealed note for one recipient. | |
| Calls | emem_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 tohttps://emem.devand receive JSON from it. Where a step says so, they also receive an image or a raster file.https://emem.devis the service that the MCP server of the plugin connects to. The commands do not execute what they download. The files underscripts/read only the files that you give them.verify_note.pymakes no network call unless you pass--read-key-card. With that flag, it sends one read-only GET tohttps://emem.devfor 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 over | The receiver gets | Strength | |
|---|---|---|---|
| a prose summary | your claim | nothing to check | |
emem:fact:<cell64>:<fact_cid> | the byte-identical signed reading | full 32-byte digest, binds the body | |
emem:raster:, emem:cube:, emem:rasterset: | a signed field, a field over time, or a set of fields | binds the derivation record, which pins the BLAKE3 of the artifact | |
emem:tree:<index> | a file cut into units under one Merkle root | binds each unit through its audit path (`emem-tokenise-files`) | |
emem:bundle:<cid> | the set that you assembled | 16-byte anchor, names the set | |
emem:entity:<cid> | the object that you mean | 16-byte anchor, names the object (`emem-shared-identity`) | |
emem:cell:<cell64> | an address | nothing to dereference | |
| a signed note in your namespace | prose and proof of who wrote it | signature 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:
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:
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:
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:
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:
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:
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:
This is the output on 7 November 2026, for the agent-to-agent standard itself:
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.
| Line | Result | Meaning | Exit code | |
|---|---|---|---|---|
body | MATCH | The content hashes to the signed body hash. | 0 | |
body | MISMATCH | The content changed after the key signed it. On 7 November 2026, one changed letter gave this result. | 1 | |
sig | VALID | The named key signed this verb, path and body hash. | 0 | |
sig | INVALID | The signature does not cover these bytes. On 28 September 2026, a changed signed_path gave this result. | 1 | |
banner | VALID | The key in the banner stated the replacement target and the reason. | no change | |
banner | INVALID | The target, the reason or the base changed after the key signed them. | 1 | |
banner | UNSIGNED | An older supersede with no stored signature. Only the responder vouches for it. | no change | |
banner | NONE | No supersede replaces the note. | no change | |
card | see Step 5 | The 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:
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 result | Meaning | |
|---|---|---|
NONE | There is no card at that path. | |
UNCHECKED | The read failed. | |
FOREIGN, INVALID, UNSIGNED | The card at that path does not verify as the card of this key. The script does not show it. | |
SKIPPED | You 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):
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
- SKILL.md in the repositoryCheckingplugins/emem/skills/emem-multi-agent-handoff/SKILL.md
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
[](https://verified-skill.com/skills/vortx-ai/emem/emem-multi-agent-handoff)