rtb-telemetry 0.7.2

Opt-in anonymous usage telemetry with pluggable sinks. Part of the phpboyscout Rust toolkit.
Documentation
Feature: rtb-telemetry — opt-in anonymous telemetry pipeline
  As a tool author
  I want a pluggable, two-level opt-in telemetry pipeline
  So that users control their data and sink choice is my call

  Scenario: S1 — Disabled context emits nothing
    Given a TelemetryContext with a MemorySink and Disabled policy
    When I record "should.not.emit"
    Then the sink recorded 0 events

  Scenario: S2 — Enabled context emits one event
    Given a TelemetryContext with a MemorySink and Enabled policy
    When I record "enabled.one"
    Then the sink recorded 1 events
    And the last event name is "enabled.one"

  Scenario: S3 — record_with_attrs attaches the attrs map
    Given a TelemetryContext with a MemorySink and Enabled policy
    When I record "with.attrs" with attrs "command=deploy;outcome=ok"
    Then the last event attribute "command" is "deploy"
    And the last event attribute "outcome" is "ok"

  Scenario: S4 — Two sequential records appear in order
    Given a TelemetryContext with a MemorySink and Enabled policy
    When I record "first"
    And I record "second"
    Then the sink recorded 2 events
    And the event at index 0 has name "first"
    And the event at index 1 has name "second"

  Scenario: S5 — FileSink writes JSONL
    Given a new FileSink with a temporary path
    When I emit an event named "disk.one"
    Then the file contains a JSON line with name "disk.one"

  Scenario: S6 — MachineId::derive with a fixed salt is stable
    Given I derive the machine id with salt "bdd-salt-1"
    When I derive the machine id with salt "bdd-salt-1" again
    Then the two ids are equal
    And each id is 64 hex characters

  Scenario: S7 — FileSink redacts args and err_msg before writing to disk
    Given a new FileSink with a temporary path
    When I emit an event named "cmd.run" with args "deploy --token ghp_aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" and err_msg "auth: Bearer ghp_aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
    Then the file does not contain "ghp_aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
    And the file contains a JSON line with name "cmd.run"

  @remote-sinks
  Scenario: S8 — HttpSink posts redacted JSON to the configured endpoint
    Given a wiremock server that accepts telemetry at "/ingest"
    When I emit an HttpSink event named "cmd.http" with err_msg "auth: Bearer ghp_aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
    Then the wiremock server received 1 request
    And the received body contains severity ERROR
    And the received body does not contain "ghp_aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"

  @remote-sinks
  Scenario: S9 — OtlpSink rejects an endpoint with no recognised scheme
    When I build an OtlpSink targeting "tcp://not-a-collector"
    Then OtlpSink construction fails with an Otlp error