SDK relationship graph primitives and lifecycle semantics#554
Conversation
Add application-defined relationship kinds and bounded graph queries to the public SDK, align lifecycle validation with ordering edge semantics, and document the extension contract in an ADR. Cover adjacency, traversal, shortest paths, subgraphs, aliases, cancellation, and validation behavior at 100% coverage. Close and release pm-zwpp, pm-4jqm, and pm-6irg while retaining pm-ju83 for its remaining durable event-index scope; track the external Neo4j Sentry finding as pm-7n5a.
|
@greptileai please review the current head. |
|
/gemini review |
|
@coderabbitai full review |
✅ Action performedFull review finished. Your plan includes PR reviews subject to rate limits. More reviews will be available in 59 minutes. |
📝 WalkthroughWalkthroughThis change adds a typed relationship graph SDK with deterministic bounded queries, exposes it publicly, filters lifecycle validation to ordering relationships, documents the model, adds tests, and records related project evidence and closure metadata. ChangesRelationship graph implementation
Estimated code review effort: 4 (Complex) | ~45 minutes Sequence Diagram(s)sequenceDiagram
participant Client
participant RelationshipKindRegistry
participant RelationshipGraph
participant QueryResult
Client->>RelationshipKindRegistry: resolve relationship kinds
Client->>RelationshipGraph: construct nodes and edges
RelationshipGraph->>RelationshipKindRegistry: validate and normalize edge kinds
Client->>RelationshipGraph: run bounded graph query
RelationshipGraph-->>QueryResult: return nodes, paths, subgraph, and metadata
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches📝 Generate docstrings
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Code Review
This pull request introduces a stable, public SDK relationship graph ontology and query kernel. It adds the RelationshipKindRegistry for managing custom and built-in relationship kinds, and the RelationshipGraph for performing bounded graph queries such as adjacency, closure, shortest path, and induced subgraphs. Additionally, lifecycle cycle validation has been updated to traverse only ordering relationship kinds, preventing false-positive cycle warnings from associative edges. Feedback focuses on optimizing performance in src/sdk/relationships.ts by replacing array spreading with standard array mutation during graph indexing to avoid closure method once the limit is reached.
Important
The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.
Codecov Report✅ All modified and coverable lines are covered by tests. 📢 Thoughts on this report? Let us know! |
Greptile SummaryThis PR adds relationship graph support to the SDK and updates lifecycle validation around relationship semantics. The main changes are:
Confidence Score: 4/5Lifecycle validation can still miss custom ordering cycles. The graph traversal fixes look consistent with the changed relationship query code. Malformed and associative dependency kinds are filtered before lifecycle cycle detection. Registered custom ordering kinds are not threaded through the real validate call path, so those edges can still be ignored. src/cli/commands/validate.ts
What T-Rex did
Important Files Changed
Prompt To Fix All With AIFix the following 1 code review issue. Work through them one at a time, proposing concise fixes.
---
### Issue 1 of 1
src/cli/commands/validate.ts:1486
**Custom Ordering Registry Is Dropped**
When `pm validate` builds lifecycle cycles, the production call path reaches this default registry because `detectLifecycleDependencyCycles` calls `buildLifecycleDependencyGraph(activeItems, idPrefix)` without passing an injected registry. A tracker using a registered custom ordering kind such as `precedes` is still skipped as unknown here, so real custom ordering cycles can pass validation without a warning.
Reviews (14): Last reviewed commit: "perf(sdk): bound shortest-path memory af..." | Re-trigger Greptile |
There was a problem hiding this comment.
Actionable comments posted: 4
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@CHANGELOG.md`:
- Around line 7-12: Update the Unreleased section in CHANGELOG.md by adding an
“Added” bullet describing the new public relationship-graph SDK primitives, and
revise the existing lifecycle cycle-detection fix entry to state that validation
ignores non-ordering related edges rather than treating them as ordering edges.
Preserve the existing changelog structure and issue references.
In `@docs/RELATIONSHIP_GRAPH.md`:
- Line 23: Update the duplicate-edge contract in the relationship graph
documentation to match the implementation in the relationships graph
constructor: describe duplicate canonical edges as deduplicated with the last
entry retained, rather than rejected. Do not change unrelated validation
behavior.
In `@src/sdk/relationships.ts`:
- Around line 570-582: Update dependencyToRelationship to resolve
dependency.kind through the same relationship-kind registry used by
RelationshipGraph, returning definition.kind as the edge’s canonical kind while
preserving the existing behavior for other fields.
- Around line 221-251: Update register() to clone and freeze
definition.payloadSchema before storing the normalized definition in
`#definitions`, ensuring cached definitions and list() snapshots cannot share
mutable schema state. Preserve the existing normalization and validation
behavior while replacing only the shared payloadSchema reference with its
isolated immutable copy.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Repository UI (base), Organization UI (inherited)
Review profile: ASSERTIVE
Plan: Pro
Run ID: 3bbaecee-5fe3-4226-b12d-4904f5fa90a2
📒 Files selected for processing (18)
.agents/pm/decisions/pm-4jqm.toon.agents/pm/features/pm-ju83.toon.agents/pm/features/pm-zwpp.toon.agents/pm/history/pm-4jqm.jsonl.agents/pm/history/pm-6irg.jsonl.agents/pm/history/pm-7n5a.jsonl.agents/pm/history/pm-ju83.jsonl.agents/pm/history/pm-zwpp.jsonl.agents/pm/issues/pm-6irg.toon.agents/pm/issues/pm-7n5a.toonCHANGELOG.mddocs/RELATIONSHIP_GRAPH.mddocs/SDK.mdsrc/cli/commands/validate.tssrc/sdk/index.tssrc/sdk/relationships.tstests/unit/commands/validate-command.spec.tstests/unit/sdk/relationships.spec.ts
Greptile SummaryThis PR adds SDK relationship graph primitives and updates lifecycle validation semantics. The main changes are:
Confidence Score: 4/5The relationship graph and validation changes need fixes for custom ordering kinds and inverse-kind traversal before merging. Custom order-bearing dependencies can be skipped by lifecycle validation, and inverse relationship kinds are declared but not honored by traversal filters. The SDK export and basic graph query paths otherwise look coherent from the inspected diff. src/cli/commands/validate.ts; src/sdk/relationships.ts
What T-Rex did
Important Files Changed
Flowchart%%{init: {'theme': 'neutral'}}%%
flowchart TD
Items[Item metadata dependencies] --> Validate[buildLifecycleDependencyGraph]
Validate --> Gate{ordering kind?}
Gate -->|yes| CycleGraph[Lifecycle cycle graph]
Gate -->|no| Skipped[dependency skipped]
Registry[RelationshipKindRegistry] --> Graph[RelationshipGraph]
Graph --> Adj[adjacency]
Graph --> Closure[closure]
Graph --> Path[shortestPath]
Graph --> Subgraph[subgraph]
%%{init: {'theme': 'base', 'themeVariables': {"darkMode": true, "background": "#0d1117", "primaryColor": "#21262d", "primaryTextColor": "#e6edf3", "primaryBorderColor": "#8b949e", "lineColor": "#8b949e", "textColor": "#e6edf3", "edgeLabelBackground": "#161b22", "actorBkg": "#21262d", "actorBorder": "#8b949e", "actorTextColor": "#e6edf3", "actorLineColor": "#8b949e", "signalColor": "#8b949e", "signalTextColor": "#e6edf3", "noteBkgColor": "#373320", "noteBorderColor": "#d4a72c", "noteTextColor": "#f0e6c0", "labelBoxBkgColor": "#21262d", "labelBoxBorderColor": "#8b949e", "labelTextColor": "#e6edf3", "loopTextColor": "#e6edf3", "activationBkgColor": "#30363d", "activationBorderColor": "#8b949e"}}}%%
flowchart TD
Items[Item metadata dependencies] --> Validate[buildLifecycleDependencyGraph]
Validate --> Gate{ordering kind?}
Gate -->|yes| CycleGraph[Lifecycle cycle graph]
Gate -->|no| Skipped[dependency skipped]
Registry[RelationshipKindRegistry] --> Graph[RelationshipGraph]
Graph --> Adj[adjacency]
Graph --> Closure[closure]
Graph --> Path[shortestPath]
Graph --> Subgraph[subgraph]
Prompt To Fix All With AIFix the following 2 code review issues. Work through them one at a time, proposing concise fixes.
---
### Issue 1 of 2
src/cli/commands/validate.ts:1493-1496
**Custom Ordering Edges Disappear**
When tracker data contains an extension-defined ordering kind, this gate checks only the built-in default registry and skips that dependency. `pm validate` can then miss a real lifecycle cycle for a valid custom order-bearing relationship.
### Issue 2 of 2
src/sdk/relationships.ts:431-438
**Inverse Kind Filters Miss Edges**
Traversal filters match only the stored edge kind, so a caller using `kinds: ["child"]` on stored `parent` edges or `kinds: ["blocks"]` on stored `blocked_by` edges gets an empty result. The registry declares those inverse kinds, but adjacency, closure, shortest-path, and subgraph queries do not honor them.
Reviews (2): Last reviewed commit: "feat(sdk): add extensible relationship g..." | Re-trigger Greptile |
Make registry snapshots deeply immutable, normalize converted dependency kinds, honor inverse kind filters, and keep bounded traversal metadata honest while reducing index construction complexity. Preserve custom ordering edges and tolerate malformed dependency metadata in lifecycle validation. Align the generated changelog and relationship ADR with tracker-backed semantics, with exact 100% focused relationship coverage.
|
@greptileai please re-review commit 2436709 after all first-round findings were addressed. |
|
/gemini review |
|
@coderabbitai full review |
✅ Action performedFull review finished. Your plan includes PR reviews subject to rate limits. More reviews will be available in 40 minutes. |
There was a problem hiding this comment.
Code Review
This pull request introduces a public relationship graph ontology and bounded graph-query kernel, which is integrated into the CLI's lifecycle cycle validation to restrict cycle detection to ordering relationship kinds only, thereby resolving false-positive cycle warnings on associative edges. It also includes comprehensive unit tests and updated documentation. Feedback on the implementation highlights opportunities to deduplicate edge candidates during bidirectional traversal, optimize induced subgraph edge construction to avoid O(E) performance bottlenecks on large graphs, and enforce strict regex validation on relationship aliases.
Important
The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.
Deduplicate bidirectional candidates, assemble induced subgraphs from bounded adjacency indexes, validate alias identifiers, and preserve the registry no-guessing rule for unknown lifecycle relationship kinds. Add exact branch coverage and second-round tracker evidence.
|
@greptileai please re-review commit e9f7b7a after all second-round findings were addressed. |
|
/gemini review |
|
@coderabbitai full review |
✅ Action performedFull review finished. Your plan includes PR reviews subject to rate limits. More reviews will be available in 28 minutes. |
There was a problem hiding this comment.
Code Review
This pull request introduces a robust, dependency-free relationship ontology and bounded graph-query kernel within the SDK (src/sdk/relationships.ts), along with corresponding unit tests. It also updates the lifecycle validation command to leverage this registry, ensuring that cycle detection is restricted to ordering relationship kinds and preventing false-positive warnings from associative edges. The review feedback highlights several opportunities to improve robustness against malformed or legacy payloads. Specifically, it recommends adding defensive type guards to prevent runtime crashes when non-string values are passed to resolve, normalizeRelationshipEdge, and the RelationshipGraph constructor, as well as resolving parent and dependency IDs case-insensitively in fromItems to avoid missed edges.
Important
The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.
Defend registry, node, endpoint, and item-derived relationship inputs at runtime while normalizing identifier whitespace. Add a typed lifecycle-registry injection seam so custom ordering and associative definitions retain their declared semantics, with exact 100% relationship coverage and tracker evidence.
|
@coderabbitai full review |
✅ Action performedFull review finished. Your plan includes PR reviews subject to rate limits. More reviews will be available in 17 minutes. |
There was a problem hiding this comment.
Code Review
This pull request introduces a public SDK relationship registry and graph-query kernel (src/sdk/relationships.ts) to manage custom typed edges, adjacency, paths, closures, and subgraphs. It also updates the CLI validation command to restrict lifecycle cycle detection to ordering relationship kinds, resolving false-positive dependency cycles. Feedback on the implementation highlights issues in the graph traversal algorithms: the truncation check in closure can yield false positives and under-count inspected edges, visitedNodes is over-counted in both closure and shortestPath by relying on queue.length, and the subgraph query fails to filter edges by the requested kinds.
Important
The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.
Count dequeued nodes rather than queued frontier entries, detect max-depth truncation only for unseen work, and enforce canonical/inverse kind filters in induced subgraphs. Preserve deterministic indexed execution with exact 100% relationship coverage.
|
@greptileai please re-review commit 5403852 after all fourth-round findings were addressed. |
|
/gemini review |
|
@coderabbitai full review |
✅ Action performedFull review finished. Your plan includes PR reviews subject to rate limits. More reviews will be available in 7 minutes. |
There was a problem hiding this comment.
Code Review
This pull request introduces a public relationship ontology and bounded graph-query kernel (RelationshipGraph and RelationshipKindRegistry) to standardise edge semantics and graph queries across the SDK and CLI. It updates the lifecycle cycle detection in validate.ts to only traverse ordering relationship kinds, successfully preventing false-positive dependency cycles from associative edges. Review feedback suggests addressing a potential stack overflow in freezeValue by tracking visited objects to handle circular references, and normalizing/validating the inverse property in RelationshipKindRegistry.register to ensure consistent query matching.
Important
The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.
There was a problem hiding this comment.
Code Review
This pull request introduces a stable relationship ontology and bounded graph-query kernel to the public SDK, including a versioned relationship registry and an in-memory graph index. It also updates the CLI validation logic to restrict lifecycle cycle detection to ordering relationship kinds, resolving false-positive warnings from associative edges. The review feedback highlights opportunities to optimize graph traversal performance in the closure, adjacency, and shortestPath methods by eliminating redundant neighbor lookups and optimizing set operations.
Important
The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.
Make schema freezing cycle-safe, normalize inverse identifiers, reuse adjacency uniqueness work, and resolve BFS neighbors once per dequeued node while preserving exact truncation semantics. Maintain exact 100% relationship coverage and tracker evidence.
|
@greptileai please re-review commit 4229791 after all fifth-round findings were addressed. |
|
/gemini review |
|
@coderabbitai full review |
✅ Action performedFull review finished. Your plan includes PR reviews subject to rate limits. More reviews will be available in 59 minutes. |
There was a problem hiding this comment.
Code Review
This pull request establishes a stable relationship graph ontology and query kernel in the public SDK, introducing the RelationshipKindRegistry and RelationshipGraph classes. It refactors the CLI validation command to restrict lifecycle cycle detection to registry-declared ordering kinds, preventing false-positive cycles from associative edges. Additionally, public annotation and link primitives are promoted to the SDK, accompanied by updated documentation and unit tests. Feedback suggests optimizing the shortestPath algorithm in src/sdk/relationships.ts to use a memory-efficient parent map and case-insensitive tracking instead of copying full path arrays in the BFS queue.
Important
The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.
There was a problem hiding this comment.
Actionable comments posted: 1
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
src/sdk/relationships.ts (1)
580-633: 🚀 Performance & Scalability | 🟡 Minor | ⚡ Quick win
shortestPath()should honoroptions.limit.
RelationshipQueryOptionsalready exposeslimit, andadjacency()/closure()use it to cap traversal. This BFS ignores it entirely, so callers can still walk the full reachable component even when they asked for a bound.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/sdk/relationships.ts` around lines 580 - 633, Update shortestPath to honor options.limit during BFS traversal, using the same limit semantics as adjacency() and closure(). Apply the bound to traversal before expanding additional nodes, preserve shortest-path discovery and existing maxDepth behavior, and report the resulting truncation metadata consistently.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@tests/unit/sdk/relationships.spec.ts`:
- Around line 46-58: Update the frozen-state assertions in the relationship test
to use non-null assertions for the expected registry entry, payloadSchema,
required array, and properties.id instead of unsafe optional chaining. Preserve
the existing schema equality assertion while ensuring missing values cause the
test to fail rather than allowing Object.isFrozen(undefined) to pass.
---
Outside diff comments:
In `@src/sdk/relationships.ts`:
- Around line 580-633: Update shortestPath to honor options.limit during BFS
traversal, using the same limit semantics as adjacency() and closure(). Apply
the bound to traversal before expanding additional nodes, preserve shortest-path
discovery and existing maxDepth behavior, and report the resulting truncation
metadata consistently.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Repository UI (base), Organization UI (inherited)
Review profile: ASSERTIVE
Plan: Pro
Run ID: cfd7c35a-85a0-440d-991d-187a15b77a2e
📒 Files selected for processing (10)
.agents/pm/features/pm-ju83.toon.agents/pm/history/pm-6irg.jsonl.agents/pm/history/pm-ju83.jsonl.agents/pm/issues/pm-6irg.toonCHANGELOG.mddocs/RELATIONSHIP_GRAPH.mdsrc/cli/commands/validate.tssrc/sdk/relationships.tstests/unit/commands/validate-command.spec.tstests/unit/sdk/relationships.spec.ts
Replace per-frontier path copies with parent-map reconstruction, harden payload schema freeze assertions, record the final pm review evidence, and refresh the managed pm-changelog package to 2026.7.14-2.
|
@greptileai please re-review commit bc82530 and report any remaining actionable findings. |
|
/gemini review |
|
@coderabbitai full review |
✅ Action performedFull review finished. Your plan includes PR reviews subject to rate limits. More reviews will be available in 35 minutes. |
There was a problem hiding this comment.
Code Review
This pull request introduces a public relationship graph ontology and query kernel to the SDK, implementing the RelationshipKindRegistry and RelationshipGraph classes. It updates the CLI validation command to restrict lifecycle cycle detection to ordering relationship kinds only, resolving false-positive dependency cycles caused by associative edges. Comprehensive unit tests and documentation are also added. Feedback on the changes includes a suggestion to cast an object of type unknown to Record<string, unknown> before passing it to Object.values to prevent strict TypeScript compilation errors.
Important
The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.
| function buildLifecycleDependencyGraph( | ||
| activeItems: ItemWithBody[], | ||
| idPrefix = "pm", | ||
| relationshipRegistry: RelationshipKindRegistry = createRelationshipKindRegistry(), |
There was a problem hiding this comment.
Custom Ordering Registry Is Dropped
When pm validate builds lifecycle cycles, the production call path reaches this default registry because detectLifecycleDependencyCycles calls buildLifecycleDependencyGraph(activeItems, idPrefix) without passing an injected registry. A tracker using a registered custom ordering kind such as precedes is still skipped as unknown here, so real custom ordering cycles can pass validation without a warning.
Prompt To Fix With AI
This is a comment left during a code review.
Path: src/cli/commands/validate.ts
Line: 1486
Comment:
**Custom Ordering Registry Is Dropped**
When `pm validate` builds lifecycle cycles, the production call path reaches this default registry because `detectLifecycleDependencyCycles` calls `buildLifecycleDependencyGraph(activeItems, idPrefix)` without passing an injected registry. A tracker using a registered custom ordering kind such as `precedes` is still skipped as unknown here, so real custom ordering cycles can pass validation without a warning.
How can I resolve this? If you propose a fix, please make it concise.…backfill, frontier notes - file pm-albl for GH-557 (contract layer intercepts -h/--help before variadic-positional handlers) under pm-ugqx - backfill estimate/risk/confidence on pm-d4ns/pm-evav/pm-topu/pm-zt1c (clears missing_estimate warning) - frontier notes on pm-usfg (remaining slices 3mna -> oxrw -> oslr) and pm-4k6b (catalog-to-shipped map for PR#546/#549/#554/#556/#559) - files-missing 162 drift comment on pm-j8z6; pass summary on pm-doxj Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01VDJ1m5HDPDBVp8BBAixtnP
Summary
pm items
Verification
node scripts/run-tests.mjs coverage— 286 files, 5,664 tests; 100% statements/branches/functions/linespnpm lint:eslintand repository quality gates — pass; 100% docstring coverage and zero duplicationpm health --check-only --summary --json— healthy with zero warningspm validate --check-resolution --check-history-drift— passes; only pre-existing legacy resolution warnings remainpnpm changelog:pm:check— pass using pm-changelog 2026.7.14-1Summary by cubic
Adds a public relationship graph to the SDK with an extensible kind registry and bounded queries, and updates lifecycle validation to consider only ordering edges. Also bounds shortest-path memory via parent-map reconstruction and refreshes
pm-changelogto 2026.7.14-2.New Features
RelationshipKindRegistryandRelationshipGraphinsrc/sdk/relationships.ts, exported viasrc/sdk/index.ts.related_to→related,depends_on→blocked_by); documents semantics indocs/RELATIONSHIP_GRAPH.md; faster induced-subgraph assembly from bounded indexes; injectable lifecycle registry seam invalidate.Bug Fixes
relatededges no longer create false cycles; malformed dependency metadata is tolerated.Written for commit bc82530. Summary will update on new commits.