docs: v0.7.0 implementation plan — align with core/go v0.8.0

7-step plan to update factory signature, register process.* Actions,
remove global singleton, and align with Startable returning Result.

Written with full core/go domain context from RFC implementation session.

Co-Authored-By: Virgil <virgil@lethean.io>
This commit is contained in:
Snider 2026-03-25 15:34:24 +00:00
parent 4ff0d0b745
commit 87f53ad8dd

View file

@ -0,0 +1,151 @@
# go-process v0.7.0 — Core Alignment
> Written by Cladius with full core/go domain context (2026-03-25).
> Read core/go docs/RFC.md Section 17 for the full Process primitive spec.
## What Changed in core/go
core/go v0.8.0 added:
- `c.Process()` — primitive that delegates to `c.Action("process.*")`
- `c.Action("name")` — named action registry with panic recovery
- `Startable.OnStartup()` returns `core.Result` (not `error`)
- `Registry[T]` — universal thread-safe named collection
- `core.ID()` — unique identifier primitive
go-process needs to align its factory signature and register process Actions.
## Step 1: Fix Factory Signature
Current (`service.go`):
```go
func NewService(opts Options) func(*core.Core) (any, error) {
```
Target:
```go
func Register(c *core.Core) core.Result {
svc := &Service{
ServiceRuntime: core.NewServiceRuntime(c, Options{}),
processes: make(map[string]*ManagedProcess),
}
return core.Result{Value: svc, OK: true}
}
```
This matches `core.WithService(process.Register)` — the standard pattern.
## Step 2: Register Process Actions During OnStartup
```go
func (s *Service) OnStartup(ctx context.Context) core.Result {
c := s.Core()
// Register named actions — these are what c.Process() calls
c.Action("process.run", s.handleRun)
c.Action("process.start", s.handleStart)
c.Action("process.kill", s.handleKill)
return core.Result{OK: true}
}
```
Note: `OnStartup` now returns `core.Result` not `error`.
## Step 3: Implement Action Handlers
```go
func (s *Service) handleRun(ctx context.Context, opts core.Options) core.Result {
command := opts.String("command")
args, _ := opts.Get("args").Value.([]string)
dir := opts.String("dir")
env, _ := opts.Get("env").Value.([]string)
// Use existing RunWithOptions internally
out, err := s.RunWithOptions(ctx, RunOptions{
Command: command,
Args: args,
Dir: dir,
Env: env,
})
if err != nil {
return core.Result{Value: err, OK: false}
}
return core.Result{Value: out, OK: true}
}
func (s *Service) handleStart(ctx context.Context, opts core.Options) core.Result {
// Detached process — returns handle ID
command := opts.String("command")
args, _ := opts.Get("args").Value.([]string)
handle, err := s.Start(ctx, StartOptions{
Command: command,
Args: args,
Dir: opts.String("dir"),
Detach: opts.Bool("detach"),
})
if err != nil {
return core.Result{Value: err, OK: false}
}
return core.Result{Value: handle.ID, OK: true}
}
func (s *Service) handleKill(ctx context.Context, opts core.Options) core.Result {
id := opts.String("id")
pid := opts.Int("pid")
if id != "" {
return s.KillByID(id)
}
return s.KillByPID(pid)
}
```
## Step 4: Remove Global Singleton Pattern
Current: `process.SetDefault(svc)` and `process.Default()` global state.
Target: Service registered in Core's conclave. No global state.
The `ensureProcess()` hack in core/agent exists because go-process doesn't register properly. Once this is done, that bridge can be deleted.
## Step 5: Update OnShutdown
```go
func (s *Service) OnShutdown(ctx context.Context) core.Result {
// Kill all managed processes
for _, p := range s.processes {
p.Kill()
}
return core.Result{OK: true}
}
```
## Step 6: Use core.ID() for Process IDs
Current: `fmt.Sprintf("proc-%d", s.idCounter.Add(1))`
Target: `core.ID()` — consistent format across ecosystem.
## Step 7: AX-7 Tests
All tests renamed to `TestFile_Function_{Good,Bad,Ugly}`:
- `TestService_Register_Good` — factory returns Result
- `TestService_HandleRun_Good` — runs command via Action
- `TestService_HandleRun_Bad` — command not found
- `TestService_HandleKill_Good` — kills by ID
- `TestService_OnStartup_Good` — registers Actions
- `TestService_OnShutdown_Good` — kills all processes
## What This Unlocks
Once go-process v0.7.0 ships:
- `core.New(core.WithService(process.Register))` — standard registration
- `c.Process().Run(ctx, "git", "log")` — works end-to-end
- core/agent deletes `proc.go`, `ensureProcess()`, `ProcessRegister`
- Tests can mock process execution by registering a fake handler
## Dependencies
- core/go v0.8.0 (already done — Action system, Process primitive, Result lifecycle)
- No other deps change