Skip to content

Document codec testing roadmap#414

Merged
leynos merged 8 commits intomainfrom
custom-codec-documentation
Jan 4, 2026
Merged

Document codec testing roadmap#414
leynos merged 8 commits intomainfrom
custom-codec-documentation

Conversation

@leynos
Copy link
Copy Markdown
Owner

@leynos leynos commented Jan 2, 2026

Expand the user guide with custom FrameCodec guidance and example\nreferences.\n\nAdd codec testing tasks to the roadmap, update ADR-004 with\nimplementation guidance, and introduce a test observability ADR\nfor log and metrics capture.

Summary by Sourcery

Expand documentation for codec-aware testing, custom FrameCodec usage, and introduce a test observability ADR.

Documentation:

  • Document codec-aware testing helpers and observability features in the wireframe_testing crate guide.
  • Add user guide section describing how to implement and configure custom FrameCodec implementations, including references to example codecs.
  • Update ADR-004 with guidance on codec-focused testing and cross-reference the new observability ADR.
  • Extend the roadmap with codec testing and observability tasks, referencing the new ADR-006.
  • Introduce ADR-006 describing a unified test observability harness for logs and metrics in tests.

Expand the user guide with custom FrameCodec guidance and example\nreferences.\n\nAdd codec testing tasks to the roadmap, update ADR-004 with\nimplementation guidance, and introduce a test observability ADR\nfor log and metrics capture.
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Jan 2, 2026

Note

Other AI code review bot(s) detected

CodeRabbit has detected other AI code review bot(s) in this pull request and will avoid duplicating their findings in the review comments. This may lead to a less comprehensive review.

Summary by CodeRabbit

  • New Features

    • Testing helpers to drive apps with framed payloads and expanded codec-aware in-memory testing APIs.
    • Per-test observability handle for capturing logs and metrics during tests.
  • Documentation

    • New guidance on custom frame codecs with examples and integration instructions.
    • ADR and roadmap updates describing a phased test observability harness.
  • Tests

    • Added codec-focused testing guidance, fixtures and checklist items for regression and observability-backed assertions.

✏️ Tip: You can customize this high-level summary in your review settings.

Walkthrough

Summarise additions: add FrameCodec implementation guidance and test recommendations; introduce ADR‑006 defining a per‑test ObservabilityHandle; make wireframe_testing codec‑aware with new drive and encode/decode helpers; add user docs for creating and installing custom frame codecs.

Changes

Cohort / File(s) Summary
Architectural Decision Records
docs/adr-004-pluggable-protocol-codecs.md, docs/adr-006-test-observability.md
Add "Implementation guidance" to ADR‑004 with codec test guidance (encoder/decoder round‑trips, payload extraction, correlation IDs, max frame length, shared examples, test helpers). Add ADR‑006 describing ObservabilityHandle: scoped log capture, in‑process metrics recorder, serialised access, snapshot/inspection helpers, state restoration on drop, lifecycle and phased rollout.
User‑facing documentation
docs/users-guide.md
Add "Custom frame codecs" section specifying FrameCodec requirements (frame_payload, wrap_payload, correlation_id, max_frame_length), integration via with_codec, using send_response_framed_with_codec, and an example MyCodec with references to sample codecs.
Framework testing & roadmap
docs/wireframe-testing-crate.md, docs/roadmap.md
Make wireframe_testing codec‑aware: add codec‑aware drivers and encode/decode helpers, fixtures for valid/invalid/oversized frames, buffer capacity rules, ObservabilityHandle plumbing, and roadmap section 9.7 with checklist items and cross‑reference to ADR‑006.
Testing helpers (crate)
wireframe_testing/src/helpers.rs, wireframe_testing/src/lib.rs
Add drive_with_payloads and drive_with_payloads_mut public APIs plus internal helpers to encode payloads into frames and drive apps; add tests validating payload wrapping and round‑trip decoding; re‑export new helpers from crate root.

Sequence Diagram(s)

sequenceDiagram
    autonumber
    participant Test as Test code
    participant Obs as ObservabilityHandle
    participant Driver as Wireframe test driver
    participant Logger as Scoped Logger
    participant Metrics as Metrics recorder

    rect rgba(230,245,255,0.9)
    Note over Test,Obs: Initialise per-test observability
    Test->>Obs: ObservabilityHandle::new()
    Obs--)Logger: install scoped log capture
    Obs--)Metrics: register in-process recorder
    end

    rect rgba(245,255,230,0.9)
    Note over Test,Driver: Exercise codec paths
    Test->>Driver: drive_with_frames / drive_with_payloads (codec)
    Driver->>Logger: emit logs
    Driver->>Metrics: record metrics
    Driver-->>Test: return framed responses
    end

    rect rgba(255,245,230,0.9)
    Note over Test,Obs: Inspect and tear down
    Test->>Obs: snapshot() / logs() / counter(...)
    Obs-->>Test: return captured data
    Test->>Obs: drop
    Obs--)Logger: restore prior logger state
    Obs--)Metrics: restore prior recorder
    end
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Poem

Stitch the codec, frame by frame,
Capture logs that call a name,
Encode the payload, trace the flow,
Snapshot metrics as they grow,
Tests will hum and errors show.

Pre-merge checks and finishing touches

✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed The title directly reflects the primary change: adding codec testing tasks to the roadmap and comprehensive documentation for codec-related testing and implementation guidance.
Description check ✅ Passed The description accurately captures the changeset scope: expanding user guide documentation, adding codec testing roadmap tasks, updating ADR-004, and introducing ADR-006 for test observability.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
✨ Finishing touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch custom-codec-documentation

📜 Recent review details

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 610c46a and 78a4271.

📒 Files selected for processing (1)
  • docs/wireframe-testing-crate.md
🧰 Additional context used
📓 Path-based instructions (3)
docs/**/*.md

📄 CodeRabbit inference engine (docs/contents.md)

Follow the documentation style guide conventions when writing project documentation

Write official documentation with separate guides for 'Duplex Messaging & Pushes', 'Streaming Responses', and 'Message Fragmentation', each including runnable examples and explaining relevant concepts and APIs

docs/**/*.md: Use markdown files within the docs/ directory as a knowledge base and source of truth for project requirements, dependency choices, and architectural decisions.
When new decisions are made, requirements change, libraries are added/removed, or architectural patterns evolve, proactively update the relevant file(s) in the docs/ directory to reflect the latest state. Ensure documentation remains accurate and current.
Documentation must use en-GB-oxendict spelling and grammar ('-ize' / '-yse' / '-our'), with the exception of the filename LICENSE.
Reference the documentation style guide provided at docs/documentation-style-guide.md for documentation writing standards.

Documentation describing multi-packet streaming MUST reflect the tuple-based API and explain helper constructors that prepare the channel pair

Replace or retire documentation that refers to Cucumber, including guides and examples in docs/

docs/**/*.md: Use British English based on the Oxford English Dictionary (en-GB-oxendict), including: -ize suffixes (realize, organization), -lyse suffixes (analyse, paralyse), -our suffixes (colour, behaviour), -re suffixes (calibre, centre), double 'l' (cancelled, counsellor), maintain 'e' (likeable, liveable), -ogue suffixes (analogue, catalogue)
Keep US spelling when used in an API, for example 'color'
Use the Oxford comma in documentation: 'ships, planes, and hovercraft' where it aids comprehension
Treat company names as collective nouns in documentation: 'Lille Industries are expanding'
Write headings in sentence case
Use Markdown headings (#, ##, ###, and so on) in order without skipping levels
Follow markdownlint recommendations for markdown forma...

Files:

  • docs/wireframe-testing-crate.md
docs/**/*.{rs,md}

📄 CodeRabbit inference engine (docs/rust-doctest-dry-guide.md)

Every doctest should validate the public API of a crate from the perspective of an external user, treating each documentation test as a separate temporary crate that imports the library as an external dependency

Files:

  • docs/wireframe-testing-crate.md
**/*.md

📄 CodeRabbit inference engine (AGENTS.md)

**/*.md: Validate Markdown files using make markdownlint.
Run make fmt after any documentation changes to format all Markdown files and fix table markup.
Validate Mermaid diagrams in Markdown files by running make nixie.
Markdown paragraphs and bullet points must be wrapped at 80 columns.
Code blocks in Markdown must be wrapped at 120 columns.
Markdown tables and headings must not be wrapped.
Use dashes (-) for list bullets in Markdown.
Use GitHub-flavoured Markdown footnotes ([^1]) for references and footnotes in Markdown.

Files:

  • docs/wireframe-testing-crate.md

⚙️ CodeRabbit configuration file

**/*.md: * Avoid 2nd person or 1st person pronouns ("I", "you", "we")

  • Use en-GB-oxendict (-ize / -yse / -our) spelling and grammar
  • Headings must not be wrapped.
  • Documents must start with a level 1 heading
  • Headings must correctly increase or decrease by no more than one level at a time
  • Use GitHub-flavoured Markdown style for footnotes and endnotes.
  • Numbered footnotes must be numbered by order of appearance in the document.

Files:

  • docs/wireframe-testing-crate.md
🔍 Remote MCP Deepwiki

Relevant facts to support reviewing PR #414 (docs + wireframe_testing changes):

  • wireframe_testing crate already implements and re-exports drive_with_payloads / drive_with_payloads_mut; helpers use tokio::io::duplex with DEFAULT_CAPACITY = 4096 and MAX_CAPACITY ≈ 10MB; panic isolation converts server-task panics into io::Error (AssertUnwindSafe + catch_unwind).

  • wireframe_testing exposes TestSerializer trait alias: trait TestSerializer: Serializer + FrameMetadata<Frame = Envelope> + Send + Sync + 'static — docs and helpers rely on this bound for codec-aware helpers.

  • Observability design (ADR-006 / roadmap) proposes an ObservabilityHandle API (new, logs(&mut)->LoggerHandle, snapshot, clear, counter(name, labels)->u64) and recommends serialised test access (global lock) with guidance to run tests serially (e.g. --test-threads=1) to avoid cross-test interference.

  • Testing docs/roadmap update explicitly lists wireframe_testing tasks: codec-aware drivers, codec fixtures (valid/invalid frames, oversized payloads, correlation metadata), per-test observability harness, and regression tests for CodecError taxonomy.

  • FrameCodec / serializer integration points in the codebase: FrameProcessor/LengthPrefixedProcessor, Serializer/BincodeSerializer, FrameMetadata parse() fallback behaviour — relevant when verifying documented helper names (frame_payload / wrap_payload) and TestSerializer bounds match implementations.

Actionable checks for the reviewer (match these against PR text/changes):

  • Confirm drive_with_payloads / drive_with_payloads_mut signatures and re-exports in wireframe_testing match documented examples (including async signatures and io::Result return).
  • Confirm TestSerializer trait bound in docs matches actual alias/trait in wireframe_testing helpers.
  • Verify ObservabilityHandle names/signatures in docs exactly match the implemented logging/observability API and that ADR-006 guidance includes explicit --test-threads=1 / serialisation recommendations.
  • Ensure docs' proposed codec-aware driver signatures either accept an explicit codec parameter or are not F: FrameCodec-generic (the repo currently provides codec-aware helpers via explicit codec arguments in helpers).
  • Check that the docs mention DEFAULT_CAPACITY / MAX_CAPACITY and panic-isolation behaviour so users can apply recommended mitigations in CI.

Sources used: repository documentation and wireframe_testing pages via Deepwiki_read_wiki_contents.

⏰ Context from checks skipped due to timeout of 120000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
  • GitHub Check: Sourcery review
  • GitHub Check: build-test
🔇 Additional comments (2)
docs/wireframe-testing-crate.md (2)

268-299: Verify that the usage examples compile against the current wireframe_testing and wireframe crates.

The two examples demonstrate in-memory driver usage and observability assertions. Please confirm that the following APIs match the actual crate implementations:

  • WireframeApp::new() returns io::Result<WireframeApp<_>>
  • .route(1, Arc::new(...)) returns io::Result<WireframeApp<_>>
  • Envelope::new(1, Some(5), vec![1, 2, 3]) signature is correct
  • drive_with_bincode<M, S, C, E>(app, msg) takes owned app (not &app) and returns io::Result<Vec<u8>>
  • decode_frames(bytes) returns Vec<Vec<u8>>
  • observability() returns ObservabilityHandle
  • observability().clear() and .counter(name, labels) are available

If any signature differs, update the examples to reflect the actual API, or open a follow-up issue to align the implementation with the documented interface.

#!/bin/bash
# Verify that example code at lines 275–284 and 286–299 would compile
# against wireframe_testing crate

# Check that all public re-exports exist in wireframe_testing/src/lib.rs
echo "=== Public re-exports from wireframe_testing ==="
grep -E "pub use|pub async fn drive|pub fn observability" wireframe_testing/src/lib.rs

echo ""
echo "=== WireframeApp::new() return type ==="
rg -A 3 "pub fn new" src/app/builder.rs | head -10

echo ""
echo "=== Envelope constructor ==="
rg -B 2 -A 5 "impl Envelope" src/app/ | head -20

echo ""
echo "=== Observable API signatures ==="
rg -A 8 "impl ObservabilityHandle|pub fn observability" wireframe_testing/src/observability.rs | head -30

---

`54-256`: **Document is well-structured and properly addresses prior review feedback.**

Substantive improvements since previous rounds:

- Drive entry points (lines 76–122) include all four function variants with correct bounds; no ambiguity about codec awareness.
- Proposed enhancements (lines 316–334) are clearly separated from current API; readers understand which helpers are available now versus planned.
- Observability section (lines 213–256) explicitly recommends `--test-threads=1` and per-suite fixtures; explains global lock serialisation and its impact.
- Encoding conventions: en-GB-oxendict spelling ("amortize", "behavioural") applied consistently; no 2nd person pronouns detected.
- Markdown formatting: headings in proper order, code blocks have language tags, lists have surrounding blank lines.

</blockquote></details>

</blockquote></details>

</details>

<!-- This is an auto-generated comment: resource warnings by coderabbit.ai -->

> [!WARNING]
> ## Review ran into problems
> 
> <details>
> <summary>🔥 Problems</summary>
> 
> Errors were encountered while retrieving linked issues.
> 
> <details>
> <summary>Errors (2)</summary>
> 
> * ADR-004: Entity not found: Issue - Could not find referenced Issue.
> * ADR-006: Entity not found: Issue - Could not find referenced Issue.
> 
> </details>
> 
> </details>

<!-- end of auto-generated comment: resource warnings by coderabbit.ai -->

<!-- tips_start -->

---



<sub>Comment `@coderabbitai help` to get the list of available commands and usage tips.</sub>

<!-- tips_end -->

<!-- internal state start -->


<!-- DwQgtGAEAqAWCWBnSTIEMB26CuAXA9mAOYCmGJATmriQCaQDG+Ats2bgFyQAOFk+AIwBWJBrngA3EsgEBPRvlqU0AgfFwA6NPEgQAfACgjoCEYDEZyAAUASpETZWaCrKPR1AGxJcAIvgaO7ApKDJA0iOIYRJAU+Gi0zGjckAAUtpBmACwAjJkAlJCQBgCCeLD4FFxeshj4yIAoBJAAyvjYFAwkkAJUGAywXAERLGBMIWC0/oEYuNTw+FiASYQwzqS4XT19XInwWI1NM7jYiFz43GSpDBQk1HSQAEwADHcAbGAP2W930NkAnBx3AFYOAC7gAtApFACqNgAMlxYLhcNxjgB6FFEdSwbACDRMZgo6q1RAogDu8CuADMqGwUdxsB4PCicpk3AhkOkSAAPbiYWjICYBNjTWbzdAYejhSLRIjYeC0TAdSAUiqMI4EZiQABi1JIAGFFKIUMxuF4hQc5hhkLyUNNYrRsB1kJL+AJEJQJCp4B51PIZXKFSQNJBdbBMKR+dJLvABHQOEYoH5BUFRqIwGgSc5OpKdtFYCQPGcKFbxS63RQPWpvbh5BTrocrsgdmE85AyZSdQB9bNRRhUGiQP1KDQGKDFWj0NCQI6UAeypT2UTiUVKRBRtQ98oksL4I0mkhmsX0JgYCnwGVXVVDDXatBsfUhXem9giy0AGhtDA82FoOZiJFrVy9NI26QFyt57sEojFvQg4BvwWBkCmFAoiEBp8HmBaUMgKRUreJAdjysgeHEtDviSVDcARaBESRBTWmW8BoN6ABeM4CK04qIMOUCQtw8r9sUPg2G8DyZK2mKzv6QHwZBDBgMqgy3N20TWpcdSIGAlKUIhWYtuQW6CGWFZej6kCCTY3FmeOZlCSJzw8LE3B1L+k7YBg8Cnkp0hrIZ7qelW8ihhQ5CIMgyp8AwST1r+xFENBkBsLgFDwAwjZYJKiDvjsn7fr+sHSaKDFMUgL60s4TFeN6iDMJZACinI0CWuAtrE8SJMkZLNbJYTeS5Ja+eW/mmTMiAANbYaeDVtNI75BSFmV/kQDaIBaPURGFKopqElCxOhvLelEeTDgYTSOIkLhdPILRtB0F1XOoyjhM2nQqPgUiQAKUzmqK8Q/kulqHs9NpJYoDr/fwFI2cJDwPM8x0WMGLBmsgDhOC4rKdFcEjwCQJIzlcACO2DebcxVEBgB4xrgePnJ9Zq3MUVgAJLxfAxpPsK/3xVQSC3BEREvf1rp+ZWpnHrdlpBgA0iQ8hOTsuDxc1JDkn+TkUDQ9ARNQRxxiOH3JVIHadbAHZUCSHZyE9K3kzrVy+P4EarslMZHgacnppmBuSFhXR4EDYHs50NsYHbnQeGgDCjaT3U8jqNB8CSCBeH+2zuT2pDkMloRvTOmpcDed7u0Gp1EOG/1cCryt8L96Cx+ViUziqVzMLnQOal0HG0EGpTqjcR55lHyBXOrmvNqgGbD9I+AeFI9ByKnb2/srWoFzq96GuxblazuK8Um5YiragtSQMRUQzlt4wkGc4rsMdUCF3q7uQBhhaQKHbDxdA3lNJQjEsWxLuxxIA2BINjXGM40BjSUqGNYdN2C3FfjOD+0gUQhzDthQMRANDvlwmwKiNF4hkQogQ4iRCYA/z/sVVifAt6cQKIkXAfQgZsz3PTegjMWb8D4NjRUUgiyTgIOgCQ+A5TewpJoMyeAWD90YIPcaNofyRX7CvAUyA8YXniEINUSkdxkywEgosgNA57nURJAIFBAJrFYRzb6AMUgn33hrPMfBEBnAYB5FKyBeBLyUPQJseJkZHXjJAAA8sLQaotqxmWZvYNoFJI7eEgLVS001SwixMtWFIBQURhIicZAKAAJfanQUHEnQfWYCTY1EJWoMwleNj9wII4czAA3H+cBGi/xExJvQMCYh0DenJgeFUAopx8RuE6HcvAwHJnmPvFa8x755KMkNaJ4s2iAQYL6OcAYuDmTsh9SMLtgJFSqqTBgjozFdUnEQYiAgmKn38KNQGP5VytCoOGBQvRNlBAykGUBnTIHQPoOFUC3JvQeLWPlRUr1/abnHmlBOkdFbiS6jYNUa01gUDclnbmogkZkD8QldQZ4XyYI0Ng98EBJRgGalceIiAAC82RuE8EoGABwD0lTwCmg2I6Ui+5jz6KIBRI8KhrAOTDey1oam1C3NlL884uQmhSuoSS8ppJXECUS38NLvJ0tgAyvkLK2WICCrcSalSuIhMTF9F89hqwpyQA4aQcZChQDIGAAA4gAIXsGcBkOYuAhjDJ0AARCuKhLEXzhpApG6Q0aSr/XDUGJm7lxCPLQNIxhtwRVRyVBHMuMCkDtIjgnBK0hEBoC+eKjWQNfXJXEOagN+YDrREmq2KB6BuCqroMOD1ZkRFiLuOKMAhZECih8bUNywDw0AHU8xYFkK0QZxrApoHepOPBfMkrXGYHG81rQPDz1KSQPAVAPA9xzbI/NYrr4SsRV25AfQw0Sh3Aupddcd1az3beFAVoPDruEdoCOAgvCpoxjgIVtwsY4y6fS64WtNzFhtKSx5PJQooCUNMDyshfxuQbDPOeAHXXYVqDMcD8gV5uLbTmPIuCZ7ETxvPeQDhhY9OmGrCVKNzQ9gqh0+DChWDsHUdpP8k7Z50Cyr0JVv5OH2DPKHSpgylMHmtFK2G3yLFbJ2VJDo8NLD6lYOqz+1avmo3OvIFI8wPDyA8lON0+8PB5BCb/OONxVSWKCNaHxTk3T0EMQ0YMEdkqeSdL1HslxPPwM5qtBebiqxSi81YpUOoX75jfhU6aYVYgaj83UPN7s0wZk0eOUl8xEDtOwBMp6K91wpnBeBFOUCyzg18wfQ4DqhGbtEW7E8RxVpwrWJu0DKgU6cJtSOMAhgDAmE9f1SG2aCDEDII9IrInphcF4C6EQh8pAyHkEhFQahNDaF0DNub4AoBwFQKgTA0HCCZ3W27TbnAYjpjiWjeQC9juqHUFoHQ+gjBXdMAYNRKJ4gUBEpkcdX4y7jZIOO2IBAmAeBGO7LizBaBxnDXjgwCNihM1W1nWRlnnDyHwJDV959EBQZp182uk59IfUmGaB17G3SH1FOGpmQd2fgxhSQON28Zwr0fhvUI5kZMg3tB4jOuzpJgoyoDAaBSfRBjgC9ccRXphBEVd+YC2rCXinJSBS4dZOiX1ox408oQVcpEQmhFCBKlB8FiNvOlyVkTvkImQvpDUqDc4wO+Jg3ny2rSZj4BaiRORpbwqfMgRBmoMcT/wmtwcLUB+a1bzHvutJ8GdEFpUm01QsFkgta0HpvT8U6GrtZbGlNMWQNjScgjvIv2cPNNNI2PCTp7TfPkdc1KhU0v+bSSv8D4FwBRzoABtAAelDuyABddAawV5EohkDIXgNfpWgUN5tx8wfw9mVNP2fRzTwZtWov5f0qV9cF/tr6H0q6UGvr1E2QGhsdBgAHI7j7y9D/SPKbQGjjrUCwByJhpWgXgKx2gOh0DtK2byCxZ2LjK15TbmCWDFAeDIpcwgSqKiChZm5U7gqjy3Aqh0jgYpSgS4biDSAhIAHQG04gQqoSqUF8DUGQpHKfjlQEFKA0BiD9rYGQAACymAHkHemoXonQxQocdmNCRgtUEQbMt6BogmuMoEFI4U72YhdA8AjgBgeO4a8YYOEO9+sM7+EQYAn+mS3+2OuO+OhOxOz2fYfMZ0FO2+DOjB+sY4Q+xQ7QCAQh9YjyPgogSAq0oCYe9AKQ5kBQ0qXAzodhAUnewUVarOSYuGPYPi4G+474IQkRy4hsWE74hMsoLcom74pwXM74vmjkhWE4varUzCYKk4hY1hPk+SDeaR3ekA4Rzs0YwED24SqyX+xS4oKczU1ANo2sDIKMTAZw9AsUjAUUaSreTyyeHe1ok4iU2cU8MRM4GxexXiYAeAXoZEEkdyggjy2s/YDYBAfYq0xRpwQY4RMwXoL68wIM6OFIzG745xVYOMG0fAOwNuyWKxxuFAQ+1oJxoQ1aQcleJYxeQin41wriBwgsoKXoFaC8YG+YXEzQ7inipySazEDqJsdc1xDyHgTyBaQiMyUgXGI+GkzoCslAAEOkgMu+YKOKGA6c0QKuZydmQYoSeAB0VSeuS0FJEkXISAyWMI+AxaFAExtAXgvuHKbJkmL4dRJY3otY2yaJXQJAoY2MFQQYVgDYomdc3AoYAWMQJE7UXAVgdpnQrK++6SkS9hqx3AKmvAbMpKB27SLpUCnQdw4kDY3U1oxu/C8grWlABBCsu8LYc0VaQYKSgQ7hXxloJAnGjoqQghlAzAOw8ptBYJSU9q7WoUCZFoC0TkjUmatJVwcutwHmDI+YSAzAMmFuoZ9ASgg+iEbG8SiSdEJYxZ4gRAHOSUNwGIwEOEdYaSfxNaGIUQuCFUDy9JO4sUYADy9p8ZGstZAq6aOUK4JKE5Dq0ZTGG5LyJomAWBBOOBeBj0tZhBLYIQJBBBZB7BGsnBPA2IPB7ApKvhUAzB35mstI/5tBgF0S2WkZrcP4nk/i6UbIH0HkFIhm4hkhtYEQWoshZkChsgShBgKh4guabs84cGWh/4uhXAhSZ4sAxh+O02YARgEOrUCQSQP+OOjFphLhJOL2X2Vm3hoYtOIS6abWMcLOnOi4q0PwGgAA7EGJLlir0RkdaCkaZKLoXi2MpWQCJR0MjAuMHj3OOBtG0HIqKlVNYjQMwMcAYIOnJYpayvVI1PQG2P+J2MpGilAZfJ7BeLQCUUYmCvOuSB5XhMUL2oDIMOqFqOvM/NXsTDag5QpRoOGf4d1FajljaBGWFfgl5WCm4bMD2NXnKCiDsCVaCjqAtAbqftELnEWPAKxPQH7iRPFGHlcBHqKIlPENQGgAOroJAI5RoAAMyQDpqy6IF1zJHdFf6qVYZNjuU7pdiRaCk7iRS+lpKxTEhwneJi4d58kl4RTPwJJehZXRkEqxk8AzxqrSD9VQBDViTpVXBLRVqrQq4LWhVLX5UqiS61SWIqgzCcjzAsBxklgxmUByzXXbLGmmlzBtARjX63BNhyXZCpWpDlGhXIAo2pXBKjimV1ws7n4z7T6Yzj5bKdBL4BWHIHSjTLx6JU1v60oaXVhcXHSiG4H4EvlCJEF8FPGVbb5gW/ncFQX0HAlMHzAkCiESHuTYVrAyETYEVEUkVqHCoaGUVbjUUSpcD6E/hGEmFmEsXg6OwojThFjEBziBiOE8UPlmSuFrbuFayeEXRkE+F05+E64TjvxaFoEc4yU866hl4ag7oV5xorhri/gS7HXUi/g4peALQY3NmVrNSKBIlIU0DSngyUkhXtgJ4bEmwdhbRpqyaG5TxEyhWGVgqPxhCyBnC4KdgtXkLkRJCkIkSh4VAdUvgdhyi6n0Cx4dhLVeBRDNTtLlk4rB5TKzEzAMhRXzJnhpL51bTtK76iiDY9hujihmzSBOQ5n906i0DGyYgF3uztLWgmIpxiGyDKWNIC6rQmhHB/iclAQT1n254hCEnP6DL94v3ALlC4ASlH0hAaBGKwmyCIAEweAAOiBAP3mE5Pl80Azc1vnEH8EvlfncgcH0BUGQXbSi3AWQAAHkBS1YXSF4XyFMSEWUDKGqFkWQSaEa06Fa2QCKkkhUOkXqEUVgJCaa0axcDMPW3MWsXG2LU6idE5gjDuFcVOG8U4F22k5jzk7O3U4iXhghL1Q8i3x9ls7PjgxCJh0nJ1zdAkQzg7BgBsCtwuBt1jB+VZgrVxIUAJKKhgrCN4TLWqGrkfhyY9gmNmMVCoGBULR4K/iUlbSp11zvJLGenq7RKpmhSWSgK3kdDNVwatDIChz/VbiBM9hHAZ7eVHIhwDhxB97NgzEOC9qPqYDyCR0hD56JqDTgxkHB3dX8RoCzT7S/iJAeDhRsCVV4ShMdHOixQog7UAYzwviWTjUIGJNe1bjC1S6xIOD2OJJ0FJTAnZWqKOzdmePRABU+wH3NS729MFElF7OmwN18hHO7P53myWyyBPQpA7A/jap/3yAbGZPRDHg0ANSp47NGz507qIAdjMB4AXO/OH1nMAtAu4DvhO5KAHOfw928EGhwszSDK0keaNzJRNX8D8JUn220FVOGjWjZ25UkARXcDjO2igxTPtHYMrIZJFIlLabXxrCUks4KYLMOOdAOK4zvhbXviIChzIi/2h5eDOBt1uQJyjme3UmgEzX2HZLLMXTyzTCWS8S159mBWKuQ0KwT2lOjydxdT4AkjkAThjl4CI47nt1GukyRXZOkA8DUAJwAzWg9aXLMugSYj4yfb/NsozJgBN29qtnUT+4LSUkqqQrqpbQOuhS/hgpvMu6jA5iWT+FFZWOladA/MziAlAXxQwskAJsaHF7HgRA8wmuXSryxV4TKVCJkCI7x5sDfIltgwWhlQNU9iUk+Ko4zxJ09UzCqu1YwKdCzMxJMx2Oct5NRi+lvU7iUheADK+XpsyamP7i+NYp9QSgtQrvV7b4dWMQFRYDmw7m3NI4oEZaYRFibO5Q9gs7wX0jhzUStAjZg1I5gWPgpTkoUsTXUsUIRC/zJTUJi48y96MQT10ISi2PF6UlnKNUXkliNMkAzDNM+lrKrM4QqgpJSDERnD1vrvdRNO9W41hLik7B16QxOLVx0H6VNLTBpQnnAS1AYA7kMq01RbFbWPgqNSLL2JYI4Leygv7NbTIuIBSvoDlYgG0k7pgAws5gFu1VnsToYUc3Pn82IMZvIPwPIBoMUGYNcG0vQVi3u1+JcAAAGmbJzQnwATQ74uo74tUegKQSQ3AXAxLO6ZLln1ntnegddvTXAAAaqIMAP5wwMANgAABx6B6AFAzYoD4AcAcCgIOB4GBcBdhcRfGf2UDWKnKIWhcDON5W2PsvDmKh6NDFIWZF0541GeQCmfHP53gvufBiecOe9rOefU6hudWeNfJJecOuEJ8h+cBdBchfheRe6B6AxdxcJf0i4DJfBepd6DpeVexjVdmd/NVWAt4ANc2fdfNdOeQAABkkLkALn7XvaW3nn3nn8A3wXQ383UX43cwk30g03s3w3aXhny3NXlzYLwbrVG3M3nX23dnu3XAh3/sJ34VZ3gPF3vXIb13r3d3Y3E38Xz3SXt3I3i3VkVXxnebFnmo9nW0oPmol3bqkAQ3+cHAj8o30Xj3KPiXM36PaXuTxb05Cs1X+clbRcIQmPKbOOK3ru+E/zwA+PKQhPB3xPl04Q8PqX93yPU3aPAXFPVPC3zPlWrPXGxnHPBLDAPPHtJn1BYQQHP7uAf7/8jVlAT+ZJM4AA1JzyQPoYh71cL+lkyskhgJh6cCQON7b7/CWD7zUKELbwAOR3EpS6/Y+jH0s+iqleDGfV3YeUmJTlD9cZdQDGf6QKvRe/ydPpeDrGdbUpBg9rBuidOy9F9MNKmkAqklK58DXGcCtJBHq4CF8l8Uiy9NCCtN+19p9onOCF9Het95Dd/VdMASuUAt/5gUjvgoKg8lu8sqAEmg9z4t9JTvj7clt5Ar6y/YDPCZDh+ffM2yCZ/jeR9ekMuTEkDpc23S1SE4Xy2S360CMGB5f4TKRoLtAohBbQNSM21E78UO2CUvCLtZRngwmZUtWytLBTLoxKJ1wIebAMlrkyBZ4F4AEEcFuWzeagRI4UBM5ugGQCD1k8sAK+N6HHKWoqq7qAarzz474Q6uv3RlLt19y0C+QBQGtr0A0L0Qt8k4N0HmVI6w9WqZRBDm0AFJAxHOgATAIp4x+HMpL1uqp8setwVbj9z64Qs8A9A3gYymYHTIOSFQDUDRgTye94GMkXYuazyID4H6E+AzB9zTqUAFC8nX2EIj1aPocB0nfjCWB+bBoZBuPcFikHBaWNRA6gugo1muDMIcBSZRPEPUIFKBiBD0HpvCz/D1ghBk4KQGIBVANMqqbKB7DtBVAOYnBHaUDElQGrjUrBjyNsHTSoH1tgIwTJIJHFMgbF5B+zcFuZ3WpVDoksqWrgoJDYNDKhUKWQP9xkwiJo4rGIGCzmHaTZLI38HCq7WBiTMXoKlaYmsH4Qkl+QrQuoYwPUQURcsvTQ/E8zszltshYoN3h71roLhxQv4dQAi1QhycV4DYbem6BAgVVPMwQqUk2m/wg5f+cDM3Kp14IflUGkMQWjpz/I0EcG4gBgm7SgAO9k+onbHgbygQB8lQWAWoacxWHncdujnVrjnXgFQ8PO3XBgYoPh6M9qeD3WLnTxe54i4+TYYzi/1cZSh3+DAT/pliwjQNMeYIxQBCM+5QjEAMIikHCKWEIjFB/3JEcDxREHcjucA0lhiK652dsRcPMnoNxS4jdZetPeXgz1lFM8yRFIt/ogA/5f8iwV/BGDf1lq4UFa5DJWtQ3Yak1Ok2hGipADopEAGKj/CAIbTVErVqRBIaMN/2tp8VCq8jJ2pTiUYwE3AJIHcEMNpbF4vYVwKTugx/KVVy8jotxkQDi5BYuA8IluoyleTcjkxfIf7prhQoekV4PRaAT7CxTXJsBKw1IN6GjjbCkB4gCCCqAeRMI8wtAZgUalaA2igY+VSOPEBIDQtuQvIZeC2GGHzMiunQE2I+0GQJxfwcpWMeQR4z/41qIA5+pyFLI9hYotBFUBkL2iTEXIF4bGCtGMExgV0TUPSFRQjFjwHotlNmvrCZETg9eK3NMeC1JFYBos/YckW1xcbKQ4+KQMMa+ypDl5b2KcYzkFmM6uZQRCHcEb9E+5Jj6hkLe8b2E8zPi0Rr/Fau+M/HHi0sP40GH+IAmuZiKJo1Whw3NHcM9CBhPWkxWByg4FsmDJbNIn/7qE3sXAc2IAIui/Y0IJ2AHOdmBzzZhM45LuhmPVp0AOw2setKRI4mZAHgoXeSj8B+CZA0Aw1J4PJXkq0A7gAgbIAIGeDDVRAPwX4LQGyCPABAtAAQBSGGrZB5KAgO4HcFGrsTrsg1EgMNUuRSSfgJATIMNVUl3A6AzwAQKFx+DSSVJ2QMSWgB+C1gHgFIeSg8AEDGSfgAgC7IYA4mhcBA/k7IGgFMnyUGA9klyapP0mZASA4kkgMpJCn2TawJAAQACApAZTMgekyKWRONLDVgpVUikLQAknyVQuFIAEM8DQDyUdCzwH4PJSMkPAAQSgEEMlIaloBngdwaSeVI4nPBsgDwBgJkBakMAkpDAEycNUyChcHg2UgEJkFKkAhcgAIIqbQBCkrSVpxk6yWNMsmDTMgdwLqRlKqkAgSAkk0LncGyAkAHg8kn4ACF0m5BDJtAeSrv0elLTsgkMISZZMCTqBuJALXifvS3wWSIADkfCGwAoCkAC68iAFgJLWCkSAA3hl3DRIBbAvqYiFHDoDGYzQVgOoJrHDRcAEkfeTsZjKPT0haAuM55LYDJlKhm8VMwoFjMQChJ+EyUHXBgCZkUy3Qr4TGT+FoAYoMAiYfYMlCiCIAQwoqJmRWVZmQBI0coUWe4D/p6h5EcsnFArKVkiy3IAxSdv9BllRxNZxMQWWzJpp0AWYZGCWUzLxxmzFZEcCIEbNGiKjEATMufBl0KAYzCgPsxWXej/x4RbZqslOHenDT2zfZ4aO4kcBNkKyI54bTALGi4DhotcYQTwBm1CpiBths7RcE6D7HJQhKPhLgL9F/BRsvKI0BRB8PYrtQZ6xoK4EuhWjvQfa4MMFJfA7pjwvK1oa+to1WhC4NAYcz2T7PDTwVhcSc0rAKX7m+y2ZxuE8HPSuB8yWZ4cweRUDPA7AmIzsgOWwFtlAiIMA8gAL6LzvZk88NP7MDlJz9Z3ucGKHMXlsyo5bspIlrOvmKz45ymC0EHKQaDEp2P0S5G0BuDbD1q1qIGK7QQ72BFiSSFVD2KyZlgNUGbLRnFnmB1FysrHB8F5SrlJAwgUCcaACVqzyZbIMMTIAi3gJUscF0MLTMrg7yH8+5j8oeQaFtljycwE8o+dPNPDngR5zMymVQuXkrk158iDeawoTQfyU0e8g+QPLZknzN5Z8x2Csx7D6h08pABhRHNvkxyqFz8xOYrMTAlsS59VHJqgEmkPANAMMAAKStgEAzCVAA4B0I3UVWMATdmXUTqIYj0J6ADJABWn6KHgBiyhSIsVnDzaFXeehRwuShcKPA680+YrLURSK4ophX2bvIy4r57Z4aR2bgFsDnyUBKaJOU1PkovBrgw1HQspO0nLSEk8U+SmgBmnuTjJDyYaopIBBySGA2QWpSQCelfT/p7khgPdJ+DPAup9SpKXVIYDPAGF8SqBIkpsDBy+FdwfJVUoeBtKYwBkrSQ8DqmrTnge034L5NC7DV5QUkvabQAMnPAGAw1XSRUruAeT7JdU0LutIYB1S3J2QCaX0rCWSyiAMi5QKQAKHBQmI+wG4EzMPlsyYxVIjUTSK1F3zIAHyweQQCnqahOstZJmaFyoVAFx6IVZqOovCX/Lzpe8jLtEuiUVSZkgLSgAjLvQAtIZl2DicwAYCUQPmXIXAPxJmCCTLsBgQ+UPKrQZ5bZoCLwB6C4wONUUdgmrPq3Vq/h0gWQXIAWUdiQBbeXykuXOLyAcAAAOhgElVQBhVUWdwmuiQz2Z+c1pc6uGNHiLDvuywxQZAFyQQSVh/3dpMXmnDbhaahI2nvaD3Bx5KSPgWqJqGKCQgYQ0ADsLqEZjFBdQTMaAAAE1IArvESW0sBhiFigAADWdWur3VXqyAIAAkiSAJNLEK+p2k6jMstqUvnzB+EqKIyJqQwUOt3IqUYGDuFp5/VdoqQYoNWQ1iQgMAZIcUE0DQC1hBVqxOsR2DciVqGxGgSVdKpypfVbG7BN0MgDGEm8reheI3sVCgT3ztAawPtabwA6VBmgA6utY/Ad69s0AzvBPK7ww75hPe3vGdX72aAwjg+ofUII0BqTWhi8HVSnMhVQBgdDqskErF7C/5trGOdLM/qZBXBKZi1uCrTLklQXcACgBWHtXsNP5RNZAMfOQrEm5YkheWSpRAP3zwB5AZsipZUsBv5ad9hWjAUVhQHFZ64KADiPCPPxjB95YNegHfvkEBjG5NsQ+aDvaWdCRwrkqQGVrSTxmjQCglJXfEIgOpClo02wx3JSiDD6obCiGRlCyj8G9YxELJTosDA5JmDAw96m7LYzYqOk0FNWWvOQQjbPNT48pMxPBMpHLwMFwCBdl7EzYXsMqvKABSkAqplV3exUaISi3qorQsW3gzYfmAdT4cZgqefpuQrlapEYmoTZ6stDereQQSiMEIIWoBpoAgatQZgN/mk129lKuSaDjQnE0Z1b6oiGjmsxbAphdySSR+JaX8BVoKgKIGEEnmaiWl/wvKOgNlquQVB3wk6gBMhF9TZQDQ1W83uhrt4LqkOccN0AqwpkeBryMNTdHDT4CNAOqYCTACyy/TzCKQ+GHsGgUQR0i+AZSVIEtRwG5IA26YkThOtnVgdkAjCUxcqrgWSx71xQYPHWxxVXrLhnDCBHwBSDbaoCysG4TWm0CWg1g6QT5rgBRCu0xV7a/UDPIoAag9V2q3VbeP1UD8m8AC1VWBTSgdrPKtja7ZkS+i3Bv6qQGqi5HZG9BFMtsUHSWAVGo9sUAg4KEdE+2z0ftxvRrfFtZ5rBL11SAVdduGJiBsAWab0FAhRBk7sqsq3MLNq4jtr/OYWeQABobzAb34vTNBCDqyqU7c1/SVTTDoaS7ax4sUFckQBRCH8R2gMWYVDEOS74aqwEcNmqlRmdFDUxqZlKyli1Jpq04MUjUKH4i1lW1D6lJAsxgWpQg+DkU4I0WvXscDNaO5TFlSrguJ0AbrX0nsK11Qp648cJuDXAvAUYK22vf/rQRSBnanIKWdgNsJ8TYxTyemi8MXg2IB7I2z8FYF9Ah1BZ8dD652cUw3xvkqdgFUUDartUOqnVLqqwG6o9XerckgakNbXvr0RrfMkhOSEgFGbgwYwsND5PYB3Cm0X0D2RzlnIJRkbbg45MlImSwDuqrdkq66O0GAjTg+e4qFaI8VQKwL0C1oVnQ6y+QbFwi18MkLTU3rxAD6p+klTRw8WiLKhUSYEqdG+y2yEw9S7gCfvgC0VMsyAcNhUCxKxDkosyWHTfVFAEBuAXiGenrhS1tFIA3qdQIUmxDcYN9vjBFneS6Q9JVC/NYbEDHX3qBfGVuqAF9pe3yVtajfOuN6G6BACuCkcUaDkxQQgRJwhB0lfJQxzGhZgxg8g1QAuhR4SNuOgGNdpijRhODqzMFCXz9oYAb9isjNRQGKCIgXY5xeYO7IHnhoj9b++ALTUiWQAV8BgNFQSqJVH09cDUDsHir0BAA=== -->

<!-- internal state end -->

@sourcery-ai
Copy link
Copy Markdown
Contributor

sourcery-ai Bot commented Jan 2, 2026

Reviewer's Guide

Expands documentation around pluggable FrameCodec usage, introduces implementation guidance and testing roadmap items for codec-aware test harnesses, and adds a new ADR defining a test observability harness for logs and metrics capture in tests.

Sequence diagram for codec-aware driver with test observability

sequenceDiagram
    actor Test
    participant Obs as ObservabilityHandle
    participant Log as LoggerHandle
    participant Metrics as DebuggingRecorder
    participant Driver as WireframeTestingHelpers
    participant App as WireframeApp
    participant Codec as FrameCodec

    Test->>Obs: new()
    Obs->>Log: install_log_capture()
    Obs->>Metrics: install_metrics_recorder()

    Test->>Obs: clear()
    Obs->>Log: clear()
    Obs->>Metrics: snapshot_and_discard()

    Test->>Driver: drive_with_payloads(app, codec, payloads)
    activate Driver
    Driver->>Codec: wrap_payload(payloads)
    Codec-->>Driver: frames
    Driver->>App: handle_connection(duplex_stream)
    activate App
    App->>Codec: encoder(), decoder()
    App->>Metrics: record(codec_bytes_in)
    App->>Metrics: record(codec_bytes_out)
    App->>Log: log(codec_error or success)
    App-->>Driver: response_bytes
    deactivate App
    Driver->>Codec: decode(response_bytes)
    Codec-->>Driver: response_frames
    Driver-->>Test: response_frames
    deactivate Driver

    Test->>Obs: snapshot()
    Obs->>Metrics: snapshot()
    Metrics-->>Obs: counters
    Obs-->>Test: Snapshot

    Test->>Obs: counter("wireframe.codec.errors", [])
    Obs->>Metrics: scan_counters()
    Metrics-->>Obs: value
    Obs-->>Test: u64
Loading

File-Level Changes

Change Details Files
Rewrite wireframe_testing crate design doc to center on codec-aware drivers, fixtures, and a test observability harness instead of only length-prefixed frame helpers.
  • Clarify crate purpose as a companion for exercising Wireframe applications and codecs, including observability capture.
  • Document crate layout with helpers, observability, logging, fixtures, and multi-packet modules.
  • Specify expanded dependencies needed for codecs, async I/O, logging, metrics, and testing.
  • Describe codec-aware drivers that accept a FrameCodec, work on F::Frame instead of raw bytes, and surface errors via io::Error.
  • Define buffer capacity behavior tied to codec max frame length and shared safety limits.
  • Introduce encode/decode helpers for FrameCodec frames and a bincode convenience wrapper working with codecs.
  • Outline codec fixtures for default and example codecs, including malformed frame builders.
  • Define a test observability harness API (ObservabilityHandle) combining log capture and metrics via metrics-util, with global serialization.
  • Retain helper macros and provide updated example usage aligned with codec-aware and observability features.
  • Add implementation notes tying the doc back to concrete helper and harness changes to make in wireframe_testing.
docs/wireframe-testing-crate.md
Document how to configure and use custom FrameCodec implementations in applications and tests.
  • Add a 'Custom frame codecs' section explaining the FrameCodec contract (Frame type, encoder/decoder, payload extraction, wrap_payload, correlation_id, max_frame_length).
  • Document how to install a custom codec via WireframeApp::with_codec and its interaction with fragmentation defaults.
  • Explain use of send_response_framed_with_codec when operating on an already framed stream so responses are encoded via FrameCodec.
  • Provide a minimal example wiring a MyCodec implementation into a WireframeApp and reference example codec implementations in the repo.
docs/users-guide.md
Extend ADR-004 with concrete testing and observability guidance for codecs and link it to the new test observability ADR.
  • Add an 'Implementation guidance' section calling for codec-focused tests (round-trips, payload extraction, correlation IDs, max frame length).
  • Recommend using shared example codecs and codec-aware wireframe_testing helpers to avoid assuming length-delimited framing.
  • Advise validating observability signals (logs, metrics, recovery policies) with the planned test observability harness.
  • Introduce a footnote reference to the new ADR-006 document.
docs/adr-004-pluggable-protocol-codecs.md
Update the roadmap with a codec-aware test harness and observability workstream, and reference the new ADR for test observability.
  • Add a new section 9.7 detailing tasks for codec-aware drivers, fixtures, observability capture, and regression tests for CodecError taxonomy and recovery policies.
  • Reference ADR-006 from the new roadmap section via a footnote.
docs/roadmap.md
Introduce ADR-006 describing the design and roadmap for a test observability harness in wireframe_testing.
  • Describe the need for deterministic per-test observability and the limitations of current ad hoc approaches.
  • List decision and technical drivers, including avoiding external services and guarding global registries.
  • Compare options (status quo, unified harness, external exporters) and select a unified observability harness as the preferred direction.
  • Specify the ObservabilityHandle-based approach using logtest and metrics-util, with global locking and snapshot helpers.
  • Outline consequences, phased roadmap, and mitigation/rollback strategies including feature-flagging the harness if necessary.
docs/adr-006-test-observability.md

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

Align the testing crate design with pluggable FrameCodec support
and the observability harness from ADR 006.

Document codec-aware driver entry points, fixture expectations, and
log/metrics capture behaviour so implementers can plan the work.
@leynos leynos marked this pull request as ready for review January 3, 2026 01:41
Copy link
Copy Markdown
Contributor

@sourcery-ai sourcery-ai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey - I've found 3 issues, and left some high level feedback:

  • Several of the documented APIs in wireframe_testing (e.g., drive_with_raw_bytes’s signature missing a codec parameter, FrameCodec::wrap_payload/frame_payload helpers, TestSerializer bounds, and the observability()/ObservabilityHandle surface) are only sketched here; when you implement them, please align names and signatures exactly with the docs or adjust the docs accordingly to avoid drift and confusion for users treating this as authoritative.
  • The observability harness is described as serialising access with a global lock and requiring tests not to run concurrently; consider being more explicit in the ADR and user-facing docs about how this interacts with popular Rust test runners’ parallel execution (e.g., recommending --test-threads=1 or a per-suite fixture pattern) so users don’t accidentally write flaky observability tests.
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- Several of the documented APIs in `wireframe_testing` (e.g., `drive_with_raw_bytes`’s signature missing a codec parameter, `FrameCodec::wrap_payload`/`frame_payload` helpers, `TestSerializer` bounds, and the `observability()`/`ObservabilityHandle` surface) are only sketched here; when you implement them, please align names and signatures exactly with the docs or adjust the docs accordingly to avoid drift and confusion for users treating this as authoritative.
- The observability harness is described as serialising access with a global lock and requiring tests not to run concurrently; consider being more explicit in the ADR and user-facing docs about how this interacts with popular Rust test runners’ parallel execution (e.g., recommending `--test-threads=1` or a per-suite fixture pattern) so users don’t accidentally write flaky observability tests.

## Individual Comments

### Comment 1
<location> `docs/wireframe-testing-crate.md:109-118` </location>
<code_context>
+    E: Packet,
+    F: FrameCodec;
+
+pub async fn drive_with_raw_bytes<S, C, E, F>(
+    app: WireframeApp<S, C, E, F>,
+    wire_bytes: Vec<Vec<u8>>,
+    capacity: Option<usize>,
+) -> io::Result<Vec<u8>>
+where
+    S: TestSerializer,
+    C: Send + 'static,
+    E: Packet,
+    F: FrameCodec;
 ```

</code_context>

<issue_to_address>
**suggestion:** Align `drive_with_raw_bytes` signature with the surrounding description of codec-aware drivers.

The earlier description says primary driver APIs take both the app and its codec, but `drive_with_raw_bytes` doesn’t take a `codec: &F` argument even though it’s generic over `F: FrameCodec`. Please either add the codec parameter or remove/adjust the `F: FrameCodec` bound and update the surrounding text so the description matches the function signature.

```suggestion
pub async fn drive_with_raw_bytes<S, C, E, F>(
    app: WireframeApp<S, C, E, F>,
    codec: &F,
    wire_bytes: Vec<Vec<u8>>,
    capacity: Option<usize>,
) -> io::Result<Vec<u8>>
where
    S: TestSerializer,
    C: Send + 'static,
    E: Packet,
    F: FrameCodec;
```
</issue_to_address>

### Comment 2
<location> `docs/users-guide.md:131` </location>
<code_context>
+- Define a `Frame` type and paired decoder/encoder implementations that return
+  `std::io::Error` on failure.
+- Return only the logical payload bytes from `frame_payload` so metadata parsing
+  and deserialization run against the right buffer.
+- Wrap outbound payloads with `wrap_payload`, adding any protocol headers or
+  metadata required by the wire format.
</code_context>

<issue_to_address>
**issue (review_instructions):** Use en-GB spelling here: "deserialization" should be "deserialisation".

To follow the en-GB-oxendic spelling guideline, update "deserialization" to "deserialisation" on this line.

<details>
<summary>Review instructions:</summary>

**Path patterns:** `**/*.md`

**Instructions:**
Use en-GB-oxendic (-ize / -yse / -our) spelling and grammar.

</details>
</issue_to_address>

### Comment 3
<location> `docs/users-guide.md:142` </location>
<code_context>
+
+Install a custom codec with `with_codec`. The builder resets fragmentation to
+the codec-derived defaults, so override fragmentation afterwards if the
+protocol uses a different budget. When you already have a framed stream, use
+`send_response_framed_with_codec` so responses pass through
+`FrameCodec::wrap_payload`.
</code_context>

<issue_to_address>
**issue (review_instructions):** This sentence uses the 2nd person pronoun "you", which the style guide prohibits.

The phrase "When you already have a framed stream" violates the no 1st/2nd person pronouns rule. Consider rephrasing, for example: "When a framed stream is already available, use ..." or similar neutral wording.

<details>
<summary>Review instructions:</summary>

**Path patterns:** `**/*.md`

**Instructions:**
Avoid 2nd person or 1st person pronouns ("I", "you", "we").

</details>
</issue_to_address>

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

Comment thread docs/wireframe-testing-crate.md Outdated
Comment thread docs/users-guide.md Outdated
Comment thread docs/users-guide.md Outdated
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 7

📜 Review details

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between a4b8b85 and 4087994.

📒 Files selected for processing (5)
  • docs/adr-004-pluggable-protocol-codecs.md
  • docs/adr-006-test-observability.md
  • docs/roadmap.md
  • docs/users-guide.md
  • docs/wireframe-testing-crate.md
🧰 Additional context used
📓 Path-based instructions (8)
docs/**/*.md

📄 CodeRabbit inference engine (docs/contents.md)

Follow the documentation style guide conventions when writing project documentation

Write official documentation with separate guides for 'Duplex Messaging & Pushes', 'Streaming Responses', and 'Message Fragmentation', each including runnable examples and explaining relevant concepts and APIs

docs/**/*.md: Use markdown files within the docs/ directory as a knowledge base and source of truth for project requirements, dependency choices, and architectural decisions.
When new decisions are made, requirements change, libraries are added/removed, or architectural patterns evolve, proactively update the relevant file(s) in the docs/ directory to reflect the latest state. Ensure documentation remains accurate and current.
Documentation must use en-GB-oxendict spelling and grammar ('-ize' / '-yse' / '-our'), with the exception of the filename LICENSE.
Reference the documentation style guide provided at docs/documentation-style-guide.md for documentation writing standards.

Documentation describing multi-packet streaming MUST reflect the tuple-based API and explain helper constructors that prepare the channel pair

Replace or retire documentation that refers to Cucumber, including guides and examples in docs/

docs/**/*.md: Use British English based on the Oxford English Dictionary (en-GB-oxendict), including: -ize suffixes (realize, organization), -lyse suffixes (analyse, paralyse), -our suffixes (colour, behaviour), -re suffixes (calibre, centre), double 'l' (cancelled, counsellor), maintain 'e' (likeable, liveable), -ogue suffixes (analogue, catalogue)
Keep US spelling when used in an API, for example 'color'
Use the Oxford comma in documentation: 'ships, planes, and hovercraft' where it aids comprehension
Treat company names as collective nouns in documentation: 'Lille Industries are expanding'
Write headings in sentence case
Use Markdown headings (#, ##, ###, and so on) in order without skipping levels
Follow markdownlint recommendations for markdown forma...

Files:

  • docs/users-guide.md
  • docs/adr-004-pluggable-protocol-codecs.md
  • docs/adr-006-test-observability.md
  • docs/roadmap.md
  • docs/wireframe-testing-crate.md
docs/**/*.{rs,md}

📄 CodeRabbit inference engine (docs/rust-doctest-dry-guide.md)

Every doctest should validate the public API of a crate from the perspective of an external user, treating each documentation test as a separate temporary crate that imports the library as an external dependency

Files:

  • docs/users-guide.md
  • docs/adr-004-pluggable-protocol-codecs.md
  • docs/adr-006-test-observability.md
  • docs/roadmap.md
  • docs/wireframe-testing-crate.md
**/*.md

📄 CodeRabbit inference engine (AGENTS.md)

**/*.md: Validate Markdown files using make markdownlint.
Run make fmt after any documentation changes to format all Markdown files and fix table markup.
Validate Mermaid diagrams in Markdown files by running make nixie.
Markdown paragraphs and bullet points must be wrapped at 80 columns.
Code blocks in Markdown must be wrapped at 120 columns.
Markdown tables and headings must not be wrapped.
Use dashes (-) for list bullets in Markdown.
Use GitHub-flavoured Markdown footnotes ([^1]) for references and footnotes in Markdown.

Files:

  • docs/users-guide.md
  • docs/adr-004-pluggable-protocol-codecs.md
  • docs/adr-006-test-observability.md
  • docs/roadmap.md
  • docs/wireframe-testing-crate.md

⚙️ CodeRabbit configuration file

**/*.md: * Avoid 2nd person or 1st person pronouns ("I", "you", "we")

  • Use en-GB-oxendict (-ize / -yse / -our) spelling and grammar
  • Headings must not be wrapped.
  • Documents must start with a level 1 heading
  • Headings must correctly increase or decrease by no more than one level at a time
  • Use GitHub-flavoured Markdown style for footnotes and endnotes.
  • Numbered footnotes must be numbered by order of appearance in the document.

Files:

  • docs/users-guide.md
  • docs/adr-004-pluggable-protocol-codecs.md
  • docs/adr-006-test-observability.md
  • docs/roadmap.md
  • docs/wireframe-testing-crate.md
docs/users-guide.md

📄 CodeRabbit inference engine (docs/roadmap.md)

Extend docs/users-guide.md with client configuration tables, lifecycle diagrams, and troubleshooting guidance

Files:

  • docs/users-guide.md
docs/adr-[0-9][0-9][0-9]-*.md

📄 CodeRabbit inference engine (docs/documentation-style-guide.md)

Name ADR (Architectural Decision Record) files using the pattern 'adr-NNN-short-description.md', where NNN is a zero-padded sequence number, and place ADRs in the docs/ directory

Files:

  • docs/adr-004-pluggable-protocol-codecs.md
  • docs/adr-006-test-observability.md
docs/adr-*.md

📄 CodeRabbit inference engine (docs/documentation-style-guide.md)

docs/adr-*.md: Every ADR must include the following sections in order: Status (one of Proposed, Accepted, Superseded, or Deprecated), Date (YYYY-MM-DD format), and Context and Problem Statement
In ADRs, include Decision Drivers, Requirements, Options Considered, Decision Outcome / Proposed Direction, Goals and Non-Goals, Migration Plan, Known Risks and Limitations, Outstanding Decisions, and Architectural Rationale sections as appropriate to the decision's complexity
In ADRs, use second-level headings (##) for major sections and third-level headings (###) for subsections
In ADRs, include tables when comparing options across multiple dimensions and add a caption below the table (e.g. 'Table 1: Trade-offs between X and Y.')
In ADRs, include code snippets with language identifiers when illustrating technical approaches, and use 'no_run' for illustrative Rust code that should not be executed
In ADRs, add screen reader descriptions before complex diagrams or code blocks
In ADRs, reference external sources using inline links or footnotes

Files:

  • docs/adr-004-pluggable-protocol-codecs.md
  • docs/adr-006-test-observability.md
docs/adr-004-pluggable-protocol-codecs.md

📄 CodeRabbit inference engine (docs/roadmap.md)

Update docs/adr-004-pluggable-protocol-codecs.md with FrameCodec trait changes

Files:

  • docs/adr-004-pluggable-protocol-codecs.md
docs/**/roadmap*.md

📄 CodeRabbit inference engine (docs/documentation-style-guide.md)

docs/**/roadmap*.md: In roadmap task writing, define outcomes, not intentions: phrase tasks in terms of the capability delivered (e.g. 'Implement role-based access control for API endpoints'), not aspirations like 'Improve security'
In roadmap task writing, quantify completion criteria and attach measurable finish lines (e.g. '90% test coverage for new modules', 'response times under 200ms', 'all endpoints migrated')
In roadmap task writing, break into atomic increments: ensure tasks can be completed in weeks, not quarters, and decompose large goals into clear, deliverable units
In roadmap task writing, tie to dependencies and sequencing: document prerequisites so tasks can be scheduled realistically
In roadmap task writing, bound scope explicitly: note both in-scope and out-of-scope elements
In roadmap documentation, use three layers of scope: Phases (strategic milestones, numbered 1, 2, 3), Steps (epics/workstreams, numbered 1.1, 1.2, 1.3), and Tasks (execution units, numbered 1.1.1, 1.1.2, 1.1.3)
In roadmap documentation, use dotted numbering for phases, steps, and headline tasks, and precede task and sub-task items with a GitHub-Flavoured Markdown (GFM) checkbox '[ ]' to track completion status
In roadmap documentation, note non-linear dependencies explicitly using dotted notation (e.g. 'Requires 2.3.1')
In roadmap documentation, include explicit success criteria only where not immediately obvious from the task description
In roadmap documentation, cite relevant design document sections using dotted notation (e.g. 'See design-doc.md §3.2')

Files:

  • docs/roadmap.md
🧠 Learnings (2)
📚 Learning: 2026-01-02T04:41:11.015Z
Learnt from: CR
Repo: leynos/wireframe PR: 0
File: docs/roadmap.md:0-0
Timestamp: 2026-01-02T04:41:11.015Z
Learning: Applies to docs/adr-004-pluggable-protocol-codecs.md : Update `docs/adr-004-pluggable-protocol-codecs.md` with FrameCodec trait changes

Applied to files:

  • docs/adr-004-pluggable-protocol-codecs.md
📚 Learning: 2026-01-02T04:39:36.933Z
Learnt from: CR
Repo: leynos/wireframe PR: 0
File: docs/adr-004-pluggable-protocol-codecs.md:0-0
Timestamp: 2026-01-02T04:39:36.933Z
Learning: Tie buffer sizing and maximum frame length configuration to codec implementation to keep transport-level constraints close to the framing rules that define them

Applied to files:

  • docs/adr-004-pluggable-protocol-codecs.md
🪛 LanguageTool
docs/adr-006-test-observability.md

[style] ~18-~18: To elevate your writing, try using a synonym here.
Context: ...y assertions inconsistent, brittle, and hard to reuse across downstream crates. A d...

(HARD_TO)


[uncategorized] ~21-~21: Use a comma before ‘so’ if it connects two independent clauses (unless they are closely connected and short).
Context: ...ted test observability harness is needed so tests can assert on logging and metrics...

(COMMA_COMPOUND_SENTENCE_2)


[style] ~79-~79: Would you like to use the Oxford spelling “Serialize”? The spelling ‘Serialise’ is also correct.
Context: ... by labels when verifying counters. - Serialise access with a global lock to avoid cros...

(OXFORD_SPELLING_Z_NOT_S)


[style] ~86-~86: Would you like to use the Oxford spelling “serialization”? The spelling ‘serialisation’ is also correct.
Context: ...etup. - Global recorder access requires serialisation, which may reduce parallelism for obs...

(OXFORD_SPELLING_Z_NOT_S)

docs/wireframe-testing-crate.md

[uncategorized] ~14-~14: Use a comma before ‘so’ if it connects two independent clauses (unless they are closely connected and short).
Context: ...ses a unified test observability harness so tests can assert on logs and metrics de...

(COMMA_COMPOUND_SENTENCE_2)


[uncategorized] ~134-~134: Use a comma before ‘so’ if it connects two independent clauses (unless they are closely connected and short).
Context: ...are all returned as io::Error values so tests can assert on error handling. ##...

(COMMA_COMPOUND_SENTENCE_2)


[uncategorized] ~204-~204: Possible missing comma found.
Context: ...`. - Access is serialized with a global lock so concurrent tests do not interfere. -...

(AI_HYDRA_LEO_MISSING_COMMA)

🔍 Remote MCP Deepwiki

Summary of Additional Context for PR #414 Review

Based on my research of the wireframe repository, here are the key facts relevant to reviewing this pull request:

Project Architecture Context

The wireframe framework uses a FrameProcessor trait to abstract frame parsing and encoding logic, with a built-in LengthPrefixedProcessor supporting configurable length-prefixed framing. The WireframeApp is a generic builder struct with three type parameters: S for Serializer, C for Connection State, and E for Packet (message envelope).

Existing Testing Infrastructure

The wireframe_testing crate provides utilities for testing WireframeApp instances by simulating network connections using in-memory streams, with core components including drive_with_* functions, LoggerHandle for thread-safe log capture, and rstest integration for fixtures. The drive_internal function sets up duplex streams, runs the server function, writes frames to the client side, and collects output while handling panics in the server task.

Current Observability Capabilities

The wireframe framework provides comprehensive observability through the tracing crate for structured logging with hierarchical span structures (connection, request, response_stream, push spans), and the metrics crate for operational metrics including connections_active, frames_processed_total, push_queue_depth, and request_latency_seconds.

Codec and Protocol Customization

Wireframe provides several extension points for protocol customization: a public FrameProcessor trait for custom framing implementations, a Serializer trait for pluggable serialization backends with default bincode integration, and a Packet trait for custom envelope types.

Relevance to PR Changes

The PR documentation changes align with the existing architecture: ADR-004 adds implementation guidance for codec-specific tests that leverage the existing FrameProcessor trait flexibility; ADR-006 proposes a test observability harness that complements the existing LoggerHandle and extends it with in-process metrics capture (addressing a current gap in test-time metrics validation); and the roadmap tasks establish codec-aware testing patterns that build upon the existing wireframe_testing helper functions and rstest fixtures.

⏰ Context from checks skipped due to timeout of 120000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
  • GitHub Check: Sourcery review
  • GitHub Check: Sourcery review
🔇 Additional comments (5)
docs/adr-004-pluggable-protocol-codecs.md (1)

270-270: Footnote format is correct.

The cross-reference to ADR-006 using GitHub-flavoured Markdown footnote syntax is well integrated. Retain as-is after rewrapping the bullet points above.

docs/roadmap.md (2)

584-585: Footnote reference format is correct.

The cross-reference to ADR-006 using GitHub-flavoured Markdown footnote syntax is well placed. The footnote definition is correctly formatted. Retain as-is after rewrapping the task items above.


428-438: Section 9.7 already complies with the 80-column wrapping requirement. All lines measure within the boundary (maximum 79 characters), so no rewrapping is necessary.

Likely an incorrect or invalid review comment.

docs/adr-006-test-observability.md (1)

1-110: ADR structure and decision rationale are sound.

The ADR follows best practices: Status and Date are clear, Context and Problem Statement articulate the observability gap, Decision Drivers are well-motivated, and Options Considered provide defensible trade-offs. The Roadmap section (Phase 1 and Phase 2) is a valuable addition for phasing implementation. Technical approach (ObservabilityHandle with logtest and metrics-util, global serialisation lock, drop-based restoration) is well-reasoned and aligns with existing testing infrastructure.

docs/wireframe-testing-crate.md (1)

1-288: Documentation structure is comprehensive and technically sound.

The rewritten crate documentation provides clear motivation, design goals, and crate layout. Codec-aware driver entry points (drive_with_frames, drive_with_payloads, drive_with_raw_bytes, and mutable variants) are well-documented with behavioural details. The buffer capacity guidance and frame encoding/decoding helpers are appropriately scoped. The observability harness section accurately reflects the ADR-006 proposal (ObservabilityHandle, DebuggingRecorder, per-test isolation, drop restoration). Fixtures and example usage are concrete and helpful. Implementation notes bridge documentation to roadmap tasks.

Cross-references to ADR-004 and ADR-006 strengthen alignment with decision records.

Comment thread docs/adr-004-pluggable-protocol-codecs.md
Comment thread docs/adr-006-test-observability.md Outdated
Comment thread docs/users-guide.md
Comment thread docs/users-guide.md
Comment thread docs/wireframe-testing-crate.md Outdated
Comment thread docs/wireframe-testing-crate.md Outdated
Comment thread docs/wireframe-testing-crate.md Outdated
Refine testing crate documentation for codec-aware drivers and
observability guidance, and align the test observability ADR.

Update the users guide framing note to remove second-person phrasing
and clarify framed-stream usage.
@leynos

This comment was marked as resolved.

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Jan 3, 2026

Tip

For best results, initiate chat on the files or code changes.

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Check the drive_with_raw_bytes signature in wireframe-testing-crate.md
echo "=== Checking docs/wireframe-testing-crate.md around lines 109-118 ==="
sed -n '100,125p' docs/wireframe-testing-crate.md

echo ""
echo "=== Checking docs/users-guide.md around line 131 ==="
sed -n '125,135p' docs/users-guide.md

echo ""
echo "=== Checking docs/users-guide.md around line 142 ==="
sed -n '140,150p' docs/users-guide.md

echo ""
echo "=== Checking for observability concurrency guidance in ADR-006 ==="
rg -n -A5 -B5 "concurrent|parallel|--test-threads|serializ" docs/adr-006-test-observability.md

Length of output: 2747


@leynos: I've checked the current state of the files. Here's the status:

Resolved ✓

Comment 1 (drive_with_raw_bytes signature): Resolved by removing the F: FrameCodec bound entirely from the where clause. The function is no longer generic over F, which makes sense since drive_with_raw_bytes is designed for testing malformed wire bytes and doesn't need codec operations.

Comment 3 (pronoun usage): Resolved. Line 142 now reads "When a framed stream is already available," removing the second-person pronoun "you".

Overall observability concurrency guidance: Resolved. ADR-006 now includes explicit guidance (lines 81-83) recommending --test-threads=1 or shared fixtures for parallel test runners.

Not Resolved ✗

Comment 2 (en-GB spelling): Line 131 of docs/users-guide.md still contains "deserialization" (American spelling) instead of "deserialisation" (en-GB-oxendict spelling).

Change this line:

- Return only the logical payload bytes from `frame_payload` so metadata parsing
  and deserialization run against the right buffer.

To:

- Return only the logical payload bytes from `frame_payload` so metadata parsing
  and deserialisation run against the right buffer.

Update the custom codec guidance to use en-GB spelling for
"deserialisation".
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Jan 3, 2026

Tip

For best results, initiate chat on the files or code changes.

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Check Comment 1: drive_with_raw_bytes signature in wireframe-testing-crate.md
echo "=== Comment 1: Checking docs/wireframe-testing-crate.md around lines 109-118 ==="
sed -n '100,125p' docs/wireframe-testing-crate.md

echo ""
echo "=== Comment 2: Checking docs/users-guide.md around line 131 for 'deserialization' ==="
sed -n '125,140p' docs/users-guide.md

echo ""
echo "=== Comment 3: Checking docs/users-guide.md around line 142 for pronoun usage ==="
sed -n '140,150p' docs/users-guide.md

echo ""
echo "=== Overall: Checking ADR-006 for concurrency/parallel guidance ==="
rg -n -C3 "test-threads|concurrent|parallel|serializ" docs/adr-006-test-observability.md

Length of output: 2915


@leynos: Yes, all the review comments have now been resolved! Here's the status:

✓ All Resolved

Comment 1 (drive_with_raw_bytes signature): The F: FrameCodec bound has been removed from the where clause (Line 119). The function remains generic over F but no longer constrains it, which is appropriate since raw-bytes testing doesn't require codec operations.

Comment 2 (en-GB spelling): Line 133 of docs/users-guide.md now correctly uses "deserialisation" instead of "deserialization".

Comment 3 (pronoun usage): Line 144 of docs/users-guide.md now reads "When a framed stream is already available," removing the second-person pronoun "you".

Overall comment (concurrency guidance): ADR-006 now includes explicit guidance (lines 81-83) recommending --test-threads=1 or shared fixtures for parallel test runners, addressing the concern about flaky observability tests.

@leynos
Copy link
Copy Markdown
Owner Author

leynos commented Jan 3, 2026

@coderabbitai review

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Jan 3, 2026

✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

📜 Review details

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 4087994 and 9e3cc4a.

📒 Files selected for processing (3)
  • docs/adr-006-test-observability.md
  • docs/users-guide.md
  • docs/wireframe-testing-crate.md
🧰 Additional context used
📓 Path-based instructions (6)
docs/**/*.md

📄 CodeRabbit inference engine (docs/contents.md)

Follow the documentation style guide conventions when writing project documentation

Write official documentation with separate guides for 'Duplex Messaging & Pushes', 'Streaming Responses', and 'Message Fragmentation', each including runnable examples and explaining relevant concepts and APIs

docs/**/*.md: Use markdown files within the docs/ directory as a knowledge base and source of truth for project requirements, dependency choices, and architectural decisions.
When new decisions are made, requirements change, libraries are added/removed, or architectural patterns evolve, proactively update the relevant file(s) in the docs/ directory to reflect the latest state. Ensure documentation remains accurate and current.
Documentation must use en-GB-oxendict spelling and grammar ('-ize' / '-yse' / '-our'), with the exception of the filename LICENSE.
Reference the documentation style guide provided at docs/documentation-style-guide.md for documentation writing standards.

Documentation describing multi-packet streaming MUST reflect the tuple-based API and explain helper constructors that prepare the channel pair

Replace or retire documentation that refers to Cucumber, including guides and examples in docs/

docs/**/*.md: Use British English based on the Oxford English Dictionary (en-GB-oxendict), including: -ize suffixes (realize, organization), -lyse suffixes (analyse, paralyse), -our suffixes (colour, behaviour), -re suffixes (calibre, centre), double 'l' (cancelled, counsellor), maintain 'e' (likeable, liveable), -ogue suffixes (analogue, catalogue)
Keep US spelling when used in an API, for example 'color'
Use the Oxford comma in documentation: 'ships, planes, and hovercraft' where it aids comprehension
Treat company names as collective nouns in documentation: 'Lille Industries are expanding'
Write headings in sentence case
Use Markdown headings (#, ##, ###, and so on) in order without skipping levels
Follow markdownlint recommendations for markdown forma...

Files:

  • docs/adr-006-test-observability.md
  • docs/wireframe-testing-crate.md
  • docs/users-guide.md
docs/**/*.{rs,md}

📄 CodeRabbit inference engine (docs/rust-doctest-dry-guide.md)

Every doctest should validate the public API of a crate from the perspective of an external user, treating each documentation test as a separate temporary crate that imports the library as an external dependency

Files:

  • docs/adr-006-test-observability.md
  • docs/wireframe-testing-crate.md
  • docs/users-guide.md
**/*.md

📄 CodeRabbit inference engine (AGENTS.md)

**/*.md: Validate Markdown files using make markdownlint.
Run make fmt after any documentation changes to format all Markdown files and fix table markup.
Validate Mermaid diagrams in Markdown files by running make nixie.
Markdown paragraphs and bullet points must be wrapped at 80 columns.
Code blocks in Markdown must be wrapped at 120 columns.
Markdown tables and headings must not be wrapped.
Use dashes (-) for list bullets in Markdown.
Use GitHub-flavoured Markdown footnotes ([^1]) for references and footnotes in Markdown.

Files:

  • docs/adr-006-test-observability.md
  • docs/wireframe-testing-crate.md
  • docs/users-guide.md

⚙️ CodeRabbit configuration file

**/*.md: * Avoid 2nd person or 1st person pronouns ("I", "you", "we")

  • Use en-GB-oxendict (-ize / -yse / -our) spelling and grammar
  • Headings must not be wrapped.
  • Documents must start with a level 1 heading
  • Headings must correctly increase or decrease by no more than one level at a time
  • Use GitHub-flavoured Markdown style for footnotes and endnotes.
  • Numbered footnotes must be numbered by order of appearance in the document.

Files:

  • docs/adr-006-test-observability.md
  • docs/wireframe-testing-crate.md
  • docs/users-guide.md
docs/adr-[0-9][0-9][0-9]-*.md

📄 CodeRabbit inference engine (docs/documentation-style-guide.md)

Name ADR (Architectural Decision Record) files using the pattern 'adr-NNN-short-description.md', where NNN is a zero-padded sequence number, and place ADRs in the docs/ directory

Files:

  • docs/adr-006-test-observability.md
docs/adr-*.md

📄 CodeRabbit inference engine (docs/documentation-style-guide.md)

docs/adr-*.md: Every ADR must include the following sections in order: Status (one of Proposed, Accepted, Superseded, or Deprecated), Date (YYYY-MM-DD format), and Context and Problem Statement
In ADRs, include Decision Drivers, Requirements, Options Considered, Decision Outcome / Proposed Direction, Goals and Non-Goals, Migration Plan, Known Risks and Limitations, Outstanding Decisions, and Architectural Rationale sections as appropriate to the decision's complexity
In ADRs, use second-level headings (##) for major sections and third-level headings (###) for subsections
In ADRs, include tables when comparing options across multiple dimensions and add a caption below the table (e.g. 'Table 1: Trade-offs between X and Y.')
In ADRs, include code snippets with language identifiers when illustrating technical approaches, and use 'no_run' for illustrative Rust code that should not be executed
In ADRs, add screen reader descriptions before complex diagrams or code blocks
In ADRs, reference external sources using inline links or footnotes

Files:

  • docs/adr-006-test-observability.md
docs/users-guide.md

📄 CodeRabbit inference engine (docs/roadmap.md)

Extend docs/users-guide.md with client configuration tables, lifecycle diagrams, and troubleshooting guidance

Files:

  • docs/users-guide.md
🪛 LanguageTool
docs/adr-006-test-observability.md

[style] ~18-~18: To elevate your writing, try using a synonym here.
Context: ...y assertions inconsistent, brittle, and hard to reuse across downstream crates. A d...

(HARD_TO)

docs/users-guide.md

[style] ~131-~131: Would you like to use the Oxford spelling “deserialization”? The spelling ‘deserialisation’ is also correct.
Context: ...rame_payload` so metadata parsing and deserialisation run against the right buffer. - Wrap ou...

(OXFORD_SPELLING_Z_NOT_S)

🔍 Remote MCP Deepwiki

Summary — additional facts relevant to reviewing PR #414

  • wireframe_testing crate: provides codec-aware test helpers and fixtures used by the docs changes — key APIs include drive_with_frame(s), drive_with_bincode, run_app/run_with_duplex_server, TestSerializer trait bounds, processor() and logger() rstest fixtures, and LoggerHandle for test log capture. These are implemented with tokio::io::duplex, configurable buffer capacities, and panic isolation via catch_unwind.,

  • Observability / ADR-006 specifics referenced in the PR: design proposes wireframe_testing::observability with an ObservabilityHandle that installs scoped log capture (logtest) and an in-process metrics recorder, provides snapshot/inspection helpers, serializes access with a global lock to avoid cross-test interference, and recommends running tests serially or sharing fixtures (e.g., --test-threads=1) to avoid flaky assertions.

  • Frame/codec testing guidance aligns with existing framing and serializer traits: Wireframe supports FrameProcessor/LengthPrefixedProcessor, Serializer (BincodeSerializer) and FrameMetadata; tests should use existing helpers (drive_with_*) and TestSerializer bounds to exercise encoder/decoder round-trips, payload extraction, correlation IDs, and max frame length behavior. The testing utilities already provide capacity controls and bincode integration (drive_with_bincode).

  • drive_with_raw_bytes / drive_with_* API surface: the testing docs show several drive_with_* overloads (single/multiple frames, capacity/mutable variants). If docs mention a codec-bound on a helper (e.g., drive_with_raw_bytes with F: FrameCodec), confirm the docs match the implemented helpers (many drive helpers are codec-agnostic; codec-aware variants encode/decode via TestSerializer).

References (tools used)

  • Repo documentation and crate docs: Deepwiki_read_wiki_contents (leynos/wireframe) — pages covering Testing, wireframe_testing crate, Observability, Frame/Serializer, and related API surfaces.
  • Wiki structure overview listing Testing and wireframe_testing topics.
⏰ Context from checks skipped due to timeout of 120000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: Sourcery review
🔇 Additional comments (3)
docs/wireframe-testing-crate.md (2)

219-236: This is a proposed API specification—implement the documented interface as written.

The types referenced in the proposed API do exist in the codebase:

  • LoggerHandle is fully implemented in wireframe_testing/src/logging.rs
  • metrics_util::debugging::Snapshot is available (version 0.20.0 in dev dependencies) and already used in tests/metrics.rs

The documented signatures align with existing testing infrastructure and ADR-006. Implement ObservabilityHandle with the specified public API:

  • counter(name: &str, labels: &[(&str, &str)]) -> u64 for querying metrics with label filtering
  • snapshot() -> Snapshot for capturing the current recorder state
  • logs() -> &mut LoggerHandle for accessing log capture

Ensure the implementation correctly integrates LoggerHandle acquisition and metrics recorder setup within the global lock constraint documented at line 203–206.


111-119: Remove drive_with_raw_bytes from documentation or implement the function.

The function drive_with_raw_bytes documented at lines 111–119 does not exist in the wireframe_testing crate. The actual public API exports only drive_with_frame, drive_with_frames, drive_with_bincode, and their variants (_mut, _with_capacity). These functions accept WireframeApp<S, C, E> (three generics) rather than the four-generic variant shown in the documentation.

Either implement drive_with_raw_bytes in wireframe_testing/src/helpers.rs and export it from lib.rs, or remove the description and signature from lines 78–119 in the documentation.

Likely an incorrect or invalid review comment.

docs/users-guide.md (1)

128-138: No changes needed. Verification confirms the description at lines 132–133 is accurate: wrap_payload is correctly described as a method for wrapping outbound payloads with protocol headers or metadata. The implementation uses it exclusively on the send path (via send_response_payload, drive_with_payloads, and similar), confirming it is outbound-only and not bidirectional.

Comment thread docs/adr-006-test-observability.md
Comment thread docs/wireframe-testing-crate.md Outdated
Comment thread docs/wireframe-testing-crate.md
Expand the testing crate design with mutable driver signatures
and a metrics example that aligns with existing counters.

Clarify the test observability ADR consequences with concrete
parallelism guidance.
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

♻️ Duplicate comments (1)
docs/adr-006-test-observability.md (1)

85-92: Cross-reference the Mitigation and rollback section explicitly in Consequences.

The reference to "the mitigation guidance in the approach" is vague. Past review feedback requested explicit cross-reference to lines 108–113 (the Mitigation and rollback section) to ensure readers are aware of fallback strategies (feature flag, log-based assertions) available if the global recorder approach becomes problematic. Clarify that the Approach section covers the primary strategy (--test-threads=1, shared fixtures), and the Mitigation and rollback section (lines 109–114) provides additional fallback options.

Proposed fix
- Global recorder access requires serialization, which may reduce parallelism
- for observability-heavy suites, such as forcing `--test-threads=1` for the
- affected test binary. See the mitigation guidance in the approach.
+ Global recorder access requires serialisation, which may reduce parallelism
+ for observability-heavy suites, such as forcing `--test-threads=1` for the
+ affected test binary. See the Approach section for primary strategies
+ and the Mitigation and rollback section (lines 109–114) for fallback options
+ including feature flags and log-based assertions.
📜 Review details

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 9e3cc4a and 8b9f1a2.

📒 Files selected for processing (2)
  • docs/adr-006-test-observability.md
  • docs/wireframe-testing-crate.md
🧰 Additional context used
📓 Path-based instructions (5)
docs/**/*.md

📄 CodeRabbit inference engine (docs/contents.md)

Follow the documentation style guide conventions when writing project documentation

Write official documentation with separate guides for 'Duplex Messaging & Pushes', 'Streaming Responses', and 'Message Fragmentation', each including runnable examples and explaining relevant concepts and APIs

docs/**/*.md: Use markdown files within the docs/ directory as a knowledge base and source of truth for project requirements, dependency choices, and architectural decisions.
When new decisions are made, requirements change, libraries are added/removed, or architectural patterns evolve, proactively update the relevant file(s) in the docs/ directory to reflect the latest state. Ensure documentation remains accurate and current.
Documentation must use en-GB-oxendict spelling and grammar ('-ize' / '-yse' / '-our'), with the exception of the filename LICENSE.
Reference the documentation style guide provided at docs/documentation-style-guide.md for documentation writing standards.

Documentation describing multi-packet streaming MUST reflect the tuple-based API and explain helper constructors that prepare the channel pair

Replace or retire documentation that refers to Cucumber, including guides and examples in docs/

docs/**/*.md: Use British English based on the Oxford English Dictionary (en-GB-oxendict), including: -ize suffixes (realize, organization), -lyse suffixes (analyse, paralyse), -our suffixes (colour, behaviour), -re suffixes (calibre, centre), double 'l' (cancelled, counsellor), maintain 'e' (likeable, liveable), -ogue suffixes (analogue, catalogue)
Keep US spelling when used in an API, for example 'color'
Use the Oxford comma in documentation: 'ships, planes, and hovercraft' where it aids comprehension
Treat company names as collective nouns in documentation: 'Lille Industries are expanding'
Write headings in sentence case
Use Markdown headings (#, ##, ###, and so on) in order without skipping levels
Follow markdownlint recommendations for markdown forma...

Files:

  • docs/adr-006-test-observability.md
  • docs/wireframe-testing-crate.md
docs/**/*.{rs,md}

📄 CodeRabbit inference engine (docs/rust-doctest-dry-guide.md)

Every doctest should validate the public API of a crate from the perspective of an external user, treating each documentation test as a separate temporary crate that imports the library as an external dependency

Files:

  • docs/adr-006-test-observability.md
  • docs/wireframe-testing-crate.md
**/*.md

📄 CodeRabbit inference engine (AGENTS.md)

**/*.md: Validate Markdown files using make markdownlint.
Run make fmt after any documentation changes to format all Markdown files and fix table markup.
Validate Mermaid diagrams in Markdown files by running make nixie.
Markdown paragraphs and bullet points must be wrapped at 80 columns.
Code blocks in Markdown must be wrapped at 120 columns.
Markdown tables and headings must not be wrapped.
Use dashes (-) for list bullets in Markdown.
Use GitHub-flavoured Markdown footnotes ([^1]) for references and footnotes in Markdown.

Files:

  • docs/adr-006-test-observability.md
  • docs/wireframe-testing-crate.md

⚙️ CodeRabbit configuration file

**/*.md: * Avoid 2nd person or 1st person pronouns ("I", "you", "we")

  • Use en-GB-oxendict (-ize / -yse / -our) spelling and grammar
  • Headings must not be wrapped.
  • Documents must start with a level 1 heading
  • Headings must correctly increase or decrease by no more than one level at a time
  • Use GitHub-flavoured Markdown style for footnotes and endnotes.
  • Numbered footnotes must be numbered by order of appearance in the document.

Files:

  • docs/adr-006-test-observability.md
  • docs/wireframe-testing-crate.md
docs/adr-[0-9][0-9][0-9]-*.md

📄 CodeRabbit inference engine (docs/documentation-style-guide.md)

Name ADR (Architectural Decision Record) files using the pattern 'adr-NNN-short-description.md', where NNN is a zero-padded sequence number, and place ADRs in the docs/ directory

Files:

  • docs/adr-006-test-observability.md
docs/adr-*.md

📄 CodeRabbit inference engine (docs/documentation-style-guide.md)

docs/adr-*.md: Every ADR must include the following sections in order: Status (one of Proposed, Accepted, Superseded, or Deprecated), Date (YYYY-MM-DD format), and Context and Problem Statement
In ADRs, include Decision Drivers, Requirements, Options Considered, Decision Outcome / Proposed Direction, Goals and Non-Goals, Migration Plan, Known Risks and Limitations, Outstanding Decisions, and Architectural Rationale sections as appropriate to the decision's complexity
In ADRs, use second-level headings (##) for major sections and third-level headings (###) for subsections
In ADRs, include tables when comparing options across multiple dimensions and add a caption below the table (e.g. 'Table 1: Trade-offs between X and Y.')
In ADRs, include code snippets with language identifiers when illustrating technical approaches, and use 'no_run' for illustrative Rust code that should not be executed
In ADRs, add screen reader descriptions before complex diagrams or code blocks
In ADRs, reference external sources using inline links or footnotes

Files:

  • docs/adr-006-test-observability.md
🪛 LanguageTool
docs/adr-006-test-observability.md

[style] ~18-~18: To elevate your writing, try using a synonym here.
Context: ...y assertions inconsistent, brittle, and hard to reuse across downstream crates. A d...

(HARD_TO)

🔍 Remote MCP Deepwiki

Relevant facts gathered for reviewing PR #414

  • wireframe_testing crate already exposes codec-aware test helpers and the public driver functions described in the PR (drive_with_frame(s), drive_with_payloads, drive_with_raw_bytes, mutable variants, encode/decode helpers) and documents the TestSerializer trait bounds; helpers live in wireframe_testing/src/helpers.rs.
  • ObservabilityHandle and observability() concepts (scoped log capture, per-test metrics recorder, global serialization/lock, snapshot/clear/counter helpers) are documented as part of the testing crate design and testing utilities (wireframe_testing/src/logging.rs).
  • The testing helpers use tokio::io::duplex, support configurable buffer capacities (DEFAULT_CAPACITY = 4096, MAX_CAPACITY ≈ 10MB), and implement panic isolation (catch_unwind) — relevant when ADR-006 recommends serialisation or running tests with --test-threads=1.
  • wireframe core docs show FrameProcessor/LengthPrefixedProcessor, Serializer/BincodeSerializer, FrameMetadata, and correlation_id propagation are already first-class concepts — confirms the PR's codec guidance (frame_payload/wrap_payload, max_frame_length, correlation IDs) aligns with existing architecture.
  • The roadmap and testing pages already call out adding codec fixtures, codec-aware drivers, and a test observability harness (the PR mirrors those roadmap items).

Sources used:,

⏰ Context from checks skipped due to timeout of 120000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
  • GitHub Check: Sourcery review
  • GitHub Check: build-test
🔇 Additional comments (2)
docs/adr-006-test-observability.md (1)

79-79: Fix British English spelling for -ise verbs.

Change "Serialize access" to "Serialise access" to align with en-GB-oxendict spelling rules.

Proposed fix
- Serialize access with a global lock to avoid cross-test interference, and
+ Serialise access with a global lock to avoid cross-test interference, and

Likely an incorrect or invalid review comment.

docs/wireframe-testing-crate.md (1)

149-150: No action required. The documentation correctly uses F::wrap_payload and F::frame_payload as trait methods on FrameCodec. Both are defined in src/codec.rs as static methods with signatures matching their documented usage. The examples at lines 149–150 and 193–202 accurately represent the API.

Comment thread docs/wireframe-testing-crate.md
Comment thread docs/wireframe-testing-crate.md Outdated
Comment thread docs/wireframe-testing-crate.md
Introduce payload-driven helpers in wireframe_testing and
re-export them for tests.

Update the testing crate design doc to reflect the current helper
signatures, correct the bincode wrapper example, and expand the
observability concurrency guidance.
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 4

📜 Review details

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 8b9f1a2 and be37037.

📒 Files selected for processing (3)
  • docs/wireframe-testing-crate.md
  • wireframe_testing/src/helpers.rs
  • wireframe_testing/src/lib.rs
🧰 Additional context used
📓 Path-based instructions (4)
**/*.rs

📄 CodeRabbit inference engine (AGENTS.md)

**/*.rs: Run make check-fmt (cargo fmt --workspace -- --check) before committing to validate Rust formatting across the entire workspace without modifying files.
Run make lint (cargo clippy --workspace --all-targets --all-features -- -D warnings) before committing to lint every target with all features enabled and deny all Clippy warnings.
Run make test (cargo test --workspace) before committing to run the full workspace test suite.
Clippy warnings MUST be disallowed. Fix any warnings emitted during tests in the code itself rather than silencing them.
Use make fmt (cargo fmt --workspace) to apply formatting fixes reported by the formatter check.
Where a Rust function is too long, extract meaningfully named helper functions adhering to separation of concerns and CQRS.
Where a Rust function has too many parameters, group related parameters in meaningfully named structs.
Where a Rust function is returning a large error, consider using Arc to reduce the amount of data returned.
Write unit and behavioural tests for new Rust functionality. Run both before and after making any change.
Every Rust module must begin with a module level (//!) comment explaining the module's purpose and utility.
Document public Rust APIs using Rustdoc comments (///) so documentation can be generated with cargo doc.
Prefer immutable data and avoid unnecessary mut bindings in Rust code.
Avoid unsafe code in Rust unless absolutely necessary, and document any usage clearly with a 'SAFETY' comment.
Place function attributes after doc comments in Rust code.
Do not use return in single-line Rust functions.
Use predicate functions for Rust conditional criteria with more than two branches.
Lints must not be silenced in Rust except as a last resort. Lint rule suppressions must be tightly scoped and include a clear reason.
Use concat!() to combine long string literals in Rust rather than escaping newlines with a backslash.
Prefer single-line versions of Rust functions where...

Files:

  • wireframe_testing/src/lib.rs
  • wireframe_testing/src/helpers.rs

⚙️ CodeRabbit configuration file

**/*.rs: * Seek to keep the cognitive complexity of functions no more than 9.

  • Adhere to single responsibility and CQRS
  • Place function attributes after doc comments.
  • Do not use return in single-line functions.
  • Move conditionals with >2 branches into a predicate function.
  • Avoid unsafe unless absolutely necessary.
  • Every module must begin with a //! doc comment that explains the module's purpose and utility.
  • Comments and docs must follow en-GB-oxendict (-ize / -yse / -our) spelling and grammar
  • Lints must not be silenced except as a last resort.
    • #[allow] is forbidden.
    • Only narrowly scoped #[expect(lint, reason = "...")] is allowed.
    • No lint groups, no blanket or file-wide suppression.
    • Include FIXME: with link if a fix is expected.
  • Where code is only used by specific features, it must be conditionally compiled or a conditional expectation for unused_code applied.
  • Use rstest fixtures for shared setup and to avoid repetition between tests.
  • Replace duplicated tests with #[rstest(...)] parameterised cases.
  • Prefer mockall for mocks/stubs.
  • Prefer .expect() over .unwrap() in tests.
  • .expect() and .unwrap() are forbidden outside of tests. Errors must be propagated.
  • Ensure that any API or behavioural changes are reflected in the documentation in docs/
  • Ensure that any completed roadmap steps are recorded in the appropriate roadmap in docs/
  • Files must not exceed 400 lines in length
    • Large modules must be decomposed
    • Long match statements or dispatch tables should be decomposed by domain and collocated with targets
    • Large blocks of inline data (e.g., test fixtures, constants or templates) must be moved to external files and inlined at compile-time or loaded at run-time.
  • Environment access (env::set_var and env::remove_var) are always unsafe in Rust 2024 and MUST be marked as such
    • For testing of functionality depending upon environment variables, dependency injection and...

Files:

  • wireframe_testing/src/lib.rs
  • wireframe_testing/src/helpers.rs
docs/**/*.md

📄 CodeRabbit inference engine (docs/contents.md)

Follow the documentation style guide conventions when writing project documentation

Write official documentation with separate guides for 'Duplex Messaging & Pushes', 'Streaming Responses', and 'Message Fragmentation', each including runnable examples and explaining relevant concepts and APIs

docs/**/*.md: Use markdown files within the docs/ directory as a knowledge base and source of truth for project requirements, dependency choices, and architectural decisions.
When new decisions are made, requirements change, libraries are added/removed, or architectural patterns evolve, proactively update the relevant file(s) in the docs/ directory to reflect the latest state. Ensure documentation remains accurate and current.
Documentation must use en-GB-oxendict spelling and grammar ('-ize' / '-yse' / '-our'), with the exception of the filename LICENSE.
Reference the documentation style guide provided at docs/documentation-style-guide.md for documentation writing standards.

Documentation describing multi-packet streaming MUST reflect the tuple-based API and explain helper constructors that prepare the channel pair

Replace or retire documentation that refers to Cucumber, including guides and examples in docs/

docs/**/*.md: Use British English based on the Oxford English Dictionary (en-GB-oxendict), including: -ize suffixes (realize, organization), -lyse suffixes (analyse, paralyse), -our suffixes (colour, behaviour), -re suffixes (calibre, centre), double 'l' (cancelled, counsellor), maintain 'e' (likeable, liveable), -ogue suffixes (analogue, catalogue)
Keep US spelling when used in an API, for example 'color'
Use the Oxford comma in documentation: 'ships, planes, and hovercraft' where it aids comprehension
Treat company names as collective nouns in documentation: 'Lille Industries are expanding'
Write headings in sentence case
Use Markdown headings (#, ##, ###, and so on) in order without skipping levels
Follow markdownlint recommendations for markdown forma...

Files:

  • docs/wireframe-testing-crate.md
docs/**/*.{rs,md}

📄 CodeRabbit inference engine (docs/rust-doctest-dry-guide.md)

Every doctest should validate the public API of a crate from the perspective of an external user, treating each documentation test as a separate temporary crate that imports the library as an external dependency

Files:

  • docs/wireframe-testing-crate.md
**/*.md

📄 CodeRabbit inference engine (AGENTS.md)

**/*.md: Validate Markdown files using make markdownlint.
Run make fmt after any documentation changes to format all Markdown files and fix table markup.
Validate Mermaid diagrams in Markdown files by running make nixie.
Markdown paragraphs and bullet points must be wrapped at 80 columns.
Code blocks in Markdown must be wrapped at 120 columns.
Markdown tables and headings must not be wrapped.
Use dashes (-) for list bullets in Markdown.
Use GitHub-flavoured Markdown footnotes ([^1]) for references and footnotes in Markdown.

Files:

  • docs/wireframe-testing-crate.md

⚙️ CodeRabbit configuration file

**/*.md: * Avoid 2nd person or 1st person pronouns ("I", "you", "we")

  • Use en-GB-oxendict (-ize / -yse / -our) spelling and grammar
  • Headings must not be wrapped.
  • Documents must start with a level 1 heading
  • Headings must correctly increase or decrease by no more than one level at a time
  • Use GitHub-flavoured Markdown style for footnotes and endnotes.
  • Numbered footnotes must be numbered by order of appearance in the document.

Files:

  • docs/wireframe-testing-crate.md
🧬 Code graph analysis (2)
wireframe_testing/src/lib.rs (1)
wireframe_testing/src/helpers.rs (2)
  • drive_with_payloads (297-307)
  • drive_with_payloads_mut (321-331)
wireframe_testing/src/helpers.rs (2)
src/app/envelope.rs (3)
  • payload (162-162)
  • new (85-91)
  • new (117-123)
src/frame/format.rs (4)
  • default (112-112)
  • err (142-143)
  • err (145-145)
  • new (32-35)
🪛 LanguageTool
docs/wireframe-testing-crate.md

[uncategorized] ~124-~124: Use a comma before ‘so’ if it connects two independent clauses (unless they are closely connected and short).
Context: ...ould be added as non-breaking extensions so tests can pass FrameCodec values and ...

(COMMA_COMPOUND_SENTENCE_2)


[style] ~231-~231: Would you like to use the Oxford spelling “amortize”? The spelling ‘amortise’ is also correct.
Context: ...ilityHandle` via a per-suite fixture to amortise setup costs. - When partial parallelism...

(OXFORD_SPELLING_Z_NOT_S)

🔍 Remote MCP Deepwiki

Summary of additional repository facts relevant to reviewing PR #414

  • Documentation sources (docs/ and wireframe_testing crate) already describe and implement codec-aware testing helpers, per-test observability, and the ObservabilityHandle/observability() concepts; these docs and test helpers live under wireframe_testing and related docs.,

  • wireframe_testing exposes drive helpers and re-exports:

    • drive_with_payloads / drive_with_payloads_mut implemented in wireframe_testing/src/helpers.rs and re-exported from wireframe_testing::helpers.
  • Test harness behavior and constraints:

    • duplex-based in-memory testing uses tokio::io::duplex with DEFAULT_CAPACITY = 4096 and MAX_CAPACITY ≈ 10MB (configurable capacity variants). Panic isolation uses AssertUnwindSafe + catch_unwind so server task panics surface as io::Error in tests. These details affect ADR-006 guidance about serialisation and running tests with --test-threads=1.
  • Observability/test harness facts:

    • ObservabilityHandle and observability() are documented as the per-test API surface (methods like new(), logs(), snapshot(), clear(), counter()). Docs emphasize global serialization (global lock) to avoid cross-test interference and recommend serial test execution or --test-threads=1. Verify PR doc names/signatures match actual wireframe_testing API to avoid doc/impl drift.
  • FrameCodec and codec testing alignment:

    • Core types (FrameProcessor, Serializer, FrameMetadata, Packet/Envelope, correlation_id propagation) are implemented in core and testing docs; FrameCodec-related helper names (frame_payload, wrap_payload, max_frame_length, TestSerializer trait bounds) must match these existing abstractions or be updated in docs.
  • Roadmap and ADR linking:

    • Roadmap.md and ADR-004 already reference adding codec fixtures and a test observability harness; ADR-006 (new) should be consistent with these roadmap entries.

Actionable checks for the PR reviewer

  • Confirm documented function/type names and signatures (drive_with_raw_bytes, drive_with_payloads, ObservabilityHandle/observability, FrameCodec helper names, TestSerializer bounds) exactly match implementations in wireframe_testing/src/helpers.rs and wireframe_testing/src/logging.rs.
  • Verify guidance in ADR-006 about global lock/serial tests includes explicit instruction (and examples) for running Rust tests with --test-threads=1 or using per-suite fixtures; confirm tests/docs show the DEFAULT_CAPACITY and MAX_CAPACITY values and panic-isolation behavior.
  • Ensure roadmap cross-reference footnote to ADR-006 is present and accurate.

Sources

  • Repo documentation and testing crate contents retrieved via Deepwiki_read_wiki_contents and Deepwiki_read_wiki_structure.,
⏰ Context from checks skipped due to timeout of 120000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
  • GitHub Check: Sourcery review
  • GitHub Check: build-test
🔇 Additional comments (6)
wireframe_testing/src/helpers.rs (3)

282-307: LGTM!

The drive_with_payloads function provides a clean abstraction for tests that need length-prefixed framing without manually constructing frames. The delegation to the capacity variant follows the established pattern in this module.


333-351: LGTM!

The encode_payloads helper encapsulates the framing logic cleanly, returning an io::Result to propagate encoding failures. The pre-allocation using LengthFormat::default().bytes() is consistent with encode_frame at line 523.


604-624: LGTM!

The test validates the round-trip behaviour of drive_with_payloads by encoding an Envelope, driving it through the app, and verifying the payload survives the journey intact. The pattern match on frames.as_slice() is idiomatic for asserting exactly one response frame.

wireframe_testing/src/lib.rs (1)

37-38: LGTM!

The new payload driver helpers are correctly re-exported, extending the crate's public API surface for tests that need automatic length-prefixed framing.

docs/wireframe-testing-crate.md (2)

1-35: LGTM!

The introduction and crate layout provide a clear overview of the testing crate's purpose and structure. The design goals align well with ADR 004 and ADR 006.


272-305: LGTM!

The example tests demonstrate realistic usage of the driver and observability helpers. The round_trips_with_codec example correctly uses drive_with_bincode and decode_frames, and captures_metrics shows the observability harness API.

Comment thread docs/wireframe-testing-crate.md Outdated
Comment thread docs/wireframe-testing-crate.md Outdated
Comment thread docs/wireframe-testing-crate.md Outdated
Adjust punctuation and clarify which codec helpers are proposed,
plus correct the bincode example assertions and spelling.
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

📜 Review details

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between be37037 and 610c46a.

📒 Files selected for processing (1)
  • docs/wireframe-testing-crate.md
🧰 Additional context used
📓 Path-based instructions (3)
docs/**/*.md

📄 CodeRabbit inference engine (docs/contents.md)

Follow the documentation style guide conventions when writing project documentation

Write official documentation with separate guides for 'Duplex Messaging & Pushes', 'Streaming Responses', and 'Message Fragmentation', each including runnable examples and explaining relevant concepts and APIs

docs/**/*.md: Use markdown files within the docs/ directory as a knowledge base and source of truth for project requirements, dependency choices, and architectural decisions.
When new decisions are made, requirements change, libraries are added/removed, or architectural patterns evolve, proactively update the relevant file(s) in the docs/ directory to reflect the latest state. Ensure documentation remains accurate and current.
Documentation must use en-GB-oxendict spelling and grammar ('-ize' / '-yse' / '-our'), with the exception of the filename LICENSE.
Reference the documentation style guide provided at docs/documentation-style-guide.md for documentation writing standards.

Documentation describing multi-packet streaming MUST reflect the tuple-based API and explain helper constructors that prepare the channel pair

Replace or retire documentation that refers to Cucumber, including guides and examples in docs/

docs/**/*.md: Use British English based on the Oxford English Dictionary (en-GB-oxendict), including: -ize suffixes (realize, organization), -lyse suffixes (analyse, paralyse), -our suffixes (colour, behaviour), -re suffixes (calibre, centre), double 'l' (cancelled, counsellor), maintain 'e' (likeable, liveable), -ogue suffixes (analogue, catalogue)
Keep US spelling when used in an API, for example 'color'
Use the Oxford comma in documentation: 'ships, planes, and hovercraft' where it aids comprehension
Treat company names as collective nouns in documentation: 'Lille Industries are expanding'
Write headings in sentence case
Use Markdown headings (#, ##, ###, and so on) in order without skipping levels
Follow markdownlint recommendations for markdown forma...

Files:

  • docs/wireframe-testing-crate.md
docs/**/*.{rs,md}

📄 CodeRabbit inference engine (docs/rust-doctest-dry-guide.md)

Every doctest should validate the public API of a crate from the perspective of an external user, treating each documentation test as a separate temporary crate that imports the library as an external dependency

Files:

  • docs/wireframe-testing-crate.md
**/*.md

📄 CodeRabbit inference engine (AGENTS.md)

**/*.md: Validate Markdown files using make markdownlint.
Run make fmt after any documentation changes to format all Markdown files and fix table markup.
Validate Mermaid diagrams in Markdown files by running make nixie.
Markdown paragraphs and bullet points must be wrapped at 80 columns.
Code blocks in Markdown must be wrapped at 120 columns.
Markdown tables and headings must not be wrapped.
Use dashes (-) for list bullets in Markdown.
Use GitHub-flavoured Markdown footnotes ([^1]) for references and footnotes in Markdown.

Files:

  • docs/wireframe-testing-crate.md

⚙️ CodeRabbit configuration file

**/*.md: * Avoid 2nd person or 1st person pronouns ("I", "you", "we")

  • Use en-GB-oxendict (-ize / -yse / -our) spelling and grammar
  • Headings must not be wrapped.
  • Documents must start with a level 1 heading
  • Headings must correctly increase or decrease by no more than one level at a time
  • Use GitHub-flavoured Markdown style for footnotes and endnotes.
  • Numbered footnotes must be numbered by order of appearance in the document.

Files:

  • docs/wireframe-testing-crate.md
🔍 Remote MCP Deepwiki

Relevant facts to help review PR #414 (documentation + wireframe_testing docs / helpers):

  • New/changed testing APIs documented and implemented in wireframe_testing:

    • drive_with_payloads / drive_with_payloads_mut added and re-exported; they encode payloads as length-delimited frames and return response bytes (helpers in wireframe_testing/src/helpers.rs).
    • ObservabilityHandle API documented with: new(), logs(&mut), snapshot(&self), clear(&mut), counter(&self, name: &str, labels: &[(&str,&str)]) -> u64, plus observability() -> ObservabilityHandle entry point.
    • encode_frames / decode_frames and codec-aware drive helpers documented for codec-aware testing (docs/wireframe-testing-crate).
  • Test harness / observability behavior and constraints:

    • Test observability ADR (ADR-006) proposes an ObservabilityHandle that installs scoped log capture and a metrics recorder, uses a global lock/serialization to avoid cross-test interference, and recommends running tests serially or with --test-threads=1 (or per-suite fixtures) to prevent interference. ADR-006 describes phased rollout: capture primitives first, then wire codec/recovery assertions.
    • wireframe_testing uses tokio::io::duplex with DEFAULT_CAPACITY = 4096 and MAX_CAPACITY ≈ 10MB for in-memory test buffers; panic isolation in test drives uses AssertUnwindSafe + catch_unwind and converts server-task panics into io::Error for tests. These are relevant to ADR-006's guidance on serialization/parallelism.
  • Codec testing guidance / docs alignment points called out by reviewer:

    • Users/docs now describe codec-aware helpers and FrameCodec bounds; reviewers should confirm doc signatures (drive_with_raw_bytes, drive_with_payloads, ObservabilityHandle/observability, FrameCodec helper names like frame_payload/wrap_payload, and TestSerializer trait bounds) exactly match implementations in wireframe_testing/src/helpers.rs and related modules.

Actionable checks for reviewer (derived from repo docs):

  • Verify documented function/type names and signatures match implementations:
    • drive_with_payloads / drive_with_payloads_mut implementations and re-exports in wireframe_testing.
    • ObservabilityHandle and observability() API surface in docs vs wireframe_testing logging/observability implementation.
    • Any FrameCodec/TestSerializer helper names in users-guide and ADR-004 match code (helpers and trait bounds).
  • Confirm ADR-006 includes explicit guidance for running tests serially (--test-threads=1) and documents global lock/serialization behavior and the DEFAULT_CAPACITY / MAX_CAPACITY / panic-isolation details so users can follow mitigations in CI.

Sources consulted: repository docs and wireframe_testing docs/helpers via Deepwiki_read_wiki_contents and structure.

⏰ Context from checks skipped due to timeout of 120000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
  • GitHub Check: Sourcery review
  • GitHub Check: build-test
🔇 Additional comments (1)
docs/wireframe-testing-crate.md (1)

293-305: Verify that inc_frames() in the global metrics module updates the scoped recorder in ObservabilityHandle.

The example calls inc_frames(Direction::Inbound) as a global function at line 299 and then asserts that obs.counter(...) captures the incremented value at lines 300–303. This assumes that the observability handle's scoped metrics recorder is active when inc_frames() is called.

Confirm that:

  1. The observability harness installs a scoped metrics recorder before returning the handle
  2. Global metrics:: function calls (like inc_frames) route to the active scoped recorder during the handle's lifetime
  3. The example correctly reflects this behaviour
Verify in wireframe_testing/src/observability.rs that the ObservabilityHandle::new() method (or observability() function) installs a scoped metrics recorder and that global metrics functions respect this scoping.

Comment thread docs/wireframe-testing-crate.md
Clarify the testing crate documentation by splitting current
frame helper signatures from proposed codec-aware additions.

Update the bincode example assertion and punctuation to avoid
confusion about available APIs.
@leynos leynos merged commit 07e5cd4 into main Jan 4, 2026
6 checks passed
@leynos leynos deleted the custom-codec-documentation branch January 4, 2026 02:57
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant