go/docs/RFC.implementation.2.md
Snider 9cd83daaae feat: 6 implementation plans for v0.8.0
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>
2026-03-25 13:31:11 +00:00

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:

  1. serviceRegistryServiceRegistry embedding Registry[*Service]
  2. commandRegistryCommandRegistry embedding Registry[*Command]
  3. Drive.handles → embed Registry[*DriveHandle]
  4. Data.mounts → embed Registry[*Embed]
  5. Lock.locksRegistry[*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).