Thank you for your interest in contributing to trpc-agent-service.
We welcome bug fixes, features, tests, documentation, examples, design improvements, and other contributions. Read this guide before submitting a change so that proposals, implementations, and reviews can proceed consistently.
Except for trivial changes, contributions should be associated with an existing issue or a newly opened issue.
Starting with an issue allows maintainers and contributors to agree on the problem, scope, acceptance criteria, and high-level design before implementation begins. It also helps prevent duplicate work and avoids moving architectural discussions into code review.
Use the repository's issue templates when reporting a bug, requesting a feature, or proposing a design. Do not begin implementation while important design or scope questions remain unresolved.
A bug report should answer the following questions:
- Which commit or version of trpc-agent-service are you using?
- Which Go version, operating system, and processor architecture are you using?
- Which deployment mode, storage backend, and IM integration are involved?
- What did you do?
- What did you expect to happen?
- What happened instead?
Include the relevant output of go env when environment details may affect the
problem. Remove credentials, tokens, personal data, and customer content from
logs, traces, configuration, and examples.
Significant features, framework abstractions, public API changes, persistence changes, protocol changes, tenant-isolation changes, and migration behavior should be discussed before implementation.
High-level design should be settled in an issue or design proposal. Code review should verify and refine an agreed design, not become the first place where the design is considered.
Follow GitHub flow and submit changes through a pull request. Keep each pull request focused on one coherent outcome and avoid unrelated refactoring.
Pull request titles and descriptions must be written in English.
Source-code comments and Go documentation comments must also be written in English. Exceptions include translated documentation and test data that intentionally verifies localized behavior.
Issues and review discussions may use another language when that makes communication more effective.
Every pull request title must identify the primary affected package or repository area and summarize the result of the change.
Prefer the following form for a change with one primary package:
package: lowercase summary
When multiple packages are equally affected, enclose the package list in braces and separate package names with a comma and a space:
{package/a, package/b}: lowercase summary
Use one primary package whenever possible. Do not add documentation, tests, or
examples to the package list when they only support the primary implementation
change. For a change that does not belong to a Go package, use the narrowest
repository area or subsystem that owns the change, such as docs, ci, or
scripts.
The summary should:
- begin with a lowercase letter;
- describe the result rather than the implementation process;
- be concise but meaningful without reading the diff; and
- complete the sentence "This change modifies trpc-agent-service to _____."
Use an ASCII colon followed by one space. A generic change type, issue number, tool name, or bracketed tag does not replace the affected package name.
Keep the description concise. The diff is the source of truth; the description should provide the context that code alone cannot.
Use the pull request template to explain:
- What changed: the outcome and its user or developer impact.
- Why: the problem and any non-obvious design rationale.
- Scope and compatibility: public API, configuration, data, migration, deployment, tenant-isolation, and failure-behavior implications.
- Testing: the validation that was actually performed.
- Notes for reviewers: optional risks or design decisions that deserve focused review.
Do not restate the implementation, enumerate every changed file or symbol, or leave template instructions unchanged. Call out public API, compatibility, migration, security, or tenant-isolation concerns when they are not obvious from the diff.
The pull request title and description form durable project history regardless of the merge method. Keep them synchronized with the final outcome.
Treat every public API and externally observable platform behavior as a long-lived compatibility commitment.
A public API change includes adding, removing, renaming, or changing:
- an exported type, function, method, interface, field, constant, or variable;
- an option, callback, plugin, guardrail, adapter, or sentinel error contract;
- default, zero-value, nil, ownership, concurrency, or lifecycle behavior;
- serialized fields, database schemas, persistence formats, or protocols; or
- event ordering, streaming, cancellation, retry, idempotency, or other observable behavior.
Before adding a public API:
- search for an existing API or extension point that supports the use case;
- verify that the concept belongs to the selected package and abstraction layer;
- prefer reusing tRPC-Agent-Go capabilities over duplicating framework behavior;
- keep implementation-specific concepts in their owning packages unless their semantics are genuinely shared across implementations;
- avoid parallel entry points with substantially overlapping responsibilities;
- prefer the smallest surface that supports external consumers; and
- consider how the API can evolve without duplicate types, methods, or incompatible renames.
Every exported symbol must have meaningful Godoc that explains its contract. Documentation that only restates the declaration is insufficient.
Review exported names for semantic accuracy, discoverability, package fit, abstraction boundaries, and future evolution. Unexported naming and local refactoring preferences are not public API concerns unless they are misleading or likely to cause incorrect behavior.
Tenant identity must come from an authenticated and trusted binding. Do not accept a tenant ID directly from untrusted headers, message payloads, tool arguments, or user input.
All tenant-owned storage operations must carry an explicit tenant_id boundary.
Namespaced string IDs are collision protection, not a replacement for storage
isolation or authorization.
Do not place model keys, IM tokens, database credentials, customer content, or other secrets in source code, tests, logs, traces, error messages, issue text, or pull request descriptions. Preserve the distinction between compliance audit events and sampled telemetry.
Changes involving authentication, authorization, tools, external integrations, storage routing, or tenant configuration must include focused security and tenant-boundary review.
Follow Effective Go and the Go Code Review Comments, while preserving established project APIs when compatibility requires it.
- Format code with
gofmtby running./scripts/format.sh. - Use short, lowercase, single-word package names. Avoid underscores, mixed capitals, and names that repeat their package when qualified.
- Use MixedCaps for Go names and spell common initialisms consistently, such as
ID,URL,HTTP, andAPI. - Make exported names read naturally with their package qualifier. Avoid stutter
and redundant prefixes such as
pkg.PkgType. - Prefer small interfaces that describe behavior required by consumers. Do not introduce an interface only to anticipate hypothetical implementations or to make a concrete type easier to mock.
- Prefer returning concrete types from constructors. Add a constructor when it establishes invariants or improves usability; otherwise, make the zero value useful when practical.
- Pass
context.Contextas the first parameter when an operation needs it. Do not store a context in a struct unless the type explicitly represents that context's lifetime. - Keep error strings lowercase and without trailing punctuation. Wrap errors
with
%wwhen callers need the cause, and expose sentinel or typed errors only when callers have a stable reason to inspect them. - Make goroutine, channel, resource, cancellation, and shutdown ownership explicit. Background work must have a bounded way to stop.
- Write doc comments for exported declarations as complete sentences beginning with the declared name, and document behavior that callers must understand.
Do not turn idiomatic guidance into subjective churn. Match surrounding code when several forms are valid, and do not refactor established public APIs only to satisfy a style preference.
Before submitting or updating a pull request:
- run
./scripts/format.sh --check; - run
./scripts/lint.sh; - run
./scripts/build.sh; - run
go test ./...or./scripts/coverage.shfor root-module changes; - run race tests for concurrency-sensitive packages, for example
go test -race ./trpcservice/tenant/...; - add targeted tests for new behavior, boundary conditions, and regressions;
- update documentation and examples when public behavior changes; and
- verify that tests do not depend on credentials, external services, machine-specific paths, or unstable timing unless explicitly required.
Tests should validate externally observable behavior rather than merely execute new code. Assertions should be strong enough to fail when the intended contract is broken.
Report validation commands in a portable form. Do not include local absolute paths, machine-specific cache directories, credentials, or developer-specific environment configuration in pull request descriptions.
Use Fixes #123 when the pull request completely resolves an issue.
Use Updates #123 when the pull request contributes to an issue but does not
fully resolve it.
For an issue in another repository, use the full repository reference:
Fixes owner/repository#123
Push additional commits to the pull request branch when addressing feedback. Both incremental commits and rebasing with a force-push are accepted when they do not disrupt other contributors. Keep the pull request description synchronized with the final outcome and important review context.
When using stacked pull requests, state the stack and base branch explicitly.
Merge from the bottom of the stack upward, then retarget and revalidate each
remaining pull request so that every final diff is reviewable against main.
This guide is adapted from the tRPC-Agent-Go contribution guide for this repository's platform scope, scripts, and security model.