Skip to main content

Retrieval

Retrieval returns memory records the caller is allowed to see, ranked for the current task and expanded through graph relationships. The public daemon API exposes RetrieveGraph for task retrieval and RetrieveByID for direct record lookup.

Every retrieval call requires a TrustContext. The trust context controls sensitivity access and scoped visibility.


Trust Rules

Membrane enforces graduated access control on every read:

  1. A record at or below trust.max_sensitivity is returned in full.
  2. A record exactly one level above trust.max_sensitivity may be returned redacted.
  3. A record two or more levels above trust.max_sensitivity is omitted.
  4. If trust.scopes is non-empty, scoped records must match one of those values. Unscoped records are visible to all allowed callers.
Record sensitivityCaller maxResult
lowmediumFull record
mediummediumFull record
highmediumRedacted metadata
hypermediumNot returned

Redacted records keep IDs, type, sensitivity, salience, tags, scope, and timestamps. Payload, provenance, relations, and audit log are stripped.


RetrieveGraph

rpc RetrieveGraph(RetrieveGraphRequest) returns (RetrieveGraphResponse);

Retrieves ranked root memories for a task descriptor, then expands a bounded graph neighborhood around those roots. This is the preferred retrieval method for prompts because it returns both task-relevant roots and the entity, semantic, or provenance records connected to them.

Request fields

task_descriptorstring

Natural-language description of the current task. With embeddings configured, this drives semantic similarity search.

trustTrustContextrequired

Trust context that gates all returned records.

TrustContext fields
trust.max_sensitivitystringrequired

Maximum sensitivity the caller may read in full: public, low, medium, high, or hyper.

trust.authenticatedboolean

Whether the caller has been authenticated.

trust.actor_idstring

Identifier of the requesting user, agent, or service.

trust.scopesstring[]

Allowed scopes. An empty list means scoped filtering is not applied.

memory_typesstring[]

Optional memory type filter. Valid values are episodic, working, semantic, competence, plan_graph, and entity.

min_saliencenumber

Minimum salience threshold. Records below this value are excluded before graph expansion.

root_limitnumber

Maximum number of ranked root records. SDKs default to 10.

node_limitnumber

Maximum total graph nodes to return, including roots. SDKs default to 25.

edge_limitnumber

Maximum graph edges to return. SDKs default to 100.

max_hopsnumber

Number of relation hops to expand from each root. 0 returns only roots; SDKs default to 1.

Response fields

nodesGraphNode[]

Retrieved records wrapped with root and hop metadata.

edgesGraphEdge[]

Graph edges between returned records.

root_idsstring[]

IDs of the records selected as ranked roots.

selectionSelectionResult

Optional selector metadata when competence or plan graph candidates were scored.

Examples

resp, err := m.RetrieveGraph(ctx, &retrieval.RetrieveGraphRequest{
TaskDescriptor: "fix auth build error",
Trust: retrieval.NewTrustContext(
schema.SensitivityMedium,
true,
"build-agent",
[]string{"project-auth"},
),
MemoryTypes: []schema.MemoryType{
schema.MemoryTypeEntity,
schema.MemoryTypeSemantic,
schema.MemoryTypeCompetence,
schema.MemoryTypeEpisodic,
},
RootLimit: 10,
NodeLimit: 25,
EdgeLimit: 100,
MaxHops: 1,
})
if err != nil {
log.Fatal(err)
}

for _, node := range resp.Nodes {
fmt.Printf("Found: %s (type=%s, root=%t, hop=%d)\n",
node.Record.ID,
node.Record.Type,
node.Root,
node.Hop,
)
}
const graph = await client.retrieveGraph("fix auth build error", {
trust: {
max_sensitivity: Sensitivity.MEDIUM,
authenticated: true,
actor_id: "build-agent",
scopes: ["project-auth"],
},
memoryTypes: ["entity", "semantic", "competence", "episodic"],
rootLimit: 10,
nodeLimit: 25,
edgeLimit: 100,
maxHops: 1,
});

for (const node of graph.nodes) {
console.log(`${node.record.id} ${node.record.type} root=${node.root} hop=${node.hop}`);
}
graph = client.retrieve_graph(
"fix auth build error",
trust=TrustContext(
max_sensitivity=Sensitivity.MEDIUM,
authenticated=True,
actor_id="build-agent",
scopes=["project-auth"],
),
memory_types=["entity", "semantic", "competence", "episodic"],
root_limit=10,
node_limit=25,
edge_limit=100,
max_hops=1,
)

for node in graph.nodes:
print(f"{node.record.id} {node.record.type.value} root={node.root} hop={node.hop}")

Prompt Projection

For LLM prompts, use the root nodes as the shortest high-signal context, or include all graph nodes when entity and provenance context matter:

const roots = graph.nodes.filter((node) => node.root).map((node) => node.record);
const context = roots.map((record) => JSON.stringify(record)).join("\n");

Use rootLimit, nodeLimit, and maxHops to keep prompt context bounded.


RetrieveByID

rpc RetrieveByID(RetrieveByIDRequest) returns (MemoryRecordResponse);

Fetches a single record by UUID. The same trust rules apply. If the record does not exist or trust denies access, the RPC returns an error.

Request fields

idstringrequired

UUID of the record to retrieve.

trustTrustContextrequired

Trust context that gates access to the record.

Response fields

recordMemoryRecord

The requested typed memory record.

Example

record, err := m.RetrieveByID(ctx, recordID, retrieval.NewTrustContext(
schema.SensitivityHigh,
true,
"support-agent",
[]string{"project-auth"},
))
if err != nil {
log.Fatal(err)
}
fmt.Println(record.ID, record.Type)
const record = await client.retrieveById(recordId, {
trust: {
max_sensitivity: Sensitivity.HIGH,
authenticated: true,
actor_id: "support-agent",
scopes: ["project-auth"],
},
});
record = client.retrieve_by_id(
record_id,
trust=TrustContext(
max_sensitivity=Sensitivity.HIGH,
authenticated=True,
actor_id="support-agent",
scopes=["project-auth"],
),
)

Layer Order

When no memory_types filter is supplied, graph retrieval starts from the same layered ranking model used internally:

working -> entity -> semantic -> competence -> plan_graph -> episodic

The graph expansion can add related records of any allowed type, subject to trust, node, edge, and hop limits.