wifi-densepose/v2/crates/wifi-densepose-bfld/tests
ruv d7d500f5d8 feat(adr-118/p6.7): apply_privacy_gating irreversibility tests (255/255 GREEN)
Iter 38. Pins ADR-120 §2.4 ("There is no `promote` operation") at the
BfldEvent::apply_privacy_gating soft-mutation surface. Iter 9's
PrivacyGate::demote tests already proved this for the explicit
class-transition transformer; this iter proves it for the *soft*
in-place re-classifier used by BfldPipeline::process() under
enable_privacy_mode().

Defense-in-depth property: an attacker who manages to flip
event.privacy_class from Restricted back to Anonymous cannot then
resurrect the stripped identity fields through apply_privacy_gating
alone. They'd have to fabricate the fields via direct field assignment
or rebuild via with_privacy_gating — both of which are conspicuous in
code review (single byte flip is not).

Added (in tests/event_gating_irreversibility.rs):
- 7 named tests, all green:

  apply_at_anonymous_preserves_identity_fields
    Sanity: apply doesn't strip when class is Anonymous.

  manual_class_flip_to_restricted_then_apply_strips_both_fields
    Direct path: class Anonymous → flip to Restricted → apply
    → identity_risk_score and rf_signature_hash both None.

  one_way_strip_survives_class_flip_back_to_anonymous
    *** HEADLINE TEST ***
    Anonymous → flip to Restricted → apply (strip) → flip back to
    Anonymous → apply → fields STILL None. apply_privacy_gating
    must not resurrect.

  manual_field_restoration_after_strip_only_works_via_explicit_assignment
    The escape hatch is direct field assignment (visible in code
    review), not the soft gate. Confirms: after explicit
    Some(0.42) reassignment + class=Anonymous + apply, the
    values survive.

  apply_at_already_restricted_with_already_none_fields_is_a_noop
    Idempotency on stripped-state.

  one_way_property_holds_through_multiple_class_round_trips
    Stress: 5 Restricted→apply→Anonymous→apply cycles. Fields
    must stay None throughout — no slow-resurrection bug.

  rebuilding_via_with_privacy_gating_is_the_documented_restoration_path
    Pins the doc contract: to publish identity fields again after
    a strip, build a fresh BfldEvent. The constructor accepts
    explicit Some(...) values; apply_privacy_gating then doesn't
    strip because class is Anonymous.

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-120 §2.4 "no promote operation" now structurally proven at the
  SOFT (apply_privacy_gating) path in addition to the EXPLICIT
  (PrivacyGate::demote) path that iter 9 covered. Both layers of
  the privacy gate carry the one-way-only invariant.
- ADR-118 invariant I1 — once stripped, raw identity fields can only
  be re-introduced through paths visible in code review (direct
  field assignment, fresh constructor). No subtle byte-flip path
  resurrects them.

Test config:
- cargo test --no-default-features → 80 passed (event_gating_irreversibility cfg-out)
- cargo test                       → 255 passed (248 + 7)

Out of scope (next iter target):
- PR-readiness pivot: CHANGELOG, witness bundle, AC closeout table.
  External-resource-gated work (KIT BFId, Pi5/Nexmon) still skipped.

Co-Authored-By: claude-flow <ruv@ruv.net>
2026-05-24 19:04:00 -04:00
..
availability_topic.rs feat(adr-118/p5.8): availability topic + LWT integration (203/203 GREEN) 2026-05-24 17:57:55 -04:00
ci_workflow.rs feat(adr-118/p6.5): GitHub Actions mosquitto Docker CI workflow (235/235 GREEN) 2026-05-24 18:49:49 -04:00
coherence_gate.rs feat(adr-118/p3.3): CoherenceGate hysteresis + 5s debounce — 85/85 GREEN 2026-05-24 15:07:40 -04:00
embedding_ring.rs feat(adr-118/p2.2): EmbeddingRing 64-entry FIFO buffer — 53/53 GREEN 2026-05-24 14:37:03 -04:00
emitter_hasher.rs feat(adr-118/p4.3): wire SignatureHasher into BfldEmitter (123/123 GREEN) 2026-05-24 15:57:44 -04:00
emitter_pipeline.rs feat(adr-118/p4.2): BfldEmitter end-to-end pipeline (109/109 GREEN) 2026-05-24 15:37:23 -04:00
event_gating_irreversibility.rs feat(adr-118/p6.7): apply_privacy_gating irreversibility tests (255/255 GREEN) 2026-05-24 19:04:00 -04:00
event_privacy_gating.rs feat(adr-118/p4.1): BfldEvent privacy-gated output + JSON (102/102 GREEN) 2026-05-24 15:27:49 -04:00
frame_header_size.rs feat(adr-118/p1): scaffold wifi-densepose-bfld crate + frame header (3/3 tests GREEN) 2026-05-24 13:34:05 -04:00
frame_payload_integration.rs feat(adr-118/p1.6): BfldFrame <-> BfldPayload wire integration (39/39 GREEN) 2026-05-24 14:16:54 -04:00
frame_roundtrip.rs feat(adr-118/p1.4): BfldFrame (header + payload + CRC32) — 24/24 GREEN 2026-05-24 13:58:26 -04:00
ha_blueprints.rs feat(adr-118/p5.10): three HA operator blueprints (210/210 GREEN) 2026-05-24 18:17:41 -04:00
ha_discovery.rs feat(adr-118/p5.6): HA auto-discovery payload publisher (187/187 GREEN) 2026-05-24 17:37:26 -04:00
ha_discovery_publish.rs feat(adr-118/p5.7): publish_discovery bootstrap helper (193/193 GREEN) 2026-05-24 17:47:17 -04:00
handle_soul_oracle.rs feat(adr-118/p6.4): spawn_with_oracle for Soul Signature deployments (227/227 GREEN) 2026-05-24 18:45:54 -04:00
header_roundtrip.rs feat(adr-118/p1.2): header encode/decode + 6 round-trip tests (9/9 GREEN) 2026-05-24 13:38:11 -04:00
identity_embedding.rs feat(adr-118/p2.1): IdentityEmbedding newtype + zeroizing Drop — 44/44 GREEN 2026-05-24 14:27:28 -04:00
identity_features_encoder.rs feat(adr-118/p3.6): IdentityFeatures canonical-bytes encoder (137/137 GREEN) 2026-05-24 16:18:33 -04:00
identity_risk_score.rs feat(adr-118/p3.2): identity_risk score + GateAction enum — 72/72 GREEN 2026-05-24 14:57:08 -04:00
json_hash_format.rs feat(adr-118/p4.4): rf_signature_hash JSON as "blake3:<hex>" (128/128 GREEN) 2026-05-24 16:08:29 -04:00
mosquitto_integration.rs feat(adr-118/p5.4): mosquitto integration test (env-gated, 178/178 with mqtt) 2026-05-24 17:17:38 -04:00
motion_publish_rate.rs feat(adr-118/p6.3): motion publish rate ≥ 1Hz integration test (ADR-122 AC3) — 224/224 GREEN 2026-05-24 18:39:58 -04:00
mqtt_publish_loop.rs feat(adr-118/p5.2): Publish trait + publish_event free function — 169/169 GREEN 2026-05-24 16:57:05 -04:00
mqtt_topic_routing.rs feat(adr-118/p5.1): MQTT topic router (BfldEvent → Vec<TopicMessage>) — 162/162 GREEN 2026-05-24 16:47:11 -04:00
payload_sections.rs feat(adr-118/p1.5): payload section parser (BfldPayload) — 32/32 GREEN 2026-05-24 14:07:14 -04:00
pipeline_determinism.rs feat(adr-118/p6.6): pipeline event-stream JSON determinism (248/248 GREEN) 2026-05-24 18:59:29 -04:00
pipeline_facade.rs feat(adr-118/p4.5): BfldPipeline facade + BfldConfig (146/146 GREEN) 2026-05-24 16:28:42 -04:00
pipeline_handle_worker.rs feat(adr-118/p5.5): BfldPipelineHandle worker thread (177/177 GREEN) 2026-05-24 17:27:48 -04:00
pipeline_i3_isolation.rs feat(adr-118/p6.1): end-to-end I3 isolation proof via BfldPipeline (217/217 GREEN) 2026-05-24 18:32:01 -04:00
pipeline_to_frame.rs feat(adr-118/p4.6): BfldPipeline::process_to_frame wire-bytes path (152/152 GREEN) 2026-05-24 16:37:11 -04:00
privacy_gate_demote.rs feat(adr-118/p3.1): PrivacyGate::demote monotonic class transformer (60/60 GREEN) 2026-05-24 14:48:01 -04:00
reserved_flags.rs feat(adr-118/p1.7): reserved-flag-bits forward-compat (243/243 GREEN) 2026-05-24 18:55:04 -04:00
rumqttc_lwt.rs feat(adr-118/p5.9): RumqttPublisher::connect_with_lwt — broker auto-publishes "offline" (220/220 GREEN with mqtt) 2026-05-24 18:08:59 -04:00
rumqttc_publisher_smoke.rs feat(adr-118/p5.3): RumqttPublisher behind mqtt feature gate (176/176 GREEN with mqtt) 2026-05-24 17:09:05 -04:00
serialization_throughput.rs feat(adr-118/p6.2): serialization throughput test (ADR-119 AC7) — 221/221 GREEN 2026-05-24 18:35:48 -04:00
signature_hasher.rs feat(adr-118/p3.5): SignatureHasher (BLAKE3-keyed) — 117/117 GREEN 2026-05-24 15:47:21 -04:00
sink_enforcement.rs feat(adr-118/p1.3): Sink marker traits + PrivacyClass::try_from (17/17 GREEN) 2026-05-24 13:43:05 -04:00
soul_match_oracle.rs feat(adr-118/p3.4): SoulMatchOracle + Recalibrate exemption (93/93 GREEN) 2026-05-24 15:17:24 -04:00