Skip to content

feat(trogon-gateway): require webhook integrations#156

Merged
yordis merged 5 commits into
mainfrom
yordis/fix-n-webhooks-gateway
May 12, 2026
Merged

feat(trogon-gateway): require webhook integrations#156
yordis merged 5 commits into
mainfrom
yordis/fix-n-webhooks-gateway

Conversation

@yordis
Copy link
Copy Markdown
Member

@yordis yordis commented May 12, 2026

  • Gateway route families need separate namespaces so source ingress can coexist with ACP, MCP, and future protocols.
  • Multiple webhook integrations need explicit boundaries so source secrets and routes cannot collide.
  • Source activation needs to be visible in committed config so environment variables cannot silently change gateway behavior.
  • Env-backed secret references keep credential material outside committed gateway config without restoring legacy singleton env vars.

@cursor
Copy link
Copy Markdown

cursor Bot commented May 12, 2026

PR Summary

Medium Risk
Medium risk because it changes the gateway’s configuration schema and HTTP routing for all webhook sources (breaking existing env-var and legacy route setups), which could prevent sources from mounting or publishing if configs aren’t migrated correctly.

Overview
Moves webhook source configuration from per-source env vars to explicit TOML "integrations", enabling multiple independently-named integrations per source with per-integration secrets and optional NATS tuning.

Namespaces all webhook routes under /sources/<source>/<integration>/webhook (replacing /github/webhook, /slack/webhook, etc.), validates integration IDs as route-safe tokens, and updates error reporting and tests accordingly.

Docker Compose/dev docs are updated to mount gateway.toml, load .env via env_file, and provide example env-backed secret references (e.g. { env = "..." }) rather than legacy TROGON_SOURCE_* variables.

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

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 12, 2026

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 48 minutes and 44 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: 55c595c1-2db0-4c18-855d-9672b8646659

📥 Commits

Reviewing files that changed from the base of the PR and between 89c2800 and 3e244d5.

📒 Files selected for processing (1)
  • rsworkspace/crates/trogon-gateway/src/main.rs

Walkthrough

The PR refactors trogon-gateway from single-config-per-source to multi-instance webhook routing. A new SourceIntegrationId type validates route-safe instance names. Config resolution now iterates source instance collections, validates per-instance secrets, and builds Vec<SourceInstance<...>> structures. HTTP routing mounts integrations under /sources/<source>/<instance_id>/webhook. Stream provisioning and Telegram startup logic updated to handle multiple instances per source. Docker compose and documentation describe the new TOML-based configuration layout.

Changes

Multi-Instance Webhook Routing Refactor

Layer / File(s) Summary
Instance ID Type & Validation
rsworkspace/crates/trogon-gateway/src/source_integration_id.rs
New SourceIntegrationId newtype wrapping NatsToken with construction validation (max length, alphanumeric/hyphen/underscore only). SourceIntegrationIdError covers empty, invalid character, and too-long violations. Includes stream_name_suffix() for uppercase conversion.
Configuration Foundation
rsworkspace/crates/trogon-gateway/src/config.rs, rsworkspace/crates/trogon-gateway/src/constants.rs
Extended ConfigValidationError with instance-scoped variants (InvalidInstanceId, InvalidInstanceField, MissingInstanceField, InvalidInstanceSubjectToken) and updated Display/Error::source(). Added timing constants. Changed ResolvedConfig struct fields from Option<Config> to Vec<SourceInstance<Config>> for most sources. Added webhooks: BTreeMap<String, WebhookConfig> to all multi-instance source configuration structs.
Configuration Resolution
rsworkspace/crates/trogon-gateway/src/config.rs
Shared utilities: resolve_instance_id, require_instance_value, resolve_common_instance_fields, resolve_instance_source_status for per-instance field parsing and validation. Modified resolve() entry point to call new resolve_*_instances functions for each multi-instance source and aggregate validation errors. Implemented resolvers for GitHub, Slack, Telegram, Twitter, GitLab, Linear, Microsoft Graph, Incidentio, Notion, Sentry; each handles legacy fallback, per-instance webhook secret parsing, optional per-instance tuning, registration validation (Telegram), and common field resolution.
Configuration Tests
rsworkspace/crates/trogon-gateway/src/config.rs
Updated GitHub and Telegram unit tests to verify vector-based results, default instance field derivation, missing secret validation, route-safe instance ID parsing, and per-instance registration requirements.
HTTP Webhook Routing
rsworkspace/crates/trogon-gateway/src/http.rs
Refactored mount_sources to iterate source instance collections and mount each under /sources/<source_path>/<integration.id> using source-specific routers. Updated test fixtures and added GitHub webhook signature verification; new integration routing test verifies 404 on legacy paths and 200 on new paths with correct JetStream subject.
Stream Provisioning
rsworkspace/crates/trogon-gateway/src/streams.rs
Updated provision() to iterate per-source instance lists (except Discord, which remains single optional config), calling provisioners with integration.config and logging source plus integration fields. New test verifies multiple instances create distinct streams.
Telegram Multi-Instance Startup
rsworkspace/crates/trogon-gateway/src/main.rs, rsworkspace/crates/trogon-gateway/src/source/telegram/*
Changed startup Telegram registration from single instance to multi-instance: collects all instances with registration configured, creates shared HTTP client, registers webhooks for each. Updated test URLs to /sources/telegram/<integration>/webhook.
Docker Compose & Environment
devops/docker/compose/compose.yml, devops/docker/compose/.env.example, services/trogon-gateway/gateway.toml
Added optional shared .env file loading to gateway and ngrok. Trimmed inline environment variables to only core settings. Updated .env.example to document instance configuration via TOML with environment variable references; replaced per-source TROGON_SOURCE_* blocks with single-placeholder "primary" variables. Created gateway.toml with active [http_server] port and [sources.github.integrations.local.webhook] secret, plus commented template for all sources.
Documentation
devops/docker/compose/services/trogon-gateway/README.md, rsworkspace/crates/trogon-gateway/README.md
Updated both READMEs to document multi-instance webhook routing (/sources/<source>/{integration}/webhook endpoints), instance ID format constraints, per-source TOML configuration structure, and optional per-integration tuning fields. Replaced environment-variable-based examples with TOML-based configuration. Added integration-scoped Microsoft Graph change-notification paths and incident.io signing secret examples.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Possibly related PRs

  • TrogonStack/trogonai#141: Adds Telegram webhook startup registration; this PR extends that logic to support multi-instance registration with a shared HTTP client.
  • TrogonStack/trogonai#125: Adds Twitter source; this PR refactors config/HTTP/streams modules where Twitter is wired into the per-instance routing model.
  • TrogonStack/trogonai#124: Adds Sentry source; this PR refactors config/streams mounting that Sentry plugs into via the new instance-based resolver pattern.

Poem

A thousand integrations, each with a name,
Route-safe and validated, they're not all the same.
Per-source, per-instance, the webhooks now flow,
From /sources/<name>/<id>/webhook we go! 🐇✨
(Discord stands alone—some prefer it that way.)

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 50.00% 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 Title 'require webhook integrations' directly reflects the main objective of the PR: converting the gateway from single optional configs to per-source webhook integrations with explicit boundaries.
Description check ✅ Passed The description articulates four key reasons for the changes (namespace separation, explicit boundaries, visible config, env-backed secrets), all of which align with the substantial refactoring across config, HTTP routing, and stream provisioning demonstrated in the changeset.
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/fix-n-webhooks-gateway

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
Copy link
Copy Markdown

github-actions Bot commented May 12, 2026

badge

Code Coverage Summary

Details
Filename                                                                      Stmts    Miss  Cover    Missing
--------------------------------------------------------------------------  -------  ------  -------  ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
crates/acp-nats/src/nats/subjects/mod.rs                                        362       0  100.00%
crates/acp-nats/src/nats/subjects/stream.rs                                      56       0  100.00%
crates/trogon-std/src/telemetry/http.rs                                         217       0  100.00%
crates/trogon-nats/src/jetstream/create_conflicts.rs                             24       0  100.00%
crates/trogon-nats/src/jetstream/mocks.rs                                       670      32  95.22%   364-378, 384-392, 407-413, 427-430, 494-496
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/claim_check.rs                                 346       0  100.00%
crates/trogon-nats/src/jetstream/traits.rs                                       46      46  0.00%    145-248
crates/acp-nats/src/nats/subjects/global/session_new.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.rs                                   9       0  100.00%
crates/acp-nats/src/nats/subjects/global/authenticate.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_list.rs                          6       0  100.00%
crates/acp-nats-agent/src/connection.rs                                        1270       1  99.92%   607
crates/acp-nats/src/nats/subjects/responses/update.rs                            27       0  100.00%
crates/acp-nats/src/nats/subjects/responses/cancelled.rs                         15       0  100.00%
crates/acp-nats/src/nats/subjects/responses/prompt_response.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/ext_ready.rs                         12       0  100.00%
crates/acp-nats/src/telemetry/metrics.rs                                         53       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/http.rs                                               192       1  99.48%   119
crates/trogon-gateway/src/config.rs                                            2524      49  98.06%   90, 109, 327-328, 331, 710, 713, 873, 876, 879, 883, 958, 961, 964, 968, 1052-1059, 1136, 1139, 1142, 1147, 1205, 1208, 1211, 1215, 1273, 1276, 1279, 1283, 1347, 1350, 1353, 1416, 1419, 1422, 1427, 1502, 1505, 1508, 1513, 1571, 1574, 1577, 1790-1792
crates/trogon-gateway/src/main.rs                                                 4       0  100.00%
crates/trogon-gateway/src/source_integration_id.rs                               61       3  95.08%   55, 57, 65
crates/trogon-gateway/src/source/notion/notion_event_type.rs                     46       3  93.48%   47-49
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%   92-96, 129-130, 149-150
crates/trogon-gateway/src/source/notion/signature.rs                             56       1  98.21%   32
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/trogon-std/src/dirs/system.rs                                             71       0  100.00%
crates/trogon-std/src/dirs/fixed.rs                                              80       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/trogon-gateway/src/source/github/signature.rs                             61       0  100.00%
crates/trogon-gateway/src/source/github/config.rs                                17       0  100.00%
crates/trogon-gateway/src/source/github/server.rs                               328       0  100.00%
crates/mcp-nats/src/nats/subjects/server/resource_updated.rs                     12       0  100.00%
crates/mcp-nats/src/nats/subjects/server/unsubscribe_resource.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/logging_message.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/get_prompt.rs                           12       0  100.00%
crates/mcp-nats/src/nats/subjects/server/read_resource.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/cancelled.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/get_task_result.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_prompts.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/elicitation_completed.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/ping.rs                                  9       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/tool_list_changed.rs                    12       0  100.00%
crates/mcp-nats/src/nats/subjects/server/get_task.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/progress.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/resource_list_changed.rs                12       0  100.00%
crates/trogon-nats/src/connect.rs                                                94       9  90.43%   22-23, 33, 60-65
crates/trogon-nats/src/auth.rs                                                  114       0  100.00%
crates/trogon-nats/src/messaging.rs                                             561       2  99.64%   144, 154
crates/trogon-nats/src/mocks.rs                                                 314       0  100.00%
crates/trogon-nats/src/client.rs                                                 22      22  0.00%    50-86
crates/trogon-nats/src/subject_token_violation.rs                                17       0  100.00%
crates/trogon-nats/src/nats_token.rs                                            157       0  100.00%
crates/trogon-nats/src/token.rs                                                   6       0  100.00%
crates/mcp-nats/src/nats/subjects/client/create_message.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/progress.rs                             12       0  100.00%
crates/mcp-nats/src/nats/subjects/client/ping.rs                                  9       0  100.00%
crates/mcp-nats/src/nats/subjects/client/create_elicitation.rs                   12       0  100.00%
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/trogon-telemetry/src/service_name.rs                                      44       0  100.00%
crates/trogon-telemetry/src/log.rs                                               68       1  98.53%   33
crates/trogon-telemetry/src/trace.rs                                             23       1  95.65%   22
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/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/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/telegram/registration.rs                       327       0  100.00%
crates/trogon-gateway/src/source/telegram/signature.rs                           32       0  100.00%
crates/trogon-gateway/src/source/telegram/server.rs                             339       0  100.00%
crates/trogon-gateway/src/source/telegram/config.rs                             109       0  100.00%
crates/trogon-nats/src/lease/provision.rs                                       187      10  94.65%   82-92
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/acquire.rs                                           5       5  0.00%    9-14
crates/trogon-nats/src/lease/lease_timing.rs                                     15       0  100.00%
crates/trogon-nats/src/lease/mod.rs                                             561      13  97.68%   180-193
crates/trogon-nats/src/lease/renew.rs                                           246      19  92.28%   23-29, 48-59
crates/trogon-nats/src/lease/lease_config_error.rs                               11       0  100.00%
crates/trogon-nats/src/lease/renew_interval.rs                                   61       0  100.00%
crates/trogon-nats/src/lease/lease_key.rs                                        19       0  100.00%
crates/trogon-nats/src/lease/lease_bucket.rs                                     19       0  100.00%
crates/trogon-nats/src/lease/ttl.rs                                              73       0  100.00%
crates/acp-nats-server/src/acp_connection_id.rs                                  45       0  100.00%
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/main.rs                                              896      10  98.88%   100, 231-238, 437
crates/acp-nats-server/src/config.rs                                            137       9  93.43%   41, 50-61
crates/acp-nats-server/src/transport.rs                                        1852     110  94.06%   277, 452, 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, 1290, 1293-1300, 1305-1309, 1312-1317, 1334, 1336-1337, 1419-1420, 1432-1433, 1453-1454, 1506-1522, 2218, 2261, 2313, 2368, 2380
crates/mcp-nats/src/nats/subjects/subscriptions/all_client.rs                     6       0  100.00%
crates/mcp-nats/src/nats/subjects/subscriptions/all_server.rs                     6       0  100.00%
crates/mcp-nats/src/nats/subjects/subscriptions/one_server.rs                     9       0  100.00%
crates/mcp-nats/src/nats/subjects/subscriptions/one_client.rs                     9       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/acp-nats/src/nats/subjects/client_ops/terminal_output.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/fs_write_text_file.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/session_update.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_create.rs                  12       0  100.00%
crates/acp-nats/src/nats/subjects/client_ops/terminal_wait_for_exit.rs           12       0  100.00%
crates/trogon-std/src/uuid.rs                                                     7       0  100.00%
crates/trogon-std/src/duration.rs                                                45       0  100.00%
crates/trogon-std/src/args.rs                                                    19       9  52.63%   11-28
crates/trogon-std/src/json.rs                                                    30       0  100.00%
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/signal.rs                                                  26      12  53.85%   6-11, 18-25, 34
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/set_session_config_option.rs                           67       0  100.00%
crates/acp-nats/src/agent/cancel.rs                                             101       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/new_session.rs                                         82       0  100.00%
crates/acp-nats/src/agent/js_request.rs                                         283       0  100.00%
crates/acp-nats/src/agent/bridge.rs                                             123       4  96.75%   108-111
crates/acp-nats/src/agent/logout.rs                                              49       0  100.00%
crates/acp-nats/src/agent/test_support.rs                                       267       0  100.00%
crates/acp-nats/src/agent/set_session_mode.rs                                    67       0  100.00%
crates/acp-nats/src/agent/prompt.rs                                             471       0  100.00%
crates/acp-nats/src/agent/resume_session.rs                                      90       0  100.00%
crates/acp-nats/src/agent/authenticate.rs                                        49       0  100.00%
crates/acp-nats/src/agent/ext_method.rs                                          82       0  100.00%
crates/acp-nats/src/agent/load_session.rs                                        89       0  100.00%
crates/acp-nats/src/agent/mod.rs                                                 65       0  100.00%
crates/acp-nats/src/agent/set_session_model.rs                                   67       0  100.00%
crates/acp-nats/src/agent/ext_notification.rs                                    82       0  100.00%
crates/acp-nats/src/ext_method_name.rs                                           68       0  100.00%
crates/acp-nats/src/config.rs                                                   203       0  100.00%
crates/acp-nats/src/req_id.rs                                                    39       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/pending_prompt_waiters.rs                                   134       0  100.00%
crates/acp-nats/src/session_id.rs                                                71       0  100.00%
crates/acp-nats/src/jsonrpc.rs                                                    6       0  100.00%
crates/acp-nats/src/lib.rs                                                       69       0  100.00%
crates/acp-nats/src/error.rs                                                     82       0  100.00%
crates/acp-nats/src/in_flight_slot_guard.rs                                      32       0  100.00%
crates/trogon-std/src/time/system.rs                                             31       0  100.00%
crates/trogon-std/src/time/mock.rs                                              125       0  100.00%
crates/trogon-nats/src/telemetry/messaging.rs                                    82       0  100.00%
crates/trogon-service-config/src/lib.rs                                          92       0  100.00%
crates/mcp-nats/src/telemetry/transport.rs                                        6       0  100.00%
crates/mcp-nats/src/nats/subjects/mod.rs                                         89       0  100.00%
crates/acp-nats/src/client/terminal_release.rs                                  347       0  100.00%
crates/acp-nats/src/client/session_update.rs                                     55       0  100.00%
crates/acp-nats/src/client/terminal_create.rs                                   274       0  100.00%
crates/acp-nats/src/client/fs_read_text_file.rs                                 356       0  100.00%
crates/acp-nats/src/client/ext_session_prompt_response.rs                       135       0  100.00%
crates/acp-nats/src/client/terminal_output.rs                                   206       0  100.00%
crates/acp-nats/src/client/terminal_wait_for_exit.rs                            378       0  100.00%
crates/acp-nats/src/client/terminal_kill.rs                                     290       0  100.00%
crates/acp-nats/src/client/request_permission.rs                                308       0  100.00%
crates/acp-nats/src/client/mod.rs                                              2851       0  100.00%
crates/acp-nats/src/client/ext.rs                                               308       8  97.40%   163-172, 189-198
crates/acp-nats/src/client/fs_write_text_file.rs                                418       0  100.00%
crates/acp-nats/src/client/rpc_reply.rs                                          64       0  100.00%
crates/mcp-nats-stdio/src/config.rs                                             160       0  100.00%
crates/mcp-nats-stdio/src/main.rs                                               212       0  100.00%
crates/trogon-gateway/src/source/linear/config.rs                                17       0  100.00%
crates/trogon-gateway/src/source/linear/signature.rs                             54       1  98.15%   16
crates/trogon-gateway/src/source/linear/server.rs                               386       0  100.00%
crates/acp-nats-stdio/src/config.rs                                              66       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/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/jetstream/consumers.rs                                       91       0  100.00%
crates/acp-nats/src/jetstream/provision.rs                                       53       0  100.00%
crates/acp-nats/src/nats/extensions.rs                                            3       0  100.00%
crates/acp-nats/src/nats/mod.rs                                                  23       0  100.00%
crates/acp-nats/src/nats/parsing.rs                                             278       1  99.64%   151
crates/trogon-gateway/src/source/gitlab/config.rs                                17       0  100.00%
crates/trogon-gateway/src/source/gitlab/server.rs                               397       0  100.00%
crates/trogon-gateway/src/source/gitlab/signature.rs                             28       0  100.00%
crates/trogon-gateway/src/source/discord/config.rs                              108       0  100.00%
crates/trogon-gateway/src/source/discord/gateway.rs                             426       1  99.77%   137
crates/acp-nats/src/nats/subjects/subscriptions/all_session.rs                    9       0  100.00%
crates/acp-nats/src/nats/subjects/subscriptions/all_agent.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/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/one_client.rs                    15       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/mcp-nats/src/client.rs                                                    31       0  100.00%
crates/mcp-nats/src/jsonrpc.rs                                                   22       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/trogon-gateway/src/source/slack/config.rs                                 17       0  100.00%
crates/trogon-gateway/src/source/slack/signature.rs                              77       0  100.00%
crates/trogon-gateway/src/source/slack/server.rs                                863       0  100.00%
crates/trogon-gateway/src/source/incidentio/incidentio_signing_secret.rs         67       0  100.00%
crates/trogon-gateway/src/source/incidentio/incidentio_event_type.rs             62       0  100.00%
crates/trogon-gateway/src/source/incidentio/server.rs                           343       0  100.00%
crates/trogon-gateway/src/source/incidentio/signature.rs                        366       0  100.00%
crates/trogon-gateway/src/source/incidentio/config.rs                            16       0  100.00%
crates/trogon-std/src/fs/mem.rs                                                 216      10  95.37%   61-63, 77-79, 132-134, 157
crates/trogon-std/src/fs/system.rs                                               92       0  100.00%
crates/acp-nats/src/nats/subjects/commands/fork.rs                               15       0  100.00%
crates/acp-nats/src/nats/subjects/commands/resume.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/cancel.rs                             15       0  100.00%
crates/acp-nats/src/nats/subjects/commands/set_mode.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/set_model.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/close.rs                              15       0  100.00%
crates/trogon-gateway/src/source/twitter/config.rs                               17       0  100.00%
crates/trogon-gateway/src/source/twitter/signature.rs                            69       0  100.00%
crates/trogon-gateway/src/source/twitter/server.rs                              525       0  100.00%
TOTAL                                                                         32854     628  98.09%

Diff against main

Filename                                                     Stmts    Miss  Cover
---------------------------------------------------------  -------  ------  --------
crates/trogon-gateway/src/streams.rs                           +21     +10  -5.92%
crates/trogon-gateway/src/http.rs                              +73      +1  -0.52%
crates/trogon-gateway/src/config.rs                           +578     +49  -1.94%
crates/trogon-gateway/src/source_integration_id.rs             +61      +3  +95.08%
crates/trogon-gateway/src/source/telegram/registration.rs       +3       0  +100.00%
TOTAL                                                         +736     +63  -0.15%

Results for commit: 3e244d5

Minimum allowed coverage is 95%

♻️ This comment has been updated with latest results

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

🧹 Nitpick comments (1)
devops/docker/compose/services/trogon-gateway/README.md (1)

47-70: ⚡ Quick win

Consider adding guidance for persistent TOML config setup.

The docker compose run example is helpful for testing, but users deploying multi-webhook configurations permanently would need to mount the volume in compose.yml rather than passing it on the command line. Consider adding a brief note about adding the volume and command args to the gateway service definition in compose.yml for persistent deployments.

📝 Example addition

After line 70, you could add:

For persistent deployment, add the volume mount and config flag to the `trogon-gateway` service in `compose.yml`:

```yaml
services:
  trogon-gateway:
    volumes:
      - ./gateway.toml:/etc/trogon-gateway/gateway.toml:ro
    command: ["--config", "/etc/trogon-gateway/gateway.toml"]

</details>

<details>
<summary>🤖 Prompt for AI Agents</summary>

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

In @devops/docker/compose/services/trogon-gateway/README.md around lines 47 -
70, Add a short persistent-deployment note to the README explaining how to mount
the TOML and pass the config flag in the Docker Compose service definition
(referencing the trogon-gateway service in compose.yml); instruct users to add a
volumes entry that mounts ./gateway.toml to /etc/trogon-gateway/gateway.toml:ro
and add the command/args ["--config", "/etc/trogon-gateway/gateway.toml"] (or
equivalent) to the trogon-gateway service so the gateway uses the persistent
config rather than the transient docker compose run example.


</details>

</blockquote></details>

</blockquote></details>

<details>
<summary>🤖 Prompt for all review comments with AI agents</summary>

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

Nitpick comments:
In @devops/docker/compose/services/trogon-gateway/README.md:

  • Around line 47-70: Add a short persistent-deployment note to the README
    explaining how to mount the TOML and pass the config flag in the Docker Compose
    service definition (referencing the trogon-gateway service in compose.yml);
    instruct users to add a volumes entry that mounts ./gateway.toml to
    /etc/trogon-gateway/gateway.toml:ro and add the command/args ["--config",
    "/etc/trogon-gateway/gateway.toml"] (or equivalent) to the trogon-gateway
    service so the gateway uses the persistent config rather than the transient
    docker compose run example.

</details>

---

<details>
<summary>ℹ️ Review info</summary>

<details>
<summary>⚙️ Run configuration</summary>

**Configuration used**: Organization UI

**Review profile**: CHILL

**Plan**: Pro

**Run ID**: `b084951d-bf2c-42cc-9234-2e07a091ed1d`

</details>

<details>
<summary>📥 Commits</summary>

Reviewing files that changed from the base of the PR and between aec1a447e2ef270773028a7f67d986d558624067 and 4dd79720766c5402c1e215260d7cf2e0b541c538.

</details>

<details>
<summary>📒 Files selected for processing (9)</summary>

* `devops/docker/compose/.env.example`
* `devops/docker/compose/compose.yml`
* `devops/docker/compose/services/trogon-gateway/README.md`
* `rsworkspace/crates/trogon-gateway/README.md`
* `rsworkspace/crates/trogon-gateway/src/config.rs`
* `rsworkspace/crates/trogon-gateway/src/http.rs`
* `rsworkspace/crates/trogon-gateway/src/main.rs`
* `rsworkspace/crates/trogon-gateway/src/source_instance_id.rs`
* `rsworkspace/crates/trogon-gateway/src/streams.rs`

</details>

</details>

<!-- This is an auto-generated comment by CodeRabbit for review status -->

@yordis yordis force-pushed the yordis/fix-n-webhooks-gateway branch from 4dd7972 to 3bc2b71 Compare May 12, 2026 00:19
@yordis yordis added the rust:coverage-baseline-reset Relax Rust coverage gate to establish a new baseline label May 12, 2026
Comment thread rsworkspace/crates/trogon-gateway/src/source_instance_id.rs Outdated
@yordis yordis force-pushed the yordis/fix-n-webhooks-gateway branch from 3bc2b71 to b300f74 Compare May 12, 2026 00:44
@yordis yordis changed the title feat(trogon-gateway): support multiple webhooks feat(trogon-gateway): require webhook instances May 12, 2026
@yordis yordis force-pushed the yordis/fix-n-webhooks-gateway branch from b300f74 to 88c0da5 Compare May 12, 2026 04:35
Comment thread devops/docker/compose/.env.example Outdated
Comment thread rsworkspace/crates/trogon-gateway/src/source_instance_id.rs Outdated
@yordis yordis force-pushed the yordis/fix-n-webhooks-gateway branch 2 times, most recently from cc92fe6 to 55791d6 Compare May 12, 2026 04:57
Comment thread rsworkspace/crates/trogon-gateway/src/source_integration_id.rs
Comment thread devops/docker/compose/.env.example
@yordis yordis force-pushed the yordis/fix-n-webhooks-gateway branch from 55791d6 to 32e3bb1 Compare May 12, 2026 05:44
@yordis yordis changed the title feat(trogon-gateway): require webhook instances feat(trogon-gateway): require webhook integrations May 12, 2026
Copy link
Copy Markdown

@cursor cursor Bot left a comment

Choose a reason for hiding this comment

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

Cursor Bugbot has reviewed your changes and found 1 potential issue.

There are 3 total unresolved issues (including 2 from previous reviews).

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, have a team admin enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 32e3bb1. Configure here.

Comment thread devops/docker/compose/services/trogon-gateway/README.md
@yordis yordis force-pushed the yordis/fix-n-webhooks-gateway branch 2 times, most recently from 66575cd to 757edb5 Compare May 12, 2026 06:27
Signed-off-by: Yordis Prieto <yordis.prieto@gmail.com>
@yordis yordis force-pushed the yordis/fix-n-webhooks-gateway branch from 757edb5 to 25ceff3 Compare May 12, 2026 07:03
yordis added 3 commits May 12, 2026 03:30
Signed-off-by: Yordis Prieto <yordis.prieto@gmail.com>
Signed-off-by: Yordis Prieto <yordis.prieto@gmail.com>
Signed-off-by: Yordis Prieto <yordis.prieto@gmail.com>
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🧹 Nitpick comments (2)
rsworkspace/crates/trogon-gateway/src/source_integration_id.rs (1)

14-19: 💤 Low value

Consider clarifying the relationship between MAX_INTEGRATION_ID_LEN and NatsToken's length limit.

The code checks char_count > MAX_INTEGRATION_ID_LEN before calling NatsToken::new, which also validates length. If MAX_INTEGRATION_ID_LEN matches NatsToken's internal limit, the early check is redundant (though harmless). If they differ, a brief comment explaining why SourceIntegrationId enforces a stricter limit would improve clarity.

🤖 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-gateway/src/source_integration_id.rs` around lines
14 - 19, The length-check against MAX_INTEGRATION_ID_LEN before calling
NatsToken::new is ambiguous—either remove the redundant char_count >
MAX_INTEGRATION_ID_LEN check if MAX_INTEGRATION_ID_LEN is identical to
NatsToken's internal max, or if SourceIntegrationId intentionally enforces a
stricter limit, add a concise comment above the check explaining the
relationship (e.g., "SourceIntegrationId enforces a stricter length than
NatsToken to X") and keep the existing error return
(SourceIntegrationIdError::TooLong), leaving the
NatsToken::new(...).map_err(SourceIntegrationIdError::from_subject_token_violation)?
call as the secondary validation.
rsworkspace/crates/trogon-gateway/src/streams.rs (1)

7-90: ⚖️ Poor tradeoff

Consider extracting the integration provisioning pattern into a helper function.

Lines 7-90 repeat the same pattern for each webhook source: iterate integrations, provision, log with source + integration. A helper function could reduce duplication:

async fn provision_integrations<C, T, F>(
    client: &C,
    source: &'static str,
    integrations: &[SourceIntegration<T>],
    provision_fn: F,
) -> Result<(), C::Error>
where
    C: JetStreamContext,
    F: Fn(&C, &T) -> impl std::future::Future<Output = Result<(), C::Error>>,
{
    for integration in integrations {
        provision_fn(client, &integration.config).await?;
        info!(
            source,
            integration = integration.id.as_str(),
            "stream provisioned"
        );
    }
    Ok(())
}

However, given the straightforward nature and limited scope, the current explicit approach is acceptable.

🤖 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-gateway/src/streams.rs` around lines 7 - 90, The
code repeats the same iterate->call provision->log pattern for each source
(e.g., config.github, config.slack, crate::source::github::provision, info!
logging), so extract a generic async helper (e.g., provision_integrations) that
accepts the JetStream client, a &'static str source name, a slice of
integrations (like &[SourceIntegration<T>]) and a provision function (Fn(&C, &T)
-> Future<Output=Result<() ,C::Error>>), then replace each duplicated loop (for
integration in &config.github / &config.slack / etc.) with a call to that helper
passing the appropriate crate::source::<x>::provision function and source name
so provisioning and the info!(source, integration = integration.id.as_str(),
"stream provisioned") logging are centralized.
🤖 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-gateway/src/main.rs`:
- Around line 97-108: The startup currently propagates Telegram webhook
registration errors (via the `?` after `registration_http_client()` and
`register_webhook(...)`), which contradicts the README; change the behavior so
registration failures are non-blocking by catching errors instead of using `?`:
obtain the HTTP client with a fallible call but handle its Err by logging and
continuing, and for each config call
`crate::source::telegram::registration::register_webhook(config,
&telegram_http_client).await` inside a match or `if let
Err(e)`/`.await.unwrap_or_else(|e| { log/error!(...) })`-style block so failures
are logged and do not return early; keep using the existing
`telegram_registration_configs` collection and the
`crate::source::telegram::registration::registration_http_client()` /
`register_webhook` symbols to locate the code.

---

Nitpick comments:
In `@rsworkspace/crates/trogon-gateway/src/source_integration_id.rs`:
- Around line 14-19: The length-check against MAX_INTEGRATION_ID_LEN before
calling NatsToken::new is ambiguous—either remove the redundant char_count >
MAX_INTEGRATION_ID_LEN check if MAX_INTEGRATION_ID_LEN is identical to
NatsToken's internal max, or if SourceIntegrationId intentionally enforces a
stricter limit, add a concise comment above the check explaining the
relationship (e.g., "SourceIntegrationId enforces a stricter length than
NatsToken to X") and keep the existing error return
(SourceIntegrationIdError::TooLong), leaving the
NatsToken::new(...).map_err(SourceIntegrationIdError::from_subject_token_violation)?
call as the secondary validation.

In `@rsworkspace/crates/trogon-gateway/src/streams.rs`:
- Around line 7-90: The code repeats the same iterate->call provision->log
pattern for each source (e.g., config.github, config.slack,
crate::source::github::provision, info! logging), so extract a generic async
helper (e.g., provision_integrations) that accepts the JetStream client, a
&'static str source name, a slice of integrations (like &[SourceIntegration<T>])
and a provision function (Fn(&C, &T) -> Future<Output=Result<() ,C::Error>>),
then replace each duplicated loop (for integration in &config.github /
&config.slack / etc.) with a call to that helper passing the appropriate
crate::source::<x>::provision function and source name so provisioning and the
info!(source, integration = integration.id.as_str(), "stream provisioned")
logging are centralized.
🪄 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: cb7552d1-d4ee-4349-9705-ef541a2addd5

📥 Commits

Reviewing files that changed from the base of the PR and between 88c0da5 and 89c2800.

📒 Files selected for processing (13)
  • devops/docker/compose/.env.example
  • devops/docker/compose/compose.yml
  • devops/docker/compose/services/trogon-gateway/README.md
  • rsworkspace/crates/trogon-gateway/README.md
  • rsworkspace/crates/trogon-gateway/src/config.rs
  • rsworkspace/crates/trogon-gateway/src/constants.rs
  • rsworkspace/crates/trogon-gateway/src/http.rs
  • rsworkspace/crates/trogon-gateway/src/main.rs
  • rsworkspace/crates/trogon-gateway/src/source/telegram/config.rs
  • rsworkspace/crates/trogon-gateway/src/source/telegram/registration.rs
  • rsworkspace/crates/trogon-gateway/src/source_integration_id.rs
  • rsworkspace/crates/trogon-gateway/src/streams.rs
  • services/trogon-gateway/gateway.toml
✅ Files skipped from review due to trivial changes (2)
  • rsworkspace/crates/trogon-gateway/src/constants.rs
  • rsworkspace/crates/trogon-gateway/src/source/telegram/registration.rs
🚧 Files skipped from review as they are similar to previous changes (2)
  • rsworkspace/crates/trogon-gateway/src/source/telegram/config.rs
  • devops/docker/compose/compose.yml

Comment thread rsworkspace/crates/trogon-gateway/src/main.rs
Signed-off-by: Yordis Prieto <yordis.prieto@gmail.com>
@yordis yordis merged commit 53dc901 into main May 12, 2026
7 checks passed
@yordis yordis deleted the yordis/fix-n-webhooks-gateway branch May 12, 2026 22:28
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

rust:coverage-baseline-reset Relax Rust coverage gate to establish a new baseline

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant