Conversation
Reviewer's GuideThis PR integrates the Entity relationship diagram for metrics counters and gaugeserDiagram
CONNECTIONS_ACTIVE ||--o{ FRAMES_PROCESSED : tracks
CONNECTIONS_ACTIVE {
string name
float value
}
FRAMES_PROCESSED {
string name
int value
string direction
}
ERRORS_TOTAL {
string name
int value
}
CONNECTIONS_ACTIVE ||--o{ ERRORS_TOTAL : tracks
Class diagram for the new metrics module and helpersclassDiagram
class Direction {
+Inbound
+Outbound
+as_str() str
}
class metrics {
<<module>>
+CONNECTIONS_ACTIVE: &str
+FRAMES_PROCESSED: &str
+ERRORS_TOTAL: &str
+inc_connections()
+dec_connections()
+inc_frames(direction: Direction)
+inc_errors()
}
metrics --> Direction
File-Level Changes
Tips and commandsInteracting with Sourcery
Customizing Your ExperienceAccess your dashboard to:
Getting Help
|
Summary by CodeRabbit
WalkthroughIntroduce a metrics subsystem to the codebase by adding a new Changes
Sequence Diagram(s)sequenceDiagram
participant Client
participant WireframeApp
participant Metrics
Client->>WireframeApp: Send Frame
WireframeApp->>Metrics: inc_frames(Inbound)
alt Deserialization fails
WireframeApp->>Metrics: inc_deser_errors()
else Handler error
WireframeApp->>Metrics: inc_handler_errors()
end
WireframeApp->>Client: Send Response
sequenceDiagram
participant Connection
participant Metrics
Note over Connection: On connection creation
Connection->>Metrics: inc_connections()
Note over Connection: On connection drop
Connection->>Metrics: dec_connections()
Note over Connection: On outbound frame
Connection->>Metrics: inc_frames(Outbound)
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~45 minutes Possibly related PRs
Poem
📜 Recent review detailsConfiguration used: CodeRabbit UI 📒 Files selected for processing (3)
🧰 Additional context used📓 Path-based instructions (2)**/*.rs📄 CodeRabbit Inference Engine (AGENTS.md)
Files:
⚙️ CodeRabbit Configuration File
Files:
Cargo.toml📄 CodeRabbit Inference Engine (AGENTS.md)
Files:
🔇 Additional comments (9)
✨ Finishing Touches
🧪 Generate unit tests
🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
SupportNeed help? Create a ticket on our support page for assistance with any issues or questions. Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments. CodeRabbit Commands (Invoked using PR comments)
Other keywords and placeholders
CodeRabbit Configuration File (
|
There was a problem hiding this comment.
Hey @leynos - I've reviewed your changes and found some issues that need to be addressed.
- Consider gating all metric calls (and the
metricsdependency) behind a Cargo feature (e.g. “metrics”) so users can opt out of pulling in the crate and runtime overhead. - The Prometheus recorder example is duplicated in multiple docs—extract it to a single snippet (for example in the
metricsmodule docs) and reference it in both guides to avoid drift. - You’ve added tests for outbound frames and active connections, but consider adding a test or Cucumber scenario for inbound-frame metrics and error counters to cover the other instrumented paths.
Prompt for AI Agents
Please address the comments from this code review:
## Overall Comments
- Consider gating all metric calls (and the `metrics` dependency) behind a Cargo feature (e.g. “metrics”) so users can opt out of pulling in the crate and runtime overhead.
- The Prometheus recorder example is duplicated in multiple docs—extract it to a single snippet (for example in the `metrics` module docs) and reference it in both guides to avoid drift.
- You’ve added tests for outbound frames and active connections, but consider adding a test or Cucumber scenario for inbound-frame metrics and error counters to cover the other instrumented paths.
## Individual Comments
### Comment 1
<location> `src/app.rs:657` </location>
<code_context>
let (env, _) = match self.parse_envelope(frame) {
Ok(result) => {
*deser_failures = 0;
+ crate::metrics::inc_frames(crate::metrics::Direction::Inbound);
result
}
</code_context>
<issue_to_address>
Metrics increment is only on successful envelope parsing.
To track all inbound frames, increment the metric before parse_envelope; otherwise, only successfully parsed frames are counted.
</issue_to_address>
### Comment 2
<location> `src/app.rs:663` </location>
<code_context>
Err(e) => {
*deser_failures += 1;
tracing::warn!(error = ?e, "failed to deserialize message");
+ crate::metrics::inc_errors();
if *deser_failures >= MAX_DESER_FAILURES {
return Err(io::Error::new(
</code_context>
<issue_to_address>
Error metric is incremented for deserialization failures and handler errors.
Consider using separate counters or labels to differentiate between deserialization failures and handler errors for more precise error metrics.
Suggested implementation:
```rust
crate::metrics::inc_deser_errors();
```
```rust
crate::metrics::inc_handler_errors();
```
```rust
crate::metrics::inc_handler_errors();
```
You will need to implement the new functions `inc_deser_errors()` and `inc_handler_errors()` in your `crate::metrics` module. If you prefer to use a single function with a label, adjust the calls accordingly (e.g., `inc_errors("deserialization")` and `inc_errors("handler")`), and update the metrics module to support labeled error counting.
</issue_to_address>
### Comment 3
<location> `tests/metrics.rs:6` </location>
<code_context>
+use wireframe::{connection::ConnectionActor, push::PushQueues};
+
+#[tokio::test]
+async fn outbound_frame_metric_increments() {
+ let recorder = DebuggingRecorder::new();
+ let snapshotter = recorder.snapshotter();
+ recorder.install().expect("install");
+
+ let (queues, handle) = PushQueues::<u8>::bounded(1, 1);
+ handle.push_high_priority(1).await.unwrap();
+ let token = CancellationToken::new();
+ let mut actor: ConnectionActor<_, ()> = ConnectionActor::new(queues, handle, None, token);
+ let mut out = Vec::new();
+ actor.run(&mut out).await.unwrap();
+
+ let metrics = snapshotter.snapshot().into_vec();
+ let found = metrics
+ .iter()
+ .any(|(k, ..)| k.key().name() == wireframe::metrics::FRAMES_PROCESSED);
+ assert!(found, "frames_processed metric not recorded");
+}
</code_context>
<issue_to_address>
Missing tests for inbound frame and error metrics.
Please add tests to verify that inbound frame and error metrics are also recorded, ensuring full coverage of the metrics functionality.
Suggested implementation:
```rust
#[tokio::test]
async fn outbound_frame_metric_increments() {
let recorder = DebuggingRecorder::new();
let snapshotter = recorder.snapshotter();
recorder.install().expect("install");
let (queues, handle) = PushQueues::<u8>::bounded(1, 1);
handle.push_high_priority(1).await.unwrap();
let token = CancellationToken::new();
let mut actor: ConnectionActor<_, ()> = ConnectionActor::new(queues, handle, None, token);
let mut out = Vec::new();
actor.run(&mut out).await.unwrap();
let metrics = snapshotter.snapshot().into_vec();
let found = metrics
.iter()
.any(|(k, ..)| k.key().name() == wireframe::metrics::FRAMES_PROCESSED);
assert!(found, "frames_processed metric not recorded");
}
#[tokio::test]
async fn inbound_frame_metric_increments() {
let recorder = DebuggingRecorder::new();
let snapshotter = recorder.snapshotter();
recorder.install().expect("install");
let (queues, handle) = PushQueues::<u8>::bounded(1, 1);
// Simulate inbound frame by pushing to the inbound queue if available
queues.inbound().send(2).await.unwrap();
let token = CancellationToken::new();
let mut actor: ConnectionActor<_, ()> = ConnectionActor::new(queues, handle, None, token);
let mut out = Vec::new();
actor.run(&mut out).await.ok();
let metrics = snapshotter.snapshot().into_vec();
let found = metrics
.iter()
.any(|(k, ..)| k.key().name() == wireframe::metrics::INBOUND_FRAMES_PROCESSED);
assert!(found, "inbound_frames_processed metric not recorded");
}
#[tokio::test]
async fn error_metric_increments() {
let recorder = DebuggingRecorder::new();
let snapshotter = recorder.snapshotter();
recorder.install().expect("install");
let (queues, handle) = PushQueues::<u8>::bounded(1, 1);
// Simulate an error by dropping the handle before running the actor
drop(handle);
let token = CancellationToken::new();
let mut actor: ConnectionActor<_, ()> = ConnectionActor::new(queues, /* handle is dropped */ Default::default(), None, token);
let mut out = Vec::new();
// This should result in an error metric being recorded
let _ = actor.run(&mut out).await;
let metrics = snapshotter.snapshot().into_vec();
let found = metrics
.iter()
.any(|(k, ..)| k.key().name() == wireframe::metrics::FRAME_ERRORS);
assert!(found, "frame_errors metric not recorded");
}
```
- If the actual metric names for inbound frames and errors differ from `INBOUND_FRAMES_PROCESSED` and `FRAME_ERRORS`, replace them with the correct constants from `wireframe::metrics`.
- If the `queues.inbound()` or error simulation does not match your actual API, adjust the test logic to properly trigger inbound frame processing and error conditions in your implementation.
</issue_to_address>
### Comment 4
<location> `tests/cucumber.rs:1` </location>
<code_context>
+use cucumber::World as _;
+
+#[derive(Debug, Default, cucumber::World)]
</code_context>
<issue_to_address>
Consider replacing the Cucumber test harness with a simple Rust test file for metrics validation.
Here you pull in a whole Cucumber test harness (and its boilerplate) just to verify a handful of metrics. You can keep the same coverage with a single Rust test file, no extra dependency or `features/` folder needed.
For example, replace the entire `cucumber::World` setup with something like this in `tests/metrics.rs`:
```rust
// tests/metrics.rs
use metrics_exporter_prometheus::{PrometheusBuilder, PrometheusHandle};
use your_crate::record_some_metrics; // <-- your metric logic
#[tokio::test]
async fn basic_metric_export() {
// Install a Prometheus exporter handle
let handle: PrometheusHandle = PrometheusBuilder::new()
.with_family("my_counter", "counter")
.install()
.expect("failed to install exporter");
// Call the code under test
record_some_metrics();
// Grab the rendered output
let output = handle.render();
// Assert that your metric shows up
assert!(
output.contains("my_counter"),
"expected `my_counter` in Prometheus output, got:\n{}",
output
);
}
```
Steps to migrate:
1. Delete the new `main.rs` cucumber harness + `features/` folder.
2. Create `tests/metrics.rs` as shown above.
3. For each scenario in your old `.feature` files, write one `#[test]` or `#[tokio::test]` that:
- Installs a `PrometheusHandle`
- Invokes the behavior under test
- Renders and asserts on the output string.
This keeps all your metric‐validation logic, removes the Cucumber dependency, and slims down your CI setup dramatically.
</issue_to_address>
### Comment 5
<location> `tests/features/metrics.feature:1` </location>
<code_context>
+Feature: metrics exporter
+ Scenario: active connections metric recorded
+ Given a metrics recorder
</code_context>
<issue_to_address>
Consider replacing the Cucumber scenario with a simple Rust test using assertions for the same coverage.
Here’s a simpler, zero-dependency way to get the exact same coverage in a plain Rust test. You can keep the `.feature` file for docs if you want, but move your “active connections” check into an assertion-based test:
```rust
// tests/metrics.rs
use my_crate::metrics::{MetricsRecorder, run_connection};
#[test]
fn active_connections_metric_recorded() {
// arrange
let recorder = MetricsRecorder::new();
// act
run_connection(&recorder, /* no frames */ &[]);
// assert
let output = recorder.scrape();
assert!(
output.contains("active_connections"),
"metrics output did not include `active_connections` gauge; got:\n{}",
output
);
}
```
Actionable steps:
1. Create (or update) `tests/metrics.rs` with the snippet above.
2. Remove your Cucumber runner / glue code for this one scenario.
3. Run `cargo test -- --nocapture` and confirm identical behavior.
</issue_to_address>
### Comment 6
<location> `tests/steps/mod.rs:8` </location>
<code_context>
+use crate::MetricsWorld;
+
+#[given("a metrics recorder")]
+fn metrics_recorder(world: &mut MetricsWorld) {
+ let handle = metrics_exporter_prometheus::PrometheusBuilder::new()
+ .install_recorder()
</code_context>
<issue_to_address>
Consider combining the recorder setup and connection run steps into a single helper or inlining them to eliminate unnecessary indirection and fields.
```markdown
You can collapse the “given” + exporter‐in‐world indirection and the “when” step into a single helper on `MetricsWorld`, or even inline the recorder into the “when” step. That removes the extra `exporter` field and simplifies maintenance, while keeping your scenario semantics.
Example 1: add a helper method on `MetricsWorld`
```rust
impl MetricsWorld {
/// Installs a Prometheus recorder, runs a no‐frame connection,
/// does upkeep, and captures the rendered output.
pub async fn record_active_connections(&mut self) {
let handle = metrics_exporter_prometheus::PrometheusBuilder::new()
.install_recorder()
.expect("recorder install");
let (queues, handle2) = PushQueues::<u8>::bounded(1, 1);
let token = CancellationToken::new();
let mut actor = ConnectionActor::new(queues, handle2, None, token);
let mut out = Vec::new();
actor.run(&mut out).await.unwrap();
handle.run_upkeep();
self.output = Some(handle.render());
}
}
```
Then the step defs become:
```rust
#[when("a connection runs with no frames")]
async fn run_connection(world: &mut MetricsWorld) {
world.record_active_connections().await;
}
#[then("the exporter output includes active connections gauge")]
fn check_output(world: &mut MetricsWorld) {
let out = world.output.as_ref().unwrap();
assert!(out.contains("wireframe_connections_active"), "{out}");
}
```
Example 2: inline everything in the “when” step
```rust
#[when("a connection runs with no frames")]
async fn run_connection(world: &mut MetricsWorld) {
let handle = metrics_exporter_prometheus::PrometheusBuilder::new()
.install_recorder().unwrap();
let (queues, handle2) = PushQueues::<u8>::bounded(1, 1);
let token = CancellationToken::new();
let mut actor = ConnectionActor::new(queues, handle2, None, token);
let mut out = Vec::new();
actor.run(&mut out).await.unwrap();
handle.run_upkeep();
world.output = Some(handle.render());
}
```
Either approach keeps the same behavior but drops the extra `#[given]` indirection and the `exporter` field from your world, reducing boilerplate and future maintenance cost.
</issue_to_address>Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.
There was a problem hiding this comment.
Actionable comments posted: 3
🔭 Outside diff range comments (2)
tests/cucumber.rs (1)
1-13: Address missing dependency and add required module documentation.The build failure indicates
metrics_exporter_prometheusis not available as a dependency. Add it toCargo.tomlunder[dev-dependencies]since it's used in tests.Additionally, this file violates the coding guideline requiring every module to begin with a
//!doc comment explaining the module's purpose and utility.+//! Cucumber test infrastructure for metrics validation. +//! +//! Defines the test world and main test runner for behaviour-driven +//! testing of metrics recording and exporting functionality. + use cucumber::World as _;Also ensure
metrics-exporter-prometheusis added toCargo.toml:[dev-dependencies] metrics-exporter-prometheus = "0.x.x" # Use appropriate versiontests/steps/mod.rs (1)
1-33: Add required module documentation and resolve dependency.This file lacks the mandatory module-level doc comment and has the same dependency issue as the previous file.
+//! Cucumber step definitions for metrics testing. +//! +//! Implements Given-When-Then steps to validate metrics recording +//! and Prometheus export functionality in integration tests. + use cucumber::{given, then, when};
📜 Review details
Configuration used: CodeRabbit UI
Review profile: ASSERTIVE
Plan: Pro
⛔ Files ignored due to path filters (1)
Cargo.lockis excluded by!**/*.lock
📒 Files selected for processing (13)
Cargo.toml(2 hunks)docs/hardening-wireframe-a-guide-to-production-resilience.md(1 hunks)docs/roadmap.md(1 hunks)docs/the-road-to-wireframe-1-0-feature-set-philosophy-and-capability-maturity.md(1 hunks)src/app.rs(2 hunks)src/connection.rs(3 hunks)src/lib.rs(2 hunks)src/metrics.rs(1 hunks)tests/cucumber.rs(1 hunks)tests/features/metrics.feature(1 hunks)tests/metrics.rs(1 hunks)tests/steps/mod.rs(1 hunks)wireframe_testing/Cargo.toml(1 hunks)
📓 Path-based instructions (4)
docs/**/*.md
📄 CodeRabbit Inference Engine (AGENTS.md)
docs/**/*.md: Reference: Use the markdown files within the docs/ directory as a knowledge base and source of truth for project requirements, dependency choices, and architectural decisions.
Update: 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 the documentation remains accurate and current.
Documentation must use en-GB-oxendict spelling and grammar (with the exception of 'license' which is to be left unchanged for community consistency).Conventions for writing project documentation should be followed as described in the documentation style guide.
docs/**/*.md: Use British English based on the Oxford English Dictionary (en-oxendict) for documentation.
The word "outwith" is acceptable in documentation.
Keep US spelling when used in an API, for examplecolor.
Use the Oxford comma in documentation lists and sentences.
Company names are treated as collective nouns (e.g., "Lille Industries are expanding").
Write headings in sentence case.
Use Markdown headings (#,##,###, etc.) in order without skipping levels.
Follow markdownlint recommendations.
Provide code blocks and lists using standard Markdown syntax.
Always provide a language identifier for fenced code blocks; useplaintextfor non-code text.
Use-as the first level bullet and renumber lists when items change.
Prefer inline links using[text](url)or angle brackets around the URL.
Ensure blank lines before and after bulleted lists and fenced blocks.
Ensure tables have a delimiter line below the header row.
Expand any uncommon acronym on first use, for example, Continuous Integration (CI).
Wrap paragraphs at 80 columns.
Wrap code at 120 columns.
Do not wrap tables.
Use footnotes referenced with[^label].
Include Mermaid diagrams where they add clarity in documentation.
When embedding figures, usean...
Files:
docs/roadmap.mddocs/hardening-wireframe-a-guide-to-production-resilience.mddocs/the-road-to-wireframe-1-0-feature-set-philosophy-and-capability-maturity.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 must be wrapped at 120 columns.
Tables and headings must not be wrapped.
Use dashes (-) for list bullets.
Use GitHub-flavoured Markdown footnotes ([^1]) for references.
Files:
docs/roadmap.mddocs/hardening-wireframe-a-guide-to-production-resilience.mddocs/the-road-to-wireframe-1-0-feature-set-philosophy-and-capability-maturity.md
⚙️ CodeRabbit Configuration File
**/*.md: * Avoid 2nd person or 1st person pronouns ("I", "you", "we")
- Use en-GB-oxendict (-ize / -our) spelling and grammar
- Paragraphs and bullets must be wrapped to 80 columns, except where a long URL would prevent this (in which case, silence MD013 for that line)
- Code blocks should be wrapped to 120 columns.
- 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/roadmap.mddocs/hardening-wireframe-a-guide-to-production-resilience.mddocs/the-road-to-wireframe-1-0-feature-set-philosophy-and-capability-maturity.md
**/*.rs
📄 CodeRabbit Inference Engine (AGENTS.md)
**/*.rs: Comment why, not what. Explain assumptions, edge cases, trade-offs, or complexity. Don't echo the obvious.
Comments must use en-GB-oxendict spelling and grammar.
Function documentation must include clear examples.
Name things precisely. Use clear, descriptive variable and function names. For booleans, prefer names with is, has, or should.
Each file should encapsulate a coherent module. Group related code (e.g., models + utilities + fixtures) close together.
Group by feature, not layer. Colocate views, logic, fixtures, and helpers related to a domain concept rather than splitting by type.
Every module must begin with a module level (//! ) comment explaining the module's purpose and utility.
Document public APIs using Rustdoc comments (///) so documentation can be generated with cargo doc.
Place function attributes after doc comments.
Do not use return in single-line functions.
Prefer immutable data and avoid unnecessary mut bindings.
Handle errors with the Result type instead of panicking where feasible.
Avoid unsafe code unless absolutely necessary and document any usage clearly.
Clippy warnings MUST be disallowed.
Lints must not be silenced except as a last resort.
Lint rule suppressions must be tightly scoped and include a clear reason.
Prefer expect over allow.
Fix any warnings emitted during tests in the code itself rather than silencing them.
Write unit and behavioural tests for new functionality. Run both before and after making any change.
Prefer .expect() over .unwrap().
Use predicate functions for conditional criteria with more than two branches.
Where a function is too long, extract meaningfully named helper functions adhering to separation of concerns and CQRS.
Where a function has too many parameters, group related parameters in meaningfully named structs.
Where a function is returning a large error consider using Arc to reduce the amount of data returned.
Files:
src/lib.rstests/metrics.rssrc/connection.rstests/steps/mod.rstests/cucumber.rssrc/app.rssrc/metrics.rs
⚙️ CodeRabbit Configuration File
**/*.rs: * Seek to keep the cyclomatic complexity of functions no more than 12.
Adhere to single responsibility and CQRS
Place function attributes after doc comments.
Do not use
returnin single-line functions.Move conditionals with >2 branches into a predicate function.
Avoid
unsafeunless 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 / -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.Use
rstestfixtures for shared setup and to avoid repetition between tests.Replace duplicated tests with
#[rstest(...)]parameterised cases.Prefer
mockallfor mocks/stubs.Prefer
.expect()over.unwrap()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.
Files:
src/lib.rstests/metrics.rssrc/connection.rstests/steps/mod.rstests/cucumber.rssrc/app.rssrc/metrics.rs
Cargo.toml
📄 CodeRabbit Inference Engine (AGENTS.md)
Use explicit version ranges in Cargo.toml and keep dependencies up-to-date.
Files:
Cargo.toml
🧬 Code Graph Analysis (3)
src/connection.rs (1)
src/metrics.rs (4)
inc_connections(34-34)dec_connections(37-37)inc_frames(40-42)inc_errors(45-45)
tests/steps/mod.rs (3)
src/connection.rs (3)
new(30-34)new(139-152)new(511-520)tests/connection_actor.rs (1)
queues(24-24)src/push.rs (1)
bounded(288-291)
src/app.rs (1)
src/metrics.rs (2)
inc_frames(40-42)inc_errors(45-45)
🪛 LanguageTool
docs/the-road-to-wireframe-1-0-feature-set-philosophy-and-capability-maturity.md
[uncategorized] ~289-~289: Use a comma before ‘so’ if it connects two independent clauses (unless they are closely connected and short).
Context: ...usBuilder` can install a global recorder so external systems may scrape the values....
(COMMA_COMPOUND_SENTENCE_2)
🪛 GitHub Check: build-test
tests/steps/mod.rs
[failure] 9-9:
failed to resolve: use of unresolved module or unlinked crate metrics_exporter_prometheus
tests/cucumber.rs
[failure] 5-5:
failed to resolve: use of unresolved module or unlinked crate metrics_exporter_prometheus
🪛 GitHub Actions: CI
tests/steps/mod.rs
[error] 9-9: Rust compiler error E0433: failed to resolve: use of unresolved module or unlinked crate metrics_exporter_prometheus.
🧰 Additional context used
📓 Path-based instructions (4)
docs/**/*.md
📄 CodeRabbit Inference Engine (AGENTS.md)
docs/**/*.md: Reference: Use the markdown files within the docs/ directory as a knowledge base and source of truth for project requirements, dependency choices, and architectural decisions.
Update: 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 the documentation remains accurate and current.
Documentation must use en-GB-oxendict spelling and grammar (with the exception of 'license' which is to be left unchanged for community consistency).Conventions for writing project documentation should be followed as described in the documentation style guide.
docs/**/*.md: Use British English based on the Oxford English Dictionary (en-oxendict) for documentation.
The word "outwith" is acceptable in documentation.
Keep US spelling when used in an API, for examplecolor.
Use the Oxford comma in documentation lists and sentences.
Company names are treated as collective nouns (e.g., "Lille Industries are expanding").
Write headings in sentence case.
Use Markdown headings (#,##,###, etc.) in order without skipping levels.
Follow markdownlint recommendations.
Provide code blocks and lists using standard Markdown syntax.
Always provide a language identifier for fenced code blocks; useplaintextfor non-code text.
Use-as the first level bullet and renumber lists when items change.
Prefer inline links using[text](url)or angle brackets around the URL.
Ensure blank lines before and after bulleted lists and fenced blocks.
Ensure tables have a delimiter line below the header row.
Expand any uncommon acronym on first use, for example, Continuous Integration (CI).
Wrap paragraphs at 80 columns.
Wrap code at 120 columns.
Do not wrap tables.
Use footnotes referenced with[^label].
Include Mermaid diagrams where they add clarity in documentation.
When embedding figures, usean...
Files:
docs/roadmap.mddocs/hardening-wireframe-a-guide-to-production-resilience.mddocs/the-road-to-wireframe-1-0-feature-set-philosophy-and-capability-maturity.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 must be wrapped at 120 columns.
Tables and headings must not be wrapped.
Use dashes (-) for list bullets.
Use GitHub-flavoured Markdown footnotes ([^1]) for references.
Files:
docs/roadmap.mddocs/hardening-wireframe-a-guide-to-production-resilience.mddocs/the-road-to-wireframe-1-0-feature-set-philosophy-and-capability-maturity.md
⚙️ CodeRabbit Configuration File
**/*.md: * Avoid 2nd person or 1st person pronouns ("I", "you", "we")
- Use en-GB-oxendict (-ize / -our) spelling and grammar
- Paragraphs and bullets must be wrapped to 80 columns, except where a long URL would prevent this (in which case, silence MD013 for that line)
- Code blocks should be wrapped to 120 columns.
- 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/roadmap.mddocs/hardening-wireframe-a-guide-to-production-resilience.mddocs/the-road-to-wireframe-1-0-feature-set-philosophy-and-capability-maturity.md
**/*.rs
📄 CodeRabbit Inference Engine (AGENTS.md)
**/*.rs: Comment why, not what. Explain assumptions, edge cases, trade-offs, or complexity. Don't echo the obvious.
Comments must use en-GB-oxendict spelling and grammar.
Function documentation must include clear examples.
Name things precisely. Use clear, descriptive variable and function names. For booleans, prefer names with is, has, or should.
Each file should encapsulate a coherent module. Group related code (e.g., models + utilities + fixtures) close together.
Group by feature, not layer. Colocate views, logic, fixtures, and helpers related to a domain concept rather than splitting by type.
Every module must begin with a module level (//! ) comment explaining the module's purpose and utility.
Document public APIs using Rustdoc comments (///) so documentation can be generated with cargo doc.
Place function attributes after doc comments.
Do not use return in single-line functions.
Prefer immutable data and avoid unnecessary mut bindings.
Handle errors with the Result type instead of panicking where feasible.
Avoid unsafe code unless absolutely necessary and document any usage clearly.
Clippy warnings MUST be disallowed.
Lints must not be silenced except as a last resort.
Lint rule suppressions must be tightly scoped and include a clear reason.
Prefer expect over allow.
Fix any warnings emitted during tests in the code itself rather than silencing them.
Write unit and behavioural tests for new functionality. Run both before and after making any change.
Prefer .expect() over .unwrap().
Use predicate functions for conditional criteria with more than two branches.
Where a function is too long, extract meaningfully named helper functions adhering to separation of concerns and CQRS.
Where a function has too many parameters, group related parameters in meaningfully named structs.
Where a function is returning a large error consider using Arc to reduce the amount of data returned.
Files:
src/lib.rstests/metrics.rssrc/connection.rstests/steps/mod.rstests/cucumber.rssrc/app.rssrc/metrics.rs
⚙️ CodeRabbit Configuration File
**/*.rs: * Seek to keep the cyclomatic complexity of functions no more than 12.
Adhere to single responsibility and CQRS
Place function attributes after doc comments.
Do not use
returnin single-line functions.Move conditionals with >2 branches into a predicate function.
Avoid
unsafeunless 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 / -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.Use
rstestfixtures for shared setup and to avoid repetition between tests.Replace duplicated tests with
#[rstest(...)]parameterised cases.Prefer
mockallfor mocks/stubs.Prefer
.expect()over.unwrap()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.
Files:
src/lib.rstests/metrics.rssrc/connection.rstests/steps/mod.rstests/cucumber.rssrc/app.rssrc/metrics.rs
Cargo.toml
📄 CodeRabbit Inference Engine (AGENTS.md)
Use explicit version ranges in Cargo.toml and keep dependencies up-to-date.
Files:
Cargo.toml
🧬 Code Graph Analysis (3)
src/connection.rs (1)
src/metrics.rs (4)
inc_connections(34-34)dec_connections(37-37)inc_frames(40-42)inc_errors(45-45)
tests/steps/mod.rs (3)
src/connection.rs (3)
new(30-34)new(139-152)new(511-520)tests/connection_actor.rs (1)
queues(24-24)src/push.rs (1)
bounded(288-291)
src/app.rs (1)
src/metrics.rs (2)
inc_frames(40-42)inc_errors(45-45)
🪛 LanguageTool
docs/the-road-to-wireframe-1-0-feature-set-philosophy-and-capability-maturity.md
[uncategorized] ~289-~289: Use a comma before ‘so’ if it connects two independent clauses (unless they are closely connected and short).
Context: ...usBuilder` can install a global recorder so external systems may scrape the values....
(COMMA_COMPOUND_SENTENCE_2)
🪛 GitHub Check: build-test
tests/steps/mod.rs
[failure] 9-9:
failed to resolve: use of unresolved module or unlinked crate metrics_exporter_prometheus
tests/cucumber.rs
[failure] 5-5:
failed to resolve: use of unresolved module or unlinked crate metrics_exporter_prometheus
🪛 GitHub Actions: CI
tests/steps/mod.rs
[error] 9-9: Rust compiler error E0433: failed to resolve: use of unresolved module or unlinked crate metrics_exporter_prometheus.
🔇 Additional comments (25)
wireframe_testing/Cargo.toml (1)
14-14: LGTM: Dependency addition supports metrics testing.The
metrics-utildependency addition is appropriate for supporting the new metrics testing functionality.docs/roadmap.md (1)
153-159: LGTM: Roadmap accurately reflects completed metrics work.The marking of metrics and observability tasks as complete correctly reflects the implementation of metrics throughout the codebase, including the new metrics module, instrumentation, and Prometheus integration guide.
src/lib.rs (2)
15-15: LGTM: Metrics module properly exposed.The addition of the
metricsmodule follows the established pattern for public module exposure.
26-26: LGTM: Key metrics items appropriately re-exported.Re-exporting
CONNECTIONS_ACTIVE,Direction,ERRORS_TOTAL, andFRAMES_PROCESSEDat the crate root provides convenient access to the most commonly used metrics components.tests/features/metrics.feature (1)
1-6: LGTM: Well-structured Cucumber feature test.The metrics exporter feature test follows proper Gherkin syntax and provides focused validation of active connections gauge recording. The Given-When-Then structure clearly defines the test scenario.
docs/the-road-to-wireframe-1-0-feature-set-philosophy-and-capability-maturity.md (2)
288-299: LGTM: Excellent metrics integration documentation.The addition clearly explains metrics emission using the
metricscrate and provides a practical code example for Prometheus integration. The content fits well within the observability section and enhances the documentation's completeness.
289-289: Add comma for proper compound sentence structure.The sentence requires a comma before "so" when connecting two independent clauses.
-install a global recorder so external systems may scrape the values. The +install a global recorder, so external systems may scrape the values. TheLikely an incorrect or invalid review comment.
Cargo.toml (3)
18-19: LGTM! Clean metrics dependency integration.The
metricscrate addition and optional Prometheus exporter with appropriate feature flags support the observability requirements effectively.
30-31: Appropriate testing dependencies added.The
cucumberandmetrics-utiladditions support comprehensive testing of the metrics functionality.
39-41: Correct cucumber test configuration.Disabling the test harness for cucumber tests follows standard practice for BDD testing frameworks.
docs/hardening-wireframe-a-guide-to-production-resilience.md (1)
350-366: Excellent addition to the hardening guide.This section logically extends the production resilience theme by covering observability requirements. The Prometheus integration example is concise and demonstrates the essential setup clearly. The documentation maintains consistency with the existing guide's tone and technical depth.
src/app.rs (3)
657-657: Proper inbound frame tracking.Correctly increments the inbound frames metric upon successful deserialization, providing visibility into message processing throughput.
663-663: Appropriate error tracking on deserialization failures.Captures deserialization errors in the metrics, essential for monitoring data quality issues and potential attacks.
684-684: Comprehensive error instrumentation.Error metrics cover all failure scenarios: response sending, handler execution, and missing routes. This provides complete visibility into application-level errors.
Also applies to: 689-689, 694-694
tests/metrics.rs (1)
5-23: Well-structured metrics integration test.This test effectively validates outbound frame metric tracking by using the debugging recorder, exercising the connection actor with actual frame processing, and verifying the metric presence. The focused approach ensures the test validates the specific metrics integration without unnecessary complexity.
src/connection.rs (5)
32-32: Proper connection lifecycle tracking.Correctly increments the active connections metric on connection creation, complementing the existing atomic counter.
39-41: Clean connection cleanup tracking.The drop implementation properly decrements both the atomic counter and metrics gauge, ensuring accurate connection state tracking.
329-329: Accurate outbound frame tracking from push queues.Correctly instruments frame processing from push queues with the Outbound direction label, providing visibility into pushed message throughput.
430-430: Complete outbound frame instrumentation.Tracks frames from response streams alongside push queue frames, ensuring comprehensive outbound message visibility.
437-437: Appropriate error tracking on protocol failures.Captures protocol errors in metrics, providing visibility into application-level issues during response stream processing.
tests/steps/mod.rs (1)
15-26: Well-structured test step implementation.The async step correctly:
- Creates bounded push queues with appropriate capacity
- Instantiates ConnectionActor with proper parameters
- Runs the actor and captures metrics output
- Handles the optional exporter gracefully
src/metrics.rs (4)
1-5: Excellent module documentation.The module doc comment clearly explains the purpose and references the metrics crate documentation. This meets the coding guideline requirements perfectly.
8-13: Well-defined metric constants with clear documentation.The metric names follow Prometheus naming conventions and include descriptive doc comments. The consistent
wireframe_prefix ensures no namespace conflicts.
15-31: Clean Direction enum implementation.The enum provides clear semantics for frame processing direction with:
- Appropriate derive traits (Clone, Copy)
- Clear variant documentation
- Private
as_str()method for consistent string representation- Simple match implementation
33-45: Well-designed helper functions.The metric helper functions provide a clean API that:
- Encapsulate the metrics crate complexity
- Use appropriate metric types (gauge for connections, counter for frames/errors)
- Include direction labelling for frame metrics
- Follow consistent naming patterns
There was a problem hiding this comment.
Actionable comments posted: 2
♻️ Duplicate comments (1)
tests/metrics.rs (1)
23-51: Tests for inbound frames and errors are now implemented.The missing test coverage mentioned in previous reviews has been addressed. The current implementation is superior to the suggested approach, using proper metric isolation rather than complex actor setups.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: ASSERTIVE
Plan: Pro
⛔ Files ignored due to path filters (1)
Cargo.lockis excluded by!**/*.lock
📒 Files selected for processing (7)
Cargo.toml(2 hunks)docs/hardening-wireframe-a-guide-to-production-resilience.md(1 hunks)docs/the-road-to-wireframe-1-0-feature-set-philosophy-and-capability-maturity.md(1 hunks)src/app.rs(3 hunks)src/connection.rs(3 hunks)src/metrics.rs(1 hunks)tests/metrics.rs(1 hunks)
📓 Path-based instructions (4)
docs/**/*.md
📄 CodeRabbit Inference Engine (AGENTS.md)
docs/**/*.md: Reference: Use the markdown files within the docs/ directory as a knowledge base and source of truth for project requirements, dependency choices, and architectural decisions.
Update: 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 the documentation remains accurate and current.
Documentation must use en-GB-oxendict spelling and grammar (with the exception of 'license' which is to be left unchanged for community consistency).Conventions for writing project documentation should be followed as described in the documentation style guide.
docs/**/*.md: Use British English based on the Oxford English Dictionary (en-oxendict) for documentation.
The word "outwith" is acceptable in documentation.
Keep US spelling when used in an API, for examplecolor.
Use the Oxford comma in documentation lists and sentences.
Company names are treated as collective nouns (e.g., "Lille Industries are expanding").
Write headings in sentence case.
Use Markdown headings (#,##,###, etc.) in order without skipping levels.
Follow markdownlint recommendations.
Provide code blocks and lists using standard Markdown syntax.
Always provide a language identifier for fenced code blocks; useplaintextfor non-code text.
Use-as the first level bullet and renumber lists when items change.
Prefer inline links using[text](url)or angle brackets around the URL.
Ensure blank lines before and after bulleted lists and fenced blocks.
Ensure tables have a delimiter line below the header row.
Expand any uncommon acronym on first use, for example, Continuous Integration (CI).
Wrap paragraphs at 80 columns.
Wrap code at 120 columns.
Do not wrap tables.
Use footnotes referenced with[^label].
Include Mermaid diagrams where they add clarity in documentation.
When embedding figures, usean...
Files:
docs/hardening-wireframe-a-guide-to-production-resilience.mddocs/the-road-to-wireframe-1-0-feature-set-philosophy-and-capability-maturity.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 must be wrapped at 120 columns.
Tables and headings must not be wrapped.
Use dashes (-) for list bullets.
Use GitHub-flavoured Markdown footnotes ([^1]) for references.
Files:
docs/hardening-wireframe-a-guide-to-production-resilience.mddocs/the-road-to-wireframe-1-0-feature-set-philosophy-and-capability-maturity.md
⚙️ CodeRabbit Configuration File
**/*.md: * Avoid 2nd person or 1st person pronouns ("I", "you", "we")
- Use en-GB-oxendict (-ize / -our) spelling and grammar
- Paragraphs and bullets must be wrapped to 80 columns, except where a long URL would prevent this (in which case, silence MD013 for that line)
- Code blocks should be wrapped to 120 columns.
- 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/hardening-wireframe-a-guide-to-production-resilience.mddocs/the-road-to-wireframe-1-0-feature-set-philosophy-and-capability-maturity.md
**/*.rs
📄 CodeRabbit Inference Engine (AGENTS.md)
**/*.rs: Comment why, not what. Explain assumptions, edge cases, trade-offs, or complexity. Don't echo the obvious.
Comments must use en-GB-oxendict spelling and grammar.
Function documentation must include clear examples.
Name things precisely. Use clear, descriptive variable and function names. For booleans, prefer names with is, has, or should.
Each file should encapsulate a coherent module. Group related code (e.g., models + utilities + fixtures) close together.
Group by feature, not layer. Colocate views, logic, fixtures, and helpers related to a domain concept rather than splitting by type.
Every module must begin with a module level (//! ) comment explaining the module's purpose and utility.
Document public APIs using Rustdoc comments (///) so documentation can be generated with cargo doc.
Place function attributes after doc comments.
Do not use return in single-line functions.
Prefer immutable data and avoid unnecessary mut bindings.
Handle errors with the Result type instead of panicking where feasible.
Avoid unsafe code unless absolutely necessary and document any usage clearly.
Clippy warnings MUST be disallowed.
Lints must not be silenced except as a last resort.
Lint rule suppressions must be tightly scoped and include a clear reason.
Prefer expect over allow.
Fix any warnings emitted during tests in the code itself rather than silencing them.
Write unit and behavioural tests for new functionality. Run both before and after making any change.
Prefer .expect() over .unwrap().
Use predicate functions for conditional criteria with more than two branches.
Where a function is too long, extract meaningfully named helper functions adhering to separation of concerns and CQRS.
Where a function has too many parameters, group related parameters in meaningfully named structs.
Where a function is returning a large error consider using Arc to reduce the amount of data returned.
Files:
src/app.rstests/metrics.rssrc/metrics.rssrc/connection.rs
⚙️ CodeRabbit Configuration File
**/*.rs: * Seek to keep the cyclomatic complexity of functions no more than 12.
Adhere to single responsibility and CQRS
Place function attributes after doc comments.
Do not use
returnin single-line functions.Move conditionals with >2 branches into a predicate function.
Avoid
unsafeunless 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 / -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.Use
rstestfixtures for shared setup and to avoid repetition between tests.Replace duplicated tests with
#[rstest(...)]parameterised cases.Prefer
mockallfor mocks/stubs.Prefer
.expect()over.unwrap()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.
Files:
src/app.rstests/metrics.rssrc/metrics.rssrc/connection.rs
Cargo.toml
📄 CodeRabbit Inference Engine (AGENTS.md)
Use explicit version ranges in Cargo.toml and keep dependencies up-to-date.
Files:
Cargo.toml
🧬 Code Graph Analysis (3)
src/app.rs (1)
src/metrics.rs (6)
inc_frames(62-64)inc_frames(67-67)inc_deser_errors(71-71)inc_deser_errors(74-74)inc_handler_errors(78-78)inc_handler_errors(81-81)
tests/metrics.rs (1)
src/metrics.rs (4)
inc_frames(62-64)inc_frames(67-67)inc_deser_errors(71-71)inc_deser_errors(74-74)
src/connection.rs (1)
src/metrics.rs (8)
inc_connections(48-48)inc_connections(51-51)dec_connections(55-55)dec_connections(58-58)inc_frames(62-64)inc_frames(67-67)inc_handler_errors(78-78)inc_handler_errors(81-81)
🪛 LanguageTool
docs/the-road-to-wireframe-1-0-feature-set-philosophy-and-capability-maturity.md
[uncategorized] ~290-~290: Use a comma before ‘so’ if it connects two independent clauses (unless they are closely connected and short).
Context: ...rumentation is gated behind this feature so users can opt out if metrics are unnece...
(COMMA_COMPOUND_SENTENCE_2)
🪛 GitHub Check: build-test
tests/metrics.rs
[warning] 30-30:
Diff in /home/runner/work/wireframe/wireframe/tests/metrics.rs
🪛 GitHub Actions: CI
tests/metrics.rs
[warning] 30-30: cargo fmt formatting check failed. Diff detected in code formatting at line 30.
🧰 Additional context used
📓 Path-based instructions (4)
docs/**/*.md
📄 CodeRabbit Inference Engine (AGENTS.md)
docs/**/*.md: Reference: Use the markdown files within the docs/ directory as a knowledge base and source of truth for project requirements, dependency choices, and architectural decisions.
Update: 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 the documentation remains accurate and current.
Documentation must use en-GB-oxendict spelling and grammar (with the exception of 'license' which is to be left unchanged for community consistency).Conventions for writing project documentation should be followed as described in the documentation style guide.
docs/**/*.md: Use British English based on the Oxford English Dictionary (en-oxendict) for documentation.
The word "outwith" is acceptable in documentation.
Keep US spelling when used in an API, for examplecolor.
Use the Oxford comma in documentation lists and sentences.
Company names are treated as collective nouns (e.g., "Lille Industries are expanding").
Write headings in sentence case.
Use Markdown headings (#,##,###, etc.) in order without skipping levels.
Follow markdownlint recommendations.
Provide code blocks and lists using standard Markdown syntax.
Always provide a language identifier for fenced code blocks; useplaintextfor non-code text.
Use-as the first level bullet and renumber lists when items change.
Prefer inline links using[text](url)or angle brackets around the URL.
Ensure blank lines before and after bulleted lists and fenced blocks.
Ensure tables have a delimiter line below the header row.
Expand any uncommon acronym on first use, for example, Continuous Integration (CI).
Wrap paragraphs at 80 columns.
Wrap code at 120 columns.
Do not wrap tables.
Use footnotes referenced with[^label].
Include Mermaid diagrams where they add clarity in documentation.
When embedding figures, usean...
Files:
docs/hardening-wireframe-a-guide-to-production-resilience.mddocs/the-road-to-wireframe-1-0-feature-set-philosophy-and-capability-maturity.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 must be wrapped at 120 columns.
Tables and headings must not be wrapped.
Use dashes (-) for list bullets.
Use GitHub-flavoured Markdown footnotes ([^1]) for references.
Files:
docs/hardening-wireframe-a-guide-to-production-resilience.mddocs/the-road-to-wireframe-1-0-feature-set-philosophy-and-capability-maturity.md
⚙️ CodeRabbit Configuration File
**/*.md: * Avoid 2nd person or 1st person pronouns ("I", "you", "we")
- Use en-GB-oxendict (-ize / -our) spelling and grammar
- Paragraphs and bullets must be wrapped to 80 columns, except where a long URL would prevent this (in which case, silence MD013 for that line)
- Code blocks should be wrapped to 120 columns.
- 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/hardening-wireframe-a-guide-to-production-resilience.mddocs/the-road-to-wireframe-1-0-feature-set-philosophy-and-capability-maturity.md
**/*.rs
📄 CodeRabbit Inference Engine (AGENTS.md)
**/*.rs: Comment why, not what. Explain assumptions, edge cases, trade-offs, or complexity. Don't echo the obvious.
Comments must use en-GB-oxendict spelling and grammar.
Function documentation must include clear examples.
Name things precisely. Use clear, descriptive variable and function names. For booleans, prefer names with is, has, or should.
Each file should encapsulate a coherent module. Group related code (e.g., models + utilities + fixtures) close together.
Group by feature, not layer. Colocate views, logic, fixtures, and helpers related to a domain concept rather than splitting by type.
Every module must begin with a module level (//! ) comment explaining the module's purpose and utility.
Document public APIs using Rustdoc comments (///) so documentation can be generated with cargo doc.
Place function attributes after doc comments.
Do not use return in single-line functions.
Prefer immutable data and avoid unnecessary mut bindings.
Handle errors with the Result type instead of panicking where feasible.
Avoid unsafe code unless absolutely necessary and document any usage clearly.
Clippy warnings MUST be disallowed.
Lints must not be silenced except as a last resort.
Lint rule suppressions must be tightly scoped and include a clear reason.
Prefer expect over allow.
Fix any warnings emitted during tests in the code itself rather than silencing them.
Write unit and behavioural tests for new functionality. Run both before and after making any change.
Prefer .expect() over .unwrap().
Use predicate functions for conditional criteria with more than two branches.
Where a function is too long, extract meaningfully named helper functions adhering to separation of concerns and CQRS.
Where a function has too many parameters, group related parameters in meaningfully named structs.
Where a function is returning a large error consider using Arc to reduce the amount of data returned.
Files:
src/app.rstests/metrics.rssrc/metrics.rssrc/connection.rs
⚙️ CodeRabbit Configuration File
**/*.rs: * Seek to keep the cyclomatic complexity of functions no more than 12.
Adhere to single responsibility and CQRS
Place function attributes after doc comments.
Do not use
returnin single-line functions.Move conditionals with >2 branches into a predicate function.
Avoid
unsafeunless 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 / -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.Use
rstestfixtures for shared setup and to avoid repetition between tests.Replace duplicated tests with
#[rstest(...)]parameterised cases.Prefer
mockallfor mocks/stubs.Prefer
.expect()over.unwrap()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.
Files:
src/app.rstests/metrics.rssrc/metrics.rssrc/connection.rs
Cargo.toml
📄 CodeRabbit Inference Engine (AGENTS.md)
Use explicit version ranges in Cargo.toml and keep dependencies up-to-date.
Files:
Cargo.toml
🧬 Code Graph Analysis (3)
src/app.rs (1)
src/metrics.rs (6)
inc_frames(62-64)inc_frames(67-67)inc_deser_errors(71-71)inc_deser_errors(74-74)inc_handler_errors(78-78)inc_handler_errors(81-81)
tests/metrics.rs (1)
src/metrics.rs (4)
inc_frames(62-64)inc_frames(67-67)inc_deser_errors(71-71)inc_deser_errors(74-74)
src/connection.rs (1)
src/metrics.rs (8)
inc_connections(48-48)inc_connections(51-51)dec_connections(55-55)dec_connections(58-58)inc_frames(62-64)inc_frames(67-67)inc_handler_errors(78-78)inc_handler_errors(81-81)
🪛 LanguageTool
docs/the-road-to-wireframe-1-0-feature-set-philosophy-and-capability-maturity.md
[uncategorized] ~290-~290: Use a comma before ‘so’ if it connects two independent clauses (unless they are closely connected and short).
Context: ...rumentation is gated behind this feature so users can opt out if metrics are unnece...
(COMMA_COMPOUND_SENTENCE_2)
🪛 GitHub Check: build-test
tests/metrics.rs
[warning] 30-30:
Diff in /home/runner/work/wireframe/wireframe/tests/metrics.rs
🪛 GitHub Actions: CI
tests/metrics.rs
[warning] 30-30: cargo fmt formatting check failed. Diff detected in code formatting at line 30.
🔇 Additional comments (16)
docs/hardening-wireframe-a-guide-to-production-resilience.md (1)
350-355: Excellent addition of observability guidance.The new metrics section appropriately emphasises operational visibility and correctly references the optional feature gating. The content aligns well with the production resilience theme of this document.
src/app.rs (3)
654-654: Correct placement of inbound frame metric.The metric increment is positioned properly before envelope parsing to capture all inbound frames, addressing the concern from previous reviews about only counting successfully parsed frames.
663-663: Appropriate error categorisation for deserialization failures.The use of
inc_deser_errors()correctly differentiates deserialization failures from handler errors, implementing the suggestion from previous reviews for more precise error metrics.
684-684: Consistent handler error tracking across failure scenarios.All handler-related error conditions (send failures, handler errors, and missing handlers) are consistently tracked using
inc_handler_errors(), providing comprehensive coverage of handler-related issues.Also applies to: 689-689, 694-694
Cargo.toml (2)
33-34: Well-structured metrics feature configuration.The feature definition properly includes both required dependencies and setting it as default provides good ergonomics whilst maintaining the ability to opt out.
18-19: Approve metrics dependenciesConfirmed that
metrics = "0.24"pulls in v0.24.2 andmetrics-exporter-prometheus = "0.17"pulls in v0.17.2. No known security advisories affect these crates. Merge as is.src/connection.rs (3)
32-32: Excellent integration with RAII connection tracking.The metrics calls are properly integrated with the existing
ActiveConnectionRAII pattern, ensuring accurate connection count tracking that automatically handles cleanup on drop.Also applies to: 39-41
329-329: Consistent outbound frame tracking.Both push queue frames and response stream frames are properly tracked with the outbound direction label, providing comprehensive coverage of outbound frame metrics.
Also applies to: 430-430
437-437: Appropriate protocol error tracking.The handler error metric is correctly incremented for protocol errors in the response stream, maintaining consistency with error categorisation across the codebase.
tests/metrics.rs (3)
3-7: Well-structured helper function.The helper function properly encapsulates the recorder setup logic, promoting code reuse across tests.
9-21: Solid test implementation for outbound frame metrics.The test correctly isolates metric recording and validates the presence of the expected metric.
39-51: Error metrics test is properly implemented.The test correctly validates that deserialization error metrics are recorded.
src/metrics.rs (4)
1-17: Excellent module documentation with practical example.The module documentation clearly explains the purpose, feature gating behaviour, and includes a helpful Prometheus integration example.
21-26: Well-defined metric constants following Prometheus conventions.The metric name constants are appropriately named and documented, following standard Prometheus naming patterns.
28-44: Direction enum is well-designed and implemented.The enum properly represents frame processing directions with appropriate derives and a clean string conversion method.
46-81: Excellent feature-gated metrics implementation.The helper functions are properly implemented with appropriate feature gating, providing no-op versions when metrics are disabled. The use of gauge for connections and counters for frames/errors is correct.
| #[test] | ||
| fn inbound_frame_metric_increments() { | ||
| let (snapshotter, recorder) = snapshotter(); | ||
| metrics::with_local_recorder(&recorder, || { | ||
| wireframe::metrics::inc_frames(wireframe::metrics::Direction::Inbound); | ||
| }); | ||
|
|
||
| let metrics = snapshotter.snapshot().into_vec(); | ||
| let found = metrics.iter().any(|(k, _, _, v)| { | ||
| k.key().name() == wireframe::metrics::FRAMES_PROCESSED | ||
| && k.key().labels().any(|l| l.key() == "direction" && l.value() == "inbound") | ||
| && matches!(v, DebugValue::Counter(c) if *c > 0) | ||
| }); | ||
| assert!(found, "inbound frames metric not recorded"); | ||
| } |
There was a problem hiding this comment.
Fix formatting issue in the inbound frame test.
The test logic is comprehensive and correctly validates metric name, labels, and counter value. However, there's a formatting issue that must be resolved.
Apply this diff to fix the formatting:
- let found = metrics.iter().any(|(k, _, _, v)| {
+ let found = metrics
+ .iter()
+ .any(|(k, _, _, v)| {
k.key().name() == wireframe::metrics::FRAMES_PROCESSED
&& k.key().labels().any(|l| l.key() == "direction" && l.value() == "inbound")
&& matches!(v, DebugValue::Counter(c) if *c > 0)
- });
+ });📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| #[test] | |
| fn inbound_frame_metric_increments() { | |
| let (snapshotter, recorder) = snapshotter(); | |
| metrics::with_local_recorder(&recorder, || { | |
| wireframe::metrics::inc_frames(wireframe::metrics::Direction::Inbound); | |
| }); | |
| let metrics = snapshotter.snapshot().into_vec(); | |
| let found = metrics.iter().any(|(k, _, _, v)| { | |
| k.key().name() == wireframe::metrics::FRAMES_PROCESSED | |
| && k.key().labels().any(|l| l.key() == "direction" && l.value() == "inbound") | |
| && matches!(v, DebugValue::Counter(c) if *c > 0) | |
| }); | |
| assert!(found, "inbound frames metric not recorded"); | |
| } | |
| let metrics = snapshotter.snapshot().into_vec(); | |
| let found = metrics | |
| .iter() | |
| .any(|(k, _, _, v)| { | |
| k.key().name() == wireframe::metrics::FRAMES_PROCESSED | |
| && k.key().labels().any(|l| l.key() == "direction" && l.value() == "inbound") | |
| && matches!(v, DebugValue::Counter(c) if *c > 0) | |
| }); | |
| assert!(found, "inbound frames metric not recorded"); |
🧰 Tools
🪛 GitHub Check: build-test
[warning] 30-30:
Diff in /home/runner/work/wireframe/wireframe/tests/metrics.rs
🪛 GitHub Actions: CI
[warning] 30-30: cargo fmt formatting check failed. Diff detected in code formatting at line 30.
🤖 Prompt for AI Agents
In tests/metrics.rs around lines 23 to 37, the test function
inbound_frame_metric_increments has a formatting issue. Fix the formatting by
ensuring consistent indentation and spacing according to Rust style guidelines,
such as proper alignment of code blocks, consistent use of blank lines, and
correct placement of braces to improve readability and maintainability.
There was a problem hiding this comment.
Actionable comments posted: 3
📜 Review details
Configuration used: CodeRabbit UI
Review profile: ASSERTIVE
Plan: Pro
📒 Files selected for processing (1)
tests/metrics.rs(1 hunks)
📓 Path-based instructions (1)
**/*.rs
📄 CodeRabbit Inference Engine (AGENTS.md)
**/*.rs: Comment why, not what. Explain assumptions, edge cases, trade-offs, or complexity. Don't echo the obvious.
Comments must use en-GB-oxendict spelling and grammar.
Function documentation must include clear examples.
Name things precisely. Use clear, descriptive variable and function names. For booleans, prefer names with is, has, or should.
Each file should encapsulate a coherent module. Group related code (e.g., models + utilities + fixtures) close together.
Group by feature, not layer. Colocate views, logic, fixtures, and helpers related to a domain concept rather than splitting by type.
Every module must begin with a module level (//! ) comment explaining the module's purpose and utility.
Document public APIs using Rustdoc comments (///) so documentation can be generated with cargo doc.
Place function attributes after doc comments.
Do not use return in single-line functions.
Prefer immutable data and avoid unnecessary mut bindings.
Handle errors with the Result type instead of panicking where feasible.
Avoid unsafe code unless absolutely necessary and document any usage clearly.
Clippy warnings MUST be disallowed.
Lints must not be silenced except as a last resort.
Lint rule suppressions must be tightly scoped and include a clear reason.
Prefer expect over allow.
Fix any warnings emitted during tests in the code itself rather than silencing them.
Write unit and behavioural tests for new functionality. Run both before and after making any change.
Prefer .expect() over .unwrap().
Use predicate functions for conditional criteria with more than two branches.
Where a function is too long, extract meaningfully named helper functions adhering to separation of concerns and CQRS.
Where a function has too many parameters, group related parameters in meaningfully named structs.
Where a function is returning a large error consider using Arc to reduce the amount of data returned.
Files:
tests/metrics.rs
⚙️ CodeRabbit Configuration File
**/*.rs: * Seek to keep the cyclomatic complexity of functions no more than 12.
Adhere to single responsibility and CQRS
Place function attributes after doc comments.
Do not use
returnin single-line functions.Move conditionals with >2 branches into a predicate function.
Avoid
unsafeunless 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 / -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.Use
rstestfixtures for shared setup and to avoid repetition between tests.Replace duplicated tests with
#[rstest(...)]parameterised cases.Prefer
mockallfor mocks/stubs.Prefer
.expect()over.unwrap()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.
Files:
tests/metrics.rs
🧰 Additional context used
📓 Path-based instructions (1)
**/*.rs
📄 CodeRabbit Inference Engine (AGENTS.md)
**/*.rs: Comment why, not what. Explain assumptions, edge cases, trade-offs, or complexity. Don't echo the obvious.
Comments must use en-GB-oxendict spelling and grammar.
Function documentation must include clear examples.
Name things precisely. Use clear, descriptive variable and function names. For booleans, prefer names with is, has, or should.
Each file should encapsulate a coherent module. Group related code (e.g., models + utilities + fixtures) close together.
Group by feature, not layer. Colocate views, logic, fixtures, and helpers related to a domain concept rather than splitting by type.
Every module must begin with a module level (//! ) comment explaining the module's purpose and utility.
Document public APIs using Rustdoc comments (///) so documentation can be generated with cargo doc.
Place function attributes after doc comments.
Do not use return in single-line functions.
Prefer immutable data and avoid unnecessary mut bindings.
Handle errors with the Result type instead of panicking where feasible.
Avoid unsafe code unless absolutely necessary and document any usage clearly.
Clippy warnings MUST be disallowed.
Lints must not be silenced except as a last resort.
Lint rule suppressions must be tightly scoped and include a clear reason.
Prefer expect over allow.
Fix any warnings emitted during tests in the code itself rather than silencing them.
Write unit and behavioural tests for new functionality. Run both before and after making any change.
Prefer .expect() over .unwrap().
Use predicate functions for conditional criteria with more than two branches.
Where a function is too long, extract meaningfully named helper functions adhering to separation of concerns and CQRS.
Where a function has too many parameters, group related parameters in meaningfully named structs.
Where a function is returning a large error consider using Arc to reduce the amount of data returned.
Files:
tests/metrics.rs
⚙️ CodeRabbit Configuration File
**/*.rs: * Seek to keep the cyclomatic complexity of functions no more than 12.
Adhere to single responsibility and CQRS
Place function attributes after doc comments.
Do not use
returnin single-line functions.Move conditionals with >2 branches into a predicate function.
Avoid
unsafeunless 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 / -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.Use
rstestfixtures for shared setup and to avoid repetition between tests.Replace duplicated tests with
#[rstest(...)]parameterised cases.Prefer
mockallfor mocks/stubs.Prefer
.expect()over.unwrap()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.
Files:
tests/metrics.rs
⏰ Context from checks skipped due to timeout of 240000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
- GitHub Check: build-test
🔇 Additional comments (2)
tests/metrics.rs (2)
1-4: Module documentation follows guidelines correctly.The module-level doc comment properly explains the module's purpose and testing approach using the required
//!format.
27-43: Well-implemented comprehensive test.The test correctly validates metric name, direction label, and counter value. The formatting issues from previous reviews appear to have been resolved.
There was a problem hiding this comment.
Actionable comments posted: 1
📜 Review details
Configuration used: CodeRabbit UI
Review profile: ASSERTIVE
Plan: Pro
📒 Files selected for processing (1)
docs/the-road-to-wireframe-1-0-feature-set-philosophy-and-capability-maturity.md(1 hunks)
📓 Path-based instructions (2)
docs/**/*.md
📄 CodeRabbit Inference Engine (AGENTS.md)
docs/**/*.md: Reference: Use the markdown files within the docs/ directory as a knowledge base and source of truth for project requirements, dependency choices, and architectural decisions.
Update: 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 the documentation remains accurate and current.
Documentation must use en-GB-oxendict spelling and grammar (with the exception of 'license' which is to be left unchanged for community consistency).Conventions for writing project documentation should be followed as described in the documentation style guide.
docs/**/*.md: Use British English based on the Oxford English Dictionary (en-oxendict) for documentation.
The word "outwith" is acceptable in documentation.
Keep US spelling when used in an API, for examplecolor.
Use the Oxford comma in documentation lists and sentences.
Company names are treated as collective nouns (e.g., "Lille Industries are expanding").
Write headings in sentence case.
Use Markdown headings (#,##,###, etc.) in order without skipping levels.
Follow markdownlint recommendations.
Provide code blocks and lists using standard Markdown syntax.
Always provide a language identifier for fenced code blocks; useplaintextfor non-code text.
Use-as the first level bullet and renumber lists when items change.
Prefer inline links using[text](url)or angle brackets around the URL.
Ensure blank lines before and after bulleted lists and fenced blocks.
Ensure tables have a delimiter line below the header row.
Expand any uncommon acronym on first use, for example, Continuous Integration (CI).
Wrap paragraphs at 80 columns.
Wrap code at 120 columns.
Do not wrap tables.
Use footnotes referenced with[^label].
Include Mermaid diagrams where they add clarity in documentation.
When embedding figures, usean...
Files:
docs/the-road-to-wireframe-1-0-feature-set-philosophy-and-capability-maturity.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 must be wrapped at 120 columns.
Tables and headings must not be wrapped.
Use dashes (-) for list bullets.
Use GitHub-flavoured Markdown footnotes ([^1]) for references.
Files:
docs/the-road-to-wireframe-1-0-feature-set-philosophy-and-capability-maturity.md
⚙️ CodeRabbit Configuration File
**/*.md: * Avoid 2nd person or 1st person pronouns ("I", "you", "we")
- Use en-GB-oxendict (-ize / -our) spelling and grammar
- Paragraphs and bullets must be wrapped to 80 columns, except where a long URL would prevent this (in which case, silence MD013 for that line)
- Code blocks should be wrapped to 120 columns.
- 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/the-road-to-wireframe-1-0-feature-set-philosophy-and-capability-maturity.md
🧰 Additional context used
📓 Path-based instructions (2)
docs/**/*.md
📄 CodeRabbit Inference Engine (AGENTS.md)
docs/**/*.md: Reference: Use the markdown files within the docs/ directory as a knowledge base and source of truth for project requirements, dependency choices, and architectural decisions.
Update: 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 the documentation remains accurate and current.
Documentation must use en-GB-oxendict spelling and grammar (with the exception of 'license' which is to be left unchanged for community consistency).Conventions for writing project documentation should be followed as described in the documentation style guide.
docs/**/*.md: Use British English based on the Oxford English Dictionary (en-oxendict) for documentation.
The word "outwith" is acceptable in documentation.
Keep US spelling when used in an API, for examplecolor.
Use the Oxford comma in documentation lists and sentences.
Company names are treated as collective nouns (e.g., "Lille Industries are expanding").
Write headings in sentence case.
Use Markdown headings (#,##,###, etc.) in order without skipping levels.
Follow markdownlint recommendations.
Provide code blocks and lists using standard Markdown syntax.
Always provide a language identifier for fenced code blocks; useplaintextfor non-code text.
Use-as the first level bullet and renumber lists when items change.
Prefer inline links using[text](url)or angle brackets around the URL.
Ensure blank lines before and after bulleted lists and fenced blocks.
Ensure tables have a delimiter line below the header row.
Expand any uncommon acronym on first use, for example, Continuous Integration (CI).
Wrap paragraphs at 80 columns.
Wrap code at 120 columns.
Do not wrap tables.
Use footnotes referenced with[^label].
Include Mermaid diagrams where they add clarity in documentation.
When embedding figures, usean...
Files:
docs/the-road-to-wireframe-1-0-feature-set-philosophy-and-capability-maturity.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 must be wrapped at 120 columns.
Tables and headings must not be wrapped.
Use dashes (-) for list bullets.
Use GitHub-flavoured Markdown footnotes ([^1]) for references.
Files:
docs/the-road-to-wireframe-1-0-feature-set-philosophy-and-capability-maturity.md
⚙️ CodeRabbit Configuration File
**/*.md: * Avoid 2nd person or 1st person pronouns ("I", "you", "we")
- Use en-GB-oxendict (-ize / -our) spelling and grammar
- Paragraphs and bullets must be wrapped to 80 columns, except where a long URL would prevent this (in which case, silence MD013 for that line)
- Code blocks should be wrapped to 120 columns.
- 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/the-road-to-wireframe-1-0-feature-set-philosophy-and-capability-maturity.md
There was a problem hiding this comment.
Actionable comments posted: 2
📜 Review details
Configuration used: CodeRabbit UI
Review profile: ASSERTIVE
Plan: Pro
📒 Files selected for processing (5)
docs/the-road-to-wireframe-1-0-feature-set-philosophy-and-capability-maturity.md(1 hunks)examples/metadata_routing.rs(1 hunks)rust-toolchain.toml(1 hunks)src/server.rs(1 hunks)tests/metrics.rs(1 hunks)
🧰 Additional context used
📓 Path-based instructions (3)
**/*.rs
📄 CodeRabbit Inference Engine (AGENTS.md)
**/*.rs: Comment why, not what. Explain assumptions, edge cases, trade-offs, or complexity. Don't echo the obvious.
Comments must use en-GB-oxendict spelling and grammar.
Function documentation must include clear examples.
Name things precisely. Use clear, descriptive variable and function names. For booleans, prefer names with is, has, or should.
Each file should encapsulate a coherent module. Group related code (e.g., models + utilities + fixtures) close together.
Group by feature, not layer. Colocate views, logic, fixtures, and helpers related to a domain concept rather than splitting by type.
Every module must begin with a module level (//! ) comment explaining the module's purpose and utility.
Document public APIs using Rustdoc comments (///) so documentation can be generated with cargo doc.
Place function attributes after doc comments.
Do not use return in single-line functions.
Prefer immutable data and avoid unnecessary mut bindings.
Handle errors with the Result type instead of panicking where feasible.
Avoid unsafe code unless absolutely necessary and document any usage clearly.
Clippy warnings MUST be disallowed.
Lints must not be silenced except as a last resort.
Lint rule suppressions must be tightly scoped and include a clear reason.
Prefer expect over allow.
Fix any warnings emitted during tests in the code itself rather than silencing them.
Write unit and behavioural tests for new functionality. Run both before and after making any change.
Prefer .expect() over .unwrap().
Use predicate functions for conditional criteria with more than two branches.
Where a function is too long, extract meaningfully named helper functions adhering to separation of concerns and CQRS.
Where a function has too many parameters, group related parameters in meaningfully named structs.
Where a function is returning a large error consider using Arc to reduce the amount of data returned.
Files:
src/server.rsexamples/metadata_routing.rstests/metrics.rs
⚙️ CodeRabbit Configuration File
**/*.rs: * Seek to keep the cyclomatic complexity of functions no more than 12.
Adhere to single responsibility and CQRS
Place function attributes after doc comments.
Do not use
returnin single-line functions.Move conditionals with >2 branches into a predicate function.
Avoid
unsafeunless 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 / -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.Use
rstestfixtures for shared setup and to avoid repetition between tests.Replace duplicated tests with
#[rstest(...)]parameterised cases.Prefer
mockallfor mocks/stubs.Prefer
.expect()over.unwrap()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.
Files:
src/server.rsexamples/metadata_routing.rstests/metrics.rs
docs/**/*.md
📄 CodeRabbit Inference Engine (AGENTS.md)
docs/**/*.md: Reference: Use the markdown files within the docs/ directory as a knowledge base and source of truth for project requirements, dependency choices, and architectural decisions.
Update: 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 the documentation remains accurate and current.
Documentation must use en-GB-oxendict spelling and grammar (with the exception of 'license' which is to be left unchanged for community consistency).Conventions for writing project documentation should be followed as described in the documentation style guide.
docs/**/*.md: Use British English based on the Oxford English Dictionary (en-oxendict) for documentation.
The word "outwith" is acceptable in documentation.
Keep US spelling when used in an API, for examplecolor.
Use the Oxford comma in documentation lists and sentences.
Company names are treated as collective nouns (e.g., "Lille Industries are expanding").
Write headings in sentence case.
Use Markdown headings (#,##,###, etc.) in order without skipping levels.
Follow markdownlint recommendations.
Provide code blocks and lists using standard Markdown syntax.
Always provide a language identifier for fenced code blocks; useplaintextfor non-code text.
Use-as the first level bullet and renumber lists when items change.
Prefer inline links using[text](url)or angle brackets around the URL.
Ensure blank lines before and after bulleted lists and fenced blocks.
Ensure tables have a delimiter line below the header row.
Expand any uncommon acronym on first use, for example, Continuous Integration (CI).
Wrap paragraphs at 80 columns.
Wrap code at 120 columns.
Do not wrap tables.
Use footnotes referenced with[^label].
Include Mermaid diagrams where they add clarity in documentation.
When embedding figures, usean...
Files:
docs/the-road-to-wireframe-1-0-feature-set-philosophy-and-capability-maturity.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 must be wrapped at 120 columns.
Tables and headings must not be wrapped.
Use dashes (-) for list bullets.
Use GitHub-flavoured Markdown footnotes ([^1]) for references.
Files:
docs/the-road-to-wireframe-1-0-feature-set-philosophy-and-capability-maturity.md
⚙️ CodeRabbit Configuration File
**/*.md: * Avoid 2nd person or 1st person pronouns ("I", "you", "we")
- Use en-GB-oxendict (-ize / -our) spelling and grammar
- Paragraphs and bullets must be wrapped to 80 columns, except where a long URL would prevent this (in which case, silence MD013 for that line)
- Code blocks should be wrapped to 120 columns.
- 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/the-road-to-wireframe-1-0-feature-set-philosophy-and-capability-maturity.md
🪛 LanguageTool
docs/the-road-to-wireframe-1-0-feature-set-philosophy-and-capability-maturity.md
[style] ~288-~288: Would you like to use the Oxford spelling “summarizes”? The spelling ‘summarises’ is also correct.
Context: ...e following entity–relationship diagram summarises how the core metrics relate. ```mermai...
(OXFORD_SPELLING_Z_NOT_S)
🔇 Additional comments (3)
rust-toolchain.toml (1)
2-2: Synchronise CI with the new nightly versionUpdate all CI workflows, Dockerfiles, and dev-container configs to pull
nightly-2025-07-22or rely solely onrust-toolchain.toml; mismatched toolchains will break the build cache and gate the pipeline.docs/the-road-to-wireframe-1-0-feature-set-philosophy-and-capability-maturity.md (1)
288-312: LGTM! Excellent metrics documentation with clear visual representation.The entity-relationship diagram effectively illustrates the core metrics relationships, and the explanatory text clearly communicates the optional nature of the metrics feature. The documentation follows the British English requirements correctly (ignore the static analysis hint suggesting "summarizes" - "summarises" is the correct British spelling per the coding guidelines).
tests/metrics.rs (1)
1-63: LGTM! Comprehensive metrics testing with excellent validation.The test suite provides thorough coverage of the metrics functionality with proper isolation using
metrics::with_local_recorder. Each test validates not only metric existence but also correct labelling and counter increments. The helper function is well-named and documented, and the tests cover the core metrics: outbound/inbound frames and error counting.
|
@coderabbitai review |
✅ Actions performedReview triggered.
|
There was a problem hiding this comment.
Actionable comments posted: 1
📜 Review details
Configuration used: CodeRabbit UI
Review profile: ASSERTIVE
Plan: Pro
📒 Files selected for processing (2)
examples/metadata_routing.rs(1 hunks)src/server.rs(1 hunks)
🧰 Additional context used
📓 Path-based instructions (1)
**/*.rs
⚙️ CodeRabbit Configuration File
**/*.rs: * Seek to keep the cyclomatic complexity of functions no more than 12.
Adhere to single responsibility and CQRS
Place function attributes after doc comments.
Do not use
returnin single-line functions.Move conditionals with >2 branches into a predicate function.
Avoid
unsafeunless 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 / -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.Use
rstestfixtures for shared setup and to avoid repetition between tests.Replace duplicated tests with
#[rstest(...)]parameterised cases.Prefer
mockallfor mocks/stubs.Prefer
.expect()over.unwrap()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.
Files:
examples/metadata_routing.rssrc/server.rs
🔇 Additional comments (1)
examples/metadata_routing.rs (1)
63-64: Keep the#[expect]attribute as-is – change fully aligns with guidelinesThe
#[expect(dead_code, reason = "used only in documentation example")]attribute replaces the forbidden#[allow], supplies a clear justification, and is narrowly scoped to thePongstruct. No further action required.
|
@coderabbitai review |
✅ Actions performedReview triggered.
|
Summary
metricscrateTesting
cargo clippy --all-targets --all-features -- -D warningscargo test --all-targets --all-featuresmdformat-all docs/**/*.md README.mdhttps://chatgpt.com/codex/tasks/task_e_687edb587d988322812c4a1cf95d88ec
Summary by Sourcery
Implement metrics instrumentation and observability by adding a dedicated metrics module, recording active connections, processed frames, and errors via the metrics crate, integrating a Prometheus exporter with examples, updating documentation, and adding corresponding tests.
New Features:
Enhancements:
Build:
Documentation:
Tests: