Plan 1: Critical bug fixes (v0.7.1, zero breakage) - ACTION chain, panic recovery, defer shutdown, stale code removal Plan 2: Registry[T] primitive (Section 20) - Foundation brick, migration of 5 internal registries Plan 3: Action/Task system (Section 18) - Named callables, task composition, cascade fix Plan 4: c.Process() primitive (Section 17) - go-process v0.7.0, proc.go migration, atomic writes Plan 5: Missing primitives + AX-7 - core.ID(), ValidateName, WriteAtomic, RunE(), test coverage Plan 6: Ecosystem sweep (Phase 3) - 44 repos in 5 batches, Codex dispatch with RFC as spec Each plan lists: files to change, code examples, what it resolves, dependencies on other plans, and migration strategy. Co-Authored-By: Virgil <virgil@lethean.io>
2 KiB
2 KiB
Implementation Plan 2 — Registry[T] Primitive (Section 20)
Foundation brick. Most other plans depend on this.
The Type
New file: registry.go
type Registry[T any] struct {
items map[string]T
order []string // insertion order (fixes P4-1)
mu sync.RWMutex
mode registryMode // open, sealed, locked
}
type registryMode int
const (
registryOpen registryMode = iota // anything goes
registrySealed // update existing, no new keys
registryLocked // fully frozen
)
Methods
func NewRegistry[T any]() *Registry[T]
func (r *Registry[T]) Set(name string, item T) Result
func (r *Registry[T]) Get(name string) Result
func (r *Registry[T]) Has(name string) bool
func (r *Registry[T]) Names() []string // insertion order
func (r *Registry[T]) List(pattern string) []T // glob match
func (r *Registry[T]) Each(fn func(string, T))
func (r *Registry[T]) Len() int
func (r *Registry[T]) Delete(name string) Result
func (r *Registry[T]) Disable(name string) // soft — exists but skipped
func (r *Registry[T]) Lock() // fully frozen
func (r *Registry[T]) Seal() // no new, updates OK
func (r *Registry[T]) Open() // default
Migration
Replace internal registries one at a time:
serviceRegistry→ServiceRegistryembeddingRegistry[*Service]commandRegistry→CommandRegistryembeddingRegistry[*Command]Drive.handles→ embedRegistry[*DriveHandle]Data.mounts→ embedRegistry[*Embed]Lock.locks→Registry[*sync.RWMutex](fixes P4-8 allocation)
Each migration is a separate commit. Tests before and after.
Core Accessor
func (c *Core) Registry(name string) *Registry[any]
Returns named registries for cross-cutting queries.
Resolves
P4-1 (startup order), P4-8 (lock allocation), I6 (serviceRegistry unexported), I12 (Ipc data-only), I13 (Lock allocation), I14 (Startables return type).