open-standards/jouleclaw/jouleclaw-rs/crates/jouleclaw-stack/examples/wave46_recall_fuzz_verified.rs
Transaction Science 781c8d446f jouleclaw: wave-46 — ingest from today's SOTA research
Five concrete deliverables absorbing patterns from the day's research
(Hermes Desktop, turbovec, Axiom Math, Valkey/Madelyn Olson, Jerry Liu)
into the JouleClaw substrate. Each lands in an existing or new crate
without rearchitecting; all pure-Rust, no external runtime deps;
composable with the triangle just shipped.

1. jouleclaw-context-store (new crate) — typed deterministic recall.
   - TurnStore: SQLite + FTS5 over agent/CLI/chat turns. ~20ms per
     query at zero LLM cost. Microjoule-class recall as a first-class
     primitive between L0 cache and L2 embedding+retrieval.
   - FrozenSnapshot + StagedSnapshot: bounded byte-budget memory +
     user blocks. Mutations don't surface mid-session — they persist
     immediately but only the next session loads them. Rationale:
     keep the LLM prefix-cache warm. The byte block at the top of
     every prompt in a session is byte-identical, so providers can
     amortize attention over it.
   - 12 tests, all green. Ingested from Hermes Agent's documented
     memory pattern.

2. jouleclaw-oracle-fuzz (new crate) — adversarial Oracle backend.
   - FuzzOracle<P>: implements jouleclaw-oracle::Oracle over a
     caller-supplied deterministic FuzzProperty. Seeds ChaCha20 with
     (seed, round) to produce reproducible inputs; short-circuits on
     first counterexample with the structured FuzzFailure carried in
     FailReason::Custom.
   - Composes via CompositeOracle alongside type-checkers / linters /
     a future Lean Oracle.
   - 6 tests including determinism (same seed → byte-equal verdict)
     and composition. Ingested from the OSS-maintainer crash-harness
     pattern (Valkey CVE hunt).

3. jouleclaw-cone — cone-gated context injection.
   - cone_gated_inject helper + InjectDecision { Full | Skip } enum.
     Catalog (skills / tools / memory) is injected ONLY when the
     request's novelty crosses a configured threshold; below it, the
     agent uses cheap on-demand lookup tools instead of paying the
     unconditional prompt-token cost.
   - 4 new tests on top of the existing 23. Ingested from Hermes's
     own issue #4379 documenting catalog-injection token bloat.

4. jouleclaw-jcr1 — verified-code/1 receipt schema.
   - VerifiedCodeReceipt + ProgramRef + SpecRef + ProofRef
     { Lean | Fuzz | TestSuite } + VerifierRef + VerifiedCodeVerdict
     { Pass | Fail }. Canonical JSON with sorted keys; content-
     addressed via BLAKE3; ready for COSE_Sign1 over the canonical
     bytes via the existing v1 signing path.
   - 2 conformance vectors (Lean Pass + Fuzz Fail) with embedded
     content_hash that the Rust verifier asserts byte-equal at test
     time. Other-language verifiers MUST round-trip under canonical
     encoding and match the hash.
   - 5 verified_code tests. Ingested from the Axiom Math /
     "code-with-proof" pattern (Verina benchmark).

5. Demo binary — examples/wave46_recall_fuzz_verified.rs in
   jouleclaw-stack. Runs all five primitives end-to-end in one
   cargo run: seed FTS5 store, search, build + freeze snapshot, gate
   catalog injection by cone novelty, run fuzz Oracle over a property
   in two directions (pass + fail), mint a verified-code/1 receipt
   over the pass. Output is reproducible and self-checking.

The triangle is the type system; these five are concrete backends +
schemas + helpers that fill load-bearing slots the triangle types up
but leaves to consumers. None of them invalidate prior waves; each
sits beneath inference per doctrine.

Workspace check clean.

Co-Authored-By: Claude Opus 4.7 <[email protected]>
2026-06-05 03:56:59 -04:00

214 lines
8.8 KiB
Rust

//! `wave46_recall_fuzz_verified` — the wave-46 ingest demo.
//!
//! Wires the five new primitives shipped this wave into one runnable
//! pipeline:
//!
//! 1. **Context store** ([`jouleclaw_context_store`]) — seed an FTS5
//! turn store with a few previous sessions; show that recall over
//! them is microjoule-class with no LLM call.
//! 2. **Frozen snapshot** — build a bounded memory + user block; show
//! that staged mutations don't surface in the current session
//! (the prefix-cache stays warm).
//! 3. **Cone-gated injection** ([`jouleclaw_cone::cone_gated_inject`])
//! — for a low-novelty request, the skills catalog is SKIPPED
//! (the agent uses on-demand lookup instead of paying the prompt-
//! token cost); for a high-novelty request, it's INJECTED.
//! 4. **Fuzz Oracle** ([`jouleclaw_oracle_fuzz::FuzzOracle`]) — run a
//! deterministic property over 256 seeded inputs; on pass, mint a
//! `verified-code/1` JCR-1 receipt; on fail, mint the same with a
//! counterexample.
//! 5. **JCR-1 receipt** ([`jouleclaw_jcr1::VerifiedCodeReceipt`]) —
//! canonical JSON, content-addressed, ready for the steward to
//! sign.
//!
//! Run:
//! cargo run -p jouleclaw-stack --example wave46_recall_fuzz_verified
use jouleclaw_context_store::{
DEFAULT_MEMORY_BUDGET_BYTES, DEFAULT_USER_BUDGET_BYTES, FrozenSnapshot, StagedSnapshot,
TurnRecord, TurnStore,
};
use jouleclaw_cone::{BandDispatch, ConeCoord, NoveltyBand, cone_gated_inject};
use jouleclaw_oracle::{Candidate, Oracle};
use jouleclaw_oracle_fuzz::{FuzzOracle, FuzzProperty};
use jouleclaw_jcr1::{
ProgramRef, ProofRef, SpecRef, VerifiedCodeReceipt, VerifierRef,
};
const CLOSED_AT: &str = "2026-06-05T00:00:00Z";
const STEWARD: &str = "did:keri:EJ9testStewardAID000000000000000";
/// A property: the candidate's content (interpreted as Rust source)
/// never contains the substring `"unsafe"`. The fuzz inputs are
/// ignored — this is a property of the candidate, not of inputs.
/// (Real callers parameterize on inputs; we keep this tight for the
/// demo.)
struct NoUnsafe;
impl FuzzProperty for NoUnsafe {
fn id(&self) -> &str {
"no-unsafe"
}
fn check(&self, candidate: &Candidate, _input: &[u8]) -> Result<(), String> {
if candidate.content.contains("unsafe") {
Err("candidate contains `unsafe`".into())
} else {
Ok(())
}
}
}
#[tokio::main(flavor = "current_thread")]
async fn main() {
// ── 1. Context store: FTS5 over prior session turns ────────────
println!("== 1. Context store (FTS5 turn search) ==");
let store = TurnStore::in_memory().expect("open store");
for (role, text, ts) in [
("user", "yesterday we discussed prefix-cache preservation", 100),
("agent", "the frozen-snapshot pattern keeps the prompt block byte-stable", 101),
("user", "and the FTS5 search over sessions is microjoules", 102),
("user", "what was the magic word from last week?", 103),
("agent", "the magic word, as previously discussed, is `please`", 104),
] {
store
.record(&TurnRecord {
session_id: "session-1".into(),
role: role.into(),
content: text.into(),
ts_unix_secs: ts,
})
.expect("record");
}
let hits = store.search("magic word", 3).expect("search");
println!(" query=\"magic word\" hits={}", hits.len());
for h in &hits {
println!(" [{:.3}] {} > {}", h.score, h.turn.role, h.turn.content);
}
println!();
// ── 2. Frozen snapshot: bounded, prefix-cache-stable ───────────
println!("== 2. Frozen snapshot (bounded; mutations deferred) ==");
let base = FrozenSnapshot::build(
"Working on JouleClaw wave-46 ingest from Hermes / Axiom / Valkey research.",
"David — Founder of openIE / Transaction Science. Prefers terse honest engineering.",
DEFAULT_MEMORY_BUDGET_BYTES,
DEFAULT_USER_BUDGET_BYTES,
)
.expect("build snapshot");
println!(" base hash: {}", &base.hash[..16]);
println!(" base block bytes: {}", base.frozen_block().len());
let mut staged = StagedSnapshot::from_base(base.clone());
staged
.stage_memory("(updated) wave-46 shipped: context-store, oracle-fuzz, cone-gated.")
.stage_user(
"David — Founder of openIE / Transaction Science. Prefers terse honest engineering.",
);
// Current session STILL sees the base block — staged mutations
// don't surface, by design. The LLM's prefix cache hash stays
// identical across the whole session.
assert_eq!(staged.current_block(), base.frozen_block());
println!(" current-session block UNCHANGED — prefix cache preserved.");
let next = staged
.freeze(DEFAULT_MEMORY_BUDGET_BYTES, DEFAULT_USER_BUDGET_BYTES)
.expect("freeze");
println!(" next-session hash: {}", &next.hash[..16]);
println!(" (mutations surface only when the next session loads it)\n");
// ── 3. Cone-gated catalog injection ────────────────────────────
println!("== 3. Cone-gated catalog injection ==");
let dispatch = BandDispatch::new(NoveltyBand::datum_default()).expect("valid band");
// Low-novelty: catalog SKIPPED, agent uses on-demand lookup.
let low = ConeCoord::new(0.1, 0.1);
let dec_low = cone_gated_inject(&dispatch, low, 0.5, "skills");
println!(
" low-novelty (n=0.10) → {} (tier={})",
if dec_low.should_inject() { "INJECT" } else { "SKIP" },
dec_low.tier_id()
);
// High-novelty: catalog INJECTED.
let high = ConeCoord::new(0.5, 0.9);
let dec_high = cone_gated_inject(&dispatch, high, 0.5, "skills");
println!(
" high-novelty (n=0.90) → {} (tier={})",
if dec_high.should_inject() { "INJECT" } else { "SKIP" },
dec_high.tier_id()
);
println!();
// ── 4. Fuzz Oracle over a deterministic property ──────────────
println!("== 4. Adversarial fuzz Oracle ==");
let safe_candidate = Candidate {
id: "safe-1".into(),
content: "fn add(a: i32, b: i32) -> i32 { a + b }".into(),
language: "rust".into(),
source_tier: "lut".into(),
provenance: "demo".into(),
};
let oracle = FuzzOracle::smoke("fuzz/no-unsafe", NoUnsafe);
let v_pass = oracle.verify(&safe_candidate).await.expect("oracle");
println!(" safe candidate verdict: {}", verdict_tag(&v_pass));
let unsafe_candidate = Candidate {
id: "unsafe-1".into(),
content: "fn raw() { unsafe { *(0 as *mut u8) = 0 } }".into(),
language: "rust".into(),
source_tier: "lut".into(),
provenance: "demo".into(),
};
let v_fail = oracle.verify(&unsafe_candidate).await.expect("oracle");
println!(" unsafe candidate verdict: {}", verdict_tag(&v_fail));
println!();
// ── 5. Mint a verified-code/1 JCR-1 receipt over the pass ─────
println!("== 5. verified-code/1 JCR-1 receipt ==");
let program = ProgramRef {
language: "rust".into(),
content_hash: hex_blake3(safe_candidate.content.as_bytes()),
byte_length: safe_candidate.content.len() as u64,
};
let spec = SpecRef {
content_hash: hex_blake3(b"no `unsafe` in candidate"),
summary: "no `unsafe` in candidate".into(),
};
let proof = ProofRef::Fuzz {
property_id: "no-unsafe".into(),
seed: 0,
rounds: 256,
};
let verifier = VerifierRef {
id: "jouleclaw-oracle-fuzz".into(),
version: env!("CARGO_PKG_VERSION").into(),
};
let receipt = VerifiedCodeReceipt::pass(
"vcr-wave46-0001",
CLOSED_AT,
STEWARD,
program,
spec,
proof,
verifier,
vec!["fuzz/no-unsafe".into(), "no-unsafe".into()],
);
let canonical = receipt.canonical_bytes().expect("canonical");
let hash = receipt.content_hash().expect("hash");
println!(" schema: verified-code/1");
println!(" receipt id: {}", receipt.id);
println!(" canonical: {} bytes", canonical.len());
println!(" content hash: {hash}");
println!(" (this is the payload the steward signs; verifiers re-canonicalize and check)");
println!();
println!("✓ Wave-46 substrate works end-to-end:");
println!(" FTS5 turn recall → frozen snapshot → cone-gated → fuzz Oracle → JCR-1 receipt");
}
fn verdict_tag(v: &jouleclaw_oracle::Verdict) -> &'static str {
match v {
jouleclaw_oracle::Verdict::Pass { .. } => "PASS",
jouleclaw_oracle::Verdict::Fail { .. } => "FAIL",
}
}
fn hex_blake3(bytes: &[u8]) -> String {
blake3::hash(bytes).to_hex().to_string()
}