Skip to content

Zeptosecond measurement validation: test, optimize and prove the 247 zs photon transit - #64

Draft
ruvnet wants to merge 22 commits into
mainfrom
claude/zeptosecond-measurement-3umcr4
Draft

Zeptosecond measurement validation: test, optimize and prove the 247 zs photon transit#64
ruvnet wants to merge 22 commits into
mainfrom
claude/zeptosecond-measurement-3umcr4

Conversation

@ruvnet

@ruvnet ruvnet commented Jul 4, 2026

Copy link
Copy Markdown
Owner

Summary

This branch began as the 247 zeptosecond measurement validation and grew into two further self-contained, independently-verifiable packages under integrations/: a metaharness self-learning proof-of-mechanism and a ruflo guidance-flywheel integration (3.24.0 flywheel + 3.25.0 embedder tier). Every claim below is reproduced by a verifier that re-executes from sealed inputs and trusts none of the service logs.


Part 1 — Zeptosecond measurement validation (validation/zeptosecond/)

Tests, optimizes and proves the 247 zeptosecond (247 × 10⁻²¹ s) X-ray photon transit across the H₂ molecule (Grundmann et al., Science 370, 339, 2020, PETRA III/DESY), using the ruvnet stack (ruvector, and the repo's temporal_nexus quantum framework).

  • Forward: t = R/c = 74.14 pm / c = 247.30 zs — agrees with measured 247 zs to 0.12%; inverse recovers the H₂ bond to 0.13%
  • Margolus–Levitin cross-check mirrors MargolousLevitinValidator in src/temporal_nexus/quantum/speed_limits.rs
  • 21 node:test tests passing; ZeptoClock (BigInt) keeps a 247 zs interval exact where IEEE-754 silently drops it; 5.2× benchmark speedup with proven bit-level statistical equivalence; ruvector kNN retrieval proven physics-consistent

Part 2 — Metaharness self-learning proof-of-mechanism (integrations/metaharness-proof/)

Drives the real @metaharness/darwin ADR-076 promotion gate and builds the missing provenance layer (receipts, immutable lineage, statistical plateau detection). Labeled precisely: single-round proof-of-mechanism, not a compounding-learning claim. Each stage has its own re-execution verifier.

  • Generation-0 receipt (7 sealed artifacts) — verify-receipt.mjs recomputes all, 14/14
  • Immutable hash-chained lineage, cohort knowledge base, statistical plateau detection
  • REAL evaluation: buggy Neumann baseline 0/8 vs the repo's SublinearSolver 8/8, by re-execution
  • Autonomous discovery (config search): gate selects {neumann, maxIterations:75} (8/8) no human authored — reproduced bit-for-bit (12/12)
  • Novel discovery engine (run-novel.mjs): a real LLM (claude -p) proposes arbitrary solver code. Champion Jacobi diverges on SPD-non-dominant systems (0/8); Claude autonomously proposed a preconditioned BiCGSTAB solver (8/8), gate promoted it. Generation is non-deterministic, so verify-novel.mjs validates the discovered code by re-execution — reproducing solve counts and the gate decision hash (9/9)

Part 3 — ruflo guidance flywheel + embedder tier (integrations/ruflo-flywheel/)

Integrates the self-optimizing flywheel from the ruflo 3.24.0 gist and the 3.25.0 Lattice embedder gist.

Correction of an earlier note: the flywheel machinery is not absent from npm. It ships inside @claude-flow/guidance (ruflo's transitive dep): EvolutionPipeline, ProofChain, ArtifactLedger, EnforcementGates, TrustAccumulator, ContinueGate — surfaced via ruflo guidance. This package drives the real pipeline, no reimplementation.

  • Part ✨ Add Temporal Neural Solver (TNS) - Sub-microsecond Neural Network Inference #2 — the flywheel. Evolves a bounded retrieval policy over this repo's guidance (baseline intent-blind → candidate intent-routed, activating the retriever's real +0.15 intent boost). Held-out intent-precision@2 rises 0.250 → 1.000, drift 0.0375 ≤ 0.2 canary gate, no regression → PROMOTED through canary→partial→full by the real EvolutionPipeline. verify-flywheel.mjs reproduces the bundle digest, both precision numbers, divergence, verdict, promotion, decision hash bit-for-bit, and the proposal HMAC — 12/12.
  • Part Add MseeP.ai badge #1 — the signed champion, captured live. Running ruflo guidance auto-wrote a signed retrieval config champion to .claude/proven-config.json (gist part Add MseeP.ai badge #1). The exact adopted artifact — with its gate receipt (heldOutDelta 0.0738, redblue PASS, drift 0, canary rollbackRate 0, receiptCoverage 1) — is captured verbatim under proven-config/ as committed evidence (ruflo produced the numbers, not me).
  • 3.25.0 Lattice WASM embedder tier — fail-closed seam. Wired via the retriever's real IEmbeddingProvider. Honest status: @ruvector/lattice-wasm 404s on npm today (verified; ruvnet's gist itself calls it a dormant seam). So this implements the seam: absent package → fails closed to hash (all sealed numbers on that path, zero regression); package present → real embeddings, no code change. verify-embedder.mjs proves fallback + fail-closed-on-bad-specifier + activation (via a labeled local stub, not a real model) + zero-regression — 11/11.

Defaults match the gists throughout: $0 cost, no network, fail-closed, mutation explicit. Honest scope stated plainly: the default hash embeddings are test-only (the win is attributable to the real intent-boost mechanism, not semantics), and ground-truth intents are a deterministic author oracle, not human relevance judgments.

cd integrations/ruflo-flywheel && npm install && npm run prove:flywheel   # flywheel + embedder, 12/12 + 11/11
cd integrations/metaharness-proof && npm run prove:novel                  # novel-discovery engine, 9/9

🤖 Generated with Claude Code

https://claude.ai/code/session_011cHoWPXP5UHwVaNYwjhvjn

claude added 7 commits July 4, 2026 14:59
Test, optimize and prove the Grundmann et al. (Science 370, 339, 2020)
zeptosecond measurement — the 247 zs X-ray photon transit across the H2
molecule measured at PETRA III:

- Prove t = R/c = 247.30 zs vs measured 247 zs (0.12% agreement) plus
  inverse, orientation-model, de Broglie, and energy-time uncertainty
  cross-checks; Margolus-Levitin bound mirrored from
  src/temporal_nexus/quantum/speed_limits.rs
- Exact BigInt ZeptoClock: doubles silently drop 247 zs against a 1 s
  epoch; the clock accumulates a million 247 zs events with zero drift
- Optimized Monte Carlo orientation estimator: 5.2x speedup over the
  naive baseline with bit-identical statistics, converging to the
  analytic R/(2c) expectation
- ruvector (ruvnet) integration: measurement events indexed in VectorDb
  with kNN retrieval proven physics-consistent to <25 zs; per-test
  storagePath isolation for its shared ./ruvector.db default store
- 21 node:test tests, zero required dependencies for the core suite

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011cHoWPXP5UHwVaNYwjhvjn
…n, deps

Server (server/index.js):
- Mount auth middleware on the real /api/v1 router instead of the unused
  /api/protected prefix, so --auth-token actually gates every endpoint
- Authenticate WebSocket upgrades with the same token (header or ?token=)
- Add validateProblemSize() and enforce a maxDimension cap on matrix/vector
  dimensions before session/job creation on /solve, /solve-stream, and the
  WS solve path — blocks tiny sparse bodies that declare enormous dimensions
  from driving unbounded allocations (OOM DoS)
- Only pair CORS credentials with an explicit origin allowlist; never reflect
  an arbitrary Origin together with credentials

WASM entry points (src/wasm.rs):
- Validate matrix_data.len() == rows*cols in solveJacobi and
  solveConjugateGradient before flat-buffer indexing (checked_mul also
  rejects wasm32 overflow)
- Validate adjacency.len() == n*n and n>0 in computePageRank, returning a
  Result instead of panicking (panic=abort would kill the whole instance)

goalie (npx/goalie/src/utils/output-manager.ts):
- Contain caller-supplied outputPath within the project directory; reject
  absolute paths and .. escapes (CWE-73 arbitrary file write)

Dependencies:
- npm audit fix: ws 8.14.2 -> 8.21.0 (high-severity DoS), plus hono and tar
  advisories; 0 vulnerabilities remaining

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011cHoWPXP5UHwVaNYwjhvjn
…rdination

Prototype integration of agenticow (ruvnet 'Git for Agent Memory') as a
copy-on-write collective-memory primitive for the repo's multi-agent /
hive-mind coordination layer:

- SwarmMemory wraps a shared agenticow base and gives each agent a private
  COW branch (spawn/fork). Agents recall base union their own edits with
  read-through queries, isolated from peers; validated findings are promoted
  to the base with commit(), dead-end branches dropped with discard() at zero
  cost to the base. checkpoint()/rollback() snapshot the whole hive.
- Proof suite runs against the native agenticow backend (read-through,
  peer isolation, commit-propagates, discard-preserves-base, checkpoint/
  rollback, dimension + lifecycle guards) and falls back to an in-memory COW
  fake when the native package is absent, so CI needs no native binary.
  Detection uses a real dynamic import (agenticow is import-only ESM).
- benchmark.mjs shows per-agent fork cost stays ~flat (~3 ms) as the base
  grows 100 -> 50000 vectors: spawning speculative agents is O(1) in
  collective-memory size.

Self-contained under integrations/agenticow with its own package.json;
node_modules and .rvf stores git-ignored.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011cHoWPXP5UHwVaNYwjhvjn
Closes gaps a second adversarial sweep found in the prior security fixes,
plus correctness bugs in the new agenticow module.

Server DoS (server/index.js, streaming.js, session-manager.js):
- validateProblemSize now caps total dense elements (rows*cols) and sparse
  non-zero count, not just each axis — a 1e6 x 1e6 dense body or a
  {rows:2,cols:2} body with millions of COO values previously passed the
  per-axis cap and pinned the single worker.
- Release the solver worker on client disconnect: createAsyncIterator wraps
  its loop in try/finally so cleanup() runs on early break, and the streaming
  handler detects res 'close' and stops pulling (the drain wait also resolves
  on close, so a dead socket can't hang the handler holding the worker).
- sanitizeOptions clamps caller-supplied maxIterations (was unbounded).
- Bound costUpdates (ring buffer) and swarmNodes growth per session.
- Constant-time auth token comparison (crypto.timingSafeEqual) for HTTP and WS.

WASM input validation (src/wasm.rs):
- Cap dimensions in solveSublinear/verifySublinearConditions (n from triplet
  indices) and guard benchmark/validatePerformance against size==0 underflow
  and size*size overflow — same class the prior checked_mul guards addressed.

Core (src/core/utils.ts):
- normInf reduces instead of Math.max(...vector); spreading a large vector
  overflowed the call stack (RangeError) at n >~ 100k.

goalie (npx/goalie):
- resolveBaseDir realpaths the nearest existing ancestor to defeat symlink
  escape (lexical containment alone followed a symlink pointing outside).
- Stop logging API-key length/prefix fragments to stdout.

agenticow SwarmMemory (integrations/agenticow):
- commit() and discard() retire the branch in finally, so a throwing promote()
  no longer leaks the handle or leaves the agent half-promoted and 'live'.
- checkpoint/rollback test now asserts the base actually reverts (post-
  checkpoint writes gone, checkpointed data preserved), verified against the
  native backend; the in-memory fake models sealed checkpoint layers faithfully
  so both backends validate the same real behavior.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011cHoWPXP5UHwVaNYwjhvjn
Root-cause optimization from the review sweeps: MatrixOperations.getEntry
re-ran an O(nnz) validateMatrix AND a full O(nnz) linear scan on every call,
so it was the innermost cost of every nested loop in the graph/matrix MCP
tools — turning O(V^2) algorithms into O(V^2*nnz).

src/core/matrix.ts:
- Cache validation per matrix (WeakSet) so per-entry accessors don't
  re-validate every call.
- Build a lazy per-matrix COO index (WeakMap: row*cols+col -> value) once,
  making getEntry O(1). First-occurrence-wins preserves the original
  linear-scan semantics exactly (verified against duplicate-coordinate and
  implicit-zero cases).

src/mcp/tools/graph.ts:
- computeModularity precomputes node degrees once instead of recomputing
  ki/kj (each O(V)) inside the O(V^2) pair loop — was O(V^3). Total edge
  weight m is derived from the degree sum (m = sum(deg)/2), dropping the
  separate O(V^2) countEdges pass. Output is byte-identical.

Regression guards (tests/, run via
> sublinear-time-solver@1.7.2 test:refactor
> tsx tests/matrix-getentry-characterization.mts && tsx tests/graph-modularity-equivalence.mts

getEntry characterization: 5852 checks passed
reference modularity: {"n4":-0.3209477023628898,"n8":0.06727403001919355,"n16":0.028879743941472337}
modularity equivalence: 3 graphs match the pre-refactor values exactly):
- 5852 getEntry checks vs a naive reference (dense + COO with duplicates
  and implicit zeros) — behavior unchanged.
- Refactored computeModularity reproduces the pre-refactor modularity values
  exactly on 3 graphs.

Measured: modularity now scales ~O(V^2) (4-5x per 2x of V, was ~8x);
getEntry sustains ~15M lookups/s on a 200k-nnz matrix (previously a full
scan per call).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011cHoWPXP5UHwVaNYwjhvjn
Continues the getEntry-cluster optimization in the matrix analysis path
(checkDiagonalDominance and isSymmetric are both on the solve path via
analyzeMatrix).

src/core/matrix.ts:
- checkDiagonalDominance previously called getRowSum + getColumnSum (each a
  full O(nnz) scan) for every row -> O(rows*nnz). Now computeDominanceComponents
  accumulates the diagonal and off-diagonal |value| row/col sums in a single
  O(nnz) pass (O(rows*cols) for dense). Diagonal uses first-stored-value and
  off-diagonal sums include duplicates, matching getDiagonal/getRowSum/
  getColumnSum semantics exactly.
- isSymmetric for COO replaced the O(V^2) entry-probe with an O(nnz) pass over
  stored off-diagonal coordinates, comparing each against its mirror via the
  O(1) index — equivalent because only a stored coordinate can break symmetry.

Regression guard extended (tests/matrix-getentry-characterization.mts):
- 24 checkDiagonalDominance/isSymmetric checks against naive references over
  random, dense, and diagonally-dominant matrices (with duplicate coordinates
  and implicit zeros) — output unchanged.

Measured: analyzeMatrix on a sparse DD matrix now scales ~linearly with nnz
(~5.5 ms at V=4000 / 44k nnz), where checkDiagonalDominance alone was
previously O(V*nnz).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011cHoWPXP5UHwVaNYwjhvjn
The crate did not compile, which blocked landing the flagged optimization.
Fixed all 21 compile errors:

- core.rs: make Matrix.data / Vector.data pub so solver.rs and predictor.rs
  can index them (E0616, ~14 sites); annotate Array2<f64>/f64 to resolve
  ambiguous numeric types for .abs()/.max() (E0689); rewrite
  SparseMatrix::multiply_vector as an explicit O(nnz) iteration since this
  sprs version has no "&CsMat * &Array1" impl (E0277/E0282).
- solver.rs: compute the residual before moving the solution vector into
  SolverResult (E0382 borrow-after-move).
- predictor.rs: annotate s_max: f64 (E0689).
- Remove now-unused imports across core/solver/predictor/validation.

Optimization (the original goal): compute_iteration_matrix started from
Matrix::zeros instead of Matrix::random -- every entry is overwritten, so the
n^2 RNG fill was pure waste.

Status: crate builds cleanly; 13/16 lib tests pass. The 3 failures are
pre-existing and unrelated to these changes (the crate never compiled before,
so they had never run): test_neumann_solver and test_temporal_prediction are
timing/complexity-heuristic assertions (is_sublinear / has_temporal_lead),
and test_adaptive_selection is a genuine Neumann-iteration convergence issue
in the solver's math -- a separate algorithmic fix, not a build problem.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011cHoWPXP5UHwVaNYwjhvjn
@ruvnet
ruvnet force-pushed the claude/zeptosecond-measurement-3umcr4 branch from 0b42c16 to 33a11bb Compare July 4, 2026 22:54
claude added 15 commits July 5, 2026 02:16
Follow-up to the build fix; addresses the solver-quality failures that were
never observable while the crate did not compile (13/16 -> 15/16 passing).

- solve_neumann solved A x = D b, not A x = b. The fixed point of x = c + M x
  with M = I - D^-1 A satisfies D^-1 A x = c, so the constant must be
  c = D^-1 b (it was plain b). Precompute D^-1 b once and iterate from it.
  Fixes test_adaptive_selection (residual now converges below 1e-3).

- Replace estimate_complexity, which mapped a single wall-clock sample to an
  operation-count class by comparing raw nanoseconds to n / n^2 / n^3 (a
  dimensionally meaningless ratio that classified a fast 10x10 solve as Cubic).
  Complexity class is a property of the method's iteration count, so classify
  by method instead. Fixes test_neumann_solver (is_sublinear).

- DominanceParameters::from_matrix rebuilt the ndarray view on every element
  access inside its O(n^2) loop; hoist it out (n^2 view constructions -> 1).

Remaining: test_temporal_prediction still fails. Root cause is a design issue,
not a mechanical bug: from_matrix estimates the condition number via a
100-iteration O(n^2) power method (spectral_radius), making the "sublinear"
analysis itself superlinear, so for n=1000 it exceeds the Tokyo-NYC light
budget. A genuine fix is a sampling-based condition estimate (a redesign),
not tuning the iteration count to squeak under the timing bar.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011cHoWPXP5UHwVaNYwjhvjn
… 16/16

The matrix-analysis step was superlinear, contradicting the crate's sublinear
premise and dominating runtime (measured 50.4ms of a 50.5ms predict_functional
call on a 1000x1000 system, so it lost to the 36ms Tokyo-NYC light budget).
Two genuinely wasteful operations removed:

- Condition number used m.spectral_radius(), a 100-iteration O(n^2) power
  method (~1e8 ops). Replaced with the Gershgorin bound rho(A) <= max_i
  sum_j |a_ij|, computed inline from the row sums the dominance loop already
  accumulates -- a textbook spectral-radius bound, no extra passes.
- Sparsity/density called m.to_sparse(), building a throwaway ~1e6-entry CSR
  copy of the (dense) matrix just to count nonzeros. Replaced with an inline
  nonzero count in the same loop (same 1e-10 threshold).

from_matrix now runs ~2.9ms instead of ~50ms for n=1000. This makes the
release lib suite pass 16/16 (was 15/16) and drops its wall-clock from ~54s
to ~1.2s, since other tests (e.g. test_lower_bounds on a 10000x10000 matrix)
also go through from_matrix.

Note: test_temporal_prediction asserts has_temporal_lead(), a real wall-clock
comparison against light-travel time -- it holds in release (~3ms << 36ms) but
not in an unoptimized debug build, by design (it is a benchmark of optimized
code, not a correctness invariant).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011cHoWPXP5UHwVaNYwjhvjn
Both crates build but shipped with no [profile.release], so their release
binaries defaulted to codegen-units=16 / lto=false -- under-optimized, which
also undermined temporal-compare's benchmark numbers. Added
opt-level=3 / lto=true / codegen-units=1 (matching the other solver crates).

Verified both compile cleanly under the new release profile
(temporal-compare and all three psycho-symbolic-reasoner workspace members).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011cHoWPXP5UHwVaNYwjhvjn
Correctness: SublinearSolver's Neumann method converged to the wrong vector.
The Jacobi iteration matrix is M = I - D^-1 A = -D^-1 * offdiag(A), but the
term update computed seriesTerm = +D^-1 * offdiag(A) * c_k (computeOffDiagonal-
Multiply returns +offdiag), so the series summed (-M)^k D^-1 b instead of
M^k D^-1 b. For [[4,-1,0],[-1,4,-1],[0,-1,4]] x = [1,2,3] it returned
[0.179, 0.286, 0.679] (residual ~1.9) instead of the true [0.464, 0.857, 0.964].
Negating the term fixes it (residuals now ~1e-12 across the test systems).

Optimization: removed state.series, which retained a copy of every iteration's
n-length term (O(iterations * n) memory, multi-GB for large systems) but was
never read anywhere; also dropped the now-unused NeumannState.series field.

Added tests/solver-neumann-correctness.mts (wired into `npm run test:refactor`):
solves three systems and asserts residual < 1e-6 and, where known, the exact
solution — guarding against this regression.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011cHoWPXP5UHwVaNYwjhvjn
… class

Audited every Neumann/iterative solver after fixing the core solver's sign bug:
- src/core/solver.ts (Neumann): had the sign bug, fixed previously.
- src/mcp/tools/simple-wasm-solver.ts (Neumann): correct -- builds N = I - D^-1 A
  explicitly; empirically converges (residual ~6e-7 on the tridiagonal test).
- src/mcp/tools/true-sublinear-solver.ts (Neumann): correct -- computes
  M c = c - D^-1 A c directly, the right sign.
- js/fast-solver.js: textbook conjugate gradient, unaffected by the Neumann
  iteration-matrix sign trap.
- crates/temporal-lead-solver (Neumann): had the D^-1 b RHS bug, fixed earlier.

No new bugs; the sign-bug class is fully resolved. Extended
tests/solver-neumann-correctness.mts to also exercise
SimpleSublinearSolver.solveNeumann so both TS Neumann paths are guarded
against regression.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011cHoWPXP5UHwVaNYwjhvjn
…bundle

Seals one synthetic evolve round into an independently-verifiable generation-0
bundle over the REAL @metaharness/darwin promotion gate (hashTasks,
scoreBenchmark, decidePromotion / ADR-076). Narrow purpose: prove gate wiring,
receipt persistence, SHADOW registration, and no-auto-serve. NOT flywheel proof,
NOT compounding learning, NOT production learning -- the candidate and its
outcomes are transparent synthetic fixtures; only the mechanism is real.

Emits all seven required artifacts into generation-0/: input holdout hash
(library hashTasks), baseline + candidate manifest hashes (SHA-256 content
manifests), meetsPromotionRule version (adr-076@<darwin>), decision receipt
(full decidePromotion output: 6 clauses + bootstrap lower95), SHADOW
registration id, cost receipt (metered per-task proxy). RECEIPT.json indexes
them under one bundleRootHash -- the immutable root of the evolution graph.

run-proof.mjs produces the bundle; verify-receipt.mjs is the acceptance test:
reads only the sealed bundle, recomputes every hash, re-runs the real gate on
the sealed raw outcomes, and asserts the decision reproduces bit-for-bit, then
explains WHY the candidate passed from the receipt alone -- no service logs.

The synthetic round: baseline retries by hammering (expensive), candidate uses
bounded backoff (cheap, same solve rate) -- a uniform, statistically-significant
efficiency win. The gate promotes it (all 6 clauses, lower95=0.17), registers it
SHADOW, and the serving manifest stays empty (gate-promoted != served).

Verified: deterministic (identical bundleRootHash across runs), portable
(verifies from any cwd on a copy), tamper-evident (mutating any sealed byte
fails verification). @metaharness/darwin pinned to 0.1.0 to keep the fixture
reproducible; generation-0/ committed as the frozen fixture for F-P1/F-P2.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011cHoWPXP5UHwVaNYwjhvjn
Extends the proof-of-mechanism from one round to a hash-chained, append-only
lineage — the "version control for operating policies" substrate.

What is REAL at generation 1:
- autonomous candidate generation: the candidate is produced by the real
  DeterministicMutator (machine-generated, not hand-authored); the receipt
  records the mutated surface + summary.
- frozen anchor suite: gen-1 is scored against the SAME holdout suite as gen-0;
  run-lineage aborts unless its hash equals gen-0's inputHoldoutHash.
- hash-chained parent link: gen-1.parent === gen-0.bundleRootHash, and gen-1's
  own root hash binds that parent in (append-only, tamper-evident).
- the real ADR-076 gate + full 7-artifact receipt bundle, plus lineage.json.

What is still SYNTHETIC (documented boundary): the per-task outcomes. This
proves compounding STRUCTURE + autonomous mutation, NOT that the flywheel turns
on real work — that needs real agent execution against real tasks.

verify-lineage.mjs independently replays the whole chain: each generation's
hashes + gate decision reproduce bit-for-bit, gen-1 links to gen-0's immutable
root, the anchor is frozen across the chain, the candidate is provably
machine-generated, and nothing is auto-served. 18/18 checks pass; the lineage
is deterministic (identical gen-1 root across runs). README states plainly the
line this does not cross and what real evaluation would require.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011cHoWPXP5UHwVaNYwjhvjn
Turns the lineage from an audit trail into a verifiable knowledge base
(design items #1/#3/#4/#5). From the immutable gen-0 root, run-cohort.mjs
autonomously generates a cohort of machine-mutated candidates (real
DeterministicMutator, one per seed), gates each against the frozen anchor
suite with the real ADR-076 gate, and derives two analytics:

- mutation-effectiveness: per mutation surface {attempts, promotions, meanDelta},
  sorted by payoff — the evidence a future optimizer uses to bias mutation
  toward high-payoff classes.
- regression-ancestry: each rejected candidate -> the gate clause it failed ->
  its ancestor (why a direction was abandoned).

verify-cohort.mjs re-runs every node's gate from sealed inputs and RECOMPUTES
both analytics from the node receipts, asserting they match — the knowledge
base is itself verifiable, not a trusted summary. 8-node cohort, deterministic,
all checks pass. Outcomes remain synthetic and are keyed by mutation surface so
payoff differs by class (efficiency surfaces promote; planner regresses and is
abandoned); the real/synthetic boundary is unchanged and documented.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011cHoWPXP5UHwVaNYwjhvjn
Completes the verifiable structural backlog. src/plateau.mjs is a pure,
deterministic detector: a plateau is declared only when ALL three hold over a
rolling window -- median per-generation improvement < epsilon, promotion rate
< max, and candidate-score variance shrinking. It emits a classification
(local-optimum / noisy-benchmark / still-improving / inconclusive), separating
a real local optimum from noise or optimizer failure without intuition.

run-plateau.mjs builds a 6-generation history with diminishing returns, gates
every candidate with the real ADR-076 gate, derives per-generation stats
(bestDelta, promotion rate, score variance) from the real decisions, and
applies the detector (final verdict + per-prefix trace showing WHEN it fires).
On the demo history it declares plateau=true (local-optimum) first at
generation 4.

verify-plateau.mjs re-gates every sealed candidate, rebuilds the history, and
recomputes the detector -- asserting the history and verdict reproduce
bit-for-bit. Deterministic; the plateau signal is verifiable, not a claim.
Outcomes remain synthetic and are shaped to diminish so a plateau forms; the
real/synthetic boundary is unchanged.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011cHoWPXP5UHwVaNYwjhvjn
The one part of this package whose outcomes are measured, not fixtured. It uses
ruvnet/sublinear-time-solver as the task and evaluates by EXECUTING the repo's
real solver:

- task: solve 8 real diagonally-dominant systems A x = b to residual < 1e-6
- candidate: the repo's real SublinearSolver (fixed Neumann)
- baseline: the pre-fix buggy Neumann (missing sign -> converges to A x = D b)
- score: solved := measured ||A x - b|| < 1e-6, via the repo's real
  MatrixOperations (deterministic, reproducible)
- gate: the real ADR-076 decidePromotion

Measured: baseline 0/8 verified-solves (median residual 1.5e+01), candidate 8/8
(median residual 6.7e-13). The gate promotes on real verified correctness
(verified-solve rate 0 -> 1, statistically real). These are numbers from real
execution, not hand-authored fixtures.

verify-real-eval.mts is the strongest verifier here: it RE-EXECUTES both
solvers on the sealed systems, recomputes the residuals and the gate decision,
and asserts they reproduce (9/9) — trusting no producer-claimed value.
src/real-task.mts holds the shared task; its evaluate() seam is exactly where
an autonomous mutator + real agent plug in next.

Honest scope: this makes EVALUATION real (real code, real systems, real measured
correctness, gated for real). The two variants were authored by the operator,
so it is real evaluation, not yet autonomous discovery.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011cHoWPXP5UHwVaNYwjhvjn
Closes the loop: no human authors the winning change. The system searches a
configuration space over the real SublinearSolver (method / maxIterations /
epsilon), real measured evaluation scores each candidate, and the real ADR-076
gate selects the winner.

Pipeline (src/autonomous-task.mts, run-autonomous.mts):
- a seeded mutation operator PROPOSES a cohort of candidate configs (it does
  not know which will win)
- each config is evaluated by RUNNING THE REAL SOLVER on 8 real diagonally-
  dominant systems of varying difficulty; solved := measured ||A x - b|| < 1e-6
- the gate selects the best config that beats the champion

Result: the champion (maxIterations:3) solves 0/8. From 12 machine-proposed
configs the gate discovered {neumann, maxIterations:75, epsilon:1e-9}, which
solves 8/8 (meanDelta=0.70, lower95=0.70, verified-solve rate 0 -> 1). No human
authored that config.

Validation (verify-autonomous.mts, 12/12 checks): re-executes the ENTIRE
pipeline from sealed inputs -- re-derives the proposals from the seed (proving
they were not cherry-picked), re-runs the real solver on every config, re-gates,
and recomputes the gate's selection -- asserting the discovery reproduces
bit-for-bit, was machine-proposed, and genuinely solves more than the champion.

Honest scope: this is autonomous discovery of the configuration-search kind
(AutoML-style) over a designed space; the winning config is not authored by a
human. Open-ended LLM code synthesis over the same evaluate() seam is the
remaining frontier and needs an agent runtime + budget.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011cHoWPXP5UHwVaNYwjhvjn
Crosses the configuration-search frontier: the proposer is a real LLM
(claude -p) that emits arbitrary solver code, not a point in a designed grid.

- champion is plain Jacobi, which diverges on SPD-non-dominant systems, so
  no iteration count can win; only a real method change can
- each proposal passes a static safety gate (pure numeric ESM: no imports,
  I/O, eval, template literals) before it is allowed to run
- each genome runs in a sandboxed subprocess with a hard timeout
- the real ADR-076 gate selects any candidate that genuinely beats champion
- winner sealed with a replayable receipt + lineage

Discovery: claude -p autonomously proposed a preconditioned BiCGSTAB solver,
recognizing Jacobi diverges on SPD systems (not fixable by iteration count),
solving 8/8 where champion solves 0/8. Gate promoted it.

Honest reproducibility boundary: LLM output is non-deterministic, so the
proposal is not reproducible. verify-novel.mjs validates the discovered CODE
by re-execution: re-hashes the sealed genome, re-runs both solvers in the
sandbox, reproduces solve counts (0/8 vs 8/8) and the gate decision bit-for-bit
(hashJson(decision) === receipt.discovery.decisionHash). 9/9 checks pass.

Files: run-novel.mjs, verify-novel.mjs, src/llm-proposer.mjs,
src/genome-runner.mjs, novel/genome/champion.mjs, sealed novel/.
npm scripts: novel, verify:novel, prove:novel (added to test).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011cHoWPXP5UHwVaNYwjhvjn
Drives the REAL @claude-flow/guidance EvolutionPipeline that ruflo 3.24.0
ships (as a transitive dep of @claude-flow/cli), applied to this repo's own
contributor guidance, and seals a replayable, independently-verifiable receipt
for the policy promotion.

Corrects an earlier incomplete finding: the flywheel machinery is NOT absent
from npm. It ships inside @claude-flow/guidance, surfaced via `ruflo guidance`:
EvolutionPipeline (propose->simulate->compare->stage->promote/rollback),
ProofChain, ArtifactLedger, EnforcementGates, TrustAccumulator, ContinueGate.
It is just not a top-level `ruflo flywheel` command.

What evolves: a bounded retrieval policy. GUIDANCE.md compiles (real
GuidanceCompiler) into intent-tagged shards. Two policies differ by one knob:
- baseline: intent-blind (intent=general) -> retriever intent boost never fires
- candidate: intent-routed (intent=task) -> real +0.15 scoreShards boost fires

Metric: held-out intent-precision@2. Result driven by the real pipeline:
  baseline 0.250 -> candidate 1.000, drift 0.0375 <= 0.2 (canary gate),
  no regression, PROMOTED through canary -> partial -> full.

verify-flywheel.mjs re-executes from GUIDANCE.md and reproduces: bundle digest,
both precision numbers, divergence, gate verdict, promotion, decision hash
bit-for-bit, and recomputes the proposal HMAC to prove authenticity. 12/12 pass.
Only proposalId + createdAt (UUID/clock) are non-reproduced; the gate never
acts on them.

Defaults match the gist: $0 cost, no network (local HashEmbeddingProvider),
fail-closed, mutation explicit. Honest scope documented: HashEmbeddingProvider
is test-only (so the win is attributable to the real intent-boost mechanism,
not semantic embeddings), and ground-truth intents are a deterministic author
oracle, not human relevance judgments.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011cHoWPXP5UHwVaNYwjhvjn
Running `ruflo guidance` auto-wrote a signed retrieval config champion to
.claude/proven-config.json — this is part #1 of the ruflo 3.24.0 gist ("a
signed retrieval config champion that auto applies on upgrade when authenticity
and compatibility pass"). The exact adopted artifact is captured verbatim under
integrations/ruflo-flywheel/proven-config/ as committed evidence; I did not
author its numbers — ruflo produced them.

The champion carries the full gate receipt the gist describes: heldOutDelta
0.0738, redblue PASS, drift 0, canary rollbackRate 0 / costPerTask 0,
receiptCoverage 1.

The live .claude/ copies are ruflo's runtime state, left in place for it and
gitignored so they don't pollute the tracked .claude/ agent tree.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011cHoWPXP5UHwVaNYwjhvjn
Wires the ruflo 3.25.0 multi-model WASM embedder tier (miniLM, bge,
paraphrase-miniLM, GPU qwen3-0.6b) into the flywheel via the real
@claude-flow/guidance IEmbeddingProvider seam (createRetriever(provider)),
matching the gist's contract: optional, fail-closed, zero-regression.

Honest status: per ruvnet's own gist this is a dormant adapter seam —
@ruvector/lattice-wasm 404s on npm today (independently verified: npm view ->
E404). So this implements the SEAM, not a live model:
- absent package (today) -> fails closed to HashEmbeddingProvider; all sealed
  numbers are produced on that path -> zero regression.
- package present (future) -> retrieval upgrades to real embeddings, no code
  change; RUFLO_LATTICE_WASM_PKG / RUFLO_EMBED_MODEL point at it.

src/embedder.mjs probes the plausible wasm-bindgen surfaces the gist lists
(embed(text,model), embed(text), embedText, new Embedder(model).embed), runs a
verification probe, and falls through to hash on any failure — never throws.

verify-embedder.mjs proves the seam without fabricating the package: default ->
hash fallback; bad specifier -> fails closed; a LABELED local stub
(src/lattice-stub.mjs, explicitly not a real model) -> activation path fires and
the flywheel runs end-to-end on it; sealed fallback-path receipt reproduces
bit-for-bit -> zero regression. 11/11 pass. The flywheel's own verifier still
passes 12/12 (adding the tier changed nothing on the fallback path).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011cHoWPXP5UHwVaNYwjhvjn
ruvnet added a commit to ruvnet/metaharness that referenced this pull request Jul 6, 2026
…iscipline (ADR-235) (#93)

verifyReplayBundle wrongly FAILED an HONEST-NULL run (0 promotions): the chain is
just the immutable gen-0 root — a valid, signed, replayable result — but allPromoted
required >=1 promotion (`promos.length > 0 && ...`). The intent ("no rejected node
smuggled into the promoted chain") is satisfied VACUOUSLY by an empty non-root set.
Fix: `allPromoted = promos.every(c => c.verdict === 'PROMOTED')`. The real D1-S4
SWE-bench honest-null bundle (glm-5.2 resolved 1/25, 0 lift, $0.0086) now replays PASS.

Regression tests both directions (root-only PASSES; a smuggled non-PROMOTED commit
still FAILS). @metaharness/flywheel 0.1.2; healthcheck 8/8.

ADR-235 also adopts the "verifiers RE-EXECUTE from sealed inputs, trust no logs"
discipline (reviewed + locally PASS-verified from ruvnet/sublinear-time-solver#64's
metaharness-proof) as the standard, with the forward plan to store baseline+candidate
Score on each LineageCommit and re-run meetsPromotionRule to assert the verdict
reproduces bit-for-bit. meetsPromotionRule UNCHANGED.


Claude-Session: https://claude.ai/code/session_01V84YJJK7RBF9TuUo4eVSW7
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