Skip to content

feat(retrieval-receipt): periodic index_state_root anchoring (ADR-341) - #959

Draft
ruvnet wants to merge 4 commits into
mainfrom
claude/focused-darwin-dfik90
Draft

feat(retrieval-receipt): periodic index_state_root anchoring (ADR-341)#959
ruvnet wants to merge 4 commits into
mainfrom
claude/focused-darwin-dfik90

Conversation

@ruvnet

@ruvnet ruvnet commented Sep 3, 2026

Copy link
Copy Markdown
Owner

Summary

Nightly research contribution continuing the 2026-08-31 run's own named
"Next Research" item and ADR-340's third Open Question: independent,
periodically-signed index_state_root anchoring, decoupled from any
specific query or receipt.

  • ADR-304 (unsigned retrieval receipts) → ADR-340 (Ed25519-signed receipt
    roots, per-query and batched) → this PR, ADR-341 (Ed25519-signed
    index_state_root checkpoints, independent of any query).
  • Adds crates/ruvector-retrieval-receipt/src/state_anchor.rs:
    StateAnchorPolicy, StateAnchorLog, verify_state_anchor, reusing
    ADR-340's Issuer/AnchorContext/verify_root machinery unchanged via
    a new AnchorPurpose::StateAnchor. No existing type, field, or test
    changed.
  • Lets an auditor who holds no query receipt confirm "was the index
    ever attested to be in state R" in O(1), without replaying the full
    write history (HashChainGate::verify_integrity, O(n)).

Hypothesis

Given a HashChainGate-backed index accumulating N writes, whose full-history
integrity check costs O(N),

when index_state_root is signed independently of any query, either (A) on
every write (interval_writes=1) or (B) periodically every W writes,

then policy B should reduce signing operations by roughly the factor W,
enabling an O(1)-per-checkpoint audit without full replay,

subject to: every tamper stays detected at every W, staleness never
exceeds W-1 (measured exactly, not merely asserted), and O(1) verification
is never presented as a substitute for O(N) full-history checking.

Benchmark

Command: cargo run --release -p ruvector-retrieval-receipt --bin benchmark -- 5000 128 10 200, 3 repeated process runs, 4 logical CPUs,
rustc 1.94.1, release profile. Raw output:
docs/research/nightly/2026-09-03-state-root-anchoring/raw-runs.txt.

Representative run (interval_writes sweep over 5,000 writes):

interval_writes anchors_taken expected sign_amortized_ns max_staleness anchor_verify_ns tamper (2×40)
1 5,000 5,000 17,445.5 0 46,575 80/80
8 625 625 2,126.8 7 45,317 80/80
32 156 156 562.5 31 45,953 80/80
128 39 39 141.1 127 43,996 80/80
512 9 9 32.7 511 46,756 80/80

Five acceptance thresholds, fixed before the run, all passed in all 3
runs — anchor count and max staleness matched the closed-form prediction
exactly (structural correctness, not statistical tolerance); 100%
tamper detection (400 trials/run); anchor-verify cost within a 2x band
(observed 1.04–1.07x); amortized signing cost at W=512 under 10% of the
W=1 cost (observed 0.2%).

Honest counterpoint reported, not hidden: a separate, explicitly
non-gated table shows verify_integrity's O(n) full-replay cost — at
n=10,000 it's 28–31x more expensive than one O(1) anchor verify across the
3 runs, and that gap is real, but the periodic anchor does not replace
full-history integrity checking; it's a cheaper, bounded-staleness
checkpoint, and the ADR says so explicitly.

ACCEPTANCE RESULT (both the pre-existing receipt benchmark and the new
state-anchor benchmark): ACCEPT
in all 3 runs.

Acceptance result

ACCEPT — full formal hypothesis, thresholds, and evidence in
ADR-341 and the
nightly research README.

Darwin result

Not executed. Capability verification (npx metaharness --help, npx ruvector harness doctor/status --json) found metaharness installed only
as a project-scaffolding generator, not a research/Darwin/Flywheel harness
wired to this repository; ruvector harness has no such executable here.
This is disclosed explicitly in the research README rather than fabricating
Darwin generations or Flywheel evidence-store writes that no installed
tool actually produced. The interval_writes sweep plays the same
empirical exploration role a bounded Darwin generation would, authored
directly.

Security review

  • Reuses ADR-340's typed, domain-separated signing statement unchanged —
    no new signature format. AnchorPurpose::StateAnchor is bound into the
    signed statement, so a receipt/batch-purpose signature can never be
    replayed as a state anchor (tested).
  • Adds an O(1)-verifiable "state was attested" checkpoint; does not
    add issuer honesty, durability, or stalled-job detection (all named
    explicitly in ADR-341 Failure Modes).
  • cargo clippy --release -p ruvector-retrieval-receipt --all-targets -D warnings: clean. cargo fmt -- --check: clean.

Main limitations

  • StateAnchorLog is in-process, non-durable, not thread-safe — a
    production deployment needs a persistence design first (Next Research
    Implement Ruvector high-performance vector database #1).
  • Only a uniform synthetic write rate was tested; a time-based/hybrid
    anchoring policy for bursty traffic is deferred (Next Research Set up Claude Flow swarm initialization #2, also
    the Rejected-Alternatives discussion in the README).
  • No wall-clock anchor-fill-latency or WASM measurement (same disclosed
    gaps ADR-340 already carries).

Production recommendation

Experimental, matching ADR-304/ADR-340's posture — not wired into any
default write or query path by this PR. Promotion requires a durable
StateAnchorLog persistence design and benchmark evidence against a real
deployment's write-rate/staleness tolerance (see ADR-341 Governance and
Production Path).

Files changed

  • crates/ruvector-retrieval-receipt/src/state_anchor.rs (new) — policy,
    log, verification, 6 unit tests.
  • crates/ruvector-retrieval-receipt/src/signing.rsAnchorPurpose::StateAnchor,
    AnchorError::InvalidInterval.
  • crates/ruvector-retrieval-receipt/src/lib.rs — module wiring, re-exports.
  • crates/ruvector-retrieval-receipt/src/bin/benchmark.rs — interval-sweep
    benchmark + descriptive verify_integrity scaling table.
  • docs/adr/ADR-341-periodic-state-root-anchoring.md (new).
  • docs/research/nightly/2026-09-03-state-root-anchoring/ (new) — README,
    gist, raw 3-run benchmark output.

Research document

docs/research/nightly/2026-09-03-state-root-anchoring/README.md

ADR

docs/adr/ADR-341-periodic-state-root-anchoring.md

Gist

docs/research/nightly/2026-09-03-state-root-anchoring/gist.md
(standalone technical article; not separately published as a public GitHub
gist — no gh/GitHub CLI access available in this environment).

Test plan

  • cargo test -p ruvector-retrieval-receipt --release — 30/30 pass
    (16 pre-existing regression tests + 14 new/touched).
  • cargo test -p ruvector-proof-gate --release — pass, unaffected.
  • cargo clippy --release -p ruvector-retrieval-receipt --all-targets -- -D warnings — clean.
  • cargo fmt -p ruvector-retrieval-receipt -- --check — clean.
  • Benchmark run 3x, raw output preserved, ACCEPT in all 3 runs.

🤖 Generated with claude-flow

https://claude.ai/code/session_01KV63T53qpYkXYkAKXvfPXT


Generated by Claude Code

claude and others added 4 commits September 3, 2026 07:28
Implements ADR-341: independent, query-decoupled signing of
index_state_root via a new AnchorPurpose::StateAnchor, reusing ADR-340's
Ed25519 signing machinery unchanged. Lets an auditor authenticate a
checkpoint of the index's state in O(1) without holding any specific
query receipt or replaying the full write history.

StateAnchorPolicy/StateAnchorLog/verify_state_anchor implement a
write-count-based anchoring interval with an exact, disclosed staleness
bound (interval_writes - 1), operating directly over WriteGate roots
rather than any RetrievalIndex.

Co-Authored-By: claude-flow <ruv@ruv.net>
Claude-Session: https://claude.ai/code/session_01KV63T53qpYkXYkAKXvfPXT
…cost table

Sweeps interval_writes in {1, 8, 32, 128, 512} over 5,000 writes, measuring
anchor count vs. the closed-form N/W prediction, exact staleness bound,
O(1) anchor-verify cost flatness, tamper detection, and amortized signing
cost. Adds a separate, explicitly non-gated verify_integrity O(n) scaling
table so the O(1) anchor-verify numbers are never read as a substitute for
full write-history integrity checking.

Co-Authored-By: claude-flow <ruv@ruv.net>
Claude-Session: https://claude.ai/code/session_01KV63T53qpYkXYkAKXvfPXT
Research README, standalone gist, and raw 3-run benchmark output for the
periodic index_state_root anchoring experiment (ADR-341), continuing the
2026-08-31 nightly run's named Next Research item.

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

ruvnet commented Sep 3, 2026

Copy link
Copy Markdown
Owner Author

CI status: every check has passed on this PR's head (9d666d979) except Tests (core-and-rest) (part of the Workspace CI workflow), which was cancelled after running ~4 hours, still mid-dependency-compilation (last log line: compiling ruvector-temporal-tensor-wasm, then The operation was canceled.).

This is not caused by this PR's diff (2 small files in one experimental crate, ruvector-retrieval-receipt). Confirmed against main itself: the same Workspace CI workflow was also cancelled after ~4 hours on each of the last two pushes to mainrun on d8c8e94 (16:06:52→20:09:10) and run on c2df540 (16:14:04→20:14:45). This looks like a standing, repo-wide Workspace CI job-timeout issue against the full ~180-crate workspace build, unrelated to any individual PR's content — outside the scope of a documentation + one small crate extension to fix. I don't have a ported fix for it (no open PR addressing the Workspace CI timeout was found).

This PR's own dedicated job, Tests (research-nightly), which covers the crate this PR actually touches, passed cleanly in under 4 minutes. All other 48 checks (Clippy, Rustfmt, Security audit, ADR numbering guard, npm publish pipeline, native builds for all 5 platforms, etc.) are green.

I'll trigger one re-run of the cancelled job to rule out a one-off scheduling issue, per the drive-to-green process; if it cancels again for the same reason I won't keep re-running it, since the evidence above indicates it's a pre-existing infra limit rather than something a re-run fixes.


Generated by Claude Code


Generated by Claude Code

@ruvnet ruvnet left a comment

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Dream exact-head review — INCONCLUSIVE

Frozen hypothesis: periodic signed state-root anchors reduce signing work by approximately the configured interval while bounding staleness to interval - 1, preserving tamper detection, and keeping verification effectively O(1).

The committed benchmark is falsifiable and promising: 5,000 writes across intervals 1/8/32/128/512, exact anchor counts/staleness, 400 tamper trials per run, and roughly 0.2% of interval-1 signing work at interval 512. Focused tests and native, WASM-dedup, regression, supply-chain, formatting, and clippy gates pass.

Two blockers remain:

  1. Required Workspace CI was cancelled.
  2. StateAnchorLog relies on callers to supply monotonically increasing write_count, but the public append path does not reject duplicate or decreasing counts. That can make insertion order diverge from logical order and invalidates the stated lookup/staleness contract.

Acceptance gate:

  • Fail closed on duplicate/decreasing write counts and test out-of-order, duplicate, restart/reload, and concurrent append cases.
  • Re-run the frozen benchmark after that invariant.
  • Add native/WASM parity for checkpoint serialization and verification.
  • Obtain a successful exact-head Workspace CI run.

Acceptance is limited to the software proof; no durable external transparency or production deployment claim is made.

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants