fix(validate): scope cross-repo UnknownPrefix to consumer-owned links (#649)#658
Open
avrabe wants to merge 3 commits into
Open
fix(validate): scope cross-repo UnknownPrefix to consumer-owned links (#649)#658avrabe wants to merge 3 commits into
avrabe wants to merge 3 commits into
Conversation
…#649) `rivet validate` walked EVERY artifact's outgoing links when computing `broken_cross_refs`, so any supplier's own external reference (e.g. `super:REQ-EXT` in an artifact synced under `sup:`) leaked into the consumer as `UnknownPrefix("super")` — 51 broken cross-refs in the reported ordeal case for prefixes the consumer never declared. That contradicts two of rivet's own documented positions: - DD-017 (`rivet docs cross-repo`): "declare direct deps only" - REQ-065 / AoU-X1 (`rivet validate --help`): "the consumer's PASS does not otherwise reflect the supplier's validation state" The cross-ref walk in `cmd_validate` now filters external (`prefix:ID`) artifacts out of both the `local_ids` set and the `all_refs` collection before calling `validate_refs`, mirroring the REQ-082 `is_external_artifact` convention already used across the per-artifact validation passes and by the lifecycle-completeness check on the same page. Consumer-owned broken prefixes still surface (the fix does not silently accept the consumer's own bogus refs); supplier internals stay in the supplier's validation gate, opt-in via `--with-externals-validate` (REQ-065 / AoU-X1). Regression: `validate_does_not_leak_transitive_external_prefixes` spins a supplier whose own artifact links to `super:REQ-EXT` (a prefix the consumer never declares) and a consumer whose own artifact links to a locally-broken `xyz:REQ-BOGUS`. After the fix: `broken_cross_refs` contains no `super:` findings but still contains the `xyz:` finding. Fixes: REQ-065 Refs: DD-017, #649
📐 Rivet artifact deltaNo artifact changes in this PR. Code-only changes (renderer, CLI wiring, tests) don't touch the artifact graph. |
There was a problem hiding this comment.
⚠️ Performance Alert ⚠️
Possible performance regression was detected for benchmark 'Rivet Criterion Benchmarks'.
Benchmark result of this commit is worse than the previous benchmark result exceeding threshold 1.20.
| Benchmark suite | Current: ca3cefe | Previous: 632eb8a | Ratio |
|---|---|---|---|
link_graph_build/10000 |
33762787 ns/iter (± 2544519) |
25008993 ns/iter (± 252673) |
1.35 |
This comment was automatically generated by workflow using github-action-benchmark.
Codecov Report✅ All modified and coverable lines are covered by tests. 📢 Thoughts on this report? Let us know! |
Picks up the quick-xml 0.41 security fix (RustSec) and the CI paths-filter. Trace: skip
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.
Closes #649.
What
rivet validatewalked EVERY artifact's outgoing links when computingbroken_cross_refs, so any supplier's OWN external reference (e.g.super:REQ-EXTin an artifact synced undersup:) leaked into the consumer asUnknownPrefix("super")— 51 broken cross-refs in the reported ordeal case for prefixes the consumer never declared.That contradicts two of rivet's own documented positions:
rivet docs cross-repo): "declare direct deps only"rivet validate --help, on--with-externals-validate): "the consumer's PASS does not otherwise reflect the supplier's validation state"The cross-ref walk in
cmd_validate(rivet-cli/src/main.rs:5819-5824) now filters external (prefix:ID) artifacts out of both thelocal_idsset and theall_refscollection before callingvalidate_refs, mirroring the REQ-082is_external_artifactconvention already used by every per-artifact validation pass inrivet-core/src/validate.rs:572-574and by the lifecycle-completeness check a few lines below on the same page (main.rs:5901-5905).Why this direction
Semantic (a) from the triage sketch — "strict transitive-scope: broken cross-refs classify as
UnknownPrefixonly for links originating in the consumer's own artifacts". The issue body already prescribes exactly this shape ("cross-ref checking should scopeUnknownPrefix/broken-ref errors to links originating in the local project"), and it matches the letter of DD-017 / REQ-065 without adding a new config knob (semantic (b) would have needed a new opt-inexternals.validate-transitiveflag; not worth the surface for a fix that removes the wrong behavior). The--with-externals-validateopt-in (REQ-065 / AoU-X1) is the remaining path if you want to walk supplier internals — untouched by this PR.Acceptance criteria (from #649)
cd ordeal; rivet sync; rivet validate) yields PASS on defaultrivet validate.UnknownPrefix("gale"/"kiln"/"jess"/"scry")— all originating in loom's and synth's own graphs — never fire.rivet validatestill FAILS on a genuinely brokenloom:ref written in the consumer's own artifacts.:) are still walked in full. Covered by the counter-assertion in the new test (xyz:REQ-BOGUSin the consumer surfaces as before).rivet-cli/tests/cli_commands.rs::validate_does_not_leak_transitive_external_prefixes— spins tworivet init --preset devprojects, wires supplier assup:, has supplier link tosuper:REQ-EXT(undeclared by the consumer), then assertsbroken_cross_refscontains nosuper:entries and DOES contain the consumer's ownxyz:REQ-BOGUS.--with-externals-validate(REQ-065 / AoU-X1) still surfaces supplier diagnostics when opted in.main.rs:5872-5897) is untouched; the existingvalidate_with_externals_validate_surfaces_supplier_diagnosticstest continues to guard it.rivet validateon this repo remains PASS.Why draft
This session's egress policy is scoped to
pulseengine/rivetonly. The workspace transitively depends onpulseengine/rowan(git dependency pinned at9e7abd1…, the maintenance fork), which the proxy denies with a 403 — same pattern as PRs #657 and #599. I could not runcargo build -p rivet-cli --testsorcargo testlocally in this session — the fetch ofrowancannot succeed. Please flip to Ready-for-review after CI (which has full scope) confirms:cargo test -p rivet-cli --test cli_commands validate_does_not_leak_transitive_external_prefixespasses on this branch,main(proves the regression test is real — thesuper:UnknownPrefix would fire, hitting theleaked.is_empty()assertion),rivet validateon the rivet repo remains PASS,validate_with_externals_validate_surfaces_supplier_diagnosticsandvalidate_does_not_count_external_repo_violations(the REQ-065 / REQ-082 guardrails) still pass.Test plan
validate_does_not_leak_transitive_external_prefixesfails onmain(revert the two.filter(...)lines, expectleakedpopulated with asuper:UnknownPrefix entry)rivet validateon a real cross-repo consumer (e.g. ordeal afterrivet syncof loom + synth) and confirm the 51 broken cross-refs are gone; a genuinely broken consumer-owned ref still failsBlog process pre-check
Re-fetched
https://pulseengine.eu/blog/at the start of this run — no posts on team workflow / branching / PR flow / testing conventions (the blog focuses on WebAssembly tooling, formal verification, and AI-assisted spec-driven verification). Nothing there overrides this PR.Generated by Claude Code — issue-triage agent run 2026-07-02.
Generated by Claude Code