Commit graph

256 commits

Author SHA1 Message Date
rUv
684d21a354
docs(adr): ADR-339 — a WebAssembly binding for ruv:// context, and its boundary (#925)
* docs(adr): ADR-339 — a WebAssembly binding for ruv:// context, and its boundary

Records why a JavaScript consumer cannot reach rvm-context today, and what a
binding may and may not carry.

The manifest settles the first half: crate-type = ["rlib"] links Rust to Rust,
so there is no JS, wasm, or C ABI surface and no feature flag that produces
one. Three adjacent facts were verified rather than assumed, each plausible
enough to guess wrong about: crates/rvm-wasm is a WebAssembly GUEST runtime for
partitions, not a binding; ed25519-dalek is a dev-dependency, so the runtime
crypto surface is sha2 and sha3, both wasm32-clean; and a std feature already
exists, which wasm-bindgen requires.

The decision is a cdylib wrapper crate publishing to npm as
@ruvnet/rvm-context, exposing canonical parsing, canonical re-formatting, and
the specific UriError variant on rejection -- pure computation over a string.

It deliberately does not expose the runtime or resolver paths. Those require an
authenticated PartitionId bound at construction and a runtime-owned clock,
which exist so a caller cannot supply its own actor or timestamp. Projecting
them into JavaScript would mean inventing a JS-side actor -- the forgery the
design prevents -- or shipping something that looks like authorization and is
not.

So a JavaScript consumer gets the naming layer, not the trust layer. That is
not a limitation to lift later by adding bindings; it is the separation the
namespace is built on, holding at one more boundary.

Also records that npm's `rvm` belongs to an unrelated project (Ruff Version
Manager, ruffjs/rvm), so any JS distribution here is a new scoped package
rather than an update to that one.

Co-Authored-By: claude-flow <ruv@ruv.net>
Claude-Session: https://claude.ai/code/session_016QSCkKnxDjqU49NVVpWMK5

* docs(adr): revise ADR-339 after reading the real capability API

Sizing the binding against origin/main turned up four facts that change the
decision, two of which contradict what the release notes imply.

Capability handles are not portable. CapabilityHandle is {index, generation}
into a LIVE LOCAL CapabilityManager table -- not a bearer token, not signed,
not serializable. Two integers handed from a Rust service to a JS host index a
different table and mean something else. This is the load-bearing constraint.

An allow decision cannot be separated from its witness record: authorize is
pub(crate) and AuthorizedRequest construction is private, documented as
reachable only after a P1 allow record is appended. A binding that authorizes
must carry ContextRuntime and therefore the witness log.

There is no entropy requirement. ed25519 lives only in rvm-proof; rvm-witness
signs with HMAC-SHA256, deterministic and keyed, and no getrandom or rand
exists in the workspace. The hazard is key provisioning -- default_signer() and
with_default_key() must not reach JS -- not randomness. No host clock is needed
either: LogicalContextClock is a counter from zero.

The consequence is that the earlier draft drew the boundary in the wrong place.
It excluded authorization entirely; the handle representation shows why that
was wrong. The danger was never that JS might mint a capability, because a
capability minted in the module grants nothing outside it. The danger is the
ILLUSION of authority -- a gateway provisioning its own scopes, rendering a
decision, and reporting it as though it said something about a separate
Rust-side authority.

So the binding widens to four layers (URI, scope, runtime, verification) and
the claim sharpens: the module is a faithful deterministic policy SIMULATOR,
handles are not portable, a decision binds only to host-provisioned scopes.
Correct for shadow mode, not evidence about another authority.

Scope containment alone answers the shadow-mode question with no capability, no
runtime and no key, so the motivating consumer is unblocked at layer 2.

Gates revised accordingly, including that the cross-tenant negative test must
place the violating segment LAST -- a containment check inside a
short-circuiting loop is green at position 1 while broken for 2..n.

Tracks ruvnet/rvm#45.

Co-Authored-By: claude-flow <ruv@ruv.net>
Claude-Session: https://claude.ai/code/session_016QSCkKnxDjqU49NVVpWMK5
2026-08-23 18:28:45 -04:00
ruv
9935b30649 docs(adr-337): correct three statements that understate the overhead problem
ADR-337 is merged and being read, and three of its claims are wrong in the
direction that makes the problem look smaller. Wrong merged documentation
propagates faster than an unfixed accounting bug and costs nothing to
correct, so this goes ahead of the code fixes.

The 108% figure was quoted as the realistic bad case. It is the
10%-mandatory mix -- which is why its rung count divides to 0.4 per
operation rather than max_rounds. Against an all-mandatory stream the same
configuration measures 1075%, an order of magnitude worse. An adversarial
stream is not 10% mandatory, so 1075% is the number to size against.

"The ladder spends max_rounds on every operation" cannot be literally true
at 80 rungs over 200 operations. It is every operation it INSPECTS: an
all-benign stream buys 0 rungs, an all-mandatory one buys 800, exactly 4.00
each.

detector.rs claimed that sourcing uncertainty from the detector "removes
the divergence rather than bounding it." It bounds it. Nothing cross-checks
the declared figure against what score() actually carries, so an
implementation may still declare one value and produce another; the (0,1]
bound caps how far apart they can be, with residual inflation reaching 44x
at sigma=0.05. What changed is that exploiting it now requires writing a
trait implementation rather than editing a config value -- a different risk
class, not an absent one.

Also records that every overhead figure is a declared-cost model rather
than a wall-clock measurement: the account charges each rung its declared
latency and separately charges the wall-clock of the whole inspection, so a
real investigator is billed roughly twice (2.46x measured on one 300 ms
rung). That direction is conservative and cannot conceal a breach, but
fraction() should be read as a model until it is fixed.

Docs and comments only; no behaviour change. 42 lib tests pass, fmt clean,
ADR index check passes.

Co-Authored-By: claude-flow <ruv@ruv.net>
Claude-Session: https://claude.ai/code/session_016QSCkKnxDjqU49NVVpWMK5
2026-08-23 10:57:05 -04:00
ruv
38205687d7 docs(adr): correct ADR-337's cost reasoning — the limiter is the belief update, not the price
Reverses part of the previous commit. That text said the <5% target was
unenforced BECAUSE latency_price defaults to 0.0, which implied pricing
latency would enforce it. The coder implemented exactly that, measured it,
and the implication is false.

Measured (WP33, fixes at 5d81fb1):

  investigator resolves the ambiguity (0.2)      2.6%   20 rungs
  investigator leaves it ambiguous (0.5), priced  108%   80 rungs
  same, unpriced                                  205%   80 rungs

The limiter is the belief update. When the first rung settles the
question, VoI collapses and the ladder stops. When it does not, the belief
sits at the escalation threshold, every further rung still looks worth
buying, and the ladder spends max_rounds on every operation. Pricing
latency roughly halves overhead by shifting the rung mix toward cheaper
rungs; it does not reduce the rung count.

So max_rounds is the only hard bound on wall-clock monitoring cost -- four
rounds of a 200ms rung against a 20ms workload is 40x the budget by itself
-- and whether <5% is met depends on whether investigators actually
resolve ambiguity, which is a property of the investigators, not of the
ladder's economics. An investigator that returns "maybe" is not a cheaper
investigator; it is an unbounded one.

The 0.06% / 14.8% pairing is kept for what it measures, but the 108% and
205% figures are the ones a reader needs, because they are the realistic
bad case and they are far outside target.

Also recorded, because it is the second occurrence this wave: implementing
a proposed mitigation disproved the reasoning behind it. The Wave-4
precedent is #902's inode identity check, necessary but not sufficient --
it correctly refused to publish a foreign inode, but the harm had already
landed earlier in the sequence. In both cases the mitigation was real and
the reasoning was wrong, and only building and measuring it exposed the
difference. A mitigation that is plausible, correct in isolation, and
aimed at the wrong quantity will pass review and fail in production.

Audit findings now fixed at 5d81fb1 and recorded: calibration guard takes
uncertainty from TinyDetector::expected_uncertainty() rather than an
operator declaration; the ceiling calls voi_upper_bound instead of
recomputing with sigma; Classification no longer derives Default; coverage
has a denominator, so "nothing mandatory occurred" is now distinguishable
from "classification stopped"; six plain-ASCII destructive verbs added;
record_rung moved ahead of validation; rung_is_purchasable validates.
41 lib + 24 integration tests, clippy and fmt clean, all seven negative
checks bit.

Unchanged: the 121,500-check enforcement evidence, the no-call-site
deployment status, the recognition-gap-lives-in-classes.rs point (six
verbs added, obfuscation still open), and the #921 dependency-closure
reference.

Co-Authored-By: claude-flow <ruv@ruv.net>
Claude-Session: https://claude.ai/code/session_016QSCkKnxDjqU49NVVpWMK5
2026-08-23 10:34:05 -04:00
ruv
099340004c docs(adr): record WP33 audit findings in ADR-337 and #920 field evidence in ADR-335
The WP33 audit (#919) returned one strong result and four corrections.
Two of the corrections were claims that would otherwise have travelled
downstream as facts, so they are recorded before the ADRs merge.

The enforcement guarantee held under brute force and is now evidenced
rather than asserted: 24,300 constructible configurations times 5
mandatory operations is 121,500 checks, zero bypasses. The forced
purchase, classification-before-detection ordering, union-not-first-match
classification, must_use outcome, the cost>0 and round-cap pair, the
oracle exit with its non-finite guard, and unit-range rescaling all
verified clean.

Four corrections, each of which narrows a claim rather than weakening the
mechanism:

The 0.06% overhead figure now never appears without its caveat. It is
honest for what it measures -- the ladder's own cost with an
instant-return fixture, and the accounting genuinely wraps classification,
detection, the VoI decision, investigation and observation -- but it is
not the number the <5% target is about. With investigators that sleep
their declared latency the measured overhead is 14.8%, roughly three times
target. Both numbers and what each measures are stated.

The <5% target is unenforced, and said so plainly. latency_price defaults
to 0.0, so a rung declaring ten seconds costs what a 0us rung costs, and
only max_rounds bounds wall-clock cost. Pricing latency honestly refuses
the shipped reference ladder at construction, so the honest configuration
is currently hard to reach.

"100% inspection of mandatory classes" is not yet a checkable metric.
mandatory_inspections has no denominator, so a run of 200 operations each
matching all five mandatory classes reported zero -- correct behaviour,
since they halted fail-closed before purchase, but indistinguishable from
a ladder that silently stopped classifying. Enforcement is airtight; the
measurement of it is not, and the ADR now separates the two.

The module is not wired into the gate's request path, so nothing in the
ADR describes the running system. Deployment status is explicit, and #921
(42 crates including bundled SQLite, ndarray and safetensors pulled into a
security gate's closure to reuse six pure-math items) should land first.

Also recorded: the recognition gap does not close by swapping the
detector. Recognition lives in the classes.rs marker list, not in
KeywordDetector, so a better detector changes nothing.

ADR-335 gains the #920 field evidence, which strengthens its own argument:
the flywheel's hard_regression gate is permanently stuck closed, rejecting
120 of 120 candidates across 30 unattended generations including 30 that
were strictly better on primary, recall, qps and cost, because it tests an
absolute threshold rather than comparing to baseline. That is the case for
per-repo declaration made empirically rather than rhetorically.

Co-Authored-By: claude-flow <ruv@ruv.net>
Claude-Session: https://claude.ai/code/session_016QSCkKnxDjqU49NVVpWMK5
2026-08-23 10:24:11 -04:00
ruv
a51d84db20 docs(adr): Wave-5 ADRs — repo-native optimization skills, reversible capability transactions, adaptive runtime monitoring, electromagnetic world model (PIR)
Adds ADR-335 through ADR-338 and the Wave-5 evidence review and program
plan. All five briefed claims verified against primary sources with zero
misattributions -- a first for this program. The failure mode this wave is
omission, and two omissions change decisions:

NVIDIA's 15-77% throughput range rests on exactly two paired runs ("one
Claude Code pair and one Codex pair"), so it is recorded as a directional
anecdote rather than a target. The stronger evidence, independent
re-deployment and re-benchmarking of every produced recipe on real
clusters, is cited in preference.

OpenAI's 20% monitoring overhead has the monitored subset as its
denominator, not total inference, and monitoring is deliberately scoped to
a narrow high-risk slice. An ADR reading "monitoring costs 20%" would
overstate the budget by an unknown factor, so ADR-337 states the
denominator every time it cites the figure.

Covenant (open-covenant/covenant) genuinely implements signed grants,
revocation, audit chains, memory, provenance, and fail-closed dispatch, so
the novelty framing is dropped -- claiming otherwise would repeat the
Wave-1 "component absent" mistake. But its own docs disclaim isolation,
DeepSeek ships a live mount/unmount runtime it refuses to call a security
boundary, and OpenAI pays for runtime monitoring because static gating is
insufficient. Three independent sources converge on the same gap, so
ADR-336's thesis is signed plus reversible plus evolvable, not signed
alone.

Scope is stated honestly rather than optimistically. ADR-335 is an
extension: the scout's at-source audit found the objective, benchmark
command, invariants, one-isolated-variable enforcement, cost budget,
promotion rule, and three-way keep/discard/reject already implemented in
the harness. The gaps are a per-repo declaration layer and an in-repo
Pareto frontier. ADR-336 is contract-only here because ADR-333 already
placed RVM work in ruvnet/rvm under maintainer review, and its PR #38 is
REVIEW_REQUIRED -- Wave 5 cannot merge it. ADR-337 consumes Wave 4's VoI
primitive unchanged, binding the four caveats voi.rs documents about
free rungs, oracle rungs, value_of_success calibration, and deep-tail
precision. ADR-338 honours ADR-332's existing deferral.

The Wave-5 acceptance test cannot be fully satisfied while WP32 is
blocked; the plan says so and requires the capability-envelope clause be
reported unmet rather than stubbed.

Co-Authored-By: claude-flow <ruv@ruv.net>
Claude-Session: https://claude.ai/code/session_016QSCkKnxDjqU49NVVpWMK5
2026-08-23 09:59:54 -04:00
ruv
4c6da3b30d fix(context): make the index root private and enforce it
Four rounds of security review kept finding the same shape: a sensitive
thing placed under a NAME in the attacker-writable root, defended by a
check on that name, and the next round swapped the next name. The scratch
name moved inside a private staging directory -- and then the staging
directory was itself a name in the root, so it was swappable too. The
review demonstrated 274 victim rows readable outside the root after
erase_scope reported success.

There is no fixed point on that path, because every component under the
root is re-resolved on every syscall and this crate holds none of them by
descriptor. Two things terminate it: descriptor-anchored I/O, which needs
an fd- or directory-relative open in the vector engine and is therefore an
engine-level change, or removing the hostile directory from the threat
model. This takes the second.

It also settles a finding that made the rest academic: under a normal umask
shards were published 0644 inside a 0755 root, so a different-uid attacker
could read every tenant's vectors with no exploit at all. The staging
directory was protecting a shard for the milliseconds it was being built
and then publishing it world-readable.

The root is now created 0700 by mkdir itself, shards and the lock are
created 0600, and open refuses a root that is group- or other-accessible,
reporting the offending mode without the path. An existing root is
inspected and never modified, so an operator's deliberate permissions are
reported rather than silently widened or narrowed. Observed on disk under
both umask 022 and umask 000: root 0700, lock 0600, shard 0600, staging
0700.

The staging directory, the inode identity check, the lone-regular-file
requirement and the reserved-name sweep are all kept, but they are now
defence in depth against operator error rather than the boundary itself,
and their docs say so. The nlink documentation is corrected in particular:
a link count of one means only that no second name existed at the instant
of the lstat, not that the file is this index's, and the private root
rather than that check is what prevents a second name.

An attacker running as the same uid remains conceded, and content forgery
remains out of scope for want of a MAC over stored vectors. Both are stated
in the crate docs, the tests, and ADR-334.

Note for reviewers: tempfile::tempdir() creates 0755, so the new check
refused every existing test root and the suite now builds its roots at
0700 explicitly. That default is exactly the class of mistake that produced
the world-readable shards.

Co-Authored-By: claude-flow <ruv@ruv.net>
Claude-Session: https://claude.ai/code/session_016QSCkKnxDjqU49NVVpWMK5
2026-08-22 18:21:20 -04:00
ruv
13e7dbb50b fix(context,core): close three HIGH findings in the scope-sharded index
Security review of this PR found three HIGH issues, each demonstrated by
running code rather than inferred. All three are fixed here, with
regression tests that were verified to fail against the unfixed code
before the fix was applied.

HIGH-1 -- concurrent open regressed in ruvector-core. Moving DB_POOL to
Weak without giving VectorStorage a Drop meant Weak::upgrade went None the
instant the strong count hit zero, while redb's Database::drop (a write txn
plus fsync) and the flock release were still pending. A concurrent
VectorStorage::new then called Database::create against a still-locked
file: 194/200 failures with "Database already open", against 0/200 on main.
The Weak change is kept -- it fixes a real data-correctness bug -- and the
lifetime is made explicit instead: VectorStorage now has a Drop that clears
the slot and drops the Database while still holding the path guard, so the
lock is released before a racing open can observe an empty slot. The pool
is now per-path, so one path's fsync no longer blocks opens of unrelated
paths, and dead entries are reaped rather than accumulating forever.

HIGH-2 -- create_shard adopted a pre-existing file. open() verified the
scope-to-filename binding but the create path did not, and VectorDB::new on
an existing path silently inherits that file's stored config and vectors.
A shard planted at a victim's computed filename while the index was open
was adopted on the next insert, and because create_shard then rewrote the
manifest to the victim scope, the rows were laundered: after a restart the
binding check passed and the victim scope permanently contained them.
Creation now refuses an existing file, and refuses again after opening if
the database carries a manifest, is non-empty, or opened with unrequested
dimensions or metric -- closing the check-to-open window. Neither refusal
unlinks, so a planted file survives to be quarantined rather than deleted.

HIGH-3 -- erase_scope resurrected data. Two index handles over one root
shared the process-global pool while keeping independent in-memory indexes,
so an erase reported success while the other handle kept the rows alive,
and the erasing handle's next insert got the unlinked database back. open()
now takes an exclusive advisory lock on the root, so a second handle fails
loudly instead of silently sharing state. This also closes the divergence
where one handle's search could not see another's insert while scope_stats
reported the higher count.

Also fixed: erase_scope now unlinks before mutating the catalog, so a
failed unlink can no longer report an in-memory erase over a surviving
file; a single unreadable shard-shaped file is quarantined and surfaced
through quarantined_shards() instead of denying open() to every tenant;
max_results is capped so usize::MAX is refused by validate() rather than
reaching Vec::with_capacity and panicking out of a #![forbid(unsafe_code)]
crate; and errors report the shard filename rather than an absolute path.

The per-shard search counter is now type-enforced. Shard moved into a
private module where ann_search is the only route to the ANN index and
always increments, so an uncounted traversal no longer compiles. The
counter previously guarded one of five db touch sites, which made the
isolation claim close to tautological.

The integration suite is parameterized over both FlatIndex and HNSW. It
previously set hnsw_config: None throughout, so the claim that a tenant
search never calls another tenant's ANN index was established with no ANN
index in the process. The claim holds under HNSW.

ADR renumbered 332 -> 334: 332 was already taken by the RF-sensing ADR
merged earlier the same day, on a branch that already contained that merge.
The ADR now also records that the manifest binds scope to filename and not
to content, that there is no MAC over stored vectors, and that the global
scope ceiling and eager open are explicit non-goals.

Co-Authored-By: claude-flow <ruv@ruv.net>
Claude-Session: https://claude.ai/code/session_016QSCkKnxDjqU49NVVpWMK5
2026-08-22 17:04:43 -04:00
rUv
40580b52b0 feat(context): add scope-sharded vector index 2026-08-22 12:17:13 -04:00
ruv
697cf28b04 docs(adr): record VoI escalate-only invariant and value_of_success calibration hazard (PIR WP28, ADR-331)
From the WP28 audit (PR #893, HIGH). Two additions to ADR-331 and one to
ADR-330:

- ADR-331 Decision §6: escalate-only invariant — the VoI gate may only
  convert a would-be-lightweight route into an escalation, never rescue a
  below-threshold or over-uncertain candidate into the cheap path. The
  "decide on current belief" arm falls back to the legacy rule rather
  than short-circuiting to the lightweight model, so confidence_threshold
  and max_uncertainty are consulted on every path. Routing analog of
  ADR-330's downgrade-only confidence bound; a non-finite surviving a
  clamp resolves toward escalation. Added to the gates section as a
  blocking, regression-tested requirement.
- ADR-331 Consequences: operational note on the value_of_success
  calibration hazard — VoI is bounded by ~0.4σ and σ here is a conformal
  uncertainty on a [0,1] score, so value_of_success = 1.0 with σ ≈ 0.05
  makes any escalation above ~$0.02 unpurchasable at every score, leaving
  a permanent never-escalate switch that still looks healthy. Operators
  must express value_of_success as the currency value of a correct route.
- ADR-330 Consequences: security corollary — shipped scope detects
  declared derivation only, so no sufficiency threshold may be relied on
  as a trust gate against repeated-claim attacks (20 rumor-copying agents
  yielded 21 lineages, zero downgrade).

Co-Authored-By: claude-flow <ruv@ruv.net>
Claude-Session: https://claude.ai/code/session_016QSCkKnxDjqU49NVVpWMK5
2026-08-22 11:51:40 -04:00
ruv
95ae0b0bf4 docs(adr): Wave-4 ADRs — AI4AI recursive-improvement bench, schema-resource cache, correlation-aware memory arbitration, VoI routing (PIR)
Wave-4 evidence review (10) and program plan (11) for the six Aug 20 2026
papers plus the NVIDIA security-stack items, all independently verified at
source (6/6 arXiv IDs resolve; two brief corrections carried: the
AstraNetLab/CacheRoute repo is a name collision with arXiv:2608.19677, and
the RF-sensing sensor attributions were swapped). Allocates ADR-328
through ADR-333 (confirmed free at kickoff; 322 remains skipped) and
regenerates INDEX.md (next available: 334).

- ADR-328: AI4AI-Bench (arXiv:2608.20318) adapter behind the harness's
  injected-benchmark seam; research-artifact-emission restriction intact
- ADR-329: content-addressed schema-resource cache (ReCache-pattern,
  arXiv:2608.19662); bind-to-resolved-content, downgrade-only accounting
- ADR-330: CAMA-pattern (arXiv:2608.19701) correlation-aware memory
  arbitration; downgrade-only effective evidence, non-finite rejection
- ADR-331: VoI cost-aware routing (arXiv:2608.20316) in tiny-dancer;
  centralized policy only, decentralized variant out of scope
- ADR-332: RF modality router posture (arXiv:2608.20322, stretch)
- ADR-333: RVM semantic authority above OpenShell-class runtimes
  (cross-repo; RVM merge is USER ACTION)

Co-Authored-By: claude-flow <ruv@ruv.net>
Claude-Session: https://claude.ai/code/session_016QSCkKnxDjqU49NVVpWMK5
2026-08-22 09:39:17 -04:00
ruv
a2a724ebd3 docs(adr): fix D²ACCI acronym expansion + stage count (PR #884 review)
Blocking (B1): ADR-325 spelled out D²ACCI's acronym as "Dual-Loop
Diagnostic Protocol for evidence-preserving agent memory" — that's the
paper's title subtitle, not its acronym expansion. arXiv:2608.17756's
abstract defines it verbatim: "D²ACCI (Diagnostic-Driven Artifact-based
Closed-loop Controlled Iteration)". Fixed the first-use spell-out and the
propagate-this-expansion instruction to the correct acronym; left the
"dual-loop / inner loop / outer loop" mechanism language unchanged since
the protocol genuinely is dual-loop.

Non-blocking, folded in:
- N1: ADR-325 and 09-wave3-program-plan.md said "five stages (ingestion,
  extraction, retrieval, filtering, generation)" — the abstract enumerates
  four (ingestion, retrieval, filtering, generation); "supplement
  extraction" is only an ablated intervention, not a named pipeline stage.
  Aligned both documents to the paper's four-stage count.
- N2: 09-wave3-program-plan.md expanded "DCR (Diagnostic Coverage Ratio,
  per the paper)" with no abstract support; now describes DCR only as the
  abstract's own "a graded observability metric," no invented expansion.
- Nit: dropped exact GitHub star counts from ADR-324 (SPADE) and ADR-327
  (Zetta) — they'd already drifted (31→33, 224→227) since the review pass;
  kept size/forks/license/push-date, the non-volatile provenance signals.

Co-Authored-By: claude-flow <ruv@ruv.net>
2026-08-21 10:15:42 -04:00
ruv
73aa6d8a68 docs(adr): regenerate INDEX.md for Wave-3 ADRs 324-327
INDEX.md was stale, still reading "next available: 317" since PR #868
added ADR-317 through ADR-323 without a regeneration. Re-run
node scripts/adr-index.mjs (ADR-316 policy) to index the merged
317-323 range plus this branch's new 324-327; next available is now 328.
CI collision gate (adr-index.mjs --check) passes: 358 files, 27 frozen
historical duplicates, no new unfrozen collisions.

Co-Authored-By: claude-flow <ruv@ruv.net>
2026-08-21 10:04:49 -04:00
ruv
4915587636 docs(adr): add Wave-3 PIR ADRs 324-327 (self-play envs, memory diagnostics, decentralized reasoning, timescale evolution)
Four Wave-3 Perpetual Intelligence Runtime ADRs, Status: Proposed, per
08-wave3-evidence-review.md and 09-wave3-program-plan.md:

- ADR-324: SPADE-pattern (arXiv:2608.19197) self-play environment designer
  for Dream Machine, extending ADR-306/313/321. Adds a REQUIRED hard veto
  in research-gate requiring every generated environment to trace to
  external evidence, generalizing the paper's own ablation finding.
  Flags the severe same-domain "SPADE" name collision with the
  established Smart Python multi-Agent Development Environment framework.
- ADR-325: D²ACCI-pattern (arXiv:2608.17756) stage-level memory diagnostic
  gate, extending ADR-307/320, complementary to (not a duplicate of)
  research-gate's existing outcome-level gate (ADR-282/306).
- ADR-326: DeAR-pattern (arXiv:2608.17282, Grade B+) decentralized
  capability-grounded reasoning over LatentMesh's compressed latent
  state, extending ADR-309/310/311. Marks the dead-end continue-vs-restart
  behavior explicitly as this program's own design choice, not a verified
  paper claim.
- ADR-327: Zetta-pattern (arXiv:2608.16590) three-timescale evolution
  harness, a new bounded context extending ADR-313's frozen-weight
  pattern. Scopes to a synthetic/stubbed environment in
  crates/ruvector-sota-bench/harness and explicitly defers the physical
  actuation target — no ruvnet repo has an actuation surface today.

Every ADR carries the program-wide preprint-reproduction rule (paper
numbers are hypotheses; only this program's own research-gate-measured
delta counts). ADR-324 carries ruv's Wave-3 acceptance test verbatim
(2026-08-20) as an acceptance criterion.

Co-Authored-By: claude-flow <ruv@ruv.net>
2026-08-21 10:04:25 -04:00
rUv
f19babf0e9
Merge pull request #868 from ruvnet/feat/pir-wave2-adrs
docs(adr): Wave-2 ADRs — lifecycle security, state binding, shadow execution (PIR)
2026-08-20 09:09:59 -04:00
ruv
2fb7724eec docs(adr): fix review blockers on Wave-2 ADRs — ADR-134 cites, preprint rule
Addresses the CHANGES-REQUIRED verdict on PR #868:

B1: disambiguate bare "ADR-134" citations per ADR-316's slug rule
    (ADR-318 L44; ADR-323 trust/gates/consequences) -> "ADR-134
    (witness-schema-log-format)", matching merged ADR-312's form.
B2: add the preprint-reproduction rule as a labeled paragraph to
    ADR-319 and ADR-323 (present in the other four; PR body promised
    it in all six).

Non-blocking cleanups folded into the same commit:
- 06: fix stale pointer to 07's now-resolved "Missing input" note;
  add an "as of" timestamp to the #837 comment-count snapshot and
  cross-reference issue #862 as the acceptance test's canonical
  written record.
- 07: correct "TRUSS/Trussed AI" -> "TRUSS/truss-agent.com" (Trussed
  AI is unsourced); fix the four-misattribution-instances enumeration
  to name all four with their real addendum sections (ADR-103 per
  ADR-305 §4; §5; §8b for the phantom "metaharness ADR-251"; §8c),
  dropping §8d which is not itself a wrong-repo-number instance;
  correct the agentdb surface path to crates/rvf/rvf-adapters/agentdb
  (WP18).
- ADR-320: same agentdb path correction in Affected Repos.
- ADR-323: restore the elided "not in the frozen historical list
  above" qualifier in the ADR-316 Decision §5 quote; apply the same
  four-instances and agentdb-adjacent fixes as above.

Co-Authored-By: claude-flow <ruv@ruv.net>
2026-08-20 09:07:41 -04:00
rUv
33ad5d4345
Merge pull request #860 from ruvnet/fix/pir-wp0b-gguf-download
fix(ruvllm-cli): resolve GGUF globs via HF file listing + alias routing (PIR WP0b)
2026-08-20 08:49:42 -04:00
ruv
b3ca3017c1 docs(adr): Wave-2 ADRs — lifecycle security, state binding, shadow execution (PIR)
Adds ADR-317 through ADR-321 and ADR-323 (322 deliberately skipped —
see ADR-323's Numbering note), extending merged ADR-305-315 with six
Aug 18-19 2026 papers per docs/research/perpetual-intelligence-runtime/
06-wave2-evidence-review.md and 07-wave2-program-plan.md:

- ADR-317: HarnessRisk lifecycle security benchmark gate on Darwin
  harness mutations (extends ADR-313, ADR-306)
- ADR-318: StagedWorkspace-pattern content-hash state binding as a
  RuV invariant (extends ADR-307, ADR-312)
- ADR-319: TRUSS-pattern shadow execution for generated capabilities
  (extends ADR-311, ADR-315, ADR-306)
- ADR-320: MemFuse-pattern AtomicObservation + causal episodic graph
  (extends ADR-307, ADR-310)
- ADR-321: SkillForge-pattern synthetic-issue self-training in the
  Darwin loop (extends ADR-313)
- ADR-323: governed pipeline-shard placement for multi-node ruvLLM
  serving (extends ADR-314; 322 skipped to avoid colliding with the
  heavily-cited ruflo ADR-322 series across sibling repos)

Each ADR carries its own evidence grade, artifact-availability check,
and name-collision citation discipline per the evidence review; the
preprint-reproduction rule (every paper is a candidate mutation
requiring an internal benchmark delta before promotion) applies
uniformly. ADR-317 carries ruv's Wave-2 acceptance test verbatim.

Co-Authored-By: claude-flow <ruv@ruv.net>
2026-08-20 08:48:03 -04:00
ruv
19bc919aaa fix(ruvllm-cli): resolve GGUF globs via HF file listing + alias routing (PIR WP0b, #846)
GGUF weight downloads failed two ways (deferred in 946275a61, blocks WP9 #841):

1. get_files_to_download() pushed an unexpanded glob ("*Q4_K_M.gguf") that was
   sent to HF as a literal filename -> 404. Now the repo's actual file list is
   fetched (hf-hub ApiRepo::info(), with a curl fallback against
   GET /api/models/<id>/tree/<rev> in the same HF_TOKEN-honoring idiom as the
   307-redirect fix) and the quant pattern is matched against real filenames.
   Multi-part GGUF (…-q4_k_m-00001-of-00003.gguf) is handled — all parts are
   downloaded in order — because the flagship `qwen` alias (Qwen2.5-14B) only
   ships Q4_K_M as a 3-part split; failing on multi-part would leave the
   primary model unusable. Matching is case-insensitive and accepts per-preset
   spelling variants (f16/fp16). Aux files (tokenizer.json etc.) are filtered
   by the listing, so GGUF-only repos no longer fail on files they don't have.

2. The `phi` alias maps to microsoft/Phi-4-mini-instruct (safetensors-only),
   yet the default q4k quant forced the GGUF path. The registry gains an
   optional gguf_repo twin (bartowski GGUF repos for phi/mistral/llama; all
   verified live against the HF tree API) and resolve_weights_repo() routes
   quantized requests there. chat/serve use the same resolution so the cache
   key matches download's. Repos with no GGUF files and no twin now fail
   early with the repo's actual file inventory and an actionable hint,
   instead of a 404 on a glob.

ADR-259's "Honest gap" is updated: the 307 redirect was fixed 2026-06-18
(946275a61, PR #590); this closes the remaining GGUF gap.

Tests: 11 new unit tests (tree-JSON fixture parsing, multi-part glob
expansion + ordering, uppercase/lowercase naming, fp16 variant, no-GGUF and
missing-quant error listings, aux filtering, alias-routing decisions).
Verified live: `download microsoft/Phi-4-mini-instruct` routes to the twin
and fetches the real 2.5GB Q4_K_M; `download microsoft/phi-2` fails early
listing available files.

Refs #846, #841, ADR-259.

Co-Authored-By: claude-flow <ruv@ruv.net>
2026-08-19 21:52:55 -04:00
ruv
6bc3d1d906 docs(adr): numbering hygiene — freeze duplicates, canonical index + collision check (PIR WP0a)
Verified ground truth on origin/main: 336 ADR files (289 plain-counter,
47 namespaced), 27 duplicated plain numbers spanning 61 files
(ADR-272 x5; ADR-264/252/194/144 x3; 22 numbers x2). Corrects issue
#845's ~15+ estimate and its ADR-040 x3 claim — 040/040a/040b is the
intentional sub-ADR convention, not a collision.

- ADR-316: policy — duplicates are frozen historical artifacts, never
  renamed; cite duplicated numbers as "ADR-NNN (slug)"; new numbers
  come from a single canonical counter whose source of truth is the
  generated index. 316 chosen because 305-315 are claimed on
  feat/pir-adrs (PR #847).
- docs/adr/INDEX.md: generated canonical index with next-available
  number header, per-file title/path/date/status and DUPLICATE flags.
- scripts/adr-index.mjs: regenerates the index; --check exits nonzero
  on any duplicate outside the frozen list (CI gate for #845).

Refs #845, #837

Co-Authored-By: claude-flow <ruv@ruv.net>
2026-08-19 21:49:20 -04:00
ruv
9f11cae541 docs(adr): resolve ADR-150 to ruflo (not unverified), fix signing-domain count
B-3 residual from the re-review: the optionalDependencies policy
METAHARNESS-README.md attributes to an "upstream ADR-150" is not
unresolvable — it's ruflo's own ADR-150
(v3/docs/adr/ADR-150-metaharness-integration-surfaces.md, "MetaHarness
Integration Surfaces in npx ruflo," Status: Implemented, 2026-06-16),
whose rule 2 is verbatim the optionalDependencies policy in question,
and whose rule 4 (a CI job on the --ignore-optional install path) is a
stronger, CI-testable acceptance criterion than a plain npm install
check. Fixed in all five places the review flagged: ADR-313's Related
line and Context, ADR-306's version-drift note, 03-program-plan.md's
WP0b description and its GitHub issue-breakdown body, and the
verification addendum's section 8c — replacing "does not resolve /
unverified" with the confirmed source and citing rule 4 as WP0b's
acceptance criterion. Noted this as the fourth instance of the same
wrong-repo-ADR-number pattern this program keeps catching (ADR-103,
"metaharness ADR-322", "metaharness ADR-251", and now this one).

Also fixes two nits from the same re-review:
- ADR-312's Context and the addendum's section 8d overcounted ruflo
  ADR-322C's signing domains as three; it defines two Ed25519 signing
  domains (flywheel-receipt, flywheel-ledger-head) plus a third,
  non-signing domain-separated prefix that seeds the deterministic
  paired bootstrap's statistics. Corrected in both places, and the
  addendum's "ADR-381 needed two corrections" is relabeled "three"
  to match the (a)/(b)/(c) list that follows it.
- ADR-315 now cites governing invariant 7 (ruflo ADR-322B's
  separation-of-powers rule, adopted in ADR-305) in its Related line,
  Decision, and Security Gates — it was previously named as bound by
  the invariant in ADR-305 and 03-program-plan.md without the
  reciprocal reference.

Co-Authored-By: claude-flow <ruv@ruv.net>
2026-08-19 21:44:09 -04:00
ruv
313543ace3 docs(adr): address PR #847 review — fix cross-repo citations, rescope ADR-315
Fixes three blocking findings and several non-blocking ones from
adr-reviewer's adversarial review of the PIR ADR set, cross-checked
against direct clones of ruvnet/LatentMesh, ruvnet/autogenous,
ruvnet/dream-machine, ruvnet/metaharness, and ruvnet/ruflo:

- B-1: ADR-315 and ADR-305 wrongly treated autogenous ADR-401's
  Better/Safe/Authorized/Reversible promotion predicate as open work.
  ADR-401's Update 1 section 3 marks it DONE upstream
  (mesh-evolve.ts's promoteAuthorized, proven by
  test/promote-authorized.test.ts) — the capability-table row cited
  was stale relative to ADR-401's own Decision section. ADR-315 now
  adopts promoteAuthorized instead of scoping work to close it.
- B-2: "metaharness ADR-251" does not exist (metaharness's ADR series
  tops out at ADR-250; the Nightly Dream Cycle lives in
  docs/dream-cycle/, not an ADR). ADR-306's four citations now point
  at docs/dream-cycle/ and note the bad citation's provenance
  (inherited from dream-machine ADR-0001) instead of restating it as
  fact.
- B-3: "ruvector ADR-150 (optionalDependencies policy)" was a
  misattribution — ruvector's own ADR-150 and metaharness's own
  ADR-150 are both unrelated documents; METAHARNESS-README.md
  attributes the policy to an upstream ADR-150 neither clone
  contains. Every reference (ADR-306, ADR-313, 03-program-plan.md)
  now cites METAHARNESS-README.md's documented invariant directly,
  with the upstream attribution flagged unverified.

Also fixed in the same push:
- ADR-313's WP0b gate: the ruvllm HTTP-307 redirect bug is already
  fixed on main (commit 946275a61, PR #590, 2026-06-18); the real
  remaining blocker is a GGUF glob/alias mismatch in ruvllm-cli's
  get_files_to_download() (download.rs:193, models.rs:65).
- 03-program-plan.md: recorded the 7th governing invariant
  (ruflo ADR-322B's proposer/promotion separation, adopted in
  ADR-305) that was missing from the "six, unchanged" list; reworded
  ADR-list items 0 and 12 as work-package-only entries so the plan's
  promised ADR count (11) matches what shipped.
- ADR-306 now attributes "the machine never merges; a human does" to
  dream-machine's README (verbatim source) rather than claiming it
  verbatim from ADR-0001, whose own section 2.4 phrases the same
  substance differently.
- ADR-306/310/312 replace the ruflo ADR-322/322C citations with
  source-verified detail (three signing domains, evidence-grading
  vocabulary, verbatim 322B quote) now that a full ruflo clone
  confirmed them, and correct ADR-381: it is Proposed, not Accepted,
  and its own contribution is stream-identity/budget-epoch-reset
  governance — the 0.6% false-promotion figure and the alpha_k
  allocation belong to ruflo PR #2956's mechanism, which ADR-381
  governs. Every family-wise bound is now stated per-epoch, not
  globally, per ADR-381's own text.
- ADR-305 adds a standing fix-history verification rule: an inherited
  "known bug/gap/not-yet-implemented" claim must be checked against
  the named path's actual fix history before being repeated in a PIR
  ADR — the root cause shared by all three blocking findings above.

docs/research/perpetual-intelligence-runtime/04-verification-addendum.md
records the full correction trail (new section 8) without editing
02-asset-map.md or 03-program-plan.md's prior content in place.

Co-Authored-By: claude-flow <ruv@ruv.net>
2026-08-19 21:32:58 -04:00
ruv
357d4dc303 docs(adr): add Perpetual Intelligence Runtime ADRs (PIR program)
Adds ADR-305 through ADR-315, the eleven architecture decisions for the
Perpetual Intelligence Runtime program: adopting LatentMesh ADR-009 and
autogenous ADR-401 as the program's control-loop spine and definition of
record; adopting the ruvnet/dream-machine evaluation engine wired to
ruvector's research-gate/sota-bench statistics and Darwin; three-level
persistent memory (LiveMem + TARL); WorldCycle-style physical-action
verification; greenfield LatentMesh transport/RVF/RVM crates coordinated
on wire format; a causal-attribution CI gate; net-new anomaly quarantine
(explicitly not "LATTE", which is not a real paper); a shared witness
record schema and cross-layer anchoring contract anchored on ruflo
ADR-322C rather than merging the rvm-witness and autogenous witness
crates; the SHAPER-pattern frozen-weight skill/harness evolution loop;
KV-cache cross-model migration in ruvLLM; and a governance constitution
for capability expansion built on autogenous's admission-gate pattern.

All ADRs are numbered above the repo's true existing maximum (ADR-304,
confirmed by scanning every filename in docs/adr/ rather than assuming
uniqueness, since duplicate numbers exist elsewhere in the sequence) and
cite only sources verified against primary text in
docs/research/perpetual-intelligence-runtime/.

Co-Authored-By: claude-flow <ruv@ruv.net>
2026-08-19 21:11:51 -04:00
rUv
1563982a6d
Merge pull request #824 from ruvnet/claude/focused-darwin-3krfwp
feat: retrieval receipts — witness-chained provenance for ANN results (nightly 2026-08-13)
2026-08-13 11:12:25 -04:00
ruv
fcf0595eef fix(ruvector-retrieval-receipt): correct provenance claims, harden verification per review
Doc corrections (merge gate for PR #824):
- State the actual threat model everywhere: receipts detect post-issuance
  mutation of a receipt/result pair; they do NOT protect against a
  dishonest query engine and do NOT prove write-chain membership. Leaves
  commit to COPIES of WriteReceipt fields and verification never consults
  the write gate, so a mutated ingestion history leaves already-issued
  receipts verifying. Named future work: bind leaves to MerkleGate's MMR
  membership proofs (HashChainGate::verify_receipt needs the live chain;
  no offline membership proof exists).
- Soften "verifiable offline without trusting the query engine" to match
  reality (unsigned, engine-chosen leaves).
- Relabel the 2x/2.1x benchmark comparison: PerResultReceipt proof size
  is defined as genesis-anchored replay O(idx); a head-anchored verifier
  needs only the O(k-idx) suffix, so the durable claim is asymptotic
  O(log k) vs O(k), not the constant. Reframe 200/200 tamper detection
  as a SHA-256 regression check, not an empirical rate (incl. ADR-304
  Rejection Criteria).
- Reword ADR-304 Evidence line citing
  index_state_root_changes_receipts_across_reingestion (that test
  compares roots only; it builds no receipt).
- Applications table: legal/medical row no longer marketed as
  chain-of-custody.

Code fixes:
- verify_full now fails closed on empty result sets (was vacuously true);
  documented + tested for all variants.
- RetrievalIndex::search uses total_cmp instead of
  partial_cmp().unwrap() (NaN no longer panics a public API).
- gate_variant is bound into each result leaf so a NullGate receipt
  (all-zero commitment) is distinguishable from a gated one; tested.

Tests: 14 passed (was 12). Clippy -D warnings and fmt clean.

Co-Authored-By: claude-flow <ruv@ruv.net>
2026-08-13 11:11:59 -04:00
ruv
ce638244b8 fix(ruvector-entropy-ann): reframe as measured negative result, fix benchmark methodology
Review (measured, with rebuilt crate) found the PoC's headline claim does not
hold: EntropyScaledEf computes ef_actual=122-124 for every query — no per-query
adaptivity — and FixedEf(124) reproduces its recall to four decimal places on
all three query sets. The reported +1.6-3.9pp recall gain was entirely the
2.5x larger ef budget, not entropy. Entropy separation between easy and hard
queries is negative at every usable temperature (softmin entropy over
retrieved-neighbour distances tracks local density, wrong sign for beam
control); T=0.1 is effectively infinite temperature on this data.

Fixes applied:
- graph.rs: add FlatGraph::is_empty() (clippy len_without_is_empty CI blocker),
  use it in find_entry
- benchmark.rs: move ground_truth() out of the timed closure (it was ~41% of
  reported time, hiding a real ~50% search-only latency regression); add
  FixedEf(124, matched) control rows so the adaptive claim is falsifiable
- lib.rs: recall_at_k denominator is now min(k, |ground_truth|) only — no
  longer shrinks with |results|, which rewarded early termination
- search.rs: fix doc/code mismatch (scale uses ln(|results|), docs said ln(k));
  document measured outcomes on both entropy variants
- tests: graph_is_symmetric_on_uniform now asserts the reciprocity fraction it
  computes; renamed entropy_threshold_exits_early_on_easy_query and
  entropy_scaled_ef_expands_for_hard_queries to match what they actually test
- ADR-303: status now 'Closed — negative result'; removed 'recommended' and
  'validated in the PoC benchmark' for Strategy B and the false 'same nominal
  ef budget' claim; documented the matched-budget equivalence and wrong-sign
  finding; marked the multi-layer-HNSW rescue as untested conjecture
- research README + gist: results regenerated with honest search-only timing
  (FixedEf(50) ~33us vs EntropyScaledEf ~50us) and matched-budget comparison

cargo test / clippy -D warnings / fmt --check all pass.

Co-Authored-By: claude-flow <ruv@ruv.net>
2026-08-13 11:11:26 -04:00
Claude
af68ab14cb
docs: add ADR-304 for retrieval receipts
Documents the hypothesis, evidence, alternatives considered, and
rejection criteria for promoting retrieval receipts beyond the
experimental crate, including the disclosed Merkle padding
malleability limitation.
2026-08-13 14:42:33 +00:00
Claude
9974deb9b8
feat(ruvector-entropy-ann): entropy-adaptive ANN beam search PoC
Implements Shannon entropy of the candidate-heap distance distribution as
a live beam-width gate for ANN graph traversal — a novel application of
EDEN's entropy-based branching (ICML 2026) to HNSW-style search.

Three variants (FixedEf baseline, EntropyThresholdBeam, EntropyScaledEf)
benchmarked on 16D clustered synthetic data (N=2000, k=10, ef=50).
EntropyScaledEf achieves +1.6–3.9 pp recall@10 vs FixedEf at equal ef.

- 15 unit tests, all pass
- Zero external dependencies
- Real benchmark numbers, no mocks or placeholder values
- ADR-303 and research README included

Co-Authored-By: claude-flow <ruv@ruv.net>
Claude-Session: https://claude.ai/code/session_018DMsyZzgWJ1pWw3svjfAAG
2026-08-13 07:53:28 +00:00
ruv
31bb944015 fix: integrate latest PRs and issue regressions 2026-08-12 10:37:32 -04:00
Claude
e6b4fc79dd
feat(turbo4): RaBitQ-style length renormalization from verified SOTA research
Deep-research pass over primary sources (TurboQuant arXiv:2504.19874,
Qdrant 1.18 quantization docs/blog, RaBitQ SIGMOD 2024 + extended RaBitQ
arXiv:2409.09913, RaBitQ rebuttal arXiv:2604.19528) — findings recorded in
ADR-296 "Refinements from verified research":

- Lloyd-Max reconstructions are systematically short (||r|| = a*sqrt(S) <
  a*sqrt(D)), biasing inner-product estimates — the bias TurboQuant fixes
  with QJL and Qdrant fixes with RaBitQ renormalization. All three scoring
  tiers now scale the level dot by sqrt(D/S) per encoded side and use exact
  norms a^2*D — zero storage cost since a, S, D are already in the blob.
- New estimator-bias gate: mean signed relative L2 error across pairs must
  stay under 1%.
- Kernel roadmap (maddubs/VPDPBUSD with u8-biased level table) and the
  RaBitQ-cascade reinforcement documented for ADR-297 phases C/G.
- Stabilize adaptive-policy test: allow the hnsw_rs graph-construction
  nondeterminism noise band when comparing separately built indexes.

Co-Authored-By: claude-flow <ruv@ruv.net>
Claude-Session: https://claude.ai/code/session_01XFWB9PKwsZYk5FbjBRY6mk
2026-08-06 02:34:03 +00:00
Claude
4cdc1be09e
feat(acrp): adaptive compression & retrieval plane — unified codec interface, search policies, adaptive escalation (ADR-297)
ADR-297 lays out the plane: one EncodedVector interface for every
representation, storage/search precision separation, per-query automatic
precision selection, memory tiers, topology-aware bit allocation, drift
detection, provenance, honest benchmarking, and a three-policy product
surface — gated by an ablation acceptance test (adaptive must beat uniform
Turbo4 by >= 30% memory at <= 0.5pp recall loss and <= 10% P95).

Phase B lands here:

- ruvector-core::encoding — CodecKind + VectorCodec/EncodedQuery traits;
  Fp32, Fp16 (in-crate RNE binary16, no half dep), Int8, and Turbo4 plane
  codecs; codec_for() registry; VectorProvenance schema (model id, codec
  version, rotation seed, source hash, migration lineage).
  ruvector-turboquant is now an unconditional core dependency (dep-free,
  WASM-safe) so the codec plane exists on every build.
- SearchPolicy { Quality, Balanced, MaxCompression } on
  QuantizationConfig::Turbo4 — users pick an outcome, not an algorithm.
- Turbo4HnswIndex adaptive escalation: relative kept/dropped score margin
  triggers widened re-search (2-3x ef, 2x rescore pool), stopping when
  top-k membership stabilizes; MaxCompression never escalates; telemetry
  via adaptive_stats() targets a 5-15% escalation budget.
- clippy --all-targets clean for both crates (fixes CI identity_op).

Co-Authored-By: claude-flow <ruv@ruv.net>
Claude-Session: https://claude.ai/code/session_01XFWB9PKwsZYk5FbjBRY6mk
2026-08-06 01:54:45 +00:00
Claude
3290e24c5e
feat(turbo4): Turbo4 4-bit quantized vector datatype with direct packed HNSW scoring (ADR-296)
Adds crates/ruvector-turboquant — a dependency-free, WASM-safe Turbo4 codec:
- deterministic randomized rotation (sign/permute/block-FWHT rounds over an
  in-crate SplitMix64; bit-stable across platforms, no zero-padding, so codes
  stay exactly ceil(D/2) bytes for any even D)
- precomputed 16-level Lloyd-Max tables (N(0,1), Max 1960) with per-vector
  standardization alpha = ||v||/sqrt(D)
- packed nibble codes (D/2 + 8 bytes; ~7.9x vs f32 at 1536-D) — the original
  float vector is never stored
- three scoring tiers, no reconstruction: symmetric code x code (graph
  construction), asymmetric int8-query x code (traversal), exact f32 rescore
  (final ranking); AVX2 kernels runtime-dispatched and tested bit-exact
  against the scalar oracle

Wires it into ruvector-core (closes the Turbo4 slice of issue #563 —
quantization that is actually applied):
- QuantizationConfig::Turbo4 { rotation_seed, rescore_multiplier }
- Turbo4HnswIndex: hnsw_rs instantiated over u8 packed code blobs; query and
  code blobs are structurally disjoint by length, so one Distance functor
  gives symmetric construction + asymmetric traversal, then exact rescoring
  of k * rescore_multiplier candidates
- VectorDB::new builds the quantized index when Turbo4 + HNSW are configured;
  legacy variants keep the not-applied warning
- recall gate: <= 2pp loss vs the f32 HNSW baseline on clustered data, floor
  0.75 on the iid-Gaussian concentration worst case

Co-Authored-By: claude-flow <ruv@ruv.net>
Claude-Session: https://claude.ai/code/session_01XFWB9PKwsZYk5FbjBRY6mk
2026-08-06 01:42:28 +00:00
rUv
cbf9f6d7b6
feat: rvForge — one canonical RVF to signed platform installers (ADRs 283-293) (#790)
* chore: gitignore Hailo venvs, .ruvnet-brain scratch dirs, coverage output

Co-Authored-By: claude-flow <ruv@ruv.net>
Claude-Session: https://claude.ai/code/session_01ParP55bZs2iTGEGvpnUecx

* docs: rvForge ADRs 283-293 + canonical requirements (ADR-283 master, RVM integration 284-293)

One canonical RVF to signed platform installers: @ruvector/forge CLI,
hosted build service, Tauri RVF Reader, rvm-* backend crates. Derived
from the rvForge product directive; requirements.md is the source of
truth for the feat/rvf-forge build-out.

Co-Authored-By: claude-flow <ruv@ruv.net>
Claude-Session: https://claude.ai/code/session_01ParP55bZs2iTGEGvpnUecx

* docs: RVForge platform spec (Store/Reader/Publisher/Registry/Enterprise) + naming

Adopt RVForge capitalization; publisher CLI is @ruvector/rvforge.
Adds marketplace objects, trust levels, review pipeline, security/
countersigning model, licensing, enterprise governance, and platform
acceptance test to the canonical requirements. Seeds loop-state.md for
the overnight build loop.

Co-Authored-By: claude-flow <ruv@ruv.net>
Claude-Session: https://claude.ai/code/session_01ParP55bZs2iTGEGvpnUecx

* docs: ADR-294 — RVForge platform (store, registry, trust system)

Five products (Store/Reader/Publisher/Registry/Enterprise), immutable
predecessor-linked releases, four trust levels, review pipeline,
countersigning + revocation semantics, licensing, enterprise override.
Documents the @ruvector/rvforge naming supersession.

Co-Authored-By: claude-flow <ruv@ruv.net>
Claude-Session: https://claude.ai/code/session_01ParP55bZs2iTGEGvpnUecx

* chore: loop-state iteration 2 — forge-core crate agent spawned

Co-Authored-By: claude-flow <ruv@ruv.net>
Claude-Session: https://claude.ai/code/session_01ParP55bZs2iTGEGvpnUecx

* docs: RVForge registry data model v0.1 (content-addressed, predecessor-linked)

Wire-format contract for publisher CLI, Reader, and registry: canonical
JSON identity rules, Release/PublisherRecord/CapabilityManifest/
WitnessReceipt/Revocation/TransparencyLogEntry objects, local storage
layout. Revocation blocks execution, never deletes local RVFs (ADR-294).

Co-Authored-By: claude-flow <ruv@ruv.net>
Claude-Session: https://claude.ai/code/session_01ParP55bZs2iTGEGvpnUecx

* ci: RVForge 3-OS build matrix for CLI package and rvf-forge-core crate

Path-filtered workflow: npm install/build/test for the CLI on
ubuntu/windows/macos, cargo test + clippy -D warnings + fmt check for
the crate. Tolerates the pending forge->rvforge package rename and
skips gracefully while directories are still landing.

Co-Authored-By: claude-flow <ruv@ruv.net>
Claude-Session: https://claude.ai/code/session_01ParP55bZs2iTGEGvpnUecx

* docs: ADR-291 compatibility matrix v1; reader scaffold in flight

Machine-readable runtime-profile/packaging/output matrix the CLI vendors;
wasm and os-isolation+wasm supported, microvm and rvm-native planned with
explicit isolation claims per ADR-285.

Co-Authored-By: claude-flow <ruv@ruv.net>
Claude-Session: https://claude.ai/code/session_01ParP55bZs2iTGEGvpnUecx

* feat(rvforge): @ruvector/rvforge CLI — validate/build/verify with local RVF inspection

Publisher/build CLI per ADR-283 §4: init, validate (local, inspection-
only, never executes RVF content), build (local mode: canonical build
manifest + staged bundle + checksums + provenance), submit/status/
download (hosted API client, FORGE_API_URL), verify (checksum + prove-
nance recheck). Stable FORGE_E_* error codes, --json unattended mode,
73 jest tests green across 5 suites with synthetic RVF fixture.

Co-Authored-By: claude-flow <ruv@ruv.net>
Claude-Session: https://claude.ai/code/session_01ParP55bZs2iTGEGvpnUecx

* chore: loop-state — CLI step 1 complete

Co-Authored-By: claude-flow <ruv@ruv.net>
Claude-Session: https://claude.ai/code/session_01ParP55bZs2iTGEGvpnUecx

* ci: install rvforge CLI standalone (--workspaces=false)

Plain npm install inside npm/packages/rvforge resolves the parent npm
workspace and fails EBADPLATFORM on platform-pinned siblings
(router-darwin-arm64 on linux runners). Verified clean install + 73
tests green locally with the flag.

Co-Authored-By: claude-flow <ruv@ruv.net>
Claude-Session: https://claude.ai/code/session_01ParP55bZs2iTGEGvpnUecx

* chore: loop-state iteration 6

Co-Authored-By: claude-flow <ruv@ruv.net>
Claude-Session: https://claude.ai/code/session_01ParP55bZs2iTGEGvpnUecx

* feat(rvf-forge-core): inspection-only RVF packaging/verification crate

Per ADR-283/290/291: container inspection without execution, Ed25519
root-manifest + per-segment hash verification with unsigned-executable-
segment rejection, deterministic canonical build manifest (ADR-291
contract fields), provenance records, SHA256 checksum manifests, stable
wire error codes mirroring the CLI. 103 unit tests + integration
pipeline test, clippy -D warnings and fmt clean.

Co-Authored-By: claude-flow <ruv@ruv.net>
Claude-Session: https://claude.ai/code/session_01ParP55bZs2iTGEGvpnUecx

* chore: loop-state — core crate step 2 complete

Co-Authored-By: claude-flow <ruv@ruv.net>
Claude-Session: https://claude.ai/code/session_01ParP55bZs2iTGEGvpnUecx

* chore: loop-state iteration 7 — packaging+witness agent spawned

Co-Authored-By: claude-flow <ruv@ruv.net>
Claude-Session: https://claude.ai/code/session_01ParP55bZs2iTGEGvpnUecx

* docs: RVForge Agent Dock spec (D1-D8) — security/control surface

Collapsed pill + expanded trust view, 8 agent states, RVForge-owned
chrome vs agent content separation (spoofing defense), per-platform
placement, capability card, event-threshold noise control, 5s/2-action
termination acceptance test. ADR-295 in flight; dock implementation
queued behind reader scaffold in loop plan.

Co-Authored-By: claude-flow <ruv@ruv.net>
Claude-Session: https://claude.ai/code/session_01ParP55bZs2iTGEGvpnUecx

* chore: loop-state — scope widened to full ADR-283..295 implementation

Co-Authored-By: claude-flow <ruv@ruv.net>
Claude-Session: https://claude.ai/code/session_01ParP55bZs2iTGEGvpnUecx

* feat(rvforge-reader): Tauri v2 Reader scaffold + ADR-295 Agent Dock spec

Reader (standalone workspace, excluded from root): verify/capability-
card/runtime screens as framework-free static UI, runtime selection
implementing the FR004 ladder from the vendored compatibility matrix,
P6 capability contract rendering with vague-scope rejection, ADR-288
state-capsule layout (encryption stubbed, marked), inspect stubbed
pending rvf-forge-core FFI. 39 tests green, cargo check clean, parent
workspace unaffected. ADR-295: dock chrome RVForge-owned, agent content
strictly separated.

Co-Authored-By: claude-flow <ruv@ruv.net>
Claude-Session: https://claude.ai/code/session_01ParP55bZs2iTGEGvpnUecx

* chore: loop-state — reader scaffold + ADR-295 landed

Co-Authored-By: claude-flow <ruv@ruv.net>
Claude-Session: https://claude.ai/code/session_01ParP55bZs2iTGEGvpnUecx

* chore: loop-state iteration 10 — dock-impl spawned

Co-Authored-By: claude-flow <ruv@ruv.net>
Claude-Session: https://claude.ai/code/session_01ParP55bZs2iTGEGvpnUecx

* chore: loop-state iteration 11

Co-Authored-By: claude-flow <ruv@ruv.net>
Claude-Session: https://claude.ai/code/session_01ParP55bZs2iTGEGvpnUecx

* feat(rvforge): embedded/thin packaging, compat enforcement, inventory, witness chains

FR001/FR002: embedded mode with cross-target identical-RVF-hash
invariant (build fails on divergence), thin-mode signed locators with
round-trip verification. ADR-291 compat-matrix enforcement with
closest-supported suggestions. Deterministic software inventory (§3.9).
Hash-chained witness receipts (receipts.jsonl) on build/verify with
broken-chain detection. 137 jest tests green across 9 suites.

Co-Authored-By: claude-flow <ruv@ruv.net>
Claude-Session: https://claude.ai/code/session_01ParP55bZs2iTGEGvpnUecx

* chore: loop-state — steps 6+7 CLI side complete

Co-Authored-By: claude-flow <ruv@ruv.net>
Claude-Session: https://claude.ai/code/session_01ParP55bZs2iTGEGvpnUecx

* chore: loop-state iteration 13 — publisher-verbs spawned

Co-Authored-By: claude-flow <ruv@ruv.net>
Claude-Session: https://claude.ai/code/session_01ParP55bZs2iTGEGvpnUecx

* chore: loop-state iteration 14

Co-Authored-By: claude-flow <ruv@ruv.net>
Claude-Session: https://claude.ai/code/session_01ParP55bZs2iTGEGvpnUecx

* feat(rvforge-registry): content-addressed local registry with transparency log

ADR-294 MVP: canonical-JSON content addressing (id excludes signatures),
typed registry objects, ed25519 release-publish rules (bad-sig/revoked-
key/lineage violations typed), trust levels raisable only by registry
signature, non-destructive revocation (blocks execution, reads preserved
— tested), Merkle transparency log with inclusion proofs + tamper
detection, witness receipt chains on publish/revoke/verify. Reuses
rvf-forge-core canonical/error patterns. 67 tests, clippy+fmt clean.

Co-Authored-By: claude-flow <ruv@ruv.net>
Claude-Session: https://claude.ai/code/session_01ParP55bZs2iTGEGvpnUecx

* chore: loop-state — registry crate landed (P2-impl, P4)

Co-Authored-By: claude-flow <ruv@ruv.net>
Claude-Session: https://claude.ai/code/session_01ParP55bZs2iTGEGvpnUecx

* feat(rvforge-reader): ADR-295 Agent Dock — typed trust boundary, states, roster

Trust boundary enforced structurally: AgentProvidedStatus (sanitized
task text + progress only) composed separately from SystemOwnedStatus
(state, trust badge, network, permissions, witness, cost) — agent input
cannot reach system fields by construction. Sanitizer strips ANSI/
control chars, caps length, flags system-label mimicry as suspicious.
8-state machine (pause/terminate always one action; quarantine/
capability-denied not agent-exitable), attention-priority roster
(approval > denial > error > running), D8 event thresholds, pill +
expanded UI with visually distinct system chrome. 90 reader tests green.

Co-Authored-By: claude-flow <ruv@ruv.net>
Claude-Session: https://claude.ai/code/session_01ParP55bZs2iTGEGvpnUecx

* chore: loop-state — Agent Dock implemented (P5)

Co-Authored-By: claude-flow <ruv@ruv.net>
Claude-Session: https://claude.ai/code/session_01ParP55bZs2iTGEGvpnUecx

* docs: ADR status updates — 291/295 Implemented, 283/294 Accepted-in-progress

Living-plans sync: statuses now reflect what is actually on the branch,
with Updated notes naming landed scope and remaining gaps.

Co-Authored-By: claude-flow <ruv@ruv.net>
Claude-Session: https://claude.ai/code/session_01ParP55bZs2iTGEGvpnUecx

* chore: loop-state iteration 17

Co-Authored-By: claude-flow <ruv@ruv.net>
Claude-Session: https://claude.ai/code/session_01ParP55bZs2iTGEGvpnUecx

* ci: cover rvforge-registry and rvforge-reader in the RVForge matrix

Registry tests/clippy/fmt ride the existing core job; the reader gets
its own 3-OS job run inside its standalone workspace directory.

Co-Authored-By: claude-flow <ruv@ruv.net>
Claude-Session: https://claude.ai/code/session_01ParP55bZs2iTGEGvpnUecx

* chore: loop-state iteration 18

Co-Authored-By: claude-flow <ruv@ruv.net>
Claude-Session: https://claude.ai/code/session_01ParP55bZs2iTGEGvpnUecx

* docs: acceptance traceability matrix — merge gate for PR #790

Maps every §15/platform/dock criterion to automated evidence or a named
DEFERRED blocker (clean-OS installs, notarization, cross-repo rvm
runtime). Merge gates on green AUTOMATED rows across 3 OSes.

Co-Authored-By: claude-flow <ruv@ruv.net>
Claude-Session: https://claude.ai/code/session_01ParP55bZs2iTGEGvpnUecx

* chore: loop-state iteration 19

Co-Authored-By: claude-flow <ruv@ruv.net>
Claude-Session: https://claude.ai/code/session_01ParP55bZs2iTGEGvpnUecx

* feat(rvforge): publisher verbs pack/test/publish with local registry

pack: P4 validation (structure, capability specificity with ADR-294
manual-review-trigger flagging, compat, inventory, license), draft
Release + CapabilityManifest objects. test: inspection-only subset of
the 10 P4 categories with honest 'skipped: requires quarantined runtime'
for execution-dependent ones; tampered variants rejected. publish:
ed25519-signed content-addressed writes to the registry-model layout
(predecessor lineage, transparency log, witness receipt); keygen via
node:crypto; key files never logged, world-readable keys refused.
220 jest tests green across 13 suites.

Co-Authored-By: claude-flow <ruv@ruv.net>
Claude-Session: https://claude.ai/code/session_01ParP55bZs2iTGEGvpnUecx

* chore: loop-state — publisher verbs landed (P1)

Co-Authored-By: claude-flow <ruv@ruv.net>
Claude-Session: https://claude.ai/code/session_01ParP55bZs2iTGEGvpnUecx

* chore: loop-state iteration 21 — parity-check spawned

Co-Authored-By: claude-flow <ruv@ruv.net>
Claude-Session: https://claude.ai/code/session_01ParP55bZs2iTGEGvpnUecx

* feat(rvforge-reader): real rvf-forge-core verification + encrypted state capsules

Inspect/verify now call rvf-forge-core (inspection-only, verification
before any load, witness record per verification appended to the state
dir per ADR-284 req 9); capability card derives from real declared
capabilities and refuses to render unverified; state capsules encrypted
(ChaCha20-Poly1305, per-install key, 0600 perms) with base-RVF lineage
binding and mismatch rejection per ADR-288. 113 reader tests green.

Co-Authored-By: claude-flow <ruv@ruv.net>
Claude-Session: https://claude.ai/code/session_01ParP55bZs2iTGEGvpnUecx

* chore: loop-state — reader FFI landed

Co-Authored-By: claude-flow <ruv@ruv.net>
Claude-Session: https://claude.ai/code/session_01ParP55bZs2iTGEGvpnUecx

* docs: ADR 284-293 status sync against landed implementation

284/285/286/288/289 -> Accepted with precise landed-scope notes;
287/290/292/293 stay Proposed with honest gap notes (hosted service,
rvm runtime — cross-repo). Living-plans discipline: every status now
matches the code on this branch.

Co-Authored-By: claude-flow <ruv@ruv.net>
Claude-Session: https://claude.ai/code/session_01ParP55bZs2iTGEGvpnUecx

* chore: loop-state iteration 23

Co-Authored-By: claude-flow <ruv@ruv.net>
Claude-Session: https://claude.ai/code/session_01ParP55bZs2iTGEGvpnUecx

* chore: loop-state iteration 24 — parity in progress, CI 7 green / 0 red

Co-Authored-By: claude-flow <ruv@ruv.net>
Claude-Session: https://claude.ai/code/session_01ParP55bZs2iTGEGvpnUecx

* chore: loop-state iteration 25 — witness-viewer spawned

Co-Authored-By: claude-flow <ruv@ruv.net>
Claude-Session: https://claude.ai/code/session_01ParP55bZs2iTGEGvpnUecx

* feat(rvforge): CLI<->Rust registry parity — proven interoperable

rvforge-registry-check binary validates any registry dir (content
addresses, release rules, lineage, log inclusion, witness chains);
scripts/rvforge-parity-check.sh publishes two lineage-linked releases
through the real CLI and validates with the Rust crate — PARITY OK.
CLI canonical-JSON/id divergences fixed on the CLI side per contract.
CI parity job added (ubuntu). Registry 92 tests, CLI suites green.

Co-Authored-By: claude-flow <ruv@ruv.net>
Claude-Session: https://claude.ai/code/session_01ParP55bZs2iTGEGvpnUecx

* chore: loop-state — parity landed, PARITY OK

Co-Authored-By: claude-flow <ruv@ruv.net>
Claude-Session: https://claude.ai/code/session_01ParP55bZs2iTGEGvpnUecx

* chore(rvforge): prepublishOnly gate (build+test) before any npm publish

Co-Authored-By: claude-flow <ruv@ruv.net>
Claude-Session: https://claude.ai/code/session_01ParP55bZs2iTGEGvpnUecx

* chore: loop-state iteration 27

Co-Authored-By: claude-flow <ruv@ruv.net>
Claude-Session: https://claude.ai/code/session_01ParP55bZs2iTGEGvpnUecx

* chore: loop-state iteration 28 — acceptance snapshot green, CI 6/0/48

Co-Authored-By: claude-flow <ruv@ruv.net>
Claude-Session: https://claude.ai/code/session_01ParP55bZs2iTGEGvpnUecx

* feat(rvforge-reader): witness viewer — hash-chain verification screen + dock wiring

P15.11: loads reader/CLI receipts.jsonl, verifies per-subject content-id
+ prevReceipt continuity, renders chronological chains with exact
broken-at-N indicators; dock witness-status element now reflects real
chain state. Entirely system-owned chrome (ADR-295). Tamper/reorder/
empty cases tested. 133 reader tests green.

Co-Authored-By: claude-flow <ruv@ruv.net>
Claude-Session: https://claude.ai/code/session_01ParP55bZs2iTGEGvpnUecx

* chore: loop-state — witness viewer landed; all workstreams complete

Co-Authored-By: claude-flow <ruv@ruv.net>
Claude-Session: https://claude.ai/code/session_01ParP55bZs2iTGEGvpnUecx

* chore: loop-state iteration 30 — awaiting full-green CI (0 failures)

Co-Authored-By: claude-flow <ruv@ruv.net>
Claude-Session: https://claude.ai/code/session_01ParP55bZs2iTGEGvpnUecx

* chore: loop-state iteration 31 — CI 12/42/0

Co-Authored-By: claude-flow <ruv@ruv.net>
Claude-Session: https://claude.ai/code/session_01ParP55bZs2iTGEGvpnUecx

* chore: loop-state iteration 32 — CI 31/23/0, parity green in CI

Co-Authored-By: claude-flow <ruv@ruv.net>
Claude-Session: https://claude.ai/code/session_01ParP55bZs2iTGEGvpnUecx

* chore: loop-state iteration 33 — CI 29/25/0

Co-Authored-By: claude-flow <ruv@ruv.net>
Claude-Session: https://claude.ai/code/session_01ParP55bZs2iTGEGvpnUecx

* fix(rvf-forge-core): classify rooted paths uniformly across platforms

Windows CI failure: '/etc/hostname' has a root but no drive prefix, so
is_absolute() is false on Windows and the path took the relative branch
with a different rejection message than the test (and Linux) expected.
Branch on has_root() instead — any rooted path goes through the
containment check on every platform. Refusal behavior unchanged; only
classification is now uniform. Linux gate re-verified: 117 tests,
clippy, fmt green.

Co-Authored-By: claude-flow <ruv@ruv.net>
Claude-Session: https://claude.ai/code/session_01ParP55bZs2iTGEGvpnUecx

* chore: loop-state iteration 34 — windows path-classification fix pushed

Co-Authored-By: claude-flow <ruv@ruv.net>
Claude-Session: https://claude.ai/code/session_01ParP55bZs2iTGEGvpnUecx

* chore: loop-state iteration 35 — post-fix CI clean, re-running

Co-Authored-By: claude-flow <ruv@ruv.net>
Claude-Session: https://claude.ai/code/session_01ParP55bZs2iTGEGvpnUecx

* chore: loop-state iteration 36 — CI 32/22/0, fix verified

Co-Authored-By: claude-flow <ruv@ruv.net>
Claude-Session: https://claude.ai/code/session_01ParP55bZs2iTGEGvpnUecx

* chore: loop-state iteration 37 — CI 33/21/0

Co-Authored-By: claude-flow <ruv@ruv.net>
Claude-Session: https://claude.ai/code/session_01ParP55bZs2iTGEGvpnUecx

* chore: loop-state iteration 38 — CI 32/22/0

Co-Authored-By: claude-flow <ruv@ruv.net>
Claude-Session: https://claude.ai/code/session_01ParP55bZs2iTGEGvpnUecx

* chore: loop-state — final verdict, proceeding to merge on documented basis

Co-Authored-By: claude-flow <ruv@ruv.net>
Claude-Session: https://claude.ai/code/session_01ParP55bZs2iTGEGvpnUecx
2026-08-04 08:13:26 -03:00
rUv
a2326c0449
feat: ADR-280/281/282 — durable RVF metadata, role-aware embeddings, nightly research quality gate (#774)
Three ADRs implemented and hardened across five rounds of adversarial review, plus the fixes that review surfaced.

**ADR-280 — durable RVF metadata.** Delta-encoded generations with a snapshot every 32. The first implementation wrote a full snapshot per commit and replayed every one at open: 600 commits produced a 725 MiB file that could no longer be opened, with no repair path. Now 241 KB of META payload for the same workload, opening in ~4 ms. Review also closed: derive-children that could not be reopened, an 80-byte file driving a 512 MiB allocation, delete() rollback leaving in-memory tombstones that bricked the artifact, ten BufWriter sites discarding flush errors before sync_all, corrupt mid-chain deltas made unopenable (now recovers the longest valid prefix), and an ordering bug where recovery pruning committed without its re-anchoring snapshot so `rvf ingest` printed a repair warning and then destroyed the file.

**ADR-281 — role-aware embeddings.** Query/passage routing with an attested embedding-space identity. Review found the space id hashed CARGO_PKG_VERSION, so a routine version bump would have rejected every persisted corpus and invalidated every cache key — with the test suite structurally blind to it. Now keyed on a dedicated format revision with a golden-id test. Also: three constructors that failed unconditionally with ten unmigrated callers, prompt templates applied from the attested identity rather than hardcoded strings, and ApiEmbedding no longer bypassing templating.

**ADR-282 — nightly research quality gate.** Review found the gate had never completed a single run: the candidate checkout was shallow so its git diff always failed, and a jq quoting bug made the override path dead code. Check-run queries were unpaginated — on a real main commit 8 of 22 failures were invisible, so a red base could be certified green. Schemas are now load-bearing with a hashed dependency closure.

**CI note.** The two red checks are both pre-existing on main, not regressions from this branch: `Tests (core-and-rest)` routinely exceeds its 4-hour window, and `Hooks CI` has failed on main since 2026-08-02 (and in May) on `cp -r node_modules $GITHUB_WORKSPACE/npm/packages/cli/` in hooks-ci.yml — this branch's one-line version sync merely re-triggered its path filter. 72 checks pass.

Follow-ups filed and not blocking: #770, #771, #772.

🤖 Generated with [claude-flow](https://github.com/ruvnet/claude-flow)
2026-08-03 14:13:37 -03:00
rUv
0efdbebf56
feat(rvagent): Hermes-class harness architecture — research, ADRs 273-279, harness repair + review fixes (#752)
Research docs + target architecture for rvagent as a Hermes-class harness (metaharness + ruflo integration), ADRs 273-279, rvAgent harness repair (tool schemas wired, middleware pipeline, subagents, bootstrap, policy genome), PDX vertical-layout benchmark (not adopted), plus full adversarial code-review fix round: symlink/hard-link write-escape confinement in local tools, real HITL gating in both pipeline construction paths, Gemini parallel-tool-call and schema-compatibility fixes, panic/deadlock hardening.

CI note: Tests (vector-index) failure is the pre-existing flaky ruvector-diskann recall_trigger_holds_under_no_drift probabilistic test (untouched crate; passes 3/3 locally on this head, passed on prior run). Tests (core-and-rest) historically exceeds its window and was not required.

🤖 Generated with [claude-flow](https://github.com/ruvnet/claude-flow)
2026-08-02 12:39:59 -03:00
ruvnet
d5e2fc2d87 fix(turbovec): preserve padded geometry and harden inputs 2026-07-27 14:06:25 -04:00
Ofer Shaal
39137f7033 docs(adr): renumber turbovec ADR-194 → ADR-254 to resolve collision
ADR-194 is already taken on main (ruvector ONNX embedder API & throughput).
Renumber this PR's turbovec ADR to the next free number (254), matching the
canonical record on main. Keeps the fuller PR version (D1–D5 divergences table,
D3/D4 measured-milestone markers) and adds a numbering note. Updates the 13
in-crate ADR-194 references and two stray ADR-193 'future work' pointers so they
no longer resolve to the unrelated ONNX ADR.

Refs #520, #521
2026-07-27 14:01:42 -04:00
Ofer Shaal
8c7e35374b test(turbovec): distortion-bound oracle (ADR-194 D4)
Add quantizer_mse_within_paper_bound: draw 400k N(0,1) samples (Box–Muller,
no new deps), quantize via the real quantize_coord path, and assert the
per-coordinate MSE for every width stays under TurboQuant's distortion bound
D_mse ≤ (√3·π/2)·4^(−b) (arXiv:2504.19874) AND within 5% of the Max-1960
Lloyd–Max optimum. A corrupted centroid level trips this far more precisely
than the existing recall>0.5 threshold.

Marks D4 done in ADR-194; updates test count to 17. The full-pipeline
inner-product bound D_prod remains future work (tracked with D5).
2026-07-27 14:01:31 -04:00
Ofer Shaal
4afabb99d6 feat(turbovec): add 3-bit width (ADR-194 D3) — fills the 2↔4-bit recall cliff
Adds BitWidth::Three (8-level Max-1960 optimal N(0,1) reconstruction
levels). pack/unpack, calibration, scoring, and IdMap are width-generic,
so only the centroid table + the enum arms change.

Measured (cargo run --release -p ruvector-turbovec, n=5000 uniform-random,
dim=256, k=10, no rerank, vs exact L2):
  3-bit: recall@10 0.767, 112 B/vec, 9.8x compression, bias -0.0000
landing squarely between 2-bit (0.561) and 4-bit (0.879) — a useful
memory/recall midpoint (~22% smaller than 4-bit for ~0.11 recall).

Also refresh ADR-194: add the 3-bit Validation row, mark D3 done, widen
T2 to {2,3,4}, correct the test count to 16, and scope the provenance
note so the measured recall/compression/bias figures are called measured
while the FAISS-competitive claims stay attributed targets.

16 unit + 1 doc-test pass; clippy clean; new code is rustfmt-clean.
2026-07-27 14:01:31 -04:00
Ofer Shaal
e302958acb docs(adr-194): document divergences from the TurboQuant paper
Add an explicit 'Divergences from the TurboQuant paper (arXiv:2504.19874)'
section mapping where M1 departs from the paper, so the gaps are reviewable
and the follow-ups are paper-grounded:

- D1: M1 uses a heuristic per-vector c_x scale, not the paper's provably-
  unbiased two-stage MSE + 1-bit-QJL-residual estimator. Soften the T4 and
  Validation wording accordingly (empirically near-unbiased, not proven).
- D2: M1 quantizes against the N(0,1) limit + empirical TQ+ calibration, not
  the paper's exact d-aware Beta-optimal codebooks.
- D3: M1 ships 1/2/4-bit; paper highlights ~2.5/3.5 bpc sweet spots — add 3-bit.
- D4: assert measured distortion under the paper's closed-form bounds as a
  stronger test oracle than recall > 0.5.
- D5: estimator variance deferred.

Add milestones M5 (paper-grade QJL-residual estimator) and M6 (Beta-optimal
codebooks); note what M1 already matches (norm-based L2, online ingest,
full-precision query). No code change.
2026-07-27 14:01:31 -04:00
Ofer Shaal
c23d7a311e chore(turbovec): drop unused deps; attribute external benchmark claims
- Cargo.toml: remove unused rand_distr dependency and the redundant
  rand dev-dependency (rand is a normal dep for the demo bin + tests).
- Cargo.lock: drop rand_distr from ruvector-turbovec.
- ADR-194: attribute the FAISS-competitive figures to the upstream
  RyanCodrai/turbovec project rather than presenting them as this
  crate's measured results; point readers to the reproducible
  uniform-random Validation table instead.

No code changes; 16 unit + 1 doc-test still pass, clippy clean.
2026-07-27 14:01:30 -04:00
Claude
f40fc539fa fix(turbovec): address CodeRabbit review — validate inputs, propagate errors
- index: TurboVecIndex::add/search now return RabitqError::DimensionMismatch
  in release builds instead of silently accepting/masking wrong-length
  vectors (was debug_assert + unwrap_or_default).
- index: finalize() excludes zero vectors from calibration fit so they
  don't bias shift/scale toward zero.
- idmap: add_with_id validates dim up front and reports the real length
  (was hardcoded got: 0); add_with_ids rejects vectors/ids length
  mismatch with new TurboVecError::BatchLenMismatch instead of zip-truncating.
- quantize: pack/unpack document preconditions and debug_assert code-range
  and slice-length (proportionate to internal helpers; no Result churn).
- calibrate: fit debug_asserts every row has length dim.
- ADR-194 frontmatter status proposed -> accepted to match body.

Adds 4 tests (wrong-dim reject on add/search, zero-vector calibration
exclusion via self-retrieval, batch-len mismatch, idmap wrong-dim).
16 unit tests + 1 doc-test pass; clippy clean; demo unchanged.

https://claude.ai/code/session_012AzArCzBwxrJp8mUngUcH5
2026-07-27 14:01:30 -04:00
Claude
65b9b0c926 feat(turbovec): implement ADR-194 M1 multi-bit TurboQuant ANN index
New crate crates/ruvector-turbovec implementing the scalar-reference
milestone of ADR-194 — the 2/4-bit FastScan-style ANN regime ruvector
lacked (rabitq is 1-bit; ruvllm's TurboQuant is a KV-cache codec, not a
search index).

Pipeline: normalize -> randomized Hadamard rotation (reused from
ruvector-rabitq) -> TQ+ per-coordinate calibration -> Lloyd-Max 2/4-bit
scalar quantization -> per-vector length-renormalized unbiased scoring.
Implements the shared ruvector_rabitq::AnnIndex trait. Adds IdMapIndex
with O(1) delete and allowlist-filtered search.

Proof (cargo run --release -p ruvector-turbovec), n=5000 uniform-random
vectors, dim=256, k=10, no f32 rerank, vs exact brute-force L2:
  1-bit: recall@10 0.308, 25.6x compression, bias +0.0005
  2-bit: recall@10 0.561, 14.2x compression, bias +0.0001
  4-bit: recall@10 0.879,  7.5x compression, bias -0.0000
Recall rises monotonically with bit-width; mean cosine bias ~0 confirms
the unbiased estimator. Determinism + IdMap delete/filter verified.

12 unit tests + 1 doc-test pass; build green; clippy clean.
M2-M4 (FastScan nibble-LUT SIMD kernel, AVX-512, dispatcher) are future
milestones; the scalar scorer here is their determinism oracle.

https://claude.ai/code/session_012AzArCzBwxrJp8mUngUcH5
2026-07-27 14:01:30 -04:00
Claude
7689f1a9cf docs(adr): ADR-194 ruvector-turbovec multi-bit TurboQuant FastScan ANN index
Research and scope a new crate adapting TurboQuant techniques from
RyanCodrai/turbovec: 2/4-bit Lloyd-Max scalar quantization, TQ+
per-coordinate calibration, length-renormalized unbiased scoring, and a
nibble-LUT FastScan SIMD kernel (AVX-512BW/AVX2/NEON). Reuses
ruvector-rabitq's Hadamard rotation + AnnIndex/VectorKernel traits and
borrows ruvllm's MSE quantizer math, closing the missing 2-4-bit FastScan
ANN regime.

https://claude.ai/code/session_012AzArCzBwxrJp8mUngUcH5
2026-07-27 14:01:30 -04:00
rUv
a4f9991d9d
feat: add k-scoped adaptive ANN calibration (#718)
* research: add nightly survey for adaptive-recall-ann

Identifies adaptive recall-targeted ANN as the 2026-07-23 nightly topic.
Connects vector search, agent memory, edge AI, MCP tool latency SLAs,
and ruFlo workflow recall budgets. No prior nightly covered this angle.

* feat: add ruvector-adaptive-ann Rust proof of concept

Implements RecallTargetedSearch trait with three variants:
- FixedEfSearch (baseline): constant ef=64, ignore recall target
- BinarySearchCalibrated: binary-search ef per query with ground truth
- TableCalibratedSearch: O(1) ef lookup from offline calibration table

Core insight: calibration queries must match production query distribution.
CalibrationTable is a monotone ef→recall mapping from 50-100 held-out queries.

Benchmark: N=3000×D=64, recall_target=0.90
- FixedEf(64): 0.778 recall, 9,497 QPS (misses target)
- BinarySearch: 0.902 recall, 738 QPS (oracle, 13x slower)
- TableCalibrated: 0.940 recall, 4,390 QPS (exceeds target, O(1) ef)

* test: add 7 integration tests for ruvector-adaptive-ann

- beam search at ef=N achieves near-perfect recall
- recall is monotone in ef
- FixedEf(128) achieves minimum recall threshold
- CalibrationTable returns valid ef
- TableCalibratedSearch achieves recall within distribution-mismatch tolerance
- BinarySearchCalibrated achieves per-query target on 12/15 queries
- effective_ef_for_target returns Some for Table, None for Fixed

All 7 tests pass.

* docs: add ADR-272 for adaptive-recall-ann

Documents the calibration table approach, distribution matching constraint,
three implementation variants, benchmark evidence, failure modes, security
considerations, and migration path for adopting recall-targeted search.

ADR-272 status: Proposed.

* bench: capture adaptive-recall-ann benchmark results

cargo run --release -p ruvector-adaptive-ann --bin benchmark
x86_64 Linux, release build, N=3000 D=64 300 queries

FixedEf(64): recall=0.778, mean=105.3µs, QPS=9497
BinarySearch: recall=0.902, mean=1355µs, QPS=738
TableCalibrated: recall=0.940, mean=227.8µs, QPS=4390
All acceptance tests PASSED.

* fix adaptive ANN calibration scope

---------

Co-authored-by: Claude <noreply@anthropic.com>
2026-07-27 09:57:49 -07:00
rUv
9a31a37ca2
feat: add threshold-driven ANN with empirical recall (#719)
* research: add nightly survey for recall-bounded-ann

Nightly 2026-07-24: Recall-Bounded Approximate Nearest-Neighbour Search.
Establishes the RecallBoundedIndex trait and three measured Rust variants
for quality-first agent memory retrieval (search_above_threshold instead
of top-k). All 8 tests pass; acceptance gate met at recall >= 0.80.

Co-Authored-By: claude-flow <ruv@ruv.net>
Claude-Session: https://claude.ai/code/session_01GyrjFPrMZCH3knQuw8QgLk

* fix recall-bounded ANN ids and search budgets

---------

Co-authored-by: Claude <noreply@anthropic.com>
2026-07-27 09:57:00 -07:00
rUv
e24813cd7b
feat: add bounded RAG graph retrieval research (ADR-272) (#720)
* feat: add ruvector-bounded-rag MinCut context window retrieval crate

Three BoundedRetriever variants: TopK baseline, GraphBFS coherence expansion,
and MinCutBounded Edmonds-Karp max-flow partition. All 9 tests pass with
precision=1.000 acceptance on synthetic 2-cluster corpora.

Co-Authored-By: claude-flow <ruv@ruv.net>
Claude-Session: https://claude.ai/code/session_012eSJ4Y33PH9w8RCv73ugu5

* docs: add ADR-272 for bounded-rag-mincut

Documents decision to add MinCut-bounded RAG retrieval, benchmark evidence,
failure modes, security considerations, and Phase 2 production hardening plan.

Co-Authored-By: claude-flow <ruv@ruv.net>
Claude-Session: https://claude.ai/code/session_012eSJ4Y33PH9w8RCv73ugu5

* docs: add nightly research README and gist for bounded-rag-mincut

Full research document with SOTA survey, architecture diagrams, real benchmark
numbers, practical/exotic applications, and public SEO gist.

Co-Authored-By: claude-flow <ruv@ruv.net>
Claude-Session: https://claude.ai/code/session_012eSJ4Y33PH9w8RCv73ugu5

* chore: update Cargo.lock for ruvector-bounded-rag dependencies

Co-Authored-By: claude-flow <ruv@ruv.net>
Claude-Session: https://claude.ai/code/session_012eSJ4Y33PH9w8RCv73ugu5

* fix bounded RAG flow and input validation

---------

Co-authored-by: Claude <noreply@anthropic.com>
2026-07-27 09:55:59 -07:00
rUv
f0e53cf9e7
feat: add measured diverse beam ANN research (ADR-272) (#723)
* feat(diverse-beam): add ruvector-diverse-beam crate with MMR and coherence-pruned beam search

Implements three beam-search variants on a flat kNN graph:
- GreedyBeam: baseline greedy BFS (recall@10=0.816, QPS=10975 on uniform n=2500)
- MMRRerank: greedy pool + MMR post-reranking (λ=0.75, +1.67% diversity, −13.4% recall)
- CoherenceBeam: cosine-gated BFS (anti-pattern for clustered data, documented)

Also includes odd-stride entry point fix, normalised MMR scoring, and a benchmark
binary with acceptance thresholds. All 9 unit tests pass; benchmark PASS ✓.

* docs(adr): ADR-272 diverse beam ANN — MMR post-reranking and coherence-pruned beam search

Documents decision to implement ruvector-diverse-beam, measured results, two negative
results (MMR during traversal, CoherenceBeam on clustered data), and alternatives
considered (DPP, structural diversity). Status: Proposed.

* research(nightly): 2026-07-26 diverse beam ANN — README and gist

README: full 24-section research document with SOTA survey, architecture diagram,
all measured benchmark results, key findings (MMR traversal anti-pattern, coherence
cluster failure), memory model, practical/exotic applications, and future work.

gist.md: SEO-optimized public technical article targeting engineers building
RAG/agent-memory systems on vector databases.

* fix diverse beam traversal and scoring

---------

Co-authored-by: Claude <noreply@anthropic.com>
2026-07-27 09:55:22 -07:00
rUv
e1784a2934
feat: add audited speculative ANN search (ADR-272) (#725)
* feat: add speculative-ann-search Rust PoC with adaptive k' controller (ADR-272)

Implements the speculative decoding protocol for ANN retrieval:
- QuantizedDraft: u8 scalar-quantized linear scan (4× memory compression)
- SpeculativeANN: u8 draft proposes k' candidates; exact f32 verify + re-rank
- Adaptive controller: rolling recall feedback tunes k' to maintain target recall

Benchmark results (10K vectors, 128 dims, 500 queries, k=10):
  LinearFull:     recall=1.000  805 q/s  4.9 MB
  QuantizedDraft: recall=0.858  1385 q/s  1.2 MB  (1.7× faster, 4× smaller)
  SpeculativeANN: recall=0.964  1293 q/s  6.1 MB  (mult=2: 99.5% recall, <1% latency overhead)

18 unit tests + 6 acceptance tests — all green.
Research README, ADR-272, and SEO gist included.

Co-Authored-By: claude-flow <ruv@ruv.net>
Claude-Session: https://claude.ai/code/session_01Us7kwnqa65p1FUALNC3X8p

* fix speculative ANN feedback and packaging

---------

Co-authored-by: Claude <noreply@anthropic.com>
2026-07-27 09:54:31 -07:00
rUv
ca8224e0cd
feat(maxsim): add GraphMaxSim centroid-graph variant (salvaged from #622) (#623)
Adds a fourth MultiVecIndex variant to ruvector-maxsim: a greedy kNN graph
over per-document centroids + multi-seed beam search + exact MaxSim rerank.
Complements the token-level HnswMaxSim with a one-node-per-document graph.

Includes the consecutive-seeding correctness fix discovered in nightly PR
#622: step-based beam seeding collapses recall when the step is a multiple
of the cluster count. Documented in graph.rs and ADR-252.

#622 produced a duplicate ruvector-maxsim crate (the name was already taken
by #569, merged 2026-06-15); rather than merge the duplicate, its unique
value is salvaged here. The public research gist from #622 remains published.

- 5 new tests (recall vs Flat, dim validation, build/empty guards) — 23/23 pass
- cargo fmt clean, cargo clippy -D warnings clean
2026-06-29 10:47:01 -04:00
rUv
b2a32eae2f
feat(sona): metaharness-Darwin evolves EWC++ config beyond hand-tuned SOTA (#615)
* feat(sona): metaharness-Darwin evolves EWC++ config beyond hand-tuned SOTA

examples/darwin_ewc: applies the Meta-Harness 'freeze the model, evolve the
harness' pattern to SONA's continual-learning layer — frozen = the EWC++
algorithm (EwcPlusPlus), evolved = its EwcConfig genome (lambda schedule, Fisher
decay, auto task-boundary threshold, learning rate).

Benchmark: a single weight vector trained on a sequence of tasks (no replay,
auto-detected boundaries) — the canonical plasticity-vs-forgetting frontier.
Darwin (GA + coordinate-descent polish) evolves the genome on TRAIN task-
sequences; results reported on HELD-OUT sequences (different seeds).

Measured (deterministic), held-out: the evolved config beats EwcConfig::default()
(the crate's hand-tuned 'OPTIMIZED' values) by 35% lower final loss and 98.6%
less forgetting — a strict Pareto win (plasticity also improves), and it
generalizes to unseen task sequences. clippy -D warnings clean, fmt clean.

Co-Authored-By: claude-flow <ruv@ruv.net>

* feat(sona): weightAdapter gene — Darwin selects/prunes a fine-tuned adapter

Extends the metaharness-Darwin line: expose a fine-tuned adapter (e.g. a LoRA
distilled from verified SWE-bench trajectories — the 'autonomous data engine')
as a gene (which_adapter, alpha) so evolutionary selection decides whether/how
much to apply it (w_eff = w_base + alpha·Δw) instead of assuming new weights are
better. examples/darwin_weightadapter demonstrates it on two conflicting domains
with a generalizing adapter and an overfit one.

Key finding (sharpens the idea): 'selection prunes overfit adapters' holds ONLY
under per-domain evaluation. Measured (held-out, in-dist-majority eval):
  overfit α=0.55 → ΔA +0.249 / ΔB -0.357 (regresses out-dist)
  AGGREGATE (volume-weighted) fitness  → picks the overfit adapter (silent B regression)
  PER-DOMAIN (no-regression Pareto)    → prunes it, keeps the generalizing adapter
So: evolve the adapter as a gene, but score it per-repository. clippy/fmt clean.

Co-Authored-By: claude-flow <ruv@ruv.net>

* docs(adr): ADR-271 metaharness-Darwin for SONA self-improvement

Documents the metaharness-Darwin-evolves-SONA architecture: EWC++ config
evolution (PR #615), the weightAdapter gene (per-domain Pareto selection of
fine-tuned adapters), the Autonomous Data Engine (execution-verified SWE-bench
trajectories -> DPO pairs), and four Ornith-1.0 borrows (immutable-boundary +
deterministic-monitor-with-exclude-from-advantage + frozen-LLM-judge-veto
reward-hacking defense; per-task-category specialization; two-stage scaffold
reward credit; staleness-weighted replay). Method-not-model: external
evolutionary vs Ornith's in-weights RL.

Co-Authored-By: claude-flow <ruv@ruv.net>

* feat(sona): darwin-guard reward-hacking defense (Ornith-1.0 borrow, ADR-271)

3-layer defense for evolutionary config search: (1) immutable verifier boundary
(screen is a pure fn of verifier output the candidate can't fabricate);
(2) deterministic monitor — non-finite / out-of-bounds / degenerate candidates
are EXCLUDED from selection (best_accepted), not zero-scored, so a hack can
neither win nor bias the advantage; (3) IntentJudge trait = frozen-LLM veto-only
layer. Wired into darwin_ewc: NaN/collapsed configs are excluded from the GA
ranking (also fixes the partial_cmp().unwrap() NaN-panic). 4 unit tests; benchmark
still reaches beyond-SOTA (35% lower loss, 98.6% less forgetting) unchanged.
clippy -D warnings + fmt clean.

Co-Authored-By: claude-flow <ruv@ruv.net>

* feat(sona): per-task-category genome router beats single global config (ADR-271)

Ornith-1.0 borrow #2 (per-category specialization): evolve a router task-class
-> genome instead of one global EwcConfig. Two continual-learning workload
classes with conflicting optima (STABLE wants high lambda / retain; VOLATILE
wants low lambda / stay plastic). Guard-screened evolution.

Measured (held-out, adequate per-class data): per-category router 0.1122 vs
single best global genome 0.1144 -> router ~1.9% better on unseen sequences,
because one config cannot serve conflicting workloads.

Honest caveat (discovered + documented): the gain REVERSES when per-class data
is scarce — a specialized config overfits while the pooled global generalizes.
Per-category routing needs enough per-category samples (Ornith's regime). ADR-271
updated; clippy/fmt clean.

Co-Authored-By: claude-flow <ruv@ruv.net>

* feat(sona): online auto-tuner with staleness-weighted replay (ADR-271, Ornith borrow #4)

auto_tuner module: StalenessSchedule (Ornith w(d_t): fresh<=k1, exp-decay,
drop>k2) + StalenessWindow (staleness-weighted running estimate of recent
config performance, evicts stale obs). 4 unit tests.

examples/darwin_autotuner: a (1+1)-ES that adapts a DEPLOYED EwcConfig to a
drifting workload stream (regime A -> B at the midpoint), scoring the incumbent
on the staleness window and accepting a perturbation only when it beats the
recent score. Measured: online tuner ~3% lower post-drift loss than the static
deployment config (10 accepted re-tunes). Margin is modest on synthetic regimes;
the durable win is the reusable staleness machinery + the online-adaptation
principle (a fixed offline-tuned config goes stale under drift).

Completes the four ADR-271 components. clippy --all-targets -D warnings + fmt
clean; 102 sona tests pass.

Co-Authored-By: claude-flow <ruv@ruv.net>

* feat(sona): contamination/disjointness guard in darwin-guard (weight-eft/ADR-198 borrow)

Adds the train/eval contamination guard — the gap @metaharness/weight-eft exposed
in our reward-hacking-only guard. contamination()/assert_train_eval_disjoint()
fail on any train∩eval instance-ID overlap (training/selecting on eval instances
is fake lift); filter_holdout() partitions a set disjoint-by-construction and
surfaces what was excluded. The SONA-side analog of weight-eft's
assertTrainEvalDisjoint. 2 new tests (6 total in darwin_guard).

ADR-271 updated: §3 Data Engine now cites @metaharness/weight-eft + adopts its
RLHF-correct recipe (SFT distills ALL gold incl. off-policy frontier successes;
DPO ON-POLICY cheap-vs-cheap only), and the darwin-guard borrow gains layer (iv)
the contamination disjointness guard. clippy -D warnings + fmt clean.

Co-Authored-By: claude-flow <ruv@ruv.net>

* chore(release): ruvector-sona 0.2.1 — darwin_guard + auto_tuner modules

Non-breaking minor feature release (new public modules darwin_guard,
auto_tuner). Patch bump keeps the ^0.2 requirement of all in-workspace
dependents (ruvllm, rvlite, mcp-brain, ...) satisfied.

Co-Authored-By: claude-flow <ruv@ruv.net>

---------

Co-authored-by: ruvnet <ruvnet@gmail.com>
2026-06-27 12:57:48 -04:00