Guidance for coding agents working in github.com/ncode/twamp.
This repository is a Go TWAMP implementation with strict RFC semantics and strong test coverage.
- Keep changes small, local, and protocol-correct.
- Preserve RFC behavior (especially MBZ fields, mode negotiation, and message sizes).
- Treat RFC 4656, RFC 5357, RFC 5618, RFC 5938, and RFC 6038 as mandatory constraints for all protocol-affecting changes.
- Prefer readable code over clever abstractions.
- Add or update tests for behavior changes.
- Never weaken security checks for convenience.
- Go version:
1.25.x(module usesgo 1.25.6). - Module path:
github.com/ncode/twamp. - Main packages:
client,server,messages,common,crypto,metrics,logging. - Integration tests:
test/integration.
Run from repository root.
- Download modules:
go mod download - Verify module files:
go mod tidy
- Build all packages (CI build parity):
go build ./... - Build one package:
go build ./client
- Format all code:
go fmt ./... - Vet all packages:
go vet ./... - Optional extra strictness (if installed):
staticcheck ./...
- Run all tests:
go test ./... - Run with race detector:
go test -race ./... - Run with verbose output:
go test -v ./...
- Single test in a package:
go test ./client -run '^TestConnect$'
- Single subtest:
go test ./common -run '^TestValidateRequestedMode$/mixed_authenticated_with_extensions$'
- Multiple matching tests by regex:
go test ./server -run 'TestHandleRequest|TestStart'
- Single package, single count (disable cache):
go test ./messages -run '^TestServerGreeting_Unmarshal$' -count=1
- All integration tests:
go test -v ./test/integration - Single integration test:
go test ./test/integration -run '^TestRFC6038' -count=1
- perfSONAR helper script:
chmod +x test/integration/perfsonar/run.shINTEROP_DIAGNOSTICS_DIR="$(pwd)/test-results/perfsonar-interop" test/integration/perfsonar/run.sh
- Coverage profile (repo-wide):
go test -race -coverpkg=./... ./... -coverprofile=coverage.out -covermode=atomic
- View coverage report:
go tool cover -html=coverage.out - Benchmarks:
go test -bench . -benchmem ./...
Follow existing patterns in the touched package first.
- Group imports in Go standard style:
- standard library
- blank line
- internal/external module imports
- Do not use dot imports.
- Use import aliases only when required to avoid collisions or improve clarity.
- Always keep files
gofmt-clean. - Prefer small functions with clear control flow.
- Keep protocol constants near related types/functions.
- Use comments for non-obvious protocol rules or invariants, not obvious code.
- Use domain types from
common(e.g.,common.Mode,common.SessionID,common.TWAMPTimestamp) instead of raw primitives when available. - Prefer concrete types over
interface{}unless polymorphism is needed. - Keep zero-value behavior safe and explicit in config constructors (
NewClient,NewServer). - Use typed constants for protocol values and accept codes.
- Exported identifiers:
PascalCasewith clear domain meaning. - Unexported identifiers:
camelCase. - Sentinel errors:
ErrXxxin package-levelvarblocks. - Constructors:
NewXxx. - Test names:
TestXxx, table entries with descriptivenamefields.
- Return errors; do not panic in library code.
- Wrap lower-level errors with context using
%w(e.g.,fmt.Errorf("failed to parse greeting: %w", err)). - Preserve sentinel semantics so callers can use
errors.Is. - Prefer fail-closed behavior for auth/crypto validation.
- For combined cleanup failures, use
errors.Joinwhere appropriate.
- Propagate
context.Contextthrough network operations. - Respect timeouts/deadlines; avoid goroutine leaks.
- Protect shared mutable state with mutexes/atomics as existing code does.
- Validate concurrency changes with
go test -race ./....
- Message lengths and field offsets are strict; validate before parsing.
- Preserve big-endian encoding conventions for wire fields.
- Enforce MBZ fields (
must be zero) on unmarshal paths. - Keep mode negotiation logic consistent with RFC 4656/5357/5618/5938/6038 behavior already implemented.
- Treat RFC 4656/5357/5618/5938/6038 as required review checklist items before merging protocol changes.
- Cite RFC sections in comments where behavior may look surprising.
- Confirm wire sizes, offsets, and field ordering match RFC definitions before/after changes.
- Verify all MBZ fields are written as zero and rejected on parse when non-zero.
- Validate mode negotiation behavior against RFC 4656/5357 and extensions from RFC 5618/5938/6038.
- Ensure authenticated/encrypted paths verify HMAC before consuming dependent fields.
- Add or update tests that exercise protocol changes, including at least one RFC-specific regression case.
- Verify HMAC before using dependent authenticated fields.
- Do not log secrets, keys, IVs, or raw auth material.
- Keep key derivation and crypto stream setup paths explicit and test-covered.
- Prefer table-driven tests for validation-heavy logic.
- Use
t.Runfor case naming and selective execution. - Use
t.Parallel()only when shared state and port usage are safe. - Keep tests deterministic (avoid flaky timing assumptions).
- Add regression tests when fixing bugs.
- Existing integration tests use
testify/require; stay consistent in that area.