Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Reference Tree

The Reference Tree semantic module marks entity references that form parent-child relationships. A scope-ref applies both the reference-target and reference-tree constraints. The parser validates all scoped references together as one tree.

Why is a target type required?

A type-erased ref cannot form part of the Reference Tree. A scope-ref must name its target entity type so Quent can validate the complete tree when it processes the schema.

Without a declared target type, different instances of the same child entity type could refer to different parent entity types at runtime. The generated instrumentation API could then no longer guarantee that the resulting relationships form the tree declared by the schema.

This gives analysis tools a preferred path from one root entity to every related entity and its events. In the model below, a task points to the pipeline that contains it. A user interface can open one pipeline and list its tasks, while analysis can associate each task’s events with that pipeline. Other tools can use the same hierarchy for their own purposes.

YAML model

quent: alpha
model: scoped_references

entities:
  Pipeline:
    events:
      created: {}

  Task:
    events:
      started:
        attributes:
          parent: { scope-ref: Pipeline }
      ended: {}

Instrumentation API

The parent entity’s handle provides the reference. The additional hierarchy meaning belongs to the model and its constraints.

// SPDX-FileCopyrightText: Copyright (c) 2026, NVIDIA CORPORATION & AFFILIATES. All rights reserved.
// SPDX-License-Identifier: Apache-2.0

#[allow(unused)]
mod instrumentation {
    include!(concat!(env!("OUT_DIR"), "/scoped_references.rs"));
}

use instrumentation::{Context, Noop, Pipeline, ScopedReferences, Task};

fn main() -> Result<(), Box<dyn std::error::Error>> {
    let context = Context::<ScopedReferences>::try_new(Noop)?;

    let mut pipeline = context.observer::<Pipeline>().handle();
    pipeline.created()?;

    let mut task = context.observer::<Task>().handle();
    task.started(pipeline.as_entity_ref())?;
    task.ended()?;

    Ok(())
}
Key point

A scoped reference defines a parent relationship in a validated entity tree.

Check yourself

What does scope-ref add beyond a normal targeted ref?

Which value is passed as the task's parent?