P0: stand up executus harness module above majordomo
executus CI / test (push) Failing after 24s

Batteries-included agent-harness base, extracted from mort's agent layer.
This first cut establishes the module + the zero-coupling core primitives:

- lane, dispatchguard, pendingattach, run/progress.go: moved verbatim from mort
- config: host config Source seam + env-var default (nil-safe helpers)
- deliver: output-egress seam + Discard/Stdout defaults
- identity: AdminPolicy + MemberResolver seams (nil-safe)
- fanout: programmatic N×M swarm (bounded global + per-key concurrency)
- README/CLAUDE.md with the vibe-coded banner; CI with Go gates +
  the "core stays majordomo+stdlib only" invariant

Core builds with stdlib only today; majordomo enters at P1 (model/structured).
go build/vet/test -race all green.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-06-26 19:18:37 -04:00
parent 25feb63c00
commit ca243a2d50
31 changed files with 5042 additions and 18 deletions
+137
View File
@@ -0,0 +1,137 @@
// Package config is executus's runtime-configuration seam.
//
// A host supplies a Source so the harness can read tunable knobs (model tiers,
// caps, thresholds, lane widths) without depending on any particular config
// backend. Mort adapts its DB-backed convar.Manager; Gadfly adapts environment
// variables; a brand-new project can use Env (or pass a nil Source and rely on
// the code defaults every reader provides).
//
// Design rules:
// - Every accessor takes a code default. A Source is NEVER required to know a
// key — readers degrade to the default, so the harness runs with zero config.
// - Reads are LIVE: callers read on every use so a host whose backend mutates
// at runtime (e.g. convar) propagates without a restart. Sources that cache
// (mort's 5-minute convar cache) may additionally implement Reloader to
// signal invalidation.
package config
import (
"os"
"strconv"
"strings"
)
// Source is the host configuration seam. All methods take a default and must be
// safe for concurrent use.
type Source interface {
String(key, def string) string
Int(key string, def int) int
Float(key string, def float64) float64
Bool(key string, def bool) bool
}
// Reloader is an optional capability for Sources whose values can change at
// runtime and that can notify watchers (e.g. a tier-reload or cache
// invalidation). Sources that do not implement it are simply read live on every
// access. Watch returns a cancel func; a nil-safe no-op is acceptable.
type Reloader interface {
Watch(prefix string, fn func(key string)) (cancel func())
}
// Nil-safe package helpers: callers that may hold a nil Source use these instead
// of dereferencing. They let every battery treat config as optional.
func String(s Source, key, def string) string {
if s == nil {
return def
}
return s.String(key, def)
}
func Int(s Source, key string, def int) int {
if s == nil {
return def
}
return s.Int(key, def)
}
func Float(s Source, key string, def float64) float64 {
if s == nil {
return def
}
return s.Float(key, def)
}
func Bool(s Source, key string, def bool) bool {
if s == nil {
return def
}
return s.Bool(key, def)
}
// Env is the default Source: it reads process environment variables. A key is
// mapped to an env var name by uppercasing it and replacing every rune outside
// [A-Za-z0-9] with '_', then prefixing. So Env("GADFLY_").String("models", "")
// reads GADFLY_MODELS, and Env("").Int("model.tier.fast.max_steps", 8) reads
// MODEL_TIER_FAST_MAX_STEPS. An unset or unparseable value yields the default.
func Env(prefix string) Source { return envSource{prefix: prefix} }
type envSource struct{ prefix string }
func (e envSource) envName(key string) string {
var b strings.Builder
b.WriteString(e.prefix)
for _, r := range key {
switch {
case r >= 'a' && r <= 'z':
b.WriteRune(r - 32)
case (r >= 'A' && r <= 'Z') || (r >= '0' && r <= '9'):
b.WriteRune(r)
default:
b.WriteByte('_')
}
}
return b.String()
}
func (e envSource) raw(key string) (string, bool) {
v, ok := os.LookupEnv(e.envName(key))
if !ok {
return "", false
}
return strings.TrimSpace(v), true
}
func (e envSource) String(key, def string) string {
if v, ok := e.raw(key); ok && v != "" {
return v
}
return def
}
func (e envSource) Int(key string, def int) int {
if v, ok := e.raw(key); ok {
if n, err := strconv.Atoi(v); err == nil {
return n
}
}
return def
}
func (e envSource) Float(key string, def float64) float64 {
if v, ok := e.raw(key); ok {
if f, err := strconv.ParseFloat(v, 64); err == nil {
return f
}
}
return def
}
func (e envSource) Bool(key string, def bool) bool {
if v, ok := e.raw(key); ok {
if b, err := strconv.ParseBool(v); err == nil {
return b
}
}
return def
}