Problem
Go HTTP services can begin with a small net/http handler and gradually accumulate routing rules, middleware ordering, response contracts, security policy, storage adapters, and operational checks. When those decisions are distributed through packages without a visible control point, reviewers and coding agents have to infer the system rather than inspect it.
PlumeGo is a Go HTTP toolkit built around an explicit, net/http-compatible composition model. Its stable kernel imports only the Go standard library, while routing, middleware order, and dependency wiring stay visible in a canonical application route file. Existing http.Handler implementations can remain in place rather than being rewritten behind a framework-specific handler type.
Summary
PlumeGo centers on a small standard-library-only kernel with nine stable modules: core, router, contract, middleware, security, store, health, log, and metrics. The kernel is complemented by extension families with explicit maturity labels and a machine-readable control plane for contributor and agent workflows.
The result is a service architecture that makes two decisions visible: where a request is routed and which module owns the next change. The public Birdor.dev record should point to that implementation rather than substitute for its documentation or source.
Architecture
flowchart LR
Handler[net/http Handler] --> Core[core App]
Core --> Router[router]
Router --> Middleware[middleware]
Middleware --> Contract[contract]
Middleware --> Security[security]
Core --> Operations[log · metrics · health]
Specs[specs and module.yaml] --> Corecore is the composition root. It receives application dependencies, registers routes through the router, and prepares the HTTP server. contract centralizes response behavior, while middleware and security hold transport-level cross-cutting concerns. The control-plane files guide a contributor or coding agent toward the owning module before an implementation change begins.
Public interfaces
| Interface | Responsibility | Deliberate boundary |
|---|---|---|
core | Application composition, lifecycle and server preparation | Does not hide route ownership in generated wiring |
router | Explicit route registration and grouping | Remains compatible with net/http handlers |
contract | Response envelopes and HTTP response writes | Does not own domain policy or persistence |
middleware and security | Request-level cross-cutting behavior | Do not absorb application-specific features |
specs/ and <module>/module.yaml | Task routing, dependency rules, module scope | Describe the control plane rather than the runtime |
The separation keeps the dependency direction legible. A reviewer can locate a change by the type of work it represents, and a coding agent can use the same repository-level rules rather than guessing a package boundary.
Source repository
The implementation, issue tracker, release history, and contribution discussion are maintained in the public repository: github.com/spcent/plumego ↗. The project currently publishes the toolkit as github.com/spcent/plumego and identifies its stable kernel as standard-library-only.
Content pipeline
PlumeGo keeps project-level engineering instructions in the repository. specs/task-routing.yaml maps work types to the responsible module, specs/dependency-rules.yaml makes boundary violations enforceable in CI, and a module.yaml inside each module records the local scope and checks. This is a control plane for the codebase: it is readable by people and provides precise context to coding agents.
app := core.New(core.DefaultConfig(),
core.AppDependencies{Logger: plog.NewLogger()})
app.Get("/ping", http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
_ = contract.WriteResponse(w, r, http.StatusOK,
map[string]string{"status": "ok"}, nil)
}))
if err := app.Prepare(); err != nil {
log.Fatal(err)
}
The code uses core for composition and contract for response writing while keeping the standard http.HandlerFunc signature. That is the practical expression of PlumeGo’s compatibility boundary.
Delivery model
PlumeGo’s stable path is designed for direct Go use. A service can add the module with go get github.com/spcent/plumego@latest, compose an application in core, call Prepare, and obtain the server through the application lifecycle. The project also provides a reference/standard-service path for a canonical service shape.
Trade-offs
The standard-library-only kernel narrows the dependency surface but deliberately does not make every capability part of the stable root. Extensions carry maturity labels, and project-specific capabilities can live outside the core path. That gives adopters a clear distinction between the stable HTTP toolkit and modules still being evaluated.
The explicit control plane also requires maintenance. Specifications and module ownership files need to evolve with the codebase. The payoff is that review and automation can reason from declared structure rather than from conventions held only in team memory.
Conclusion
PlumeGo makes a Go HTTP service easier to inspect by preserving familiar net/http shapes while exposing composition and ownership. Its small stable kernel, explicit route wiring, and machine-readable repository controls offer a concrete technical model for teams that want code review and AI-assisted work to begin from the same system map.