Skip to content

MailboxRPC 2/7: contract + codegen + make rpc - #86

Merged
Roasbeef merged 2 commits into
mainfrom
mailbox-contract
Feb 10, 2026
Merged

MailboxRPC 2/7: contract + codegen + make rpc#86
Roasbeef merged 2 commits into
mainfrom
mailbox-contract

Conversation

@bhandras

@bhandras bhandras commented Jan 16, 2026

Copy link
Copy Markdown
Member

Summary

This PR adds initial scaffolding for an RPC-over-mailbox transport layer:

  • mailboxrpc: a small runtime interface package for sending/awaiting RPCs and registering handlers.
  • mailboxpb: the public protobuf contract for the mailbox edge transport.
  • protoc-gen-mailboxrpc: a repo-local protoc plugin that generates typed RPC-over-mailbox client stubs and server registration helpers.
  • make rpc wiring to generate mailbox RPC stubs alongside existing protos.

Why

We want a durable, retry-safe RPC layer that can be transported over a mailbox edge with at-least-once delivery semantics and cursor-based acking. This is part of the durability work tracked in #48 and the mailbox/RPC spec tracked in lightninglabs/darepo#71.

Notes

  • Generated *.pb.go and *_mailboxrpc.pb.go files are checked in.
  • Contributors can regenerate with make rpc (Docker-based tooling).

Follow-ups

  • Implement a concrete mailboxrpc.RPCClient and a router backed by the mailbox transport.
  • Add a conformance test harness once the runtime implementation exists.

@gemini-code-assist

Copy link
Copy Markdown

Summary of Changes

Hello @bhandras, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request establishes the foundational scaffolding for a robust RPC-over-mailbox transport layer. It introduces the necessary protobuf contracts, runtime interfaces, and code generation tooling to enable durable, retry-safe RPC communication with at-least-once delivery semantics and cursor-based acknowledgment. This work is a critical step towards enhancing the system's durability and reliability, aligning with ongoing efforts to improve the mailbox/RPC specification.

Highlights

  • New mailboxrpc Package: Introduced a new mailboxrpc package that defines the runtime interfaces for sending/awaiting RPCs and registering handlers over a mailbox transport. This package provides the core contracts for the RPC-over-mailbox overlay.
  • New mailboxpb Package: Added a mailboxpb package containing the public protobuf contract for the mailbox edge transport. This includes definitions for RpcMeta, Envelope, Status, and RPC methods like Send, Pull, and AckUpTo.
  • New protoc-gen-mailboxrpc Plugin: Developed a new repo-local protoc-gen-mailboxrpc plugin. This plugin automatically generates typed RPC-over-mailbox client stubs and server registration helpers for protobuf services, streamlining the integration of RPCs with the mailbox transport.
  • Updated Proto Generation Wiring: Modified the make rpc command and scripts/gen_protos.sh to include the new protoc-gen-mailboxrpc plugin. This ensures that RPC-over-mailbox stubs are generated alongside existing protobuf files, with a specific exclusion for the mailboxpb package itself.

🧠 New Feature in Public Preview: You can now enable Memory to help Gemini Code Assist learn from your team's feedback. This makes future code reviews more consistent and personalized to your project's style. Click here to enable Memory in your admin console.

Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

@gemini-code-assist gemini-code-assist 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.

Code Review

This pull request introduces the initial scaffolding for an RPC-over-mailbox transport layer. It includes the mailboxrpc runtime interface package, the mailboxpb public protobuf contract, and a protoc-gen-mailboxrpc plugin for generating typed client stubs and server registration helpers. The scripts/gen_protos.sh has been updated to integrate the new generator, ensuring proper installation and conditional exclusion for the mailboxpb package. The overall architecture appears robust and well-documented, laying a solid foundation for a durable and retry-safe RPC mechanism.

@bhandras bhandras changed the title mailboxrpc: add contract, codegen, and make rpc wiring MailboxRPC 2/8: contract + codegen + make rpc Jan 16, 2026
@bhandras bhandras changed the title MailboxRPC 2/8: contract + codegen + make rpc MailboxRPC 2/7: contract + codegen + make rpc Jan 17, 2026
@bhandras
bhandras changed the base branch from main to durability January 17, 2026 10:07
@bhandras
bhandras force-pushed the durability branch 2 times, most recently from ba42f3c to 3a5dbec Compare January 17, 2026 14:31
@bhandras

Copy link
Copy Markdown
Member Author

@codex review pls

@chatgpt-codex-connector

Copy link
Copy Markdown

To use Codex here, create a Codex account and connect to github.

@Roasbeef
Roasbeef force-pushed the durability branch 2 times, most recently from a6c6186 to abdad2a Compare February 6, 2026 02:06
@litbot-9000

Copy link
Copy Markdown
Collaborator

@bhandras, remember to re-request review from reviewers when ready

GoName: "Message",
}

g.P("// ", serviceGoName,

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

@Roasbeef
Roasbeef changed the base branch from durability to main February 10, 2026 21:51
@Roasbeef

Roasbeef commented Feb 10, 2026

Copy link
Copy Markdown
Member

@claude review this

@Roasbeef

Copy link
Copy Markdown
Member

@codex review this

@claude

claude Bot commented Feb 10, 2026

Copy link
Copy Markdown

Claude finished @Roasbeef's task in 2m 48s —— View job


Code Review

Reviewing PR #86: MailboxRPC contract + codegen

Summary

This PR establishes solid foundational scaffolding for RPC-over-mailbox transport. The architecture is clean, the interfaces are well-thought-out, and the code generation approach is sound. I've identified several issues that should be addressed, primarily around code style conformance to the project's development guidelines.


Critical Issues

None - this is solid foundational work.


Major Issues

1. Code generator uses string concatenation instead of templates (generator.go:112+)

As Roasbeef mentioned in the review comments, the generator should use Go templates for better readability and maintainability. The current approach with extensive g.P() calls is hard to read and modify.

Consider using text/template or html/template like the falafel example: https://github.com/lightninglabs/falafel/blob/1b3698ff9a08bc70fc284ee8cfd7ed109b5d74b6/templates.go#L100

2. Missing function comments throughout (development_guidelines.md violation)

Per the development guidelines: "At a minimum every function must be commented with its intended purpose." Several functions lack proper GoDoc comments:

  • cmd/protoc-gen-mailboxrpc/internal/gen/generator.go:
    • Generate (line 11) - has comment but doesn't explain WHY or HOW
    • generateFile (line 29) - minimal comment
    • shouldGenerateFile (line 59) - minimal comment
    • generateService (line 76) - no comment at all
    • protoServiceFQN (line 230) - minimal comment

Each should have a detailed comment explaining the purpose, assumptions, and any important details. See development_guidelines.md lines 19-63 for examples.

3. Function parameter wrapping issues (generator.go)

Several function definitions violate the wrapping guidelines:

  • Line 30-31: generateFile - parameters should be wrapped with proper indentation
  • Line 78-79: generateService - same issue
  • Line 221-222: clientMethodComment - same issue

Per development_guidelines.md lines 405-453, function definitions must follow specific wrapping rules.


Minor Issues / Style Violations

4. Missing blank line after multi-line function declaration

generator.go:30-35 - The generateFile function spans multiple lines but the body doesn't start with a blank line. Per development_guidelines.md lines 436-453:

// WRONG
func generateFile(plugin *protogen.Plugin, file *protogen.File,
	cfg Config) error {
	if !shouldGenerateFile(file, cfg) {

// RIGHT
func generateFile(plugin *protogen.Plugin, file *protogen.File,
	cfg Config) error {

	if !shouldGenerateFile(file, cfg) {

5. Inconsistent code spacing (generator.go)

The generateService function (lines 76-217) is a large block without logical stanzas. Per development_guidelines.md lines 99-144, code should be organized into logical stanzas with blank lines and comments between them.

6. Long lines in generator output (generator.go:112-114)

The generated GoDoc comment is split across multiple g.P() calls in a way that seems awkward:

g.P("// ", serviceGoName,
	"MailboxClient is a typed mailbox RPC client ", "for ",
	serviceGoName, ".",
)

This generates: // ArkServiceMailboxClient is a typed mailbox RPC client for ArkService.

While the output is fine, the code would be cleaner with templates or at least consolidating the string parts.

7. Unused parameters in clientMethodComment (generator.go:224-225)

_ = g
_ = serviceGoName

These underscore assignments are unnecessary - just remove the unused parameters or use them in a more meaningful comment. The comment is too generic ("calls the X RPC") and doesn't add value beyond what the function signature already says.


Documentation & Testing

8. Test coverage is minimal

The generator_test.go only has 2 tests:

  • TestGenerateEmitsRoutingKeys - verifies basic output
  • TestGenerateExcludeService - verifies exclusion works

Missing tests for:

  • Multi-method services
  • Services with no methods
  • Error cases (malformed proto descriptors)
  • Generated code for various method signatures
  • Verification that generated code actually compiles

Per CLAUDE.md: "Strive for near 90% test coverage where practical."

9. Missing integration/golden tests

Consider adding golden tests that verify the complete generated output matches expected files. This would catch unintended changes to the generation logic.


Protobuf Contract (mailbox.proto)

10. Comments could be more detailed

The proto file has good structural comments but could benefit from more details:

  • RpcMeta.correlation_id (line 29): Should specify format/generation requirements
  • Envelope.msg_id (line 42): "unique per send attempt" - how is uniqueness ensured? UUID? ULID?
  • Envelope.idempotency_key (line 44): Should specify format and how it differs from msg_id
  • Status.code (line 81): Should reference a list of error codes or specify the format

11. Consider versioning strategy

The proto package is mailbox.v1 but there's no discussion of versioning strategy in the PR description. Consider documenting:

  • How will v2 work alongside v1?
  • Is protocol_version in Envelope sufficient for breaking changes?
  • What's the upgrade path?

Runtime Interfaces (mailbox/rpc/*)

12. Excellent design - minor documentation improvements

The interface design is clean and well-documented. Minor suggestions:

  • interface.go:14 - HandlerFunc comment mentions "envelope's idempotency key" but the handler doesn't receive the envelope, only the unmarshaled message. Should clarify this or provide access to the envelope metadata.

  • interface.go:42 - SendRPC returns both correlationID and idempotencyKey. The relationship between these could be better documented. From the code, it seems correlation_id can be overridden but defaults to idempotency_key?

  • options.go:13 - The comment says "callers typically use the idempotency key as the correlation id" but this seems like an implementation detail. Should this be part of the interface contract?


Build Integration (gen_protos.sh)

13. Good integration, minor improvements

  • Line 14: go install -buildvcs=false - consider documenting why -buildvcs=false is needed
  • Lines 33-37: The exclusion logic is clear and well-commented
  • Consider adding a check that protoc-gen-mailboxrpc built successfully before proceeding

Generated Code Quality

14. Generated code looks good

Spot-checking arkrpc/ark_mailboxrpc.pb.go:

  • Clean, readable output
  • Proper imports
  • Good naming conventions
  • Type-safe interfaces

The main change to arkrpc/ark.pb.go is a protoc-gen-go version bump (v1.35.1 -> v1.36.6) which brought internal struct layout changes. This is expected and fine.


Recommendations

  1. Address Roasbeef's template suggestion - This will make the generator much more maintainable
  2. Add comprehensive function comments - Critical for project standards compliance
  3. Fix function wrapping violations - These will fail make lint
  4. Expand test coverage - Add golden tests and edge case coverage
  5. Document versioning strategy - Even a brief note in the PR description would help
  6. Consider running make lint - Some of these style issues should be caught by the linter

Positive Notes

  • Clean separation between runtime interfaces (mailbox/rpc) and generated code
  • Well-structured protobuf contract with clear RPC overlay semantics
  • Good use of exclude_service to prevent generating stubs for the transport itself
  • Tests verify the critical behavior (routing keys, exclusion)
  • Build integration is clean and well-documented
  • The generated code is idiomatic Go

This is solid foundational work. The main issues are code style conformance and the need for template-based generation as Roasbeef mentioned.


@chatgpt-codex-connector chatgpt-codex-connector 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.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 06821ef30b

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +191 to +193
g.P("\tif len(opts) > 0 {")
g.P("\t\topt = opts[0]")
g.P("\t}")

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Consume every variadic RPCOptions value

The generated client methods accept opts ...RPCOptions but only copy opts[0], so any additional option structs are silently ignored. In call sites that compose options (for example, adding headers in one helper and overriding correlation/idempotency in another), this drops settings without any error and can change request routing/dedup behavior in production. Either reject len(opts) > 1 explicitly or merge all provided options deterministically.

Useful? React with 👍 / 👎.

@Roasbeef

Copy link
Copy Markdown
Member

@claude review this

@codex review this

@claude

claude Bot commented Feb 10, 2026

Copy link
Copy Markdown

Claude finished @Roasbeef's task in 2m 18s —— View job


Code Review Complete

Reviewing PR #86: MailboxRPC contract + codegen


Summary

This PR establishes solid foundational scaffolding for RPC-over-mailbox transport. The architecture is clean and well-designed, with good separation of concerns between runtime interfaces (mailbox/rpc), protobuf contracts (mailbox/pb), and code generation (protoc-gen-mailboxrpc). The switch to text/template (per Roasbeef's feedback) was the right call - it makes the generated code structure much more readable and maintainable.

However, there are several code style violations that need to be addressed per the development guidelines.


Critical Issues

None - This is solid foundational work with no bugs or architectural problems.


Major Issues

1. Function parameter wrapping violations (generator.go)

Lines 30-31, 78-82, 106-107

Multiple function definitions violate the wrapping guidelines from development_guidelines.md (lines 405-434):

// WRONG (current)
func generateFile(plugin *protogen.Plugin, file *protogen.File,
	cfg Config) error {

func generateService(g *protogen.GeneratedFile,
	svc *protogen.Service, serviceFQN string) error {

func buildServiceData(g *protogen.GeneratedFile,
	svc *protogen.Service, serviceFQN string) serviceData {

Per the guidelines: "lines should not end with an open parenthesis if the function definition isn't finished yet."

Correct form:

func generateFile(plugin *protogen.Plugin, file *protogen.File, cfg Config) (
	error) {

// OR if first line fits:
func generateService(g *protogen.GeneratedFile, svc *protogen.Service,
	serviceFQN string) error {

Additionally, multi-line function declarations should have a blank line after the opening brace (development_guidelines.md lines 436-453):

// WRONG (current - line 30)
func generateFile(plugin *protogen.Plugin, file *protogen.File,
	cfg Config) error {
	if !shouldGenerateFile(file, cfg) {

// RIGHT
func generateFile(plugin *protogen.Plugin, file *protogen.File,
	cfg Config) error {

	if !shouldGenerateFile(file, cfg) {

Fix function wrapping →

2. Missing comprehensive function comments (generator.go)

Lines 11, 29, 61, 78, 95, 104, 136

Per CLAUDE.md: "Every function and method (including unexported ones) must have a comment starting with the function/method name" and "Comments should explain how/why, not just what."

Current comments are minimal and don't explain the "why" or important details:

// INSUFFICIENT (line 11)
// Generate generates mailbox RPC stubs for all services in the protoc request.
func Generate(plugin *protogen.Plugin, cfg Config) error {

Better:

// Generate generates mailbox RPC stubs for all services in the protoc request.
// It iterates through each proto file that should be generated and creates
// corresponding *_mailboxrpc.pb.go files containing typed client/server stubs
// for RPC-over-mailbox transport. Services can be excluded via cfg.ExcludeService
// to prevent generating stubs for the mailbox transport itself.
func Generate(plugin *protogen.Plugin, cfg Config) error {

Similarly, functions like generateFile, shouldGenerateFile, generateService, resolveIdent, buildServiceData, and protoServiceFQN need more detailed comments explaining their purpose, assumptions, and any important details.

Improve function comments →

3. RPCOptions only consumes opts[0] (templates.go:104-106)

Codex correctly identified this issue. The generated code accepts opts ...RPCOptions but only uses opts[0]:

func (c *ArkServiceMailboxClient) GetInfo(..., opts ...rpc.RPCOptions) (...) {
	var opt rpc.RPCOptions
	if len(opts) > 0 {
		opt = opts[0]  // Silently ignores opts[1], opts[2], etc.
	}

This is problematic if callers accidentally pass multiple options structs - the extras are silently dropped.

Solutions:

  1. Reject multiple options: Add validation:
    if len(opts) > 1 {
        return nil, fmt.Errorf("multiple RPCOptions not supported")
    }
  2. Merge options: Define merge semantics (later opts override earlier ones)
  3. Change signature: Use opt RPCOptions instead of opts ...RPCOptions

I recommend option 3 (non-variadic) unless there's a specific reason for variadic args. If variadic is needed, go with option 1 (reject multiple).

Fix opts handling →


Minor Issues

4. Code organization - large function without stanzas (generator.go:78-93)

The generateService function is now quite clean with the template approach, but buildServiceData (lines 104-134) could benefit from logical stanzas per development_guidelines.md lines 99-144:

// CURRENT (dense, hard to skim)
func buildServiceData(...) serviceData {
	const mailboxrpcPath = "..."
	const protoPath = "..."
	data := serviceData{
		ServiceName: ...,
		...
	}
	for _, m := range svc.Methods {
		data.Methods = append(...)
	}
	return data
}

// BETTER (organized into stanzas)
func buildServiceData(...) serviceData {

	// Define import paths for external dependencies that will be
	// registered with the protogen file generator.
	const mailboxrpcPath = "github.com/lightninglabs/darepo-client/" +
		"mailbox/rpc"
	const protoPath = "google.golang.org/protobuf/proto"

	// Build the service-level template data, resolving all external
	// identifiers to register necessary imports.
	data := serviceData{
		ServiceName:  svc.GoName,
		ServiceFQN:   serviceFQN,
		RPCClient:    resolveIdent(g, mailboxrpcPath, "RPCClient"),
		...
	}

	// Add method-level template data for each RPC method in the service.
	for _, m := range svc.Methods {
		data.Methods = append(data.Methods, methodData{
			...
		})
	}

	return data
}

Improve code organization →

5. Test coverage could be expanded (generator_test.go)

Per CLAUDE.md: "Strive for near 90% test coverage where practical."

Current tests (TestGenerateEmitsRoutingKeys, TestGenerateExcludeService) cover basic functionality but miss:

  • Multi-method services (current test has only one method)
  • Services with no methods (edge case)
  • Multiple services in one file
  • Template execution errors
  • Golden tests verifying complete generated output

Suggestions:

  • Add a test with multiple methods to verify all methods generate correctly
  • Add a golden test comparing generated output to a checked-in .golden file
  • Test error handling (malformed proto descriptors)

This is less critical for a code generator since compilation of generated code will catch many issues, but better test coverage would help catch regressions.

6. Proto contract documentation could be more detailed (mailbox.proto)

The proto file has good structural comments but could benefit from more operational details:

Line 29 (correlation_id): Should specify format (UUID? ULID? arbitrary string?) and whether it must be unique.

Line 42 (msg_id): "unique per send attempt" - How is uniqueness ensured? Should this be a UUID/ULID? What happens if not unique?

Line 44 (idempotency_key): Should specify format and clarify how it differs from msg_id in practice. The interface.go comment (line 13) says handlers must be idempotent "under the envelope's idempotency key" but the handler doesn't receive the envelope, only the unmarshaled message.

Line 81 (code): Should reference error code format or provide examples (e.g., "DUPLICATE", "INVALID_PROTOCOL", etc.)

These are minor documentation improvements that would help future implementers.


Documentation & Architecture

7. Excellent interface design (mailbox/rpc/*)

The runtime interface design is clean, well-documented, and appropriately minimal. Good choices:

  • Separation of concerns: mailboxrpc package contains only interfaces, no implementation
  • Clear contracts: HandlerFunc clearly states at-least-once delivery and idempotency requirements
  • Type safety: Router uses func() proto.Message factory for type-safe unmarshaling
  • Flexibility: RPCOptions provides extensibility for headers, correlation, idempotency overrides

Minor suggestion: The relationship between correlationID and idempotencyKey could be clearer. From reading the code:

  • idempotencyKey: Stable per semantic operation (for server-side deduplication)
  • correlationID: Used to match responses to requests (for client-side demuxing)
  • Default behavior: Use idempotencyKey as correlationID

This is documented in options.go:13-14 but could be restated in the RPCClient.SendRPC comment for clarity.

8. Code generation approach is sound

The template-based approach (templates.go) is much better than the previous g.P() concatenation. Good decisions:

  • Using text/template makes output structure directly visible
  • Template data structs (serviceData, methodData) are well-documented
  • resolveIdent properly registers imports with protogen
  • Generated code follows Go idioms (pointer receivers, error handling)

One observation: The //nolint:lll directive (line 63) suppresses line length checks for the template. This is fine for templates where readability matters more than strict column limits, but be aware that generated code will have some long lines (e.g., the client method signatures). This is acceptable for generated code.

9. Build integration is clean (gen_protos.sh)

The build integration is well-thought-out:

  • Line 14: go install -buildvcs=false ensures reproducible builds (though the reason isn't documented - consider adding a comment explaining why -buildvcs=false is needed)
  • Lines 33-37: Exclusion logic is clear and well-commented
  • Formatting: Running clang-format on protos before generation is good hygiene

Minor suggestion: Consider adding error checking after go install to ensure the plugin built successfully before proceeding.


Positive Notes

Template-based generation is much more maintainable than string concatenation
Clean separation between runtime interfaces and generated code
Well-structured protobuf contract with clear RPC overlay semantics
Exclusion mechanism (exclude_service) prevents circular generation
Generated code is idiomatic - clean, readable, type-safe
Good test coverage for core functionality (routing keys, exclusion)
Build integration is clean and well-documented
Package documentation (doc.go) clearly explains the purpose


Recommendations (Priority Order)

  1. Fix function parameter wrapping (generator.go) - Will fail make lint
  2. Add blank lines after multi-line function declarations (generator.go) - Style compliance
  3. Fix RPCOptions handling (templates.go:104-106) - Potential silent bug
  4. Improve function comments (generator.go) - Required by project standards
  5. Add code stanzas to buildServiceData - Improves readability
  6. Expand test coverage - Add multi-method and golden tests
  7. Document proto fields more thoroughly - Helps future implementers
  8. Clarify correlationID vs idempotencyKey relationship - Better API docs

Should this PR be merged?

Yes, with fixes for items 1-4 above. Items 5-8 are nice-to-haves but not blockers.

This is solid foundational work that establishes a clean architecture for RPC-over-mailbox transport. The main issues are code style violations that should be caught by make lint and the RPCOptions handling bug that Codex identified.


@chatgpt-codex-connector chatgpt-codex-connector 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.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 25e96e5aba

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +117 to +121
RPCOptions: resolveIdent(g, mailboxrpcPath, "RPCOptions"),
Router: resolveIdent(g, mailboxrpcPath, "Router"),
Context: resolveIdent(g, "context", "Context"),
ProtoMessage: resolveIdent(g, protoPath, "Message"),
FmtErrorf: resolveIdent(g, "fmt", "Errorf"),

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Skip method-only imports for empty services

buildServiceData always registers RPCOptions, context.Context, proto.Message, and fmt.Errorf imports, but the template only emits those identifiers inside {{range .Methods}} sections. For a valid proto service with zero RPC methods, the generated *_mailboxrpc.pb.go file will still carry these imports even though no code references them, causing a compile-time unused-import failure. Please gate these resolveIdent calls on len(svc.Methods) > 0 (or resolve lazily per method) so empty-service generation remains buildable.

Useful? React with 👍 / 👎.

Replace g.P() call chains with a text/template in the protoc plugin.
This makes the generated output shape directly visible in the
template text, following the pattern used by falafel.

Split generateService into modular helpers: resolveIdent registers
imports and returns qualified names, buildServiceData constructs
template data from protogen types, and generateService orchestrates
template execution into a buffer before writing to g.

@Roasbeef Roasbeef left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

LGTM 🐔

@Roasbeef
Roasbeef merged commit 9dc6ae5 into main Feb 10, 2026
16 checks passed
@bhandras
bhandras deleted the mailbox-contract branch February 20, 2026 16:20
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.

3 participants