Diana Valdes
← Interactions
Protocoldesignerdevagent

#rū - portable context primitive

Seed personal knowledge with a #tag. Any agent that can listen, fetches it.

LIVE DEMO

Try a live public seed:

#ru/onboarding.ru

To call it, install rū in Claude Desktop:

bash
npx ru-mcp setup

Then in any Claude conversation, type:

Use #ru/onboarding.ru

OVERVIEW

The # primitive does two things depending on context. When you're writing, it seeds — attaching meaning to a thought and storing it for retrieval. When you're commanding, it resolves — pulling that context into an agent's working memory at the exact moment it's needed.

This is the most load-bearing pattern in the library. Every other interaction assumes the agent already has context to work with. # is how that context gets there — authored by the human, not harvested automatically.

rū is built on a single philosophical constraint: the person who plants is always known. Anonymous seeding is architecturally impossible. Context has authorship, or it doesn't exist.

PROTOCOL

A tag breaks down as tree/document.namespace

#work/brief.diana└── tree: work└── document: brief└── namespace: diana ← public, callable by anyone
#work/brief└── no namespace suffix└── private, owner only, never leaves your machine
private:no namespace suffix · owner only
public:namespace suffix · callable by any agent, no auth required · returns external_context typed primitive

WHEN TO USE / WHEN NOT TO USE

When to use

  • Context needs to travel across sessions or surfaces
  • You want an agent to reference specific personal knowledge
  • The human, not the system, should decide what's relevant
  • You're building multi-agent workflows that require shared context

When not to use

  • Context is ephemeral and session-specific
  • The agent should determine relevance autonomously
  • You're building a fully automated pipeline with no human authorship
  • Context is better handled by RAG or retrieval over a corpus

AGENT SPEC

yaml
pattern: context-primitive
primitive: "#"
modes:
  seed:
    trigger: writing-surface
    action: store-context-under-tag
  resolve:
    trigger: command-surface
    action: retrieve-context-by-tag
access:
  private: no-namespace-suffix
  public: tree/document.namespace
api:
  resolves: GET https://ru-ivory.vercel.app/api/resolve/{namespace}/{path}
  response: { type, namespace, path, content, flagged }
security:
  authorship: always-known
  anonymous-seeding: architecturally-impossible
  external_context: typed-primitive, never-treated-as-instructions

CODE

bash
# Install
npx ru-mcp setup

# Call a public seed (in any Claude conversation)
Use #ru/onboarding.ru

# Call a private seed (your own grove)
Use #work/brief
→ resolves locally, never leaves your machine

# Machine endpoint (for agents)
GET https://ru-ivory.vercel.app/api/resolve/ru/ru/onboarding
← { type: "external_context", content: "...", flagged: false }

ARCHITECTURE & DESIGN

Three-tier context model

rū separates context into three distinct tiers, each with different trust and transport boundaries:

local private → stays on device, never touches the networkgrove private → cloud-stored, owner-only, authenticated readsgrove public → world-readable, no auth required, typed response

The decision to hard-separate local from cloud wasn't a tradeoff — it was a constraint. Private context that could accidentally become network-accessible isn't private. The tiers are architecturally distinct, not just permission flags.

external_context as a typed primitive

Public seeds don't return raw strings. They return a typed object:

json
{
  "type": "external_context",
  "namespace": "ru",
  "path": "...",
  "content": "...",
  "flagged": false
}

The type field is the security boundary. Agents are expected to treat external_context as reference material — never as instructions. This is a defense against prompt injection via public seeds: a malicious seed can't disguise itself as a system prompt if the transport layer labels it explicitly.

Authorship is non-negotiable

rū is built around one constraint: authorship is always known. There is no anonymous write path — every seed is tied to an authenticated identity. This means every piece of public context has a traceable author, which is the prerequisite for community flagging to work at all.

MCP as the transport layer

rū doesn't own the pipe. It runs as an MCP server, which means it works in any client that supports the protocol — Claude Desktop, Cursor, and others — without rū needing to build individual integrations. The resolution logic lives in the server; the client just calls a tool.

Keeper and bring-your-own-key

Keeper is the synthesis layer — it reads seed history and maintains a distilled, always-current summary of each document. It runs under the user's own LLM API key. rū never pays for synthesis and never sees the key. Per-document toggle lets users opt specific seeds out of synthesis entirely — useful for seeds that shouldn't be rewritten automatically.

Centralized namespace resolution, local private context

Global namespace resolution requires a central registry — there's no way around it if #path.namespace needs to be callable from anywhere. rū uses a hosted Supabase instance for this. But private context never touches it. The MCP server handles private reads locally, and the Supabase layer only ever sees public seeds and namespace metadata.

Machine-readable index at /patterns.json