Memory trees, 8 levels deep.

Namespaces aren't tags — they're paths. alphaone/engineering/platform/team-a/squad-1/alice is a real, valid namespace. Hierarchical paths give you team isolation, organizational inheritance, and visibility scopes that mirror how real organizations work. v0.6.3 ships the memory_get_taxonomy tool that walks the tree and returns it as a queryable structure.

8-level depth 5 visibility scopes parent inheritance memory_get_taxonomy (v0.6.3) v0.6.3 Stream A
The tree itself

A real namespace path, 8 levels.

Flat namespaces ("global", "ai-memory-dev") still work — hierarchy is opt-in. When you go hierarchical, segments split on /, and depth caps at MAX_NAMESPACE_DEPTH = 8. Validators reject leading/trailing slashes, empty segments, and path-traversal segments (. / ..) per red-team #240.

alphaone L1 · org root engineering L2 · division platform L3 · group team-a L4 · team team-b L4 · team squad-1 L5 · squad squad-2 L5 · squad pod-x L6 · pod pod-y L6 · pod role-eng alice 8 levels max — MAX_NAMESPACE_DEPTH flat namespaces still work ("global", "ai-memory-dev") Path-traversal blocked: alphaone/.. → REJECTED alphaone//eng → REJECTED /alphaone → REJECTED (no leading /) Each level can carry a namespace_meta standard, parents inherited automatically
Scope visibility — Task 1.5

Five rings of "who can see this."

Every memory carries a metadata.scope. The query layer combines that scope with the calling agent's namespace position (as_agent) to decide if the memory is visible. Memories with no explicit scope are treated as private.

private
visibility · 1 agent

Only the originating metadata.agent_id can read it. The default for any memory without an explicit scope. Personal notes, draft thoughts.

team
visibility · same namespace prefix

Visible to any agent whose as_agent shares the same namespace prefix as the memory. team-a/alice + team-a/bob see each other; team-b/charlie doesn't.

unit
visibility · 2 levels up

Walks two levels up. platform/team-a/alice is visible to all of platform/*. The "your immediate organization" ring.

org
visibility · entire org root

Visible to every agent under the same root namespace. Org-wide announcements, charters, public-by-default policies.

collective
visibility · federation-wide

Visible to every peer in the federation. Cross-org public knowledge — open standards, public APIs.

// On write — scope is opt-in (defaults to "private") {"title": "Q3 OKR draft", "namespace": "alphaone/eng/platform/team-a", "scope": "team"} // On read — caller stamps as_agent so the daemon knows where they are // in the hierarchy. The query filter then decides which scopes match. {"q": "OKR", "as_agent": "alphaone/eng/platform/team-a/bob"} → sees: scope=team where namespace prefix matches "alphaone/eng/platform/team-a" → sees: scope=unit where namespace prefix matches "alphaone/eng/platform" → sees: scope=org where namespace prefix matches "alphaone" → sees: scope=private only when metadata.agent_id == "bob"
memory_get_taxonomy — v0.6.3 Stream A

Walk the tree as data.

The grand-slam memory_get_taxonomy tool returns the live tree of namespaces with per-node counts. Drives dashboards, taxonomy-aware UIs, and the org-overview narrative without needing to enumerate every memory.

// MCP — memory_get_taxonomy { "namespace_prefix": "alphaone/engineering", // optional · scopes the walk "depth": 8, // default 8 = MAX_NAMESPACE_DEPTH "limit": 1000 // default 1000, max 10000 }

Returns a TaxonomyNode tree with per-node count (memories at exactly this namespace) and subtree_count (count plus every descendant). The envelope adds total_count (independent aggregation, honest even when limit truncates) and a truncated flag.

alphaone/engineering/ total_count: 1247 truncated: false ├── platform/ subtree: 856 │ ├── team-a/ subtree: 412 │ │ ├── squad-1/ subtree: 211 │ │ │ ├── pod-x/ count: 87 │ │ │ └── pod-y/ count: 124 │ │ └── squad-2/ subtree: 201 │ └── team-b/ subtree: 444 └── research/ subtree: 391 ├── papers/ count: 178 └── experiments/ count: 213

Why subtree_count matters: "How big is the platform org's memory footprint?" — one number, one lookup. Without subtree aggregation you'd have to enumerate and count yourself, which scales poorly past a few thousand rows.

Namespace standards — inheritance

Set policy once, inherit everywhere.

Every namespace can have a standard memory — the canonical row at that path whose metadata carries the per-namespace policy (governance + default scope + parent_namespace pointer). When a write hits a namespace with no standard, the resolver walks up the path until it finds one. Set the standard at alphaone/eng once, every sub-namespace inherits.

// Set the standard at the platform group level // MCP — memory_namespace_set_standard { "namespace": "alphaone/engineering/platform", "title": "Platform standard", "content": "Platform-wide architectural decisions and conventions.", "metadata": { "governance": { "write": "registered", "promote": "approve", "delete": "owner", "approver": {"consensus": 2} }, "scope": "team", // default scope for new memories under this ns "parent_namespace": "alphaone/engineering" // explicit parent link } } // Now — every write to alphaone/engineering/platform/* applies these rules. // alphaone/engineering/platform/team-a/squad-1/pod-x has no standard of its own, // so the resolver walks up the chain: write to: alphaone/engineering/platform/team-a/squad-1/pod-x ↓ no standard walk to: alphaone/engineering/platform/team-a/squad-1 ↓ no standard walk to: alphaone/engineering/platform/team-a ↓ no standard walk to: alphaone/engineering/platform ↓ FOUND — apply this standard's governance + scope
Federation propagation — v0.6.2 S35

Every peer agrees on the tree.

A namespace standard's metadata gets pushed to peers via the sync_push.namespace_meta field (S35 fanout). Without this propagation, peers would see the standard memory itself but miss the (namespace, standard_id, parent_namespace) tuple, and inheritance walks on the peer would fall back to auto_detect_parent — different answers on different peers.

// sync_push body — the additive namespace_meta field { "memories": [...], // the standard memory itself "namespace_meta": [ { "namespace": "alphaone/engineering/platform", "standard_id": "550e8400-…", "parent_namespace": "alphaone/engineering", "updated_at": "2026-04-27T05:00:00Z" } ] } // Peer applies via db::set_namespace_standard, mirrors our local row.