Skip to content

Instantly share code, notes, and snippets.

@ruvnet
Created August 13, 2026 15:13
Show Gist options
  • Select an option

  • Save ruvnet/d049ba7b4cf9ccfa8d96a630db48a4d7 to your computer and use it in GitHub Desktop.

Select an option

Save ruvnet/d049ba7b4cf9ccfa8d96a630db48a4d7 to your computer and use it in GitHub Desktop.
RuVector PR sweep 2026-08-13: CI shard-split root cause found & fixed, two research PRs merged with corrected claims, external PR closed with credit

RuVector PR Sweep — 2026-08-13

A multi-agent Claude review swept the four most recent open PRs in ruvnet/ruvector, then integrated the findings, published them as PR comments, and merged/closed each PR per verdict. Three PRs merged, one closed with credit, two follow-up issues filed — and one long-standing CI mystery solved at the root.

Headline: the CI shard split was never sharding

PR #822 — ci: split platform crates from workspace catch-all → MERGED (6c7cb709d)

The review found the root cause behind every failed shard-split iteration (iters 228–240): the catch-all shard's --exclude list lived inside a YAML folded scalar (>-) with #-prefixed lines mixed in. Those # lines are content, not YAML comments — folding joins everything onto one line, and the shell truncates the expanded command at the first #. Net effect: 0 of 162 exclude flags ever reached cargo, and core-and-rest has been running cargo nextest run --workspace — all 210 crates — on every run. Every prior split was inert, which is why the timeouts never moved.

Fixes merged:

  • All comments relocated to mapping level, above the packages: key; scalars now contain only flags. Validated with PyYAML: 50 effective packages in the catch-all, 203/210 crates covered, zero double-builds (the remaining 7 are deliberate hardware/wasm/feature-gated exclusions).
  • New .config/nextest.toml with slow-timeout + terminate-after: a hung test now fails in 10 minutes instead of burning the 240-minute job budget.
  • ruvector-delta-index held out of CI: its test_insert_and_search hangs indefinitely (sat 3h52m on the PR's own run) → tracked in #825.

Note: the first post-merge run on main is the first real measurement of the 50-crate catch-all — all prior timing data described a 210-crate build.

Research PRs: claims corrected to match the code, then merged

PR #823 — entropy-adaptive ANN beam search → MERGED as a negative result

The reviewer rebuilt the crate and ran the comparison the PR omitted: EntropyScaledEf computed ef_actual = 122–124 for every query, and a plain FixedEf(124) baseline reproduced its recall to four decimal places on all three query sets. The entire reported +1.6–3.9 pp gain was "2.5× the ef budget," not entropy. The benchmark also timed ground-truth computation inside the measured closure, masking a ~47% search-only latency regression.

Merged with: ADR-303 rewritten to "Closed — negative result" (the genuinely valuable finding: softmin entropy over already-retrieved neighbour distances measures local density, not query difficulty — with the wrong sign), benchmark methodology fixed (search-only timing + a permanent matched-ef control column), clippy blocker fixed, recall_at_k no longer rewards returning fewer results. 15/15 tests, clippy and fmt clean.

PR #824 — retrieval receipts (witness-chained provenance) → MERGED with corrected threat model

The hashing was competent (domain separation, to_bits() for floats, no unsafe, no new deps), but the headline claim — "tampering with the ingestion history invalidates the receipt" — was false as implemented: verification never consults the write gate; receipts commit to copies of write-receipt fields, so a mutated ingestion history leaves issued receipts verifying. ADR-304 was also marketing legal/medical chain-of-custody on that claim.

Merged with: threat model corrected everywhere (receipts detect post-issuance mutation of a receipt/result pair — they do not prove write-chain membership or protect against a dishonest query engine; binding to MerkleGate's MMR membership proofs is the named future-work item), the "2x smaller / 2.1x faster" framing relabeled to the durable asymptotic O(log k) vs O(k) argument, and three code hardenings: verify_full now fails closed on empty result sets, NaN-safe sorting via total_cmp, and gate_variant bound into each leaf so ungated (NullGate) receipts are distinguishable. 14/14 tests, clippy and fmt clean.

External contribution: right diagnosis, already landed

PR #810 — graph-node persistence fix → CLOSED with credit

@Bolivar1234 correctly diagnosed that @ruvector/graph-node silently lost all data on restart, and their analysis of the PropertyValue::from(Vec<f32>) generic-impl dispatch bug was sharp work. The fix had already landed on main (commit 31bb944, 2026-08-12) in hardened form — cascade-guarded storage deletes, propagated errors, O(degree) cascades, and test coverage — so merging the now-conflicting branch would have reverted those hardenings (including reintroducing unconditional edge deletion on deleteNode with cascade: false). Closed with a detailed crediting comment; the contributor's data also surfaced a real defect in shipped code — synchronous hydrate_from_storage in the NAPI constructor blocks the Node event loop ~15s on a 154K-node graph — now tracked in #826.

Scoreboard

PR Verdict Outcome
#822 Request changes → fixed Merged 6c7cb709d + issue #825
#823 Keep as research, reframe Merged as documented negative result
#824 Keep as research, fix claims Merged with corrected threat model + hardened verification
#810 Close (already on main) Closed with credit + issue #826

Reviews, fixes, and integration performed by Claude (multi-agent review swarm) on behalf of the maintainer, 2026-08-13.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment