Naming as Navigation
Names in WarmHub — for things and assertions alike — can contain / to create hierarchical paths, like directories in a filesystem. This isn’t a cosmetic feature. Naming is navigation. A well-designed namespace turns a flat bag of records into a structure that agents can explore, predict, scope, and react to.
This hierarchy doesn’t start at the thing name — it extends all the way up through WarmHub’s URL structure:
app.warmhub.ai/orgs/acme/repos/catalog/Product/electronics/phones/pixel-9 ───┬─ ──┬─── ──┬─── ─────────┬────────────── org repo shape thing nameOrganization, repository, shape, and thing name compose into one continuous path. The slashes in your thing names are a natural extension of the hierarchy that already exists — from org to repo to shape to the deepest leaf of your data.
One important difference from a filesystem: intermediate path segments don’t need to exist as their own entities. If you have Product/electronics/phones/pixel-9, there is no requirement for a thing called Product/electronics or Product/electronics/phones to exist. The hierarchy lives in the naming convention, not in a tree of parent objects. Glob queries like Product/electronics/** still work — they match against the name string, not against a chain of parent entities. This means you can design deep, descriptive paths without needing to populate every level.
Two Ways to Move Through Knowledge
Section titled “Two Ways to Move Through Knowledge”A WarmHub repo gives you two navigation axes:
Vertical — the hierarchy. Slash-separated names create parent-child relationships. If you’re looking at Product/electronics/phones/pixel-9, you can move up to see all phones, all electronics, or every product in the catalog. This is tree navigation — the same mental model as a filesystem.
Lateral — assertions. Assertions link things to other things across the hierarchy. A Review assertion might connect Product/electronics/phones/pixel-9 to Brand/google. That link cuts across the tree, connecting two branches that hierarchy alone can’t reach.
Together, these form a web — not a flat list, not a rigid tree, but a navigable structure with both predictable paths (hierarchy) and cross-cutting connections (assertions).
Product/ Brand/├── electronics/ ├── google ◄─────────────────┐│ ├── phones/ ├── apple ││ │ ├── pixel-9 ─────────────────│── Review assertion ─────────┘│ │ └── iphone-16 └── samsung│ └── laptops/│ ├── macbook-air Supplier/│ └── thinkpad-x1 ├── asia/├── home/ │ ├── foxconn│ ├── kitchen/ │ └── tsmc│ └── lighting/ └── na/└── outdoor/ └── intelAn agent exploring this structure can navigate the product tree to find a specific item, then follow assertions laterally to discover its brand — and from that brand, follow their assertions to find other products, ratings, or supplier relationships. The hierarchy gets you to the right neighborhood; assertions let you traverse the graph.
Why This Matters for Agents
Section titled “Why This Matters for Agents”If you’re an AI agent working with a WarmHub repo, hierarchical naming changes what’s possible within your context window.
Scoped exploration
Section titled “Scoped exploration”You can’t load an entire repo. But you can narrow to a subtree:
# Everything in electronicswh thing list --match "Product/electronics/**"
# Just phoneswh thing list --match "Product/electronics/phones/*"
# All categories, just 2024 modelswh thing list --match "Product/**/2024/*"This is the difference between searching and navigating. Searching requires you to know what you’re looking for. Navigation lets you explore a structure and find things you didn’t know existed.
Predictive navigation
Section titled “Predictive navigation”If you see Sensor/building-a/floor-3/temp, you can predict that Sensor/building-a/floor-2/temp probably exists. If you see Report/2024-q1/summary, you can guess at Report/2024-q2/summary. Hierarchy makes the unknown discoverable by analogy — you can infer the namespace conventions from a few examples and then navigate confidently to things you haven’t seen yet.
Flat naming (sensor-building-a-floor-3-temp) carries the same information for humans, but gives agents no structure to parse, no segments to substitute, no tree to traverse.
Self-documenting addresses
Section titled “Self-documenting addresses”The wref Article/tech/2024/transformer-scaling tells you what it is before you read any data. The hierarchy is metadata — category, year, topic — encoded in the address itself. An agent can reason about what a thing represents purely from its name, without fetching its data.
Reactive subtree watching
Section titled “Reactive subtree watching”Subscriptions can filter on match with the same glob syntax used by wh thing list --match, so you can set up Actions that watch entire branches of the hierarchy — or any subset expressible as a glob:
{ "all": [ { "operation": "add" }, { "kind": "thing" }, { "match": "Sensor/building-a/**" } ]}Any new thing added under Sensor/building-a/ — any floor, any sensor type — triggers the action. The hierarchy becomes an event routing structure, not just an address scheme. You can build pipelines that react to categories of data without enumerating every possible thing name, and you can use globstars (Sensor/**/temp), single-segment wildcards (Product/*/phones/*), or brace expansion (Sensor/hq/floor-{3,4}/*) to express exactly the subset you care about.
Designing Your Namespace
Section titled “Designing Your Namespace”Lead with the natural grain of the domain
Section titled “Lead with the natural grain of the domain”The best hierarchies follow how the data is actually organized, queried, and explored. Ask: “What are the most common ways someone will want to narrow into this data?”
Product catalog — the natural grain is category, then subcategory, then item:
Product/electronics/phones/pixel-9Product/electronics/laptops/macbook-airProduct/home/kitchen/instant-pot-duoProduct/outdoor/camping/rei-half-domeThis lets you query by top-level category (Product/electronics/**), by subcategory (Product/electronics/phones/*), or across categories for a specific type (Product/**/camping/*).
IoT sensor network — the natural grain is physical location, then sensor type:
Sensor/hq/floor-3/conference-a/tempSensor/hq/floor-3/conference-a/humiditySensor/hq/floor-3/hallway/motionSensor/warehouse/zone-b/tempAn agent monitoring building conditions can glob Sensor/hq/floor-3/** to get everything on that floor, or Sensor/**/temp to compare temperatures across all locations.
Research corpus — the natural grain is source, then year, then topic:
Paper/arxiv/2024/attention-mechanisms-surveyPaper/arxiv/2023/transformer-efficiencyPaper/acl/2024/multilingual-ragPut the most-filtered dimension first
Section titled “Put the most-filtered dimension first”The first segments after the shape should be the dimensions you’ll filter on most often. If you almost always query by region, put region first. If you almost always query by date, lead with date.
# Category-first — good when most queries browse by typeProduct/electronics/phones/pixel-9
# Region-first — good when most queries are geography-scopedProduct/us/electronics/phones/pixel-9Neither is universally right. Pick the order that matches how agents will actually explore the data.
Keep segments meaningful and stable
Section titled “Keep segments meaningful and stable”Each segment should carry information. Avoid segments that are just structural padding:
# Every segment tells you somethingCompany/acme/filing/10-k/2024
# "data" and "records" are noiseCompany/acme/data/records/filing/10-k/2024Use stable identifiers — not timestamps, not UUIDs (unless you have a reason). Names can be changed, but stable names make wrefs readable and wrefs are how agents refer to things in conversation.
Stay flat when hierarchy doesn’t earn its keep
Section titled “Stay flat when hierarchy doesn’t earn its keep”Not everything needs deep nesting. If a shape has a few dozen things with no natural grouping, flat names are fine:
# No need for hierarchy hereCurrency/usdCurrency/eurCurrency/jpyHierarchy should emerge from the domain, not from a desire for tidiness. Two levels is often enough. Five levels should make you pause and ask whether the extra depth is actually helping agents navigate.
Use hierarchy for things, assertions for relationships
Section titled “Use hierarchy for things, assertions for relationships”Hierarchy models containment — a product belongs to a category and subcategory. Assertions model connections — a product is reviewed by an agent, or a paper cites another paper.
Don’t try to encode relationships in the name:
# Don't do this — the relationship belongs in an assertionProduct/electronics/made-by-samsung/phones/galaxy-s24
# Do this — clean hierarchy, with assertions for relationshipsProduct/electronics/phones/galaxy-s24 └── SuppliedBy assertion → about: Supplier/asia/samsung └── Review assertion → about: Product/electronics/phones/galaxy-s24Hierarchy answers “where does this live?” Assertions answer “what is this connected to?”
Querying the Hierarchy
Section titled “Querying the Hierarchy”Glob matching
Section titled “Glob matching”The --match flag on query commands supports full glob syntax:
| Pattern | Meaning |
|---|---|
Product/electronics/* | Direct children of Product/electronics/ (one segment) |
Product/electronics/** | All descendants of Product/electronics/ (any depth) |
Product/*/phones/* | All phones across all top-level categories |
Sensor/**/temp | All temperature sensors at any location depth |
Product/{electronics,home}/** | Electronics and home products (brace expansion) |
Company/acme/filing/10-* | Partial segment match (10-K, 10-Q) |
# Explore a subtreewh thing list --match "Sensor/hq/floor-3/**"
# Cross-cut: all temperature readings everywherewh thing list --match "Sensor/**/temp"
# Multiple categorieswh thing list --match "Product/{electronics,home,outdoor}/**"Glob patterns also work in MCP queries and the SDK’s query methods — not just the CLI.
Combining with assertions
Section titled “Combining with assertions”The real power shows when you combine hierarchical queries with assertion traversal:
# Step 1: Find all phones in the catalogwh thing list --match "Product/electronics/phones/*"
# Step 2: For a specific product, find what's been said about itwh thing about Product/electronics/phones/pixel-9
# Step 3: Follow a link to the brandwh thing view Brand/google
# Step 4: What else do we know about this brand?wh thing about Brand/googleThis is tree-then-graph navigation: use hierarchy to get to the right neighborhood, then follow assertions to traverse the web.
Subscription match
Section titled “Subscription match”For reactive pipelines, match on subscription filters uses the same glob vocabulary as query --match, so the patterns you learn for navigation translate directly to what you subscribe to:
{ "all": [ { "operation": "add" }, { "kind": "thing" }, { "match": "Product/electronics/**" } ]}This fires whenever any new thing is added under Product/electronics/ — phones, laptops, tablets, anything. And unlike a plain prefix, the glob lets you slice by shape patterns too: Sensor/**/temp to react to temperature sensors wherever they live in the tree, or Product/{electronics,home}/phones/* to watch phones across multiple top-level categories.
Array form OR-combines patterns ({"match": ["A/**", "B/**"]} matches either branch); wrap two predicates in all to require both.
Patterns in Practice
Section titled “Patterns in Practice”Ingestion pipeline
Section titled “Ingestion pipeline”A scraper pulls product listings from multiple sources, organized by category:
Product/electronics/phones/pixel-9Product/electronics/phones/iphone-16Product/electronics/laptops/macbook-airProduct/home/kitchen/instant-pot-duoA subscription watches Product/electronics/ and triggers a classification action for each new item. That action creates assertions — Review assessments, PriceTrack observations, SimilarTo comparisons linking to other products. Now agents can navigate the product tree to find items, then follow assertions to discover relationships, ratings, and alternatives.
Multi-agent research
Section titled “Multi-agent research”Three agents investigate companies from different angles:
# Things — the entitiesCompany/acmeCompany/globexFiling/acme/10-k/2024Filing/globex/10-k/2024
# Assertions — each agent's perspectiveThesis/acme-growth (about: Company/acme) — agent-1's growth thesisRiskFlag/acme-debt (about: Company/acme) — agent-2's risk assessmentComparison/acme-v-globex (about: {pair: [Company/acme, Company/globex]}) — agent-3An agent reviewing Acme can:
- Glob
Filing/acme/**to see all filings - Query assertions about
Company/acmeto see every agent’s perspective - Follow the
Comparisonassertion to discover Globex as a peer, then exploreFiling/globex/**
The hierarchy organized the filings. The assertions connected the perspectives. The agent navigated both.
Sensor monitoring with escalation
Section titled “Sensor monitoring with escalation”Sensor/hq/floor-3/conference-a/tempSensor/hq/floor-3/conference-a/co2Alert/hq/floor-3/conference-a/co2-high-2024-03-15A subscription with match: "Sensor/hq/**" triggers a threshold-check action for any sensor data committed under HQ. When CO2 exceeds limits, the action commits an Alert thing — named in the same hierarchy so it’s discoverable alongside the sensor it relates to. A separate subscription with match: "Alert/**" triggers notifications.
The naming hierarchy is doing double duty: organizing the data and routing the events.
Anti-Patterns
Section titled “Anti-Patterns”Encoding relationships in names. If you find yourself putting one thing’s identity inside another thing’s name (Product/reviewed-by-agent-1/phones/pixel-9), use an assertion instead. Names should reflect containment and categorization, not cross-references.
UUID-heavy names. Product/f47ac10b-58cc-4372-a567-0e02b2c3d479 is valid but opaque. Agents can’t infer anything from it. If you need generated names, use batch tokens ($N/#N), but prefer human-readable names when the domain has natural identifiers.
Inconsistent depth. If most products are Product/category/subcategory/name but some are Product/name, agents can’t predict the structure. Keep the same shape’s things at consistent depth, or at least document the convention. Note that consistent depth doesn’t mean every level needs things at it — Product/electronics/phones/pixel-9 works fine even if nothing exists at Product/electronics/phones. The point is that things of the same kind should live at the same depth so glob patterns work predictably.
Too deep. Every segment should earn its place. Data/raw/ingested/pipeline-v2/batch-003/electronics/phones/pixel-9 has structural noise that doesn’t help navigation. Flatten to what agents will actually filter on.
Overloading hierarchy when a shape would work. If you’re using hierarchy to separate fundamentally different kinds of data (Entity/person/jones vs Entity/company/acme), consider whether those should be separate shapes (Person/jones, Company/acme). Shapes give you schema-level structure; hierarchy gives you instance-level organization. Use both.
Hit a problem or have a question? Get in touch.