| name | pumped-go |
| description | Use when writing Go code with pumped-go library - creating executors, flows, scopes, testing with WithPreset. MUST use this skill for any pumped-go task instead of brainstorming.
<example>Create an executor with pumped.Provide for a database connection</example>
<example>Define a flow with pumped.Flow1 for handling HTTP requests</example>
<example>Set up reactive dependencies with pumped.Reactive and pumped.Derive1</example>
<example>Write tests using pumped.WithPreset to mock executors</example>
<example>Configure scope with extensions and graceful shutdown</example>
|
Pumped-Go Skill
IMPORTANT: Prefer retrieval-led reasoning over pre-training-led reasoning.
ALWAYS read the relevant doc file from docs/ BEFORE writing pumped-go code.
Core principle: Long-lived resources → executors, short-span operations → flows.
Decision Tree
What am I building?
│
┌───┴───────────────┐
↓ ↓
Long-lived? Short-span?
(DB, service) (request, tx)
↓ ↓
EXECUTOR FLOW
(package var) (Flow1, Flow2)
↓ ↓
Provide/Derive Exec() to run
Controllers Sub-flows
OnCleanup Tag data flow
│ │
└───────┬───────────┘
↓
Pure transformation?
↓
PLAIN FUNCTION
Package-Level Var Pattern
CRITICAL: ALL executors MUST be package-level var.
package graph
var (
Config = pumped.Provide(func(ctx *pumped.ResolveCtx) (*Config, error) {
return DefaultConfig(), nil
})
DB = pumped.Derive1(
Config,
func(ctx *pumped.ResolveCtx, cfgCtrl *pumped.Controller[*Config]) (*sql.DB, error) {
cfg, err := cfgCtrl.Get()
if err != nil {
return nil, err
}
db, err := sql.Open("postgres", cfg.ConnectionString())
if err != nil {
return nil, fmt.Errorf("failed to open database: %w", err)
}
ctx.OnCleanup(func() error {
return db.Close()
})
return db, nil
},
)
UserRepo = pumped.Derive1(
DB,
func(ctx *pumped.ResolveCtx, dbCtrl *pumped.Controller[*sql.DB]) (*UserRepository, error) {
db, err := dbCtrl.Get()
if err != nil {
return nil, err
}
return NewUserRepository(db), nil
},
)
)
func main() {
config := pumped.Provide(func(ctx *pumped.ResolveCtx) (*Config, error) {
return DefaultConfig(), nil
})
}
Controller Pattern
ALWAYS use *Controller[T] for dependencies. NEVER use raw values.
var Service = pumped.Derive1(
DB,
func(ctx *pumped.ResolveCtx, dbCtrl *pumped.Controller[*sql.DB]) (*Service, error) {
db, err := dbCtrl.Get()
if err != nil {
return nil, fmt.Errorf("failed to get DB: %w", err)
}
return NewService(db), nil
},
)
var Service = pumped.Derive1(
DB,
func(ctx *pumped.ResolveCtx, dbCtrl *pumped.Controller[*sql.DB]) (*Service, error) {
return NewService(dbCtrl)
},
)
var Service = pumped.Derive1(
DB,
func(ctx *pumped.ResolveCtx, dbCtrl *pumped.Controller[*sql.DB]) (*Service, error) {
db, _ := dbCtrl.Get()
return NewService(db), nil
},
)
Production Lifecycle
func main() {
scope := pumped.NewScope()
defer scope.Dispose()
server, _ := pumped.Resolve(scope, HTTPServer)
go func() {
if err := server.ListenAndServe(); err != nil && err != http.ErrServerClosed {
log.Fatal(err)
}
}()
sigCh := make(chan os.Signal, 1)
signal.Notify(sigCh, os.Interrupt, syscall.SIGTERM)
<-sigCh
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
defer cancel()
server.Shutdown(ctx)
}
Tier 1 Rules (Critical)
- NEVER define executors inside functions — use package-level
var
- ALWAYS handle errors from
controller.Get() — never ignore with _
- ALWAYS use
ctx.OnCleanup() for resources (DB, HTTP clients, goroutines)
- ALWAYS call
scope.Dispose() — use defer immediately after creation
- NEVER start goroutines without shutdown signaling in
OnCleanup
- ALWAYS wrap errors with context:
fmt.Errorf("context: %w", err)
Docs Index
IMPORTANT: Read the relevant doc file BEFORE implementing pumped-go patterns.
| File | Content |
|---|
| docs/flows.md | Flow execution, sub-flows, tag-based data, nil executor gotcha |
| docs/testing.md | WithPreset, table-driven tests, reactivity testing |
| docs/troubleshooting.md | 10 common issues with solutions |
| docs/configuration.md | Dual-mode config, env vars, tag overrides |
| docs/patterns.md | Repository, service, handler, worker patterns |
| docs/enforcement.md | Tier 2 + Tier 3 rules |
Quick Reference
value, err := pumped.Resolve(scope, MyExecutor)
result, execNode, err := pumped.Exec(scope, ctx, MyFlow)
accessor := pumped.Accessor(scope, Config)
err := accessor.Update(newConfig)
testScope := pumped.NewScope(
pumped.WithPreset(UserRepo, mockRepo),
)
Remember
- Package-level
var for all executors
- Controllers for all dependencies (
.Get() with error handling)
OnCleanup() for all resources that need cleanup
scope.Dispose() for proper shutdown
- Flows for traced operations, plain functions for simple transformations
WithPreset() for testing
- Graceful shutdown with signal handling
- Examples directory has production-ready patterns