mirror of
https://github.com/ruvnet/RuView
synced 2026-07-26 18:01:48 +00:00
ea7b5711a1
Iter 47. Ships the operator-facing quickstart as doc-as-code. Three
goals:
1. New operators reading the crate get a 50-line working example
instead of having to assemble pipeline + config + hasher + inputs
+ embedding + JSON publish themselves.
2. CI proves the example COMPILES and RUNS end-to-end via a
separate test that re-executes the same flow inline.
3. The example output is the canonical BfldEvent JSON, demonstrating
every documented field (presence/motion/count/conf/zone/class/
identity_risk_score/rf_signature_hash) for a typical Anonymous
class publish.
Added:
- v2/crates/wifi-densepose-bfld/examples/bfld_minimal.rs (~70 LOC):
* Per-site secret salt
* BfldPipeline::new(BfldConfig::new(...).with_signature_hasher(...))
* SensingInputs with low-risk factors so the gate emits
* IdentityEmbedding from a deterministic ramp
* pipeline.process(...).ok_or(...) for the gate-drop case
* event.to_json() printed to stdout
* Run command in the doc comment:
cargo run -p wifi-densepose-bfld --example bfld_minimal
- v2/crates/wifi-densepose-bfld/tests/example_minimal.rs (4 tests):
minimal_example_documents_the_operator_quickstart_flow
(asserts file contains BfldPipeline, SignatureHasher,
SensingInputs, IdentityEmbedding, BfldConfig, .process(,
to_json — catches doc drift if the example removes a key
symbol)
minimal_example_carries_run_instructions_in_doc_comments
(the cargo run --example line must be present)
minimal_example_flow_produces_valid_json_with_documented_fields
*** Re-runs the example flow inline and asserts every
documented JSON field appears in the output ***
example_returns_box_dyn_error_for_main_signature
(canonical Rust-example main signature)
- v2/crates/wifi-densepose-bfld/Cargo.toml:
[[example]] name = "bfld_minimal", required-features = ["serde-json"]
so `cargo test --no-default-features` doesn't try to build the
example (which needs to_json gated on serde-json).
Example run output (sanity check before commit):
{"type":"bfld_update","node_id":"seed-example","timestamp_ns":...,
"presence":true,"motion":0.42,"person_count":1,"confidence":0.91,
"privacy_class":"anonymous","identity_risk_score":0.0016000001,
"rf_signature_hash":"blake3:cc3615c7aaab9d0867a0c15327444b8f...bf"}
ADR-124 status (iter step 0 sibling check):
- docs/adr/ADR-124-rvagent-mcp-ruvector-npm-integration.md unchanged
at 431 lines. SENSE-BRIDGE scope remains orthogonal.
ACs progressed:
- ADR-118 §2.1 documentation surface — first operator-facing example
shipped as part of the crate. Discoverable via
`cargo run --example bfld_minimal` and verified via cargo test.
Test config:
- cargo test --no-default-features → 101 passed (example_minimal cfg-out)
- cargo test → 315 passed (311 + 4 example_minimal)
Out of scope (next iter target):
- PR-readiness pivot still pending: CHANGELOG, witness bundle,
AC closeout table. External-resource-gated work still skipped.
Co-Authored-By: claude-flow <ruv@ruv.net>
99 lines
3.5 KiB
Rust
99 lines
3.5 KiB
Rust
//! Validates the `examples/bfld_minimal.rs` operator-quickstart contract.
|
|
//! The example file embeds via include_str! for documentation-drift checks,
|
|
//! then a separate test re-executes the same end-to-end flow inline so we
|
|
//! get a CI-runnable proof that the operator workflow produces valid JSON.
|
|
|
|
#![cfg(feature = "std")]
|
|
|
|
use wifi_densepose_bfld::{
|
|
BfldConfig, BfldPipeline, IdentityEmbedding, SensingInputs, SignatureHasher, EMBEDDING_DIM,
|
|
SITE_SALT_LEN,
|
|
};
|
|
|
|
const MINIMAL_EXAMPLE: &str = include_str!("../examples/bfld_minimal.rs");
|
|
|
|
#[test]
|
|
fn minimal_example_documents_the_operator_quickstart_flow() {
|
|
// The example must call out the canonical operator-facing types so
|
|
// anyone reading it sees the right entry points.
|
|
assert!(MINIMAL_EXAMPLE.contains("BfldPipeline"));
|
|
assert!(MINIMAL_EXAMPLE.contains("SignatureHasher"));
|
|
assert!(MINIMAL_EXAMPLE.contains("SensingInputs"));
|
|
assert!(MINIMAL_EXAMPLE.contains("IdentityEmbedding"));
|
|
assert!(MINIMAL_EXAMPLE.contains("BfldConfig"));
|
|
assert!(
|
|
MINIMAL_EXAMPLE.contains(".process("),
|
|
"example must invoke pipeline.process(...) — method-chain style OK",
|
|
);
|
|
assert!(MINIMAL_EXAMPLE.contains("to_json"));
|
|
}
|
|
|
|
#[test]
|
|
fn minimal_example_carries_run_instructions_in_doc_comments() {
|
|
assert!(
|
|
MINIMAL_EXAMPLE.contains("cargo run -p wifi-densepose-bfld --example bfld_minimal"),
|
|
"example must document its own run command",
|
|
);
|
|
}
|
|
|
|
#[test]
|
|
fn minimal_example_flow_produces_valid_json_with_documented_fields() {
|
|
// Re-execute the same logic the example does so CI proves the flow
|
|
// works end-to-end without needing `cargo run --example`.
|
|
let site_salt: [u8; SITE_SALT_LEN] = [0xAB; SITE_SALT_LEN];
|
|
let mut pipeline = BfldPipeline::new(
|
|
BfldConfig::new("seed-example")
|
|
.with_signature_hasher(SignatureHasher::new(site_salt)),
|
|
);
|
|
let inputs = SensingInputs {
|
|
timestamp_ns: 1_700_000_000_000_000_000,
|
|
presence: true,
|
|
motion: 0.42,
|
|
person_count: 1,
|
|
sensing_confidence: 0.91,
|
|
sep: 0.2,
|
|
stab: 0.2,
|
|
consist: 0.2,
|
|
risk_conf: 0.2,
|
|
rf_signature_hash: None,
|
|
};
|
|
let mut emb_values = [0.0f32; EMBEDDING_DIM];
|
|
for (i, v) in emb_values.iter_mut().enumerate() {
|
|
*v = (i as f32) * 0.0073;
|
|
}
|
|
let embedding = IdentityEmbedding::from_raw(emb_values);
|
|
|
|
let event = pipeline
|
|
.process(inputs, Some(embedding))
|
|
.expect("low-risk emit must succeed");
|
|
let json = event.to_json().expect("JSON serialization must succeed");
|
|
|
|
// The published JSON should carry every documented anonymous-class field.
|
|
for needle in [
|
|
"\"type\":\"bfld_update\"",
|
|
"\"node_id\":\"seed-example\"",
|
|
"\"presence\":true",
|
|
"\"motion\":",
|
|
"\"person_count\":1",
|
|
"\"confidence\":",
|
|
"\"privacy_class\":\"anonymous\"",
|
|
"\"identity_risk_score\":",
|
|
"\"rf_signature_hash\":\"blake3:",
|
|
] {
|
|
assert!(
|
|
json.contains(needle),
|
|
"example JSON missing expected snippet `{needle}`\nfull JSON: {json}",
|
|
);
|
|
}
|
|
}
|
|
|
|
#[test]
|
|
fn example_returns_box_dyn_error_for_main_signature() {
|
|
// `main() -> Result<(), Box<dyn std::error::Error>>` is the standard
|
|
// Rust-example pattern. Confirm the file uses it so future copy-paste
|
|
// doesn't drop error propagation.
|
|
assert!(
|
|
MINIMAL_EXAMPLE.contains("fn main() -> Result<(), Box<dyn std::error::Error>>"),
|
|
);
|
|
}
|