Skip to content

fix: reconcile validation between dippin-lang and tracker#71

Merged
clintecker merged 5 commits intomainfrom
fix/validation-divergence-60
Apr 15, 2026
Merged

fix: reconcile validation between dippin-lang and tracker#71
clintecker merged 5 commits intomainfrom
fix/validation-divergence-60

Conversation

@clintecker
Copy link
Copy Markdown
Collaborator

@clintecker clintecker commented Apr 15, 2026

Summary

  • Add Graph.DippinValidated bool field that is set to true after the dippin-lang validator (DIP001–DIP009) runs successfully during .dip source parsing
  • In validateGraph, skip the structural checks that overlap with dippin's diagnostics when DippinValidated=true — these are: start/exit existence, edge endpoint validity, reachability, unconditional cycles, and duplicate edges
  • Tracker-specific checks that dippin does not cover still always run: validateShapes (DOT shape→handler resolution), validateConditionalFailEdges, and validateEdgeLabelConsistency
  • DOT-format graphs (DippinValidated=false) continue to run all structural checks, since no upstream validator has covered them

What was removed vs kept

Removed from .dip code path (dippin already covers these via DIP001–DIP009):

  • validateStartExit — DIP001 (missing start) and DIP002 (missing exit)
  • validateEdgeEndpoints — DIP003 (unknown node reference)
  • validateExitOutgoingEdges — DIP006 (exit node has outgoing edges)
  • validateReachability — DIP004 (unreachable nodes)
  • validateNoCycles — DIP005 (unconditional cycles)
  • validateNoDuplicateEdges — DIP009 (duplicate edges)

Kept (tracker-specific, dippin does not check these):

  • validateShapes — maps DOT shapes to handler names; dippin uses role: not DOT shapes
  • validateConditionalFailEdges — warns on diamond nodes missing a fail path
  • validateEdgeLabelConsistency — warns on mixed labeled/unlabeled edges from a single node

Test plan

  • go build ./... passes
  • go test ./... -short — all 15 packages pass
  • dippin doctor examples/ask_and_execute.dip examples/build_product.dip examples/build_product_with_superspec.dip — Grade A, 100/100
  • New TestDippinValidatedSkipsStructuralChecks table test covers all 6 sub-cases: missing start, unreachable node, unconditional cycle, duplicate edges (skipped for dippin-validated), and shape check + fail-edge warning (still fire for dippin-validated)
  • Existing structural tests (TestValidateNoStartNode, TestValidateCycleDetection, etc.) still pass because manually-constructed test graphs have DippinValidated=false
  • Pre-commit hooks passed: gofmt, go vet, build, tests, race detector, coverage, complexity, dippin lint

Closes #60

🤖 Generated with Claude Code

Summary by CodeRabbit

  • New Features

    • Imported Dippin workflows are marked as pre-validated so redundant structural checks are skipped while tracker-specific validations still run.
  • Behavior Change

    • Loading Dippin workflows now reports all validation/lint diagnostics (printed) and treats lint warnings as non-fatal; fatal parse/validation/conversion errors stop loading and are returned directly.
  • Tests

    • Added tests confirming pre-validated graphs skip structural checks but still surface tracker-specific errors and warnings.

Add Graph.DippinValidated flag that is set true after dippin-lang's
validator (DIP001–DIP009) runs during .dip source parsing. When set,
tracker's own validateGraph skips the structural checks that overlap
with dippin's diagnostics (start/exit existence, edge endpoints,
reachability, cycles, duplicate edges), preventing false positives and
divergence between `dippin doctor` and `tracker validate`.

Tracker-specific checks that dippin does not cover still run regardless
of source format: shape→handler resolution, conditional-fail-edge
warnings, and edge-label consistency warnings. DOT-format graphs
(DippinValidated=false) continue to run all structural checks since no
upstream validator has covered them.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Apr 15, 2026

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 9c4d6347-d631-4161-a45f-b21f6d355e0d

📥 Commits

Reviewing files that changed from the base of the PR and between dd520e6 and 7b3bb8b.

📒 Files selected for processing (3)
  • cmd/tracker/loading.go
  • pipeline/dippin_load.go
  • tracker.go
🚧 Files skipped from review as they are similar to previous changes (2)
  • pipeline/dippin_load.go
  • cmd/tracker/loading.go

Walkthrough

Adds a Dippin-aware load path: introduces DippinValidated on pipeline.Graph, adds pipeline.LoadDippinWorkflow to parse/validate/lint .dip sources and mark graphs validated, updates tracker load paths to call it and surface diagnostics, and skips several structural checks in pipeline.Validate when the flag is set.

Changes

Cohort / File(s) Summary
Graph Flag
pipeline/graph.go
Added exported DippinValidated bool to pipeline.Graph with docs describing when it must be set/cleared.
Dippin loader
pipeline/dippin_load.go
New exported LoadDippinWorkflow(source, filename) that: parses with dippin parser, runs validator.Validate (errors -> fatal), runs validator.Lint (non-fatal diagnostics), converts via FromDippinIR, sets graph.DippinValidated = true, and returns graph + aggregated diagnostics.
Tracker load paths
cmd/tracker/loading.go, tracker.go
Replaced inline parse/validate/lint flow with calls to pipeline.LoadDippinWorkflow; callers now print all returned diagnostics to stderr unconditionally and return loader errors directly. Removed separate FromDippinIR conversion at call sites.
Conditional validation logic
pipeline/validate.go
Gated structural validators (validateStartExit, validateEdgeEndpoints, validateExitOutgoingEdges, validateReachability, validateNoCycles, validateNoDuplicateEdges) behind if !g.DippinValidated; left tracker-specific checks (validateShapes, validateConditionalFailEdges, validateEdgeLabelConsistency) running unconditionally.
Tests
pipeline/validate_test.go
Added TestDippinValidatedSkipsStructuralChecks asserting that with DippinValidated=true structural checks are skipped while tracker-specific validations still run.

Sequence Diagram(s)

sequenceDiagram
  participant CLI as "tracker CLI"
  participant Loader as "pipeline.LoadDippinWorkflow"
  participant Parser as "dippin-lang/parser"
  participant Validator as "dippin-lang/validator"
  participant Conv as "FromDippinIR -> Graph"
  participant Validate as "pipeline.Validate"

  CLI->>Loader: Load(source, filename)
  Loader->>Parser: parse(source, filename)
  Parser-->>Loader: workflow / parse error
  Loader->>Validator: Validate(workflow)  %% structural (fatal if errors)
  Validator-->>Loader: validation diagnostics / errors
  Loader->>Validator: Lint(workflow)     %% lint (non-fatal)
  Validator-->>Loader: lint diagnostics
  Loader->>Conv: FromDippinIR(workflow)
  Conv-->>Loader: *Graph / conversion error
  Loader-->>CLI: return graph + diagnostics
  CLI->>CLI: print diagnostics to stderr
  CLI->>Validate: Validate(graph)
  Validate->>Validate: if graph.DippinValidated skip structural checks
  Validate-->>CLI: validation result / warnings
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

Poem

🐰 I nibble through lines with a twitch and a cheer,
Dippin already checked — I mark the graph clear,
Loader calls, sends warnings out to the light,
Tracker still checks shapes to keep logic tight,
Tiny hops, tidy code, and fewer surprises near!

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 66.67% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'fix: reconcile validation between dippin-lang and tracker' clearly and concisely summarizes the main change: resolving validation divergence between the two systems.
Linked Issues check ✅ Passed All objectives from issue #60 are met: dippin-lang validation is now the source of truth for structural checks [DIP001-DIP009], tracker-specific validations (shapes, conditional-fail-edges, edge-label consistency) continue to run, and consistent results between dippin doctor and tracker validate are achieved.
Out of Scope Changes check ✅ Passed All changes directly support the objective of reconciling validation: the new LoadDippinWorkflow function, DippinValidated flag, and conditional validation logic in validateGraph are all aligned with deferring structural validation to dippin while keeping tracker-specific checks.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/validation-divergence-60

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (2)
pipeline/validate_test.go (1)

367-433: Tighten skip-check subtests to fail on any unexpected error.

Right now those subtests only fail when the error string contains one token (start, unreachable, cycle, duplicate). Any different validation error would be ignored and the test would still pass.

Proposed assertion tightening
-		if err := Validate(g); err != nil {
-			if strings.Contains(err.Error(), "start") {
-				t.Errorf("DippinValidated graph should not re-check for missing start node, got: %v", err)
-			}
-		}
+		if err := Validate(g); err != nil {
+			t.Fatalf("expected no validation errors when DippinValidated=true, got: %v", err)
+		}
...
-		if err := Validate(g); err != nil {
-			if strings.Contains(err.Error(), "unreachable") {
-				t.Errorf("DippinValidated graph should not re-check reachability, got: %v", err)
-			}
-		}
+		if err := Validate(g); err != nil {
+			t.Fatalf("expected no validation errors when DippinValidated=true, got: %v", err)
+		}
...
-		if err := Validate(g); err != nil {
-			if strings.Contains(err.Error(), "cycle") {
-				t.Errorf("DippinValidated graph should not re-check cycles, got: %v", err)
-			}
-		}
+		if err := Validate(g); err != nil {
+			t.Fatalf("expected no validation errors when DippinValidated=true, got: %v", err)
+		}
...
-		if err := Validate(g); err != nil {
-			if strings.Contains(err.Error(), "duplicate") {
-				t.Errorf("DippinValidated graph should not re-check duplicate edges, got: %v", err)
-			}
-		}
+		if err := Validate(g); err != nil {
+			t.Fatalf("expected no validation errors when DippinValidated=true, got: %v", err)
+		}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@pipeline/validate_test.go` around lines 367 - 433, The subtests for
DippinValidated graphs (e.g., "missing start node is ignored when
dippin-validated", "unreachable node is ignored when dippin-validated",
"unconditional cycle is ignored when dippin-validated", "duplicate edges ignored
when dippin-validated") currently only fail if the error string contains a
specific token, allowing other unexpected validation errors to pass; update each
subtest that calls Validate(g) to fail on any non-nil error (not just errors
containing "start"/"unreachable"/"cycle"/"duplicate") by asserting err == nil
and reporting the full error from Validate, ensuring Validate, NewGraph, and the
DippinValidated flag behavior are being correctly enforced in the tests.
cmd/tracker/loading.go (1)

194-196: Consider centralizing the post-validate DippinValidated assignment.

The same marker logic is duplicated in multiple DIP ingestion paths. A shared helper for parse+validate+convert+mark would reduce future divergence risk.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@cmd/tracker/loading.go` around lines 194 - 196, Duplicate setting of
graph.DippinValidated should be centralized: create a shared helper (e.g.,
finalizeDippinGraph or processDIPGraph) that performs parse, validate, convert
and then sets graph.DippinValidated = true; replace the duplicated post-validate
assignments in each DIP ingestion path with a single call to this helper,
ensuring the helper accepts the same graph (and any needed context/params) and
returns the converted result or error so callers no longer set DippinValidated
themselves.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@pipeline/validate.go`:
- Around line 2-3: Update the stale ABOUTME header to accurately reflect
behavior: mention that duplicate-edge checks (validateNoDuplicateEdges) are
conditional and only run when the graph's DippinValidated flag is false (i.e.,
!g.DippinValidated); adjust the ABOUTME text to remove "always run" and clarify
which checks are skipped when DippinValidated=true and which still execute
unconditionally.

---

Nitpick comments:
In `@cmd/tracker/loading.go`:
- Around line 194-196: Duplicate setting of graph.DippinValidated should be
centralized: create a shared helper (e.g., finalizeDippinGraph or
processDIPGraph) that performs parse, validate, convert and then sets
graph.DippinValidated = true; replace the duplicated post-validate assignments
in each DIP ingestion path with a single call to this helper, ensuring the
helper accepts the same graph (and any needed context/params) and returns the
converted result or error so callers no longer set DippinValidated themselves.

In `@pipeline/validate_test.go`:
- Around line 367-433: The subtests for DippinValidated graphs (e.g., "missing
start node is ignored when dippin-validated", "unreachable node is ignored when
dippin-validated", "unconditional cycle is ignored when dippin-validated",
"duplicate edges ignored when dippin-validated") currently only fail if the
error string contains a specific token, allowing other unexpected validation
errors to pass; update each subtest that calls Validate(g) to fail on any
non-nil error (not just errors containing
"start"/"unreachable"/"cycle"/"duplicate") by asserting err == nil and reporting
the full error from Validate, ensuring Validate, NewGraph, and the
DippinValidated flag behavior are being correctly enforced in the tests.
🪄 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: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: bf840e54-f894-45ce-b572-8d371d1a4f30

📥 Commits

Reviewing files that changed from the base of the PR and between ad9ce91 and 9e7885c.

📒 Files selected for processing (5)
  • cmd/tracker/loading.go
  • pipeline/graph.go
  • pipeline/validate.go
  • pipeline/validate_test.go
  • tracker.go

Comment thread pipeline/validate.go Outdated
Comment on lines +2 to +3
// ABOUTME: Tracker-specific checks (shapes, duplicate edges, conditional routing) always run.
// ABOUTME: Structural checks that dippin-lang already covers are skipped when DippinValidated=true.
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot Apr 15, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Fix stale header comment: duplicate-edge checks are not always run.

The ABOUTME note says duplicate-edge checks always run, but Line 134 runs validateNoDuplicateEdges only when !g.DippinValidated.

Suggested comment correction
-// ABOUTME: Tracker-specific checks (shapes, duplicate edges, conditional routing) always run.
+// ABOUTME: Tracker-specific checks (shape validation and conditional-routing warnings) always run.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@pipeline/validate.go` around lines 2 - 3, Update the stale ABOUTME header to
accurately reflect behavior: mention that duplicate-edge checks
(validateNoDuplicateEdges) are conditional and only run when the graph's
DippinValidated flag is false (i.e., !g.DippinValidated); adjust the ABOUTME
text to remove "always run" and clarify which checks are skipped when
DippinValidated=true and which still execute unconditionally.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in 40daf6c. The ABOUTME header now accurately reflects that tracker-specific checks (shapes, conditional routing) always run, while structural checks (start/exit, reachability, cycles, duplicate edges) are skipped for dippin-validated graphs.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@clintecker, thanks for the update! The corrected ABOUTME header now accurately reflects the actual behavior — structural checks (start/exit, reachability, cycles, duplicate edges) are skipped for dippin-validated graphs, while shape validation and conditional-routing warnings always run unconditionally.


🧠 Learnings used
Learnt from: CR
Repo: 2389-research/tracker PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-04-15T18:32:26.002Z
Learning: Applies to **/*.go : When a node's outcome is 'fail' and all outgoing edges are unconditional, the pipeline stops

Learnt from: CR
Repo: 2389-research/tracker PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-04-15T18:32:26.002Z
Learning: Applies to **/dippin_adapter.go : `pipeline/dippin_adapter.go` converts dippin IR to tracker's Graph model — update it when dippin-lang adds new IR fields

Learnt from: CR
Repo: 2389-research/tracker PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-04-15T18:32:26.002Z
Learning: Applies to **/cmd/tracker/*.go : Pipeline source resolution applies uniformly to `tracker validate`, `tracker simulate`, and `tracker run`

Learnt from: CR
Repo: 2389-research/tracker PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-04-15T18:32:26.002Z
Learning: Applies to **/*.dip : Pipelines that intentionally handle failure must use `when ctx.outcome = fail` edges

Learnt from: CR
Repo: 2389-research/tracker PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-04-15T18:32:26.002Z
Learning: Applies to **/*.go : Checkpoints store completed nodes and context snapshots with edge selections stored per-node for deterministic replay

Learnt from: CR
Repo: 2389-research/tracker PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-04-15T18:32:26.002Z
Learning: Applies to **/cmd/tracker/*.go : `tracker doctor` — preflight health check (API keys, dippin binary, workdir). Run before first pipeline.

Learnt from: CR
Repo: 2389-research/tracker PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-04-15T18:32:26.002Z
Learning: Applies to **/dippin_adapter.go : The adapter must synthesize implicit edges from `ParallelConfig.Targets` and `FanInConfig.Sources`

Learnt from: CR
Repo: 2389-research/tracker PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-04-15T18:32:26.002Z
Learning: Applies to **/*.go : Nodes with ANY conditional edges are assumed to have intentional routing

Learnt from: CR
Repo: 2389-research/tracker PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-04-15T18:32:26.002Z
Learning: Applies to **/*.dip : NEVER add an unconditional edge to the same target as a conditional edge (causes infinite loops)

Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 9e7885c71d

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread pipeline/validate.go
// DIP005 — unconditional cycle detected
// DIP006 — exit node has outgoing edges
// DIP009 — duplicate edge
if !g.DippinValidated {
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Keep structural validation independent of mutable graph flag

validateGraph now bypasses start/exit, endpoint, reachability, cycle, and duplicate-edge checks whenever g.DippinValidated is true. Since DippinValidated is a mutable exported field on Graph, any caller (or a graph that is modified after parsing) can flip this bit and make pipeline.Validate accept malformed graphs; the added table test cases already demonstrate invalid graphs passing once the flag is set. This turns validation into an opt-out and can let bad graphs reach engine execution, where failures become runtime-only and harder to diagnose.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in 40daf6c. Added a CONTRACT comment on the DippinValidated field in graph.go explaining the mutation responsibility: callers who mutate the graph after dippin validation must clear the flag or re-run validation, otherwise structural checks will be incorrectly skipped.

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Reconciles pipeline validation behavior between dippin-lang and tracker by marking graphs produced from .dip sources as already structurally validated, and skipping tracker structural checks that overlap with dippin’s DIP001–DIP009 diagnostics to avoid divergence.

Changes:

  • Add Graph.DippinValidated and set it to true for graphs produced via .dip parsing/conversion.
  • Update validateGraph to skip structural checks (start/exit, endpoints, reachability, cycles, duplicates) when DippinValidated=true, while still running tracker-specific checks (shapes, conditional warnings, label consistency).
  • Add a new table-style test to verify the skip behavior and that tracker-specific checks still run.

Reviewed changes

Copilot reviewed 5 out of 5 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
pipeline/graph.go Adds DippinValidated flag to Graph model.
pipeline/validate.go Gates structural validation on !DippinValidated; always runs tracker-specific checks.
tracker.go Marks .dip-parsed graphs as DippinValidated=true.
cmd/tracker/loading.go Marks CLI-loaded .dip graphs as DippinValidated=true.
pipeline/validate_test.go Adds tests covering skip behavior and “still-run” tracker checks.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread pipeline/validate.go Outdated
Comment on lines +2 to +3
// ABOUTME: Tracker-specific checks (shapes, duplicate edges, conditional routing) always run.
// ABOUTME: Structural checks that dippin-lang already covers are skipped when DippinValidated=true.
Copy link

Copilot AI Apr 15, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The ABOUTME header says duplicate-edge checks always run, but validateNoDuplicateEdges is now only executed when DippinValidated=false. Please update the header comment to match the actual behavior (duplicate-edge checks are skipped for dippin-validated graphs).

Suggested change
// ABOUTME: Tracker-specific checks (shapes, duplicate edges, conditional routing) always run.
// ABOUTME: Structural checks that dippin-lang already covers are skipped when DippinValidated=true.
// ABOUTME: Tracker-specific checks such as shapes and conditional routing always run.
// ABOUTME: Structural checks that dippin-lang already covers, including duplicate-edge checks, are skipped when DippinValidated=true.

Copilot uses AI. Check for mistakes.
Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in 40daf6c.

Comment thread pipeline/validate_test.go
Comment on lines +375 to +379
if err := Validate(g); err != nil {
if strings.Contains(err.Error(), "start") {
t.Errorf("DippinValidated graph should not re-check for missing start node, got: %v", err)
}
}
Copy link

Copilot AI Apr 15, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This subtest is meant to confirm that structural validation is bypassed when DippinValidated=true, but it currently allows Validate() to return a non-nil error as long as it doesn't contain "start". That can mask unexpected failures and make the test pass incorrectly. Prefer asserting err == nil here (and similarly in the other "skipped" cases).

Copilot uses AI. Check for mistakes.
Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in 40daf6c. The four skipped-check subtests now assert err==nil directly (not merely 'no error mentioning X'), with comments explaining why each expects no error from tracker-specific checks either.

@clintecker
Copy link
Copy Markdown
Collaborator Author

@copilot please address all the review feedback

Copy link
Copy Markdown
Contributor

Copilot AI commented Apr 15, 2026

@copilot please address all the review feedback

Addressed both review comments in commit 6e108e7:

  1. validate.go ABOUTME comment — removed "duplicate edges" from the "always run" list and explicitly called out that duplicate-edge checks are skipped for dippin-validated graphs.

  2. validate_test.go "skipped" subtests — all four subtests (missing start, unreachable, unconditional cycle, duplicate edges) now assert err == nil directly, rather than allowing non-nil errors that happen not to contain a specific keyword.

- Added mutation contract to DippinValidated field: callers must clear
  the flag or re-run dippin validation after mutating the graph, or
  structural checks will be skipped for the new shape
- Tightened TestDippinValidatedSkipsStructuralChecks to assert err==nil
  (not merely "no error mentioning X"), with explanatory comments on why
  each subtest expects no error

Refs #60

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 5 out of 5 changed files in this pull request and generated 3 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread pipeline/validate.go Outdated
Comment on lines +121 to +127
// DIP001 — start node missing (partial: we also check for >1 start)
// DIP002 — exit node missing (partial: we also check for >1 exit)
// DIP003 — unknown node reference in edge
// DIP004 — unreachable node(s) from start
// DIP005 — unconditional cycle detected
// DIP006 — exit node has outgoing edges
// DIP009 — duplicate edge
Copy link

Copilot AI Apr 15, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The note that DIP001/DIP002 are only "partial" because tracker also checks for ">1 start/exit" is confusing in the DippinValidated flow: .dip workflows have a single workflow.Start/workflow.Exit (see FromDippinIR), and ensureStartExitNodes forces exactly one node to carry each start/exit shape. Consider rewording to clarify that the ">1" check is primarily relevant to DOT graphs, or drop the "partial" qualifier here to avoid implying dippin-lang might allow multiple start/exit nodes.

Suggested change
// DIP001 — start node missing (partial: we also check for >1 start)
// DIP002 — exit node missing (partial: we also check for >1 exit)
// DIP003 — unknown node reference in edge
// DIP004 — unreachable node(s) from start
// DIP005 — unconditional cycle detected
// DIP006 — exit node has outgoing edges
// DIP009 — duplicate edge
// DIP001 — start node missing
// DIP002 — exit node missing
// DIP003 — unknown node reference in edge
// DIP004 — unreachable node(s) from start
// DIP005 — unconditional cycle detected
// DIP006 — exit node has outgoing edges
// DIP009 — duplicate edge
// Tracker also enforces exactly one start and exit when validating
// non-Dippin/DOT graphs; that multiplicity check is not part of the
// skipped dippin-lang overlap for DippinValidated inputs.

Copilot uses AI. Check for mistakes.
Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in dd520e6.

Comment thread tracker.go Outdated
Comment on lines +348 to +350
// Mark graph as already validated by dippin-lang so that tracker's
// own validator skips redundant structural checks (DIP001–DIP009).
graph.DippinValidated = true
Copy link

Copilot AI Apr 15, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This graph.DippinValidated = true assignment is duplicated with the same intent in cmd/tracker/loading.go. To reduce the chance of future .dip load paths forgetting to set the flag (and accidentally re-enabling redundant structural validation), consider centralizing this in a single helper (e.g., a shared loader or a small function that wraps parse+validate+convert).

Copilot uses AI. Check for mistakes.
Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in dd520e6.

Comment thread cmd/tracker/loading.go Outdated
Comment on lines +194 to +196
// Mark graph as already validated by dippin-lang so that tracker's
// own validator skips redundant structural checks (DIP001–DIP009).
graph.DippinValidated = true
Copy link

Copilot AI Apr 15, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This .dip loader sets graph.DippinValidated = true, and the inline .dip parser does the same in tracker.go. Consider factoring the parse+validate+convert+mark logic into a shared helper to avoid drift between the two code paths and to ensure any future .dip entry point consistently marks graphs as pre-validated.

Copilot uses AI. Check for mistakes.
Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in dd520e6.

- Clarify start/exit validation comment to note DIP001/DIP002 give
  complete coverage for .dip flows (DOT is the only path that needs
  tracker's >1 start/exit check).
- Factor duplicated parse+validate+convert+mark logic out of
  tracker.go and cmd/tracker/loading.go into a single pipeline helper
  so future .dip entry points can't forget to mark DippinValidated.

Refs #60
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@pipeline/dippin_load.go`:
- Around line 26-28: The current early-return drops structured diagnostics by
doing "return nil, nil, fmt.Errorf(...)" when valResult.HasErrors() is true;
change this to preserve and return valResult.Diagnostics (e.g., "return nil,
valResult.Diagnostics, fmt.Errorf(...)" or otherwise include
valResult.Diagnostics in the returned error payload) so callers can inspect
file/line diagnostics; ensure you still include the existing formatted summary
using filename and len(valResult.Errors()) while returning the Diagnostics
instead of nil.
🪄 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: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 79ff9a09-7de4-48d1-bc34-115794e0cc1a

📥 Commits

Reviewing files that changed from the base of the PR and between 40daf6c and dd520e6.

📒 Files selected for processing (4)
  • cmd/tracker/loading.go
  • pipeline/dippin_load.go
  • pipeline/validate.go
  • tracker.go
🚧 Files skipped from review as they are similar to previous changes (2)
  • cmd/tracker/loading.go
  • pipeline/validate.go

Comment thread pipeline/dippin_load.go
LoadDippinWorkflow now returns valResult.Diagnostics even when
validation reports errors, so callers can surface the specific
file/line info. Callers moved the diagnostics log above the error
return so users see them even on fatal failures.

Addresses CodeRabbit feedback on PR #71.
Refs #60
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

fix: validation divergence between dippin-lang and tracker

3 participants