feat(rust): validate @c4 uses against real crate deps via cargo metadata - #7
Open
nightscape wants to merge 1 commit into
Open
nightscape wants to merge 1 commit into
nightscape wants to merge 1 commit into
Conversation
Add a workspace-native dependency source and a `ir check-deps` CLI command that diffs declared `@c4 uses` arrows against the real crate→crate graph. - adapters/archidoc-rust/cargo_metadata.rs: workspace_import_graph() reads `cargo metadata --no-deps` (no external tooling, unlike the cargo-modules path) into the existing ImportGraph; validate_ir_relationships() diffs a compiled IR's relationships against it, reusing RelationshipWarning. - archidoc ir check-deps <ir> --manifest-dir <dir> [--ignore N] [--strict]: reports `missing` (real dep, no @C4 uses — prints paste-ready line) and `stale` (declared @C4 uses, no real dep). --strict exits 1 for CI. - Revives the previously dead validate_relationships/ImportGraph machinery by giving it a tool-free, crate-level edge source and a CLI entry point. - workspace-hack ignored by default. 3 unit tests. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
There was a problem hiding this comment.
Pull request overview
Note
Copilot was unable to run its full agentic suite in this review.
Adds a new archidoc ir check-deps command to detect drift between declared @c4 uses relationships in compiled IR and actual Rust workspace crate dependencies using cargo metadata.
Changes:
- Introduces
IrCommand::CheckDepsand CLI handler to report missing vs stale@c4 usesedges (optionally CI-gating via--strict). - Adds a new
archidoc-rust::cargo_metadataadapter for building crate-level graphs fromcargo metadataand validating IR relationships. - Wires up the new adapter module and adds
serde_jsondependency for parsing metadata.
Reviewed changes
Copilot reviewed 4 out of 5 changed files in this pull request and generated 5 comments.
| File | Description |
|---|---|
| core/archidoc-cli/src/main.rs | Adds the ir check-deps subcommand and output/exit-code behavior for drift detection. |
| adapters/archidoc-rust/src/lib.rs | Exposes the new cargo_metadata module publicly. |
| adapters/archidoc-rust/src/cargo_metadata.rs | Implements dependency graph extraction from cargo metadata and validation against IR @c4 uses, with unit tests for validation. |
| adapters/archidoc-rust/Cargo.toml | Adds serde_json for parsing Cargo metadata JSON. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Comment on lines
+49
to
+58
| let packages = meta["packages"] | ||
| .as_array() | ||
| .ok_or("`cargo metadata` JSON has no `packages` array")?; | ||
|
|
||
| let members: HashSet<String> = packages | ||
| .iter() | ||
| .filter_map(|p| p["name"].as_str()) | ||
| .map(str::to_string) | ||
| .filter(|n| !ignore.contains(n)) | ||
| .collect(); |
Comment on lines
+65
to
+82
| for pkg in packages { | ||
| let from = match pkg["name"].as_str() { | ||
| Some(n) if members.contains(n) => n.to_string(), | ||
| _ => continue, | ||
| }; | ||
| let deps = match pkg["dependencies"].as_array() { | ||
| Some(d) => d, | ||
| None => continue, | ||
| }; | ||
| for dep in deps { | ||
| // `kind` is null for normal deps, "dev"/"build" otherwise. | ||
| if !dep["kind"].is_null() { | ||
| continue; | ||
| } | ||
| let to = match dep["name"].as_str() { | ||
| Some(n) if members.contains(n) && n != from => n.to_string(), | ||
| _ => continue, | ||
| }; |
Comment on lines
+83
to
+86
| let edge = (from.clone(), to); | ||
| if !graph.edges.contains(&edge) { | ||
| graph.edges.push(edge); | ||
| } |
Comment on lines
+263
to
+269
| /// Check declared `@c4 uses` relationships against real crate dependencies | ||
| /// | ||
| /// Reads the actual crate→crate dependency graph from `cargo metadata` | ||
| /// (no extra tooling) and diffs it against the `@c4 uses` arrows declared | ||
| /// in a compiled IR. Reports two kinds of drift: | ||
| /// missing — a real dependency with no `@c4 uses` (add the arrow) | ||
| /// stale — an `@c4 uses` with no real dependency (remove the arrow) |
Comment on lines
+149
to
+152
| warnings.sort_by(|a, b| { | ||
| (&a.module, &a.target, a.kind.clone() as u8) | ||
| .cmp(&(&b.module, &b.target, b.kind.clone() as u8)) | ||
| }); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
Adds
archidoc ir check-deps— validates the@c4 usesrelationship arrows declared in a compiled IR against the real crate→crate dependency graph, read fromcargo metadata(no extra tooling).Reports two kinds of drift:
@c4 uses(prints a paste-ready//! @c4 uses …line)@c4 useswith no real dependency--strictexits 1 (CI gate).workspace-hackis ignored by default.Why
cargo_modules.rsalready containedImportGraph+validate_relationships(both drift directions) +detect_orphans, but it was dead code: never wired into the CLI, and it depends on the externalcargo-modulestool (module-level). This revives that machinery with:cargo metadata --no-deps, crate-level — matches@c4 componentgranularity), and@c4 usesarrows in the generated C4 diagrams can now be kept honest automatically instead of silently rotting as dependencies change.How
adapters/archidoc-rust/src/cargo_metadata.rs—workspace_import_graph()builds the existingImportGraph;validate_ir_relationships()diffs a compiledArchitectureIRagainst it, reusingRelationshipWarning/WarningKind.core/archidoc-cli— newir check-depssubcommand.Validated against a real 20+ crate workspace: a fully-declared IR passes; a perturbed IR correctly reports the injected missing + stale edges.
🤖 Generated with Claude Code