How retrieval works

Retrieval is the core read path in Estratos. An agent asks for a scope path and gets back one Markdown bundle. This page explains what that bundle contains and how its explicit priorities determine which memory wins when guidance conflicts.

Paths address scopes, never single memories

A path like root.pennine-joinery.vat addresses a scope in the hierarchy. It never points at an individual memory. There is no way to fetch one memory by key, id, or version through retrieval — memory bodies are only ever returned as part of a scope bundle. (The one exception is archive_memory, which takes a memory id purely to archive it, never to read it.)

The walk: root to target

When you retrieve root.pennine-joinery.vat, Estratos walks the tree from the root down to that folder, visiting each ancestor in order:

root  →  root.pennine-joinery  →  root.pennine-joinery.vat

At each step (depth) along that walk, it gathers the memories that apply and stitches them into one bundle. A memory high in the tree (say, a firm-wide standard on root) is included alongside the specifics of the exact engagement.

Priority determines precedence

Every block header carries priority: N. A higher-priority block overrides a lower-priority block where they conflict; it replaces the conflicting guidance rather than adding to it. Lower-priority material still applies wherever it does not conflict. If equal-priority blocks contradict each other, neither wins — the agent should surface the conflict.

Priorities increase with depth. At the same depth, layer-wide tagged, value-targeted tagged, and scoped memories occupy consecutive tiers, with scoped highest. For example, at depth 2 they are priorities 7, 8, and 9.

The bundle still emits scoped, then layer-wide tagged, then value-targeted tagged memories at each depth, with stable-key ordering inside a bucket. That order makes the bundle deterministic but carries no precedence meaning — only the priority values do. The bundle opens with a comment that states this contract.

Each block then starts with a compact header:

  • Scoped: <!-- scoped: root.acme.vat | priority: 9 | key: vat-policy -->
  • Tagged: <!-- tagged: services=vat | priority: 8 | key: flat-rate-rule | memory_id: UUID -->

Scoped headers identify the canonical path and key. Tagged headers also carry the stable memory_id used for management actions.

An empty scope is a valid answer

If nothing applies to a scope, retrieval returns an empty bundle — that's a success, not an error. A scope with a single memory is still a scope retrieval; no memory is ever fetched on its own.

Canonical paths and aliases

You can rename a folder without breaking anything. After a rename:

  • The old path keeps resolving as an alias, so agents and bookmarks that used it still work.
  • Retrieval headers always show the canonical (current) path, even when you retrieved through an alias — so what an agent reads back is never stale.

This is why renaming a folder is always safe, while changing the hierarchy's structure goes through the draft-and-publish flow instead.

What you see vs. what everyone sees

Retrieval honours the review workflow's visibility rules. Published memories are visible to everyone. On top of that, your own pending work folds into your bundles: a pending create you made appears in its bucket, and a pending edit's content replaces the published body — but only for you, through your own agent. Those headers end in | pending. Agents apply that content while caveating conclusions that rely on it. Everyone else sees published content only, until an approver signs off.

Over MCP

An agent performs a retrieval with the retrieve tool, passing the scope path. It accepts canonical or aliased paths and returns the bundle as Markdown. See the MCP reference for the tool's exact contract.

Next steps