Skip to content

Development

Go 1.27.1 or later. The root uses the toolkit errors module and the JSON Schema compiler github.com/santhosh-tekuri/jsonschema/v6 v6.0.3. TestDependencyFootprint runs go list -deps . to reject protocol SDKs, Cobra, HTTP/gRPC, controls and service frameworks in the root graph; the adapters carry them (see package boundaries).

Command Check
just tidy Resolve module metadata
just test Unit tests and runnable examples with coverage
just test-race Race detection, including concurrent reads and accessor mutation
just lint Estate golangci-lint v2 rules
just docs Strict Zensical documentation build
just proto Lint and regenerate the fixture contract under proto/ with buf and the local protoc plugins; the output is committed
just ci Tidy, tests, race, lint and docs
just coverage Local HTML coverage view
just bench 1,000-operation registry construction and search benchmarks
just vuln govulncheck against the current vulnerability database
just deadcode Dead-code inspection; exported library APIs require consumer-aware interpretation
just test-sdk-compat The pinned SDK 1.4.1/1.6.0/1.7.0 stdio/HTTP fixture matrix (needs Python 3 and a loopback listener)

The cobra and cli tests build the real Cobra fixture under cobra/testdata/fixture in TestMain and execute it: argv fidelity, refused values, exit codes, truncation, timeout and cancellation with a grandchild, the one-slot busy, shutdown, a full stdio session and an HTTP session with the Origin rule. They need a Go toolchain on PATH and skip without one. The internal/servicefixture tests start a real service on a loopback port (the transport server, a transit chain and a controls controller around the handler) and prove the mounted shape the how-to describes. The internal/grpcfixture tests do the same for the gRPC binding: a transport gRPC server and the HTTP chain under one controller, called both ways. Run go test -run '^$' -fuzz FuzzInvocationJSONNeverPanics -fuzztime 5s for the JSON gateway fuzz target.

CI

Released phpboyscout/cicd v0.46.0 components run lint, tests, security scans, Colophon release orchestration and Zensical Pages. Merge-request pipelines run the full test suite; the main pipeline runs docs and release. A cross-vet job vets GOOS=darwin and GOOS=windows on every pipeline.

Two native jobs, binding-test-macos and binding-test-windows, run the cobra and cli suites on runners tagged macos and windows. Each is armed by its own CI variable, MCP_NATIVE_MACOS=true or MCP_NATIVE_WINDOWS=true, and otherwise does not exist in the pipeline, so neither can stall it before its runner does. Until they have run, native descendant cleanup on those platforms is designed and compiled but not proven (spec 0001 B10 makes it a release gate for the platform claim, not for publishing the module).

Releases

Colophon proposes a release merge request from main; merging it tags. Nothing written in that merge request survives: release notes go in Release-Note: commit trailers before the change merges. A .colophon.yaml with hold: true stops both the proposal and the tag; lift it in its own change when the reason has passed.

Local gotchas

  • Do not run Zensical and golangci-lint concurrently: Zensical replaces site/, which makes Go package enumeration fail under the linter with a misleading "0 issues" line.
  • The registry canonicalises numbers to their shortest exact exponent form (1000000 arrives at a handler as 1e6). A consumer parsing arguments as integers must accept that shape; the Cobra codecs do.
  • The Go SDK client decodes metadata numbers into float64, so a client round-trip can round 9007199254740993 even though the server wire preserves it. Tests that assert exactness read the wire, not the client's re-encoding.