You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Add an opt-in plaintext message trace for conformance tooling - #205
Many sendspin-cpp client cases in the conformance matrix fail because the adapter cannot see the messages the library exchanges: received audio hashes, raw chunk frames, and the protocol-baseline trace. This adds an opt-in plaintext trace, mirroring sendspin-server-cpp's ServerConfig::trace.
Change
SENDSPIN_ENABLE_MESSAGE_TRACE: a host-only CMake option, off by default, with no Kconfig entry. With it off, the build is unchanged, ESP included.
SendspinClientConfig::message_trace receives a SendspinTracedMessage for every message on the protocol task. Each one carries:
connection id, direction and stamp
the plaintext: inbound after decryption and reassembly, outbound before encryption (each fragment on its own), plus the cleartext handshake
audio_bytes: for a player audio chunk, the encoded audio it carries
The pairing secrets a client sends (long_term_psk, wrapped_psk, wrapped_nonce_B) read "<redacted>".
MessageTracer (src/message_trace.h) is owned per connection. The trace points are gated inline in connection.cpp and in NoiseTransport::encrypt_in_place().
The gate is listed in CLAUDE.md, conventions.md, internals.md and the house-patterns skill. integration-guide.md documents the option.
CI's test and TSan jobs build with the trace on; the build and no-opus jobs leave it off.
Notes
Once this lands, the conformance adapter (adapters/sendspin-cpp/client/main.cpp in Sendspin/conformance) needs updating to turn the option on and read the trace.
Tests
End-to-end against the fake encrypted server, read only through the trace. It asserts:
the exact opening sequence from client/init to server/activate, with the transport JSON readable
an audio chunk's audio_bytes
a single connection id, and stamps on the client clock
A redaction table whose secret rows are built by the real pairing formatters, with control rows: a message without secrets and a binary message reach the trace unchanged and uncopied.
Not covered by any test: inbound reassembly and outbound fragmentation.
Adds SendspinClientConfig::message_trace behind SENDSPIN_ENABLE_MESSAGE_TRACE,
a host-only CMake option that is off by default and has no Kconfig entry.
The callback receives every protocol message's plaintext on the protocol
task: inbound after decryption and reassembly, outbound before encryption,
and the cleartext handshake. It mirrors sendspin-server-cpp's
ServerConfig::trace, so the conformance harness can observe sendspin-cpp's
messages and audio chunks.
clang-tidy analyzes every src/ file against the default build's compile
database, where the trace is off, so message_trace.cpp was analyzed
without its macro. Generate the database with the trace on.
The secret-bearing rows of the redaction test are now built by the client's
own formatters, so a change to how they spell a field fails the test. The
conventions threading rule names message_trace as the protocol task's one
consumer callback. clang-tidy.sh configures its own build-tidy directory with
the trace on every run, so it never reuses a trace-off build or changes the
main one.
Verify unchanged secret bytes, not just pointer and length
tests/test_message_trace.cpp:244
The no-secret controls only verify that the pointer was not copied; they do not verify the claimed unchanged bytes. A regression that reports the original pointer with a truncated plaintext_len would still pass, so also compare the captured value with row.sent.
Label redaction table accepting rows as Control
tests/test_message_trace.cpp:221
These are the accepting controls for the redaction table, but they are not labeled as such. The repository’s testing convention requires accepting rows to be visibly marked Control: so a failure cannot be mistaken for a rejection case; rename both control rows accordingly.
The pass-through rows now compare the traced bytes with what was sent, so a
wrong plaintext_len fails them, and carry the Control: label the test
standards require.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Many sendspin-cpp client cases in the conformance matrix fail because the adapter cannot see the messages the library exchanges: received audio hashes, raw chunk frames, and the protocol-baseline trace. This adds an opt-in plaintext trace, mirroring sendspin-server-cpp's
ServerConfig::trace.Change
SENDSPIN_ENABLE_MESSAGE_TRACE: a host-only CMake option, off by default, with no Kconfig entry. With it off, the build is unchanged, ESP included.SendspinClientConfig::message_tracereceives aSendspinTracedMessagefor every message on the protocol task. Each one carries:audio_bytes: for a player audio chunk, the encoded audio it carrieslong_term_psk,wrapped_psk,wrapped_nonce_B) read"<redacted>".MessageTracer(src/message_trace.h) is owned per connection. The trace points are gated inline inconnection.cppand inNoiseTransport::encrypt_in_place().conventions.md,internals.mdand the house-patterns skill.integration-guide.mddocuments the option.Notes
adapters/sendspin-cpp/client/main.cppin Sendspin/conformance) needs updating to turn the option on and read the trace.Tests
client/inittoserver/activate, with the transport JSON readableaudio_bytes