Problem
Confirmed on current main at 6dc51fa47a9658d26a3f6e51e8a8261aaf9b4b86.
Storage defines type_ids as the authoritative full label set and type_id as legacy primary at crates/graphforge-storage/src/schemas.rs:124-139. Variable-length path hydration reads only type_id and constructs a one-element label list at crates/graphforge-rel/src/expr.rs:12044-12092.
Ordinary node hydration consumes full type_ids at crates/graphforge-rel/src/expr.rs:5214-5238. Thus nodes(p) can turn multi-label nodes into single-label values, making labels() and predicates report false graph state.
Objective
Make variable-length path node values carry the same complete canonical label set as direct node values.
Requirements
- Hydrate labels from authoritative
type_ids.
- Resolve IDs through the correct ontology/runtime catalog domain.
- Preserve canonical ordering, null/error behavior, and Arrow list representation.
- Match direct-node semantics before and after reopen.
- Keep Rust authoritative and bindings thin.
Acceptance Criteria
BDD Completion Scenarios
Scenario: Multi-label path nodes remain truthful
Given a Person:Employee node on a variable-length path
When Cypher evaluates nodes(p) and labels()
Then both labels are present in canonical order
And match a direct result for that node.
Scenario: Reopen preserves path labels
Given a committed multi-label graph
When reopened and queried through the same path
Then full label sets and schema remain identical
And no runtime catalog ID substitutes for an ontology ID.
Implementation Notes
Likely surfaces include crates/graphforge-rel/src/expr.rs, storage catalog readers, path-value tests, and facade/binding Cypher tests. Reuse full-label hydration logic or a shared helper.
Observability
No new telemetry expected. Tests must assert complete label lists, not only primary label or row count.
Security And Privacy
Do not expose properties or UUIDs in diagnostics beyond deterministic fixtures.
Testing
Add direct-node versus variable-path parity with multiple labels. Cover bounded/unbounded paths, repeated nodes, reopen, mixed identity domains, and ordering. Assert full Arrow values and schema; no weakened checks.
Documentation
Update path semantics only if current docs describe a different label contract.
Non-Goals
- Optimizing whole-graph hydration; that is a dependent issue.
- Changing stored label meaning/order.
- Binding-side reconstruction.
Related Issues
- The path-hydration performance issue depends on this correctness contract.
- Parent tracker will be attached through GitHub's native sub-issue relationship.
Problem
Confirmed on current
mainat6dc51fa47a9658d26a3f6e51e8a8261aaf9b4b86.Storage defines
type_idsas the authoritative full label set andtype_idas legacy primary atcrates/graphforge-storage/src/schemas.rs:124-139. Variable-length path hydration reads onlytype_idand constructs a one-element label list atcrates/graphforge-rel/src/expr.rs:12044-12092.Ordinary node hydration consumes full
type_idsatcrates/graphforge-rel/src/expr.rs:5214-5238. Thusnodes(p)can turn multi-label nodes into single-label values, makinglabels()and predicates report false graph state.Objective
Make variable-length path node values carry the same complete canonical label set as direct node values.
Requirements
type_ids.Acceptance Criteria
Person:Employeenode retains both labels throughnodes(p)for bounded and unbounded variable-length patterns.labels(x)and label predicates match the same node returned directly.BDD Completion Scenarios
Scenario: Multi-label path nodes remain truthful
Given a
Person:Employeenode on a variable-length pathWhen Cypher evaluates
nodes(p)andlabels()Then both labels are present in canonical order
And match a direct result for that node.
Scenario: Reopen preserves path labels
Given a committed multi-label graph
When reopened and queried through the same path
Then full label sets and schema remain identical
And no runtime catalog ID substitutes for an ontology ID.
Implementation Notes
Likely surfaces include
crates/graphforge-rel/src/expr.rs, storage catalog readers, path-value tests, and facade/binding Cypher tests. Reuse full-label hydration logic or a shared helper.Observability
No new telemetry expected. Tests must assert complete label lists, not only primary label or row count.
Security And Privacy
Do not expose properties or UUIDs in diagnostics beyond deterministic fixtures.
Testing
Add direct-node versus variable-path parity with multiple labels. Cover bounded/unbounded paths, repeated nodes, reopen, mixed identity domains, and ordering. Assert full Arrow values and schema; no weakened checks.
Documentation
Update path semantics only if current docs describe a different label contract.
Non-Goals
Related Issues