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.
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.
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.
Only the originating metadata.agent_id can read it. The default for any memory without an explicit scope. Personal notes, draft thoughts.
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.
Walks two levels up. platform/team-a/alice is visible to all of platform/*. The "your immediate organization" ring.
Visible to every agent under the same root namespace. Org-wide announcements, charters, public-by-default policies.
Visible to every peer in the federation. Cross-org public knowledge — open standards, public APIs.
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.
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.
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.
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.
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.