Concepts: Graph Resolution¶
Understanding how CUTIP resolves and validates the artifact graph is useful when debugging ref errors or building complex multi-group workspaces.
The pipeline¶
cutip/ WorkspaceDiscovery CutipRegistry
*.yaml files ──▶ parse + dispatch ──▶ in-memory store
(by kind) keyed by prefix/name
CutipRegistry RefResolver GraphValidator
──▶ resolve refs ──▶ full graph walk
on demand non-failing error collection
WorkspaceDiscovery¶
WorkspaceDiscovery walks the cutip/ directory, reads every .yaml / .yml file, and dispatches to the right model based on the kind field:
kind |
Model | Registry prefix |
|---|---|---|
ImageCard |
ImageCard |
images/ |
ContainerCard |
ContainerCard |
containers/ |
NetworkCard |
NetworkCard |
networks/ |
Unit |
Unit |
unit registry |
Group |
Group |
group registry |
Parse errors are non-fatal warnings — a malformed file is skipped and logged, not a hard crash. This lets you add work-in-progress YAMLs without breaking cutip tree.
CutipRegistry¶
The registry is an in-memory store with three namespaces:
cards— keyed by<prefix>/<name>, e.g.images/app,containers/dbunits— keyed by unit namegroups— keyed by group name
The registry also stores _sources — a mapping from registry key to the source file path, used by cutip show and cutip tree to display file locations.
RefResolver¶
RefResolver is a thin lookup layer on top of CutipRegistry. It parses ref strings ("images/app", "containers/db"), maps the prefix to an expected model class, and returns the registered artifact or raises CutipRefError.
resolver.resolve("images/app") # → ImageCard
resolver.resolve_card("containers/db", ContainerCard) # → ContainerCard (type-checked)
resolver.resolve_unit("my-unit") # → Unit
GraphValidator¶
GraphValidator performs a full semantic walk of the graph and collects all errors before reporting:
For each Unit:
resolve containerRef → ContainerCard
resolve imageRef → ImageCard
resolve networkRef → NetworkCard (skipped when network_mode is set)
For each Group:
resolve each unit ref → Unit
check workflow.py exists on disk
Errors are collected into a ValidationResult(ok: bool, errors: list[str]). All errors are reported in one pass — you never fix one error only to discover the next.
Error types¶
| Exception | When raised |
|---|---|
CutipParseError |
YAML file fails Pydantic validation |
CutipRefError |
A ref: string points to a non-existent artifact |
CutipValidationError |
Graph validation fails |
CutipWorkflowError |
workflow.py raises an exception during execution |
Full exception hierarchy: reference/exceptions.md