feat(a2a-nats): subjects schema + gateway ingress - #304
Conversation
yordis
commented
Jun 17, 2026
- Establishing the subject typestate (Requestable / Publishable / Subscribable / JetStreamEvents) once means each per-operation PR only declares its subject struct and the dispatch trait it implements — call sites can't accidentally publish a subject that expects a reply.
- Gateway ingress carries a closed list of recognised method-suffix tails so a typo on the wire fails the resolve instead of silently landing on a typo subject the agent never subscribed to, and re-deriving that list every per-op PR would invite drift.
Subject marker traits split publishable / requestable / subscribable /
jetstream-events so call sites can't accidentally publish a subject that
expects a reply. Gateway ingress maps {prefix}.gateway.{agent_id}.{method.dots}
into the matching {prefix}.agents.{agent_id}.{method} shape with a closed
method-suffix list so a typo on the wire fails the resolve instead of
silently landing on a typo subject the agent never subscribed to.
Signed-off-by: Yordis Prieto <yordis.prieto@gmail.com>
PR SummaryMedium Risk Overview Adds helpers to build correlating JSON-RPC error replies for ingress failures (invalid request, policy tiers, deadlines). Scaffolds Reviewed by Cursor Bugbot for commit 6645730. Bugbot is set up for automated code reviews on this repo. Configure here. |
|
Warning Review limit reached
More reviews will be available in 42 minutes and 30 seconds. Learn how PR review limits work. Your organization has used up its prepaid credits, and credit purchases are no longer available. Enable the review add-on in the billing tab to keep reviews running — you're only billed for reviews past your plan's rate limits ($0.25/file). ⌛ How to resolve this issue?After more reviews become available, a review can be triggered using the To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based credits. 🚦 How do rate limits work?CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan refill rate. For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, the refill rate gradually slows as usage increases. The highest same-day bursts are limited more strictly. Please see our Fair Usage Limits Policy for further information. ℹ️ Review info⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (1)
WalkthroughAdds a new ChangesGateway Ingress Routing and Subjects Scaffold
Sequence Diagram(s)sequenceDiagram
participant GatewayIngress as Gateway Ingress Handler
participant resolve_gateway_ingress_subject
participant peel_agent_and_suffix
participant A2aAgentId as A2aAgentId Validator
participant JsonRpcErrorResponse as JSON-RPC Error Builder
GatewayIngress->>resolve_gateway_ingress_subject: subject, prefix
resolve_gateway_ingress_subject->>resolve_gateway_ingress_subject: strip {prefix}.gateway. leader
resolve_gateway_ingress_subject->>peel_agent_and_suffix: remaining tokens
peel_agent_and_suffix->>peel_agent_and_suffix: longest-first match vs GATEWAY_INGRESS_METHOD_SUFFIXES
peel_agent_and_suffix-->>resolve_gateway_ingress_subject: (agent_token, suffix_dots) or UnknownMethod
resolve_gateway_ingress_subject->>A2aAgentId: validate agent_token
A2aAgentId-->>resolve_gateway_ingress_subject: A2aAgentId or InvalidAgentId
resolve_gateway_ingress_subject-->>GatewayIngress: {prefix}.agents.{agent_id}.{suffix} or GatewayIngressError
GatewayIngress->>JsonRpcErrorResponse: ingress_*_response_bytes(payload_hint, message)
JsonRpcErrorResponse-->>GatewayIngress: bytes::Bytes (serialized JSON-RPC error)
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes Possibly related PRs
Poem
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
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. Comment |
Code Coverage SummaryDetailsDiff against mainResults for commit: 6645730 Minimum allowed coverage is ♻️ This comment has been updated with latest results |
There was a problem hiding this comment.
Actionable comments posted: 2
🤖 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/a2a-nats/src/gateway_ingress.rs`:
- Around line 82-93: The `compose_gateway_ingress_subject` function currently
only checks if the method suffix is non-empty but does not validate it against a
closed list of valid methods, allowing invalid method names like "sned" to pass
through. Add validation logic after trimming the dots to check if the trimmed
method suffix matches one of the allowed/valid method names for the gateway. If
the method is not in the valid closed set, return an appropriate error (such as
GatewayComposeError::InvalidMethod or similar) instead of allowing arbitrary
values. This ensures that only valid methods can be composed into subjects,
maintaining the fail-fast guarantee.
- Around line 6-7: The module documentation comment contains a singular form
mismatch: the docs reference `{prefix}.agent…` and "agent → gateway" but the
actual implementation uses the plural form `.agents.` as the subject leader.
Update the module documentation at the beginning of the gateway_ingress.rs file
to change `{prefix}.agent…` to `{prefix}.agents…` and update the description
from "agent → gateway" to "agents → gateway" to accurately reflect how the
gateway_ingress_subject_from_agent_subject function and related helpers actually
work with agent-shaped subjects.
🪄 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: d2a5c502-c8cd-46a1-9355-7c16da6eb487
📒 Files selected for processing (8)
rsworkspace/crates/a2a-nats/src/gateway_ingress.rsrsworkspace/crates/a2a-nats/src/lib.rsrsworkspace/crates/a2a-nats/src/nats/mod.rsrsworkspace/crates/a2a-nats/src/nats/subjects/agents/mod.rsrsworkspace/crates/a2a-nats/src/nats/subjects/markers.rsrsworkspace/crates/a2a-nats/src/nats/subjects/mod.rsrsworkspace/crates/a2a-nats/src/nats/subjects/subscriptions/mod.rsrsworkspace/crates/a2a-nats/src/nats/subjects/tasks/mod.rs
Drop defensive shape checks that can't fire (resolve already filters empty tokens and matches a closed suffix list with a non-empty agent), inline the agent-id parse so the helper has the same single decision shape as resolve. Add tests for Display, empty-rest, no-suffix-match, and the four ingress response-bytes helpers so the coverage gate reflects exercised behaviour rather than dead branches. Signed-off-by: Yordis Prieto <yordis.prieto@gmail.com>
Compose now rejects suffixes that aren't in the closed list so a typo like 'message.sned' fails at the call site instead of producing a subject that the resolve step would refuse on the wire — keeps the end-to-end closed-list guarantee symmetric between compose and resolve. Module docs also align on the plural '.agents.' source leader the helpers actually match. Signed-off-by: Yordis Prieto <yordis.prieto@gmail.com>
Signed-off-by: Yordis Prieto <yordis.prieto@gmail.com>