Skip to content

refactor(jans-cedarling): defer audit entry serialization off hot path#14531

Merged
olehbozhok merged 13 commits into
mainfrom
jans-cedarling-14512
Jul 14, 2026
Merged

refactor(jans-cedarling): defer audit entry serialization off hot path#14531
olehbozhok merged 13 commits into
mainfrom
jans-cedarling-14512

Conversation

@dagregi

@dagregi dagregi commented Jul 10, 2026

Copy link
Copy Markdown
Contributor

Prepare


Description

Target issue

closes #14512

Implementation Details


Test and Document the changes

  • Static code analysis has been run locally and issues have been fixed
  • Relevant unit and integration tests have been added/updated
  • Relevant documentation has been updated if any (i.e. user guides, installation and configuration guides, technical design docs etc)

Please check the below before submitting your PR. The PR will not be merged if there are no commits that start with docs: to indicate documentation changes or if the below checklist is not selected.

  • I confirm that there is no impact on the docs due to the code changes in this PR.

Summary by CodeRabbit

  • New Features
    • Audit logging is now dispatched as structured typed audit data (decision/metric/health) across the REST and gRPC paths.
    • Health reporting is sent through the same typed audit transport pipeline.
  • Bug Fixes
    • Invalid audit items are handled more robustly: validation is applied during mapping, malformed items are skipped while valid ones are still delivered.
    • Health handling no longer uses per-entry JSON parsing flows.
  • Tests
    • Updated/expanded test utilities and assertions for typed audit transport, including new malformed-item coverage.

* replace SerializedAuditEntry (Box<str>) with typed AuditItem
* drop Loggable::get_log_kind in favor of into_audit_payload
* replace LockService LogWriter impl with dispatch_audit routing by payload variant
* carry pdp_id/app_name as typed fields, not stringified

Signed-off-by: dagregi <dagmawi.m@proton.me>
@dagregi dagregi self-assigned this Jul 10, 2026
@mo-auto

mo-auto commented Jul 10, 2026

Copy link
Copy Markdown
Member

Snyk checks have passed. No issues have been found so far.

Status Scan Engine Critical High Medium Low Total (0)
Open Source Security 0 0 0 0 0 issues

💻 Catch issues earlier using the plugins for VS Code, JetBrains IDEs, Visual Studio, and Eclipse.

@mo-auto mo-auto added comp-jans-cedarling Touching folder /jans-cedarling kind-enhancement Issue or PR is an enhancement to an existing functionality labels Jul 10, 2026
@coderabbitai

coderabbitai Bot commented Jul 10, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

Cedarling replaces serialized audit strings with typed AuditItem values across logging, dispatch, workers, health reporting, and REST/gRPC transports. Shared mapping validates and converts decision, metric, and health payloads at the transport boundary.

Changes

Typed audit pipeline

Layer / File(s) Summary
Logging payload contract
jans-cedarling/cedarling/src/log/*, jans-cedarling/cedarling/src/common/policy_store/log_entry.rs, jans-cedarling/cedarling/src/jwt/log_entry.rs, jans-cedarling/cedarling/src/lock/log_entry.rs
Loggable removes get_log_kind and adds typed AuditPayload conversion for decision and metric entries.
Typed transport and mapping
jans-cedarling/cedarling/src/lock/transport/*
Typed audit primitives, payload validation, lock-server conversions, shared fixtures, and batch filtering replace serialized-entry deserialization.
Typed lock dispatch and workers
jans-cedarling/cedarling/src/lock/mod.rs, jans-cedarling/cedarling/src/lock/log_worker.rs
LockService routes typed audit payloads to worker channels, and workers buffer typed batches for transport submission.
Typed health audit flow
jans-cedarling/cedarling/src/lock/health_ticker.rs
HealthTicker stores typed identity values and sends health records as AuditItem values.
REST and gRPC transport conversion
jans-cedarling/cedarling/src/lock/transport/rest.rs, jans-cedarling/cedarling/src/lock/transport/grpc.rs
REST and gRPC transports map typed log, metric, and health batches before submission and update their transport tests.
Example formatting updates
jans-cedarling/cedarling/examples/*
Three example debug-print statements use inline formatting syntax.

Estimated code review effort: 4 (Complex) | ~60 minutes

Possibly related PRs

Suggested reviewers: olehbozhok, haileyesus2433

🚥 Pre-merge checks | ✅ 3 | ❌ 2

❌ Failed checks (2 warnings)

Check name Status Explanation Resolution
Out of Scope Changes check ⚠️ Warning The println! formatting tweaks in the example binaries are unrelated to #14512 and appear out of scope. Remove the example formatting-only edits or split them into a separate cleanup PR.
Docstring Coverage ⚠️ Warning Docstring coverage is 78.57% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed The title is concise and accurately summarizes the main change: deferring audit serialization off the hot path.
Description check ✅ Passed The template is mostly complete with target issue, checklist, and test/doc confirmations filled, though Implementation Details is sparse.
Linked Issues check ✅ Passed The refactor matches #14512 by using typed audit items, moving mapping/serialization into transport, and updating tests.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch jans-cedarling-14512

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 2

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
jans-cedarling/cedarling/src/lock/transport/rest.rs (1)

314-319: 📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

Use expect_err with a descriptive message and add a message to assert!(matches!(...)).

This assertion uses result.unwrap_err() and a message-less assert!(matches!(...)). The equivalent gRPC test (test_send_logs_malformed_json, lines 605-615) already follows the required pattern; align this one for parity and better failure diagnostics.

As per coding guidelines: "For error checking in tests, use result.expect_err(...)", "For pattern matching errors in tests, use assert!(matches!(...), "descriptive message")", and "All assertions must include a descriptive message".

💚 Proposed fix
-        let result = transport.send(&entries, &AuditKind::Log(endpoint)).await;
-        assert!(matches!(
-            result.unwrap_err(),
-            TransportError::Serialization(_)
-        ));
+        let error = transport
+            .send(&entries, &AuditKind::Log(endpoint))
+            .await
+            .expect_err("all-invalid batch must fail mapping");
+        assert!(
+            matches!(error, TransportError::Serialization(_)),
+            "expected serialization error, got {error:?}"
+        );
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@jans-cedarling/cedarling/src/lock/transport/rest.rs` around lines 314 - 319,
Update the test around the `transport.send` result to use
`result.expect_err(...)` with a descriptive failure message, then pass the
resulting error to `assert!(matches!(...))` and add a descriptive assertion
message. Match the established pattern in `test_send_logs_malformed_json` for
consistency.

Source: Coding guidelines

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@jans-cedarling/cedarling/src/lock/transport/mapping.rs`:
- Around line 97-100: Validate that entry.base.timestamp is present and
non-empty before constructing the mapped entry; do not use unwrap_or_default().
Update the validation in the mapping function containing this logic to return
MappingValidationError::MissingField for None or blank timestamps, while
preserving the existing action/resource checks and only assigning
creation_date/event_time after validation.

In `@jans-cedarling/cedarling/src/lock/transport/rest.rs`:
- Around line 91-159: Consolidate the duplicated sample builders across the REST
and gRPC transport tests. Move `sample_log_item`, `sample_metric_item`, and
`sample_health_item` into a shared test-only module, reusing the existing
`mapping.rs` helpers such as `decision_audit_item` and `metric_audit_item` where
applicable, then update both transport test modules to import and call the
shared builders instead of defining local copies.

---

Outside diff comments:
In `@jans-cedarling/cedarling/src/lock/transport/rest.rs`:
- Around line 314-319: Update the test around the `transport.send` result to use
`result.expect_err(...)` with a descriptive failure message, then pass the
resulting error to `assert!(matches!(...))` and add a descriptive assertion
message. Match the established pattern in `test_send_logs_malformed_json` for
consistency.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: 02f5145b-2678-4f49-bcaf-fcf21d398c44

📥 Commits

Reviewing files that changed from the base of the PR and between b6aa748 and 2f81c14.

📒 Files selected for processing (14)
  • jans-cedarling/cedarling/src/common/policy_store/log_entry.rs
  • jans-cedarling/cedarling/src/jwt/log_entry.rs
  • jans-cedarling/cedarling/src/lock/health_ticker.rs
  • jans-cedarling/cedarling/src/lock/log_entry.rs
  • jans-cedarling/cedarling/src/lock/log_worker.rs
  • jans-cedarling/cedarling/src/lock/mod.rs
  • jans-cedarling/cedarling/src/lock/transport/grpc.rs
  • jans-cedarling/cedarling/src/lock/transport/mapping.rs
  • jans-cedarling/cedarling/src/lock/transport/mod.rs
  • jans-cedarling/cedarling/src/lock/transport/rest.rs
  • jans-cedarling/cedarling/src/log/err_log_entry.rs
  • jans-cedarling/cedarling/src/log/interface.rs
  • jans-cedarling/cedarling/src/log/log_entry.rs
  • jans-cedarling/cedarling/src/log/log_strategy.rs
💤 Files with no reviewable changes (1)
  • jans-cedarling/cedarling/src/lock/log_entry.rs

Comment thread jans-cedarling/cedarling/src/lock/transport/mapping.rs Outdated
Comment thread jans-cedarling/cedarling/src/lock/transport/rest.rs Outdated
dagregi added 3 commits July 10, 2026 12:30
Signed-off-by: dagregi <dagmawi.m@proton.me>
Signed-off-by: dagregi <dagmawi.m@proton.me>
Signed-off-by: dagregi <dagmawi.m@proton.me>

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (2)
jans-cedarling/cedarling/src/lock/transport/rest.rs (1)

248-252: 📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

Use expect_err and add a descriptive assertion message.

This assertion uses unwrap_err() and a message-less assert!(matches!(...)), unlike the sibling error tests here and in grpc.rs.

As per coding guidelines: "For pattern matching errors in tests, use assert!(matches!(...), "descriptive message")" and "Use expect_err("explicit comment") instead of panic() when expecting errors in tests".

♻️ Proposed change
-        let result = transport.send(&entries, &AuditKind::Log(endpoint)).await;
-        assert!(matches!(
-            result.unwrap_err(),
-            TransportError::Serialization(_)
-        ));
+        let error = transport
+            .send(&entries, &AuditKind::Log(endpoint))
+            .await
+            .expect_err("all-invalid batch must fail mapping");
+        assert!(
+            matches!(error, TransportError::Serialization(_)),
+            "expected serialization error, got {error:?}"
+        );
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@jans-cedarling/cedarling/src/lock/transport/rest.rs` around lines 248 - 252,
Update the error assertion in the REST transport test using the existing
`transport.send` call: replace `unwrap_err()` with `expect_err(...)` and add a
descriptive message to the surrounding `assert!(matches!(...))`, matching the
style of the sibling REST and gRPC error tests.

Source: Coding guidelines

jans-cedarling/cedarling/src/lock/transport/mapping.rs (1)

331-340: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Reject blank timestamps too
LockServerLogEntry::try_from(&AuditItem) rejects None, but Some("") still flows through as creation_date and event_time. Add a non-empty/RFC3339 validation here so malformed timestamps fail instead of being forwarded.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@jans-cedarling/cedarling/src/lock/transport/mapping.rs` around lines 331 -
340, Extend LockServerLogEntry::try_from(&AuditItem) timestamp validation to
reject Some("") and other malformed values, not only None. Require a non-empty
RFC3339 timestamp before assigning creation_date and event_time, return
MappingValidationError::MissingField (or the existing appropriate validation
error), and add tests covering blank and invalid timestamp strings.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Outside diff comments:
In `@jans-cedarling/cedarling/src/lock/transport/mapping.rs`:
- Around line 331-340: Extend LockServerLogEntry::try_from(&AuditItem) timestamp
validation to reject Some("") and other malformed values, not only None. Require
a non-empty RFC3339 timestamp before assigning creation_date and event_time,
return MappingValidationError::MissingField (or the existing appropriate
validation error), and add tests covering blank and invalid timestamp strings.

In `@jans-cedarling/cedarling/src/lock/transport/rest.rs`:
- Around line 248-252: Update the error assertion in the REST transport test
using the existing `transport.send` call: replace `unwrap_err()` with
`expect_err(...)` and add a descriptive message to the surrounding
`assert!(matches!(...))`, matching the style of the sibling REST and gRPC error
tests.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: d7c147db-3f9c-4bbd-b343-4dd3bf203584

📥 Commits

Reviewing files that changed from the base of the PR and between 2c6b7ca and 0611890.

📒 Files selected for processing (8)
  • jans-cedarling/cedarling/examples/log_init.rs
  • jans-cedarling/cedarling/examples/profiling_multi_issuer.rs
  • jans-cedarling/cedarling/examples/profiling_unsigned.rs
  • jans-cedarling/cedarling/src/lock/transport/grpc.rs
  • jans-cedarling/cedarling/src/lock/transport/mapping.rs
  • jans-cedarling/cedarling/src/lock/transport/mod.rs
  • jans-cedarling/cedarling/src/lock/transport/rest.rs
  • jans-cedarling/cedarling/src/lock/transport/test_utils.rs

coderabbitai[bot]
coderabbitai Bot previously approved these changes Jul 10, 2026
};

if let Err(err) = sender.try_send(serialized) {
if let Err(err) = tx.clone().try_send(item) {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I think this might have quietly changed the channel backpressure. The old code held one Sender behind the RwLock so when the buffer filled up try_send returned Full and we dropped the entry (that's what the "channel send failed (full or closed)" log is for).

Now we clone a fresh Sender on every dispatch. With futures::channel::mpsc each sender gets its own guaranteed slot on top of the buffer and a freshly cloned sender is never parked so its try_send pushes the message no matter how full the channel already is and only parks the clone we're about to drop.

So try_send here basically never returns Full anymore. Wouldn't this mean that if the Lock Server transport stalls, the channel keeps growing past log_channel_capacity instead of dropping entries?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I quickly checked with a futures::channel::mpsc::channel(1) and a receiver that never drains: cloning a sender per send enqueued 1000 messages with zero Full rejections but a single reused sender stopped at 2 and rejected the rest. I could be wrong about how this plays out in the worker

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

If it's real, a tokio mpsc (whose try_send takes &self) or keeping one shared sender would put the bound back.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Thanks I almost missed that I will fix it

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

It has been fixed in 6c57b0f

"requested_resource": "Jans::Issue",
"principal_id": "Jans::User",
}])))
.match_body(mockito::Matcher::Any)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

We dropped the PartialJson body matcher here and switched to Matcher::Any so this test no longer checks the actual payload we send to the Lock Server. I think the reason is that node_name is now a random PdpID so the old hardcoded match wouldn't line up.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

I redid the partial json with node_name removed since just like used is a random uuid


/// Like [`sample_log_item`], but with the required `action` field left empty so
/// that mapping into the Lock Server shape fails validation.
fn malformed_log_item() -> AuditItem {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

This malformed_log_item builder is basically the same as the inline one in the rest.rs test_send_logs_all_invalid_dropped test (a decision entry with an empty action).

We already moved the sample builders into test_utils. maybe this one could live there too so both transports share it.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Refactored it in 6c57b0f

service: "test_app".to_string(),
node_name: "test-pdp".to_string(),
status: "running".to_string(),
engine_status: HashMap::new(),

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

sample_health_item builds with an empty engine_status and the gRPC test_send_health_success dropped its old engine_status.get("core") assertion so we don't cover the engine_status -> proto conversion anymore. Could the sample carry one entry so we keep that check?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Thanks, added the check in 959a6c0

creation_date: timestamp,
service: (!value.application_id.is_empty()).then_some(value.application_id),
node_name: value.pdp_id,
creation_date: entry.base.timestamp.clone().unwrap_or_default(),

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Nit: the decision path now rejects a missing timestamp (the ok_or(MissingField) in the log mapping) but metrics still fall back to an empty string with unwrap_or_default().

This matches the old behavior so it's not something this PR changed but now that the two paths validate differently. Do you think metrics should reject a missing timestamp too?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

All metrics logs emitted have timestamps so getting an empty string is not possible but I'll still add the check for consistency

Signed-off-by: dagregi <dagmawi.m@proton.me>

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
jans-cedarling/cedarling/src/lock/transport/rest.rs (1)

219-222: 📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

Use expect_err with a descriptive message instead of unwrap_err().

Per coding guidelines, error checking in tests should use expect_err("descriptive message"), and matches! assertions should include a descriptive message. The gRPC transport's equivalent test (grpc.rs lines 505–515) already follows this pattern.

💚 Proposed fix
-        let result = transport.send(&entries, &AuditKind::Log(endpoint)).await;
-        assert!(matches!(
-            result.unwrap_err(),
-            TransportError::Serialization(_)
-        ));
+        let error = transport
+            .send(&entries, &AuditKind::Log(endpoint))
+            .await
+            .expect_err("all malformed entries should cause a serialization error");
+        assert!(
+            matches!(error, TransportError::Serialization(_)),
+            "expected serialization error, got {error:?}"
+        );
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@jans-cedarling/cedarling/src/lock/transport/rest.rs` around lines 219 - 222,
Update the test assertion around result in the REST transport test to use
expect_err with a descriptive failure message instead of unwrap_err, and add a
descriptive message to the matches! assertion while preserving the
TransportError::Serialization check.

Source: Coding guidelines

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Outside diff comments:
In `@jans-cedarling/cedarling/src/lock/transport/rest.rs`:
- Around line 219-222: Update the test assertion around result in the REST
transport test to use expect_err with a descriptive failure message instead of
unwrap_err, and add a descriptive message to the matches! assertion while
preserving the TransportError::Serialization check.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: 695d0dcc-4b2c-4cbb-9820-eb135bd63dc3

📥 Commits

Reviewing files that changed from the base of the PR and between 0611890 and 6c57b0f.

📒 Files selected for processing (5)
  • jans-cedarling/cedarling/src/lock/log_worker.rs
  • jans-cedarling/cedarling/src/lock/mod.rs
  • jans-cedarling/cedarling/src/lock/transport/grpc.rs
  • jans-cedarling/cedarling/src/lock/transport/rest.rs
  • jans-cedarling/cedarling/src/lock/transport/test_utils.rs

coderabbitai[bot]
coderabbitai Bot previously approved these changes Jul 13, 2026

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
jans-cedarling/cedarling/src/lock/transport/mapping.rs (1)

448-456: 📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

Add a descriptive message to the assertion.

The assert!(matches!(...)) assertion violates the repository guideline requiring every assertion to explain what it verifies.

Proposed fix
-        assert!(matches!(err, TransportError::Serialization(_)));
+        assert!(
+            matches!(err, TransportError::Serialization(_)),
+            "all-malformed batches should return a serialization error",
+        );
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@jans-cedarling/cedarling/src/lock/transport/mapping.rs` around lines 448 -
456, Add a descriptive failure message to the assert! call in
map_entries_fails_when_all_entries_are_malformed, stating that an all-malformed
batch should return a TransportError::Serialization error.

Source: Coding guidelines

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@jans-cedarling/cedarling/src/lock/transport/grpc.rs`:
- Line 755: Update the test assertion on received[0].engine_status in the
relevant gRPC transport test to replace unwrap() with expect(), including a
clear message explaining that the core engine status must be present; retain the
existing equality check against "success".

---

Outside diff comments:
In `@jans-cedarling/cedarling/src/lock/transport/mapping.rs`:
- Around line 448-456: Add a descriptive failure message to the assert! call in
map_entries_fails_when_all_entries_are_malformed, stating that an all-malformed
batch should return a TransportError::Serialization error.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: af4f1a01-20e1-491d-814e-a7d29d7608f8

📥 Commits

Reviewing files that changed from the base of the PR and between 6c57b0f and 959a6c0.

📒 Files selected for processing (3)
  • jans-cedarling/cedarling/src/lock/transport/grpc.rs
  • jans-cedarling/cedarling/src/lock/transport/mapping.rs
  • jans-cedarling/cedarling/src/lock/transport/test_utils.rs

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Caution

Inline review comments failed to post. This is likely due to GitHub's internal server error or limits when posting large numbers of comments. If you are seeing this consistently it is likely a permissions issue. Please check "Moderation" -> "Code review limits" under your organization settings.

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
jans-cedarling/cedarling/src/lock/transport/mapping.rs (1)

448-456: 📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

Add a descriptive message to the assertion.

The assert!(matches!(...)) assertion violates the repository guideline requiring every assertion to explain what it verifies.

Proposed fix
-        assert!(matches!(err, TransportError::Serialization(_)));
+        assert!(
+            matches!(err, TransportError::Serialization(_)),
+            "all-malformed batches should return a serialization error",
+        );
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@jans-cedarling/cedarling/src/lock/transport/mapping.rs` around lines 448 -
456, Add a descriptive failure message to the assert! call in
map_entries_fails_when_all_entries_are_malformed, stating that an all-malformed
batch should return a TransportError::Serialization error.

Source: Coding guidelines

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@jans-cedarling/cedarling/src/lock/transport/grpc.rs`:
- Line 755: Update the test assertion on received[0].engine_status in the
relevant gRPC transport test to replace unwrap() with expect(), including a
clear message explaining that the core engine status must be present; retain the
existing equality check against "success".

---

Outside diff comments:
In `@jans-cedarling/cedarling/src/lock/transport/mapping.rs`:
- Around line 448-456: Add a descriptive failure message to the assert! call in
map_entries_fails_when_all_entries_are_malformed, stating that an all-malformed
batch should return a TransportError::Serialization error.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: af4f1a01-20e1-491d-814e-a7d29d7608f8

📥 Commits

Reviewing files that changed from the base of the PR and between 6c57b0f and 959a6c0.

📒 Files selected for processing (3)
  • jans-cedarling/cedarling/src/lock/transport/grpc.rs
  • jans-cedarling/cedarling/src/lock/transport/mapping.rs
  • jans-cedarling/cedarling/src/lock/transport/test_utils.rs
🛑 Comments failed to post (1)
jans-cedarling/cedarling/src/lock/transport/grpc.rs (1)

755-755: 📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

Use expect and add an assertion message.

This new test assertion uses unwrap() and provides no explanation on failure, contrary to the Rust testing guidelines.

Proposed fix
-        assert_eq!(received[0].engine_status.get("core").unwrap(), "success");
+        assert_eq!(
+            received[0]
+                .engine_status
+                .get("core")
+                .expect("core engine status should be present"),
+            "success",
+            "core engine status should be serialized as success",
+        );
📝 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.

        assert_eq!(
            received[0]
                .engine_status
                .get("core")
                .expect("core engine status should be present"),
            "success",
            "core engine status should be serialized as success",
        );
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@jans-cedarling/cedarling/src/lock/transport/grpc.rs` at line 755, Update the
test assertion on received[0].engine_status in the relevant gRPC transport test
to replace unwrap() with expect(), including a clear message explaining that the
core engine status must be present; retain the existing equality check against
"success".

Source: Coding guidelines

Signed-off-by: dagregi <dagmawi.m@proton.me>
/// Map a batch of typed audit items into the Lock Server wire format
pub(super) fn map_entries<'a, T>(
entries: &'a [AuditItem],
label: &str,

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I think better to have label as enum with specific entries

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Or I could just remove the param entirely and get it from the audit payload

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

fixed it in 06dde70

Signed-off-by: dagregi <dagmawi.m@proton.me>
http_conf: HttpClientConfig,
) -> Result<WorkerSenderAndHandle, InitLockServiceError> {
let (tx, rx) = mpsc::channel::<SerializedAuditEntry>(bootstrap_conf.log_channel_capacity);
let (tx, rx) = mpsc::channel::<AuditItem>(bootstrap_conf.log_channel_capacity);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I think swapping to tokio's mpsc might panic at startup if someone sets log_channel_capacity to 0. tokio's mpsc::channel panics when the buffer is 0 ("mpsc bounded channel requires buffer > 0") but the old futures::channel::mpsc::channel(0) accepted it

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

yes, we should verify that it has a non-zero value
let capacity = bootstrap_conf.log_channel_capacity.max(1);

@dagregi dagregi Jul 14, 2026

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

now a zero value will be clamped to 1

Signed-off-by: dagregi <dagmawi.m@proton.me>
olehbozhok
olehbozhok previously approved these changes Jul 14, 2026
…n placeholders

Signed-off-by: Oleh Bozhok <6554798+olehbozhok@users.noreply.github.com>
olehbozhok
olehbozhok previously approved these changes Jul 14, 2026
Replace runtime .max(1) clamp on log_channel_capacity with
compile-time NonZeroUsize. Prevents panic on tokio::mpsc::channel(0).

Signed-off-by: Oleh Bozhok <6554798+olehbozhok@users.noreply.github.com>
olehbozhok and others added 2 commits July 14, 2026 15:06
Signed-off-by: Oleh Bozhok <6554798+olehbozhok@users.noreply.github.com>
Signed-off-by: moabu <47318409+moabu@users.noreply.github.com>
@moabu
moabu self-requested a review as a code owner July 14, 2026 13:14
@olehbozhok

Copy link
Copy Markdown
Contributor

@coderabbitai approve

@coderabbitai

coderabbitai Bot commented Jul 14, 2026

Copy link
Copy Markdown
Contributor
✅ Action performed

Comments resolved and changes approved.

@olehbozhok
olehbozhok merged commit a8e0659 into main Jul 14, 2026
3 checks passed
@olehbozhok
olehbozhok deleted the jans-cedarling-14512 branch July 14, 2026 13:31
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

comp-jans-cedarling Touching folder /jans-cedarling kind-enhancement Issue or PR is an enhancement to an existing functionality

Projects

None yet

Development

Successfully merging this pull request may close these issues.

fix(jans-cedarling): triple json pass for each lock audit entry

5 participants