Wave-8 close-the-gaps move 3. The five-lens cross-talk audit
(Phillip / Rafie / Bloom / Hyper-Agent / Priscilla) named the same
on-ramp gap from five different vocabularies: *"100 crates, one
end-to-end example."* This commit closes it.
Six runnable starter cascades, each ≤ 120 LOC, one per use case
the audits surfaced. Every example builds with `cargo run -p
jouleclaw-stack --example <name>` and produces a meaningful output
out of the box.
## The six examples
minimal_cache_only.rs The smallest cascade walk. Ask the
same question twice, watch the L0
cache serve the repeat at floor
energy. (Phillip: text-is-state.)
rag_with_retrieval.rs Seeded local index → retrieve →
enrich → rerank → read pipeline,
with per-stage joule trace. (Bloom:
the verifiable zone in action.)
comprehend_demo.rs `Stack::comprehend` against a
seeded corpus, with HeuristicClassifier
installed. Prints passages,
extracted answer, intent verdict,
and the verifiable-zone invariant.
(Priscilla: *understand before you
generate*.)
agent_with_skill_induction.rs Register a Skill with a template
matcher + Format procedure, watch
the cascade resolve a whole query
class at L0.5 — nanojoules, no
model invocation. (Phillip:
agent-ready APIs.)
save_memory_and_promote.rs Demonstrates Hyper-Agent's three
modes of memory on JouleClaw's
primitives: manual save_memory,
plus an FnPromotionListener
capturing a NotifyPromotedFact
event when a verified compartment
answer is promoted. (Hyper-Agent:
three modes of memory.)
ledger_breakdown.rs Constructs a 7-receipt synthetic
workload over jouleclaw-ledger,
prints a CostSummary by tier /
tool / model / intent. The output
reproduces a Priscilla-style 67/2-
ish breakdown on a controlled
fixture. (Rafie: breakdown at the
top.)
## AGENTS.md companion
`examples/AGENTS.md` indexes the six with a one-line "what it shows"
and the audit lens each serves. The doctrine in one line:
*Inference is the last resort, not the entry point.* (SPEC §1.1)
Discovered automatically by `jouleclaw-agents-md` via the hierarchical
walk; an operator who drops their own AGENTS.md alongside picks up
the starter notes without configuration.
## Test infrastructure
`[dev-dependencies]` in `jouleclaw-stack/Cargo.toml` extended with
`jouleclaw-prov`, `jouleclaw-energy`, `jouleclaw-ledger`,
`jouleclaw-local-index`, `jouleclaw-skill` — needed by examples and
documented as such ("Direct deps the starter examples reach for").
These do not affect the library surface.
All six examples smoke-tested:
minimal_cache_only first ask L3 / second ask L0 (cache hit)
rag_with_retrieval extracts "Paris" from seeded index
comprehend_demo highest tier = L2.5 (invariant), intent
tagged as comprehension (80% confidence)
agent_with_skill_induction three countries all resolve at L0.5
(~40 nanojoules each)
save_memory_and_promote manual capture + listener fires once
ledger_breakdown 7 receipts → 71.4% / 14.3% comprehension /
generation (close to Priscilla's 67% / 2%)
Workspace regression: 0 failures.
82 lines
3.1 KiB
Rust
82 lines
3.1 KiB
Rust
//! `comprehend_demo` — *understand before you generate.*
|
||
//!
|
||
//! Drives `JouleClawStack::comprehend` against a seeded corpus. The
|
||
//! cascade walks only the L0–L2.5 verifiable zone — never the L3 model
|
||
//! — and returns a [`ComprehensionTrace`] with every passage that
|
||
//! grounded the answer, per-stage joule attribution, the optional
|
||
//! extractive answer from the L1.5 reader, and (when a classifier is
|
||
//! installed) the query's intent verdict.
|
||
//!
|
||
//! This is the Priscilla-from-Sentry surface: the 67%-comprehension
|
||
//! workload made operationally visible.
|
||
//!
|
||
//! Run with:
|
||
//! cargo run -p jouleclaw-stack --example comprehend_demo
|
||
|
||
use jouleclaw_intent::HeuristicClassifier;
|
||
use jouleclaw_local_index::{Document, InMemoryIndex, LocalIndexTier};
|
||
use jouleclaw_stack::{ComprehensionConfig, JouleClawStack};
|
||
|
||
fn main() {
|
||
// Seed a tiny set of facts.
|
||
let mut idx = InMemoryIndex::new();
|
||
idx.insert(Document::new("d1", "The capital of France is Paris."));
|
||
idx.insert(Document::new("d2", "The capital of Germany is Berlin."));
|
||
idx.insert(Document::new("d3", "The capital of Italy is Rome."));
|
||
|
||
let mut stack = JouleClawStack::with_defaults()
|
||
.with_intent_classifier(Box::new(HeuristicClassifier::new()));
|
||
stack.local_index = LocalIndexTier::new(idx);
|
||
|
||
let cfg = ComprehensionConfig {
|
||
use_federation: false,
|
||
use_graph_enrich: false,
|
||
..ComprehensionConfig::default()
|
||
};
|
||
let trace = stack.comprehend_with("explain what the capital of France is", 100.0, &cfg);
|
||
|
||
println!("comprehension trace:");
|
||
println!(" question {}", trace.question);
|
||
println!(
|
||
" highest tier touched {} (verifiable-zone invariant)",
|
||
trace.highest_tier_touched
|
||
);
|
||
println!(" joules spent {:.6}", trace.joules_spent);
|
||
println!(" budget exhausted {}", trace.budget_exhausted);
|
||
if let Some(intent) = &trace.intent {
|
||
println!(
|
||
" intent {} ({:.0}% confident, classifier={})",
|
||
intent.intent.label(),
|
||
intent.confidence * 100.0,
|
||
intent.classifier_id
|
||
);
|
||
}
|
||
println!();
|
||
println!("passages ({} total, in best-first order):", trace.passages.len());
|
||
for (i, p) in trace.passages.iter().enumerate() {
|
||
let src = p.source.as_deref().unwrap_or("(no source)");
|
||
let score = p
|
||
.rerank_score
|
||
.map(|s| format!("{s:.3}"))
|
||
.unwrap_or_else(|| "—".into());
|
||
println!(" [{i}] (score={score}) [{src}]");
|
||
println!(" {}", p.text);
|
||
}
|
||
println!();
|
||
if let Some(extracted) = trace.extracted_answer {
|
||
println!("extracted answer: {extracted}");
|
||
println!("confidence: {:.3}", trace.confidence);
|
||
} else {
|
||
println!("(reader produced no extractive answer)");
|
||
}
|
||
println!();
|
||
println!("per-stage trace:");
|
||
for s in &trace.stages {
|
||
println!(
|
||
" {stage:<26} {joules:>10.6} J {note}",
|
||
stage = s.stage,
|
||
joules = s.joules,
|
||
note = s.note
|
||
);
|
||
}
|
||
}
|