Wave 2: five P1 cross-git fixes (REQ-063/064/068/075/076)#309
Merged
Conversation
…REQ-063) The do-178c/en-50128/iec-61508/iec-62304 presets named schemas that were never embedded in the binary; rivet init relies entirely on the include_str! embedded-schema registry and never writes schemas to disk, so the next rivet validate failed. Embed all four schemas alongside the working five. iec-61508 and iec-62304 also carried an unsupported `condition:` field inside traceability-rules (no such parser feature exists); replace it with the project-level-concern comment pattern that en-50128 already uses, so the schemas parse and fresh projects validate. Implements: REQ-007 Verifies: REQ-063 Refs: FEAT-135
…m link-field (REQ-064) The cross-git investigation's S4 finding misdiagnosed this as "the structured target is silently parsed as derives-from with no target". Reproduction shows the link parses correctly — `rivet get` reports `type: derives-from-external, target: ANCHOR-X`. The real bug is in the validator's link-field cardinality check (`validate.rs` phase 4): it counted only links whose type *exactly* equalled the required link-field type. A `sw-req` carrying a `derives-from-external` link to satisfy its required `derives-from` link-field therefore counted 0 and failed with a spurious `link 'derives-from' requires at least 1 target, found 0` Error. Fix: new `link_satisfies_field(actual, required)` — a `<base>-external` link is the cross-organizational variant of `<base>` (it terminates at an `external-anchor` rather than an in-house artifact, but the derivation still happened, it just crossed an org boundary), so it satisfies a required `<base>` link-field. The cardinality count uses it. The target-type check deliberately does NOT: a `derives-from-external` link legitimately points at an `external-anchor`, which is not in the base field's target-type list, and the existing exact-match filter correctly skips it there. Regression test: validate_accepts_derives_from_external_structured_target. Verified: test_dogfood_validate still green; clippy -D warnings exit 0. Implements: REQ-004 Verifies: REQ-064 Refs: FEAT-135
…drift to override (REQ-068) `rivet supplier pull` was the only side of the federation handshake that silently accepted changed supplier bytes — overwriting the cache and exiting 0 with no DRIFT header — while `rivet validate` correctly refused the same drift. A fetch was thus granting the supplier authority to revise a delivered artifact with no audit trail. Pull is now the authorisation point: it compares the new payload's sha256 against the prior recorded hash (the prior cache manifest's source-hash, falling back to the anchor's stamped cited-source.sha256). On mismatch it refuses — exit non-zero, naming the prior hash, the new hash, and the supplier identity (org + contract) — and leaves the cache untouched. The new --accept-drift flag is the explicit auditor authorisation path: it overwrites the cache and re-stamps the anchor's cited-source. First pulls and idempotent re-pulls of identical bytes are unaffected. Implements: REQ-007 Verifies: REQ-068 Refs: FEAT-135
…75, REQ-076) REQ-075: two artifacts declaring the same `id` collapsed silently — `Store::upsert` is last-write-wins, so by the time `validate::validate` runs only the survivor exists and the validator is structurally blind to the collision. Extend the REQ-062 load-report channel: add a `LoadReport` struct and `load_artifacts_with_report` that, alongside skipped files, returns `DuplicateId` records detected at LOAD time where both copies are still visible. `cmd_validate` loads every source, runs a project-wide duplicate pass (`detect_duplicate_ids_for_validate`), and emits one Error diagnostic per collision with `rule: duplicate-artifact-id` naming both source files and the colliding ID. `load_artifacts`'s signature is unchanged (rivet-core public API semver gate). REQ-076: orphan artifacts (no inbound and no outbound links) were visible to `rivet stats` but never to `rivet validate`. `cmd_validate` now reuses `LinkGraph::orphans` — the exact computation behind `rivet stats` — and emits one `rule: orphan-artifact` diagnostic per orphan. Severity is Warning by default (a hard-error default would break Rivet's own dogfood, which carries orphans) and is promoted to Error by a new `--strict-orphans` flag, wired exactly like `--strict-cited-sources`. `cmd_stats` now mirrors both rules into its diagnostic counts so `stats` and `validate` stay consistent (`stats_json_counts_match_validate`). Both new rules surface in the `--format json` `rule` field automatically. Regression tests: `validate_detects_duplicate_artifact_ids` (two files and twice-in-one-file) and `validate_reports_orphans_as_warnings` (Warning default, Error under `--strict-orphans`). Implements: REQ-004 Verifies: REQ-075, REQ-076 Refs: FEAT-135 Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
REQ-075's new duplicate-artifact-id detection (in this same Wave-2
branch) immediately surfaced a genuine, pre-existing collision in
rivet's own artifacts/: `REQ-060` was declared twice —
- artifacts/v040-verification.yaml:471 "Cross-platform binary support"
- artifacts/v042-artifacts.yaml:393 "Every embed option must validate
before the embed renders"
two unrelated requirements sharing one ID. Until now `Store::upsert`'s
last-write-wins silently kept only one and `rivet validate` reported
PASS — exactly the F2 silent-data-loss the cross-git investigation is
about. With REQ-075 shipped, `rivet validate` on the rivet repo itself
(pre-commit hook + CI) would FAIL on this collision.
Resolved by renaming the v042 entry to REQ-077 (the next free id). It
was the safe one to rename: zero inbound links anywhere in artifacts/,
zero mentions in docs/. The v040 REQ-060 keeps its id — its two inbound
links (v040-verification.yaml:125, :453) stay valid. The renamed
artifact's own outgoing links (verifies REQ-010, satisfies REQ-004) are
unchanged.
Also folds in `cargo fmt` of the cherry-pick-integrated cli_commands.rs
test block.
Implements: REQ-010
Refs: FEAT-135, REQ-075
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
📐 Rivet artifact delta
Graphgraph LR
REQ_060["REQ-060"]:::modified
REQ_077["REQ-077"]:::added
classDef added fill:#d4edda,stroke:#28a745,color:#155724
classDef removed fill:#f8d7da,stroke:#dc3545,color:#721c24
classDef modified fill:#fff3cd,stroke:#ffc107,color:#856404
classDef overflow fill:#e2e3e5,stroke:#6c757d,color:#495057,stroke-dasharray: 3 3
Added
Modified
Posted by |
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: 4db7152 | Previous: 0d98b7c | Ratio |
|---|---|---|---|
validate/10000 |
17999875 ns/iter (± 2513882) |
13701860 ns/iter (± 1780687) |
1.31 |
This comment was automatically generated by workflow using github-action-benchmark.
Codecov Report❌ Patch coverage is
📢 Thoughts on this report? Let us know! |
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.
Summary
Wave 2 of the cross-git investigation follow-ups (FEAT-135) — five P1
code fixes, each closing an F2-family finding (a silent failure under a
green
rivet validate). Integrated from four parallel work units.rivet init --preset {do-178c,en-50128,iec-61508,iec-62304}no longer produces an unvalidatable project — the four safety-critical schemas are now embedded in the binary alongside the working five. (Two also carried an unparseablecondition:field; brought in line with theen-50128pattern.)derives-from-externallink now satisfies a requiredderives-fromlink-field. The S4 finding was misdiagnosed as a parse failure; the link parses fine — the validator's cardinality check counted only exact matches. Newlink_satisfies_fieldhelper.rivet supplier pullrefuses on sha256 drift (exit non-zero, names both hashes + supplier) instead of silently overwriting the cache;--accept-driftis the explicit auditor override.duplicate-artifact-idError naming both source files — instead ofStore::upsertsilently keeping last-write-wins.rivet validate(orphan-artifact, Warning by default;--strict-orphanspromotes to Error) — previously visible only inrivet stats.Notable: REQ-075 immediately found a real bug
The new duplicate detection surfaced a genuine pre-existing collision in
rivet's own
artifacts/:REQ-060was declared twice (two unrelatedrequirements). Resolved by renaming the v042 entry to
REQ-077(zeroinbound links, zero doc mentions — the safe one). Without this,
rivet validateon the rivet repo itself would now FAIL.Test plan
cargo build --workspace— clean.cargo test --workspace— 0 failures across the full suite.init_safety_critical_presets_produce_validating_projects,validate_accepts_derives_from_external_structured_target,supplier_pull_refuses_on_sha256_drift_without_accept_flag,validate_detects_duplicate_artifact_ids,validate_reports_orphans_as_warnings.test_dogfood_validate+stats_json_counts_match_validate— still green.cargo clippy --workspace --all-targets -- -D warnings— exit 0.Implements: REQ-004, REQ-007, REQ-010
Verifies: REQ-063, REQ-064, REQ-068, REQ-075, REQ-076
Refs: FEAT-135
🤖 Generated with Claude Code