Skip to content

feat(trogon-decider-runtime): add snapshot execution#172

Merged
yordis merged 1 commit into
mainfrom
yordis/chore-create-pr-v3
May 21, 2026
Merged

feat(trogon-decider-runtime): add snapshot execution#172
yordis merged 1 commit into
mainfrom
yordis/chore-create-pr-v3

Conversation

@yordis

@yordis yordis commented May 20, 2026

Copy link
Copy Markdown
Member
  • Runtime consumers need a stable snapshot boundary so long-lived streams can avoid full replay without coupling to a storage backend.
  • Snapshot failures need to stay phase-specific so applications can retry infrastructure paths separately from domain rejections.

@cursor

cursor Bot commented May 20, 2026

Copy link
Copy Markdown

PR Summary

Medium Risk
Updates the core CommandExecution API to optionally load from/write to snapshots and expands CommandError/CommandResult generics, which may require downstream adapter changes and could affect replay/append precondition behavior if misconfigured.

Overview
Adds first-class snapshot support to trogon-decider-runtime: a new snapshot module defines Snapshot, SnapshotType, SnapshotRead/SnapshotWrite contracts, and JSON envelope/payload codecs (EncodedSnapshot, encode_snapshot/decode_snapshot) with dedicated encode/decode error types.

Extends CommandExecution with an optional snapshot mode via with_snapshot(...) and Snapshots configuration (policy + store + task scheduler). When enabled, execution loads a snapshot, reads only the stream delta using ReadFrom::after, validates snapshot position (SnapshotAheadOfStream / ReadAfterOverflow), and can best-effort persist a new snapshot after a successful append based on a SnapshotPolicy (provided NoSnapshot and FrequencySnapshot).

Introduces snapshot task scheduling (SnapshotTaskScheduler) with TokioSnapshotTaskScheduler and test-only ImmediateSnapshotTaskScheduler, and updates exports/docs plus tests to cover snapshot restore, policy decisions, scheduler behavior, and phase-specific error reporting.

Reviewed by Cursor Bugbot for commit a71d254. Bugbot is set up for automated code reviews on this repo. Configure here.

@coderabbitai

coderabbitai Bot commented May 20, 2026

Copy link
Copy Markdown

Review Change Stack

Warning

Rate limit exceeded

@yordis has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 20 minutes and 29 seconds before requesting another review.

You’ve run out of usage credits. Purchase more in the billing tab.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 5c0b6061-81ee-4214-869d-dd74428570c6

📥 Commits

Reviewing files that changed from the base of the PR and between 32b38a8 and a71d254.

📒 Files selected for processing (14)
  • rsworkspace/crates/trogon-decider-runtime/src/execution.rs
  • rsworkspace/crates/trogon-decider-runtime/src/lib.rs
  • rsworkspace/crates/trogon-decider-runtime/src/snapshot/codec/encoded_snapshot.rs
  • rsworkspace/crates/trogon-decider-runtime/src/snapshot/codec/mod.rs
  • rsworkspace/crates/trogon-decider-runtime/src/snapshot/codec/snapshot_decode_error.rs
  • rsworkspace/crates/trogon-decider-runtime/src/snapshot/codec/snapshot_encode_error.rs
  • rsworkspace/crates/trogon-decider-runtime/src/snapshot/codec/snapshot_envelope_decode_error.rs
  • rsworkspace/crates/trogon-decider-runtime/src/snapshot/codec/snapshot_envelope_encode_error.rs
  • rsworkspace/crates/trogon-decider-runtime/src/snapshot/codec/snapshot_payload_decode.rs
  • rsworkspace/crates/trogon-decider-runtime/src/snapshot/codec/snapshot_payload_encode.rs
  • rsworkspace/crates/trogon-decider-runtime/src/snapshot/mod.rs
  • rsworkspace/crates/trogon-decider-runtime/src/snapshot/read_snapshot.rs
  • rsworkspace/crates/trogon-decider-runtime/src/snapshot/snapshot_type.rs
  • rsworkspace/crates/trogon-decider-runtime/src/snapshot/write_snapshot.rs

Walkthrough

This PR adds comprehensive snapshot support to the trogon-decider-runtime crate, enabling command execution to optionally read snapshots, replay only event deltas, and persist new snapshots via pluggable policies and async task scheduling, with new error variants for snapshot ordering validation.

Changes

Snapshot-Aware Command Execution

Layer / File(s) Summary
Snapshot Type Contracts
src/snapshot/snapshot_type.rs, src/snapshot/mod.rs, src/snapshot/read_snapshot.rs, src/snapshot/write_snapshot.rs
Snapshot<T> holds a checkpoint position and payload. SnapshotType defines stream prefixes. SnapshotRead and SnapshotWrite traits expose async request/response-based read and write operations with generic error types.
Snapshot Payload Serialization Traits
src/snapshot/codec/snapshot_payload_*.rs
SnapshotPayloadEncode and SnapshotPayloadDecode traits define how snapshot payloads are encoded to/decoded from byte arrays, parameterizing the codec layer independently from storage.
Snapshot Codec, Error Types, and Serialization
src/snapshot/codec/*.rs
Error types cover payload and envelope encode/decode failures. EncodedSnapshot wraps position and raw payload bytes with JSON serialization. encode_snapshot() and decode_snapshot() generic helpers transform Snapshot<T> using payload codec traits, mapping errors into snapshot-specific error types.
Snapshot Task Scheduling and Policies
src/execution.rs (lines 27–163)
SnapshotTaskScheduler trait with TokioSnapshotTaskScheduler and ImmediateSnapshotTaskScheduler implementations enable async snapshot write scheduling. SnapshotPolicy and CommandSnapshotPolicy traits define decision logic. Built-in NoSnapshot and FrequencySnapshot policies provide off-the-shelf snapshot cadence strategies. SnapshotDecision and DecideSnapshot carry policy inputs.
Command Execution Error Types and Variants
src/execution.rs (lines 181–388, 409–553)
CommandResult and CommandError parameterized with ReadSnapshotError. New variants: ReadSnapshot, SnapshotAheadOfStream, ReadAfterOverflow. SnapshotAheadOfStream captures diagnostic position data. Error trait impls expose snapshot read errors as source and format new variants.
Snapshot-Aware Execution Builder API
src/execution.rs (lines 45–657)
Snapshots container and IntoSnapshots trait wrap snapshot store and policy. with_snapshot() adds snapshot configuration. with_task_runtime() swaps the scheduler at runtime. with_headers() sets headers on snapshot builds. Builder state preserves snapshots across with_event_id_generator().
Snapshot-Enabled Execution Implementation
src/execution.rs (lines 668–813)
Dual execute() paths: snapshot-less reads full stream from beginning; snapshot-enabled reads snapshot, validates position against stream, reads delta, evolves from snapshot payload plus delta, appends decided events, evaluates policy to decide persistence, and schedules async snapshot write as best-effort without failing the committed command. schedule_snapshot_write() logs failures without propagation.
Test Infrastructure and Snapshot Test Cases
src/execution.rs (tests: lines 843–1785)
FakeRuntime extended with snapshot storage, position tracking, failure injection, and SnapshotRead/SnapshotWrite implementations. test_snapshots() helper uses immediate scheduler. TestInfraError covers snapshot read/write failures. Tests verify snapshot restore and delta replay, snapshot ordering validation, overflow detection, frequency-based policy cadence, and ensure snapshot write failures do not fail already-committed commands.
Module Structure and Public API
src/lib.rs
New pub mod snapshot declaration. Crate docs updated to reflect snapshot-aware state rebuild and separated error phases. Expanded pub use exports from execution and snapshot modules to surface snapshot policies, schedulers, codec traits, read/write contracts, and error types.
Runtime Boundary and Snapshot Workflow Documentation
README.md
Documents the runtime boundary for executing typed deciders. Explains separation of domain rejections from infrastructure failures (evolution, codec, stream, snapshot). Outlines snapshot-less and snapshot-enabled workflows, snapshot policy inputs, built-in strategies, and snapshot adapter contracts for read/write and payload serialization.

Sequence Diagram

sequenceDiagram
  participant Client as Client
  participant Exec as CommandExecution
  participant SnapRead as SnapshotRead
  participant StreamRead as StreamRead
  participant Decider as Decider
  participant StreamAppend as StreamAppend
  participant Policy as SnapshotPolicy
  participant Scheduler as SnapshotTaskScheduler
  
  Client->>Exec: execute()
  Exec->>SnapRead: read_snapshot(stream_id)
  SnapRead-->>Exec: Snapshot or empty
  Exec->>StreamRead: read from position (or beginning)
  StreamRead-->>Exec: event delta
  Exec->>Decider: decide(state from snapshot+delta)
  Decider-->>Exec: emitted events
  Exec->>StreamAppend: append events with preconditions
  StreamAppend-->>Exec: stream position
  Exec->>Policy: decide_snapshot(state, events, position)
  Policy-->>Exec: Skip or Take
  Exec->>Scheduler: schedule async snapshot write (best-effort)
  Scheduler-->>Exec: fire-and-forget (log failures)
  Exec-->>Client: CommandResult
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~65 minutes

Possibly related PRs

  • TrogonStack/trogonai#171: Establishes the foundational CommandExecution, CommandResult, and CommandError types that this PR extends with snapshot-aware execution semantics.
  • TrogonStack/trogonai#169: Exposes the execution and snapshot modules in the crate's public API, complementing this PR's snapshot execution implementation.

🐰 A snapshot in time, so clean and bright,
Delta replays dance through the night,
Policies decide when to persist,
No failures linger—just async bliss!
Hop along, deciders now glide.

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 22.62% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title 'feat(trogon-decider-runtime): add snapshot execution' accurately and specifically describes the main change—adding snapshot execution capabilities to the trogon-decider-runtime crate.
Description check ✅ Passed The description directly addresses the motivation for the snapshot execution feature by explaining the need for a stable snapshot boundary and phase-specific error handling.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch yordis/chore-create-pr-v3

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 and usage tips.

@github-actions

github-actions Bot commented May 20, 2026

Copy link
Copy Markdown

badge

Code Coverage Summary

Details
Filename                                                                              Stmts    Miss  Cover    Missing
----------------------------------------------------------------------------------  -------  ------  -------  ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
crates/trogon-gateway/src/source/gitlab/gitlab_signing_token.rs                          74       0  100.00%
crates/trogon-gateway/src/source/gitlab/server.rs                                       460       0  100.00%
crates/trogon-gateway/src/source/gitlab/signature.rs                                    165       0  100.00%
crates/acp-nats/src/nats/subjects/responses/cancelled.rs                                 15       0  100.00%
crates/acp-nats/src/nats/subjects/responses/update.rs                                    27       0  100.00%
crates/acp-nats/src/nats/subjects/responses/response.rs                                  20       0  100.00%
crates/acp-nats/src/nats/subjects/responses/prompt_response.rs                           27       0  100.00%
crates/acp-nats/src/nats/subjects/responses/ext_ready.rs                                 12       0  100.00%
crates/trogon-decider-runtime/src/snapshot/read_snapshot.rs                              11       0  100.00%
crates/trogon-decider-runtime/src/snapshot/mod.rs                                         3       0  100.00%
crates/mcp-nats/src/client.rs                                                            31       0  100.00%
crates/mcp-nats/src/server.rs                                                            31       0  100.00%
crates/mcp-nats/src/mcp_peer_id.rs                                                       33       0  100.00%
crates/mcp-nats/src/config.rs                                                           110       0  100.00%
crates/mcp-nats/src/mcp_prefix.rs                                                        36       0  100.00%
crates/mcp-nats/src/transport.rs                                                        722       0  100.00%
crates/mcp-nats/src/jsonrpc.rs                                                           22       0  100.00%
crates/trogon-std/src/telemetry/http.rs                                                 217       0  100.00%
crates/trogon-gateway/src/streams.rs                                                    169      10  94.08%   11, 23, 31, 39, 47, 55, 63, 71, 79, 87
crates/trogon-gateway/src/source_status.rs                                               28       0  100.00%
crates/trogon-gateway/src/config.rs                                                    2559      48  98.12%   91, 110, 328-329, 332, 712, 715, 875, 878, 881, 885, 960, 963, 966, 970, 1054-1061, 1138, 1141, 1144, 1149, 1207, 1210, 1213, 1292, 1295, 1298, 1302, 1366, 1369, 1372, 1435, 1438, 1441, 1446, 1521, 1524, 1527, 1532, 1590, 1593, 1596, 1809-1811
crates/trogon-gateway/src/main.rs                                                       116       0  100.00%
crates/trogon-gateway/src/source_integration_id.rs                                       61       3  95.08%   55, 57, 65
crates/trogon-gateway/src/http.rs                                                       192       1  99.48%   119
crates/acp-nats/src/nats/subjects/commands/resume.rs                                     15       0  100.00%
crates/acp-nats/src/nats/subjects/commands/cancel.rs                                     15       0  100.00%
crates/acp-nats/src/nats/subjects/commands/load.rs                                       15       0  100.00%
crates/acp-nats/src/nats/subjects/commands/set_config_option.rs                          15       0  100.00%
crates/acp-nats/src/nats/subjects/commands/prompt.rs                                     15       0  100.00%
crates/acp-nats/src/nats/subjects/commands/set_model.rs                                  15       0  100.00%
crates/acp-nats/src/nats/subjects/commands/close.rs                                      15       0  100.00%
crates/acp-nats/src/nats/subjects/commands/fork.rs                                       15       0  100.00%
crates/acp-nats/src/nats/subjects/commands/set_mode.rs                                   15       0  100.00%
crates/trogon-decider-runtime/src/snapshot/codec/snapshot_envelope_decode_error.rs       38       0  100.00%
crates/trogon-decider-runtime/src/snapshot/codec/snapshot_decode_error.rs                23       0  100.00%
crates/trogon-decider-runtime/src/snapshot/codec/snapshot_encode_error.rs                23       0  100.00%
crates/trogon-decider-runtime/src/snapshot/codec/snapshot_envelope_encode_error.rs       20       0  100.00%
crates/trogon-decider-runtime/src/snapshot/codec/encoded_snapshot.rs                     59       0  100.00%
crates/trogon-decider-runtime/src/snapshot/codec/snapshot_payload_decode.rs               3       0  100.00%
crates/acp-nats/src/nats/parsing.rs                                                     278       1  99.64%   151
crates/acp-nats/src/nats/extensions.rs                                                    3       0  100.00%
crates/acp-nats/src/nats/mod.rs                                                          23       0  100.00%
crates/trogon-gateway/src/source/linear/signature.rs                                     54       1  98.15%   16
crates/trogon-gateway/src/source/linear/config.rs                                        17       0  100.00%
crates/trogon-gateway/src/source/linear/server.rs                                       386       0  100.00%
crates/trogon-decider-runtime/src/headers/header_name.rs                                 33       0  100.00%
crates/trogon-decider-runtime/src/headers/mod.rs                                         74       0  100.00%
crates/trogon-decider-runtime/src/headers/header_map.rs                                  54       3  94.44%   20-22
crates/trogon-decider-runtime/src/headers/header_value.rs                                37       0  100.00%
crates/trogon-decider-runtime/src/headers/from_entries_error.rs                          11       0  100.00%
crates/trogon-decider/src/lib.rs                                                        143       0  100.00%
crates/trogon-decider/src/testing.rs                                                    660       0  100.00%
crates/trogon-decider/src/decision.rs                                                    37       0  100.00%
crates/trogon-decider/src/events.rs                                                      49       0  100.00%
crates/trogon-decider/src/act.rs                                                         62       0  100.00%
crates/trogon-gateway/src/source/discord/gateway.rs                                     426       1  99.77%   137
crates/trogon-gateway/src/source/discord/config.rs                                      108       0  100.00%
crates/trogon-gateway/src/source/telegram/signature.rs                                   32       0  100.00%
crates/trogon-gateway/src/source/telegram/config.rs                                     109       0  100.00%
crates/trogon-gateway/src/source/telegram/registration.rs                               327       0  100.00%
crates/trogon-gateway/src/source/telegram/server.rs                                     339       0  100.00%
crates/trogon-gateway/src/source/microsoft_graph/client_state.rs                         30       0  100.00%
crates/trogon-gateway/src/source/microsoft_graph/server.rs                              325       0  100.00%
crates/trogon-gateway/src/source/notion/notion_verification_token.rs                     17       0  100.00%
crates/trogon-gateway/src/source/notion/server.rs                                       318       8  97.48%   93-97, 130-131, 150-151
crates/trogon-gateway/src/source/notion/verification_token.rs                           240       0  100.00%
crates/trogon-gateway/src/source/notion/signature.rs                                     56       1  98.21%   32
crates/trogon-gateway/src/source/notion/notion_event_type.rs                             46       3  93.48%   47-49
crates/trogon-service-config/src/lib.rs                                                  92       0  100.00%
crates/mcp-nats/src/nats/parsing.rs                                                     191       0  100.00%
crates/mcp-nats/src/nats/mod.rs                                                          99       0  100.00%
crates/trogon-gateway/src/source/incidentio/signature.rs                                206       0  100.00%
crates/trogon-gateway/src/source/incidentio/incidentio_signing_secret.rs                 67       0  100.00%
crates/trogon-gateway/src/source/incidentio/server.rs                                   343       0  100.00%
crates/trogon-gateway/src/source/incidentio/config.rs                                    16       0  100.00%
crates/trogon-gateway/src/source/incidentio/incidentio_event_type.rs                     62       0  100.00%
crates/trogon-nats/src/jetstream/publish.rs                                              64       0  100.00%
crates/trogon-nats/src/jetstream/stream_max_age.rs                                       18       0  100.00%
crates/trogon-nats/src/jetstream/traits.rs                                               46      46  0.00%    152-262
crates/trogon-nats/src/jetstream/mocks.rs                                               748      32  95.72%   367-381, 387-395, 410-416, 430-433, 497-499
crates/trogon-nats/src/jetstream/claim_check.rs                                         346       0  100.00%
crates/trogon-nats/src/jetstream/create_conflicts.rs                                     24       0  100.00%
crates/mcp-nats-server/src/main.rs                                                      357     127  64.43%   149-166, 202-204, 214, 220-221, 228-231, 255-257, 261-270, 292-305, 310-358, 489, 492, 500-542
crates/mcp-nats-server/src/config.rs                                                    276       0  100.00%
crates/mcp-nats-server/src/allowed_host.rs                                               90       0  100.00%
crates/trogon-std/src/uuid.rs                                                             7       0  100.00%
crates/trogon-std/src/args.rs                                                            19       9  52.63%   11-28
crates/trogon-std/src/secret_string.rs                                                   35       0  100.00%
crates/trogon-std/src/http.rs                                                            19       0  100.00%
crates/trogon-std/src/duration.rs                                                        45       0  100.00%
crates/trogon-std/src/json.rs                                                            30       0  100.00%
crates/trogon-std/src/signal.rs                                                          26      12  53.85%   6-11, 18-25, 34
crates/acp-nats/src/client/rpc_reply.rs                                                  64       0  100.00%
crates/acp-nats/src/client/terminal_release.rs                                          347       0  100.00%
crates/acp-nats/src/client/terminal_kill.rs                                             290       0  100.00%
crates/acp-nats/src/client/session_update.rs                                             55       0  100.00%
crates/acp-nats/src/client/ext_session_prompt_response.rs                               135       0  100.00%
crates/acp-nats/src/client/ext.rs                                                       308       8  97.40%   163-172, 189-198
crates/acp-nats/src/client/mod.rs                                                      2851       0  100.00%
crates/acp-nats/src/client/terminal_create.rs                                           274       0  100.00%
crates/acp-nats/src/client/terminal_wait_for_exit.rs                                    378       0  100.00%
crates/acp-nats/src/client/fs_read_text_file.rs                                         356       0  100.00%
crates/acp-nats/src/client/request_permission.rs                                        308       0  100.00%
crates/acp-nats/src/client/terminal_output.rs                                           206       0  100.00%
crates/acp-nats/src/client/fs_write_text_file.rs                                        418       0  100.00%
crates/mcp-nats/src/nats/subjects/server/unsubscribe_resource.rs                         12       0  100.00%
crates/mcp-nats/src/nats/subjects/server/set_logging_level.rs                            12       0  100.00%
crates/mcp-nats/src/nats/subjects/server/complete.rs                                     12       0  100.00%
crates/mcp-nats/src/nats/subjects/server/resource_list_changed.rs                        12       0  100.00%
crates/mcp-nats/src/nats/subjects/server/initialize.rs                                   12       0  100.00%
crates/mcp-nats/src/nats/subjects/server/elicitation_completed.rs                        12       0  100.00%
crates/mcp-nats/src/nats/subjects/server/tool_list_changed.rs                            12       0  100.00%
crates/mcp-nats/src/nats/subjects/server/list_tools.rs                                   12       0  100.00%
crates/mcp-nats/src/nats/subjects/server/get_prompt.rs                                   12       0  100.00%
crates/mcp-nats/src/nats/subjects/server/call_tool.rs                                    12       0  100.00%
crates/mcp-nats/src/nats/subjects/server/progress.rs                                     12       0  100.00%
crates/mcp-nats/src/nats/subjects/server/get_task_result.rs                              12       0  100.00%
crates/mcp-nats/src/nats/subjects/server/cancelled.rs                                    12       0  100.00%
crates/mcp-nats/src/nats/subjects/server/cancel_task.rs                                  12       0  100.00%
crates/mcp-nats/src/nats/subjects/server/list_prompts.rs                                 12       0  100.00%
crates/mcp-nats/src/nats/subjects/server/list_resource_templates.rs                      12       0  100.00%
crates/mcp-nats/src/nats/subjects/server/list_resources.rs                               12       0  100.00%
crates/mcp-nats/src/nats/subjects/server/list_tasks.rs                                   12       0  100.00%
crates/mcp-nats/src/nats/subjects/server/logging_message.rs                              12       0  100.00%
crates/mcp-nats/src/nats/subjects/server/ping.rs                                          9       0  100.00%
crates/mcp-nats/src/nats/subjects/server/read_resource.rs                                12       0  100.00%
crates/mcp-nats/src/nats/subjects/server/resource_updated.rs                             12       0  100.00%
crates/mcp-nats/src/nats/subjects/server/prompt_list_changed.rs                          12       0  100.00%
crates/mcp-nats/src/nats/subjects/server/subscribe_resource.rs                           12       0  100.00%
crates/mcp-nats/src/nats/subjects/server/get_task.rs                                     12       0  100.00%
crates/trogon-std/src/env/system.rs                                                      17       0  100.00%
crates/trogon-std/src/env/in_memory.rs                                                   73       0  100.00%
crates/acp-nats/src/nats/subjects/subscriptions/all_client.rs                             9       0  100.00%
crates/acp-nats/src/nats/subjects/subscriptions/one_agent.rs                             15       0  100.00%
crates/acp-nats/src/nats/subjects/subscriptions/global_all.rs                             9       0  100.00%
crates/acp-nats/src/nats/subjects/subscriptions/one_session.rs                           12       0  100.00%
crates/acp-nats/src/nats/subjects/subscriptions/one_client.rs                            15       0  100.00%
crates/acp-nats/src/nats/subjects/subscriptions/all_agent.rs                              9       0  100.00%
crates/acp-nats/src/nats/subjects/subscriptions/all_agent_ext.rs                          9       0  100.00%
crates/acp-nats/src/nats/subjects/subscriptions/prompt_wildcard.rs                        9       0  100.00%
crates/acp-nats/src/nats/subjects/subscriptions/all_session.rs                            9       0  100.00%
crates/acp-nats-agent/src/connection.rs                                                1270       1  99.92%   607
crates/trogon-gateway/src/source/sentry/server.rs                                       311       0  100.00%
crates/trogon-gateway/src/source/sentry/signature.rs                                     54       0  100.00%
crates/trogon-gateway/src/source/sentry/sentry_client_secret.rs                          17       0  100.00%
crates/acp-nats/src/telemetry/metrics.rs                                                 53       0  100.00%
crates/acp-nats/src/jetstream/consumers.rs                                               91       0  100.00%
crates/acp-nats/src/jetstream/provision.rs                                               53       0  100.00%
crates/acp-nats/src/jetstream/streams.rs                                                163       4  97.55%   206-208, 218
crates/acp-nats/src/jetstream/ext_policy.rs                                              26       0  100.00%
crates/acp-nats/src/agent/authenticate.rs                                                49       0  100.00%
crates/acp-nats/src/agent/initialize.rs                                                  79       0  100.00%
crates/acp-nats/src/agent/close_session.rs                                               63       0  100.00%
crates/acp-nats/src/agent/ext_method.rs                                                  82       0  100.00%
crates/acp-nats/src/agent/bridge.rs                                                     123       4  96.75%   108-111
crates/acp-nats/src/agent/prompt.rs                                                     471       0  100.00%
crates/acp-nats/src/agent/set_session_config_option.rs                                   67       0  100.00%
crates/acp-nats/src/agent/resume_session.rs                                              90       0  100.00%
crates/acp-nats/src/agent/set_session_mode.rs                                            67       0  100.00%
crates/acp-nats/src/agent/cancel.rs                                                     101       0  100.00%
crates/acp-nats/src/agent/test_support.rs                                               267       0  100.00%
crates/acp-nats/src/agent/ext_notification.rs                                            82       0  100.00%
crates/acp-nats/src/agent/set_session_model.rs                                           67       0  100.00%
crates/acp-nats/src/agent/js_request.rs                                                 283       0  100.00%
crates/acp-nats/src/agent/mod.rs                                                         65       0  100.00%
crates/acp-nats/src/agent/list_sessions.rs                                               47       0  100.00%
crates/acp-nats/src/agent/fork_session.rs                                                94       0  100.00%
crates/acp-nats/src/agent/load_session.rs                                                89       0  100.00%
crates/acp-nats/src/agent/logout.rs                                                      49       0  100.00%
crates/acp-nats/src/agent/new_session.rs                                                 82       0  100.00%
crates/trogon-nats/src/connect.rs                                                        94       9  90.43%   22-23, 33, 60-65
crates/trogon-nats/src/messaging.rs                                                     561       2  99.64%   144, 154
crates/trogon-nats/src/mocks.rs                                                         317       0  100.00%
crates/trogon-nats/src/client.rs                                                         22      22  0.00%    50-86
crates/trogon-nats/src/token.rs                                                           6       0  100.00%
crates/trogon-nats/src/nats_token.rs                                                    157       0  100.00%
crates/trogon-nats/src/auth.rs                                                          114       0  100.00%
crates/trogon-nats/src/subject_token_violation.rs                                        17       0  100.00%
crates/acp-nats-server/src/main.rs                                                      896      10  98.88%   100, 231-238, 437
crates/acp-nats-server/src/connection.rs                                                171      32  81.29%   76-83, 88-99, 115, 117-118, 123, 132-133, 138, 142, 146, 149, 157, 161, 164, 167-171, 207
crates/acp-nats-server/src/transport.rs                                                1852     106  94.28%   277, 536, 554, 581, 635, 640, 659, 671, 790, 813-815, 867, 884-887, 982-985, 1059, 1062, 1065, 1074, 1078, 1081, 1084-1087, 1106, 1138-1141, 1149-1154, 1166-1170, 1174-1183, 1195-1196, 1214-1215, 1225, 1241-1245, 1273-1279, 1298-1300, 1305-1309, 1312-1317, 1334, 1336-1337, 1419-1420, 1432-1433, 1453-1454, 1506-1522, 2218, 2261, 2313, 2368, 2380
crates/acp-nats-server/src/acp_connection_id.rs                                          45       0  100.00%
crates/acp-nats-server/src/config.rs                                                    137       9  93.43%   41, 50-61
crates/mcp-nats/src/telemetry/transport.rs                                                6       0  100.00%
crates/trogon-decider-runtime/src/event/codec/event_decode.rs                             3       0  100.00%
crates/trogon-gateway/src/source/github/server.rs                                       328       0  100.00%
crates/trogon-gateway/src/source/github/config.rs                                        17       0  100.00%
crates/trogon-gateway/src/source/github/signature.rs                                     61       0  100.00%
crates/mcp-nats-stdio/src/main.rs                                                       212       0  100.00%
crates/mcp-nats-stdio/src/config.rs                                                     160       0  100.00%
crates/trogon-gateway/src/source/twitter/config.rs                                       17       0  100.00%
crates/trogon-gateway/src/source/twitter/server.rs                                      525       0  100.00%
crates/trogon-gateway/src/source/twitter/signature.rs                                    69       0  100.00%
crates/mcp-nats/src/nats/subjects/mod.rs                                                 89       0  100.00%
crates/trogon-gateway/src/source/slack/server.rs                                        863       0  100.00%
crates/trogon-gateway/src/source/slack/signature.rs                                      77       0  100.00%
crates/trogon-gateway/src/source/slack/config.rs                                         17       0  100.00%
crates/trogon-nats/src/lease/lease_config_error.rs                                       11       0  100.00%
crates/trogon-nats/src/lease/ttl.rs                                                      73       0  100.00%
crates/trogon-nats/src/lease/mod.rs                                                     561      13  97.68%   180-193
crates/trogon-nats/src/lease/provision.rs                                               187      10  94.65%   82-92
crates/trogon-nats/src/lease/lease_key.rs                                                19       0  100.00%
crates/trogon-nats/src/lease/renew.rs                                                   246      19  92.28%   23-29, 48-59
crates/trogon-nats/src/lease/renew_interval.rs                                           61       0  100.00%
crates/trogon-nats/src/lease/acquire.rs                                                   5       5  0.00%    9-14
crates/trogon-nats/src/lease/lease_bucket.rs                                             19       0  100.00%
crates/trogon-nats/src/lease/release.rs                                                   5       5  0.00%    8-12
crates/trogon-nats/src/lease/nats_kv_lease_config.rs                                     26       0  100.00%
crates/trogon-nats/src/lease/lease_timing.rs                                             15       0  100.00%
crates/trogon-telemetry/src/service_name.rs                                              44       0  100.00%
crates/trogon-telemetry/src/metric.rs                                                    26       1  96.15%   29
crates/trogon-telemetry/src/resource_attribute.rs                                        23       0  100.00%
crates/trogon-telemetry/src/lib.rs                                                      197      23  88.32%   94, 99, 104, 114-115, 121-139, 175, 178, 181, 187
crates/trogon-telemetry/src/trace.rs                                                     23       1  95.65%   22
crates/trogon-telemetry/src/log.rs                                                       68       1  98.53%   33
crates/trogon-nats/src/telemetry/messaging.rs                                            82       0  100.00%
crates/trogon-std/src/dirs/system.rs                                                     71       0  100.00%
crates/trogon-std/src/dirs/fixed.rs                                                      80       0  100.00%
crates/trogon-decider-runtime/src/event/event_id.rs                                      32       0  100.00%
crates/trogon-decider-runtime/src/event/event_identity.rs                                 3       0  100.00%
crates/trogon-decider-runtime/src/event/mod.rs                                          162       0  100.00%
crates/trogon-decider-runtime/src/event/stream_event.rs                                   8       0  100.00%
crates/acp-nats/src/nats/subjects/stream.rs                                              56       0  100.00%
crates/acp-nats/src/nats/subjects/mod.rs                                                362       0  100.00%
crates/trogon-decider-runtime/src/execution.rs                                         1202       0  100.00%
crates/trogon-gateway/src/source/standard_webhooks.rs                                   172       0  100.00%
crates/acp-nats/src/client_proxy.rs                                                     181       0  100.00%
crates/acp-nats/src/acp_prefix.rs                                                        50       0  100.00%
crates/acp-nats/src/ext_method_name.rs                                                   68       0  100.00%
crates/acp-nats/src/session_id.rs                                                        71       0  100.00%
crates/acp-nats/src/error.rs                                                             82       0  100.00%
crates/acp-nats/src/pending_prompt_waiters.rs                                           134       0  100.00%
crates/acp-nats/src/jsonrpc.rs                                                            6       0  100.00%
crates/acp-nats/src/req_id.rs                                                            39       0  100.00%
crates/acp-nats/src/lib.rs                                                               69       0  100.00%
crates/acp-nats/src/config.rs                                                           203       0  100.00%
crates/acp-nats/src/in_flight_slot_guard.rs                                              32       0  100.00%
crates/trogon-decider-runtime/src/stream/read_stream.rs                                  10       0  100.00%
crates/trogon-decider-runtime/src/stream/append_stream.rs                                 5       0  100.00%
crates/trogon-decider-runtime/src/stream/mod.rs                                          38       0  100.00%
crates/trogon-decider-runtime/src/stream/stream_position.rs                              29       0  100.00%
crates/trogon-std/src/time/mock.rs                                                      125       0  100.00%
crates/trogon-std/src/time/system.rs                                                     31       0  100.00%
crates/acp-nats/src/nats/subjects/client_ops/fs_write_text_file.rs                       12       0  100.00%
crates/acp-nats/src/nats/subjects/client_ops/terminal_create.rs                          12       0  100.00%
crates/acp-nats/src/nats/subjects/client_ops/session_update.rs                           12       0  100.00%
crates/acp-nats/src/nats/subjects/client_ops/terminal_release.rs                         12       0  100.00%
crates/acp-nats/src/nats/subjects/client_ops/terminal_kill.rs                            12       0  100.00%
crates/acp-nats/src/nats/subjects/client_ops/terminal_output.rs                          12       0  100.00%
crates/acp-nats/src/nats/subjects/client_ops/session_request_permission.rs               12       0  100.00%
crates/acp-nats/src/nats/subjects/client_ops/fs_read_text_file.rs                        12       0  100.00%
crates/acp-nats/src/nats/subjects/client_ops/terminal_wait_for_exit.rs                   12       0  100.00%
crates/mcp-nats/src/nats/subjects/subscriptions/one_server.rs                             9       0  100.00%
crates/mcp-nats/src/nats/subjects/subscriptions/all_client.rs                             6       0  100.00%
crates/mcp-nats/src/nats/subjects/subscriptions/one_client.rs                             9       0  100.00%
crates/mcp-nats/src/nats/subjects/subscriptions/all_server.rs                             6       0  100.00%
crates/acp-nats/src/nats/subjects/global/ext.rs                                           9       0  100.00%
crates/acp-nats/src/nats/subjects/global/session_list.rs                                  6       0  100.00%
crates/acp-nats/src/nats/subjects/global/authenticate.rs                                  6       0  100.00%
crates/acp-nats/src/nats/subjects/global/initialize.rs                                    6       0  100.00%
crates/acp-nats/src/nats/subjects/global/ext_notify.rs                                    9       0  100.00%
crates/acp-nats/src/nats/subjects/global/logout.rs                                        6       0  100.00%
crates/acp-nats/src/nats/subjects/global/session_new.rs                                   6       0  100.00%
crates/acp-nats-stdio/src/main.rs                                                       135      25  81.48%   65, 113-120, 126-128, 145, 174-193
crates/acp-nats-stdio/src/config.rs                                                      66       0  100.00%
crates/trogon-std/src/fs/system.rs                                                       92       0  100.00%
crates/trogon-std/src/fs/mem.rs                                                         216      10  95.37%   61-63, 77-79, 132-134, 157
crates/mcp-nats/src/nats/subjects/client/cancelled.rs                                    12       0  100.00%
crates/mcp-nats/src/nats/subjects/client/list_roots.rs                                   12       0  100.00%
crates/mcp-nats/src/nats/subjects/client/initialized.rs                                  12       0  100.00%
crates/mcp-nats/src/nats/subjects/client/roots_list_changed.rs                           12       0  100.00%
crates/mcp-nats/src/nats/subjects/client/create_elicitation.rs                           12       0  100.00%
crates/mcp-nats/src/nats/subjects/client/progress.rs                                     12       0  100.00%
crates/mcp-nats/src/nats/subjects/client/create_message.rs                               12       0  100.00%
crates/mcp-nats/src/nats/subjects/client/ping.rs                                          9       0  100.00%
TOTAL                                                                                 36423     626  98.28%

Diff against main

Filename                                                                              Stmts    Miss  Cover
----------------------------------------------------------------------------------  -------  ------  --------
crates/trogon-decider-runtime/src/snapshot/read_snapshot.rs                             +11       0  +100.00%
crates/trogon-decider-runtime/src/snapshot/mod.rs                                        +3       0  +100.00%
crates/trogon-decider-runtime/src/snapshot/codec/snapshot_envelope_decode_error.rs      +38       0  +100.00%
crates/trogon-decider-runtime/src/snapshot/codec/snapshot_decode_error.rs               +23       0  +100.00%
crates/trogon-decider-runtime/src/snapshot/codec/snapshot_encode_error.rs               +23       0  +100.00%
crates/trogon-decider-runtime/src/snapshot/codec/snapshot_envelope_encode_error.rs      +20       0  +100.00%
crates/trogon-decider-runtime/src/snapshot/codec/encoded_snapshot.rs                    +59       0  +100.00%
crates/trogon-decider-runtime/src/snapshot/codec/snapshot_payload_decode.rs              +3       0  +100.00%
crates/acp-nats-server/src/transport.rs                                                   0      -4  +0.22%
crates/trogon-decider-runtime/src/execution.rs                                         +494       0  +100.00%
TOTAL                                                                                  +674      -4  +0.04%

Results for commit: a71d254

Minimum allowed coverage is 95%

♻️ This comment has been updated with latest results

@yordis yordis force-pushed the yordis/chore-create-pr-v3 branch from a2f2a15 to 32b38a8 Compare May 20, 2026 23:07

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 5

🧹 Nitpick comments (1)
rsworkspace/crates/trogon-decider-runtime/src/snapshot/snapshot_type.rs (1)

1-2: 🏗️ Heavy lift

Use a typed prefix value object instead of raw &'static str.

This contract allows invalid prefixes (e.g., empty/unsupported format). Expose a dedicated prefix type with validated construction so invalid values are unrepresentable at the API boundary.

As per coding guidelines, "Prefer domain-specific value objects over primitives (e.g., AcpPrefix instead of String). Each type's factory must guarantee correctness at construction—invalid instances should be unrepresentable."

🤖 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 `@rsworkspace/crates/trogon-decider-runtime/src/snapshot/snapshot_type.rs`
around lines 1 - 2, Replace the raw &'static str constant with a domain value
object: add a new SnapshotStreamPrefix type (newtype struct with a private field
and a public validated constructor like SnapshotStreamPrefix::try_from(&str) ->
Result<Self, PrefixError>) that enforces non-empty/format rules at construction,
then update the SnapshotType trait to expose that type (e.g., fn
snapshot_stream_prefix() -> SnapshotStreamPrefix or an associated constant of
type SnapshotStreamPrefix) instead of const SNAPSHOT_STREAM_PREFIX: &'static str
so implementors must produce a validated SnapshotStreamPrefix instance; update
all implementors to construct the prefix via the validated constructor and
remove direct use of raw &'static str.
🤖 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 `@rsworkspace/crates/trogon-decider-runtime/README.md`:
- Line 70: Update the awkward sentence in the README that currently reads "Use
`NoSnapshot` when a caller wants snapshot reads" to clearer phrasing; locate the
sentence near the phrase "events since the loaded snapshot" and change it to:
"Use `NoSnapshot` when a caller wants to read snapshots without writes." Ensure
the `NoSnapshot` symbol remains inline code.

In
`@rsworkspace/crates/trogon-decider-runtime/src/snapshot/codec/snapshot_payload_decode.rs`:
- Around line 14-16: The associated type Error on SnapshotPayloadDecode is
unconstrained; add trait bounds to make it a proper error type (e.g. Error:
std::error::Error + Send + Sync + 'static) and update the trait signature
accordingly so decode returns Result<Self, Self::Error> with a typed error;
apply the identical bound change to the SnapshotPayloadEncode trait's Error
associated type so both codec traits match the project’s other codec/stream
trait bounds (use the same Error: std::error::Error + Send + Sync + 'static
constraint and adjust any impls as needed).

In
`@rsworkspace/crates/trogon-decider-runtime/src/snapshot/codec/snapshot_payload_encode.rs`:
- Around line 2-4: Constrain the associated Error types to match other infra
traits by changing the trait declarations so the associated type has the
std::error::Error + Send + Sync + 'static bounds; specifically update
SnapshotPayloadEncode to declare "type Error: std::error::Error + Send + Sync +
'static;" (and likewise update SnapshotPayloadDecode's Error associated type if
present) so implementations like TestPayload (which uses serde_json::Error)
satisfy the crate-wide error bounds.

In `@rsworkspace/crates/trogon-decider-runtime/src/snapshot/read_snapshot.rs`:
- Around line 20-25: The associated type SnapshotRead::Error must be constrained
to enforce proper typed errors; update the trait declaration for SnapshotRead so
Error has bounds like implementing std::error::Error (and typically Debug), and
being Send + Sync + 'static to ensure it can be propagated across async
boundaries; adjust the trait signature around type Error and ensure the
read_snapshot return type stays the same (refer to SnapshotRead::Error,
read_snapshot, ReadSnapshotRequest, and ReadSnapshotResponse<SnapshotPayload>)
so implementations cannot use plain primitives or String and must supply
concrete error structs/enums.

In `@rsworkspace/crates/trogon-decider-runtime/src/snapshot/write_snapshot.rs`:
- Around line 13-18: Add concrete trait bounds to the associated Error type on
the SnapshotWrite and SnapshotRead traits so implementations must provide a
typed, sendable error; specifically update the associated type declarations
(SnapshotWrite::Error and SnapshotRead::Error) to require something like
std::error::Error + Send + Sync + 'static (or your crate's preferred error trait
bounds) and ensure any method signatures that reference Error (e.g.,
write_snapshot returning Result<WriteSnapshotResponse, Self::Error>) continue to
compile with those bounds.

---

Nitpick comments:
In `@rsworkspace/crates/trogon-decider-runtime/src/snapshot/snapshot_type.rs`:
- Around line 1-2: Replace the raw &'static str constant with a domain value
object: add a new SnapshotStreamPrefix type (newtype struct with a private field
and a public validated constructor like SnapshotStreamPrefix::try_from(&str) ->
Result<Self, PrefixError>) that enforces non-empty/format rules at construction,
then update the SnapshotType trait to expose that type (e.g., fn
snapshot_stream_prefix() -> SnapshotStreamPrefix or an associated constant of
type SnapshotStreamPrefix) instead of const SNAPSHOT_STREAM_PREFIX: &'static str
so implementors must produce a validated SnapshotStreamPrefix instance; update
all implementors to construct the prefix via the validated constructor and
remove direct use of raw &'static str.
🪄 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: CHILL

Plan: Pro

Run ID: 243ddf1a-7a85-4c09-b954-e9f083c5984f

📥 Commits

Reviewing files that changed from the base of the PR and between 8d42454 and 32b38a8.

📒 Files selected for processing (15)
  • rsworkspace/crates/trogon-decider-runtime/README.md
  • rsworkspace/crates/trogon-decider-runtime/src/execution.rs
  • rsworkspace/crates/trogon-decider-runtime/src/lib.rs
  • rsworkspace/crates/trogon-decider-runtime/src/snapshot/codec/encoded_snapshot.rs
  • rsworkspace/crates/trogon-decider-runtime/src/snapshot/codec/mod.rs
  • rsworkspace/crates/trogon-decider-runtime/src/snapshot/codec/snapshot_decode_error.rs
  • rsworkspace/crates/trogon-decider-runtime/src/snapshot/codec/snapshot_encode_error.rs
  • rsworkspace/crates/trogon-decider-runtime/src/snapshot/codec/snapshot_envelope_decode_error.rs
  • rsworkspace/crates/trogon-decider-runtime/src/snapshot/codec/snapshot_envelope_encode_error.rs
  • rsworkspace/crates/trogon-decider-runtime/src/snapshot/codec/snapshot_payload_decode.rs
  • rsworkspace/crates/trogon-decider-runtime/src/snapshot/codec/snapshot_payload_encode.rs
  • rsworkspace/crates/trogon-decider-runtime/src/snapshot/mod.rs
  • rsworkspace/crates/trogon-decider-runtime/src/snapshot/read_snapshot.rs
  • rsworkspace/crates/trogon-decider-runtime/src/snapshot/snapshot_type.rs
  • rsworkspace/crates/trogon-decider-runtime/src/snapshot/write_snapshot.rs

Comment thread rsworkspace/crates/trogon-decider-runtime/README.md Outdated
Comment thread rsworkspace/crates/trogon-decider-runtime/src/snapshot/read_snapshot.rs Outdated
Comment thread rsworkspace/crates/trogon-decider-runtime/src/snapshot/write_snapshot.rs Outdated
@yordis yordis force-pushed the yordis/chore-create-pr-v3 branch 2 times, most recently from aefc5a1 to 7e8094b Compare May 20, 2026 23:25
Signed-off-by: Yordis Prieto <yordis.prieto@gmail.com>
@yordis yordis force-pushed the yordis/chore-create-pr-v3 branch from 7e8094b to a71d254 Compare May 20, 2026 23:46
@yordis yordis merged commit d92aaa2 into main May 21, 2026
7 checks passed
@yordis yordis deleted the yordis/chore-create-pr-v3 branch May 21, 2026 00:02
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant